Added public files

Roughly added all public files. Probably missed some, though.
diff --git a/doc/.idx b/doc/.idx
new file mode 100644
index 0000000..ceb6245
--- /dev/null
+++ b/doc/.idx
@@ -0,0 +1,1218 @@
+.	
+Grundlagen	Grundlagen
+Objekte	Grundlagen/Objekte
+Effizienz	Grundlagen/Effizienz
+Effizienz.0	Grundlagen/Effizienz.0
+efun	efun
+transpose_array	efun/transpose_array
+find_player	efun/find_player
+write_file	efun/write_file
+write_bytes	efun/write_bytes
+write	efun/write
+wizlist_info	efun/wizlist_info
+users	efun/users
+wizlist	efun/wizlist
+walk_mapping	efun/walk_mapping
+unique_array	efun/unique_array
+unshadow	efun/unshadow
+unbound_lambda	efun/unbound_lambda
+typeof	efun/typeof
+traceprefix	efun/traceprefix
+transfer	efun/transfer
+to_string	efun/to_string
+trace	efun/trace
+to_int	efun/to_int
+this_player	efun/this_player
+to_float	efun/to_float
+to_array	efun/to_array
+time	efun/time
+throw	efun/throw
+this_interactive	efun/this_interactive
+tan	efun/tan
+this_object	efun/this_object
+tell_object	efun/tell_object
+tell_room	efun/tell_room
+test_bit	efun/test_bit
+symbolp	efun/symbolp
+tail	efun/tail
+shutdown	efun/shutdown
+sin	efun/sin
+symbol_function	efun/symbol_function
+swap	efun/swap
+strstr	efun/strstr
+strlen	efun/strlen
+stringp	efun/stringp
+sscanf	efun/sscanf
+sprintf	efun/sprintf
+sqrt	efun/sqrt
+sort_array	efun/sort_array
+snoop	efun/snoop
+slice_array	efun/slice_array
+sizeof	efun/sizeof
+seteuid	efun/seteuid
+shadow	efun/shadow
+shout	efun/shout
+set_extra_wizinfo_size	efun/set_extra_wizinfo_size
+set_this_player	efun/set_this_player
+set_this_object	efun/set_this_object
+sizeof	efun/sizeof
+say	efun/say
+set_modify_command	efun/set_modify_command
+set_prompt	efun/set_prompt
+rm	efun/rm
+set_light	efun/set_light
+set_living_name	efun/set_living_name
+set_heart_beat	efun/set_heart_beat
+set_is_wizard	efun/set_is_wizard
+set_extra_wizinfo	efun/set_extra_wizinfo
+save_object	efun/save_object
+set_bit	efun/set_bit
+rename	efun/rename
+set_auto_include_string	efun/set_auto_include_string
+send_imp	efun/send_imp
+rmdir	efun/rmdir
+rusage	efun/rusage
+restore_object	efun/restore_object
+query_once_interactive	efun/query_once_interactive
+replace_program	efun/replace_program
+rename_object	efun/rename_object
+remove_call_out	efun/remove_call_out
+remove_action	efun/remove_action
+remove_alist	efun/remove_alist
+referencep	efun/referencep
+remove_interactive	efun/remove_interactive
+read_file	efun/read_file
+regexplode	efun/regexplode
+regexp	efun/regexp
+read_bytes	efun/read_bytes
+raise_error	efun/raise_error
+random	efun/random
+query_verb	efun/query_verb
+quote	efun/quote
+query_load_average	efun/query_load_average
+query_snoop	efun/query_snoop
+query_mud_port	efun/query_mud_port
+query_input_pending	efun/query_input_pending
+query_ip_number	efun/query_ip_number
+query_ip_name	efun/query_ip_name
+query_imp_port	efun/query_imp_port
+query_editing	efun/query_editing
+query_idle	efun/query_idle
+interactive	efun/interactive
+log	efun/log
+query_actions	efun/query_actions
+program_time	efun/program_time
+printf	efun/printf
+query_host_name	efun/query_host_name
+process_string	efun/process_string
+previous_object	efun/previous_object
+pointerp	efun/pointerp
+people	efun/people
+present	efun/present
+parse_command	efun/parse_command
+parse_command.1	efun/parse_command.1
+order_alist	efun/order_alist
+objectp	efun/objectp
+negate	efun/negate
+notify_fail	efun/notify_fail
+next_inventory	efun/next_inventory
+mkdir	efun/mkdir
+move_object	efun/move_object
+member_array	efun/member_array
+mkmapping	efun/mkmapping
+mappingp	efun/mappingp
+m_contains	efun/m_contains
+member	efun/member
+map	efun/map
+m_values	efun/m_values
+map_indices	efun/map_indices
+map_objects	efun/map_objects
+m_indices	efun/m_indices
+m_delete	efun/m_delete
+log_file	efun/log_file
+lower_case	efun/lower_case
+living	efun/living
+lambda	efun/lambda
+intp	efun/intp
+function_exists	efun/function_exists
+intersect_alist	efun/intersect_alist
+insert_alist.orig	efun/insert_alist.orig
+insert_alist.rej	efun/insert_alist.rej
+inherit_list	efun/inherit_list
+input_to	efun/input_to
+implode	efun/implode
+insert_alist	efun/insert_alist
+heart_beat_info	efun/heart_beat_info
+get_type_info	efun/get_type_info
+geteuid	efun/geteuid
+getuid	efun/getuid
+get_error_file	efun/get_error_file
+get_extra_wizinfo	efun/get_extra_wizinfo
+get_eval_cost	efun/get_eval_cost
+get_dir	efun/get_dir
+garbage_collection	efun/garbage_collection
+funcall	efun/funcall
+find_object	efun/find_object
+first_inventory	efun/first_inventory
+functionlist	efun/functionlist
+floatp	efun/floatp
+enable_commands	efun/enable_commands
+filter_objects	efun/filter_objects
+find_living	efun/find_living
+find_call_out	efun/find_call_out
+filter	efun/filter
+filter_indices	efun/filter_indices
+file_size	efun/file_size
+object_name	efun/object_name
+file_time	efun/file_time
+export_uid	efun/export_uid
+extract	efun/extract
+explode	efun/explode
+exclude_array	efun/exclude_array
+exp	efun/exp
+exec	efun/exec
+exclude_alist	efun/exclude_alist
+ed	efun/ed
+environment	efun/environment
+debug_info	efun/debug_info
+efun	efun/efun
+cos	efun/cos
+destruct	efun/destruct
+crypt	efun/crypt
+disable_commands	efun/disable_commands
+caller_stack_depth	efun/caller_stack_depth
+deep_inventory	efun/deep_inventory
+ctime	efun/ctime
+create_wizard	efun/create_wizard
+creator	efun/creator
+copy	efun/copy
+command	efun/command
+clone_object	efun/clone_object
+closurep	efun/closurep
+catch	efun/catch
+clear_bit	efun/clear_bit
+cindent	efun/cindent
+cat	efun/cat
+call_resolved	efun/call_resolved
+call_out_info	efun/call_out_info
+capitalize	efun/capitalize
+call_other	efun/call_other
+call_out	efun/call_out
+allocate_mapping	efun/allocate_mapping
+break_string	efun/break_string
+assoc	efun/assoc
+bind_lambda	efun/bind_lambda
+atan	efun/atan
+apply	efun/apply
+break_point	efun/break_point
+allocate	efun/allocate
+add_worth	efun/add_worth
+asin	efun/asin
+all_inventory	efun/all_inventory
+add_xverb	efun/add_xverb
+send_erq	efun/send_erq
+add_verb	efun/add_verb
+acos	efun/acos
+add_action	efun/add_action
+attach_erq_demon	efun/attach_erq_demon
+binary_message	efun/binary_message
+debug_message	efun/debug_message
+set_environment	efun/set_environment
+extern_call	efun/extern_call
+last_instructions	efun/last_instructions
+query_shadowing	efun/query_shadowing
+set_buffer_size	efun/set_buffer_size
+set_connection_charset	efun/set_connection_charset
+set_driver_hook	efun/set_driver_hook
+symbol_variable	efun/symbol_variable
+to_object	efun/to_object
+deep_present	efun/deep_present
+efun::m_delete	efun/efun::m_delete
+efun::explode	efun/efun::explode
+all_environment	efun/all_environment
+dtime	efun/dtime
+find_livings	efun/find_livings
+find_netdead	efun/find_netdead
+is_clone	efun/is_clone
+lowerchar	efun/lowerchar
+lowerstring	efun/lowerstring
+match_living	efun/match_living
+new_explode	efun/new_explode
+old_explode	efun/old_explode
+query_wiz_grp	efun/query_wiz_grp
+query_wiz_level	efun/query_wiz_level
+set_object_heart_beat	efun/set_object_heart_beat
+update_actions	efun/update_actions
+upperstring	efun/upperstring
+uptime	efun/uptime
+time2string	efun/time2string
+regreplace	efun/regreplace
+dump_netdead	efun/dump_netdead
+std	std
+room.doku	std/room.doku
+weapon	std/weapon
+transport	std/transport
+room	std/room
+thing	std/thing
+armour	std/armour
+unit	std/unit
+tuer	std/tuer
+ruestung	std/ruestung
+sequencer	std/sequencer
+schluessel	std/schluessel
+living	std/living
+door	std/door
+corpse	std/corpse
+container	std/container
+vererbungsbaeume	std/vererbungsbaeume
+virtual_compiler	std/virtual_compiler
+MG	MG
+gilden-doku	MG/gilden-doku
+waffen_werte	MG/waffen_werte
+zaubertraenke	MG/zaubertraenke
+obj_geruest	MG/obj_geruest
+netz	MG/netz
+put_and_get	MG/put_and_get
+autoload	MG/autoload
+GOOD_STYLE	MG/GOOD_STYLE
+benennung	MG/benennung
+banish	MG/banish
+angriff	MG/angriff
+muster_raum.c	MG/muster_raum.c
+skills.doc	MG/skills.doc
+put_and_get.c	MG/put_and_get.c
+quests.doc	MG/quests.doc
+todessequenz	MG/todessequenz
+sensitive	MG/sensitive
+concepts	concepts
+erq	concepts/erq
+hooks	concepts/hooks
+properties.new	concepts/properties.new
+terminals	concepts/terminals
+uids	concepts/uids
+simul_efun	concepts/simul_efun
+oop	concepts/oop
+properties	concepts/properties
+memory	concepts/memory
+news	concepts/news
+objects	concepts/objects
+native	concepts/native
+mail	concepts/mail
+lpc	concepts/lpc
+files	concepts/files
+concepts	concepts/concepts
+imp	concepts/imp
+negotiation	concepts/negotiation
+lfun	lfun
+QueryDamage	lfun/QueryDamage
+SetHitFunc	lfun/SetHitFunc
+HitFunc	lfun/HitFunc
+create_default_npc	lfun/create_default_npc
+SetDefendFunc	lfun/SetDefendFunc
+DefendFunc	lfun/DefendFunc
+QueryDefend	lfun/QueryDefend
+Defend	lfun/Defend
+Attack	lfun/Attack
+AddCmd	lfun/AddCmd
+heart_beat	lfun/heart_beat
+name	lfun/name
+reset	lfun/reset
+remove	lfun/remove
+muster	lfun/muster
+long	lfun/long
+query_real_name	lfun/query_real_name
+reduce_hit_point	lfun/reduce_hit_point
+move	lfun/move
+id	lfun/id
+modify_command	lfun/modify_command
+lfun	lfun/lfun
+logon	lfun/logon
+init	lfun/init
+do_damage	lfun/do_damage
+exit	lfun/exit
+heal_self	lfun/heal_self
+extra_look	lfun/extra_look
+clean_up	lfun/clean_up
+create	lfun/create
+DiscoverDoor	lfun/DiscoverDoor
+catch_tell	lfun/catch_tell
+catch_msg	lfun/catch_msg
+Teleport	lfun/Teleport
+__INIT	lfun/__INIT
+SetProp	lfun/SetProp
+ShowDoors	lfun/ShowDoors
+Kill	lfun/Kill
+NewDoor	lfun/NewDoor
+QueryPossPronoun	lfun/QueryPossPronoun
+CheckResistance	lfun/CheckResistance
+DoorIsKnown	lfun/DoorIsKnown
+AddPursuer	lfun/AddPursuer
+AddRoomCmd	lfun/AddRoomCmd
+AddInfo	lfun/AddInfo
+RemoveRursuer	lfun/RemoveRursuer
+PreventFollow	lfun/PreventFollow
+Message	lfun/Message
+InFight	lfun/InFight
+AddAmount	lfun/AddAmount
+access_rights	lfun/access_rights
+trigger_sensitive_attack	lfun/trigger_sensitive_attack
+QueryDoorStatus	lfun/QueryDoorStatus
+QueryAllDoors	lfun/QueryAllDoors
+SetDoorStatus	lfun/SetDoorStatus
+QueryDoorKey	lfun/QueryDoorKey
+AddAdjective	lfun/AddAdjective
+AddClass	lfun/AddClass
+AddDetail	lfun/AddDetail
+AddDrink	lfun/AddDrink
+AddExit	lfun/AddExit
+AddFood	lfun/AddFood
+AddFuel	lfun/AddFuel
+AddFun	lfun/AddFun
+AddId	lfun/AddId
+AddItem	lfun/AddItem
+AddMsg	lfun/AddMsg
+AddPluralId	lfun/AddPluralId
+AddReadDetail	lfun/AddReadDetail
+AddRoomMessage	lfun/AddRoomMessage
+AddRoute	lfun/AddRoute
+AddSingularId	lfun/AddSingularId
+AddSpecialDetail	lfun/AddSpecialDetail
+DeclAdj	lfun/DeclAdj
+AddSpecialExit	lfun/AddSpecialExit
+DoUnwear	lfun/DoUnwear
+DoUnwield	lfun/DoUnwield
+DoWear	lfun/DoWear
+Enter	lfun/Enter
+GetDetail	lfun/GetDetail
+GetExits	lfun/GetExits
+Halt	lfun/Halt
+Identify	lfun/Identify
+IsUnit	lfun/IsUnit
+Leave	lfun/Leave
+MayAddWeight	lfun/MayAddWeight
+PreventInsert	lfun/PreventInsert
+Query	lfun/Query
+QueryArrived	lfun/QueryArrived
+QueryArticle	lfun/QueryArticle
+QueryBuyFact	lfun/QueryBuyFact
+QueryCoinsPerUnits	lfun/QueryCoinsPerUnits
+QueryDu	lfun/QueryDu
+QueryFlaw	lfun/QueryFlaw
+QueryGenderString	lfun/QueryGenderString
+QueryGramsPerUnits	lfun/QueryGramsPerUnits
+QueryName	lfun/QueryName
+QueryPassengers	lfun/QueryPassengers
+QueryPosition	lfun/QueryPosition
+QueryPronoun	lfun/QueryPronoun
+QueryProp	lfun/QueryProp
+QueryProperties	lfun/QueryProperties
+RemoveAdjective	lfun/RemoveAdjective
+RemoveId	lfun/RemoveId
+RemoveClass	lfun/RemoveClass
+RemoveCmd	lfun/RemoveCmd
+RemoveDetail	lfun/RemoveDetail
+RemoveExit	lfun/RemoveExit
+RemoveFunc	lfun/RemoveFunc
+RemoveReadDetail	lfun/RemoveReadDetail
+RemoveRoute	lfun/RemoveRoute
+RemoveSpecialDetail	lfun/RemoveSpecialDetail
+RemoveSpecialExit	lfun/RemoveSpecialExit
+Set	lfun/Set
+SetBuyFact	lfun/SetBuyFact
+SetCoinsPerUnits	lfun/SetCoinsPerUnits
+SetGramsPerUnits	lfun/SetGramsPerUnits
+SetProperties	lfun/SetProperties
+SetStorageRoom	lfun/SetStorageRoom
+ShowPropList	lfun/ShowPropList
+Start	lfun/Start
+SuggestArticle	lfun/SuggestArticle
+TakeFlaw	lfun/TakeFlaw
+UnwieldFunc	lfun/UnwieldFunc
+WearFunc	lfun/WearFunc
+WieldFunc	lfun/WieldFunc
+do_unwear	lfun/do_unwear
+do_wear	lfun/do_wear
+int_long	lfun/int_long
+int_short	lfun/int_short
+is_class_member	lfun/is_class_member
+locate_objects	lfun/locate_objects
+make_invlist	lfun/make_invlist
+paramove	lfun/paramove
+present_objects	lfun/present_objects
+query_weight_contents	lfun/query_weight_contents
+short	lfun/short
+trigger_sensitive_inv	lfun/trigger_sensitive_inv
+wield_me	lfun/wield_me
+AddSpell	lfun/AddSpell
+RemoveItem	lfun/RemoveItem
+NotifyGiveQuest	lfun/NotifyGiveQuest
+Damage	lfun/Damage
+SetChats	lfun/SetChats
+SetAttackChats	lfun/SetAttackChats
+RemovePluralId	lfun/RemovePluralId
+RemoveSingularId	lfun/RemoveSingularId
+QueryMaterial	lfun/QueryMaterial
+MaterialList	lfun/MaterialList
+QueryMaterialGroup	lfun/QueryMaterialGroup
+misc	misc
+called_by_player	misc/called_by_player
+simul_efuns	misc/simul_efuns
+CLEAN_UP	misc/CLEAN_UP
+mem	misc/mem
+beispiele	beispiele
+bspruest1.c	beispiele/bspruest1.c
+bspmon2.c	beispiele/bspmon2.c
+raum1.c	beispiele/raum1.c
+wolke.c	beispiele/wolke.c
+bspwaffe1.c	beispiele/bspwaffe1.c
+bspmon1.c	beispiele/bspmon1.c
+LPC	LPC
+alists	LPC/alists
+arrays	LPC/arrays
+block	LPC/block
+closures	LPC/closures
+closures-example	LPC/closures-example
+do-while	LPC/do-while
+ed0	LPC/ed0
+ed1	LPC/ed1
+ed2	LPC/ed2
+ed3	LPC/ed3
+ed4	LPC/ed4
+ed5	LPC/ed5
+ed6	LPC/ed6
+efuns	LPC/efuns
+for	LPC/for
+functions	LPC/functions
+inherit	LPC/inherit
+inheritance	LPC/inheritance
+initialisation	LPC/initialisation
+lfuns	LPC/lfuns
+lpc	LPC/lpc
+mappings	LPC/mappings
+operators	LPC/operators
+pragma	LPC/pragma
+preprocessor	LPC/preprocessor
+references	LPC/references
+switch	LPC/switch
+types	LPC/types
+while	LPC/while
+master	master
+valid_query_snoop	master/valid_query_snoop
+valid_snoop	master/valid_snoop
+valid_write	master/valid_write
+valid_read	master/valid_read
+valid_seteuid	master/valid_seteuid
+slow_shut_down	master/slow_shut_down
+valid_exec	master/valid_exec
+retrieve_ed_setup	master/retrieve_ed_setup
+save_ed_setup	master/save_ed_setup
+runtime_error	master/runtime_error
+remove_player	master/remove_player
+query_player_level	master/query_player_level
+receive_imp	master/receive_imp
+quota_demon	master/quota_demon
+preload	master/preload
+privilege_violation	master/privilege_violation
+reactivate_destructed_master	master/reactivate_destructed_master
+query_allow_shadow	master/query_allow_shadow
+heart_beat_error	master/heart_beat_error
+object_name	master/object_name
+prepare_destruct	master/prepare_destruct
+parse_command_all_word	master/parse_command_all_word
+parse_command_prepos_list	master/parse_command_prepos_list
+make_path_absolute	master/make_path_absolute
+master	master/master
+get_root_uid	master/get_root_uid
+log_error	master/log_error
+external_master_reload	master/external_master_reload
+inaugurate_master	master/inaugurate_master
+get_wiz_name	master/get_wiz_name
+get_simul_efun	master/get_simul_efun
+get_bb_uid	master/get_bb_uid
+flag	master/flag
+epilog	master/epilog
+get_ed_buffer_save_object_name	master/get_ed_buffer_save_object_name
+connect	master/connect
+dangling_lfun_closure	master/dangling_lfun_closure
+define_include_dirs	master/define_include_dirs
+disconnect	master/disconnect
+creator_file	master/creator_file
+compile_object	master/compile_object
+master-3.2	master/master-3.2
+Grep-Privilege	master/Grep-Privilege
+Grep-Apply-Master	master/Grep-Apply-Master
+Grep-CheckValidPath-Master	master/Grep-CheckValidPath-Master
+get_master_uid	master/get_master_uid
+initialisation	master/initialisation
+master-3.2.1	master/master-3.2.1
+notify_shutdown	master/notify_shutdown
+stale_erq	master/stale_erq
+ed	ed
+ed4	ed/ed4
+ed1	ed/ed1
+ed0	ed/ed0
+ed3	ed/ed3
+ed2	ed/ed2
+driver	driver
+commandline	driver/commandline
+driver	driver/driver
+debugmalloc	driver/debugmalloc
+dumpallobj	driver/dumpallobj
+malloc	driver/malloc
+opcdump	driver/opcdump
+predefined	driver/predefined
+showsmallnewmalloced	driver/showsmallnewmalloced
+status	driver/status
+KURS	KURS
+LPC-KURS2	KURS/LPC-KURS2
+chapter5	KURS/LPC-KURS2/chapter5
+chapter4	KURS/LPC-KURS2/chapter4
+chapter3	KURS/LPC-KURS2/chapter3
+chapter7	KURS/LPC-KURS2/chapter7
+chapter6	KURS/LPC-KURS2/chapter6
+chapter2	KURS/LPC-KURS2/chapter2
+Copyright	KURS/LPC-KURS2/Copyright
+chapter1	KURS/LPC-KURS2/chapter1
+Contents	KURS/LPC-KURS2/Contents
+LPC-KURS	KURS/LPC-KURS
+Introduction	KURS/LPC-KURS/Introduction
+chapter4	KURS/LPC-KURS/chapter4
+chapter2	KURS/LPC-KURS/chapter2
+chapter8	KURS/LPC-KURS/chapter8
+chapter7	KURS/LPC-KURS/chapter7
+chapter6	KURS/LPC-KURS/chapter6
+chapter5	KURS/LPC-KURS/chapter5
+chapter3	KURS/LPC-KURS/chapter3
+chapter1	KURS/LPC-KURS/chapter1
+Contents	KURS/LPC-KURS/Contents
+objekte	KURS/objekte
+raum1	KURS/raum1
+einleitung	KURS/einleitung
+RULES	KURS/RULES
+RULES.WIZ	KURS/RULES.WIZ
+COMMENTS	KURS/COMMENTS
+GUIDE.old	KURS/GUIDE.old
+3.0	3.0
+mudlib_outline	3.0/mudlib_outline
+problems	3.0/problems
+lfun_efun.man	3.0/lfun_efun.man
+lfun_efun.me	3.0/lfun_efun.me
+auto_destruct	3.0/auto_destruct
+LPmud.doc.me	3.0/LPmud.doc.me
+LPmud.doc.man	3.0/LPmud.doc.man
+3.0.info	3.0/3.0.info
+@README	@README
+about-efun+lfun-docs	about-efun+lfun-docs
+closures	closures
+func_spec	func_spec
+help	help
+abenteuer	help/abenteuer
+abenteurer	help/abenteurer
+attribute	help/attribute
+bewegung	help/bewegung
+bierschuettler	help/bierschuettler
+buecher	help/buecher
+chaos	help/chaos
+editor	help/editor
+erzmagier	help/erzmagier
+faq	help/faq
+forscherpunkte	help/forscherpunkte
+gilden	help/gilden
+kaempfer	help/kaempfer
+karate	help/karate
+klerus	help/klerus
+konzept	help/konzept
+magier	help/magier
+post	help/post
+regionen	help/regionen
+scripte	help/scripte
+seher	help/seher
+stufen	help/stufen
+stufenpunkte	help/stufenpunkte
+syntax	help/syntax
+zauberei	help/zauberei
+zauberer	help/zauberer
+zaubertraenke	help/zaubertraenke
+verein	help/verein
+props	props
+P_COMBATCMDS	props/P_COMBATCMDS
+P_INVIS	props/P_INVIS
+P_COMBATCMDS.old	props/P_COMBATCMDS.old
+P_HIDE_EXITS	props/P_HIDE_EXITS
+P_INVIS.old	props/P_INVIS.old
+P_HIDE_EXITS.old	props/P_HIDE_EXITS.old
+P_AC	props/P_AC
+P_WORN	props/P_WORN
+P_ARMOUR_TYPE	props/P_ARMOUR_TYPE
+P_DEFEND_FUNC	props/P_DEFEND_FUNC
+P_WEAR_FUNC	props/P_WEAR_FUNC
+P_REMOVE_FUNC	props/P_REMOVE_FUNC
+P_NO_GLOBAL_ATTACK	props/P_NO_GLOBAL_ATTACK
+P_DAMAGED	props/P_DAMAGED
+P_EFFECTIVE_WC	props/P_EFFECTIVE_WC
+P_EFFECTIVE_AC	props/P_EFFECTIVE_AC
+P_MAX_WEIGHT	props/P_MAX_WEIGHT
+P_CONTENTS	props/P_CONTENTS
+P_CNT_STATUS	props/P_CNT_STATUS
+P_TRANSPARENT	props/P_TRANSPARENT
+P_DOOR_INFOS	props/P_DOOR_INFOS
+P_WATER	props/P_WATER
+P_FISH	props/P_FISH
+P_LIQUID	props/P_LIQUID
+P_LONG_EMPTY	props/P_LONG_EMPTY
+P_LONG_FULL	props/P_LONG_FULL
+P_GUARD	props/P_GUARD
+P_EVAL_OFFSETS	props/P_EVAL_OFFSETS
+P_EVAL_FACTORS	props/P_EVAL_FACTORS
+P_INPC_LAST_PLAYER_CONTACT	props/P_INPC_LAST_PLAYER_CONTACT
+P_INPC_LAST_ENVIRONMENT	props/P_INPC_LAST_ENVIRONMENT
+P_INPC_WALK_MODE	props/P_INPC_WALK_MODE
+P_INPC_WALK_DELAYS	props/P_INPC_WALK_DELAYS
+P_INPC_WALK_FLAGS	props/P_INPC_WALK_FLAGS
+P_INPC_WALK_AREA	props/P_INPC_WALK_AREA
+P_INPC_WALK_ROUTE	props/P_INPC_WALK_ROUTE
+P_INPC_HOME	props/P_INPC_HOME
+P_ARTICLE	props/P_ARTICLE
+P_GENDER	props/P_GENDER
+P_ATTRIBUTES	props/P_ATTRIBUTES
+P_ATTRIBUTES_OFFSETS	props/P_ATTRIBUTES_OFFSETS
+P_X_ATTR_MOD	props/P_X_ATTR_MOD
+P_ATTRIBUTES_MODIFIER	props/P_ATTRIBUTES_MODIFIER
+P_ABILITIES	props/P_ABILITIES
+P_RESISTANCE	props/P_RESISTANCE
+P_RESISTANCE_STRENGHTS	props/P_RESISTANCE_STRENGHTS
+P_VULNERABILITY	props/P_VULNERABILITY
+P_TOTAL_AC	props/P_TOTAL_AC
+P_HANDS	props/P_HANDS
+P_MAX_HANDS	props/P_MAX_HANDS
+P_USED_HANDS	props/P_USED_HANDS
+P_ATTACK_BUSY	props/P_ATTACK_BUSY
+P_PREFERED_ENEMY	props/P_PREFERED_ENEMY
+P_RESISTANCE_STRENGTHS	props/P_RESISTANCE_STRENGTHS
+P_AGE	props/P_AGE
+P_ALIGN	props/P_ALIGN
+P_DEADS	props/P_DEADS
+P_GHOST	props/P_GHOST
+P_FROG	props/P_FROG
+P_FOOD	props/P_FOOD
+P_MAX_FOOD	props/P_MAX_FOOD
+P_DRINK	props/P_DRINK
+P_MAX_DRINK	props/P_MAX_DRINK
+P_ALCOHOL	props/P_ALCOHOL
+P_MAX_ALCOHOL	props/P_MAX_ALCOHOL
+P_HP	props/P_HP
+P_MAX_HP	props/P_MAX_HP
+P_SP	props/P_SP
+P_MAX_SP	props/P_MAX_SP
+P_XP	props/P_XP
+P_VALID_GUILDS	props/P_VALID_GUILDS
+P_GUILD_SKILLS	props/P_GUILD_SKILLS
+P_GUILD_RESTRICTIONS	props/P_GUILD_RESTRICTIONS
+P_GUILD_DEFAULT_SPELLBOOK	props/P_GUILD_DEFAULT_SPELLBOOK
+P_GUILD_MALE_TITLES	props/P_GUILD_MALE_TITLES
+P_GUILD_FEMALE_TITLES	props/P_GUILD_FEMALE_TITLES
+P_GUILD_LEVELS	props/P_GUILD_LEVELS
+P_SB_SPELLS	props/P_SB_SPELLS
+P_GLOBAL_SKILLPROPS	props/P_GLOBAL_SKILLPROPS
+P_GUILD_LEVEL	props/P_GUILD_LEVEL
+P_GUILD_TITLE	props/P_GUILD_TITLE
+P_GUILD_RATING	props/P_GUILD_RATING
+P_NEWSKILLS	props/P_NEWSKILLS
+P_NEXT_SPELL_TIME	props/P_NEXT_SPELL_TIME
+P_TMP_ATTACK_HOOK	props/P_TMP_ATTACK_HOOK
+P_TMP_ATTACK_MOD	props/P_TMP_ATTACK_MOD
+P_LEP	props/P_LEP
+P_TMP_DEFEND_HOOK	props/P_TMP_DEFEND_HOOK
+P_TMP_DIE_HOOK	props/P_TMP_DIE_HOOK
+P_DEFENDERS	props/P_DEFENDERS
+P_SKILL_ATTRIBUTES	props/P_SKILL_ATTRIBUTES
+P_IGNORE	props/P_IGNORE
+P_LAST_COMMAND_ENV	props/P_LAST_COMMAND_ENV
+P_HISTMIN	props/P_HISTMIN
+P_SHOW_ALIAS_PROCESSING	props/P_SHOW_ALIAS_PROCESSING
+P_DEFAULT_NOTIFY_FAIL	props/P_DEFAULT_NOTIFY_FAIL
+P_NETDEAD_INFO	props/P_NETDEAD_INFO
+P_IP_NAME	props/P_IP_NAME
+P_AUTH_INFO	props/P_AUTH_INFO
+P_LAST_KILLER	props/P_LAST_KILLER
+P_ACTUAL_NOTIFY_FAIL	props/P_ACTUAL_NOTIFY_FAIL
+P_LEP_MALUS	props/P_LEP_MALUS
+P_LAST_LOGIN	props/P_LAST_LOGIN
+P_LAST_LOGOUT	props/P_LAST_LOGOUT
+P_SHOW_EXITS	props/P_SHOW_EXITS
+P_WANTS_TO_LEARN	props/P_WANTS_TO_LEARN
+P_AUTOLOADOBJ	props/P_AUTOLOADOBJ
+P_TTY	props/P_TTY
+P_AUTOLOAD	props/P_AUTOLOAD
+P_MAILADDR	props/P_MAILADDR
+P_HOMEPAGE	props/P_HOMEPAGE
+P_FOLLOW_SILENT	props/P_FOLLOW_SILENT
+P_SECOND	props/P_SECOND
+P_TESTPLAYER	props/P_TESTPLAYER
+P_START_HOME	props/P_START_HOME
+P_CMSG	props/P_CMSG
+P_DMSG	props/P_DMSG
+P_CLONE_MSG	props/P_CLONE_MSG
+P_DESTRUCT_MSG	props/P_DESTRUCT_MSG
+P_CARRIED_VALUE	props/P_CARRIED_VALUE
+P_PROMPT	props/P_PROMPT
+P_SCREENSIZE	props/P_SCREENSIZE
+P_FLAGS	props/P_FLAGS
+P_CAN_FLAGS	props/P_CAN_FLAGS
+P_READ_NEWS	props/P_READ_NEWS
+P_NEEDED_QP	props/P_NEEDED_QP
+P_INTERMUD	props/P_INTERMUD
+P_BUFFER	props/P_BUFFER
+P_DEAF	props/P_DEAF
+P_PERM_STRING	props/P_PERM_STRING
+P_EXTRA_LOOK	props/P_EXTRA_LOOK
+P_PRESAY	props/P_PRESAY
+P_TITLE	props/P_TITLE
+P_AVERAGE_SIZE	props/P_AVERAGE_SIZE
+P_REFERENCE_OBJECT	props/P_REFERENCE_OBJECT
+P_MSGIN	props/P_MSGIN
+P_MSGOUT	props/P_MSGOUT
+P_MMSGIN	props/P_MMSGIN
+P_MMSGOUT	props/P_MMSGOUT
+P_POTIONROOMS	props/P_POTIONROOMS
+P_TRANK_FINDEN	props/P_TRANK_FINDEN
+P_VISITED_POTIONROOMS	props/P_VISITED_POTIONROOMS
+P_BONUS_POTIONS	props/P_BONUS_POTIONS
+P_QUESTS	props/P_QUESTS
+P_QP	props/P_QP
+P_SKILLS	props/P_SKILLS
+P_BLIND	props/P_BLIND
+P_BRIEF	props/P_BRIEF
+P_ORIG_NAME	props/P_ORIG_NAME
+P_KILLER	props/P_KILLER
+P_MURDER_MSG	props/P_MURDER_MSG
+P_KILL_MSG	props/P_KILL_MSG
+P_KILL_NAME	props/P_KILL_NAME
+P_CORPSE	props/P_CORPSE
+P_ENEMY_DEATH_SEQUENCE	props/P_ENEMY_DEATH_SEQUENCE
+P_LIGHT	props/P_LIGHT
+P_CLONER	props/P_CLONER
+P_TOTAL_LIGHT	props/P_TOTAL_LIGHT
+P_LAST_CONTENT_CHANGE	props/P_LAST_CONTENT_CHANGE
+P_VALUE	props/P_VALUE
+P_FORCE_DEMONST	props/P_FORCE_DEMONST
+P_INFO	props/P_INFO
+P_READ_MSG	props/P_READ_MSG
+P_FW_ALWAYS_READABLE	props/P_FW_ALWAYS_READABLE
+P_NOBUY	props/P_NOBUY
+P_NEVERDROP	props/P_NEVERDROP
+P_MAGIC	props/P_MAGIC
+P_WEIGHT_PERCENT	props/P_WEIGHT_PERCENT
+P_DETAILS	props/P_DETAILS
+P_SPECIAL_DETAILS	props/P_SPECIAL_DETAILS
+P_READ_DETAILS	props/P_READ_DETAILS
+P_EXITS	props/P_EXITS
+P_SPECIAL_EXITS	props/P_SPECIAL_EXITS
+P_DOORS	props/P_DOORS
+P_DOORS2	props/P_DOORS2
+P_ITEMS	props/P_ITEMS
+P_NO_TPORT	props/P_NO_TPORT
+P_TPORT_COST_IN	props/P_TPORT_COST_IN
+P_TPORT_COST_OUT	props/P_TPORT_COST_OUT
+P_INDOORS	props/P_INDOORS
+P_NOMAGIC	props/P_NOMAGIC
+P_ORAKEL	props/P_ORAKEL
+P_RACE	props/P_RACE
+P_TOTAL_WC	props/P_TOTAL_WC
+P_ZAP_MSG	props/P_ZAP_MSG
+P_AWAY	props/P_AWAY
+P_WEAPON	props/P_WEAPON
+P_ARMOURS	props/P_ARMOURS
+P_NPC	props/P_NPC
+P_WIMPY	props/P_WIMPY
+P_WIMPY_DIRECTION	props/P_WIMPY_DIRECTION
+P_HEAL	props/P_HEAL
+P_HB	props/P_HB
+P_POISON	props/P_POISON
+P_MAX_POISON	props/P_MAX_POISON
+P_DISABLE_ATTACK	props/P_DISABLE_ATTACK
+P_DIE_MSG	props/P_DIE_MSG
+P_KILLS	props/P_KILLS
+P_CALLED_FROM_IP	props/P_CALLED_FROM_IP
+P_DESCRIPTION	props/P_DESCRIPTION
+P_GUILD	props/P_GUILD
+P_LEVEL	props/P_LEVEL
+P_CAP_NAME	props/P_CAP_NAME
+P_EARMUFFS	props/P_EARMUFFS
+P_MARRIED	props/P_MARRIED
+P_AMOUNT	props/P_AMOUNT
+P_VALUE_PER_UNIT	props/P_VALUE_PER_UNIT
+P_WEIGHT_PER_UNIT	props/P_WEIGHT_PER_UNIT
+P_FUEL	props/P_FUEL
+P_LIGHTDESC	props/P_LIGHTDESC
+P_DO_DESTRUCT	props/P_DO_DESTRUCT
+P_LIGHTED	props/P_LIGHTED
+P_CHATS	props/P_CHATS
+P_CHAT_CHANCE	props/P_CHAT_CHANCE
+P_ACHATS	props/P_ACHATS
+P_ACHAT_CHANCE	props/P_ACHAT_CHANCE
+P_BODY	props/P_BODY
+P_AGGRESSIVE	props/P_AGGRESSIVE
+P_NOCORPSE	props/P_NOCORPSE
+P_REJECT	props/P_REJECT
+P_RACE_DESCRIPTION	props/P_RACE_DESCRIPTION
+P_RACESTRING	props/P_RACESTRING
+P_CONTAINER	props/P_CONTAINER
+P_FW_UNDERSTAND	props/P_FW_UNDERSTAND
+P_TRAY	props/P_TRAY
+P_DEFAULT_INFO	props/P_DEFAULT_INFO
+P_LOG_INFO	props/P_LOG_INFO
+P_PURSUERS	props/P_PURSUERS
+P_HP_HOOKS	props/P_HP_HOOKS
+P_GIVEN_AMOUNT	props/P_GIVEN_AMOUNT
+P_GIVEN_OBJECT	props/P_GIVEN_OBJECT
+P_CURSED	props/P_CURSED
+P_KEEP_ON_SELL	props/P_KEEP_ON_SELL
+P_SPELLS	props/P_SPELLS
+P_SPELLRATE	props/P_SPELLRATE
+P_INFORMME	props/P_INFORMME
+P_WAITFOR	props/P_WAITFOR
+P_LOCALCMDS	props/P_LOCALCMDS
+P_CLOCKMSG	props/P_CLOCKMSG
+P_PARA	props/P_PARA
+P_SIZE	props/P_SIZE
+P_INT_SHORT	props/P_INT_SHORT
+P_INT_LONG	props/P_INT_LONG
+P_ROOM_MSG	props/P_ROOM_MSG
+P_FUNC_MSG	props/P_FUNC_MSG
+P_MSG_PROB	props/P_MSG_PROB
+P_HAUS_ERLAUBT	props/P_HAUS_ERLAUBT
+P_SENSITIVE_INVENTORY	props/P_SENSITIVE_INVENTORY
+P_SENSITIVE_INVENTORY_TRIGGER	props/P_SENSITIVE_INVENTORY_TRIGGER
+P_SENSITIVE_ATTACK	props/P_SENSITIVE_ATTACK
+P_CURRENTDIR	props/P_CURRENTDIR
+P_SHORT_CWD	props/P_SHORT_CWD
+P_SNOOPFLAGS	props/P_SNOOPFLAGS
+P_COMMANDS	props/P_COMMANDS
+P_NAME	props/P_NAME
+P_NAME_ADJ	props/P_NAME_ADJ
+P_SHORT	props/P_SHORT
+P_LONG	props/P_LONG
+P_IDS	props/P_IDS
+P_ADJECTIVES	props/P_ADJECTIVES
+P_SHOW_INV	props/P_SHOW_INV
+P_CLASS	props/P_CLASS
+P_NODROP	props/P_NODROP
+P_NOGET	props/P_NOGET
+P_SENSITIVE	props/P_SENSITIVE
+P_UID	props/P_UID
+P_EUID	props/P_EUID
+P_WEIGHT	props/P_WEIGHT
+P_TOTAL_WEIGHT	props/P_TOTAL_WEIGHT
+P_ENTERMSG	props/P_ENTERMSG
+P_LEAVEMSG	props/P_LEAVEMSG
+P_LEAVEFAIL	props/P_LEAVEFAIL
+P_ENTERFAIL	props/P_ENTERFAIL
+P_ARRIVEMSG	props/P_ARRIVEMSG
+P_DEPARTMSG	props/P_DEPARTMSG
+P_ENTERCMDS	props/P_ENTERCMDS
+P_LEAVECMDS	props/P_LEAVECMDS
+P_MAX_PASSENGERS	props/P_MAX_PASSENGERS
+P_STD_OBJECT	props/P_STD_OBJECT
+P_COMPILER_PATH	props/P_COMPILER_PATH
+P_NR_HANDS	props/P_NR_HANDS
+P_WC	props/P_WC
+P_WEAPON_TYPE	props/P_WEAPON_TYPE
+P_DAM_TYPE	props/P_DAM_TYPE
+P_WIELDED	props/P_WIELDED
+P_HIT_FUNC	props/P_HIT_FUNC
+P_WIELD_FUNC	props/P_WIELD_FUNC
+P_UNWIELD_FUNC	props/P_UNWIELD_FUNC
+P_HIDE_EXITS.res	props/P_HIDE_EXITS.res
+P_FRIEND	props/P_FRIEND
+P_DAM_DESC	props/P_DAM_DESC
+P_QUALITY	props/P_QUALITY
+P_ALCOHOL_DELAY	props/P_ALCOHOL_DELAY
+P_DRINK_DELAY	props/P_DRINK_DELAY
+P_FOOD_DELAY	props/P_FOOD_DELAY
+P_HP_DELAY	props/P_HP_DELAY
+P_SP_DELAY	props/P_SP_DELAY
+P_POISON_DELAY	props/P_POISON_DELAY
+P_MATERIAL	props/P_MATERIAL
+obj	obj
+doormaster	obj/doormaster
+REGELN	REGELN
+README	REGELN/README
+zweities	REGELN/zweities
+Scripte	REGELN/Scripte
+balance	REGELN/balance
+npcs	REGELN/npcs
+waffen	REGELN/waffen
+ruestungen	REGELN/ruestungen
+properties.h	properties.h
+g.abenteurer	g.abenteurer
+ausweichen	g.abenteurer/ausweichen
+feuerball	g.abenteurer/feuerball
+identifiziere	g.abenteurer/identifiziere
+kampfschrei	g.abenteurer/kampfschrei
+licht	g.abenteurer/licht
+pfeil	g.abenteurer/pfeil
+schaetz	g.abenteurer/schaetz
+schnell	g.abenteurer/schnell
+g.bierschuettler	g.bierschuettler
+abstufungen	g.bierschuettler/abstufungen
+alkoholgift	g.bierschuettler/alkoholgift
+beliefere	g.bierschuettler/beliefere
+beobachte	g.bierschuettler/beobachte
+beruhige	g.bierschuettler/beruhige
+bierschuerze	g.bierschuettler/bierschuerze
+blubber	g.bierschuettler/blubber
+erdbeben	g.bierschuettler/erdbeben
+fliesse	g.bierschuettler/fliesse
+floesse	g.bierschuettler/floesse
+freibier	g.bierschuettler/freibier
+haarwuchs	g.bierschuettler/haarwuchs
+hitzeschlag	g.bierschuettler/hitzeschlag
+licht	g.bierschuettler/licht
+massiere	g.bierschuettler/massiere
+nebel	g.bierschuettler/nebel
+nuechtern	g.bierschuettler/nuechtern
+party	g.bierschuettler/party
+rkaufe	g.bierschuettler/rkaufe
+sand	g.bierschuettler/sand
+schimmer	g.bierschuettler/schimmer
+schuettele	g.bierschuettler/schuettele
+schuettelstarre	g.bierschuettler/schuettelstarre
+zaubersprueche	g.bierschuettler/zaubersprueche
+g.karate	g.karate
+abwehr	g.karate/abwehr
+angriff	g.karate/angriff
+konzentration	g.karate/konzentration
+g.klerus	g.klerus
+beistand	g.klerus/beistand
+bete	g.klerus/bete
+blitz	g.klerus/blitz
+donner	g.klerus/donner
+elementarschild	g.klerus/elementarschild
+elementarsphaere	g.klerus/elementarsphaere
+entfluche	g.klerus/entfluche
+entfrosche	g.klerus/entfrosche
+entgifte	g.klerus/entgifte
+heile	g.klerus/heile
+heiligenschein	g.klerus/heiligenschein
+heiltrank	g.klerus/heiltrank
+identifiziere	g.klerus/identifiziere
+kuriere	g.klerus/kuriere
+laeutere	g.klerus/laeutere
+lebenskraft	g.klerus/lebenskraft
+leuchten	g.klerus/leuchten
+messerkreis	g.klerus/messerkreis
+regeneriere	g.klerus/regeneriere
+schaetz	g.klerus/schaetz
+schutzhand	g.klerus/schutzhand
+segne	g.klerus/segne
+sonnenschutz	g.klerus/sonnenschutz
+spaltung	g.klerus/spaltung
+traue	g.klerus/traue
+weihe	g.klerus/weihe
+wunder	g.klerus/wunder
+g.chaos	g.chaos
+g.zauberer	g.zauberer
+old.applied	old.applied
+applied	old.applied/applied
+remove	old.applied/remove
+logon	old.applied/logon
+modify_command	old.applied/modify_command
+query_level	old.applied/query_level
+catch_tell	old.applied/catch_tell
+clean_up	old.applied/clean_up
+create	old.applied/create
+heart_beat	old.applied/heart_beat
+init	old.applied/init
+reset	old.applied/reset
+__INIT	old.applied/__INIT
+parse_command_id_list	old.applied/parse_command_id_list
+parse_command_adjectiv_id_list	old.applied/parse_command_adjectiv_id_list
+parse_command_plural_id_list	old.applied/parse_command_plural_id_list
+catch_msg	old.applied/catch_msg
+add_weight	old.applied/add_weight
+query_real_name	old.applied/query_real_name
+exit	old.applied/exit
+query_weight	old.applied/query_weight
+drop	old.applied/drop
+get	old.applied/get
+id.old	old.applied/id.old
+can_put_and_get	old.applied/can_put_and_get
+prevent_insert	old.applied/prevent_insert
+hilfe.magier	hilfe.magier
+hilfe.seher	hilfe.seher
+hilfe.spieler	hilfe.spieler
+mcmd	mcmd
+addmaster	mcmd/addmaster
+at	mcmd/at
+banish	mcmd/banish
+cat	mcmd/cat
+cd	mcmd/cd
+clone	mcmd/clone
+cp	mcmd/cp
+destruct	mcmd/destruct
+do	mcmd/do
+echoall	mcmd/echoall
+echoto	mcmd/echoto
+ed	mcmd/ed
+exec	mcmd/exec
+frieden	mcmd/frieden
+goto	mcmd/goto
+grep	mcmd/grep
+head	mcmd/head
+heile	mcmd/heile
+home	mcmd/home
+in	mcmd/in
+invis	mcmd/invis
+load	mcmd/load
+localcmd	mcmd/localcmd
+ls	mcmd/ls
+man	mcmd/man
+mbanish	mcmd/mbanish
+mecho	mcmd/mecho
+mkdir	mcmd/mkdir
+more	mcmd/more
+mschau	mcmd/mschau
+mv	mcmd/mv
+oropax	mcmd/oropax
+people	mcmd/people
+ping	mcmd/ping
+prompt	mcmd/prompt
+protect	mcmd/protect
+pwd	mcmd/pwd
+pwho	mcmd/pwho
+removemaster	mcmd/removemaster
+rm	mcmd/rm
+rmdir	mcmd/rmdir
+sallow	mcmd/sallow
+set	mcmd/set
+setcmsg	mcmd/setcmsg
+setdmsg	mcmd/setdmsg
+showpresay	mcmd/showpresay
+shutdown	mcmd/shutdown
+snoop	mcmd/snoop
+tail	mcmd/tail
+traenke	mcmd/traenke
+trans	mcmd/trans
+udpq	mcmd/udpq
+upd	mcmd/upd
+update	mcmd/update
+verfolge	mcmd/verfolge
+vis	mcmd/vis
+zap	mcmd/zap
+zwinge	mcmd/zwinge
+pcmd	pcmd
+adverb	pcmd/adverb
+alias	pcmd/alias
+antworte	pcmd/antworte
+ausgaenge	pcmd/ausgaenge
+behalte	pcmd/behalte
+ebenen	pcmd/ebenen
+email	pcmd/email
+emote	pcmd/emote
+ende	pcmd/ende
+entgifte	pcmd/entgifte
+ersetzungsanzeige	pcmd/ersetzungsanzeige
+erwarte	pcmd/erwarte
+erwidere	pcmd/erwidere
+fehler	pcmd/fehler
+finger	pcmd/finger
+fluestere	pcmd/fluestere
+frage	pcmd/frage
+gespraech	pcmd/gespraech
+gib	pcmd/gib
+hilfe	pcmd/hilfe
+history	pcmd/history
+hole	pcmd/hole
+idee	pcmd/idee
+ignoriere	pcmd/ignoriere
+info	pcmd/info
+inform	pcmd/inform
+inventur	pcmd/inventur
+kkwer	pcmd/kkwer
+klettere	pcmd/klettere
+kobold	pcmd/kobold
+kurz	pcmd/kurz
+kwer	pcmd/kwer
+lang	pcmd/lang
+mrufe	pcmd/mrufe
+muds	pcmd/muds
+nimm	pcmd/nimm
+passwort	pcmd/passwort
+rknuddle	pcmd/rknuddle
+rufe	pcmd/rufe
+rwinke	pcmd/rwinke
+sage	pcmd/sage
+schau	pcmd/schau
+schlafe	pcmd/schlafe
+selbstloeschung	pcmd/selbstloeschung
+speichern	pcmd/speichern
+spielpause	pcmd/spielpause
+stecke	pcmd/stecke
+stop	pcmd/stop
+stty	pcmd/stty
+teile	pcmd/teile
+toete	pcmd/toete
+trage	pcmd/trage
+typo	pcmd/typo
+uhrmeldung	pcmd/uhrmeldung
+ultrakurz	pcmd/ultrakurz
+unalias	pcmd/unalias
+url	pcmd/url
+verben	pcmd/verben
+vorsicht	pcmd/vorsicht
+weg	pcmd/weg
+wer	pcmd/wer
+wirf	pcmd/wirf
+zeilen	pcmd/zeilen
+zeit	pcmd/zeit
+ziehe	pcmd/ziehe
+zuecke	pcmd/zuecke
+entgifte.deaktiviert	pcmd/entgifte.deaktiviert
+README	README
+scmd	scmd
+aendere	scmd/aendere
+ausgang	scmd/ausgang
+befehl	scmd/befehl
+beschreibe	scmd/beschreibe
+echo	scmd/echo
+erlaube	scmd/erlaube
+extralook	scmd/extralook
+fehlermeldung	scmd/fehlermeldung
+fluchtrichtung	scmd/fluchtrichtung
+hausbau	scmd/hausbau
+instanthaus	scmd/instanthaus
+kopiere	scmd/kopiere
+licht	scmd/licht
+loesche	scmd/loesche
+meldungen	scmd/meldungen
+notiz	scmd/notiz
+presay	scmd/presay
+remote	scmd/remote
+review	scmd/review
+schiebe	scmd/schiebe
+seherhaus	scmd/seherhaus
+sethands	scmd/sethands
+setmin	scmd/setmin
+setmmin	scmd/setmmin
+setmmout	scmd/setmmout
+setmout	scmd/setmout
+sperre	scmd/sperre
+spion	scmd/spion
+titel	scmd/titel
+uebersicht	scmd/uebersicht
+verbiete	scmd/verbiete
+werfe	scmd/werfe
+wiz	wiz
+balance	wiz/balance
+forscherpunkte	wiz/forscherpunkte
+testspieler	wiz/testspieler
+zweitspieler	wiz/zweitspieler
+lupe	wiz/lupe
+knete	wiz/knete
+material	wiz/material
+materialliste	wiz/materialliste
+regionsmagier	wiz/regionsmagier
+materialgruppen	wiz/materialgruppen
+materialerkennung	wiz/materialerkennung
+materialdb	wiz/materialdb
diff --git a/doc/.propdesc b/doc/.propdesc
new file mode 100644
index 0000000..6360535
--- /dev/null
+++ b/doc/.propdesc
@@ -0,0 +1,1033 @@
+P_LIGHT
+// Greift auf den Lichtlevel zu. Handle with care !!!
+
+P_NAME
+// In dieser Property wird der Name des Objektes gespeichert. Er
+// sollte nur aus einem Wort bestehen. Der Name dient dazu, das
+// Objekt in einem Satz zu erwaehnen und wird auch dekliniert.
+
+P_NAME_ADJ
+// In dieser Property kann ein Adjektiv abgelegt werden, dass dann
+// bei der Ausgabe mittels name() mitbenutzt wird.
+// (In der Regel nicht noetig.)
+
+P_SHORT
+// In dieser Property wird die Kurzbeschreibung des Objektes
+// gespeichert, die beim Umschauen im Raum oder bei der Ausgabe
+// des Inventars ausgegeben wird. Fuer unsichtbare Objekte
+// sollte sie 0 sein.
+
+P_LONG
+// Unter dieser Property wird die Beschreibung gespeichert, die
+// bei der Untersuchung des Objektes ausgegeben wird.
+
+P_WEIGHT
+// Das Gewicht eines Objetes in Gramm.
+
+P_VALUE
+// Wert des Objektes in Goldmuenzen. Diesen Wert erhaelt man beim
+// Verkauf. Kaufen kostet ein Vielfaches hiervon.
+
+P_IDS
+// Hier werden die Bezeichnungen abgespeichert, unter denen sich das
+// Objekt angesprochen fuehlt.
+// Sollte nur mittels AddId( id ); gesetzt werden.
+
+P_ADJECTIVES
+// Hier werden Adjektive gespeichert, unter denen sich das Objekt
+// angesprochen fuehlt. So sind Kombinationen der Synonyme mit
+// mehreren Adjektiven moeglich. Ggf sollte auch der deklinierte
+// Fall des Adjektives eingegeben werden.
+// Sollte nur mittels AddAdjective( adjective ); gesetzt werden.
+
+P_INFO
+// Geheime Information, die ggf. ueber einen Zauberspruch
+// von Spielern ermittelt werden kann.
+
+P_READ_MSG
+// Hier koennen Informationen gespeichert werden, die beim Lesen
+// des Objektes ausgegeben werden.
+
+P_UID
+// Simulation des Zugriffs auf die uid.
+
+P_EUID
+// Simulation des Zugriffs auf die euid.
+
+P_AUTOLOADOBJ
+// Mit dieser Property werden Autoloadobjekte verwaltet.
+// Der Inhalt der Property sind die permanenten Eigenschaften des
+// Objektes, die der Spieler uebers ausloggen hinweg beibehaelt.
+// Beim Einloggen werden sie automatisch neu gesetzt. (ACHTUNG:
+// Die Property muss intern selbst verwaltet werden.)
+// Autoloadobjekte werden beim Ausloggen nicht fallengelassen!
+
+P_NOGET
+// Diese Property enthaelt eine Meldung, die ausgegeben wird, wenn
+// jemand versucht, dieses Objekt zu nehmen. Wird die Prop. auf einen
+// nicht-String-Wert gesetzt, so wird eine Defaultmeldung ausgegeben.
+
+P_NODROP
+// Diese Property enthaelt eine Meldung, die ausgegeben wird, wenn
+// jemand versucht, das Objekt fallen zu lassen. Wird die Prop.  auf einen
+// nicht-String-Wert gesetzt, so wird eine Defaultmeldung ausgegeben.
+
+P_NOBUY
+// Wenn diese Property gesetzt ist, wird das Objekt nach einem
+// Verkauf im Laden zerstoert, damit es nicht wieder von einem Spieler
+// gekauft werden kann.
+
+P_NEVERDROP
+// Objekte mit dieser Property werden beim Tod des Spielers nicht
+// in den Leichnam gelegt.
+// P_NODROP wird automatisch mitgesetzt.
+
+P_NR_HANDS
+// Anzahl der Haende, die man zur Benuztung des Objektes benoetigt.
+
+P_MAGIC
+// Dieses Objekt ist magisch.
+
+P_MAX_WEIGHT
+// Maximales Gewicht in Gramm, das in dem Container verstaut werden
+// kann.
+
+P_TOTAL_WEIGHT
+// Gewicht incl. Inhalt in Gramm. P_WEIGHT_PERCENT wird beruecksichtigt.
+
+P_TRANSPARENT
+// ist != 0, wenn hinein oder hinausgeschaut werden kann.
+
+P_CNT_STATUS
+// Status des Containers (offen, geschlossen, abgeschlossen)
+// siehe auch /sys/container.h
+
+P_WEIGHT_PERCENT
+// Diese Property gibt an, wieviel Prozent des Gewichts des Inhaltes
+// "nach aussen" wiedergegeben werden.
+
+P_INT_SHORT
+// Kurzbeschreibung, wenn man sich im Inneren des Containers
+// befindet.
+
+P_INT_LONG
+// Beschreibung, die man bekommt, wenn man sich in dem Container
+// umschaut.
+
+P_DETAILS
+// Diese Property enthaelt ein mapping, in der Objekte im Raum
+// definiert werden und Beschreibungen, die ausgegeben werden,
+// wenn man sich diese Details anschaut.
+
+P_SPECIAL_DETAILS
+// Mapping von Details, die beim Anschauen eine Funktion starten.
+
+P_READ_DETAILS
+// Details, die durch Lesen ermittelt werden koennen.
+
+P_ROOM_MSG
+// Liste mit Meldungen, die zufaellig im Raum ausgegeben werden.
+
+P_FUNC_MSG
+// Liste mit Funktionen, die zufaellig im Raum aufgerufen werden.
+
+P_MSG_PROB
+// Numerischer Wert fuer Wahrscheinlichkeit, mit der die Meldungen
+// und/oder die Funktionen ausgegeben/aufgerufen werden.
+
+P_EXITS
+// Mapping aller unmittelbar sichtbaren Ausgaenge mit zugehoerigen
+// Nachbarraeumen. Sollte nur mittels AddExit() benutzt werden.
+
+P_SPECIAL_EXITS
+// Dito, aber anstatt des Nachbarraums wird eine Funktion (im Raum)
+// angegebem, die bei Eingabe der Richtung ausgefuehrt wird.
+
+P_DOORS
+// *** OBSOLET! ***
+// Siehe P_DOOR_INFOS
+
+P_COMMANDS
+// Mapping von Kommandos, die im Objekt definiert sind.
+// Sollte nur mittels AddCmd() benutzt werden.
+
+P_ITEMS
+// Definition von Gegenstaenden, die in dem Raum liegen sollen.
+// Erklaerung in einem Extrafile.
+
+P_NO_TPORT
+// Kann folgende Werte annnehmen (definiert in moving.h):
+// NO_TPORT_IN	= Man kann nicht in den Raum hinein teleportieren.
+// NO_TPORT_OUT = Man kann nicht aus dem Raum hinaus teleportieren.
+// NO_TPORT	= Weder noch.
+
+P_INDOORS
+// Gesetzt, wenn von dem Raum aus der Himmel nicht sichtbar ist.
+// Dinge wie Wetter oder Mondaufgaenge werden in solchen Raeumen
+// nicht gezeigt.
+// Ausserdem
+
+P_NOMAGIC
+// Angabe in Prozent, mit welcher Wahrscheinlichkeit in einem
+// Raum nicht gezaubert werden kann. Bei NPC's zeigt es die
+// Resistenz gegen Magie an.
+// (Noch nicht implementiert)
+
+P_ORAKEL
+// Wenn diese Property gesetzt ist, kann der Wanderer in diesen
+// Raum hinein.
+
+P_ALIGN
+// Numerischer Wert fuer Gut- oder Boesheit des Wesens.
+
+P_RACE
+// String mit der Rasse des Wesens.
+
+P_GENDER
+// Grammatikalisches Geschlecht des Objektes:
+// (Definiert in language.h) MALE, FEMALE oder NEUTER
+
+P_ATTRIBUTES
+// Mapping mit den Attributen des Wesens.
+
+P_FOOD
+// Numerischer Wert fuer Saettigungsgrad des Wesens.
+
+P_DRINK
+// Numerischer Wert fuer Saettigung des Wesens mit Getraenken.
+
+P_ALCOHOL
+// Num. Wert fuer Besoffenheit.
+
+P_MAX_FOOD
+// Numerischer Wert fuer die maximale Saettigung des Wesens.
+
+P_MAX_DRINK
+// Numerischer Wert fuer die maximale 'Wassermenge' im Wesen.
+
+P_MAX_ALCOHOL
+// Numerischer Wert fuer die Alkoholvertraeglichkeit des Wesens.
+
+P_HP
+// Anzahl der Lebenspunkte des Wesens.
+
+P_SP
+// Anzahl der Magiepunkte des Wesens.
+
+P_MAX_HP
+// Maximale Anzahl der Lebenspunkte.
+
+P_MAX_SP
+// Maximale Anzahl der Magiepunkte.
+
+P_XP
+// Anzahl der Erfahrungspunkte.
+
+P_TOTAL_AC
+// Numerischer Wert der Abwehrstaerke des Wesens.
+
+P_TOTAL_WC
+// Numerischer Wert der Angriffsstaerke des Wesens.
+
+P_MSGIN
+// String mit der Meldung, die beim Verlassen eines Raumes mit M_GO
+// an die uebrigen Anwesenden ausgegeben wird.
+
+P_MSGOUT
+// String mit der Meldung, die beim Betreten eines Raumes mit M_GO
+// an die uebrigen Anwesenden ausgegeben wird.
+
+P_MMSGIN
+// String mit der Meldung, die beim Verlassen eines Raumes mit M_TPORT
+// an die uebrigen Anwesenden ausgegeben wird.
+
+P_MMSGOUT
+// String mit der Meldung, die beim Betreten eines Raumes mit M_TPORT
+// an die uebrigen Anwesenden ausgegeben wird.
+
+P_TITLE
+// Titel des Spielers. Erscheint hinter dem Namen in Kurz/Langbeschreibung.
+
+P_PRESAY
+// Presay des Spielers. Erscheint vor dem Namen in Kurz/Langbeschreibung.
+// Erscheint auch in name(), also in sag, ruf, teile mit usw.
+
+P_ZAP_MSG
+// Dreielementiges Array:
+// 1.) Meldung, die der Magier beim Zappen bekommt.
+// 2.) Meldung, die die Spieler im Raum beim Zappen bekommen.
+// 3.) Meldung, die das Opfer beim Zappen bekommt.
+// Mit @@wer@@, @@wessen@@, ... kann der Name des Opfers und mit
+// @@ich@@ der Name des Magiers in die Meldung eingewebt werden.
+
+P_TRANK_FINDEN
+// Wenn die Property auf 1 steht kann immer ein Zaubertrank gefunden
+// werden, auch wenn er nicht in der Liste des Spielers steht.
+
+P_AWAY
+// String der ausgegeben wird, wenn man weg ist und eine Mitteilung bekommt.
+
+P_IGNORE
+// Array der Spieler, deren Mitteilungen ignoriert werden.
+
+P_WEAPON
+// Momentan gezueckte Waffe.
+
+P_COMBATCMDS
+// Fuer den Kampf gebrauchbare Befehle spezieller Objekte (damit auch
+// Monster sie automatisch richtig anwenden koennen)
+// Der Inhalt von P_COMBATCMDS ist ein Mapping, der Key ist das Kommando,
+// um den Gegenstand zu benutzen (also z.B. "wirf flammenkugel"), und der
+// Value ein weiteres Mapping mit Zusatzinfos (definiert in /sys/combat.h).
+// Folgende Keys sind definiert:
+// - C_MIN, C_AVG, C_MAX:
+//   minimaler, mittlerer und maximaler Schaden, den das
+//   Objekt macht. Alle Angaben in LEBENSPUNKTEN, d.h. Defend-Einheiten/10.
+//   Bei einem Aufruf wie 'enemy->Defend(200+random(200), ...)' ist dann
+//   C_MIN=20, C_AVG=30, C_MAX=40.
+// - C_DTYPES:
+//   Array mit dem Schadenstyp oder den Schadenstypen. Beim Eisstab
+//   wuerde der Eintrag dann 'C_DTYPES:({DT_COLD})' lauten.
+// - C_HEAL:
+//   Sollte das Kampfobjekt ueber die Moeglichkeit verfuegen, den Anwender
+//   irgendwie zu heilen, so wird hier die Heilung in LP/MP eingetragen.
+//   Das funktioniert auch bei Objekten, die nur heilen, also sonst
+//   nichts mit Kampf zu tun haben.
+//   Im Lupinental z.B. gibt es Pfirsiche, die beim Essen 5LP heilen. Da
+//   kann man dann 'SetProp(P_COMBATCMDS, (["iss pfirsich":([C_HEAL:5])]))'
+//   eintragen.
+// Es sind auch mehrere Kommandos moeglich, z.B. bei Objekten, die sowohl
+// heilen als auch Kampfwirkung haben.
+
+P_ARMOURS
+// Liste der getragenen Schutzbekleidungen.
+
+P_HANDS
+// 3-elem. Array
+// 1. Elem.: String mit der Meldung, wenn ohne Waffen angegriffen wird.
+// 2. Elem.: Weaponclass, wenn ohne Waffen angegriffen wird.
+// 3. Elem.: Angriffs-typ, default ist DT_BLUDGEON
+
+P_RESISTANCE
+// Array mit Angriffsarten, gegen die das Lebewesen teilweise
+// resistent ist.
+
+P_VULNERABILITY
+// Array mit Angriffsarten, gegen die das Lebewesen empfindlich
+// ist.
+
+P_RESISTANCE_STRENGTHS
+// Mapping mit Schadensfaktoren minus 1.0 fuer jeden Schadenstyp
+// -0.5 entspricht also Resistance (Faktor 0.5)
+// 1.0 entspricht also Vulnerability (Faktor 2.0)
+
+P_MAX_HANDS
+// Anzahl der Haende, die ein Wesen hat.
+
+P_USED_HANDS
+// Anzahl der Haende in Benutztung
+
+P_ABILITIES
+// *** OBSOLET! ***
+// Siehe P_NEWSKILLS.
+
+P_ENEMY_DAMAGE
+// Gibt eine Kopie des Mappings zurueck, in dem vermerkt wird, wer
+// diesem Lebewesen welchen Schaden zugefuegt hat.
+
+P_NPC
+// Gesetzt bei Monstern.
+
+P_WIMPY
+// Numerischer Wert. Das Wesen flieht, wenn die Lebenspunkte
+// unter diesen Wert sinken.
+
+P_BRIEF
+// Ist gesetzt, wenn der Spieler nur die Kurzbeschreibung sehen will.
+
+P_HEAL
+// Numerischer Wert, der beim Verzehr dieses Objektes zu den
+// Lebenspunkten hinzugezaehlt wird. (kann auch negativ sein)
+// Der Wert sollte zwischen +4 und -4 liegen und bei leichten
+// Monstern 0 sein.
+
+P_DISABLE_ATTACK
+// Das Lebewesen kann nicht angreifen.
+
+P_DIE_MSG
+// String mit der Meldung, die ausgegeben wird, wenn das Wesen stirbt.
+// ist die Property nicht gesetzt, so nehme " faellt tot zu Boden.\n".
+
+P_KILLS
+// Anzahl der Spieler, die dieser Spieler schon getoetet hat.
+// Unerlaubte Manipulation ist ein SCHWERES VERGEHEN gegen
+// die Mudreglen.
+
+P_MAILADDR
+// EMailadresse des Spielers.
+
+P_CALLED_FROM_IP
+// Letzte IP-Adr, von der aus sich der Spieler eingeloggt hat.
+
+P_CURRENTDIR
+// Momentanes Verzeichnis in dem der Spieler ist. (nur fuer
+// Magier von Belang)
+
+P_AUTOLOAD
+// Mapping mit der Menge der Autoloadobjekte und den zugeh.
+// Properties.
+
+P_FROG
+// Gesetzt, wenn der Spieler ein Frosch ist.
+
+P_INVIS
+// Die Property P_INVIS dient dazu, Objekte (insbesondere Magier) als
+// unsichtbar zu kennzeichnen. Man sollte drei Arten von unsichtbaren
+// Objekten unterscheiden:
+// - Gegenstaende
+//   Gegenstaende macht man unsichtbar, indem man in ihnen die Property
+//   P_SHORT auf 0 setzt; will man ein Objekt unsichtbar machen, ohne
+//   seine Kurzbeschreibung zu aendern, kann man aber auch P_INVIS auf
+//   einen Wert ungleich 0 setzen.
+// - NPCs
+//   NPCs macht man ebenfalls unsichtbar, indem man in ihnen die Property
+//   P_SHORT auf 0 setzt. GGf. kann man auch noch die Property P_INVIS auf
+//   1 setzen.
+//   Der Unterschied: Bei gesetztem P_INVIS wird als Name 'Jemand' ver-
+//   wendet, ansonsten der normale Name des NPCs.
+// - Spieler / Magier
+//   Spieler und Magier macht man unsichtbar, indem man ihnen die Property
+//   P_INVIS auf einen Wert <>0 setzt.
+//   Spieler duerfen nicht unsichtbar gemacht werden!			 !
+//   Wird ein Magier unsichtbar gemacht, muss man ihm die Property	 !
+//   P_INVIS auf den Wert setzen, den die Property P_AGE zu diesem	 !
+//   Zeitpunkt hat (keine F_QUERY_METHOD !).				 !
+//   Setzt man die Property auf den Wert 1, so erhaelt ein Spieler,
+//   wenn er den entsp. Magier fingert, die Ausgabe: Alter: 00:00:02,
+//   was genauso verraeterisch ist, wie ein Alter, dass bei einem
+//   scheinbar nicht eingeloggten Magier immer weiter hochgezaehlt
+//   wird.
+
+P_GHOST
+// Gesetzt, wenn der Spieler tot ist.
+
+P_EXTRA_LOOK
+// String, der einen zusaetzlichen Text in der long()-Beschreibung
+// eines Spielers erzeugt.
+
+P_GUILD
+// Gilde, der der Spieler angehoert.
+// Der Name der Gilde ist hier als String definiert. Bei Spielern
+// ist der Wert dieser Property niemals 0 (Defaultmaessig gehoert
+// ein Spieler der Abenteurergilde an).
+
+P_LEVEL
+// Spieler-Level (!= Magierlevel)
+
+P_QUESTS
+// Liste der geloesten Quests.
+
+P_CAP_NAME
+// Name des Spielers, der dekliniert und ausgegen wird.
+// NOT YET IMPLEMENTED.
+
+P_TTY
+// Name der Terminalemulation, die der Spieler nutzt.
+// NOT YET IMPLEMENTED.
+
+P_SHOW_EXITS
+// Gesetzt, wenn der Spieler die offensichtlichen Ausgaenge
+// immer automatisch sehen will.
+
+P_CAN_EMOTE
+// Gesetzt, wenn der Spieler 'emoten' kann.
+
+P_EARMUFFS
+// Shouts von Magiern mit Level < earmuffs werden abgeblockt
+// (Nur fuer Magier)
+
+P_WANTS_TO_LEARN
+// Gesetzt, wenn der Magier die Filenamen sehen will.
+// (Nur fuer Magier). Wird diese Property auf 0 gesetzt, gehen auch
+// einige andere Dinge nicht mehr - verfolge zB. Eigentlich sollten
+// dann auch die Magierbefehle wie "goto" usw unterbunden werden -
+// das kommt vielleicht noch.
+
+P_TESTPLAYER
+// Gesetzt, wenn der Spieler nicht in der Bestenliste auftauchen soll.
+
+P_AGE
+// Alter des Spielers in Heart-Beats (1 HB == 2 Sekunden)
+
+P_BLIND
+// TRUE, wenn der Spieler nichts sehen kann.
+
+P_MARRIED
+// Enthaelt einen String mit der uid des Partners
+// (sofern vorhanden)
+
+P_WC
+// Numerischer Wert fuer die Staerke der Waffe.
+
+P_DAM_TYPE
+// String mit der Art der Verletzung.
+
+P_WEAPON_TYPE
+// Art der Waffe
+
+P_WIELDED
+// Flag ob die Waffe gezueckt ist.
+
+P_AC
+// Numerischer Wert fuer die Abwehrstaerke der Ruestung.
+
+P_ARMOUR_TYPE
+// String fuer Art der Ruestung; welcher Koerperteil wird
+// geschuetzt?
+
+P_WORN
+// Flag, ob die Ruestung im Moment getragen wird. Falls ja,
+// enthaelt die Property das Traegerobjekt.
+
+P_AMOUNT
+// Anzahl der Objekte, fuer die das Objekt steht.
+
+P_VALUE_PER_UNIT
+// Wert in Goldstuecken pro Untereinheit.
+
+P_WEIGHT_PER_UNIT
+// Gewicht in Gramm pro Untereinheit.
+
+P_FUEL
+// Numerischer Wert fuer die Zeitdauer, die die Lichtquelle noch
+// leuchten kann.
+
+P_LIGHTDESC
+// String mit der Bezeichnung des Leuchtvorgangs, den die Licht-
+// quelle ausfuehrt (leuchtend, brennend, gluehend ...)
+
+P_DO_DESTRUCT
+// Flag, ob sich die Lichtquelle am Ende der Leuchtzeit selbst
+// zerstoert. (Oder sogar mit String fuer die Meldung, die bei
+// der Zerstoerung angegeben wird?)
+
+P_LIGHTED
+// Flag, ob die Lichtquelle in Betrieb ist.
+
+P_CHATS
+// Alist mit Strings, die das Monster zufaellig ausgibt.
+
+P_CHAT_CHANCE
+// Wahrscheinlichkeit, mit der die Chats ausgegeben werden.
+
+P_ACHATS
+// Chats, die das Monster im Kampf ausgibt.
+
+P_ACHAT_CHANCE
+// Wahrscheinlichkeit fuer die Attack-Chat-Ausgabe.
+
+P_BODY
+// Numerischer Wert fuer die Abwehrstaerke des blanken Koerpers
+// des Wesens.
+
+P_HB
+// Diese Property wird gesetzt, wenn das Monster immer einen
+// heart_beat haben soll. (VORSICHT, nur wenn es WIRKLICH sein muss!)
+
+P_AGGRESSIVE
+// Gesetzt, wenn das Wesen von sich aus Angriffe startet.
+
+P_NOCORPSE
+// Gesetzt, wenn im Todesfall kein Leichnam erzeugt werden soll.
+
+P_REJECT
+// Ein Array aus 2 Elementen, das bestimmt, das der npc mit Dingen
+// tuen soll, die ihm gegeben werden.
+// Default, der npc behaelt die Dinge einfach.
+// Wenn gesetzt:
+// 1.Element: Art der Handlung. (aus <moving.h>)
+//	REJECT_GIVE: Der NPC gibt das Objekt zurueck.
+//	REJECT_DROP: Der NPC laesst das Objekt fallen.
+//	REJECT_KEEP: Der NPC behaelt das Objekt doch.
+// 2.Arrayelement: Meldung, mit der der NPC die Handlung kommentiert.
+
+P_ENTERMSG
+// Array mit zwei Meldungen, eine fuer den Raum, den der Spieler
+// verlaesst, und eine fuer den Transporter, in den er geht.
+
+P_LEAVEMSG
+// Array mit zwei Meldungen, eine fuer den Transporter, den er verlaesst,
+// und eine fuer den Raum in den er kommt.
+
+P_LEAVEFAIL
+// Meldung an ein Wesen, wenn es ausserhalb der Anlegezeiten den Transporter
+// verlassen will. Ist die Prop. ein Array, so wird das erste Element als
+// meldung an das Wesen, das zweite als Meldung an die Mitspieler im
+// Transporter geschickt.
+
+P_ENTERFAIL
+// Meldung an ein Wesen, wenn den vollen Transporter betreten will.
+// Ist die Prop. ein Array, so wird das erste Element als
+// meldung an das Wesen, das zweite als Meldung an die Mitspieler im
+// Raum geschickt.
+
+P_ARRIVEMSG
+// Meldung, wenn der Transporter anlegt.
+
+P_DEPARTMSG
+// Meldung, mit der ein Transporter ablegt.
+
+P_ENTERCMDS
+// Befehlsliste, die zum Betreten des Transporters fuehrt.
+
+P_LEAVECMDS
+// Befehlsliste, die zum Verlassen des Transporters fuehrt.
+
+P_MAX_PASSENGERS
+// Numerischer Wert fuer die maximale Anzahl von Wesen in dem Transporter.
+// 0 bedeutet unbeschaenkte Spielerzahl.
+
+P_ARTICLE
+// Gibt an, ob in der Beschreibung ein Artikel ausgegeben werden soll
+// oder nicht.
+
+P_LAST_COMMAND_ENV
+// Der Raum, in dem das letzte Kommando eingegeben wurde.
+
+P_NETDEAD_INFO
+// Hier kann ein Raum Informationen in einem Spieler zwischenspeichern, wenn
+// dieser in den Netztotenraum gemoved wird.
+
+P_FOLLOW_SILENT
+// Wenn diese Property 1 ist, wird der MOVE vom verfolge Silent ausge-
+// fuehrt.
+
+P_START_HOME
+// Raum, in dem der Spieler nach dem Einloggen landen soll
+
+P_CARRIED_VALUE
+// Entschaedigung, die der Spieler beim Einloggen erhaelt.
+
+P_PROMPT
+// Das Prompt (Nur fuer Magier).
+
+P_CANECHO
+// Zeigt an, ob der Seher "echo" benutzen kann oder nicht.
+
+P_POTIONROOMS
+// Alist mit den Nummern der Raeume, in denen der Spieler noch Zauber-
+// traenke finden kann.
+
+P_QP
+// Anzahl der Questpunkte, die ein Spieler hat.
+
+P_ENEMY_DEATH_SEQUENCE
+// Wenn man jemanden toetet, wird dieses in seine Todessequenz eingefuegt.
+
+P_CLONER
+// Enthaelt einen String mit dem Namen desjenigen, der das Objekt gecloned hat.
+
+P_RACE_DESCRIPTION
+// Beschreibung der Vor/Nachteile einer Rasse.
+
+P_DOOR_INFOS
+// Hat was mit den Tueren zu tun -> Muss Rochus mal dokumentieren
+
+P_ATTRIBUTES_OFFSETS
+// Mapping mit Offsets, die zu den Attributen addiert werden (koennen auch
+// negativ sein) - zB Rassenboni.
+
+P_DEADS
+// Anzahl der Tode des Spielers seit Einfuehrung dieser Property (irgendwann
+// im Dezember 94)
+
+P_LAST_LOGIN
+// Zeitpunkt des letzen Logins
+
+P_LAST_LOGOUT
+// Zeitpunkt des letzen Logouts
+
+P_SECOND
+// Spieler ist Zweitiea
+
+P_SCREENSIZE
+// Bildschirmgroesse in Zeilen (fuer More)
+
+P_FLAGS
+// Flags des Spielers
+
+P_CAN_FLAGS
+// Flags, ob Spieler echoen/emoten kann
+
+P_NEEDED_QP
+// APs, die man fuer den Seherstatus braucht
+
+P_INTERMUD
+// Obsolet?
+
+P_BUFFER
+// Enthaelt Kobold-Nachrichten
+
+P_CLASS
+// Enthaelt die Klasse (definiert in class.h), zu der ein Objekt gehoert.
+// Sollte nur mit AddClass() gesetzt werden.
+// Das setzen ist nur noetig, wenn die Klasse nicht schon aus den Ids
+// oder (bei Lebewesen) der Rasse ersichtlich ist.
+
+P_CONTENTS
+// *** OBSOLET! ***
+
+P_KILLER
+// ???
+
+P_MURDER_MSG
+// Welche Meldung soll auf dem Moerder-Kanal erscheinen?
+
+P_KILL_MSG
+// Meldung auf dem Todeskanal, wenn jemand von uns geotetet wird
+
+P_CORPSE
+// Welchen Corpse hinterlassen wir?
+
+P_WIMPY_DIRECTION
+// Fluchtrichtung
+
+P_POISON
+// Wie stark wir vergiftet sind (0-11)
+
+P_RACE_DESCRIPTION
+// Rassenbeschreibung, die man bei der Wahl der Rasse abrufen kann
+
+P_DEFAULT_INFO
+// NPC-Info-System: Default-Antwort auf dumme Fragen
+
+P_PURSUERS
+// Enthaelt Verfolger - nicht von Hand manipulieren!
+
+P_HP_HOOKS
+// Welche Objekte sollen bei HP-Aenderungen benachrichtigt werden?
+
+P_CURSED
+// Verfluchte Waffen/Ruestungen kann man nicht ausziehen/wegstecken
+
+P_SPELLS
+// NPC-Spells
+
+P_SPELLRATE
+// NPC-Spellrate (in %)
+
+P_INFORMME
+// Informieren ueber Spieler, die ins Mud kommen/aus dem Mud gehen?
+
+P_WAITFOR
+// Die Erwarte-Liste
+
+P_HAUS_ERLAUBT
+// Hier darf gebaut werden
+
+P_SHORT_CWD
+// .readme bei cd ausgeben oder nicht
+
+P_PARA
+// Nummer der Parallelwelt in der ein Spieler ist.
+
+P_LOG_INFO
+// Wenn diese Property gesetzt ist wird jede Frage, die ein
+// Monster nicht beantworten kann, im Report-File des
+// zustaendigen Magiers geloggt.
+
+P_COMBATCMDS
+// Befehle, die man mit Spezialwaffen ausfuehren kann und genauere
+// Informationen hierzu.
+
+P_DEAF
+// Der Spieler ist taub. Falls hier ein String steht, wird dieser bei
+// "teile ... mit" an den Mitteilenden ausgegeben, ansonsten kommt nur
+// "Soundso ist leider gerade taub.\n"
+
+P_ATTACK_BUSY
+// Kann der Spieler noch Spezialwaffen (zB Flammenkugel) einsetzen?
+
+P_PREFERED_ENEMY
+// Array: 1. Element: Wahrscheinlichkeit, dass einer der bevorzugten
+// Feinde (restliche Elemente) genommen wird.
+
+P_HISTMIN
+// Minimale Laenge, die eine Zeile haben muss, um in die History zu kommen
+
+P_SHOW_ALIAS_PROCESSING
+// Arbeit des Parsers beobachten (debugging)
+
+P_DEFAULT_NOTIFY_FAIL
+// Welche Fehlermeldung kommt, wenn kein Objekt ein notify_fail macht?
+
+P_IP_NAME
+// Rechnername des Interactives
+
+P_AUTH_INFO
+// Username des Spielers, wenn bei ihm ein AUTHD laeuft
+
+P_LAST_KILLER
+// Letzter Moerdes des Wesens
+
+P_CLONE_MSG
+// Meldung, die beim Clonen eines Obj ausgegegen wird (nur Magier)
+
+P_CMSG
+// *** OBSOLET! *** Siehe P_CLONE_MSG
+
+P_DESTRUCT_MSG
+// Meldung, die beim Destructen Obj ausgegegen wird (nur Magier)
+
+P_DMSG
+// *** OBSOLET! *** Siehe P_DESTRUCT_MSG
+
+P_READ_NEWS
+// Welche Artikel bereits gelesen wurde (frueher: in der MPA)
+
+P_LAST_CONTENT_CHANGE
+// Wann wurde zum letzten Mal was ins Obj gestopft oder rausgenommen?
+// Wichtig fuer den Weight-Cache
+
+P_MAX_POISON
+// Maximale Vergiftung
+
+P_DESCRIPTION
+// Beschreibung des Spielers
+
+P_KEEP_ON_SELL
+// Bei "verkaufe alles" wird das Objekt behalten.
+
+P_DESCRIPTION
+// Beschreibung des Spielers
+
+P_KEEP_ON_SELL
+// Objekt soll bei verkaufe alles behalten werden
+
+P_CLOCKMSG
+// Die Meldung wird zur vollen Stunde ausgegeben
+
+P_SIZE
+// Groesse des Lebewesens (in cm)
+
+P_AVERAGE_SIZE
+// Durchschnittliche Groesse eines Wesens dieser Rasse (derzeit nur Player)
+
+P_PERM_STRING
+// Fuer Sprachflueche. In dem Objekt, das in P_PERM_STRING vermerkt ist,
+// wird bei Sprachbefehlen permutate_string(str) aufgerufen und der
+// zurueckgegebene String statt dessen ausgegeben.
+
+P_RACESTRING
+// Gibt eine dem Geschlecht angepasste Beschreibung der Rasse zurueck
+// ("Zwerg" oder "Zwergin" etc.)
+
+P_WATER
+// Gewaessertyp. Erlaetuerungen in fishing.h
+
+P_FISH
+// Fischdichte. Erlaeuterungen in fishing.h
+
+P_SCREENSIZE
+// Zahl der Zeilen (wie mit dem "zeilen"-Befehl eingestellt).
+// Nur im Spielerobjekt sinnvoll ;)
+
+P_SKILLS
+// *** OBSOLET! ***
+// Siehe P_NEWSKILLS.
+
+P_VALID_GUILDS
+// Enthaelt die zugelassenen Gilden und ist nur fuer den Gildenmaster
+// von Bedeutung.
+
+P_GUILD_SKILLS
+// Gildenproperty
+// Enthaelt ein Mapping mit allen Spruechen und Faehigkeiten der Gilde.
+// Wird mit AddSkill()/AddSpell() modifiziert.
+
+P_GUILD_RESTRICTIONS
+// Gildenproperty
+// Enthaelt ein Mapping mit den Eintrittbeschraenkungen einer Gilde.
+
+P_GUILD_DEFAULT_SPELLBOOK
+// Gildenproperty
+// Der Name des Spellbooks, das von der Gilde standardmaessig verwendet
+// wird (kann bei Spells mit SI_SPELLBOOK ueberschrieben werden).
+
+P_GUILD_MALE_TITLES
+// Gildenproperty
+// Ein Mapping mit den Stufenbezeichnungen fuer maennliche Gildenmitglieder.
+// Als Key dient der Gildenlevel.
+
+P_GUILD_FEMALE_TITLES
+// Gildenproperty
+// Ein Mapping mit den Stufenbezeichnungen fuer weibliche Gildenmitglieder.
+// Als Key dient der Gildenlevel.
+
+P_GUILD_LEVELS
+// Gildenproperty
+// Ein Mapping mit den Stufenbeschraenkungen fuer die Gildenlevel.
+// Als Key dient der jeweilige Gildenlevel.
+
+P_SB_SPELLS
+// Spellbookproperty
+// Hier sind saemtliche Spells des Spellbooks vermerkt (wird mit AddSpell()
+// veraendert).
+
+P_GLOBAL_SKILLPROPS
+// Gilden- und Spellbookproperty
+// Eigenschaften, die ALLE Spells eines Spellbooks bzw. ALLE Skills und
+// Spells einer Gilde haben sollen.
+
+P_GUILD_LEVEL
+// Gildenlevel des Spielers (nicht unbedingt identisch mit dem Spielerlevel)
+
+P_GUILD_TITLE
+// Gildentitel, der dem Gildenlevel des Spielers entspricht. Wird nur
+// angezeigt, wenn P_TITLE=0 ist.
+
+P_GUILD_RATING
+// Einstufung des Spielers in der Gilde (zwischen 0 und 10000).
+// Wie sich die Einstufung zusammensetzt, ist Sache der jeweiligen Gilde.
+
+P_NEWSKILLS
+// Hier sind saemtliche Skills und Spells vermerkt, die der Spieler kennt.
+
+P_NEXT_SPELL_TIME
+// Wann kann das naechste Mal gezaubert werden?
+
+P_HIT_FUNC
+// Enthaelt das Objekt, das eine HitFunc() definiert
+// (fuer Waffen)
+
+P_WIELD_FUNC
+// Enthaelt das Objekt, das eine WieldFunc() definiert
+// (fuer Waffen)
+
+P_UNWIELD_FUNC
+// Enthaelt das Objekt, das eine UnwieldFunc() definiert
+// (fuer Waffen)
+
+P_DEFEND_FUNC
+// Enthaelt das Objekt, das eine DefendFunc() definiert
+// (fuer Ruestungen)
+
+P_WEAR_FUNC
+// Enthaelt das Objekt, das eine WearFunc() definiert
+// (fuer Ruestungen)
+
+P_REMOVE_FUNC
+// Enthaelt das Objekt, das eine RemoveFunc() definiert
+// (fuer Ruestungen)
+
+P_LEP
+// Levelpunkte eines Spielers
+// NICHT VON HAND SETZEN!!!
+
+P_LEP_MALUS
+// Malus auf die Levelpunkte
+// NICHT VON HAND SETZEN!!!
+
+P_ORIG_NAME
+// In einer Leiche der Name des Gestorbenen. (name(RAW))
+
+P_NO_GLOBAL_ATTACK
+// Falls diese Propertie in einem NPC gesetzt ist, wird dieser bei einem
+// "toete alle" nicht mit angegriffen
+// (das ist zB. bei BegleitNPCs ganz nuetzlich)
+
+P_DAMAGED
+// Grad der Beschaedigung einer Waffe/Ruestung.
+// Die Propertie sollte so gesetzt sein, dass P_DAMAGED + aktuelles P_WC/AC
+// die urspruengliche P_WC/AC ergibt
+
+P_EFFECTIVE_WC
+// Die durchschnittliche Wirkung einer Waffe, basierend auf P_WC und
+// einer ggf. vorhandenen HitFunc().
+
+P_EFFECTIVE_AC
+// Die durchschnittliche Wirkung einer Ruestung, basierend auf P_AC
+// und einer ggf. vorhandenen DefendFunc().
+
+P_HOMEPAGE
+// Die Homepage eines Spielers (mit dem Befehl 'url' zu setzen).
+
+P_TPORT_COST_IN
+// In einem Raum mit Sehertor: Kostenanteil, um sich in den Raum zu
+// teleportieren
+
+P_TPORT_COST_OUT
+// In einem Raum mit Sehertor: Kostenanteil, sich aus dem Raum heraus
+// zu teleportieren
+
+P_HIDE_EXITS
+// Ist diese Property in einem Raum auf einen Wert ungleich 0, gesetzt,
+// werden einem Spieler fuer diesen Raum keine Ausgaenge angezeigt.
+
+P_TMP_ATTACK_HOOK
+// Mindestens 3-elementiges Array ({zeitpunkt, objekt, funktion, ...}).
+// Die Funktion wird im 'objekt' mit dem Feind des Lebewesens als Parameter
+// zu Beginn von Attack() (des Lebewesens) aufgerufen, wenn der 'zeitpunkt'
+// noch nicht ueberschritten ist. Wenn die Funktion 0 zurueckgibt, wird
+// Attack() abgebrochen. Ueber optionale Arrayelemente koennen der Funktion
+// weitere Parameter uebergeben werden.
+
+P_TMP_DEFEND_HOOK
+// Mindestens 3-elementiges Array ({zeitpunkt, objekt, funktion, ...}).
+// Die Funktion wird im 'objekt' mit den gleichen Parametern wie Defend()
+// zu Beginn von Defend() (des Lebewesens) aufgerufen, wenn der 'zeitpunkt'
+// noch nicht ueberschritten ist. Wenn die Funktion 0 zurueckgibt, wird
+// Defend() abgebrochen, ansonsten wird als Rueckgabe ein 3-elementiges
+// Array ({schaden, schadenstypen, spell}) erwartet, die anstelle der
+// Defend() uebergebenen Werte verwendet werden. Ueber optionale Array-
+// elemente koennen der Funktion weitere Parameter uebergeben werden.
+
+P_TMP_DIE_HOOK
+// Mindestens 3-elementiges Array ({zeitpunkt, objekt, funktion, ...}).
+// Die Funktion wird im 'objekt' mit dem gleichen Parameter wie die()
+// zu Beginn von die() (des Lebewesens) aufgerufen, wenn der 'zeitpunkt'
+// noch nicht ueberschritten ist. Wenn die Funktion 1 zurueckgibt, wird
+// die() abgebrochen. Ueber optionale Arrayelemente koennen der Funktion
+// weitere Parameter uebergeben werden.
+
+P_DAM_DESC
+// Beschreibung beschaedigter Waffen/Ruestungen.
+
+P_LAST_DAMTYPES
+// Schadenstypen, mit denen das letzte do_damage() von Defend() aus
+// ausgeloest wurde (kann von Leichen abgefragt werden).
+// Entweder ein Array mit den Schadenstypen oder 0.
+
+P_TEAM
+// Teamobjekt, falls Spieler in einem Team ist.
+
+P_TEAM_NEWMEMBER
+// Spieler moechte ins Team von diesem Objekt aufgenommen werden.
+
+P_TEAM_ATTACK_CMD
+// Angriffsbefehl des Spielers, nicht setzbar.
+
+P_TEAM_AUTOFOLLOW
+// Folgewunsch des Spielers, nicht setzbar.
+
+P_TEAM_WANTED_ROW
+// Gewuenschte Reihe des Spielers (von 1 bis MAX_TEAMROWS)
+
+P_TEAM_WIMPY_ROW
+// Fluchtreihe des Spielers (von 1 bis MAX_TEAMROWS)
+// Wenn die Fluchtreihe <=1 ist ist die Flucht in eine hintere Reihe
+// deaktiviert.
+
+P_TEAM_LEADER
+// Teamobjekt, falls Spieler Anfuehrer eines Teams ist.
+
+P_TEAM_ASSOC_MEMBERS
+// Array mit den zugeordneten NPCs des Spielers bzw.
+// der Spieler, dem dieser NPC zugeordnet ist.
+// Zugeordnete NPCs sind automatisch im Team des Spielers.
+// Der Zugriff auf diese Property sollte ueber AssocMember()
+// bzw. DeAssocMember() erfolgen.
+
+P_TEAM_COLORS
+// Grenzwerte fuer farbige Anzeige im Teaminfo.
+// Array mit 4 Werten ({ lp_rot, lp_gelb, sp_rot, sp_gelb })
diff --git a/doc/.readme b/doc/.readme
new file mode 100644
index 0000000..19d3abf
--- /dev/null
+++ b/doc/.readme
@@ -0,0 +1,25 @@
+Dokumentation von Befehlen und Themen innerhalb des Spiels:
+ * help/  - allgemeine Themen, die ALLE betreffen
+ * pcmd/  - die Befehle, ueber die man schon als einfacher Spieler verfuegt
+ * scmd/  - Seherbefehle und Hilfen zum Hausbau
+ * mcmd/  - hier sind die Magierbefehle beschrieben
+ * wiz/   - allgemeine Themen fuer Magier
+ * g.XYZ/ - Hilfeseiten, die zur Gilde XYZ gehoeren
+
+Uebersicht ueber Objekte und Funktionen MudLib
+ * efun/   - Funktionen, die der GameDriver zur Verfuegung stellt
+ * lfun/   - Funktionen, die die Objekte der MudLib zur Verfuegung stellen
+ * master/ - Funktionen, die das Masterobject zur Verfuegung stellt
+
+ * std/    - Die Objekte des Basis-MudLib
+ * obj/    - Einige hilfreiche Zusatzobjekte
+
+ * props/  - Die Properties
+
+ Allgemeines
+ * beispiele/ - einige hilfreiche Beispiele fuer den Start ins Magierleben
+
+Bei Aenderungen bitte Gloinson Bescheid geben oder eine Mail an
+Doku@MorgenGrauen schicken. Eine genauere Uebersicht ueber das
+Hilfsverzeichnis findest Du in der Datei /doc/README.
+
diff --git a/doc/.synonym b/doc/.synonym
new file mode 100644
index 0000000..32d3e7d
--- /dev/null
+++ b/doc/.synonym
@@ -0,0 +1 @@
+lpc LPC
diff --git a/doc/KURS/COMMENTS b/doc/KURS/COMMENTS
new file mode 100644
index 0000000..4ef9ca9
--- /dev/null
+++ b/doc/KURS/COMMENTS
@@ -0,0 +1,75 @@
+	BEMERKUNGEN ZUM THEMA SPIELVERDERBER
+	------------------------------------
+
+	Eine konsequente Verwendung der Worte Moerder, Verbrecher,
+	o.ae. verkennt den wahren Charakter:
+	Es sind einfach nur Spielverderber, und sollten auch 
+	dementsprechend behandelt werden.
+
+	Im Moment wird noch nicht gespielt.
+	Ergo gibt es noch keine Spielverderber.
+
+	Wenn es denn welche gibt, wie geht man mit ihnen um ?
+	-	Man spielt nicht mehr mit Ihnen.
+	-	Man nimmt ihnen den Spass, sodass sie von selber
+		aufhoeren mitzuspielen, bzw. anderen das Spiel
+		zu verderben.
+
+	Vorschlaege(!) fuer Massnahmen:
+	
+	-	Belegen mit Fluechen.
+
+	(zB Erkaeltungen, oder zeitweiliger Verlust der Faehigkeit,
+	Waffen zu tragen, Schlechtes Gewissen, dass man immer wieder
+	daran erinnert wird, was man boeses getan hat. etc.)
+	Wer hat weitere Ideen ??
+
+	Vorteile:
+
+		+	Die Bestrafung erfolgt innerhalb des Spieles.
+		+	Durch die Dauer kann die Strafe fein dosiert
+			werden.
+
+	Nachteil: 
+
+		+	Magier sind auf diese Weise schwer zu
+			bestrafen.
+
+
+	-	Geld oder XP wegnehmen.
+
+	-	Herabstufung. Nur im NOTFALL
+
+	-	Aussschluss vom Spiel. Nur im AEUSSERSTEN NOTFALL
+
+
+	Wer ein Spielverderber ist, entscheidet im allgemeinen
+	die Gemeinschaft der Spielenden. Deshalb darf es keine
+	fatalen Eingriffe in das Spiel durch die Entscheidung 
+	einzelner Spieler geben!
+
+	BEMERKUNGEN ZUM THEMA FLEISS VON MAGIERN
+	----------------------------------------
+
+	Wenn ein Magier selten im Spiel ist, heisst das nicht,
+	dass er sich, wenn er einmal da ist, um so staerker
+	bemerkbar machen muss.
+
+
+	BEMERKUNGEN ZU GENAUEREN REGELN
+	-------------------------------
+
+	Man sollte sich nicht an irgendwelchen Zahlen (wiz_levels),
+	Verordnungen, Geschaeftsordnugnen etc. festhalten, sondern sich
+	immer vor Augen halten, dass es sich im ein Spiel handelt.
+	Es haben sich Leute zusammengefunden, um miteinander Spass zu
+	haben. Dieses Spiel ist keine so komplexe Gesellschaft wie die
+	reale; deshalb sollte es auch keiner so komplexen Regeln
+	beduerfen.
+
+	Olpp, Sheriff des MorgenGrauens
+	Rumata, MudAdm des MorgenGrauens
+
+	P.S.:
+		Kommentare und weitere Vorschlaege sind herzlich
+		willkommen.
diff --git a/doc/KURS/LPC-KURS/Contents b/doc/KURS/LPC-KURS/Contents
new file mode 100644
index 0000000..0dd4efb
--- /dev/null
+++ b/doc/KURS/LPC-KURS/Contents
@@ -0,0 +1,13 @@
+                             LPC Basics
+                      Written by Descartes of Borg
+                            23 april 1993
+
+Introduction
+Chapter 1: Introduction to the Coding Environment
+Chapter 2: The LPC Program
+Chapter 3: LPC Data Types
+Chapter 4: Functions
+Chapter 5: The Basics of Inheritance
+Chapter 6: Variable Handling
+Chapter 7: Flow Control
+Chapter 8: The Data Type Object
diff --git a/doc/KURS/LPC-KURS/Introduction b/doc/KURS/LPC-KURS/Introduction
new file mode 100644
index 0000000..2e3c7ff
--- /dev/null
+++ b/doc/KURS/LPC-KURS/Introduction
@@ -0,0 +1,106 @@
+                             LPC Basics
+                     Written by Descartes of Borg
+                            23 april 1993
+ 
+ 
+                            INTRODUCTION
+               This manual, how to use it, and its terms
+ 
+I have seen a lot of requests lately on USENET for LPC manuals.  In addition,
+the immortals on my mud have been telling how good the building documentation
+of Nightmare is, but that there was just no adequate explanation of the
+LPC programming language.  So I decided to try my hand at writing a manual.
+Some things you should keep in mind.
+LPC is a very easy programming language to learn, and it has real
+value in that place most of us know as the real world.  I began playing
+muds in 1991, and in the space of a month created an unimpressive area
+and musician's guild on the original Bates College MUD called Orlith.
+After that, I moved to Los Angeles for a year and had no contact with
+mudding or computers.  In June of 1992, I was back on the internet and
+a wizard of Igor.  In September of 1992 I began coding the Nightmare
+mudlib for our use, and then later decided to distribute it due to there
+not being any mudlibs for MudOS at the time that a person could just throw
+up a running mud with (now, that of course is not the case :)).
+So, I have been doing serious coding for less than a year.  As a
+Philosophy major in a world of Computer Science majors, I just want to
+make clear that it is not at all required that you have ever done anything
+with your computer than log into a mud in order for you to really come
+to understand LPC coding.  This manual makes the following assumptions:
+Someone has taught you basic UNIX commands like ls, cd, mkdir, mv, rm, etc.
+You know how to enter your mud's editor and write a file.  No other
+assumptions are made.  If you know C, you are handicapped in that LPC
+looks a lot like C, but it is not C.  Your preconceptions about
+modular programming development will be a hinderence you will have to
+overcome.  If you have never heard of the C programming language (like
+me in May of 1991), then you are only missing an understanding of the
+simple constructs of C like the flow of program execution and logical
+operators and such.  So a C guru has no real advantage over you, since
+what they know from C which is applicable to LPC is easy to pick up.
+The stuff they know about C which makes them a guru is irrelevant to
+LPC.
+ 
+The chapters of this manual are meant to be read in order.  Starting with
+the introduction, going sequentially through the chapter numbers as
+ordered in the contents file.  Each chapter begins with a paragraph or
+two explaining what you should have come to understand by that point
+in your studies.  After those introductory paragraphs, the chapter then
+begins to discuss its subject matter in nauseating detail.  At the end
+of the chapter is a briefly worded summary of what you should understand
+from that chapter if I have been successful.  Following that may or may
+not be some sidenotes relevant to the subject at hand, but not necessary
+to its understanding.
+ 
+If at any time you get to a chapter intro, and you have read the preceeding
+chapters thoroughly and you do not understand what it says you should
+understand by that point, please mail me!  Clearly, I have failed at that
+point and I need to know where it is I have gone wrong so I can revise
+it properly.  Similarly, if you do not understand what the chapter summary
+says you should, please mail me.  If your mumud is on the MudOS intermud
+system, mail descartes@nightmare.  Otherwise mail borg@hebron.connected.com.
+ 
+Some basic terms this manual uses:
+driver-
+This is the C program which is the game.  It accepts incoming sockets
+(links to other computers), interprets LPC code defined by the mudlib,
+keeps mud objects in memory, makes periodic attempts to clean unused
+mud objects from memory, makes periodic calls to objects, and so on.
+ 
+mudlib-
+LPC code which defines the world in which you are in.  The driver of itself
+is not a game.  It is just a program which allows the creation of a
+multi-user environment.  In some sense, the driver is like an LPC
+compiler, and the mudlib is like a compiler's library (a very loose
+analogy).  The mudlib defines basic objects which will likely be used
+over and over again by people creating in the mud world.  Examples of
+such objects are /std/room (or /room/room), /std/user.c (or /obj/player.c),
+and so on.
+ 
+area or castle:
+Specific creator coded objects which often use a feature of LPC called
+inheritance to make use of the properties of basic mudlib objects and
+turn them into specific objects to be used by players in the game
+ 
+object:
+a room, a weapon, a monster, a player, a bag, etc.  More importantly,
+every individual file with a .c extension is an object.  Objects are
+used in different ways.  Objects like /std/living.c are inherited by
+objects like monster.c and user.c.  Others are cloned, which means a
+duplicate of that code is loaded into memory.  And still others are
+simply loaded into memory to be referenced by other objects.
+ 
+native and compat:
+these two terms refer to two popular flavours of drivers.  Native mode
+mudlibs make use of on the design of LPMud driver 3.0 and later.  You may
+have a 3.0 driver however, but have a 2.4.5 style mudlib.  This is what
+is meant by compat mode.  Mudlibs which are native mode are any for
+MudOS, CD, and LPMud mudlibs that
+are listed as native.  Compat mudlibs are any LPMud mudlib before 3.0 and
+those which are 3.* compat mudlibs.  I believe Amylaar's is compat.
+[ Not true, Amylaar supports native and compat mudlibs, MorgenGrauen
+  is native - Boing ]
+
+Good Luck!
+George Reese
+(Descartes of Borg)
+12 july 1993
+borg@hebron.connected.com
diff --git a/doc/KURS/LPC-KURS/chapter1 b/doc/KURS/LPC-KURS/chapter1
new file mode 100644
index 0000000..6f233d0
--- /dev/null
+++ b/doc/KURS/LPC-KURS/chapter1
@@ -0,0 +1,90 @@
+                           LPC Basics
+                  Written by Descartes of Borg
+                  first edition: 23 april 1993
+                  second edition: 25 may 1993
+
+CHAPTER 1: Introduction to the Coding Environment
+
+1.1 UNIX file structure
+LPMuds use basic UNIX commands and its file structure.  If you know
+UNIX commands already, then note (with a few exceptions) options are
+not available to the commands.  Like DOS, UNIX is heirarchical.  The
+root directory of which all directories are sub-directories is called
+root(/).  And from those sub-directories you may have further
+sub-directories.  A directory may be referred to in two different ways:
+1) by its full name, or absolute name, or 2) by its relative name.
+Absolute name refers to the directory's full path starting from / winding
+down the directory tree until you name the directory in question.  For
+example:
+
+    /players/descartes/obj/monster
+
+refers to the directory monster which is a sub-directory of obj which
+is a sub-directory of descartes which is a sub-directory of players
+which is a sudirectory of /.
+
+The relative name refers to the name relative to another directory.
+The above example is called monster relative to /players/descartes/obj,
+but it is also called obj/monster relative to /players/descartes,
+descartes/obj/monster relative to /players, and finally
+players/descartes/obj/monster relative to /.  You can tell the
+difference between absolute names and relative names because absolute
+names always start with /.  In order to know exactly which directory
+is being named by a relative name, you naturally must know what
+directory it is relative to.
+
+A directory contains sub-directories and files.  LPMuds only use text files
+inside the mudlib.  Like directories, files have both absolute and
+relative names.  The most basic relative name is often referred to as the file
+name, with the rest of the absolute name being referred to as the path.  So,
+for the file: /players/descartes/castle.c, castle.c is the file name, and
+/players/descartes is the path.
+
+On some muds, a file with a file name beginning with a . (like .plan) is
+not visible when you list files with the regular file listing command.
+
+1.2 UNIX Commands
+Along with the UNIX file structure, LPMuds use many UNIX commands.  Typical
+UNIX commands on most muds are:
+pwd, cd, ls, rm, mv, cp, mkdir, rmdir, more, head, cat, ed
+If you have never before seen UNIX commands, you probably are thinking this
+is all nonsense.  Well, it is, but you got to use them.  Before getting
+into what they mean though, first a discussion of current directory.
+If you know DOS, then you know what a current working directory is.
+At any given point, you are considered to be "in" some directory.  This
+means that any relative file or directory names you give in UNIX commands
+are relative to that directory.  For example, if my current directory is
+/players/descartes and I type "ed castle.c" (ed is the command to edit),
+then it assumes I mean the file /players/descartes/castle.c
+
+pwd: shows you your current working directory
+cd: changes your current working directory.  You may give either relative
+    or absolute path names.  With no arguments, it changes to your home
+    directory.
+ls: lists all files in the directory named.  If no directory is named,
+    it lists the files of the current working directory
+rm: deletes the file named
+mv: renames the file named
+cp: copies the file named
+mkdir: makes a new directory
+rmdir: deletes a directory.  All files must have been first removed.
+more: pages the file named so that the file appears on your screen one
+    page at a time.
+cat: shows the whole file to you at once
+head: shows you the first several lines of a file
+tail: shows you the last several lines of a file
+ed: allows you to edit a file using the mud editor
+
+1.3 Chapter Summary
+UNIX uses a heirarchical file structure with the root of the tree being
+named /.  Other directories branch off from that root directory and
+in turn have their own sub-directories.  All directories may contain
+directories and files.  Directories and files are referred to either
+by their absolute name, which always begins with /, or by their relative
+name which gives the file's name relative to a particular directory.
+In order to get around in the UNIX files structure, you have the
+typical UNIX commands for listing files, your current directory, etc.
+On your mud, all of the above commands should have detailed help commands
+to help you explore exactly what they do.  In addition, there should
+be a very detailed file on your mud's editor.  If you are unfamiliar
+with ed, you should go over this convoluted file.
diff --git a/doc/KURS/LPC-KURS/chapter2 b/doc/KURS/LPC-KURS/chapter2
new file mode 100644
index 0000000..f9ad566
--- /dev/null
+++ b/doc/KURS/LPC-KURS/chapter2
@@ -0,0 +1,195 @@
+                           LPC Basics
+                  Written by Descartes of Borg
+                  first edition: 23 april 1993
+                  second edition: 16 june 1993
+
+CHAPTER 2: The LPC Program
+
+2.1 About programs
+The title of this chapter of the textbook is actually poorly named, since
+one does not write programs in LPC.  An LPC coder instead writes *objects*.
+What is the difference?  Well, for our purposes now, the difference is
+in the way the file is executed.  When you "run" a program, execution
+begins at a definite place in the program.  In other words, there
+is a place in all programs that is noted as the beginning where program
+execution starts.  In addition, programs have definite end points,
+so that when execution reaches that point, the execution of the program
+terminates.  So, in short, execution of a program runs from a definite
+beginning point through to a definite end point.  This is not so with
+LPC objects.
+
+With muds, LPC objects are simply distinct parts of the C program which
+is running the game (the driver).  In other words, execution of the mud
+program begins and ends in the driver.  But the driver in fact does
+very little in the way of creating the world you know when you play
+a mud.  Instead, the driver relies heavily on the code created in LPC,
+executing lines of the objects in the mud as needed.  LPC objects thus
+have no place that is necessarily the beginning point, nor do they
+have a definite ending point.
+
+Like other programming languages, an LPC "program" may be made up of
+one or more files.  For an LPC object to get executed, it simple
+needs to be loaded into the driver's memory.  The driver will call lines
+from the object as it needs according to a structure which will be
+defined throughout this textbook.  The important thing you need to
+understand at this point is that there is no "beginning" to an LPC
+object in terms of execution, and there is no "end".
+
+2.2 Driver-mudlib interaction
+As I have mentioned earlier, the driver is the C program that runs on
+the host machine.  It connects you into the game and processes LPC code.
+Note that this is one theory of mud programming, and not necessarily
+better than others.  It could be that the entire game is written in C.
+Such a game would be much faster, but it would be less flexible in
+that wizards could not add things to the game while it was running. This
+is the theory behind DikuMUDs.  Instead, LPMUDs run on the theory that
+the driver should in no define the nature of the game, that the nature
+of the game is to be decided by the individuals involved, and that
+you should be able to add to the game *as it is being played*.  This
+is why LPMUDs make use of the LPC programming language.  It allows
+you to define the nature of the game in LPC for the driver to read and
+execute as needed.  It is also a much simpler language to understand
+than C, thus making the process of world creation open to a greater
+number of people.
+
+Once you have written a file in LPC (assuming it is corrent LPC ), it justs
+sits there on the host machine's hard drive until something in the game
+makes reference to it.  When something in the game finally does make
+reference to the object, a copy of the file is loaded into memory and
+a special *function* of that object is called in order to initialize
+the values of the variables in the object.  Now, do not be concerned
+if that last sentence went right over your head, since someone brand
+new to programming would not know what the hell a function or a variable
+is.  The important thing to understand right now is that a copy of the
+object file is taken by the driver from the machine's hard drive and
+stored into memory (since it is a copy, multiple versions of that
+object may exist).  You will later understand what a function is, what
+a variable is, and exactly how it is something in the game made reference
+to your object.
+
+2.3 Loading an object into memory
+Although there is no particular place in an object code that must exist
+in order for the driver to begin executing it, there is a place for which
+the driver will search in order to initialize the object.  On compat 
+drivers, it is the function called reset().  On native muds it is the
+function called create(). [ MorgenGrauen is native - Boing ]
+
+LPC objects are made up of variables (values which can change) and
+functions which are used to manipulate those variables.  Functions
+manipulate variables through the use of LPC grammatical structures,
+which include calling other functions, using externally defined
+functions (efuns), and basic LPC expressions and flow control 
+mechanisms.
+
+Does that sound convoluted?  First lets start with a variable.  A
+variable might be something like: level.  It can "vary" from sitation
+to situation in value, and different things use the value of the player's
+level to make different things happen.  For instance, if you are a
+level 19 player, the value of the variable level will be 19.  Now
+if your mud is on the old LPMud 2.4.5 system where levels 1-19 are
+players and 20+ are wizards, things can ask for your level value to
+see if you can perform wizard type actions.  Basically, each object
+in LPC is a pile of variables with values which change over time.
+Things happen to these objects based on what values its variables
+hold.  Often, then things that happen cause the variables to change.
+
+So, whenever an object in LPC is referenced by another object currently
+in memory, the driver searches to see what places for values the
+object has (but they have no values yet).  Once that is done, the driver
+calls a function in the object called reset() or create() (depending
+on your driver) which will set up the starting values for the object's
+variables.  It is thus through *calls* to *functions* that variable
+values get manipulated.
+
+But create() or reset() is NOT the starting place of LPC code, although
+it is where most LPC code execution does begin.  The fact is, those
+functions need not exist.  If your object does just fine with its
+starting values all being NULL pointers (meaning, for our purposes
+here, 0), then you do not need a create() or reset() function.  Thus
+the first bit of execution of the object's code may begin somewhere
+completely different.
+
+Now we get to what this chapter is all about.  The question: What
+consists a complete LPC object?  Well, an LPC object is simply
+one or more functions grouped together manipulating 0 or more
+variables.  The order in which functions are placed in an object
+relative to one another is irrelevant.  In other words:
+
+-----
+void init() { add_action("smile", "smile"); }
+
+void create() { return; }
+
+int smile(string str) { return 0; }
+-----
+
+is exactly the same as:
+
+-----
+void create() { return; }
+
+int smile(string str) { return 0; }
+
+void init() { add_action("smile", "smile"); }
+_____
+
+Also important to note, the object containing only:
+
+-----
+void nonsense() {}
+-----
+
+is a valid, but trivial object, although it probably would not interact
+properly with other objects on your mud since such an object has no
+weight, is invisible, etc..
+
+2.4 Chapter summary
+LPC code has no beginning point or ending point, since LPC code is used
+to create objects to be used by the driver program rather than create
+individual programs.  LPC objects consist of one or more functions whose
+order in the code is irrelevant, as well as of zero or more variables whose
+values are manipulated inside those functions.  LPC objects simply sit
+on the host machine's hard driver until referenced by another object in
+the game (in other words, they do not really exist).  Once the object
+is referenced, it is loaded into the machine's memory with empty
+values for the variables.  The function reset() in compat muds or
+create() in native muds is called in that object if it exists to allow
+the variables to take on initial values.  Other functions in the object
+are used by the driver and other objects in the game to allow interaction
+among objects and the manipulation of the LPC variables.
+
+A note on reset() and create():
+create() is only used by muds in native mode (see the textbook Introduction
+for more information on native mode vs. compat mode).  It is only used
+to initialize newly referenced objects.
+
+reset() is used by both muds in compat mode and native mode.  In compat
+mode, reset() performs two functions.  First, it is used to initialize
+newly referenced objects.  In addition, however, compat mode muds use
+reset() to "reset" the object.  In other words, return it to its initial
+state of affairs.  This allows monsters to regenerate in a room and doors
+to start back in the shut position, etc..  Native mode muds use reset()
+to perform the second function (as its name implies).
+
+So there are two important things which happen in LP style muds which
+cause the driver to make calls to functions in objects.  The first is
+the creation of the object.  At this time, the driver calls a function
+to initalize the values in the object.  For compat mode muds, this
+is performed by the function named reset() (with an argument of 0,
+more on this later though).  For muds running in native mode, this is
+performed by the function create().
+
+The second is the returning of the room to some base state of affairs.
+This base set of affairs may or may not be different from the initial
+state of affairs, and certainly you would not want to take up time
+doing redundant things (like resetting variables that never change).
+Compat mode muds nevertheless use the same function that was used to
+create the object to reset it, that being reset().  Native mode muds,
+who use create() to create the room, instead use reset() to reset it.
+All is not lost in compat mode though, as there is a way to tell the
+difference between creation and resetting.  For reset purposes, the
+driver passes either 1 or the reset number as an argument to reset()
+in compat mode.  Now this is meaningless to you now, but just keep in
+mind that you can in fact tell the difference in compat mode.  Also
+keep in mind that the argment in the creation use of reset is 0 and
+the argument in the reset use is a nonzero number.
diff --git a/doc/KURS/LPC-KURS/chapter3 b/doc/KURS/LPC-KURS/chapter3
new file mode 100644
index 0000000..f7e89a4
--- /dev/null
+++ b/doc/KURS/LPC-KURS/chapter3
@@ -0,0 +1,185 @@
+                           LPC Basics
+                  Written by Descartes of Borg
+                  first edition: 23 april 1993
+                  second edition: 17 june 1993
+
+CHAPTER 3: LPC Data Types
+
+3.1 What you should know by now
+LPC object are made up of zero or more variables manipulated by one or
+more functions.  The order in which these functions appear in code is
+irrelevant.  The driver uses the LPC code you write by loading copies of
+it into memory whenever it is first referenced and additional copies
+through cloning.  When each object is loaded into memory, all the variables
+initially point to no value.  The reset() function in compat muds, and
+create() in native muds are used to give initial values to variables in
+objects.  The function for creation is called immediately after the object
+is loaded into memory.  However, if you are reading this textbook with no
+prior programming experience, you may not know what a function is or how
+it gets called.  And even if you have programming experience, you may
+be wondering how the process of functions calling each other gets started
+in newly created objects.  Before any of these questions get answered,
+however, you need to know more about what it is the functions are
+manipulating.  You therefore should thouroughly come to know the concept
+behind LPC data types.  Certainly the most boring subject in this manual,
+yet it is the most crucial, as 90% of all errors (excepting misplaced
+{} and ()) involve the improper usage of LPC data types.  So bear through
+this important chapter, because it is my feeling that understanding this
+chapter alone can help you find coding much, much easier.
+
+3.2 Communicating with the computer
+You possibly already know that computers cannot understand the letters
+and numbers used by humans.  Instead, the "language" spoken by computers
+consists of an "alphabet" of 0's and 1's.  Certainly you know computers
+do not understand natural human languages.  But in fact, they do not
+understand the computer languages we write for them either.  Computer
+languages like BASIC, C, C++, Pascal, etc. are all intermediate
+languages.  They allow you to structure your thoughts more coherently
+for translation into the 0's and 1's of the computer's languages.
+
+There are two methods in which translation is done: compilation and
+interpretation.  These simply are differences betweem when the 
+programming language is translated into computer language.  With
+compiled languages, the programmer writes the code then uses a program
+called a compiler to translate the program into the computer's
+language.  This translation occurs before the program is run.  With
+interpreted languages however, the process of translation occurs as
+the program is being run.  Since the translation of the program is
+occurring during the time of the program's running in interpreted
+languages, interpreted languages make much slower programs than
+compiled languages.
+
+The bottom line is, no matter what language you are writing in, at
+some point this has to be changed into 0's and 1's which can be
+understood by the computer.  But the variables which you store in
+memory are not simply 0's and 1's.  So you have to have a way in
+your programming languages of telling the computer whether or not
+the 0's and 1's should be treated as decimal numbers or characters or
+strings or anything else.  You do this through the use of data types.
+
+For example, say you have a variable which you call 'x' and you give
+it the decimal whole number value 65.  In LPC you would do this through
+the statement:
+
+-----
+x = 65;
+-----
+
+You can later do things like:
+
+_____
+write(x+"\n");        /* \n is symbolically represents a carriage return */
+y = x + 5;
+-----
+
+The first line allows you to send 65 and a carriage return to someone's screen.
+The second line lets you set the value of y to 70.
+The problem for the computer is that it does not know what '65' means when
+you tell it x = 65;.  What you think of 65, it might think of as:
+00000000000000000000000001000001
+But, also, to the computer, the letter 'A' is represented as:
+00000000000000000000000001000001
+So, whenever you instruct the computer write(x+"\n");, it must have some
+way of knowing that you want to see '65' and not 'A'.
+
+The computer can tell the difference between '65' and 'A' through the use
+of data types.  A data types simply says what type of data is being stored
+by the memory location pointed to by a given variable.  Thus, each LPC
+variable has a variable type which guides conversions.  In the example
+given above, you would have had the following line somewhere in the
+code *before* the lines shown above:
+
+-----
+int x;
+-----
+
+This one line tells the driver that whatever value x points to, it will
+be used as the data type "int", which is short for integer, or whole
+number.  So you have a basic introduction into the reason why data types
+exist.  They exist so the driver can make sense of the 0's and 1's that
+the computer is storing in memory.
+
+3.3 The data types of LPC
+All LPMud drivers have the following data types:
+
+void, status, int, string, object, int *, string *, object *, mixed *
+
+Many drivers, but not all have the following important data types which
+are important to discuss:
+
+float, mapping, float *, mapping *
+
+And there are a few drivers with the following rarely used data types
+which are not important to discuss:
+
+function, enum, struct, char
+
+3.4 Simple data types
+This introductory textbook will deal with the data types void, status,
+int, float, string, object, mand mixed.  You can find out about the
+more complex data types like mappings and arrays in the intermediate
+textbook.  This chapter deals with the two simplest data types (from the
+point of view of the LPC coder), int and string.
+
+An int is any whole number.  Thus 1, 42, -17, 0, -10000023 are all type int.
+A string is one or more alphanumeric characters.  Thus "a", "we are borg",
+"42", "This is a string" are all strings.  Note that strings are always
+enclosed in "" to allow the driver to distinguish between the int 42 and
+the string "42" as well as to distinguish between variable names (like x)
+and strings by the same names (like "x").
+
+When you use a variable in code, you must first let the driver know
+what type of data to which that variable points.  This process is
+called *declaration*.  You do this at the beginning of the function
+or at the beginning of the object code (outside of functions before all
+functions which use it).  This is done by placing the name of the data type
+before the name of the variable like in the following example:
+
+-----
+void add_two_and_two() {
+    int x;
+    int y;
+
+    x = 2;
+    y = x + x;
+}
+-----
+
+Now, this is a complete function.  The name of the function is 
+add_two_and_two().  The function begins with the declaration of an
+int variable named x followed by the declaration of an in variable
+named y.  So now, at this point, the driver now has two variables which
+point to NULL values, and it expects what ever values end up there to be
+of type int.
+
+A note about the data types void and status:
+Void is a trivial data type which points to nothing.  It is not used
+with respect to variables, but instead with respect to functions.  You
+will come to understand this better later.  For now, you need only
+understand that it points to no value.  
+
+The data type status is a boolean data type.  That is, it can only have
+1 or 0 as a value.  This is often referred to as being true or false.
+
+3.5 Chapter summary
+For variables, the driver needs to know how the 0's and 1's the computer
+stores in memory get converted into the forms in which you intend them
+to be used.  The simplest LPC data types are void, status, int, and string.
+You do not user variables of type void, but the data type does come
+into play with respect to functions.  In addition to being used for
+translation from one form to the next, data types are used in determining
+what rules the driver uses for such operations as +, -, etc.  For example,
+in the expression 5+5, the driver knows to add the values of 5 and 5
+together to make 10.  With strings however, the rules for int addition
+make no sense.  So instead, with "a"+"b", it appends "b" to the string "a"
+so that the final string is "ab".  Errors can thus result if you mistakenly
+try to add "5"+5.  Since int addition makes no sense with strings, the
+driver will convert the second 5 to "5" and use string addition.  The final
+result would be "55".  If you were looking for 10, you would therefore
+have ended up with erroneous code.  Keep in mind, however, that in most
+instances, the driver will not do something so useful as coming up with
+"55".  It comes up with "55" cause it has a rule for adding a string
+to an int, namely to treat the int as a string.  In most cases, if you
+use a data type for which an operation or function is not defined
+(like if you tried to divide "this is" by "nonsense", "this is"/"nonsense"),
+the driver will barf and report an error to you.
diff --git a/doc/KURS/LPC-KURS/chapter4 b/doc/KURS/LPC-KURS/chapter4
new file mode 100644
index 0000000..4f44cdc
--- /dev/null
+++ b/doc/KURS/LPC-KURS/chapter4
@@ -0,0 +1,225 @@
+                           LPC Basics
+                  Written by Descartes of Borg
+                  first edition: 23 april 1993
+                  second edition: 22 june 1993
+
+CHAPTER 4: Functions
+
+4.1 Review
+By this point, you should be aware that LPC objects consist of functions
+which manipulate variables.  The functions manipulate variables when they
+are executed, and they get executed through *calls* to those functions.
+The order in which the functions are placed in a file does not matter.
+Inside a function, the variables get manipulated.  They are stored in
+computer memory and used by the computer as 0's and 1's which
+get translated to and from useable output and input through a device
+called data typing.  String data types tell the driver that the
+data should appear to you and come from you in the form of alphanumeric
+characters.  Variables of type int are represented to you as whole
+number values.  Type status is represented to you as either 1 or 0.
+And finally type void has no value to you or the machine, and is not
+really used with variable data types.
+
+4.2 What is a function?
+Like math functions, LPC functions take input and return output.
+Languages like Pascal distinguish between the concept of proceedure abd
+the concept of function.  LPC does not, however, it is useful to
+understand this distinction.  What Pascal calls a proceedure, LPC
+calls a function of type void.  In other words, a proceedure, or function
+of type void returns no output.  What Pascal calls a function differs
+in that it does return output.  In LPC, the most trivial, correct
+function is:
+
+-----
+void do_nothing() { }
+-----
+
+This function accepts no input, performs no instructions, and returns no
+value.
+
+There are three parts to every properly written LPC function:
+1) The declaration
+2) The definition
+3) The call
+
+Like with variables, functions must be declared.  This will allow the
+driver to know 1) what type of data the function is returning as output,
+and 2) how many input(s) and of what type those input(s) are.  The
+more common word for input is parameters.
+A function declaration therefore consists of:
+type name(parameter1, parameter2, ..., parameterN);
+The declaration of a function called drink_water() which accepts a string as
+input and an int as output would thus look like this:
+
+-----
+int drink_water(string str);
+-----
+
+where str is the name of the input as it will be used inside the function.
+
+The function definition is the code which describes what the function actually
+does with the input sent to it.  
+The call is any place in other functions which invokes the execution of the
+function in question.  For two functions write_vals() and add(), you thus
+might have the following bit of code:
+
+-----
+/* First, function declarations.  They usually appear at the beginning
+   of object code. 
+*/
+void write_vals();
+int add(int x, int y);
+
+/* Next, the definition of the function write_vals().  We assume that
+   this function is going to be called from outside the object
+*/
+void write_vals() {
+    int x;
+
+    /*N Now we assign x the value of the output of add() through a call */
+    x = add(2, 2);
+    write(x+"\n");
+}
+
+/* Finally, the definition of add() */
+int add(int x, int y) {
+    return (x + y);
+}
+-----
+
+Remember, it does not matter which function definition appears first in the
+code.  This is because functions are not executed consecutively.  Instead,
+functions are executed as called.  The only requirement is that the
+declaration of a function appear before its definition and before the
+definition of any function which makes a call to it.
+
+4.3 Efuns
+Perhaps you have heard people refer to efuns.  They are externally defined
+functions.  Namely, they are defined by the mud driver.  If you have
+played around at all with coding in LPC, you have probably found some
+expressions you were told to use like this_player(), write(), say(),
+this_object(), etc. look a lot like functions.  That is because they are
+efuns.  The value of efuns is that they are much faster than LPC functions,
+since they already exist in the binary form the computer understands.
+
+In the function write_vals() above, two functions calls were made.  The first was to
+the functions add(), which you declared and defined.  The second call, however,
+was to a function called write(), and efun.  The driver has already declared
+and defined this function for you.  You needs only to make calls to it.
+
+Efuns are created to hanldle common, every day function calls, to handle
+input/output to the internet sockets, and other matters difficult to be
+dealt with in LPC.  They are written in C in the game driver and compiled
+along with the driver before the mud comes up, making them much faster
+in execution.  But for your purposes, efun calls are just like calls
+made to your functions.  Still, it is important to know two things of any
+efun: 1) what return type does it have, and 2) what parameters of what
+types does it take.
+
+Information on efuns such as input parameters and return types is often
+found in a directory called /doc/efun on your mud.  I cannot
+detail efuns here, because efuns vary from driver to driver.  However,
+you can often access this information using the commands "man" or "help"
+depending on your mudlib.  For instance, the command "man write" would
+give you information on the write efun.  But if all else fails,
+"more /doc/efun/write" should work.
+
+By looking it up, you will find write is declared as follows:
+
+-----
+void write(string);
+-----
+
+This tells you an appropriate call to write expects no return value and
+passes a single parameter of type string.
+
+4.4 Defining your own functions
+Although ordering your functions within the file does not matter, ordering
+the code which defines a function is most important.  Once a function
+has been called, function code is executed in the order it appears
+in the function definition.  In write_vals() above, the instruction:
+    
+-----
+x = add(2, 2);
+-----
+
+Must come before the write() efun call if you want to see the appropriate
+value of x used in write().  
+
+With respect to values returned by function, this is done through the "return"
+instruction followed by a value of the same data type as the function.  In
+add() above, the instruction is "return (x+y);", where the value of (x+y)
+is the value returned to write_vals() and assigned to x.  On a more
+general level, "return" halts the execution of a function and returns
+code execution to the function which called that function.  In addition,
+it returns to the calling function the value of any expression that follows.
+To stop the execution of a function of type void out of order, use
+"return"; without any value following.  Once again, remember, the data
+type of the value of any expression returned using "return" MUST be the
+same as the data type of the function itself.
+
+4.5 Chapter Summary
+The files which define LPC objects are made of of functions.  Functions, in
+turn, are made up of three parts:
+    1) The declaration
+    2) The definition
+    3) The call
+Function declarations generally appear at the top of the file before any
+defintions, although the requirement is that the declaration must appear
+before the function definition and before the definition of any function
+which calls it.
+Function definitions may appear in the file in any order so long as they
+come after their declaration.  In addition, you may not define one function
+inside another function.
+Function calls appear inside the definition of other functions where you
+want the code to begin execution of your function.  They may also appear
+within the definition of the function itself, but this is not recommended
+for new coders, as it can easily lead to infinite loops.
+
+The function definition consists of the following in this order:
+    1) function return type
+    2) function name
+    3) opening ( followed by a parameter list and a closing )
+    4) an opening { instructing the driver that execution begins here
+    5) declarations of any variables to be used only in that function
+    6) instructions, expressions, and calls to other functions as needed
+    7) a closing } stating that the function code ends here and, if no
+       "return" instruction has been given at this point (type void functions
+       only), execution returns to the calling function as if a r"return"
+       instruction was given
+
+The trivial function would thus be:
+
+-----
+void do_nothing() {}
+-----
+
+since this function does not accept any input, perform any instructions, or
+return any output.
+
+Any function which is not of type void MUST return a value of a data type
+matching the function's data type.
+
+Each driver has a set of functions already defined for you called efuns
+These you need neither need to declare nor define since it has already
+been done for you.  Furthermore, execution of these functions is faster
+than the execution of your functions since efuns are in the driver.
+In addition, each mudlib has special functions like efuns in that they
+are already defined and declared for you, but different in that they
+are defined in the mudlib and in LPC.  They are called simul_efuns, or
+simulated efuns.  You can find out all about each of these as they are
+listed in the /doc/efun directory on most muds.  In addition many
+muds have a command called "man" or a "help" command which allows you
+simply to call up the info files on them.
+
+Note on style:
+Some drivers may not require you to declare your functions, and some
+may not require you to specify the return type of the function in its
+definition.  Regardless of this fact, you should never omit this information
+for the following reasons:
+    1) It is easier for other people (and you at later dates) to read your
+       code and understand what is meant.  This is particularly useful
+       for debugging, where a large portion of errors (outside of misplaced
+       parentheses and brackets) involve problems with data types (Ever
+       gotten "Bad arg 1 to foo() line 32"?).
+    2) It is simply considered good coding form.
diff --git a/doc/KURS/LPC-KURS/chapter5 b/doc/KURS/LPC-KURS/chapter5
new file mode 100644
index 0000000..29d2a0c
--- /dev/null
+++ b/doc/KURS/LPC-KURS/chapter5
@@ -0,0 +1,161 @@
+                           LPC Basics
+                  Written by Descartes of Borg
+                  first edition: 23 april 1993
+                  second edition: 01 july 1993
+
+CHAPTER 5: The Basics of Inheritance
+
+5.1 Review
+You should now understand the basic workings of functions.  You should be
+able to declare and call one.  In addition, you should be able to recognize
+function definitions, although, if this is your first experience with LPC,
+it is unlikely that you will as yet be able to define your own functions.
+There functions form the basic building blocks of LPC objects.  Code
+in them is executed when another function makes a call to them.  In making
+a call, input is passed from the calling function into the execution of
+the called one.  The called function then executes and returns a value
+of a certain data type to the calling function.  Functions which return
+no value are of type void.
+
+After examining your workroom code, it might look something like this
+(depending on the mudlib):
+
+-----
+inherit "/std/room";
+
+void create() {
+    ::create();
+    set_property("light", 2);
+    set_property("indoors", 1);
+    set("short", "Descartes' Workroom");
+    set("long", "This is where Descartes works.\nIt is a cube.\n");
+    set_exits( ({ "/d/standard/square" }), ({ "square" }) );
+}
+-----
+
+If you understand the entire textbook to this point, you should recognize
+of the code the following:
+    1) create() is the definition of a function (hey! he did not declare it)
+    2) It makes calls to set_property(), set(), and set_exits(), none
+       of which are declared or defined in the code.
+    3) There is a line at the top that is no variable or function declaration
+       nor is it a function definition!
+
+This chapter will seek to answer the questions that should be in your head
+at this point:
+    1) Why is there no declaration of create()?
+    2) Where are the functions set_property(), set(), and set_exits() declared
+       and defined?
+    3) What the hell is that line at the top of the file?
+
+5.2 Object oriented programming
+Inheritance is one of the properties which define true object oriented
+programming (OOP).  It allows you to create generic code which can be used
+in many different ways by many different programs.  What a mudlib does is
+create these generalized files (objects) which you use to make very specific
+objects.
+
+If you had to write the code necessary for you to define the workroom above,
+you would have to write about 1000 lines of code to get all the functionality
+of the room above.  Clearly that is a waste of disk space.  In addition,
+such code does not interact well with players and other rooms since every
+creator is making up his or her own functions to perform the functionality
+of a room.  Thus, what you might use to write out the room's long description,
+query_long(), another wizard might be calling long().  This is the primary
+reason mudlibs are not compatible, since they use different protocols for
+object interaction.
+
+OOP overcomes these problems.  In the above workroom, you inherit the
+functions already defined in a file called "/std/room.c".  It has all
+the functions which are commonly needed by all rooms defined in it.  When
+you get to make a specific room, you are taking the general functionality
+of that room file and making a unique room by adding your own function,
+create().
+
+5.3 How inheritance works
+As you might have guessed by now, the line:
+
+-----
+inherit "/std/room";
+-----
+
+has you inherit the functionality of the room "/std/room.c".  By inheriting
+the functionality, it means that you can use the functions which have
+been declared and defined in the file "/std/room.c"  In the Nightmare Mudlib,
+"/std/room.c" has, among other functions, set_property(), set(), and
+set_exits() declared and defined.  In your function create(), you are
+making calls to those functions in order to set values you want your
+room to start with.  These values make your room different from others, yet
+able to interact well with other objects in memory.
+
+In actual practice, each mudlib is different, and thus requires you to use
+a different set of standard functions, often to do the same thing.  It is
+therefore beyond the scope of this textbook even to describe what
+functions exist and what they do.  If your mudlib is well documented,
+however, then (probably in /doc/build) you will have tutorials on how
+to use the inheritable files to create such objects.  These tutorials
+should tell you what functions exist, what input they take, the data
+type of their output, and what they do.
+
+5.4 Chapter summary
+This is far from a complete explanation of the complex subject of inheritance.
+The idea here is for you to be able to understand how to use inheritance in
+creating your objects.  A full discussion will follow in a later textbook.
+Right now you should know the following:
+    1) Each mudlib has a library of generic objects with their own general
+       functions used by creators through inheritance to make coding objects
+       easier and to make interaction between objects smoother.
+    2) The functions in the inheritable files of a mudlib vary from mudlib
+       to mudlib.  There should exist documentation on your mud on how to
+       use each inheritable file.  If you are unaware what functions are
+       available, then there is simply no way for you to use them.  Always
+       pay special attention to the data types of the input and the data
+       types of ay output.
+    3) You inherit the functionality of another object through the line:
+
+-----
+inherit "filename";
+-----
+       
+       where filename is the name of the file of the object to be inherited.
+       This line goes at the beginning of your code.
+
+Note:
+You may see the syntax ::create() or ::init() or ::reset() in places.
+You do not need fully to understand at this point the full nuances of this,
+but you should have a clue as to what it is. The "::" operator is a way
+to call a function specifically in an inherited object (called the scope
+resolution operator).  For instance, most muds' room.c has a function
+called create().  When you inherit room.c and configure it, you are doing
+what is called overriding the create() function in room.c.  This means
+that whenever ANYTHING calls create(), it will call *your* version and not
+the one in room.c.  However, there may be important stuff in the room.c
+version of create().  The :: operator allows you to call the create() in
+room.c instead of your create().
+An example:
+
+-----
+#1
+
+inherit "/std/room";
+
+void create() { create(); }
+-----
+
+-----
+#2
+
+inherit "/std/room";
+
+void create() { ::create(); }
+-----
+
+Example 1 is a horror.  When loaded, the driver calls create(), and then
+create() calls create(), which calls create(), which calls create()...
+In other words, all create() does is keep calling itself until the driver
+detects a too deep recursion and exits.
+
+Example 2 is basically just a waste of RAM, as it is no different from room.c
+functionally.  With it, the driver calls its create(), which in turn calls
+::create(), the create() in room.c.  Otherwise it is functionally
+exactly the same as room.c.
diff --git a/doc/KURS/LPC-KURS/chapter6 b/doc/KURS/LPC-KURS/chapter6
new file mode 100644
index 0000000..6a64215
--- /dev/null
+++ b/doc/KURS/LPC-KURS/chapter6
@@ -0,0 +1,333 @@
+                           LPC Basics
+                  Written by Descartes of Borg
+                  first edition: 23 april 1993
+                  second edition: july 5 1993
+
+CHAPTER 6: Variable Handling
+
+6.1 Review
+By now you should be able to code some simple objects using your muds standard
+object library.  Inheritance allows you to use functions defined in those
+objects without having to go and define yourself.  In addition,
+you should know how to declare your own functions.  This
+chapter will teach you about the basic elements of LPC which will allow you to
+define your own functions using the manipulation of variables.
+
+6.2 Values and objects
+Basically, what makes objects on the mud different are two things:
+1) Some have different functions
+2) All have different values
+
+Now, all player objects have the same functions.  They are therefore
+differentiated by the values they hold.  For instance, the player
+named "Forlock" is different from "Descartes" *at least* in that they
+have different values for the variable true_name, those being
+"descartes" and "forlock".
+
+Therefore, changes in the game involve changes in the values of the objects
+in the game.  Functions are used to name specific process for manipulating
+values.  For instance, the create() function is the function whose
+process is specifically to initialize the values of an object.
+Within a function, it is specifically things called instructions which are
+responsible for the direct manipulation of variables.
+
+6.3 Local and global variables
+Like variables in most programming language, LPC variables may be declared
+as variables "local" to a specific function, or "globally" available
+to all functions.  Local variables are declared inside the function which
+will use them.  No other function knows about their existence, since
+the values are only stored in memory while that function is being executed.
+A global variable is available to any function which comes after its
+declaration in the object code.  Since global variables take up RAM for
+the entire existence of the object, you should use them only when
+you need a value stored for the entire existence of the object.
+Have a look at the following 2 bits of code:
+
+-----
+int x;
+
+int query_x() { return x; }
+
+void set_x(int y) { x = y; }
+-----
+
+-----
+void set_x(int y) {
+    int x;
+
+    x = y;
+    write("x is set to x"+x+" and will now be forgotten.\n");
+}
+-----
+
+In the first example, x is declared outside of any functions, and therefore
+will be available to any function declared after it.  In that example,
+x is a global variable.
+In the second example, x is declared inside the function set_x().  It
+only exists while the function set_x() is being executed.  Afterwards,
+it ceases to exist.  In that example, x is a local variable.
+
+6.4 Manipulating the values of variables
+Instructions to the driver are used to manipulate the values of variables.
+An example of an instruction would be:
+
+-----
+x = 5;
+-----
+
+The above instruction is self-explanatory.  It assigns to the variable
+x the value 5.  However, there are some important concepts in involved
+in that instruction which are involved in instructions in general.
+The first involves the concept of an expression.  An expression is
+any series of symbols which have a value.  In the above instruction,
+the variable x is assigned the value of the expression 5.  Constant
+values are the simplest forms in which expressions can be put.  A constant
+is a value that never changes like the int 5 or the string "hello".
+The last concept is the concept of an operator.  In the above example,
+the assignment operator = is used.
+
+There are however many more operators in LPC, and expressions can get
+quite complex.  If we go up one level of complexity, we get:
+
+-----
+y = 5;
+x = y +2;
+-----
+
+The first instruction uses the assignment operator to assign the value
+of the constant expression 5 to the variable y.  The second one
+uses the assignment operator to assign to x the value of the expression
+(y+2) which uses the addition operator to come up with a value which
+is the sum of the value of y and the value of the constant expression 2.
+Sound like a lot of hot air?
+
+In another manner of speaking, operators can be used to form complex
+expressions.  In the above example, there are two expressions in the
+one instruction x = y + 2;:
+    1) the expression y+2
+    2) the expression x = y + 2
+As stated before, all expressions have a value.  The expression
+y+2 has the value of the sum of y and 2 (here, 7);
+The expression x = y + 2 *also* has the value of 7.
+So operators have to important tasks:
+    1) They *may* act upon input like a function
+    2) They evaluate as having a value themselves.
+Now, not all operators do what 1 does.  The = operators does act upon
+the value of 7 on its right by assigning that value to x.  The operator
++ however does nothing.  They both, however, have their own values.
+
+6.5 Complex expressions
+As you may have noticed above, the expression x = 5 *itself* has a value
+of 5.  In fact, since LPC operators themselves have value as expressions,
+they cal allow you to write some really convoluted looking nonsense like:
+    i = ( (x=sizeof(tmp=users())) ? --x : sizeof(tmp=children("/std/monster"))-1)
+which says basically:
+    assing to tmp the array returned by the efun users(), then assign to x
+    the value equal to the number of elements to that array.  If the value
+    of the expression assigning the value to x is true (not 0), then assign
+    x by 1 and assign the value of x-1 to i.  If x is false though,
+    then set tmp to the array returned by the efun children(), and then
+    assign to i the value of the number of members in the array tmp -1.
+Would you ever use the above statement? I doubt it.  However you might
+see or use expressions similar to it, since the ability to consolidate
+so much information into one single line helps to speed up the execution of
+your code.  A more often used version of this property of LPC operators
+would be something like:
+    x = sizeof(tmp = users());
+    while(i--) write((string)tmp[i]->query_name()+"\n");
+instead of writing something like:
+    tmp = users();
+    x = sizeof(tmp);
+    for(i=0; i<x; i++) write((string)tmp[i]->query_name()+"\n");
+Things like for(), while(), arrays and such will be explained later.
+But the first bit of code is more concise and it executed faster.
+
+NOTE: A detailed description of all basic LPC operators follows the chapter
+summary.
+
+
+6.6 Chapter Summary
+You now know how to declare variables and understand the difference between
+declaring and using them globally or locally.  Once you become familiar
+with your driver's efuns, you can display those values in many different
+ways.  In addition, through the LPC operators, you know how to change
+and evaluate the values contained in variables.  This is useful of course
+in that it allows you to do something like count how many apples have
+been picked from a tree, so that once all apples have been picked, no
+players can pick more.  Unfortunately, you do not know how to have
+code executed in anything other than a linera fashion.  In other words,
+hold off on that apple until the next chapter, cause you do not know
+how to check if the apples picked is equal to the number of apples in the
+tree.  You also do not know about the special function init() where you
+give new commands to players.  But you are almost ready to code a nice,
+fairly complex area.
+
+6.7 LPC operators
+This section contains a detailed listing of the simpler LPC operators,
+including what they do to the values they use (if anything) and the value
+that they have.
+
+The operators described here are:
+=    +    -    *    /    %    +=    -=    *=    /=    %=
+--    ++    ==    !=    >    <    >=    <=    !    &&    ||
+->    ? :
+
+Those operators are all described in a rather dry manner below, but it is best
+to at least look at each one, since some may not behave *exactly* as
+you think.  But it should make a rather good reference guide.
+
+= assignment operator:
+    example: x = 5;
+    value: the value of the variable on the *left* after its function is done
+    explanation: It takes the value of any expression on the *right* and
+      assigns it to the variable on the *left*.  Note that you must use
+      a single variable on the left, as you cannot assign values to 
+      constants or complex expressions.
+
++ addition operator:
+    example: x + 7
+    value: The sum of the value on the left and the value on the right
+    exaplanation: It takes the value of the expression on the right and
+      adds it to the value of the expression on the left. For values
+      of type int, this means the numerical sum.  For strings,
+      it means that the value on the right is stuck onto the value on
+      the left ("ab" is the value of "a"+"b").  This operator does not
+      modify any of the original values (i.e. the variable x from
+      above retains its old value).
+
+- subtraction operator:
+    example: x - 7
+    value: the value of the expression on the left reduced by the right
+    explanation:  Same characteristics as addition, except it subtracts.
+      With strings: "a" is the value of "ab" - "b"
+
+* multiplication operator:
+    example: x*7
+    value and explanation: same as with adding and subtracting except
+      this one performs the math of multiplication
+
+/ division operator:
+    example: x/7
+    value and explanation: see above
+
++= additive assignment operator:
+    example: x += 5
+    value: the same as x + 5
+    exaplanation: It takes the value of the variable on the left
+      and the value of the expression on the right, adds them together
+      and assigns the sum to the variable on the left.
+      example: if x = 2... x += 5 assigns the value
+        7 to the variable x.  The whole expression
+        has the value of 7.
+
+-= subtraction assignment operator
+    example: x-=7
+    value: the value of the left value reduced by the right value
+    examplanation: The same as += except for subtraction.
+
+*= multiplicative assignment operator
+    example: x *= 7
+    value: the value of the left value multiplied by the right
+    explanation: Similar to -= and += except for addition.
+
+/= division assignment operator
+    example: x /= 7
+    value: the value of the variable on the left divided by the right value
+    explanation: similar to above, except with division
+
+++ post/pre-increment operators
+    examples: i++ or ++i
+    values: 
+      i++ has the value of i
+      ++i has the value of i+1
+    explanation: ++ changes the value of i by increasing it by 1.
+      However, the value of the expression depends on where you
+      place the ++.  ++i is the pre-increment operator.  This means
+      that it performs the increment *before* giving a value.
+      i++ is the post-ncrement operator.  It evalutes before incrementing
+      i.  What is the point?  Well, it does not much matter to you at
+      this point, but you should recognize what it means.
+
+-- post/pre-decrement operators
+    examples: i-- or --i
+    values:
+      i-- the value of i
+      --i the value of i reduced by 1
+    explanation: like ++ except for subtraction
+
+== equality operator
+    example: x == 5
+    value: true or false (not 0 or 0)
+    explanation: it does nothing to either value, but
+      it returns true if the 2 values are the same.
+      It returns false if they are not equal.
+
+!= inequality operator
+    example: x != 5
+    value: true or false
+    explanation returns true if the left expression is not equal to the right
+      expression.  It returns fals if they are equal
+
+> greater than operator
+    example: x > 5
+    value: true or false
+    explanation: true only if x has a value greater than 5
+      false if the value is equal or less
+
+< less than operator
+>= greater than or equal to operator
+<= less than or equal to operator
+    examples: x < y    x >= y    x <= y
+    values: true or false
+    explanation: similar as to > except
+      < true if left is less than right
+      >= true if left is greater than *or equal to* right
+      <= true if the left is less than *or equal to* the right
+
+&& logical and operator
+|| logical or operator
+    examples: x && y      x || y
+    values: true or false
+    explanation: If the right value and left value are non-zero, && is true.
+      If either are false, then && is false.
+      For ||, only one of the values must be true for it to evaluate
+      as true.  It is only false if both values indeed
+      are false
+
+! negation operator
+    example: !x
+    value: true or false
+    explanation: If x is true, then !x is false
+      If x is false, !x is true.
+
+A pair of more complicated ones that are here just for the sake of being
+here.  Do not worry if they utterly confuse you.
+
+-> the call other operator
+    example: this_player()->query_name()
+    value: The value returned by the function being called
+    explanation:  It calls the function which is on the right in the object
+      on the left side of the operator.  The left expression *must* be
+      an object, and the right expression *must* be the name of a function.
+      If not such function exists in the object, it will return 0 (or
+      more correctly, undefined).
+
+? : conditional operator
+    example: x ? y : z
+    values: in the above example, if x is try, the value is y
+      if x is false, the value of the expression is z
+    explanation: If the leftmost value is true, it will give the expression as
+      a whole the value of the middle expression.  Else, it will give the
+      expression as a whole the value of the rightmost expression.
+
+A note on equality:  A very nasty error people make that is VERY difficult
+to debug is the error of placing = where you mean ==.  Since
+operators return values, they both make sense when being evaluated.
+In other words, no error occurs.  But they have very different values.  For example:
+  if(x == 5)    if(x = 5)
+The value of x == 5 is true if the value of x is 5, false othewise.
+The value of x = 5 is 5 (and therefore always true).
+The if statement is looking for the expression in () to be either true or false,
+so if you had = and meant ==, you would end up with an expression that is
+always true.  And you would pull your hair out trying to figure out
+why things were not happening like they should :)
diff --git a/doc/KURS/LPC-KURS/chapter7 b/doc/KURS/LPC-KURS/chapter7
new file mode 100644
index 0000000..39f311b
--- /dev/null
+++ b/doc/KURS/LPC-KURS/chapter7
@@ -0,0 +1,432 @@
+                           LPC Basics
+                  Written by Descartes of Borg
+                  first edition: 23 april 1993
+                  second edition: 10 july 1993
+
+CHAPTER 7: Flow Control
+
+7.1 Review of variables
+Variables may be manipulated by assigning or changing values with the
+expressions =, +=, -=, ++, --.  Those expressions may be combined with
+the expressions -, +, *, /, %.  However, so far, you have only been
+shown how to use a function to do these in a linear way.  For example:
+ 
+int hello(int x) {
+    x--;
+    write("Hello, x is "+x+".\n");
+    return x;
+}
+ 
+is a function you should know how to write and understand.  But what
+if you wanted to write the value of x only if x = 1?  Or what if
+you wanted it to keep writing x over and over until x = 1 before
+returning?  LPC uses flow control in exactly the same way as C and C++.
+
+7.2 The LPC flow control statements
+LPC uses the following expressions:
+ 
+if(expression) instruction;
+ 
+if(expression) instruction;
+else instruction;
+ 
+if(expression) instruction;
+else if(expression) instruction;
+else instruction;
+ 
+while(expression) instruction;
+ 
+do { instruction; } while(expression);
+ 
+switch(expression) {
+    case (expression): instruction; break;
+    default: instruction;
+}
+ 
+Before we discuss these, first something on what is meant by expression and
+instruction.  An expression is anything with a value like a variable,
+a comparison (like x>5, where if x is 6 or more, the value is 1, else the
+value is 0), or an assignment(like x += 2).  An instruction can be any
+single line of lpc code like a function call, a value assignment or
+modification, etc.
+ 
+You should know also the operators &&, ||, ==, !=, and !.  These are the
+logical operators.  They return a nonzero value when true, and 0 when false.
+Make note of the values of the following expressions:
+ 
+(1 && 1) value: 1   (1 and 1)
+(1 && 0) value: 0   (1 and 0)
+(1 || 0) value: 1   (1 or 0)
+(1 == 1) value: 1   (1 is equal to 1)
+(1 != 1) value: 0   (1 is not equal to 1)
+(!1) value: 0       (not 1)
+(!0) value: 1       (not 0)
+ 
+In expressions using &&, if the value of the first item being compared
+is 0, the second is never tested even.  When using ||, if the first is
+true (1), then the second is not tested.
+ 
+7.3 if()
+The first expression to look at that alters flow control is if().  Take
+a look at the following example:
+ 
+1 void reset() {
+2     int x;
+3
+4     ::reset();
+5     x = random(10);
+6     if(x > 50) set_search_func("floorboards", "search_floor");
+7 }
+ 
+The line numbers are for reference only.
+In line 2, of course we declare a variable of type int called x.  Line 3
+is aethetic whitespace to clearly show where the declarations end and the
+function code begins.  The variable x is only available to the function
+reset().
+Line 4 makes a call to the room.c version of reset().
+Line 5 uses the driver efun random() to return a random number between
+0 and the parameter minus 1.  So here we are looking for a number between
+0 and 99.
+In line 6, we test the value of the expression (x>50) to see if it is true
+or false.  If it is true, then it makes a call to the room.c function
+set_search_func().  If it is false, the call to set_search_func() is never
+executed.
+In line 7, the function returns driver control to the calling function
+(the driver itself in this case) without returning any value.
+ 
+If you had wanted to execute multiple instructions instead of just the one,
+you would have done it in the following manner:
+ 
+if(x>50) {
+    set_search_func("floorboards", "search_floor");
+    if(!present("beggar", this_object())) make_beggar();
+}
+ 
+Notice the {} encapsulate the instructions to be executed if the test
+expression is true.  In the example, again we call the room.c function
+which sets a function (search_floor()) that you will later define yourself
+to be called when the player types "search floorboards" (NOTE: This is
+highly mudlib dependent.  Nightmare mudlibs have this function call.
+Others may have something similar, while others may not have this feature
+under any name).  Next, there is another if() expression that tests the
+truth of the expression (!present("beggar",this_object())).  The ! in the
+test expression changes the truth of the expression which follows it.  In
+this case, it changes the truth of the efun present(), which will return
+the object that is a beggar if it is in the room (this_object()), or it
+will return 0 if there is no beggar in the room.  So if there is a beggar
+still living in the room, (present("beggar", this_object())) will have
+a value equal to the beggar object (data type object), otherwise it will
+be 0.  The ! will change a 0 to a 1, or any nonzero value (like the
+beggar object) to a 0.  Therefore, the expression
+(!present("beggar", this_object())) is true if there is no beggar in the
+room, and false if there is.  So, if there is no beggar in the room,
+then it calls the function you define in your room code that makes a
+new beggar and puts it in the room. (If there is a beggar in the room,
+we do not want to add yet another one :))
+ 
+Of course, if()'s often comes with ands or buts :).  In LPC, the formal
+reading of the if() statement is:
+ 
+if(expression) { set of intructions }
+else if(expression) { set of instructions }
+else { set of instructions }
+ 
+This means:
+ 
+If expression is true, then do these instructions.
+Otherise, if this second expression is true, do this second set.
+And if none of those were true, then do this last set.
+ 
+You can have if() alone:
+ 
+if(x>5) write("Foo,\n");
+ 
+with an else if():
+ 
+if(x > 5) write("X is greater than 5.\n");
+else if(x >2) write("X is less than 6, but greater than 2.\n");
+ 
+with an else:
+ 
+if(x>5) write("X is greater than 5.\n");
+else write("X is less than 6.\n");
+ 
+or the whole lot of them as listed above.  You can have any number of
+else if()'s in the expression, but you must have one and only one
+if() and at most one else.  Of course, as with the beggar example,
+you may nest if() statements inside if() instructions. (For example,
+    if(x>5) {
+        if(x==7) write("Lucky number!\n");
+        else write("Roll again.\n");
+    }
+    else write("You lose.\n");
+ 
+7.4 The statements: while() and do {} while()
+Prototype:
+while(expression) { set of instructions }
+do { set of instructions } while(expression);
+ 
+These allow you to create a set of instructions which continue to
+execute so long as some expression is true.  Suppose you wanted to
+set a variable equal to a player's level and keep subtracting random
+amounts of either money or hp from a player until that variable equals
+0 (so that player's of higher levels would lose more).  You might do it
+this way:
+ 
+1    int x;
+2
+3    x = (int)this_player()->query_level();  /* this has yet to be explained */
+4    while(x > 0) {
+5        if(random(2)) this_player()->add_money("silver", -random(50));
+6        else this_player()->add_hp(-(random(10));
+7        x--;
+8    }
+ 
+The expression this_player()->query_level() calIn line 4, we start a loop that executes so long as x is greater than 0.
+    Another way we could have done this line would be:
+        while(x) {
+    The problem with that would be if we later made a change to the funtion
+y anywhere between 0 and 49 coins.
+In line 6, if instead it returns 0, we call the add_hp() function in the
+    player which reduces the player's hit points anywhere between 0 and 9 hp.
+In line 7, we reduce x by 1.
+At line 8, the execution comes to the end of the while() instructions and
+    goes back up to line 4 to see if x is still greater than 0.  This
+    loop will keep executing until x is finally less than 1.
+ 
+You might, however, want to test an expression *after* you execute some
+instructions.  For instance, in the above, if you wanted to execute
+the instructions at least once for everyone, even if their level is
+below the test level:
+ 
+    int x;
+ 
+    x = (int)this_player()->query_level();
+    do {
+        if(random(2)) this_player()->add_money("silver", -random(50));
+        else this_player()->add_hp(-random(10));
+        x--;
+    } while(x > 0);
+ 
+This is a rather bizarre example, being as few muds have level 0 players.
+And even still, you could have done it using the original loop with
+a different test.  Nevertheless, it is intended to show how a do{} while()
+works.  As you see, instead of initiating the test at the beginning of the
+loop (which would immediately exclude some values of x), it tests after
+the loop has been executed.  This assures that the instructions of the loop
+get executed at least one time, no matter what x is.
+ 
+7.5 for() loops
+Prototype:
+for(initialize values ; test expression ; instruction) { instructions }
+ 
+initialize values:
+This allows you to set starting values of variables which will be used
+in the loop.  This part is optional.
+ 
+test expression:
+Same as the expression in if() and while().  The loop is executed
+as long as this expression (or expressions) is true. You must have a
+test expression.
+ 
+instruction:
+An expression (or expressions) which is to be executed at the end of each
+loop.  This is optional.
+ 
+Note:
+for(;expression;) {}
+IS EXACTLY THE SAME AS
+while(expression) {}
+ 
+Example:
+ 
+1    int x;
+2
+3    for(x= (int)this_player()->query_level(); x>0; x--) {
+4        if(random(2)) this_player()->add_money("silver", -random(50));
+5        else this_player()->add_hp(-random(10));
+6    }
+ 
+This for() loop behaves EXACTLY like the while() example.
+Additionally, if you wanted to initialize 2 variables:
+ 
+for(x=0, y=random(20); x<y; x++) { write(x+"\n"); }
+ 
+Here, we initialize 2 variables, x and y, and we separate them by a
+comma.  You can do the same with any of the 3 parts of the for()
+expression.
+ 
+7.6 The statement: switch()
+Prototype:
+switch(expression) {
+    case constant: instructions
+    case constant: instructions
+    ...
+    case constant: instructions
+    default: instructions
+}
+ 
+This is functionally much like if() expressions, and much nicer to the
+CPU, however most rarely used because it looks so damn complicated.
+But it is not.
+ 
+First off, the expression is not a test.  The cases are tests.  A English
+sounding way to read:
+ 
+1    int x;
+2
+3    x = random(5);
+4    switch(x) {
+5        case 1: write("X is 1.\n");
+6        case 2: x++;
+7        default: x--;
+8    }
+9    write(x+"\n");
+ 
+is:
+ 
+set variable x to a random number between 0 and 4.
+In case 1 of variable x write its value add 1 to it and subtract 1.
+In case 2 of variable x, add 1 to its value and then subtract 1.
+In other cases subtract 1.
+Write the value of x.
+ 
+switch(x) basically tells the driver that the variable x is the value
+we are trying to match to a case.
+Once the driver finds a case which matches, that case *and all following
+cases* will be acted upon.  You may break out of the switch statement
+as well as any other flow control statement with a break instruction in
+order only to execute a single case.  But that will be explained later.
+The default statement is one that will be executed for any value of
+x so long as the switch() flow has not been broken.  You may use any
+data type in a switch statement:
+ 
+string name;
+ 
+name = (string)this_player()->query_name();
+switch(name) {
+    case "descartes": write("You borg.\n");
+    case "flamme":
+    case "forlock":
+    case "shadowwolf": write("You are a Nightmare head arch.\n");
+    default: write("You exist.\n");
+}
+ 
+For me, I would see:
+You borg.
+You are a Nightmare head arch.
+You exist.
+ 
+Flamme, Forlock, or Shadowwolf would see:
+You are a Nightmare head arch.
+You exist.
+ 
+Everyone else would see:
+You exist.
+ 
+7.7 Altering the flow of functions and flow control statements
+The following instructions:
+return    continue    break
+ 
+alter the natural flow of things as described above.
+First of all,
+return
+no matter where it occurs in a function, will cease the execution of that
+function and return control to the function which called the one the
+return statement is in.  If the function is NOT of type void, then a
+value must follow the return statement, and that value must be of a
+type matching the function.  An absolute value function would look
+like this:
+ 
+int absolute_value(int x) {
+    if(x>-1) return x;
+    else return -x;
+}
+ 
+In the second line, the function ceases execution and returns to the calling
+function because the desired value has been found if x is a positive
+number.
+ 
+continue is most often used in for() and while statements.  It serves
+to stop the execution of the current loop and send the execution back
+to the beginning of the loop.  For instance, say you wanted to avoid
+division by 0:
+ 
+x= 4;
+while( x > -5) {
+    x--
+    if(!x) continue;
+    write((100/x)+"\n");
+}
+write("Done.\n")
+ 
+You would see the following output:
+33
+50
+100
+-100
+-50
+-33
+-25
+Done.
+To avoid an error, it checks in each loop to make sure x is not 0.
+If x is zero, then it starts back with the test expression without
+finishing its current loop.
+ 
+In a for() expression
+ for(x=3; x>-5; x--) {
+    if(!x) continue;
+    write((100/x)+"\n");
+ }
+ write("Done.\n");
+It works much the same way.  Note this gives exactly the same output
+as before. At x=1, it tests to see if x is zero, it is not, so it
+writes 100/x, then goes back to the top, subtracts one from x, checks to
+see if it is zero again, and it is zero, so it goes back to the top
+and subtracts 1 again.
+ 
+break
+This one ceases the function of a flow control statement.  No matter
+where you are in the statement, the control of the program will go
+to the end of the loop.  So, if in the above examples, we had
+used break instead of continue, the output would have looked like this:
+ 
+33
+50
+100
+Done.
+ 
+continue is most often used with the for() and while() statements.
+break however is mostly used with switch()
+ 
+switch(name) {
+    case "descartes": write("You are borg.\n"); break;
+    case "flamme": write("You are flamme.\n"); break;
+    case "forlock": write("You are forlock.\n"); break;
+    case "shadowwolf": write("You are shadowwolf.\n"); break;
+    default: write("You will be assimilated.\n");
+}
+ 
+This functions just like:
+ 
+if(name == "descartes") write("You are borg.\n");
+else if(name == "flamme") write("You are flamme.\n");
+else if(name == "forlock") write("You are forlock.\n");
+else if(name == "shadowwolf") write("You are shadowwolf.\n");
+else write("You will be assimilated.\n");
+ 
+except the switch statement is much better on the CPU.
+If any of these are placed in nested statements, then they alter the
+flow of the most immediate statement.
+ 
+7.8 Chapter summary
+This chapter covered one hell of a lot, but it was stuff that needed to
+be seen all at once.  You should now completely understand if() for()
+while() do{} while() and switch(), as well as how to alter their flow
+using return, continue, and break.  Effeciency says if it can be done in
+a natural way using switch() instead of a lot of if() else if()'s, then
+by all means do it.  You were also introduced to the idea of calling
+functions in other objects.  That however, is a topic to be detailed later.
+You now should be completely at ease writing simple rooms (if you have
+read your mudlib's room building document), simple monsters, and
+other sorts of simple objects.
diff --git a/doc/KURS/LPC-KURS/chapter8 b/doc/KURS/LPC-KURS/chapter8
new file mode 100644
index 0000000..a794713
--- /dev/null
+++ b/doc/KURS/LPC-KURS/chapter8
@@ -0,0 +1,195 @@
+                           LPC Basics
+                  Written by Descartes of Borg
+                  first edition: 23 april 1993
+                  second edition: 12 july 1993
+
+CHAPTER 8: The data type "object"
+
+8.1 Review
+You should now be able to do anything so long as you stick to calling
+functions within your own object.  You should also know, that at the
+bare minimum you can get the create() (or reset()) function in your object
+called to start just by loading it into memory, and that your reset()
+function will be called every now and then so that you may write the
+code necessary to refresh your room.  Note that neither of these
+functions MUST be in your object.  The driver checks to see if the
+function exists in your object first.  If it does not, then it does not
+bother.  You are also acquainted with the data types void, int, and string.
+ 
+7.2 Objects as data types
+In this chapter you will be acquainted with a more complex data type,
+object.  An object variable points to a real object loaded into the
+driver's memory.  You declare it in the same manner as other data types:
+    object ob;
+It differs in that you cannot use +, -, +=, -=, *, or / (what would it
+mean to divide a monster by another monster?).  And since efuns like
+say() and write() only want strings or ints, you cannot write() or
+say() them (again, what would it mean to say a monster?).
+But you can use them with some other of the most important efuns on any
+LPMud.
+ 
+8.3 The efun: this_object()
+This is an efun which returns an object in which the function being executed
+exists.  In other words, in a file, this_object() refers to the object your
+file is in whether the file gets cloned itself or inherted by another file.
+It is often useful when you are writing a file which is getting inherited
+by another file.  Say you are writing your own living.c which gets
+inherited by user.c and monster.c, but never used alone.  You want to log
+the function set_level() it is a player's level being set (but you do not
+care if it is a monster.
+You might do this:
+ 
+void set_level(int x) {
+    if(this_object()->is_player()) log_file("levels", "foo\n");
+    level = x;
+}
+ 
+Since is_player() is not defined in living.c or anything it inherits,
+just saying if(is_player()) will result in an error since the driver
+does not find that function in your file or anything it inherits.
+this_object() allows you to access functions which may or may not be
+present in any final products because your file is inherited by others
+without resulting in an error.
+ 
+8.4 Calling functions in other objects
+This of course introduces us to the most important characteristic of
+the object data type.  It allows us to access functions in other objects.
+In previous examples you have been able to find out about a player's level,
+reduce the money they have, and how much hp they have.
+Calls to functions in other objects may be done in two ways:
+ 
+object->function(parameters)
+call_other(object, "function", parameters);
+ 
+example:
+this_player()->add_money("silver", -5);
+call_other(this_player(), "add_money", "silver", -5);
+ 
+In some (very loose sense), the game is just a chain reaction of function
+calls initiated by player commands.  When a player initiates a chain of
+function calls, that player is the object which is returned by
+the efun this_player().  So, since this_player() can change depending
+on who initiated the sequence of events, you want to be very careful
+as to where you place calls to functions in this_player().  The most common
+place you do this is through the last important lfun (we have mentioned
+create() and reset()) init().
+ 
+8.5 The lfun: init()
+Any time a living thing encounters an object (enters a new room, or enters
+the same room as a certain other object), init() is called in all of
+the objects the living being newly encounters.  It is at this point
+that you can add commands the player can issue in order to act.
+Here is a sample init() function in a flower.
+ 
+void init() {
+    ::init();
+    add_action("smell_flower", "smell");
+}
+ 
+Ito smell_flower().  So you should have smell_flower() look like this:
+ 
+1 int smell_flower(string str);        /* action functions are type int */
+2
+3 int smell_flower(string str) {
+4    if(str != "flower") return 0;     /* it is not the flower being smelled */
+5    write("You sniff the flower.\n");
+6    say((string)this_player()->query_cap_name()+" smells the flower.\n");
+7    this_player()->add_hp(random(5));
+8    return 1;
+9 }
+ 
+In line 1, we have our function declared.
+In line 3, smell_flower() begins.  str becomes whatever comes after the
+    players command (not including the first white space).
+In line 4, it checks to see if the player had typed "smell flower".  If
+    the player had typed "smell cheese", then str would be "cheese".  If
+    it is not in fact "flower" which is being smelled, then 0 is returned,
+    letting the driver know that this was not the function which should
+    have been called.  If in fact the player had a piece of cheese as well
+    which had a smell command to it, the driver would then call the function
+    for smelling in that object.  The driver will keep calling all functions
+    tied to smell commands until one of them returns 1.  If they all return
+    0, then the player sees "What?"
+In line 5, the efun write() is called.  write() prints the string which
+    is passed to it to this_player().  So whoever typed the command here
+    sees "You sniff the flower."
+In line 6, the efun say() is called.  say() prints the string which is
+    doing the sniffing, we have to call the query_cap_name() function
+    in this_player().  That way if the player is invis, it will say
+    "Someone" (or something like that), and it will also be properly
+    capitalized.
+In line 7, we call the add_hp() function in the this_player() object,
+    since we want to do a little healing for the sniff (Note: do not
+    code this object on your mud, whoever balances your mud will shoot you).
+In line 8, we return control of the game to the driver, returning 1 to
+    let it know that this was in fact the right function to call.
+ 
+8.6 Adding objects to your rooms
+And now, using the data type object, you can add monsters to your rooms:
+ 
+void create() {
+    ::create();
+    set_property("light", 3);
+    set("short", "Krasna Square");
+    set("long", "Welcome to the Central Square of the town of Praxis.\n");
+    set_exits( ({ "d/standard/hall" }), ({ "east" }) );
+}
+ 
+void reset() {
+    object ob;
+ 
+    ::reset();
+    if(present("guard")) return;     /* Do not want to add a guard if */
+    ob = new("/std/monster");        /* one is already here           */
+    ob->set_name("guard");
+    ob->set("id", ({ "guard", "town guard" }) );
+    ob->set("short", "Town guard");
+    ob->set("long", "He guards Praxis from nothingness.\n");
+    ob->set_gender("male");
+    ob->set_race("human");
+    ob->set_level(10);
+    ob->set_alignment(200);
+    ob->set_humanoid();
+    ob->set_hp(150);
+    ob->set_wielding_limbs( ({ "right hand", "left hand" }) );
+    ob->move(this_object());
+}
+ 
+Now, this will be wildly different on most muds.  Some, as noted before,
+in that object so you have a uniquely configured monster object.  The
+last act in native muds is to call move() in the monster object to move
+it to this room (this_object()).  In compat muds, you call the efun
+move_object() which takes two parameters, the object to be moved, and the
+object into which it is being moved.
+ 
+8.7 Chapter summary
+At this point, you now have enough knowledge to code some really nice
+stuff.  Of course, as I have been stressing all along, you really need
+to read the documents on building for your mud, as they detail which
+functions exist in which types of objects for you to call.  No matter
+what your knowledge of the mudlib is, you have enough know-how to
+give a player extra things to do like sniffing flowers or glue or whatever.
+At this point you should get busy coding stuff.  But the moment things
+even look to become tedious, that means it is time for you to move to
+the next level and do more.  Right now code yourself a small area.
+Make extensive use of the special functions coded in your mud's
+room.c (search the docs for obscure ones no one else seems to use).
+Add lots o' neat actions.  Create weapons which have magic powers which
+gradually fade away.  All of this you should be able to do now.  Once
+this becomes routine for you, it will be time to move on to intermediate
+stuff.  Note that few people actually get to the intermediate stuff.
+If you have played at all, you notice there are few areas on the mud
+which do what I just told you you should be able to do.  It is not
+because it is hard, but because there is a lot of arrogance out there
+on the part of people who have gotten beyond this point, and very little
+communicating of that knowledge.  The trick is to push yourself and
+think of something you want to do that is impossible.  If you ask someone
+in the know how to do X, and they say that is impossible, find out
+youself how to code it by experimenting.
+
+George Reese
+Descartes of Borg
+12 july 1993
+borg@hebron.connected.com
+Descartes@Nightmare (intermud)
+Descartes@Igor (not intermud)
diff --git a/doc/KURS/LPC-KURS2/Contents b/doc/KURS/LPC-KURS2/Contents
new file mode 100644
index 0000000..ff58a8a
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/Contents
@@ -0,0 +1,15 @@
+Intermediate LPC
+Descartes of Borg 
+November 1993
+
+                                   Contents
+
+1: Introduction
+2: The LPMud Driver
+3: Complex Data Types
+4: The LPC Pre-Compiler
+5: Advanced String Handling
+6: Intermediate Inheritance
+7: Debugging
+
+Copyright (c) George Reese 1993
diff --git a/doc/KURS/LPC-KURS2/Copyright b/doc/KURS/LPC-KURS2/Copyright
new file mode 100644
index 0000000..29a2620
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/Copyright
@@ -0,0 +1,62 @@
+                      Intermediate LPC first edition
+
+Copyright (c) 1993 George Reese
+All rights to this text are retained by the author.
+
+
+Permission is granted to distrubute and display the contents of this
+document in full so long as the following conditions are met:
+1) No payment may be received for the redistribution or display of this text,
+except to cover the costs for distribution media and and shipping and/or
+transmission charges.
+2) The textbook must be distributed or displayed in its entirety in its original
+form.  Changes may only be made to private, individual copies, except as
+outlined below.
+
+Acceptable changes are defined as the following:
+1) Format changes, such as changing from WordPerfect to Word 
+2) Medium changes, such as from electronic copy to paper
+3) Content changes are only acceptable under the following circumstances:
+	a) In electronic media: none of the original text may be ommitted. 
+        You may add comments
+	as you feel necessary, so long as comments are enclosed in <* *>
+        and are accompanied by
+	the game name or real name of the author of the comments
+	b) In hard copy: none of the original text may be omitted, but it may
+        be struck out so long
+	as the content of the original text is visible.  Comments may be made
+        in any form so long 
+	as they are made in handwriting and they are signed by the author. 
+        Comments which are typed or printed must be made in accordance with the
+        format for electronic media.
+
+Practically speaking, this is what I mean:
+First, I wrote this mostly for mud admins to put onto their muds for learning
+coders to read as they are learning to build realms.  I did not do this for
+someone else to make a buck.  So if you charge money for redistributing it
+or allowing someone else to see it, you are in violation of this copyright. 
+Unless you are simply charging for what it cost you to print up a copy or
+what the diskettes and postage cost to mail it.
+Second, I wrote this textbook, and I should receive credit/blame for what I
+say, and others should receive credit/blame for what they say.  For example,
+if I said something completely wrong, and you simply corrected it, I would
+be getting credit for something I did not do.  Yet, if you comment according
+to the outline above, you will be properly credited for your comments. 
+More important to me, however, is the practical effect of having hundreds of
+copies of this textbook everywhere.  If you change something I had right
+without noting it as a comment, I will be blamed for spreading
+misinformation.  This problem is only compunded if the text is redistributed. 
+So I prefer my words to remain my own.  But, when I make mistakes, or if
+something I say does not fit your driver/mudlib, please comment it so people
+will know.  In addition, having the comments side-by-side allows people to
+see other ideas, like how another driver might handle something.
+
+
+I want to please note again, you may display this on your mud (like in /doc). 
+You do not need to
+mail me for permission.  I would not mind email, since it is nice to know
+people are using it, but that is not required.  Also, if you really feel I have
+done such a wonderful job that you should pay money to use this, then give
+$5 to your local ASPCA (or international equivalent).
+
+See the file titled Contents for a full list of textbook chapters.
diff --git a/doc/KURS/LPC-KURS2/chapter1 b/doc/KURS/LPC-KURS2/chapter1
new file mode 100644
index 0000000..6c459cd
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/chapter1
@@ -0,0 +1,143 @@
+Intermediate LPC
+Descartes of Borg
+Novermber 1993
+
+                         Chapter 1: Introduction
+
+1.1 LPC Basics
+Anyone reading this textbook should either have read the textbook LPC
+Basics or be familiar enough with mud realm coding such that not only are
+they capable of building rooms and other such objects involved in area
+coding, but they also have a good idea of what is going on when the code
+they write is executing.  If you do not feel you are at this point, then go
+back and read LPC Basics before continuing.  If you do so, you will find
+that what you read here will be much more meaningful to you.
+
+1.2 Goals of This Textbook
+The introductory textbook was meant to take people new to LPC from
+knowing nothing to being able to code a nice realm on any LPMud.  There
+is naturally much more to LPC and to LPMud building, however, than
+building rooms, armours, monsters, and weapons.  As you get into more
+complicated concepts like guilds, or desire to do more involved things with
+your realm, you will find the concepts detailed in LPC Basics to be lacking
+in support for these projects.  Intermediate LPC is designed to take you
+beyond the simple realm building process into a full knowledge of LPC for
+functioning as a realm builder on an LPMud.  The task of mudlib building
+itself is left to a later text.  After reading this textbook and working through
+it by experimenting with actual code, the reader should be able to code game
+objects to fit any design or idea they have in mind, so long as I have been
+successful.
+
+1.3 An Overview
+What more is there?  Well many of you are quite aware that LPC supports
+mappings and arrays and have been asking me why those were not detailed
+in LPC Basics.  I felt that those concepts were beyond the scope of what I
+was trying to do with that textbook and were more fitting to this textbook. 
+But new tools are all fine and dandy, what matters, however, is what you
+can do with those tools.  The goal of LPC Basics was to get you to building
+quality LPMud realms.  Mappings and arrays are not necessary to do that. 
+The goal of this book is to allow you to code any idea you might want to
+code in your area.  That ability requires the knowledge of mappings and
+arrays.
+
+Any idea you want to code in an LPMud is possible.  LPC is a language
+which is amazingly well suited to this task.  All that prevents you from
+coding your ideas is your knowledge of LPC or an inadequate mudlib or
+your mudÕs theme or administrative policies.  This textbook cannot make
+the mudlib you are working with any better, and it cannot change the mud
+theme or the mudÕs administrative policies.  Never once think that LPC is
+incapable of doing what you want to do.  If your idea is prevented by
+administrative policies or themes, then it is simply not an idea for your
+current mud.  If the mudlib is inadequate, talk to the people in charge of
+your mudlib about what can be done at the mudlib level to facilitate it.  You
+would be surprised by what is actually in the mudlib you did not know
+about.  More important, after reading this textbook, you should be able to
+read all of the mudlib code in your mudÕs mudlib and understand what is
+going on at each line in the mudlib code.  You may not as yet be able to
+reproduce that code on your own, but at least you can understand what is
+going on at the mudlib level.
+
+This textbook starts out with a discussion about what the LPMud driver is
+doing.  One nice thing about this textbook, in general it is completely driver
+and mudlib independent (excepting for the Dworkin Game Driver).  The
+chapter on the game driver does not get into actual implementation, but
+instead deals with what all game drivers basically do in order to run the
+mud.
+
+Next I discuss those magic topics everyone wants to know more about,
+arrays and mappings.  Mappings may be simultaneously the easiest and
+most difficult data type to understand.  Since they are sort of complex arrays
+in a loose sense, you really need to understand arrays before discussing
+them.  All the same, once you understand them, they are much easier than
+arrays to use in real situations.  At any rate, spend most of your time
+working with that chapter, because it is probably the most difficult, yet most
+useful chapter in the book.
+
+After that follows a brief chapter on the LPC pre-compiler, a tool you can
+use for sorting out how your code will look before it gets sent to the
+compiler.  Despite my horrid intro to it here, this chapter is perhaps the
+easiest chapter in the textbook.  I put it after the mappings and arrays
+chapter for exactly that reason.
+
+Strings are re-introduced next, going into more detail with how you can do
+such things as advanced command handling by breaking up strings.  Once
+you understand arrays fairly well, this chapter should be really simple.
+
+The next chapter is the second most important in the book.  It may be the
+most important if you ever intend to go beyond the intermediate stage and
+dive into mudlib coding.  That chapter involves the complex ideas behind
+LPC inheritance.  Since the goal of this textbook is not to teach mudlib
+programming, the chapter is not a detailed discussion on object oriented
+programming.  Understanding this chapter, however, will give you some
+good insights into what is involved with object oriented programming, as
+well as allow you to build more complex objects by overriding functions
+and defining your own base classes.
+
+Finally, the textbook ends with a simple discussion of code debugging. 
+This is not an essential chapter, but instead it is meant as more of an
+auxiliary supplement to what the knowledge you have accumulated so far.
+
+1.4 Not Appearing in This Textbook
+Perhaps what might appear to some as the most glaring omission of this
+textbook is largely a political omission, shadows.  Never have I ever
+encountered an example of where a shadow was either the best or most
+effecient manner of doing anything.  It does not follow from that, however,
+that there are no uses for shadows.  My reasoning for omitting shadows
+from this textbook is that the learner is best served by learning the concepts
+in this textbook first and having spent time with them before dealing with
+the subject of shadows.  In that way, I feel the person learning LPC will be
+better capable of judging the merits of using a shadow down the road.  I
+will discuss shadows in a future textbook.
+
+If you are someone who uses shadows some or a lot, please do not take the
+above paragraph as a personal attack.  There may be some perfectly valid
+uses for shadows somewhere which I have yet to encounter.  Nevertheless,
+they are not the ideal way to accomplish any given task, and therefore they
+are not considered for the purposes of this textbook an intermediate coding
+tool.
+
+I have also omitted discussions of security and object oriented
+programming.  Both are quite obviously mudlib issues.  Many people,
+however, might take exception with my leaving out a discussion of object
+oriented programming.  I chose to leave that for a later text, since most area
+builders code for the creativity, not for the computer science theory.  In both
+the intermediate and beginner textbooks, I have chosen only to discuss
+theory where it is directly applicable to practical LPC programming.  For
+people who are starting out green in LPC and want to code the next great
+mudlib, perhaps theory would be more useful.  But for the purposes of this
+book, a discussion of object oriented programming is simply a snoozer.  I
+do plan to get heavy into theory with the next textbook.
+
+1.5 Summary
+LPC is not difficult to learn.  It is a language which, although pathetic
+compared to any other language for performing most computer language
+tasks, is incredibly powerful and unequalled for the tasks of building an
+area in MUD type games.  For the beginner, it allows you to easily jump in
+and code useful objects without even knowing what you are doing.  For the
+intermediate person, it allows you to turn any idea you have into textual
+virtual reality.  And for the advanced person, itÕs object oriented features
+can allow you to build one of the most popular games on the internet.  What
+you can do is simply limited by how much you know.  And learning more
+does not require a computer science degree.
+
+Copyright (c) George Reese 1993
diff --git a/doc/KURS/LPC-KURS2/chapter2 b/doc/KURS/LPC-KURS2/chapter2
new file mode 100644
index 0000000..51a4c3c
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/chapter2
@@ -0,0 +1,223 @@
+Intermediate LPC
+Descartes of Borg
+Novermber 1993
+
+                         Chapter 2: The LPMud Driver
+
+2.1 Review of Basic Driver/Mudlib Interaction
+In the LPC Basics textbook, you learned a lot about the way the mudlib
+works, specifically in relation to objects you code in order to build your
+realm.  Not much was discussed about the interaction between the
+mudlib and the driver.  You should know, however, that the driver
+does the following:
+1) When an object is first loaded into memory, the driver will call
+create() in native muds and reset() in compat muds.  A creator
+uses create() or reset() to give initial values to the object.
+2) At an interval setup by the game administrator, the driver calls the
+function reset().  This allows the object to regenerate monsters and
+such.  Notice that in a compat mud, the same function is used to set up
+initial values as is used to reset the room.
+3) Any time a living object comes in contact with an object of any sort,
+the driver calls init() in the newly encountered object.  This allows
+newly encountered objects to give living objects commands to execute
+through the add_action() efun, as well as perform other actions which
+should happen whenever a living thing encounters a given object.
+4) The driver defines a set of functions known as efuns which are
+available to all objects in the game.  Examples of commonly used efuns
+are: this_player(), this_object(), write(), say(), etc.
+
+2.2 The Driver Cycle
+The driver is a C program which runs the game.  Its basic functions are
+to accept connections from the outside world so people can login,
+interpret the LPC code which defines LPC objects and how they
+function in the game, and accept user input and call the appropriate LPC
+functions which match the event.  In its most simplest essence, it is an
+unending loop.
+
+Once the game has booted up and is properly functioning (the boot up
+process will be discussed in a future, advanced LPC textbook), the
+driver enters a loop which does not terminate until the shutdown() efun
+is legally called or a bug causes the driver program to crash.  First off,
+the driver handles any new incoming connections and passes control of
+the connection to a login object.  After that, the driver puts together a
+table of commands which have been entered by users since the last cycle
+of the driver.  After the command table is assembled, all messages
+scheduled to be sent to the connection from the last driver cycle are sent
+out to the user.  At this point, the driver goes through the table of
+commands to be executed and executes each set of commands each
+object has stored there.  The driver ends its cycle by calling the function
+heart_beat() in every object with a heart_beat() set and finally
+performing all pending call outs.  This chapter will not deal with the
+handling of connections, but instead will focus on how the driver
+handles user commands and heartbeats and call outs.
+
+2.3 User Commands
+As noted in section 1.2, the driver stores a list of commands for each
+user to be executed each cycle.  The commands list has the name of the
+living object performing the command, the object which gave the living
+object that command, and the function which is to be executed in order
+to perform the command.  The driver refers to the object which typed in
+the command as the command giver.  It is the command giver which
+gets returned as this_player() in most cases.
+
+The driver starts at the top of the list of living objects with pending
+commands, and successively performs each command it typed by calling
+the function associated with the command and passing any arguments
+the command giver gave as arguments to the function.  As the driver
+starts with the commands issued by a new living object, the command
+giver variable is changed to be equal to the new living object, so that
+during the sequence of functions initiated by that command, the efun
+this_player() returns the object which issued the command.
+
+Let's look at the command buffer for an example player.  Since the
+execution of his last command, Bozo has typed "north" and "tell
+descartes when is the next reboot".  The command "north" is associated
+with the function "Do_Move()" in the room Bozo is in (the command
+"north" is automatically setup by the set_exits() efun in that room).  The
+command "tell" is not specifically listed as a command for the player,
+however, in the player object there is a function called "cmd_hook()"
+which is associated with the command "", which matches any possible
+user input.
+
+Once the driver gets down to Bozo, the command giver variable is set to
+the object which is Bozo.  Then, seeing Bozo typed "north" and the
+function "north" is associated with, the driver calls Bozo's_Room-
+>Do_Move(0).  An argument of 0 is passed to the function since Bozo
+only typed the command "north" with no arguments.  The room
+naturally calls some functions it needs, all the while such that the efun
+this_player() returns the object which is Bozo.  Eventually, the room
+object will call move_player() in Bozo, which in turn calls the
+move_object() efun.  This efun is responsible for changing an object's
+environment.
+
+When the environment of an object changes, the commands available to
+it from objects in its previous environment as well as from its previous
+environment are removed from the object.  Once that is done, the driver
+calls the efun init() in the new environment as well as in each object in
+the new environment.  During each of these calls to init(), the object
+Bozo is still the command giver.  Thus all add_action() efuns from this
+move will apply to Bozo.  Once all those calls are done, control passes
+back from the move_object() efun to the move_player() lfun in Bozo. 
+move_player() returns control back to Do_Move() in the old room,
+which returns 1 to signify to the driver that the command action was
+successful.  If the Do_Move() function had returned 0 for some reason,
+the driver would have written "What?" (or whatever your driver's
+default bad command message is) to Bozo.
+
+Once the first command returns 1, the driver proceeds on to Bozo's
+second command, following much the same structure.  Note that with
+"tell descartes when is the next reboot", the driver passes "descartes
+when is the next reboot" to the function associated with tell.  That
+function in turn has to decide what to do with that argument.  After that
+command returns either 1 or 0, the driver then proceeds on to the next
+living object with commands pending, and so on until all living objects
+with pending commands have had their commands performed.
+
+2.4 The Efuns set_heart_beat() and call_out()
+Once all commands are performed for objects with commands pending,
+the driver then proceeds to call the heart_beat() function in all objects
+listed with the driver as having heartbeats.  Whenever an object calls the
+efun set_heart_beat() with a non-zero argument (depending on your
+driver, what non-zero number may be important, but in most cases you
+call it with the int 1).  The efun set_heart_beat() adds the object which
+calls set_heart_beat() to the list of objects with heartbeats.  If you call it
+with an argument of 0, then it removes the object from the list of objects
+with heartbeats.
+
+The most common use for heartbeats in the mudlib is to heal players and
+monsters and perform combat.  Once the driver has finished dealing with
+the command list, it goes through the heartbeat list calling heart_beat() in
+each object in the list.  So for a player, for example, the driver will call
+heart_beat() in the player which will:
+1) age the player
+2) heal the player according to a heal rate
+3) check to see if there are any hunted, hunting, or attacking objects
+around
+4) perform an attack if step 3 returns true.
+5) any other things which need to happen automatically roughly every
+second
+
+Note that the more objects which have heartbeats, the more processing
+which has to happen every cycle the mud is up.  Objects with heartbeats
+are thus known as the major hog of CPU time on muds.  
+
+The call_out() efun is used to perform timed function calls which do not
+need to happen as often as heartbeats, or which just happen once.  Call
+outs let you specify the function in an object you want called.  The
+general formula for call outs is:
+call_out(func, time, args);
+The third argument specifying arguments is optional.  The first argument
+is a string representing the name of the function to be called.  The second
+argument is how many seconds should pass before the function gets
+called.
+
+Practically speaking, when an object calls call_out(), it is added to a list
+of objects with pending call outs with the amount of time of the call out
+and the name of the function to be called.  Each cycle of the driver, the
+time is counted down until it becomes time for the function to be called. 
+When the time comes, the driver removes the object from the list of
+objects with pending call outs and performs the call to the call out
+function, passing any special args originally specified by the call out
+function.
+
+If you want a to remove a pending call before it occurs, you need to use
+the remove_call_out() efun, passing the name of the function being
+called out.  The driver will remove the next pending call out to that
+function.  This means you may have some ambiguity if more than one
+call out is pending for the same function.
+
+In order to make a call out cyclical, you must reissue the call_out() efun
+in the function you called out, since the driver automatically removes the
+function from the call out table when a call out is performed.  Example:
+
+void foo() { call_out("hello", 10); }
+
+void hello() { call_out("hello", 10); }
+
+will set up hello() to be called every 10 seconds after foo() is first called. 
+There are several things to be careful about here.  First, you must watch
+to make sure you do not structure your call outs to be recursive in any
+unintended fashion.  Second, compare what a set_heart_beat() does
+when compared directly to what call_out() does.
+
+set_heart_beat():
+a) Adds this_object() to a table listing objects with heartbeats.
+b) The function heart_beat() in this_object() gets called every single
+driver cycle.
+
+call_out():
+a) Adds this_object(), the name of a function in this_object(), a time
+delay, and a set of arguments to a table listing functions with pending
+call outs.  
+b) The function named is called only once, and that call comes after the
+specified delay.
+
+As you can see, there is a much greater memory overhead associated
+with call outs for part (a), yet that there is a much greater CPU overhead
+associated with heartbeats as shown in part (b), assuming that the delay
+for the call out is greater than a single driver cycle. 
+
+Clearly, you do not want to be issuing 1 second call outs, for then you
+get the worst of both worlds.  Similarly, you do not want to be having
+heart beats in objects that can perform the same functions with call outs
+of a greater duration than 1 second.  I personally have heard much talk
+about at what point you should use a call out over a heartbeat.  What I
+have mostly heard is that for single calls or for cycles of a duration
+greater than 10 seconds, it is best to use a call out.  For repetitive calls of
+durations less than 10 seconds, you are better off using heartbeats.  I do
+not know if this is true, but I do not think following this can do any
+harm.
+
+2.5 Summary
+Basic to a more in depth understanding of LPC is and understanding of
+the way in which the driver interacts with the mudlib.  You should now
+understand the order in which the driver performs functions, as well as a
+more detailed knowledge of the efuns this_player(), add_action(), and
+move_object() and the lfun init().  In addition to this building upon
+knowledge you got from the LPC Basics textbook, this chapter has
+introduced call outs and heartbeats and the manner in which the driver
+handles them.  You should now have a basic understanding of call outs
+and heartbeats such that you can experiment with them in your realm
+code.
+
+Copyright (c) George Reese 1993
diff --git a/doc/KURS/LPC-KURS2/chapter3 b/doc/KURS/LPC-KURS2/chapter3
new file mode 100644
index 0000000..f986737
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/chapter3
@@ -0,0 +1,481 @@
+Intermediate LPC
+Descartes of Borg
+November 1993
+
+                        Chapter 3: Complex Data Types
+
+3.1 Simple Data Types
+In the textbook LPC Basics, you learned about the common, basic LPC
+data types: int, string, object, void.  Most important you learned that
+many operations and functions behave differently based on the data type
+of the variables upon which they are operating.  Some operators and
+functions will even give errors if you use them with the wrong data
+types.  For example, "a"+"b" is handled much differently than 1+1. 
+When you ass "a"+"b", you are adding "b" onto the end of "a" to get
+"ab".  On the other hand, when you add 1+1, you do not get 11, you get
+2 as you would expect.
+
+I refer to these data types as simple data types, because they atomic in
+that they cannot be broken down into smaller component data types. 
+The object data type is a sort of exception, but you really cannot refer
+individually to the components which make it up, so I refer to it as a
+simple data type.
+
+This chapter introduces the concept of the complex data type, a data type
+which is made up of units of simple data types.  LPC has two common
+complex data types, both kinds of arrays.  First, there is the traditional
+array which stores values in consecutive elements accessed by a number
+representing which element they are stored in.  Second is an associative
+array called a mapping.  A mapping associates to values together to
+allow a more natural access to data.
+
+3.2 The Values NULL and 0
+Before getting fully into arrays, there first should be a full understanding
+of the concept of NULL versus the concept of 0.  In LPC, a null value is
+represented by the integer 0.  Although the integer 0 and NULL are often
+freely interchangeable, this interchangeability often leads to some great
+confusion when you get into the realm of complex data types.  You may
+have even encountered such confusion while using strings.
+
+0 represents a value which for integers means the value you add to
+another value yet still retain the value added.  This for any addition
+operation on any data type, the ZERO value for that data type is the value
+that you can add to any other value and get the original value.  Thus:   A
+plus ZERO equals A where A is some value of a given data type and
+ZERO is the ZERO value for that data type.  This is not any sort of
+official mathematical definition.  There exists one, but I am not a
+mathematician, so I have no idea what the term is.  Thus for integers, 0
+is the ZERO value since 1 + 0 equals 1.
+
+NULL, on the other hand, is the absence of any value or meaning.  The
+LPC driver will interpret NULL as an integer 0 if it can make sense of it
+in that context.  In any context besides integer addition, A plus NULL
+causes an error.  NULL causes an error because adding valueless fields
+in other data types to those data types makes no sense.
+
+Looking at this from another point of view, we can get the ZERO value
+for strings by knowing what added to "a" will give us "a" as a result. 
+The answer is not 0, but instead "".  With integers, interchanging NULL
+and 0 was acceptable since 0 represents no value with respect to the
+integer data type.  This interchangeability is not true for other data types,
+since their ZERO values do not represent no value.  Namely, ""
+represents a string of no length and is very different from 0.  
+
+When you first declare any variable of any type, it has no value.  Any
+data type except integers therefore must be initialized somehow before
+you perform any operation on it.  Generally, initialization is done in the
+create() function for global variables, or at the top of the local function
+for local variables by assigning them some value, often the ZERO value
+for that data type.  For example, in the following code I want to build a
+string with random words:
+
+string build_nonsense() {
+    string str;
+    int i;
+
+    str = ""; /* Here str is initialized to the string
+ZERO value */
+    for(i=0; i<6; i++) {
+        switch(random(3)+1) {
+            case 1: str += "bing"; break;
+            case 2: str += "borg"; break;
+            case 3: str += "foo"; break;
+        }
+        if(i==5) str += ".\n";
+        else str += " ";
+    }
+    return capitalize(str);
+}
+
+If we had not initialized the variable str, an error would have resulted
+from trying to add a string to a NULL value.  Instead, this code first
+initializes str to the ZERO value for strings, "".  After that, it enters a
+loop which makes 6 cycles, each time randomly adding one of three
+possible words to the string.  For all words except the last, an additional
+blank character is added.  For the last word, a period and a return
+character are added.  The function then exits the loop, capitalizes the
+nonsense string, then exits.
+
+3.3 Arrays in LPC
+An array is a powerful complex data type of LPC which allows you to
+access multiple values through a single variable.  For instance,
+Nightmare has an indefinite number of currencies in which players may
+do business.  Only five of those currencies, however, can be considered
+hard currencies.  A hard currency for the sake of this example is a
+currency which is readily exchangeable for any other hard currency,
+whereas a soft currency may only be bought, but not sold.  In the bank,
+there is a list of hard currencies to allow bank keepers to know which
+currencies are in fact hard currencies.  With simple data types, we would
+have to perform the following nasty operation for every exchange
+transaction:
+
+int exchange(string str) {
+    string from, to;
+    int amt;
+
+    if(!str) return 0;
+    if(sscanf(str, "%d %s for %s", amt, from, to) != 3)
+      return 0;
+    if(from != "platinum" && from != "gold" && from !=
+      "silver" &&
+      from != "electrum" && from != "copper") {
+        notify_fail("We do not buy soft currencies!\n");
+        return 0;
+    }
+    ...
+}
+
+With five hard currencies, we have a rather simple example.  After all it
+took only two lines of code to represent the if statement which filtered
+out bad currencies.  But what if you had to check against all the names
+which cannot be used to make characters in the game?  There might be
+100 of those; would you want to write a 100 part if statement?
+What if you wanted to add a currency to the list of hard currencies?  That
+means you would have to change every check in the game for hard
+currencies to add one more part to the if clauses.  Arrays allow you
+simple access to groups of related data so that you do not have to deal
+with each individual value every time you want to perform a group
+operation.
+
+As a constant, an array might look like this:
+    ({ "platinum", "gold", "silver", "electrum", "copper" })
+which is an array of type string.  Individual data values in arrays are
+called elements, or sometimes members.  In code, just as constant
+strings are represented by surrounding them with "", constant arrays are
+represented by being surrounded by ({ }), with individual elements of
+the array being separated by a ,.
+
+You may have arrays of any LPC data type, simple or complex.  Arrays
+made up of mixes of values are called arrays of mixed type.  In most
+LPC drivers, you declare an array using a throw-back to C language
+syntax for arrays.  This syntax is often confusing for LPC coders
+because the syntax has a meaning in C that simply does not translate into
+LPC.  Nevertheless, if we wanted an array of type string, we would
+declare it in the following manner:
+
+string *arr;
+
+In other words, the data type of the elements it will contain followed by
+a space and an asterisk.  Remember, however, that this newly declared
+string array has a NULL value in it at the time of declaration.
+
+3.4 Using Arrays
+You now should understand how to declare and recognize an array in
+code.  In order to understand how they work in code, let's review the
+bank code, this time using arrays:
+
+string *hard_currencies;
+
+int exchange(string str) {
+    string from, to;
+    int amt;
+
+    if(!str) return 0;
+    if(sscanf(str, "%d %s for %s", amt, from, to) != 3)
+return 0;
+    if(member_array(from, hard_currencies) == -1) {
+        notify_fail("We do not buy soft currencies!\n");
+        return 0;
+    }
+    ...
+}
+
+This code assumes hard_currencies is a global variable and is initialized
+in create() as:
+    hard_currencies = ({ "platinum", "gold", "electrum", "silver",
+   "copper" });
+Ideally, you would have hard currencies as a #define in a header file for
+all objects to use, but #define is a topic for a later chapter.
+
+Once you know what the member_array() efun does, this method
+certainly is much easier to read as well as is much more efficient and
+easier to code.  In fact, you can probably guess what the
+member_array() efun does:  It tells you if a given value is a member of
+the array in question.  Specifically here, we want to know if the currency
+the player is trying to sell is an element in the hard_curencies array. 
+What might be confusing to you is, not only does member_array() tell us
+if the value is an element in the array, but it in fact tells us which element
+of the array the value is.
+
+How does it tell you which element?  It is easier to understand arrays if
+you think of the array variable as holding a number.  In the value above,
+for the sake of argument, we will say that hard_currencies holds the
+value 179000.  This value tells the driver where to look for the array
+hard_currencies represents.  Thus, hard_currencies points to a place
+where the array values may be found.  When someone is talking about
+the first element of the array, they want the element located at 179000. 
+When the object needs the value of the second element of the array, it
+looks at 179000 + one value, then 179000 plus two values for the third,
+and so on.  We can therefore access individual elements of an array by
+their index, which is the number of values beyond the starting point of
+the array we need to look to find the value.  For the array
+hard_currencies array:
+"platinum" has an index of 0.
+"gold" has an index of 1.
+"electrum" has an index of 2.
+"silver" has an index of 3.
+"copper" has an index of 4.
+
+The efun member_array() thus returns the index of the element being
+tested if it is in the array, or -1 if it is not in the array.  In order to
+reference an individual element in an array, you use its index number in
+the following manner:
+array_name[index_no]
+Example:
+hard_currencies[3]
+where hard_currencies[3] would refer to "silver".
+
+So, you now should now several ways in which arrays appear either as
+a whole or as individual elements.  As a whole, you refer to an array
+variable by its name and an array constant by enclosing the array in ({ })
+and separating elements by ,.  Individually, you refer to array variables
+by the array name followed by the element's index number enclosed in
+[], and to array constants in the same way you would refer to simple data
+types of the same type as the constant.  Examples:
+
+Whole arrays:
+variable:  arr
+constant: ({ "platinum", "gold", "electrum", "silver", "copper" })
+
+Individual members of arrays:
+variable: arr[2]
+constant: "electrum"
+
+You can use these means of reference to do all the things you are used to
+doing with other data types.  You can assign values, use the values in
+operations, pass the values as parameters to functions, and use the
+values as return types.  It is important to remember that when you are
+treating an element alone as an individual, the individual element is not
+itself an array (unless you are dealing with an array of arrays).  In the
+example above, the individual elements are strings.  So that:
+    str = arr[3] + " and " + arr[1];
+will create str to equal "silver and gold".  Although this seems simple
+enough, many people new to arrays start to run into trouble when trying
+to add elements to an array.  When you are treating an array as a whole
+and you wish to add a new element to it, you must do it by adding
+another array.
+
+Note the following example:
+string str1, str2;
+string *arr;
+
+str1 = "hi";
+str2 = "bye";
+/* str1 + str2 equals "hibye" */
+arr = ({ str1 }) + ({ str2 });
+/* arr is equal to ({ str1, str2 }) */
+Before going any further, I have to note that this example gives an
+extremely horrible way of building an array.  You should set it: arr = ({
+str1, str2 }).  The point of the example, however, is that you must add
+like types together.  If you try adding an element to an array as the data
+type it is, you will get an error.  Instead you have to treat it as an array of
+a single element.
+
+3.5 Mappings
+One of the major advances made in LPMuds since they were created is
+the mapping data type.  People alternately refer to them as associative
+arrays.  Practically speaking, a mapping allows you freedom from the
+association of a numerical index to a value which arrays require. 
+Instead, mappings allow you to associate values with indices which
+actually have meaning to you, much like a relational database.
+
+In an array of 5 elements, you access those values solely by their integer
+indices which cover the range 0 to 4.  Imagine going back to the example
+of money again.  Players have money of different amounts and different
+types.  In the player object, you need a way to store the types of money
+that exist as well as relate them to the amount of that currency type the
+player has.  The best way to do this with arrays would have been to
+store an array of strings representing money types and an array of
+integers representing values in the player object.  This would result in
+CPU-eating ugly code like this:
+
+int query_money(string type) {
+    int i;
+
+    i = member_array(type, currencies);
+    if(i>-1 && i < sizeof(amounts))  /* sizeof efun
+returns # of elements */
+        return amounts[i];
+    else return 0;
+}
+
+And that is a simple query function.  Look at an add function:
+
+void add_money(string type, int amt) {
+    string *tmp1;
+    int * tmp2;
+    int i, x, j, maxj;
+    
+    i = member_array(type, currencies);
+    if(i >= sizeof(amounts)) /*  corrupt data, we are in
+      a bad way */
+        return;
+    else if(i== -1) {
+        currencies += ({ type });
+        amounts += ({ amt });
+        return;
+    }
+    else {
+        amounts[i] += amt;
+        if(amounts[i] < 1) {
+            tmp1 = allocate(sizeof(currencies)-1);
+            tmp2 = allocate(sizeof(amounts)-1);
+            for(j=0, x =0, maxj=sizeof(tmp1); j < maxj;
+              j++) {
+                if(j==i) x = 1;
+                tmp1[j] = currencies[j+x];
+                tmp2[j] = amounts[j+x];
+            }
+            currencies = tmp1;
+            amounts = tmp2;
+        }
+    }
+}
+
+That is really some nasty code to perform the rather simple concept of
+adding some money.  First, we figure out if the player has any of that
+kind of money, and if so, which element of the currencies array it is. 
+After that, we have to check to see that the integrity of the currency data
+has been maintained.  If the index of the type in the currencies array is
+greater than the highest index of the amounts array, then we have a
+problem since the indices are our only way of relating the two arrays. 
+Once we know our data is in tact, if the currency type is not currently
+held by the player, we simply tack on the type as a new element to the
+currencies array and the amount as a new element to the amounts array. 
+Finally, if it is a currency the player currently has, we just add the
+amount to the corresponding index in the amounts array.  If the money
+gets below 1, meaning having no money of that type, we want to clear
+the currency out of memory.
+
+Subtracting an element from an array is no simple matter.  Take, for
+example, the result of the following:
+
+string *arr;
+
+arr = ({ "a", "b", "a" });
+arr -= ({ arr[2] });
+
+What do you think the final value of arr is? Well, it is:
+    ({ "b", "a" })
+Subtracting arr[2] from the original array does not remove the third
+element from the array.  Instead, it subtracts the value of the third
+element of the array from the array.  And array subtraction removes the
+first instance of the value from the array.  Since we do not want to be
+<* NOTE Highlander@MorgenGrauen 11.2.94:
+	WRONG in MorgenGrauen (at least). The result is actually ({ "b" }). Array
+	subtraction removes ALL instances of the subtracted value from the array.
+	This holds true for all Amylaar-driver LPMuds.
+*>
+forced on counting on the elements of the array as being unique, we are
+forced to go through some somersaults to remove the correct element
+from both arrays in order to maintain the correspondence of the indices
+in the two arrays.
+
+Mappings provide a better way.  They allow you to directly associate the
+money type with its value.  Some people think of mappings as arrays
+where you are not restricted to integers as indices.  Truth is, mappings
+are an entirely different concept in storing aggregate information.  Arrays
+force you to choose an index which is meaningful to the machine for
+locating the appropriate data.  The indices tell the machine how many
+elements beyond the first value the value you desire can be found.  With
+mappings, you choose indices which are meaningful to you without
+worrying about how that machine locates and stores it.
+
+You may recognize mappings in the following forms:
+
+constant values:
+whole: ([ index:value, index:value ]) Ex: ([ "gold":10, "silver":20 ])
+element:  10
+
+variable values:
+whole:    map   (where map is the name of a mapping variable)
+element: map["gold"]
+
+So now my monetary functions would look like:
+
+int query_money(string type) { return money[type]; }
+
+void add_money(string type, int amt) {
+    if(!money[type]) money[type] = amt;
+    else money[type] += amt;
+    if(money[type] < 1)
+      map_delete(money, type);          /* this is for
+          MudOS */
+            ...OR... 
+            money = m_delete(money, type)  /* for some
+          LPMud 3.* varieties */
+            ... OR... 
+         m_delete(money, type);    /* for other LPMud 3.*
+          varieties */
+}
+
+Please notice first that the efuns for clearing a mapping element from the
+mapping vary from driver to driver.  Check with your driver's
+documentation for the exact name an syntax of the relevant efun.
+
+As you can see immediately, you do not need to check the integrity of
+your data since the values which interest you are inextricably bound to
+one another in the mapping.  Secondly, getting rid of useless values is a
+simple efun call rather than a tricky, CPU-eating loop.  Finally, the
+query function is made up solely of a return instruction. 
+
+You must declare and initialize any mapping before using it. 
+Declarations look like:
+mapping map;
+Whereas common initializations look like:
+map = ([]);
+map = m_allocate(10)   ...OR...   map = m_allocate(10);
+map = ([ "gold": 20, "silver": 15 ]);
+
+As with other data types, there are rules defining how they work in
+common operations like addition and subtraction:
+    ([ "gold":20, "silver":30 ]) + ([ "electrum":5 ]) 
+gives:
+    (["gold":20, "silver":30, "electrum":5])   
+Although my demonstration shows a continuity of order, there is in fact
+no guarantee of the order in which elements of mappings will stored. 
+Equivalence tests among mappings are therefore not a good thing.
+
+3.6 Summary
+Mappings and arrays can be built as complex as you need them to be. 
+You can have an array of mappings of arrays.  Such a thing would be
+declared like this:
+
+mapping *map_of_arrs;
+which might look like:
+({ ([ ind1: ({ valA1, valA2}), ind2: ({valB1, valB2}) ]), ([ indX:
+({valX1,valX2}) ]) })
+
+Mappings may use any data type as an index, including objects. 
+Mapping indices are often referred to as keys as well, a term from
+databases.  Always keep in mind that with any non-integer data type,
+you must first initialize a variable before making use of it in common
+operations such as addition and subtraction.  In spite of the ease and
+dynamics added to LPC coding by mappings and arrays, errors caused
+by failing to initialize their values can be the most maddening experience
+for people new to these data types.  I would venture that a very high
+percentage of all errors people experimenting with mappings and arrays
+for the first time encounter are one of three error messages:
+	Indexing on illegal type.
+	Illegal index.
+	Bad argument 1 to (+ += - -=) /* insert your favourite operator */
+Error messages 1 and 3 are darn near almost always caused by a failure
+to initialize the array or mapping in question.  Error message 2 is caused
+generally when you are trying to use an index in an initialized array
+which does not exist.  Also, for arrays, often people new to arrays will
+get error message 3 because they try to add a single element to an array
+by adding the initial array to the single element value instead of adding
+an array of the single element to the initial array.  Remember, add only
+arrays to arrays.
+
+At this point, you should feel comfortable enough with mappings and
+arrays to play with them.  Expect to encounter the above error messages
+a lot when first playing with these.  The key to success with mappings is
+in debugging all of these errors and seeing exactly what causes wholes
+in your programming which allow you to try to work with uninitialized
+mappings and arrays.  Finally, go back through the basic room code and
+look at things like the set_exits() (or the equivalent on your mudlib)
+function.  Chances are it makes use of mappings.  In some instances, it
+will use arrays as well for compatibility with mudlib.n.
+
+Copyright (c) George Reese 1993
diff --git a/doc/KURS/LPC-KURS2/chapter4 b/doc/KURS/LPC-KURS2/chapter4
new file mode 100644
index 0000000..c3e9905
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/chapter4
@@ -0,0 +1,195 @@
+Intermediate LPC
+Descartes of Borg
+November 1993
+
+                       Chapter 4: The LPC Pre-Compiler
+
+4.1 Review
+The previous chapter was quite heavy, so now I will slow down a bit so
+you can digest and play with mappings and arrays by taking on the
+rather simple topic of the LPC pre-compiler.  By this point, however,
+you should well understand how the driver interacts with the mudlib and
+be able to code objects which use call outs and heart beats.  In addition,
+you should be coding simple objects which use mappings and arrays,
+noting how these data types perform in objects.  It is also a good idea to
+start looking in detail at the actual mudlib code that makes up your mud. 
+See if you understand everything which is going on in your mudlibs
+room and monster codes.  For things you do not understand, ask the
+people on your mud designated to answer creator coding questions.
+
+Pre-compiler is actually a bit of a misnomer since LPC code is never
+truly compiled.  Although this is changing with prototypes of newer
+LPC drivers, LPC drivers interpret the LPC code written by creators
+rather than compile it into binary format.  Nevertheless, the LPC pre-
+compiler functions still perform much like pre-compilers for compiled
+languages in that pre-compiler directives are interpreted before the driver
+even starts to look at object code. 
+
+4.2 Pre-compiler Directives
+If you do not know what a pre-compiler is, you really do not need to
+worry.  With respect to LPC, it is basically a process which happens
+before the driver begins to interpret LPC code which allows you to
+perform actions upon the entire code found in your file.  Since the code
+is not yet interpreted, the pre-compiler process is involved before the file
+exists as an object and before any LPC functions or instructions are ever
+examined.  The pre-compiler is thus working at the file level, meaning
+that it does not deal with any code in inherited files.
+
+The pre-compiler searches a file sent to it for pre-compiler directives. 
+These are little instructions in the file meant only for the pre-compiler
+and are not really part of the LPC language.  A pre-compiler directive is
+any line in a file beginning with a pound (#) sign.  Pre-compiler
+directives are generally used to construct what the final code of a file will
+look at.  The most common pre-compiler directives are:
+
+#define
+#undefine
+#include
+#ifdef
+#ifndef
+#if
+#elseif
+#else
+#endif
+#pragma
+
+Most realm coders on muds use exclusively the directives #define and
+#include.  The other directives you may see often and should understand
+what they mean even if you never use them.
+
+The first pair of directives are:
+#define
+#undefine
+
+The #define directive sets up a set of characters which will be replaced
+any where they exist in the code at precompiler time with their definition. 
+For example, take:
+
+#define OB_USER "/std/user"
+
+This directive has the pre-compiler search the entire file for instances of
+OB_USER.  Everywhere it sees OB_USER, it replaces with "/std/user". 
+<* NOTE Highlander@MorgenGrauen 11.2.94:
+	WRONG. OB_USER will _not_ be replaced if within "" in which case it is
+	treated as a normal string. So it is possible to write the text OB_USER.
+*>
+Note that it does not make OB_USER a variable in the code.  The LPC
+interpreter never sees the OB_USER label.  As stated above, the pre-
+compiler is a process which takes place before code interpretation.  So
+what you wrote as:
+
+#define OB_USER "/std/user"
+
+void create() {
+    if(!file_exists(OB_USER+".c")) write("Merde! No user file!");
+    else write("Good! User file still exists!");
+}
+
+would arrive at the LPC interpreter as:
+
+void create() {
+    if(!file_exists("/std/user"+".c")) write("Merde! No user file!");
+    else write("Good! User file still exists!");
+}
+
+<* NOTE Highlander@MorgenGrauen 11.2.94
+	But: write("Text is OB_USER foo bar\n");
+	simply writes "Text is OB_USER foo bar". Confer previous note.
+*>
+
+Simply put, #define just literally replaces the defined label with whatever
+follows it.  You may also use #define in a special instance where no
+value follows.  This is called a binary definition.  For example:
+
+#define __NIGHTMARE
+
+exists in the config file for the Nightmare Mudlib.  This allows for pre-
+compiler tests which will be described later in the chapter.
+
+The other pre-compiler directive you are likely to use often is #include. 
+As the name implies, #include includes the contents of another file right
+into the file being pre-compiled at the point in the file where the directive
+is placed.  Files made for inclusion into other files are often called header
+files.  They sometimes contain things like #define directives used by
+multiple files and function declarations for the file.  The traditional file
+extension to header files is .h.
+
+Include directives follow one of 2 syntax's:
+
+#include <filename>
+#include "filename"
+
+If you give the absolute name of the file, then which syntax you use is
+irrelevant.  How you enclose the file name determines how the pre-
+compiler searches for the header files.  The pre-compiler first searches in
+system include directories for files enclosed in <>.  For files enclosed in
+"", the pre-compiler begins its search in the same directory as the file
+going through the pre-compiler.  Either way, the pre-compiler will
+search the system include directories and the directory of the file for the
+header file before giving up.  The syntax simply determines the order.
+<* NOTE Highlander@MorgenGrauen 11.2.94
+	When using standard-headerfiles one should choose <>. "" is appropriate
+	when dealing with selfdefined headerfiles.
+*>
+
+The simplest pre-compiler directive is the #pragma directive.  It is
+doubtful you will ever use this one.  Basically, you follow the directive
+with some keyword which is meaningful to your driver.  The only
+keyword I have ever seen is strict_types, which simply lets the driver
+know you want this file interpreted with strict data typing.  I doubt you
+will ever need to use this, and you may never even see it.  I just included
+it in the list in the event you do see it so you do not think it is doing
+anything truly meaningful.
+
+The final group of pre-compiler directives are the conditional pre-
+compiler directives.  They allow you to pre-compile the file one way
+given the truth value of an expression, otherwise pre-compile the file
+another way.  This is mostly useful for making code portable among
+mudlibs, since putting the m_delete() efun in code on a MudOS mud
+would normally cause an error, for example.  So you might write the
+following:
+
+#ifdef  MUDOS
+    map_delete(map, key);
+#else
+    map = m_delete(map, key);
+#endif
+
+which after being passed through the pre-compiler will appear to the
+interpreter as:
+
+    map_delete(map, key);   
+
+on a MudOS mud, and:
+  
+    map = m_delete(map, key);
+
+on other muds.  The interpreter never sees the function call that would
+cause it to spam out in error. 
+
+Notice that my example made use of a binary definition as described
+above.  Binary definitions allow you to pass certain code to the
+interpreter based on what driver or mudlib you are using, among other
+conditions.
+
+4.3 Summary
+The pre-compiler is a useful LPC tool for maintaining modularity among
+your programs.  When you have values that might be subject to change,
+but are used widely throughout your files, you might stick all of those
+values in a header file as #define statements so that any need to make a
+future change will cause you to need to change just the #define directive. 
+A very good example of where this would be useful would be a header
+file called money.h  which includes the directive:
+#define HARD_CURRENCIES ({ "gold", "platinum", "silver",
+"electrum", "copper" })
+so that if ever you wanted to add a new hard currency, you only need
+change this directive in order to update all files needing to know what the
+hard currencies are.
+
+The LPC pre-compiler also allows you to write code which can be
+ported without change among different mudlibs and drivers.  Finally,
+you should be aware that the pre-compiler only accepts lines ending in
+carriage returns.  If you want a multiple line pre-compiler directive, you
+need to end each incomplete line with a backslash(\).
+
+Copyright (c) George Reese 1993
diff --git a/doc/KURS/LPC-KURS2/chapter5 b/doc/KURS/LPC-KURS2/chapter5
new file mode 100644
index 0000000..f45b6fa
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/chapter5
@@ -0,0 +1,186 @@
+Intermediate LPC
+Descartes of Borg
+November 1993
+
+                     Chapter 5: Advanced String Handling
+
+5.1 What a String Is
+The LPC Basics textbook taught strings as simple data types.  LPC
+generally deals with strings in such a matter.  The underlying driver
+program, however, is written in C, which has no string data type.  The
+driver in fact sees strings as a complex data type made up of an array of
+characters, a simple C data type.  LPC, on the other hand does not
+recognize a character data type (there may actually be a driver or two out
+there which do recognize the character as a data type, but in general not). 
+The net effect is that there are some array-like things you can do with
+strings that you cannot do with other LPC data types.
+
+The first efun regarding strings you should learn is the strlen() efun. 
+This efun returns the length in characters of an LPC string, and is thus
+the string equivalent to sizeof() for arrays.  Just from the behaviour of
+this efun, you can see that the driver treats a string as if it were made up
+of smaller elements.  In this chapter, you will learn how to deal with
+strings on a more basic level, as characters and sub strings.
+
+5.2 Strings as Character Arrays
+You can do nearly anything with strings that you can do with arrays,
+except assign values on a character basis.  At the most basic, you can
+actually refer to character constants by enclosing them in '' (single
+quotes).  'a' and "a" are therefore very different things in LPC.  'a'
+represents a character which cannot be used in assignment statements or
+any other operations except comparison evaluations.  "a" on the other
+hand is a string made up of a single character.  You can add and subtract
+other strings to it and assign it as a value to a variable.
+
+With string variables, you can access the individual characters to run
+comparisons against character constants using exactly the same syntax
+that is used with arrays.  In other words, the statement:
+    if(str[2] == 'a')
+is a valid LPC statement comparing the second character in the str string
+to the character 'a'.  You have to be very careful that you are not
+comparing elements of arrays to characters, nor are you comparing
+characters of strings to strings.
+
+LPC also allows you to access several characters together using LPC's
+range operator ..:
+    if(str[0..1] == "ab")
+In other words, you can look for the string which is formed by the
+characters 0 through 1 in the string str.  As with arrays, you must be
+careful when using indexing or range operators so that you do not try to
+reference an index number larger than the last index.  Doing so will
+result in an error.
+
+Now you can see a couple of similarities between strings and arrays:
+1) You may index on both to access the values of individual elements.
+	a) The individual elements of strings are characters
+	b) The individual elements of arrays match the data type of the
+array.
+2) You may operate on a range of values
+	a) Ex: "abcdef"[1..3] is the string "bcd"
+	b) Ex: ({ 1, 2, 3, 4, 5 })[1..3] is the int array ({ 2, 3, 4 })
+<* NOTE Highlander@MorgenGrauen
+	Also possible in MorgenGrauen (in common: Amylaar-driver LPMuds):
+	"abcdef"[2..]    -> "cdef" and
+	"abcdef"[1..<2]  -> "bcde"  (< means start counting from the end and with 1)
+*>
+
+And of course, you should always keep in mind the fundamental
+difference: a string is not made up of a more fundamental LPC data type. 
+In other words, you may not act on the individual characters by
+assigning them values.
+
+5.3 The Efun sscanf()
+You cannot do any decent string handling in LPC without using
+sscanf().  Without it, you are left trying to play with the full strings
+passed by command statements to the command functions.  In other
+words, you could not handle a command like: "give sword to leo", since
+you would have no way of separating "sword to leo" into its constituent
+parts.  Commands such as these therefore use this efun in order to use
+commands with multiple arguments or to make commands more
+"English-like".
+
+Most people find the manual entries for sscanf() to be rather difficult
+reading.  The function does not lend itself well to the format used by
+manual entries.  As I said above, the function is used to take a string and
+break it into usable parts.  Technically it is supposed to take a string and
+scan it into one or more variables of varying types.  Take the example
+above:
+
+int give(string str) {
+    string what, whom;
+
+    if(!str) return notify_fail("Give what to whom?\n");
+    if(sscanf(str, "%s to %s", what, whom) != 2) 
+      return notify_fail("Give what to whom?\n");
+    ... rest of give code ...
+}
+
+The efun sscanf() takes three or more arguments.  The first argument is
+the string you want scanned.  The second argument is called a control
+string.  The control string is a model which demonstrates in what form
+the original string is written, and how it should be divided up.  The rest
+of the arguments are variables to which you will assign values based
+upon the control string.
+
+The control string is made up of three different types of elements: 1)
+constants, 2) variable arguments to be scanned, and 3) variable
+arguments to be discarded.  You must have as many of the variable
+arguments in sscanf() as you have elements of type 2 in your control
+string.  In the above example, the control string was "%s to %s", which
+is a three element control string made up of one constant part (" to "),
+and two variable arguments to be scanned ("%s").  There were no
+variables to be discarded.
+
+The control string basically indicates that the function should find the
+string " to " in the string str.  Whatever comes before that constant will
+be placed into the first variable argument as a string.  The same thing
+will happen to whatever comes after the constant.
+
+Variable elements are noted by a "%" sign followed by a code for
+decoding them.  If the variable element is to be discarded, the "%" sign
+is followed by the "*" as well as the code for decoding the variable. 
+Common codes for variable element decoding are "s" for strings and "d"
+for integers.  In addition, your mudlib may support other conversion
+codes, such as "f" for float.  So in the two examples above, the "%s" in
+the control string indicates that whatever lies in the original string in the
+corresponding place will be scanned into a new variable as a string.
+
+A simple exercise.  How would you turn the string "145" into an
+integer?
+
+Answer:
+int x;
+sscanf("145", "%d", x);
+
+After the sscanf() function, x will equal the integer 145.
+
+Whenever you scan a string against a control string, the function
+searches the original string for the first instance of the first constant in
+the original string.  For example, if your string is "magic attack 100" and
+you have the following:
+int improve(string str) {
+    string skill;
+    int x;
+
+    if(sscanf(str, "%s %d", skill, x) != 2) return 0;
+    ...
+}
+you would find that you have come up with the wrong return value for
+sscanf() (more on the return values later).  The control string, "%s %d",
+is made up of to variables to be scanned and one constant.  The constant
+is " ".  So the function searches the original string for the first instance
+of " ", placing whatever comes before the " " into skill, and trying to
+place whatever comes after the " " into x.  This separates "magic attack
+100" into the components "magic" and "attack 100".  The function,
+however, cannot make heads or tales of "attack 100" as an integer, so it
+returns 1, meaning that 1 variable value was successfully scanned
+("magic" into skill).
+
+Perhaps you guessed from the above examples, but the efun sscanf()
+returns an int, which is the number of variables into which values from
+the original string were successfully scanned.  Some examples with
+return values for you to examine:
+
+sscanf("swo  rd descartes", "%s to %s", str1, str2)           return: 0
+sscanf("swo  rd descartes", "%s %s", str1, str2)              return: 2
+sscanf("200 gold to descartes", "%d %s to %s", x, str1, str2) return: 3
+sscanf("200 gold to descartes", "%d %*s to %s", x, str1)      return: 2
+where x is an int and str1 and str2 are string
+
+5.4 Summary
+LPC strings can be thought of as arrays of characters, yet always
+keeping in mind that LPC does not have the character data type (with
+most, but not all drivers).  Since the character is not a true LPC data
+type, you cannot act upon individual characters in an LPC string in the
+same manner you would act upon different data types.  Noticing the
+intimate relationship between strings and arrays nevertheless makes it
+easier to understand such concepts as the range operator and indexing on
+strings.
+
+There are efuns other than sscanf() which involve advanced string
+handling, however, they are not needed nearly as often.  You should
+check on your mud for man or help files on the efuns: explode(),
+implode(), replace_string(), sprintf().  All of these are very valuable
+tools, especially if you intend to do coding at the mudlib level.
+
+Copyright (c) George Reese 1993
diff --git a/doc/KURS/LPC-KURS2/chapter6 b/doc/KURS/LPC-KURS2/chapter6
new file mode 100644
index 0000000..98b3552
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/chapter6
@@ -0,0 +1,276 @@
+Intermediate LPC
+Descartes of Borg
+November 1993
+
+                       Chapter 6: Intermediate Inheritance
+
+6.1 Basics of Inheritance
+In the textbook LPC Basics, you learned how it is the mudlib maintains
+consistency amoung mud objects through inheritance.  Inheritance
+allows the mud administrators to code the basic functions and such that
+all mudlib objects, or all mudlib objects of a certain type must have so
+that you can concentrate on creating the functions which make these
+objects different.  When you build a room, or a weapon, or a monster,
+you are taking a set of functions already written for you and inheriting
+them into your object.  In this way, all objects on the mud can count on
+other objects to behave in a certain manner.  For instance, player objects
+can rely on the fact that all room objects will have a function in them
+called query_long() which describes the room.  Inheritance thus keeps
+you from having to worry about what the function query_long() should
+look like.
+
+Naturally, this textbook tries to go beyond this fundamental knowledge
+of inheritance to give the coder a better undertstanding of how
+inheritance works in LPC programming.  Without getting into detail that
+the advanced domain coder/beginner mudlib coder simply does not yet
+need, this chapter will try to explain exactly what happens when you
+inherit an object.
+
+6.2 Cloning and Inheritance
+Whenever a file is referenced for the first time as an object (as opposed
+to reading the contents of the file), the game tries to load the file into
+memory and create an object.  If the object is successfully loaded into
+memory, it becomes as master copy.  Master copies of objects may be
+cloned but not used as actual game objects.  The master copy is used to
+support any clone objects in the game.
+
+The master copy is the source of one of the controversies of mud LPC
+coding, that is whether to clone or inherit.  With rooms, there is no
+question of what you wish to do, since there should only be one instance
+of each room object in the game.  So you generally use inheritance in
+creating rooms.  Many mud administrators, including myself, however
+encourage creators to clone the standard monster object and configure it
+from inside room objects instead of keeping monsters in separate files
+which inherit the standard monster object.
+
+As I stated above, each time a file is referenced to create an object, a
+master copy is loaded into memory.  When you do something like:
+void reset() {
+    object ob;
+    ob = new("/std/monster");
+      /* clone_object("/std/monster") some places */
+    ob->set_name("foo monster");
+    ...  rest of monster config code followed by moving
+it to the room ...
+}
+the driver searches to see if their is a master object called "/std/monster". 
+If not, it creates one.  If it does exist, or after it has been created, the
+driver then creates a clone object called "/std/monster#<number>".  If
+this is the first time "/std/monster" is being referenced, in effect, two
+objects are being created: the master object and the cloned instance.
+
+On the other hand, let's say you did all your configuring in the create()
+of a special monster file which inherits "/std/monster".  Instead of
+cloning the standard monster object from your room, you clone your
+monster file.  If the standard monster has not been loaded, it gets loaded
+since your monster inherits it.  In addition, a master copy of your file
+gets loaded into memory.  Finally, a clone of your monster is created
+and moved into the room, for a total of three objects added to the game. 
+Note that you cannot make use of the master copy easily to get around
+this.  If, for example, you were to do:
+    "/wizards/descartes/my_monster"->move(this_object());
+instead of
+    new("/wizards/descartes/my_monster")->move(this_object());
+you would not be able to modify the file "my_monster.c" and update it,
+since the update command destroys the current master version of an
+object.  On some mudlibs it also loads the new version into memory. 
+Imagine the look on a player's face when their monster disappears in
+mid-combat cause you updated the file!
+
+Cloning is therefore a useful too when you plan on doing just that-
+cloning.  If you are doing nothing special to a monster which cannot be
+done through a few call others, then you will save the mud from getting
+loaded with useless master copies.  Inheritance, however, is useful if
+you plan to add functionality to an object (write your own functions) or
+if you have a single configuration that gets used over and over again
+(you have an army of orc guards all the same, so you write a special orc
+file and clone it).
+
+6.3 Inside Inheritance
+When objects A and B inherit object C, all three objects have their own
+set of data sharing one set of function definitions from object C.  In
+addition, A and B will have separate functions definitions which were
+entered separately into their code.  For the sake of example throughout
+the rest of the chapter, we will use the following code.  Do not be
+disturbed if, at this point, some of the code makes no sense:
+
+OBJECT C
+private string name, cap_name, short, long;
+private int setup;
+
+void set_name(string str)
+nomask string query_name();
+private int query_setup();
+static void unsetup();
+void set_short(string str);
+string query_short();
+void set_long(string str);
+string query_long();
+
+
+void set_name(string str) { 
+    if(!query_setup()) {
+        name = str;
+    setup = 1;
+}
+
+nomask string query_name() { return name; }
+
+private query_setup() { return setup; }
+
+static void unsetup() { setup = 0; }
+
+string query_cap_name() {
+    return (name ? capitalize(name) : ""); }
+}
+
+void set_short(string str) { short = str; }
+
+string query_short() { return short; }
+
+void set_long(string str) { long = str; }
+
+string query_long() { return str; }
+
+void create() { seteuid(getuid()); }
+
+OBJECT B
+inherit "/std/objectc";
+
+private int wc;
+
+void set_wc(int wc);
+int query_wc();
+int wieldweapon(string str);
+
+void create() { ::create(); }
+
+void init() {
+    if(environment(this_object()) == this_player())
+      add_action("wieldweapon", "wield");
+}
+
+void set_wc(int x) { wc = x; }
+
+int query_wc() { return wc; }
+
+int wieldweapon(string str) {
+    ... code for wielding the weapon ...
+}
+
+OBJECT A
+inherit "/std/objectc";
+
+int ghost;
+
+void create() { ::create(); }
+
+void change_name(string str) {
+    if(!((int)this_object()->is_player())) unsetup();
+    set_name(str);
+}
+
+string query_cap_name() {
+    if(ghost) return "A ghost";
+    else return ::query_cap_name();
+}
+
+As you can see, object C is inherited both by object A and object B. 
+Object C is a representation of a much oversimplified base object, with B
+being an equally oversimplified weapon and A being an equally
+simplified living object.  Only one copy of each function is retained in
+memory, even though we have here three objects using the functions. 
+There are of course, three instances of the variables from Object C in
+memory, with one instance of the variables of Object A and Object B in
+memory.  Each object thus gets its own data.  
+
+6.4 Function and Variable Labels
+Notice that many of the functions above are proceeded with labels which
+have not yet appeared in either this text or the beginner text, the labels
+static, private, and nomask.  These labels define special priveledges
+which an object may have to its data and member functions.  Functions
+you have used up to this point have the default label public.  This is
+default to such a degree, some drivers do not support the labeling.
+
+A public variable is available to any object down the inheritance tree
+from the object in which the variable is declared.  Public variables in
+object C may be accessed by both objects A and B.  Similarly, public
+functions may be called by any object down the inheritance tree from the
+object in which they are declared. 
+
+The opposite of public is of course private.  A private variable or
+function may only be referenced from inside the object which declares it. 
+If object A or B tried to make any reference to any of the variables in
+object C, an error would result, since the variables are said to be out of
+scope, or not available to inheriting classes due to their private labels. 
+Functions, however, provide a unique challenge which variables do not. 
+External objects in LPC have the ability to call functions in other objects
+through call others.  The private label does not protect against call
+others.
+
+To protect against call others, functions use the label static.  A function
+which is static may only be called from inside the complete object or
+from the game driver.  By complete object, I mean object A can call
+static functions in the object C it inherits.  The static only protects against
+external call others.  In addition, this_object()->foo() is considered an
+internal call as far as the static label goes.
+
+Since variables cannot be referenced externally, there is no need for an
+equivalent label for them.  Somewhere along the line, someone decided
+to muddy up the waters and use the static label with variables to have a
+completely separate meaning.  What is even more maddening is that this
+label has nothing to do with what it means in the C programming
+language.  A static variable is simply a variable that does not get saved to
+file through the efun save_object() and does not get restored through
+restore_object().  Go figure.
+
+In general, it is good practice to have private variables with public
+functions, using query_*() functions to access the values of inherited
+variables, and set_*(), add_*(), and other such functions to change
+those values.  In realm coding this is not something one really has to
+worry a lot about.  As a matter of fact, in realm coding you do not have
+to know much of anything which is in this chapter.  To be come a really
+good realm coder, however, you have to be able to read the mudlib
+code.  And mudlib code is full of these labels.  So you should work
+around with these labels until you can read code and understand why it
+is written that way and what it means to objects which inherit the code.
+
+The final label is nomask, and it deals with a property of inheritance
+which allows you to rewrite functions which have already been defined. 
+For example, you can see above that object A rewrote the function
+query_cap_name().  A rewrite of  function is called overriding the
+function.  The most common override of a function would be in a case
+like this, where a condition peculiar to our object (object A) needs to
+happen on a call ot the function under certain circumstances.  Putting test
+code into object C just so object A can be a ghost is plain silly.  So
+instead, we override query_cap_name() in object A, testing to see if the
+object is a ghost.  If so, we change what happens when another object
+queries for the cap name.  If it is not a ghost, then we want the regular
+object behaviour to happen.  We therefore use the scope resolution
+operator (::) to call the inherited version of the query_cap_name()
+function and return its value.
+
+A nomask function is one which cannot be overridden either through
+inheritance or through shadowing.  Shadowing is a sort of backwards
+inheritance which will be detailed in the advanced LPC textbook.  In the
+example above, neither object A nor object B (nor any other object for
+that matter) can override query_name().  Since we want to use
+query_name() as a unique identifier of objects, we don't want people
+faking us through shadowing or inheritance.  The function therefore gets
+the nomask label.
+
+6.5 Summary
+Through inheritance, a coder may make user of functions defined in
+other objects in order to reduce the tedium of producing masses of
+similar objects and to increase the consistency of object behaviour across
+mudlib objects.  LPC inheritance allows objects maximum priveledges in
+defining how their data can be accessed by external objects as well as
+objects inheriting them.  This data security is maintained through the
+keywords, nomask, private, and static.
+
+In addition, a coder is able to change the functionality of non-protected
+functions by overriding them.  Even in the process of overriding a
+function, however, an object may access the original function through
+the scope resolution operator.
+
+Copyright (c) George Reese 1993
diff --git a/doc/KURS/LPC-KURS2/chapter7 b/doc/KURS/LPC-KURS2/chapter7
new file mode 100644
index 0000000..aa8cc0e
--- /dev/null
+++ b/doc/KURS/LPC-KURS2/chapter7
@@ -0,0 +1,298 @@
+Intermediate LPC
+Descartes of Borg
+November 1993
+
+                            Chapter 7: Debugging
+
+7.1 Types of Errors
+By now, you have likely run into errors here, there, and everywhere.  In
+general, there are three sorts of errors you might see: compile time
+errors, run time errors, and malfunctioning code.  On most muds you
+will find a personal file where your compile time errors are logged.  For
+the most part, this file can be found either in your home directory as the
+file named "log" or ".log", or somewhere in the directory "/log" as a file
+with your name..  In addition, muds tend to keep a log of run time errors
+which occur while the mud is up.  Again, this is generally found in
+"/log".  On MudOS muds it is called "debug.log".  On other muds it may
+be called something different like "lpmud.log".  Ask your administrators
+where compile time and run time errors are each logged if you do not
+already know.
+
+Compile time errors are errors which occur when the driver tries to load
+an object into memory.  If, when the driver is trying to load an object
+into memory, it encounters things which it simply does not understand
+with respect to what you wrote, it will fail to load it into memory and log
+why it could not load the object into your personal error log.  The most
+common compile time errors are typos, missing or extra (), {}. [], or "",
+and failure to declare properly functions and variables used by the
+object.
+
+Run time errors occur when something wrong happens to an object in
+memory while it is executing a statement.  For example, the driver
+cannot tell whether the statement "x/y" will be valid in all circumstances. 
+In fact, it is a valid LPC expression.  Yet, if the value of y is 0, then a
+run time error will occur since you cannot divide by 0.  When the driver
+runs across an error during the execution of a function, it aborts
+execution of the function and logs an error to the game's run time error
+log.  It will also show the error to this_player(), if defined, if the player
+is a creator, or it will show "What?" to players.  Most common causes
+for run time errors are bad values and trying to perform operations with
+data types for which those operations are not defined.
+
+The most insideous type of error, however, is plain malfunctioning
+code.  These errors do not log, since the driver never really realizes that
+anything is wrong.  In short, this error happens when you think the code
+says one thing, but in fact it says another thing.  People too often
+encounter this bug and automatically insist that it must be a mudlib or
+driver bug.  Everyone makes all types of errors though, and more often
+than not when code is not functioning the way you should, it will be
+because you misread it.  
+
+7.2 Debugging Compile Time Errors
+Compile time errors are certainly the most common and simplest bugs to
+debug.  New coders often get frustrated by them due to the obscure
+nature of some error messages.  Nevertheless, once a person becomes
+used to the error messages generated by their driver, debugging compile
+time errors becomes utterly routine.
+
+In your error log, the driver will tell you the type of error and on which
+line it finally noticed there was an error.  Note that this is not on which
+line the actual error necessarily exists.  The most common compile time
+error, besides the typo, is the missing or superfluous parentheses,
+brackets, braces, or quotes.  Yet this error is the one that most baffles
+new coders, since the driver will not notice the missing or extra piece
+until well after the original.  Take for example the following code:
+
+1 int test(string str) {
+2    int x;
+3    for(x =0; x<10; x++)
+4        write(x+"\n");
+5    }
+6    write("Done.\n");
+7 }
+
+Depending on what you intended, the actual error here is either at line 3
+(meaning you are missing a {) or at line 5 (meaing you have an extra }). 
+Nevertheless, the driver will report that it found an error when it gets to
+line 6.  The actual driver message may vary from driver to driver, but no
+matter which driver, you will see an error on line 6, since the } in line 5
+is interpreted as ending the function test().  At line 6, the driver sees that
+you have a write() sitting outside any function definition, and thus
+reports an error.  Generally, the driver will also go on to report that it
+found an error at line 7 in the form of an extra }.
+
+The secret to debugging these is coding style.  Having closing } match
+up vertically with the clauses they close out helps you see where you are
+missing them when you are debugging code.  Similarly, when using
+multiple sets of parentheses, space out different groups like this:
+    if( (x=sizeof(who=users()) > ( (y+z)/(a-b) + (-(random(7))) ) ) 
+As you can see, the parentheses for the for() statement, are spaced out
+from the rest of the statement.  In addition, individual sub-groups are
+spaced so they can easily be sorted out in the event of an error.
+
+Once you have a coding style which aids in picking these out, you learn
+which error messages tend to indicate this sort of error.  When
+debugging this sort of error, you then view a section of code before and
+after the line in question.  In most all cases, you will catch the bug right
+off.
+
+Another common compile time error is where the driver reports an
+unknown identifier.  Generally, typos and failure to declare variables
+causes this sort of error.  Fortunately, the error log will almost always
+tell you exactly where the error is.  So when debugging it, enter the
+editor and find the line in question.  If the problem is with a variable and
+is not a typo, make sure you declared it properly.  On the other hand, if
+it is a typo, simply fix it!
+
+One thing to beware of, however, is that this error will sometimes be
+reported in conjunction with a missing parentheses, brackets, or braces
+type error.  In these situations, your problem with an unknown identifier
+is often bogus.  The driver misreads the way the {} or whatever are
+setup, and thus gets variable declarations confused.  Therefore make
+sure all other compile time errors are corrected before bothering with
+these types of errors.
+
+In the same class with the above error, is the general syntax error.  The
+driver generates this error when it simply fails to understand what you
+said.  Again, this is often caused by typos, but can also be caused by not
+properly understanding the syntax of a certain feature like writing a for()
+statement: for(x=0, x<10, x++).  If you get an error like this which is
+not a syntax error, try reviewing the syntax of the statement in which the
+error is occurring.
+
+7.3 Debugging Run Time Errors
+Run time errors are much more complex than their compile time
+counterparts.  Fortunately these errors do get logged, though many
+creators do not realise or they do not know where to look.  The error log
+for run time errors are also generally much more detailed than compile
+time errors, meaning that you can trace the history of the execution train
+from where it started to where it went wrong.  You therefore can setup
+debugging traps using precompiler statements much easier using these
+logs.  Run time errors, however, tend to result from using more
+complex codign techniques than beginners tend to use, which means you
+are left with errors which are generally more complicated than simple
+compile time errors.
+
+Run time errors almost always result from misusing LPC data types. 
+Most commonly, trying to do call others using object variables which are
+NULL, indexing on mapping, array, or string variables which are
+NULL, or passing bad arguments to functions.  We will look at a real
+run time error log from Nightmare:
+
+Bad argument 1 to explode()
+program: bin/system/_grep.c, object: bin/system/_grep
+line 32
+'       cmd_hook' in '        std/living.c' ('      
+std/user#4002')line 83
+'       cmd_grep' in '  bin/system/_grep.c' ('   
+bin/system/_grep')line 32     
+Bad argument 2 to message()
+program: adm/obj/simul_efun.c, object: adm/obj/simul_efun
+line 34
+'       cmd_hook' in '        std/living.c' ('      
+std/user#4957')line 83
+'       cmd_look' in '  bin/mortal/_look.c' ('   
+bin/mortal/_look')line 23
+' examine_object' in '  bin/mortal/_look.c' ('   
+bin/mortal/_look')line 78
+'          write' in 'adm/obj/simul_efun.c' (' 
+adm/obj/simul_efun')line 34
+Bad argument 1 to call_other()
+program: bin/system/_clone.c, object: bin/system/_clone
+line 25
+'       cmd_hook' in '        std/living.c' ('      
+std/user#3734')line 83
+'      cmd_clone' in ' bin/system/_clone.c' ('  
+bin/system/_clone')line 25
+Illegal index
+program: std/monster.c, object:
+wizards/zaknaifen/spy#7205 line 76
+'     heart_beat' in '       std/monster.c'
+('wizards/zaknaifen/spy#7205')line
+76                                                                                  
+
+All of the errors, except the last one, involve passing a bad argument to a
+function.  The first bug, involves passing a bad first arument to the efun
+explode().  This efun expects a string as its first argment.  In debugging
+these kinds of errors, we would therefore go to line 32 in
+/bin/system/_grep.c and check to see what the data type of the first
+argument being passed in fact is.  In this particular case, the value being
+passed should be a string.
+
+If for some reason I has actually passed something else, I would be done
+debugging at that point and fix it simply by making sure that I was
+passing a string.  This situation is more complex.  I now need to trace
+the actual values contained by the variable being passed to explode, so
+that I can see what it is the explode() efun sees that it is being passed.
+
+The line is question is this:
+ borg[files[i]] = regexp(explode(read_file(files[i]), "\n"), exp);
+where files is an array for strings, i is an integer, and borg is a mapping. 
+So clearly we need to find out what the value of read_file(files[i]) is. 
+Well, this efun returns a string unless the file in question does not exist,
+the object in question does not have read access to the file in question, or
+the file in question is an empty file, in which cases the function will
+return NULL.  Clearly, our problem is that one of these events must
+have happened.  In order to see which, we need to look at files[i].
+
+Examining the code, the files array gets its value through the get_dir()
+efun.  This returns all the files in a directory if the object has read access
+to the directory.  Therefore the problem is neither lack of access or non-
+existent files.  The file which caused this error then must have been an
+empty file.  And, in fact, that is exactly what caused this error.  To
+debug that, we would pass files through the filter() efun and make
+sure that only files with a file size greater than 0 were allowed into the
+array.
+
+The key to debugging a run time error is therefore knowing exactly what
+the values of all variables in question are at the exact moment where the
+bug created.  When reading your run time log, be careful to separate the
+object from the file in which the bug occurred.  For example, the
+indexing error above came about in the object /wizards/zaknaifen/spy,
+but the error occured while running a function in /std/monster.c, which
+the object inherited.
+
+7.4 Malfunctioning Code
+The nastiest problem to deal with is when your code does not behave the
+way you intended it to behave.  The object loads fine, and it produces no
+run time errors, but things simply do not happen the way they should. 
+Since the driver does not see a problem with this type of code, no logs
+are produced.  You therefore need to go through the code line by line
+and figure out what is happening.
+
+Step 1: Locate the last line of code you knew successfully executed
+Step 2: Locate the first line of code where you know things are going
+wrong
+Step 3: Examine the flow of the code from the known successful point to
+the first known unsuccessful point.
+
+More often than not, these problems occurr when you are using if()
+statements and not accounting for all possibilities.  For example:
+
+int cmd(string tmp) {
+    if(stringp(tmp)) return do_a()
+    else if(intp(tmp)) return do_b()
+    return 1;
+}
+
+In this code, we find that it compiles and runs fine.  Problem is nothing
+happens when it is executed.  We know for sure that the cmd() function
+is getting executed, so we can start there.  We also know that a value of
+1 is in fact being returned, since we do not see "What?" when we enter
+the command.  Immediately, we can see that for some reason the
+variable tmp has a value other than string or int.  As it turns out, we
+issued the command without parameters, so tmp was NULL and failed
+all tests.
+
+The above example is rather simplistic, bordering on silly. 
+Nevertheless, it gives you an idea of how to examine the flow of the
+code when debugging malfunctioning code.  Other tools are available as
+well to help in debugging code.  The most important tool is the use of
+the precompiler to debug code.  With the code above, we have a clause
+checking for integers being passed to cmd().  When we type "cmd 10",
+we are expecting do_b() to execute.  We need to see what the value of
+tmp is before we get into the loop:
+
+#define DEBUG
+int cmd(string tmp) {
+#ifdef DEBUG
+    write(tmp);
+#endif
+    if(stringp(tmp)) return do_a();
+    else if(intp(tmp)) return do_b();
+    else return 1;
+}
+
+We find out immediately upon issuing the command, that tmp has a
+value of "10".  Looking back at the code, we slap ourselves silly,
+forgetting that we have to change command arguments to integers using
+sscanf() before evaluating them as integers.
+
+7.5 Summary
+The key to debugging any LPC problem is always being aware of what
+the values of your variables are at any given step in your code.  LPC
+execution reduces on the simplest level to changes in variable values, so
+bad values are what causes bad things to happen once code has been
+loaded into memory.  If you get errors about bad arguments to
+functions, more likely than not you are passing a NULL value to a
+function for that argument.  This happens most often with objects, since
+people will do one of the following:
+    1) use a value that was set to an object that has since destructed
+    2) use the return value of this_player() when there is no this_player()
+    3) use the return value of this_object() just after this_object() was
+    destructed
+
+In addition, people will often run into errors involving illegal indexing or
+indexing on illegal types.  Most often, this is because the mapping or
+array in question was not initialized, and therefore cannot be indexed. 
+The key is to know exactly what the full value of the array or mapping
+should be at the point in question.  In addition, watch for using index
+numbers larger than the size of given arrays
+
+Finally, make use of the precompiler to temporarly throw out code, or
+introduce code which will show you the values of variables.  The
+precompiler makes it easy to get rid of debugging code quickly once you
+are done.  You can simply remove the DEBUG define when you are
+done.
+
+Copyright (c) George Reese 1993
diff --git a/doc/KURS/RULES b/doc/KURS/RULES
new file mode 100644
index 0000000..ac88cfc
--- /dev/null
+++ b/doc/KURS/RULES
@@ -0,0 +1,60 @@
+		DIE ZWEI GEBOTE IN MORGENGRAUEN
+		===============================
+
+	Was sollen Gebote?
+	------------------
+
+	Wie in jedem Spiel so haben sich auch in unserem MUD alle
+	Mitspieler (Magier eingeschlossen) an Spielregeln zu halten.
+	Allerdings machen die Spiele am meisten Spass, die die
+	wenigsten Regeln besitzen. 
+
+	Um zu verhindern, dass jetzt schon angefangen wird, dass
+	unser MUD in feste Regeln gedraengt wird, habe ich mich 
+	entschlossen, selber dem Spiel ein Regelwerk zu geben.
+	Aber ich werde dafuer sorgen, dass sie kurz bleiben.
+	
+	1.Gebot )	DU SOLLST NETT SEIN.
+
+	Das MUD ist ein Spiel; und Spiele machen nur dann Spass,
+	wenn man sich nicht gegenseitig versucht in die Pfanne zu
+	hauen; somit gilt diese Regel fuer Spieler wie fuer Magier.
+
+	2.Gebot )	DU SOLLST DIE MUDLIB EHREN UND VERMEHREN.
+
+	Das MUD steht und faellt mit der Guete seiner Mudlib; und da
+	unser Hauptziel ein schoenes MUD ist, ist es die vorrangige
+	Aufgabe aller Magier, fuer den Aufbau, die Wartung und die
+	Erhaltung der Mudlib zu sorgen.
+
+	Zum Thema Vermehrung:
+	---------------------
+
+	Es gibt in einem MUD natuerlich auch noch andere Aufgaben:
+	-	Regionskoordination
+		(Regionsmagier,Erzmagier des Verkehrs)
+	-	Wahrung des Gleichgewichtes der Kraefte
+		(Waffen,Ruestungen,Geld,XP,Monster,u.s.w.)
+	-	Schutz des MUDs vor Spielverderbern.
+		(Sheriff)
+
+	Diese Aufgaben sind aber keine Lebensaufgaben; sie sind
+	Aufgaben, die sich den Geboten unterzuordnen haben.
+	Insbesondere sollen Magier, die nichts zur Vermehrung der
+	Mudlib beitragen, nicht ueber andere urteilen.
+
+	Zum Thema Ehrung:
+	-----------------
+
+	Hiermit meine ich den Aufruf an die Magier, keine Objekte
+	zu schreiben, die das Gleichtgewicht der Kraefte verletzen.
+
+	Und ich meine den Aufruf an die Magier, dafuer zu sorgen,
+	dass es in diesem MUD Herausforderungen gibt, die (zumindest
+	teilweise) nicht umgangen werden koennen.
+	Natuerlich ist damit auch gemeint, dass Spielern nur in den
+	Faellen geholfen wird, wo Fehler oder Luecken in der Mudlib
+	auftauchen.
+
+	Olpp, Sheriff des MorgenGrauens
+	Rumata, MudAdm des MorgenGrauens
diff --git a/doc/KURS/RULES.WIZ b/doc/KURS/RULES.WIZ
new file mode 100644
index 0000000..349f0b6
--- /dev/null
+++ b/doc/KURS/RULES.WIZ
@@ -0,0 +1,46 @@
+These are the rules for a wizard.
+(Wird noch ueberarbeitet, am besten Olpp oder Rumata fragen, was
+wirklich Sache ist. Aber eine grobe Richtung weisen diese "alten"
+Regeln schon :-)
+
+1. You may not help other players, even if they lost points due to
+   lost connection. They have to go to the post office and ask Lars,
+   or use bug.
+
+2. Never attack a player or kill him. If a player behaves badly, file
+   the complaint to Lars.
+
+3. Do not make 'deadly' trapps. A player must never die because he didn't
+   know what happens in the next room. If some room is very dangerous,
+   make some hint (like the giant footprints beside the giant lair).
+
+4. Never initialize the destination of an object outside your castle. If you
+   make a monster that can walk out of the castle, be sure that it is a
+   very nice monster.
+
+5. Never generate messages that looks like something it isn't (good and precise
+   rule :-). That is, don't try to fool the player that someone says something
+   when it isn't true etc.
+
+6. If you have a "test" character, make sure is isn't seen in the top score
+   list. He must no be wizard either.
+
+7. Try to avoid making devices, situations which makes the players loose
+   experience if they are adventuring or examining objects. Players should be
+   rewarded for adventuring and discovering things. If they get killed...
+   Well, they will then loose some experience, but this is a special case!
+
+8. The game is supposed to be in the "long distant past", and thus no
+   modern things should exist. If you want some kind of airplane, use a
+   flying horse in stead etc.
+
+9. If you make available some kind of restaurant that sells food that
+   heals, then the healing must cost on average 4 gp/hp (or more). The amount
+   of healing must also be limited per reset. Generating healing items for
+   free is only allowed if they heal at most 20 points, and are destructed.
+   Not more than one such item may be generated per room and reset.
+
+10.Teleporting items should be VERY restricted, and very rare. They must
+   not allow teleportations to anywhere, but only to one or more predefined
+   room. Never to a specific player. It must cost at least 50 spell points
+   to use each time.
diff --git a/doc/KURS/einleitung b/doc/KURS/einleitung
new file mode 100644
index 0000000..1483155
--- /dev/null
+++ b/doc/KURS/einleitung
@@ -0,0 +1,45 @@
+	Einfuehrung in die Progrmmierung der Morgengrauen-Mudlib
+	von Don Rumata, MudAdm des MorgenGrauens
+	========================================================
+
+	EINLEITUNG:
+	-----------
+
+	Herzlich willkommen als Magier im MorgenGrauen. Du bist
+	gerade Magier geworden. Dieser Kurs soll Dir helfen,
+	in diesem MUD alles Moegliche zu programmieren. 
+
+
+	WICHTIGE INFORMATIONEN FUER DEN ANFANG:
+	---------------------------------------
+
+	Ein Magier hat sich gewissen Regeln zu unterwerfen, wie man
+	sich bein einem Spiel auch in die Spielregeln zu halten hat.
+	Diese Spielregeln stehen in RULES (das sind die wichtigen)
+	und in RULES.WIZ (das sind die technischen Hinweise).
+
+	Wenn Du Files editieren willst, gibt es mehrere Moeglich-
+	keiten:
+
+	1.) Mit dem Befehl "ed <filename>":
+	    Eine Einleitung fuer ed kannst Du in /doc/ed/* finden.
+
+	2.) Fileuebertragung per ftp
+	3.) Fileuebertragung per mtp
+	    frage am besten einen der erfahrenen Magier.
+
+
+	KURSUEBERBLICK:
+	---------------
+
+	I	Programmierung von Raeumen
+	     1.	Ein einfacher Raum
+	 
+	II	Programmierung von Objekten
+	
+	III	Programmierung von Monstern
+
+
+	Achja: Ich bitte flehentlich um Korrekturlesen und
+	Verbesserungs/Ergaenzungsvorschlaege. Und noch mehr
+	um Mitarbeit. (Ich hab schon jetzt wunde Finger :-)
diff --git a/doc/KURS/objekte b/doc/KURS/objekte
new file mode 100644
index 0000000..fbb11d3
--- /dev/null
+++ b/doc/KURS/objekte
@@ -0,0 +1,29 @@
+	OBJEKTE
+	
+	Als erstes musst Du wissen, dass jedes Objekt in diesem
+	Mud durch ein File repraesentiert wird. Dieses File
+	wird auch die "Blueprint" genannt. Du kannst neue Objekte
+	auf 2 Arten erschaffen.
+
+	1.) "clone"n von Blueprints. Das bedeutet, dass Du ein
+	    Objekt erschaffst, das die Eigenschaften hat, die in
+	    der Blueprint programmiert worden sind. Von einer
+	    Blueprint koennen mehrere "Clones" existieren.
+	    Typische Beispiele fuer "Clones" sind Waffen,
+	    Monster, Geld oder Spieler.
+
+	2.) "load"en von Blueprints. Das bedeutet, dass Du
+	    diese Blueprint zu Leben erweckst. In gewisser Weise
+	    benehmen sich diese Objekte genauso wie die "Clones",
+	    allerdings koennen von einmal geladenen Blueprints
+	    keine "Clones" mehr erschaffen werden.
+	    Typische geladene Objekte sind Raeme.
+
+	KNIGGE FUER MAGIER
+
+	Dadurch, dass Du beliebige Files laden oder clonen kannst,
+	bist Du in der Lage, jedem Spieler das gewuenschte Objekt
+	zu beschaffen. Aber das ist natuerlich nicht der Sinn der
+	Sache. Als Magier bist Du verpflichtet, den Spielern nur
+	noch dann zu helfen, wenn sie aufgrund von Programmier-
+	fehlern in Schwierigkeiten geraten.
diff --git a/doc/KURS/raum1 b/doc/KURS/raum1
new file mode 100644
index 0000000..b623c35
--- /dev/null
+++ b/doc/KURS/raum1
@@ -0,0 +1,137 @@
+
+	PROGRAMMIERUNG VON RAEUMEN - TEIL 1
+	von Don Rumata, MudAdm des MorgenGrauens
+	=============================================================
+
+	Ein Raum ist sehr einfach zu programmieren. Man fuellt
+	ihn mit den Informationen, die man in ihm haben will.
+
+	Am besten erklaert sich alles an einem Beispiel. Zu den
+	Funktionen sind in /doc/efuns und /doc/lfuns weitere
+	Informationen erhaeltlich.
+
+	Nachfolgend kannst Du einen (zugegebeneermassen ueber-
+	ausfuehrlich) dokumentierten Beispielraum finden.
+	In /doc/beispiele/raum1.c kannst Du den selben Raum
+	noch einmal (ohne Kommentare) finden. Den Raum
+	kannst Du uebrigens auch betreten.
+
+/* beispielraum.c von Rumata */
+
+inherit "std/room";
+	// Alle Raeume muessen diese Zeile enthalten, da in dem
+	// Standardraum wichtige Funktionen definiert werden, die
+	// innerhalb des Spieles benoetigt werden.
+
+#include <properties.h>
+	// In diesem File sind die Namen der Properties definiert.
+	// Fuer naehre Informationen kannst Du in
+	// /doc/concepts/properties und in /doc/properties.h
+	// nachschauen, da es sehr viele verschiedene Properties
+	// gibt.
+
+#include <language.h>
+	// Diese Module enthalten alle Definitionen im Zusammenhang
+	// mit Sprache. Siehe /doc/language.h
+
+create()
+// Diese Funktion wird automatisch aufgerufen, wenn der Raum geladen
+// wird. Das passiert beim Kommando "load /doc/beispiel/bspraum1" oder
+// wenn ein Spieler den Raum als erster betritt.
+{
+	::create();
+	// Diese Funktion darf NIEMALS fehlen! Sie sorgt dafuer, dass
+	// der Raum auch die allgemeine Initialisierung durchfuehrt,
+	// da diese hier die der "Mutter-Klasse" std/room ueberlaedt.
+
+	SetProp( P_INT_SHORT, "Ein kleines Schreibzimmer" );
+	SetProp( P_INT_LONG,
+		"Du stehst in einem kleinen Schreibzimmer.\n"
+	+	"Es gehoerte wohl irgendwann einmal einem Magier, aber nun\n"
+	+	"ist dieser Raum verwaist und rottet vor sich hin.\n"
+	+	"Ein grosser Schreibtisch in der Mitte des Raumes scheint\n"
+	+	"noch einigermassen gut erhalten zu sein. Durch die Tuer\n"
+	+	"im Norden faellt etwas Licht hinein.\n"
+	);
+	SetProp( P_LIGHT, 1 );
+	SetProp( P_INDOORS, 1 );
+	// Diese Properties MUESSEN in JEDEM Raum gesetzt werden.
+	// P_INT_SHORT	= Beschreibung fuer Spieler im "kurz"-Modus.
+	// P_INT_LONG	= Beschreibung fuer Spieler im "lang"-Modus.
+	// P_LIGHT	= 1 fuer Hell, 0 fuer Dunkel
+	// P_INDOORS	= 1, wenn man den Himmel nicht sehen kann.
+
+	AddDetail( ({ "schreibtisch", "tisch" }),
+		"Auf dem Tisch liegt eine dicke Staubschicht.\n"
+	+	"Eine Schublade findest Du ebenfalls.\n"
+	);
+	AddDetail( ({ "staub", "staubschicht", "schicht" }),
+		"Du malst gelangweilt einige Kreise in den Staub.\n"
+	);
+	AddDetail( "schublade",
+		"So sehr Du Dich anstrengst; Du kannst sie nicht bewegen.\n"
+	);
+	AddDetail( "tuer" ,
+		"Sie steht seit Jahren offen und ist in dieser Lage\n"
+	+	"hoffnungslos festgerostet.\n"
+	);
+	// Details sind Dinge, die man sich in einem Raum anschauen
+	// aber nicht nehmen kann. Je mehr Details ein Raum hat, destso
+	// schoener ist er. Schaut sich ein Spieler ein Detail an,
+	// so bekommt der die angegebene Beschreibung.
+
+	AddRoomCmd( ({ "schliesse", "oeffne", "bewege",
+		"schliess", "beweg" }), "beweg_etwas" );
+	// RoomCommands sind Befehle, die man in diesem ausfuehren kann.
+	// Es wird die angegebene Funktion ausgefuehrt.
+	// WICHTIG: Als Verben sollten immer die IMPERATIVE benutzt
+	//	werden! Also nicht "lese", sondern "lies".
+	
+	AddExit( "norden", "players/rumata/workroom" );
+	// Definition eines Ausgangs. Das zeite Argument bestimmt den
+	// Raum, den ein Spieler erreicht, wenn er in die angegebene
+	// Richtung geht.
+
+}
+
+beweg_etwas( str )
+// Wenn ein Spieler ein Kommando ausfuehrt, so wird alles, was hinter
+// dem Verb steht als String uebergeben, es landet also hier in "str".
+// WICHTIG: Wenn der Befehl abgearbeitet wird, MUSS er eine 1 zurueck-
+//          geben. Wenn der Befehl nichts Sinnvolles tuen konnte, eine 0.
+{
+	notify_fail( "Was willst Du denn bewegen ?" );
+	// Meldung, die der Spieler bekommt, wenn ausser dem Raum auch
+	// kein anderes Objekt den Befehl verarbeiten konnte.
+	if( str == "tuer" )
+	{
+		write( "Die Tuer ist hoffnungslos festgerostet.\n" );
+		// Write gibt eine Meldung an den Spieler (und nur an ihn)
+		// aus.
+		return 1;
+		// Das Kommando bewirkt zwar aus Sicht des Spielers
+		// nichts, aber es konnte abgearbeitet werden.
+		// Also gib eine 1 zurueck.
+	}
+	if ( str == "lade" || str == "schublade" )
+	{
+		write( "Die Schublade klemmt einfach nur.\n" );
+		return 1;
+	}
+	if ( query_verb() == "bewege" &&
+		( str == "tisch" || str == "schreibtisch" ) )
+	{
+		write(
+			"Der Tisch scheint am Boden festgeschraubt zu sein.\n"
+		);
+		say(
+			this_player()->name(WER,2)+" zerrt am Schreibtisch.\n"
+		);
+		// say gibt eine Meldung an alle Spieler im selben
+		// Raum wie der Spieler (aber nicht an ihn selbst) aus.
+		return 1;
+	}
+	return 0;
+	// Der Raum konnte nichts mit dem Kommando anfangen, also gib
+	// eine 0 zurueck.
+}
diff --git a/doc/LPC/.synonym b/doc/LPC/.synonym
new file mode 100644
index 0000000..300916b
--- /dev/null
+++ b/doc/LPC/.synonym
@@ -0,0 +1,26 @@
+array arrays
+vererbung inheritance
+erben inheritance
+integer integers
+mapping mappings
+modulo operators
+operatoren operators
+increment operators
+decrement operators
+string strings
+case switch
+private modifiers
+public modifiers
+static modifiers
+nomask modifiers
+protected modifiers
+nosave modifiers
+virtual modifiers
+struct structs
+strong_types pragma
+strict_types pragma
+save_types pragma
+pedantic pragma
+range_check pragma
+rttc pragma
+rtt_checks pragma
diff --git a/doc/LPC/alists b/doc/LPC/alists
new file mode 100644
index 0000000..5550de7
--- /dev/null
+++ b/doc/LPC/alists
@@ -0,0 +1,53 @@
+CONCEPT
+        alists
+
+LAST UPDATE
+        2 Mar 92 21:10:21 GMT
+
+AUTHOR
+        From: amylaar@mcshh.hanse.de (Joern Rennecke)
+        Subject: general documentation on alists
+
+DESCRIPTION
+        Alists provide a fast and convenient way to access data
+        associatively.
+
+        Alists are implemented as arrays of arrays, the first being
+        the array holding the keys, the others arrays holding
+        associated data. An empty alist is an array of empty arrays.
+
+        Note that the the dimensions of the arrays are used the other
+        way than in lisp to allow for faster searching.
+
+        Keys have to be of type integer, string or object. Types can
+        be mixed.
+
+        The search functions return an undefined value when another
+        list is given in place of a presorted key list.
+
+        A list with non-numeric keys retrieved by restore_object() has
+        to be readjusted by using order_alist(), especially after
+        reboot.
+
+        Deleting an entry can safely be done with exclude_array as
+        long as all associated data lists are treated like the key
+        array; index finding for such purposes can be done with assoc.
+
+        Typical applications: holding administrary information about
+        wizards, list of visitors in a pub, list of customers having
+        some sort of credit, information remembered about items etc.
+
+NOTE
+        The main use of alists, storing data associatively, is now
+        better performed by mappings. Alists are needed for more
+        extreme situations only.
+
+        Alists are available only if the driver is compiled with
+        alist support. In that case, __ALISTS__ is defined.
+
+HISTORY
+        LDMud 3.3 made alists an optional efun.
+
+SEE ALSO
+        mappings(LPC), order_alist(E), insert_alist(E), assoc(E),
+        transpose_array(E)
diff --git a/doc/LPC/arrays b/doc/LPC/arrays
new file mode 100644
index 0000000..883dddb
--- /dev/null
+++ b/doc/LPC/arrays
@@ -0,0 +1,116 @@
+CONCEPT
+        arrays
+
+DESCRIPTION
+        There is support for arrays. The arrays can't be declared, but
+        should be allocated dynamically with the function 'allocate()'
+        (see efun/allocate).
+
+        Arrays are stored by reference, so all assignments of whole
+        arrays will just copy the address. The array will be
+        deallocated when no variable points to it any longer.
+
+        When a variable points to an array, items can be accessed with
+        indexing: 'arr[3]' as an example. The name of the array being
+        indexed can be any expression, even a function call:
+        'func()[2]'. It can also be another array, if this array has
+        pointers to arrays:
+
+        arr = allocate(2);
+        arr[0] = allocate(3);
+        arr[1] = allocate(3);
+
+        Now 'arr[1][2]' is a valid value.
+
+        The 'sizeof()' function (in true C a compiler-directive, not a
+        function) will give the number of elements in an array (see
+        efun/sizeof).
+
+NOTE
+        Nowadays it is most of the time preferable to use an array
+        constructor, a list surrounded by '({' and '})',
+        e.g. ({ 1, "xx", 2 }) will construct a new array with size 3,
+        initialized with 1, "xx" and 2 respectively.
+
+
+OPERATIONS
+
+        INDEXING
+        There are several very useful operations defined on arrays.
+        The most used is the indexing:
+                a=({ 0,1,2,3 });
+                return a[2];      // this will return 2
+        You also can count from the end of the array. Use <1 to specify
+        the last element in the array:
+                a=({ 0,1,2,3 });
+                return a[<3];     // this will return 1
+        With indexing you can also create sub-arrays:
+                a=({ 0,1,2,3,4,5,6,7 });
+                return a[3..5];   // this will return ({ 3,4,5 })
+                return a[2..<2];  // this will return ({ 2,3,4,5,6 })
+                return a[<5..<3]; // this will return ({ 3,4,5 })
+                return a[<6..5];  // this will return ({ 2,3,4,5 })
+                return a[3..3];   // this will return ({ 3 })
+                return a[3..2];   // this will return ({ })
+                return a[3..0];   // this will return ({ })
+                return a[5..100]; // this will return ({ 5,6,7 })
+                [x..] is interpreted as [x..<1]
+
+        ADDING
+        You can add two arrays. The result is one array with the elements
+        of both the former arrays:
+                a=({ 0,1 });
+                b=({ "a","b" });
+                return a+b;       // this will return ({ 0,1,"a","b" })
+                return b+a;       // this will return ({ "a","b",0,1 })
+
+        SUBTRACTING
+        You can erase all elements of one array that occur in another
+        array:
+                a=({ 0,1,2,3,4,5,6,7 });
+                b=({ 7,2,5,8,1,9 });
+                return a-b;       // this will return ({ 0,3,4,6 })
+                return b-a;       // this will return ({ 8,9 })
+
+        INTERJUNCTION
+        Use the &-operator to create the interjunction of two arrays:
+                a=({ 5,2,8,1,9,4 })
+                b=({ 1,6,7,3,4,5 })
+                return a&b;       // this will return ({ 1,4,5 })
+
+        ASSIGNING
+        Assigning can also be done to sub-arrays and is thus very powerful:
+                a=({ 0,1,2,3,4,5,6,7 });
+                a[<4..<3]=({ 8,9 });
+                return a;         // this will return ({ 0,1,2,3,8,9,6,7 })
+
+                a=({ 0,1,2,3,4,5,6,7 });
+                a[2..5]=({ });
+                return a;         // this will return ({ 0,1,6,7 })
+
+                a=({ 0,1,2,3,4 });
+                a[3..2]=({ 8,9 });
+                return a;         // this will return ({ 0,1,2,8,9,3,4 })
+
+                a=({ 0,1,2,3,4 });
+                a[3..0]=({ 8,9 });
+                return a;         // this will return ({ 0,1,2,8,9,1,2,3,4 })
+                                  // this is quite funny but true ;-)
+                                  // WARNING: If done unintentionally and
+                                  // within a loop, you can quickly cause
+                                  // the game to run out of memory!
+
+        GENERAL
+        Of course for any of the operators explained above you can use
+        the combined form of assigning and operating; that means the
+        operators +=, -= and &= work.
+
+
+TIPS
+        If you want to make sure that no element is more than once in an
+        array you can use the following:
+                a = m_indices(mkmapping(a));
+        This creates a mapping out of the array and recreates the array
+        at once. The elements in the array can be shuffled by this
+        procedure.
+
diff --git a/doc/LPC/block b/doc/LPC/block
new file mode 100644
index 0000000..29eb382
--- /dev/null
+++ b/doc/LPC/block
@@ -0,0 +1,48 @@
+NAME
+        block
+
+DESCRIPTION
+        A block is a special statment, that begins with '{', contains
+        a list of statements, and ends with '}'.
+
+        The block may define local variables. If for a variable no
+        initialisation is given, the variable is initialised to 0 every
+        time the block is entered. Otherwise, the initialisation
+        expression is evaluated and its result assigned to the variable
+        everytime the block is entered.
+
+        Example definitions are:
+
+          int i;
+          int j = 3;
+          int k = 3 * j, l;
+
+          Here, i and l are both initialised to 0; j is initialised
+          to 3, and k is initialised to 9 (3 * j).
+
+        Local variables defined in a block are visible only until the
+        end of the block. Definitions in an inner block hide definitions in
+        outer blocks.
+
+HISTORY
+        Up to 3.2.7 local variables were visible (from their point of
+        definition) in the whole function. That is, code like
+
+            do {
+                int res;
+
+                res = ...
+            } while (res == 5);
+            write(res);
+
+        was perfectly legal. It is no longer, as 'res' ceases to exist
+        with the closing '}' of the while().
+
+        Up to 3.5.0 you could get this old behaviour back with the 
+        #pragma no_local_scopes and switch it off again with 
+        #pragma local_scopes.
+
+        Since 3.5.0 it is not possible to disable the local scope behaviour.
+
+        Up to 3.2.8, local variables could not be initialised in their
+        definition.
diff --git a/doc/LPC/closure_guide b/doc/LPC/closure_guide
new file mode 100644
index 0000000..438ba46
--- /dev/null
+++ b/doc/LPC/closure_guide
@@ -0,0 +1,730 @@
+Closure Guide for LPC
+
+Table of Contents
+
+        1 Indroduction, Overview and Efun-Closures
+
+        2 Lfun-, Inline and Lambda-Closures
+        2.1 Lfun-Closures
+        2.2 Inline-Closures
+        2.3 Lambda-Closures
+        2.3.1 Advantages of Lambda-Closures
+        2.3.2 Free Variables in Lambda-Closure Constructs
+        2.3.3 Special Efun-Closures and Operator-Closures for Lambdas
+        2.4 Closures with Strange Names
+        2.5 Operator-Closures
+        2.6 Variable-Closures
+
+        3 Examples
+        3.1 Lfun-Closure
+        3.2 Lambda-Closure
+
+1 Introduction, Overview and Efun-Closures
+
+  A closure is a pointer to a function. That means that it is data like an
+  int or a string are. It may be assigned to a variable or given to anoth-
+  er function as argument.
+
+  To create a closure that points to an efun like write() you can write
+  the name of the efun prepended with "hash-tick": #'. #'write is a clo-
+  sure that points to the efun write().
+
+  I very often put parentheses around such a closure-notation because
+  otherwise my editor gets confused by the hashmark: (#'write). This is
+  especially of interest within lambda-closures (see below).
+
+  A closure can be evaluated (which means that the function it points to
+  is called) using the efuns funcall() or apply(), which also allow to
+  give arguments to the function. Example:
+
+    funcall(#'write,"hello");
+
+  This will result in the same as write("hello"); alone. The string
+  "hello" is given as first (and only) argument to the function the clo-
+  sure #'write points to.
+
+  The return value of the function the closure points to is returned by
+  the efun funcall() or apply(). (Since write() always returns 0 the re-
+  turn value of the example above will be 0.)
+
+  What are closures good for? With closures you can make much more univer-
+  sally usable functions. A good example is the function filter().
+  It gets an array and a closure as arguments. Then it calls the function
+  the closure points to for each element of the array:
+
+    filter(({ "bla","foo","bar" }),#'write);
+
+  This will call write("bla"), write("foo") and write("bar") in any order;
+  the order is undefined.
+  (In the current implementation the given closure is evaluated for all
+  elements from the first to the last, so the output will be "blafoobar".)
+
+  Furthermore the efun filter() examines the return value of each
+  call of the function the closure points to (the return value of the
+  write()s). If the value is true (not 0) then this element is put into
+  another array which filter() builds up. If the return value is
+  false (== 0) then this element is _not_ put into this array. When all
+  calls are done the slowly built up array is returned. Thus,
+  filter() filters from the given array all elements that the given
+  closure evaluates "true" for and returns an array of those. (The array
+  given to filter() itself is _not_ changed!)
+
+  A more sensical example for filterwould be this:
+
+    x = filter(users(),#'query_is_wizard);
+
+  users() is an efun that gets no arguments and returns an array of all
+  logged in players (wizards and players). query_is_wizard() is a
+  simul_efun that gets an object as first (and only) argument and returns
+  true (1) if this object is a wizard and 0 otherwise.
+
+  So, for each element of the array returned by users() the function
+  query_is_wizard() is called and only those for which 1 was returned are
+  collected into the result and then put into the variable x.
+
+  We now have all logged in wizards stored as array in the variable x.
+
+  Another example: We want to filter out all numbers that are greater than
+  42 from the array a of integers:
+
+    x = filter(({ 10,50,30,70 }),#'>,42);
+
+  (x will now be ({ 50,70 }).)
+
+  Here two things are new: first: we create a closure that points to an
+  operator; second: we use the possibility to give extra arguments to
+  filter().
+
+  Like all efuns the usual operators can be pointed to with a closure by
+  prepending #' to them. funcall(#'>,4,5) is exactly the same as (4>5).
+
+  The extra arguments given as third to last argument (as many as you
+  like) to filter() are given as second to last argument to the
+  function pointed to by the closure each time it is called.
+
+  Thus we now call (({ 10,50,30,70 })[0]>42), (({ 10,50,30,70 })[1]>42) ...
+  (which is (10>42), (50>42) ...) and return an array of all elements this
+  returns true for and store it into x.
+
+  If you want to create a closure to an efun of which you have the name
+  stored in a string you can create such an efun-closure with the efun
+  symbol_function():
+
+    symbol_function("write") // this will return #'write
+
+    funcall(symbol_function("write"),"foobar");  // == write("foobar");
+
+  This function does not very often occur in normal code but it is very
+  useful for tool-programming (eg the robe uses symbol_function() to allow
+  you call any efun you give).
+
+2 Lfun- and Lambda-Closures
+
+  Very often the possibilities closures to efuns offer are not sufficient
+  for the purpose one has. In nearly all cases three possibilities exist in
+  such cases: use an lfun- or inline-closure, or a lambda-closure.
+
+2.1 Lfun-Closures
+
+    The first possibility is rather easy: like with the efun-closures you
+    can create a pointer to a function in the same object you are by using
+    the #' to prepend it to a function name of a function declared above.
+    Example:
+
+      status foo(int x) {
+        return ((x*2) > 42);
+      }
+
+      int *bar() {
+        return filter(({ 10,50,30,70 }),#'foo);
+      }
+
+    Thus, #'foo is used like there was an efun of this name and doing the
+    job that is done in foo().
+
+2.2 Inline Closure
+
+    Inline closures are a variant of lfun closures, the difference being
+    that the function text is written right where the closure is used,
+    enclosed in a pair of '(:' and ':)'. The compiler will then take care
+    of creating a proper lfun and lfun-closure. The arguments passed to
+    such an inline closure are accessible by position: $1 would be the
+    first argument, $2 the second, and so on. With this, the
+    above example would read:
+
+      int * bar() {
+        return filter(({ 10,50,30,70 }), (: ($1 * 2) > 42 :));
+      }
+
+    or alternatively:
+
+      int * bar() {
+        return filter(({ 10,50,30,70 }), (: return ($1 * 2) > 42; :));
+      }
+
+    The difference between the two versions is that in the first form the text
+    of the inline closure must be an expression only, whereas in the second
+    form any legal statement is allowed. The compiler distinguishes the two
+    forms by the last character before the ':)': if it's a ';' or '}', the
+    compiler treats the closure as statement(s), otherwise as expression.
+
+    Inline closures may also nested, so that the following (not very useful)
+    example is legal, too:
+
+      return filter( ({ 10, 50, 30, 70 })
+                         , (: string *s;
+                              s = map(users(), (: $1->query_name() :));
+                              return s[random(sizeof(s))] + ($1 * 2);
+                            :));
+
+    The notation of inline closures is modelled after the MudOS functionals,
+    but there are a few important differences in behaviour.
+
+
+2.3 Lambda-Closures
+
+    Lambda-Closures take the idea of 'define it where you use it' one step
+    further. On first glance they may look like inline closures with an uglier
+    notation, but they offer a few increased possibilities. But first things
+    first.
+
+    The efun lambda() creates a function temporarily and returns a closure
+    pointing to this function. lambda() therefor gets two arrays as
+    arguments, the first is a list of all arguments the function shall expect
+    and the second array is the code of the function (in a more or less
+    complicated form; at least not in C- or LPC-syntax). The closure #'foo
+    from the example above could be notated as lambda-closure:
+
+      lambda(({ 'x }),({ (#'>),
+                         ({ (#'*),'x,2 }),
+                         42
+                      }))
+
+    Now, the first argument is ({ 'x }), an array of all arguments the
+    function shall expect: 1 argument (called 'x) is expected. Notice the
+    strange notation for this argument with one single leading tick. Like
+    The hash-tick to denote closures the leading tick is used to denote
+    things called "symbols". They do not differ much from strings and if
+    you do not want to have a deeper look into closures you can leave it
+    this way.
+
+    The second argument is an array. The first element of such an array
+    must be an efun- or an lfun-closure, the further elements are the
+    arguments for the function this closure points to. If such an argu-
+    ment is an array, it is treated alike; the first element must be a
+    closure and the remaining elements are arguments (which of course
+    also might be arrays ...).
+
+    This leads to a problem: sometimes you want to give an array as an
+    argument to a function. But arrays in an array given to lambda() are
+    interpreted as code-arrays. To allow you to give an array as an argu-
+    ment within an array given to lambda(), you can use the function
+    quote() to make your array to a quoted array (a quoted array is for
+    an array what a symbol is for a string):
+
+      lambda(0,({ (#'sizeof),
+                  quote(({ 10,50,30,70 }))
+               }))
+
+    For array constants, you can also use a single quote to the same
+    effect:
+
+      lambda(0,({ (#'sizeof),
+                  '({ 10,50,30,70 })
+               }))
+
+    This lambda-closure points to a function that will return 4 (it will
+    call sizeof() for the array ({ 10,50,30,70 })). Another thing: if
+    we want to create a function that expects no arguments, we can give
+    an empty array as first argument to lambda() but we can give 0 as
+    well to attain this. This is just an abbreviation.
+
+    Lambda-closure constructs can become quite large and hard to read. The
+    larger they become the harder the code is to read and you should avoid
+    extreme cases. Very often the possibility to use an lfun or an inline
+    instead of a large lambda shortens the code dramatically. Example:
+
+      status foo(object o) {
+        return environment(o)->query_level()>WL_APPRENTICE;
+      }
+
+      x=filter(a,#'foo);
+
+    does the same as
+
+      x=filter(a,lambda(({ 'o }),
+                              ({ (#'>),
+                                 ({ (#'call_other),
+                                    ({ (#'environment),'o }),
+                                    "query_level"
+                                 }),
+                                 WL_APPRENTICE
+                              })));
+
+    (Note that the syntax with the arrow "->" for call_other()s cannot be
+    used, #'-> does not exist. You have to use #'call_other for this and
+    give the name of the lfun to be called as a string.)
+
+    This example also demonstrates the two disadvantages of lambda closures.
+    First, they are very difficult to read, even for a simple example like
+    this. Second, the lambda closure is re-created everytime the
+    filter() is executed, even though the created code is always the
+    same.
+
+    'Why use lambdas at all then?' you may ask now. Well, read on.
+
+
+2.3.1 Advantages of Lambda Closures
+
+    The advantages of lambdas stem from the fact that they are created
+    at runtime from normal arrays.
+
+    This means that the behaviour of a lambda can be made dependant on data
+    available only at runtime. For example:
+
+      closure c;
+      c = lambda(0, ({#'-, ({ #'time }), time() }) );
+
+    Whenever you now call this closure ('funcall(c)') it will return the
+    elapsed time since the closure was created.
+
+    The second advantage of lambdas is that the arrays from which they
+    are compiled can be constructed at runtime. Imagine a customizable prompt
+    which can be configured to display the time, the environment, or both:
+
+      mixed code;
+
+      code = ({ "> " });
+      if (user_wants_time)
+        code = ({ #'+, ({ #'ctime }), code });
+      if (user_wants_environment)
+        code = ({ #'+, ({#'to_string, ({#'environment, ({#'this_player }) }) })
+                     , code });
+      set_prompt(lambda(0, code));
+
+
+2.3.2 Free Variables in Lambda-Closure Constructs
+
+      You can use local variables in lambda constructs without declaring
+      them, just use them. The only limitation is that you at first have
+      to assign something to them. Give them as symbols like you do with
+      the arguments. This feature does not make much sense without the use
+      of complexer flow controlling features described below.
+
+      The closure #'= is used to assign a value to something (like the
+      LPC-operator = is).
+
+2.3.3 Special Efun-Closures and Operator-Closures for Lambdas
+
+      There are some special closures that are supposed to be used only
+      within a lambda construct. With them you can create nearly all code
+      you can with regular LPC-code like loops and conditions.
+
+      #'? acts like the "if" statement in LPC. The first argument is the
+          condition, the second is the code to be executed if the condition
+          returns true. The following arguments can also be such couples of
+          code-arrays that state a condition and a possible result. If at
+          the end there is a single argument, it is used as the else-case
+          if no condition returned true.
+
+          lambda(({ 'x }),({ (#'?),             // if
+                             ({ (#'>),'x,5 }),  //    (x > 5)
+                             ({ (#'*),'x,2 }),  //       result is x * 2;
+                             ({ (#'<),'x,-5 }), // else if (x < -5)
+                             ({ (#'/),'x,2 }),  //    result is x/2;
+                             'x                 // else result is x;
+                          }))
+
+      #'?! is like the #'? but it negates all conditions after evaluation
+           and thus is like an ifnot in LPC (if there were one).
+
+      #', (which looks a bit strange) is the equivalent of the comma-operator
+          in LPC and says: evaluate all arguments and return the value of
+          the last. It is used to do several things inside a lambda-closure.
+
+          lambda(({ 'x }),({ (#',),  // two commas necessary!
+                                     // one for the closure and one as
+                                     // delimiter in the array
+                             ({ (#'write),"hello world!" }),
+                             ({ (#'say),"Foobar." })
+                          }))
+
+      #'while acts like the LPC statement "while" and repeats executing one
+              code-array while another returns true.
+              #'while expects two or more arguments: the condition as first
+              argument, then the result the whole expression shall have after
+              the condition turns false (this is in many cases of no interest)
+              and as third to last argument the body of the loop.
+
+              lambda(0,({ (#',),            // several things to do ...
+                          ({ (#'=),'i,0 }),    // i is a local variable of this
+                                               // lambda-closure and is
+                                               // initialized with 0 now.
+                          ({ (#'while),
+                             ({ (#'<),'i,10 }),   // condition: i < 10
+                             42,                  // result is not interesting,
+                                                  // but we must give one
+                             ({ (#'write),'i }),  // give out i
+                             ({ (#'+=),'i,1 })    // increase i
+                          })
+                       }))
+
+               The function this closure points to will give out the
+               numbers from 0 to 9 and then return 42.
+
+      #'do is like the do-while statement in LPC and is very much like the
+           #'while. The difference is that #'while tests the condition al-
+           ready before the body is evaluated for the first time, this means
+           that the body might not be evaluated even once. #'do evaluates
+           the body first and then the condition, thus the body is evaluated
+           at least one time.
+           Furthermore, the arguments for #'do are changed in order. #'do
+           expects as first to last but two the body of the loop, then the
+           condition (as last-but-one'th argument) and the result value as
+           last argument. So #'do must have at least two arguments: the
+           condition and the result.
+
+           lambda(0,({ (#',),          // several things to do ...
+                       ({ (#'=),'i,0 }),  // i is a local variable of this
+                                          // lambda-closure and is initialized
+                                          // with 0 now.
+                       ({ (#'do),
+                          ({ (#'write),'i }),  // give out i
+                          ({ (#'+=),'i,1 })    // increase i
+                          ({ (#'<),'i,10 }),   // condition: i < 10
+                          42                   // result is not interesting
+                       })
+                    }))
+
+      NOTE: There is no #'for in LPC, you should use #'while for this.
+
+      #'foreach is like the foreach() statement in LPC. It evaluates one or
+           more bodies repeatedly for every value in a giving string, array
+           or mapping. The result of the closure is 0.
+
+           #'foreach expects two or more arguments:
+            - a single variable symbol, or an array with several variable
+              symbols
+            - the value to iterate over
+            - zero or more bodes to evaluate in each iteration.
+
+           The single values retrieved from the given value are assigned
+           one after another to the variable(s), then the bodies are executed
+           for each assignment.
+
+           lambda(0, ({#'foreach, 'o, ({#'users})
+                                    , ({#'call_other, 'o, "die" })
+                     }));
+
+           lambda(0, ({#'foreach, ({'k, 'v}), ({ ...mapping...})
+                                    , ({#'printf, "%O:%O\n", 'k, 'v })
+                     }));
+
+      #'return gets one argument and acts like the "return" statement in LPC
+               in the function that is created by lambda(). It aborts the
+               execution of this function and returns the argument.
+
+               lambda(0,({ (#'while),// loop
+                           1,        // condition is 1 ==> endles loop
+                           42,       // return value (which will never be used)
+                           ({ (#'write),"grin" })
+                           ({ (#'?!),               // ifnot
+                              ({ (#'random),10 }),  //       (random(10))
+                              ({ (#'return),100 })  //   return 100;
+                           })
+                        }))
+
+                This function will enter an endles loop that will in each
+                turn give out "grin" and if random(10) returns 0 (which will
+                of course happen very soon) it will leave the function with
+                "return 100". The value 42 that is given as result of the
+                loop would be returned if the condition would evaluate to 0
+                which cannot be. (1 is never 0 ;-)
+
+      #'break is used like the "break" statement in LPC and aborts the exe-
+              cution of loops and switches.
+              It must not appear outside a loop or switch of the lambda
+              closure itself, it cannot abort the execution of the function
+              the closure points to!
+
+                lambda(0,({ (#'?),
+                            ({ (#'random),2 }),
+                            ({ (#'break) }), // this will cause the error
+                                             // "Unimplemented operator break
+                                             // for lambda()"
+                            "random was false!"
+                         }));
+
+              You can use ({ #'return,0 }) instead of ({ #'break }) in such
+              cases.
+
+      #'continue is used like the "continue" statement in LPC and jumps to
+                 the end of the current loop and continues with the loop
+                 condition.
+
+      #'default may be used within a #'switch-construct but be careful!
+                To call symbol_function("default") (which is done usually
+                by tools that allow closure-creation) might crash the
+                driver! So please do only use it within your LPC-files.
+                (NOTE: This driver bug is fixed somewhere below 3.2.1@131.)
+
+      #'.. may be used within a #'switch-construct but is not implemented
+           yet (3.2.1@131). But #'[..] works well instead of it.
+
+      #'switch is used to create closures which behave very much like the
+               switch-construct in LPC. To understand the following you
+               should already know the syntax and possibilities of the
+               latter one (which is mightier than the C-version of switch).
+
+               I will confront some LPC versions and the corresponding clo-
+               sure versions below.
+
+               LPC:                  Closure:
+                 switch (x) {          lambda(0,({ (#'switch), x,
+                 case 5:                           ({ 5 }),
+                   return "five";                  ({ (#'return),"five" }),
+                                                   (#',),
+                 case 6..9:                        ({ 6, (#'[..]), 9 }),
+                   return "six to nine";           ({ (#'return),
+                                                      "six to nine" }),
+                                                   (#',),
+                 case 1:                           ({ 1 }),
+                   write("one");                   ({ (#'write),"one" }),
+                   // fall through                 (#',),
+                 case 2:                           ({ 2,
+                 case 10:                             10 }),
+                   return "two or ten";            ({ (#'return),
+                                                      "two or ten" }),
+                                                   (#',),
+                 case 3..4:                        ({ 3, (#'[..]), 4 }),
+                   write("three to four");         ({ (#'write),
+                                                      "three to four" }),
+                   break;  // leave switch         (#'break),
+                 default:                          ({ (#'default) }),
+                   write("something else");        ({ (#'write),
+                                                      "something else" }),
+                   break;                          (#'break)
+                 }                              }))
+
+      #'&& evaluates the arguments from the first on and stops if one evalu-
+           ates to 0 and returns 0. If none evaluates to 0 it returns the
+           result of the last argument.
+
+      #'|| evaluates the arguments from the first on and stops if one evalu-
+           ates to true (not 0) and returns it. If all evaluate to 0 it
+           returns 0.
+
+      #'catch executes the closure given as argument, but catches any
+           runtime error (see catch(E)). Optionally the symbols 'nolog,
+           'publish and 'reserve may be given as additional arguments to
+           modify the behaviour of the catch.
+
+      #'sscanf acts similar to how a funcall would, but passes the third
+           and following arguments as lvalues, that is, values which can
+           be assigned to.
+
+      #'= and the #'<op>= variants are also special because the first
+           argument has to be an lvalue.
+
+2.4 Closures with Strange Names
+
+    #'negate is the unary minus that returns -x for the argument x.
+
+             map(({ 1,2,3 }),#'negate)
+
+             This returns ({ -1,-2,-3 }).
+
+    #'[ is used for the things that in LPC are done with
+             the []-operator (it indexes an array or a mapping).
+
+             lambda(0,({ #'[,quote(({ 10,50,30,70 })),2 })) ==> 30
+             lambda(0,({ #'[,([ "x":10;50, "y":30;70 ]),"x",1 })) ==> 50
+
+    #'[< is the same as #'[ but counts the elements from the
+               end (like indexing with [] and the "<").
+
+    #'[..] returns a subarray of the argument from the one
+             given index to the other given index, both counted from the
+             beginning of the array.
+
+    #'[..<]
+    #'[<..]
+    #'[<..<] same as above, but the indexes are counted from the end,
+
+                lambda(0,({ #'[..<],
+                            quote(({ 0,1,2,3,4,5,6,7 })),2,3
+                         }))
+
+                This will return ({ 2,3,4,5 }).
+    #'[..
+    #'[<.. same as above, but only the first index is given, the
+               subarray will go till the end of the original (like with
+               [x..]).
+
+    #'({ is used to create arrays (as with ({ }) in LPC). All arguments
+             become the elements of the array.
+
+             lambda(0,({ #'({,
+                         ({ (#'random),10 }),
+                         ({ (#'random),50 }),
+                         ({ (#'random),30 }),
+                         ({ (#'random),70 })
+                      }))
+
+             This returns ({ random(10),random(50),random(30),random(70) }).
+
+    #'([ is used to create mappings out of single entries (with seve-
+               ral values) like the ([ ]) in LPC. Very unusual is the fact
+               that this closure gets arrays as argument that are not eval-
+               uated, although they are not quoted.
+
+               lambda(0,({ #'([,
+                           ({ "x",1,2,3 }),
+                           ({ "y",4,5,6 })
+                        }));
+
+               This returns ([ "x": 1;2;3,
+                               "y": 4;5;6 ]).
+
+               However, the elements of the arrays are evaluated as lambda
+               expressions, so if you want to create a mapping from values
+               evaluated at call time, write them as lambda closures:
+
+               lambda(0, ({ #'([, ({ 1, ({ #'ctime }) }) }) )
+
+               will return ([ 1: <result of ctime() at call time ]).
+
+               Arrays can be put into the mapping by quoting:
+
+               lambda(0, ({ #'([, ({ 1, '({ 2 }) }) }) )
+
+               will return ([ 1: ({ 2 }) ])
+
+
+    #'[,] is nearly the same as #'[. The only difference
+                     shows up if you want to index a mapping with a width
+                     greater than 1 (with more than just one value per
+                     key) directly with funcall(). Example:
+                     funcall(#'[,([ 0:1;2, 3:4;5 ]),0,1)
+                     This will not work. Use #'[,] and it will
+                     work. If you want to use it in a lambda closure you
+                     do not have to use #'[,] and #'[ will
+                     do fine. On the other hand, #'[,] cannot
+                     work with arrays, so in nearly all cases use #'[
+                     and just in the described special case, use
+                     #'[,].
+                     This is a strange thing and I deem it a bug, so it
+                     might change in the future.
+
+2.5 Operator-Closures
+
+    Most of the closures that are used for things which are done by opera-
+    tors are in fact not operator-closures but efun-closures. But there are
+    a few which do not have the state of efun-closures but are called
+    "operator-closures". #'return is an example, a complete list of them is
+    given below.
+
+    These closures cannot be called directly using funcall() or apply() (or
+    other efuns like filter()), but must appear only in lambda-con-
+    structs.
+
+      funcall(#'return,4);  // does not work! This will raise an
+                            // Uncallable-closure error.
+      funcall(lambda(0,     // this is a correct example
+                     ({ (#'return),4 })
+                    ));
+
+    All operator-closures:
+    #'&&
+    #'||
+    #',
+    #'?
+    #'?!
+    #'=
+    #'<op>=
+    #'++
+    #'--
+    #'break
+    #'catch
+    #'continue
+    #'default
+    #'do
+    #'foreach
+    #'return
+    #'sscanf
+    #'switch
+    #'while
+    #'({
+    #'([
+
+    #'.. is very likely to be an operator closure too, but since it is
+    not implemented yet, I cannot say for sure.
+
+2.6 Variable-Closures
+
+    All object-global variables might be "closured" by prepending a #' to
+    them to allow access and/or manipulation of them. So if your object has
+    a global variable x you can use #'x within a closure.
+
+    Normally you will treat those expressions like lfun-closures: put them
+    into an array to get the value:
+
+    object.c:
+              int x;
+              int foo() {
+                return lambda(0,({ (#'write),({ (#'x) }) }));
+              }
+
+    Anybody who now calls object->foo() will get a closure which will, when
+    evaluated, write the actual value of object's global variable x.
+
+    Variable closures do not accept arguments.
+
+3 Examples
+
+  In this section I will give and explain some examples coming out of
+  praxis. If the explanation seems to be in some cases too detailed this
+  can be explained by the trial to allow the reader to read the examples
+  section first ;-)
+
+3.1 Lfun-Closure
+
+    An item with a complex long-description like a watch that shall always
+    show the actual time will usually base upon the complex/item-class and
+    give an lfun-closure as argument to the set_long()-method.
+
+    watch.c:
+             inherit "complex/item";
+
+             string my_long() {
+               return ("The watch is small and has a strange otherworldly"
+                       " aura about it.\n"
+                       "The current time is: "+ctime()+".\n");
+             }
+
+             void create() {
+               set_short("a little watch");
+               set_id(({ "watch","little watch" }));
+               set_long(#'my_long);  // the lfun-closure to the lfun my_long()
+             }
+
+3.2 Lambda-Closure
+
+    The example from 3.1 can also be written using a lambda-closure.
+
+    watch.c:
+             inherit "complex/item";
+
+             void create() {
+               set_short("a little watch");
+               set_id(({ "watch","little watch" }));
+               set_long(lambda(0,({ (#'+),
+                                    "The watch is small and has a strange"
+                                    " otherworldly aura about it.\n"
+                                    "The current time is: ",
+                                    ({ (#'+),
+                                       ({ (#'ctime) }),
+                                       ".\n"
+                                    })
+                                 })));
+             }
diff --git a/doc/LPC/closures b/doc/LPC/closures
new file mode 100644
index 0000000..ba5d804
--- /dev/null
+++ b/doc/LPC/closures
@@ -0,0 +1,331 @@
+CONCEPT
+        closures
+
+NOTE
+        This is the official man page concerning closures. If you find
+        it hard to read maybe the Closure Guide is an easier introduction
+        for you: See closure_guide(LPC) and closures-example(LPC).
+
+DESCRIPTION
+        Closures provide a means of creating code dynamically and
+        passing pieces of code as parameters, storing them in
+        variables. One might think of them as a very advanced form of
+        process_string(). However, this falls short of what you can
+        actually do with them.
+
+        The simplest kind of closures are efuns, lfuns or operators.
+        For example, #'this_player is an example of a closure. You can
+        assign it to a variable as in
+
+                closure f;
+                object p;
+                f = #'this_player;
+
+        and later use either the funcall() or apply() efun to evaluate
+        it. Like
+
+                p = funcall(f);
+
+        or
+
+                p = apply(f);
+
+        In both cases there p will afterwards hold the value of
+        this_player().  Of course, this is only a rather simple
+        application.
+
+        Inline closures are a variant of lfun closures, the difference
+        being that the function text is written right where the
+        closure is used.  Since they are pretty powerful by
+        themselves, inline closures have their own manpage.
+
+        More useful instances of closures can be created
+        using the lambda() efun. It is much like the lambda function
+        in LISP. For example, you can do the following:
+
+                f = lambda( ({ 'x }), ({ #'environment, 'x }) );
+
+        This will create a lambda closure and assign it to f. The
+        first argument to lambda is an array describing the arguments
+        (symbols) passed to the closure upon evaluation by funcall()
+        or apply(). You can now evaluate f, for example by means of
+        funcall(f,this_object()). This will result in the following
+        steps:
+
+                1. The value of this_object() will be bound to symbol x.
+                2. environment(x) evaluates to environment(this_object())
+                   and is returned as the result of the funcall().
+
+        One might wonder why there are two functions, funcall() and
+        apply(), to perform the seemingly same job, namely evaluating
+        a closure. Of course there is a subtle difference. If the last
+        argument to apply() is an array, then each of its elements
+        gets expanded to an additional paramater. The obvious use
+        would be #'call_other as in:
+
+                mixed eval(object ob,string func,mixed *args) {
+                  return apply(#'call_other,ob,func,args);
+                }
+
+        This will result in calling
+        ob->func(args[0],args[1],...,args[sizeof(args)-1]).  Using
+        funcall() instead of apply() would have given us
+        ob->func(args).
+
+        Of course, besides efuns there are closures for operators,
+        like #'+, '-, #'<, #'&&, etc.
+
+        Well, so far closures have been pretty much limited despite
+        their obvious flexibility. This changes now with the
+        introduction of conditional and loop operators. For example,
+        try:
+
+                closure max;
+                max = lambda( ({ 'x, 'y }),
+                              ({ #'? ,({ #'>, 'x, 'y }), 'x, 'y }) );
+                return funcall(max,7,3);
+
+        The above example will return 7. What happened? Of course #'?
+        is the conditional operator and its 'syntax' is as follows:
+
+                ({ #'?, cond1, val1, cond2, val2, ..., condn, valn,
+                  valdefault });
+
+        It evaluates cond1, cond2, ..., condn successively until it
+        gets a nonzero result and then returns the corresponding
+        value. If there is no condition evaluating to a nonzero
+        result, valdefault gets returned. If valdefault is omitted, 0
+        gets returned. #'?! works just like #'?, except that the !
+        operator is applied to conditions before testing. Therefore,
+        while #'? is somewhat like an if statement, #'?! resembles an
+        if_not statement if there were one.
+
+        There are also loops:
+
+                ({ #'do, loopbody1, ..., loopbodyN, loopcond, loopresult })
+
+        will evaluate the loopbodies until loopcond evaluates to 0 and
+        then return the value of loopresult. Symbols may be used as
+        variables, of course.
+
+                ({ #'while, loopcond, loopresult, loopbody1, ..., loopbodyN })
+
+        works similar but evaluates loopcond before the loopbodies.
+
+        The foreach() loop also exists:
+
+                ({ #'foreach, 'var, expr, loopbody1, ..., loopbodyN })
+                ({ #'foreach, ({ 'var1, ..., 'varN}) , expr
+                                        , loopbody1, ..., loopbodyN })
+
+
+        Now on to a couple of tricky things:
+
+        a) How do I write down an array within a lambda closure to
+           avoid interpretation as a subclosure?
+
+           ({ #'member, ({ "abc", "xyz" }), 'x }) will obviously
+           result in an error as soon as lambda() tries to interpret
+           "abc" as a closure operator. The solution is to quote the
+           array, as in: ({ #'member, '({ "abc", "xyz" }), 'x }).
+           Applying lambda() to this will not result in an error.
+           Instead, the quote will be stripped from the array and the
+           result regarded as a normal array literal. The same can be
+           achieved by using the efun quote(), e.g.:
+
+           ({ #'member, quote( ({ "abc", "xyz" }), 'x ) })
+
+        b) Isn't it a security risk to pass, say, a closure to the
+           master object which then evaluates it with all the
+           permissions it got?
+
+           Luckily, no. Each closure gets upon compilation bound to
+           the object defining it. That means that executing it first
+           sets this_object() to the object that defined it and then
+           evaluates the closure. This also allows us to call lfuns
+           which might otherwise be undefined in the calling object.
+
+           There is however, a variant of lambda(), called
+           unbound_lambda(), which works similar but does not allow
+           the use of lfuns and does not bind the closure to the
+           defining object. The drawback is that trying to evaluate it
+           by apply() or funcall() will result in an error. The
+           closure first needs to be bound by calling bind_lambda().
+           bind_lambda() normally takes one argument and transforms an
+           unbound closure into a closure bound to the object
+           executing the bind_lambda().
+
+           Privileged objects, like the master and the simul_efun
+           object (or those authorized by the privilege_violation()
+           function in the master) may also give an object as the
+           second argument to bind_lambda(). This will bind the
+           closure to that object. A sample application is:
+
+           dump_object(ob)
+           // will dump the variables of ob to /dump.o
+           {
+             closure save;
+             save = unbound_lambda( ({ }),
+                                    ({ #'save_object, "/open/dump" }) );
+             bind_lambda(save,ob);
+             funcall(save);
+           }
+
+           bind_lambda() can also be used with efun closures.
+
+        c) It might be an interesting application to create closures
+           dynamically as an alternative to writing LPC code to a file
+           and then loading it.  However, how do I avoid doing exactly
+           that if I need symbols like 'x or 'y?
+
+           To do that one uses the quote() efun. It takes a string as
+           its argument and transforms it into a symbol. For example,
+           writing quote("x") is exactly the same as writing 'x.
+
+        d) How do I test if a variable holds a closure?
+
+           Use the closurep() efun which works like all the other type
+           testing efuns. For symbols there is also symbolp()
+           available.
+
+        e) That means, I can do:
+           if (closurep(f)) return funcall(f); else return f; ?
+
+           Yes, but in the case of funcall() it is unnecessary. If
+           funcall() gets only one argument and it is not a closure it
+           will be returned unchanged. So return funcall(f); would
+           suffice.
+
+        f) I want to use a function in some object as a closure. How do I do
+           that?
+
+           There are several ways. If the function resides in
+           this_object(), just use #'func_name. If not, or if you want
+           to create the function dnynamically, use the efun
+           symbol_function(). It takes a string as it first and an
+           object as its second argument and returns a closure which
+           upon evaluation calls the given function in the given
+           object (and faster than call_other(), too, if done from
+           inside a loop, since function search will be done only when
+           calling symbol_function().
+
+        g) Can I create efun closures dynamically, too?
+
+           Yes, just use symbol_function() with a single argument.
+           Most useful for marker objects and the like. But
+           theoretically a security risk if not used properly and from
+           inside a security relevant object.  Take care, however,
+           that, if there is a simul_efun with the same name, it will
+           be preferred as in the case of #'function. Use the efun::
+           modifier to get the efun if you need it.
+
+        h) Are there other uses of closures except using them to store
+           code?
+
+           Lots. For example, you can use them within almost all of
+           the efuns where you give a function as an argument, like
+           filter(), sort_array() or walk_mapping().
+           sort_array(array,#'>) does indeed what is expected. Another
+           application is set_prompt(), where a closure can output
+           your own prompt based on the current time and other stuff
+           which changes all the time.
+
+        Finally, there are some special efun/operator closures:
+
+        #'[ : indexes an array.
+        #'[< : does the same, but starting at the end.
+        #'[..] : gets an array and two numbers
+                and returns a sub-array.
+        #'[..<] : same as above but the second index is
+                interpreted as counted from the left end.
+        #'[<..]  and
+        #'[<..<] : should be clear now.
+        #'[.. : takes only one index and returns the sub-
+                array from this index to the end.
+        #'[<.. : same as above but the index is interpreted
+                as counted from the left end.
+        #'({ : puts all arguments into an array.
+        #'([ : gets an unquoted (!) array which must include
+                at least one element as argument and returns a mapping of
+                the width of the given array's size with one entry that
+                contains the first element as key and the other elements
+                as values to the key.
+
+        #'negate is for unary minus.
+        #', may be followed by any number of closures,
+        e.g.: ({ (#',),
+                 ({#'= 'h, 'a, }), ({#'=, 'a, 'b }), ({#'=, 'b, 'h }) })
+        will swap 'a and 'b when compiled and executed.
+
+
+        Procedural elements:
+        ====================
+
+        definition of terms:
+          <block>  : zero or more values to be evaluated.
+          <test>   : one value to be evaluated as branch or loop condition.
+          <result> : one value to be evaluated at the end of the
+                     execution of the form; the value is returned.
+          <lvalue> : local variable/parameter, global variable, or an
+                     indexed lvalue.
+        useded EBNF operators:
+        { }     iteration
+        [ ]     option
+
+        forms:
+          ({#', <body> <result>})
+          ({#'? { <test> <result> } [ <result> ] })
+          ({#'?! { <test> <result> } [ <result> ] })
+          ({#'&& { test } })
+          ({#'|| { test } })
+          ({#'while <test> <result> <body>})    loop while test
+                                                evaluates non-zero.
+          ({#'do <body> <test> <result>})       loop till test
+                                                evaluates zero.
+          ({#'= { <lvalue> <value> } })         assignment
+                                                other assignment
+                                                operators work, too.
+
+        lisp similars:
+          #',           progn
+          #'?           cond
+          #'&&          and
+          #'||          or
+          #'while       do      /* but lisp has more syntactic candy here */
+          #'=           setq
+
+        A parameter / local variable 'foo' is referenced as 'foo , a
+        global variable as ({#'foo}) . In lvalue positions
+        (assignment), you need not enclose global variable closures in
+        arrays.
+
+        Call by reference parameters are given with ({#'&, <lvalue>})
+
+        Some special efuns:
+        #'[             indexing
+        #'[<            indexing from the end
+        #'negate        unary -
+
+        Unbound lambda closures
+        =======================
+
+        These closures are not bound to any object. They are created
+        with the efun unbound_lambda() . They cannot contain
+        references to global variables, and all lfun closures are
+        inserted as is, since there is no native object for this
+        closure.  You can bind and rebind unbound lambda closures to
+        an object with efun bind_lambda() You need to bind it before
+        it can be called. Ordinary objects can obly bind to
+        themselves, binding to other objects causes a privilege
+        violation().  The point is that previous_object for calls done
+        from inside the closure will reflect the object doing
+        bind_lambda(), and all object / uid based security will also
+        refer to this object.
+
+
+AUTHOR
+        MacBeth, Amylaar, Hyp
+
+SEE ALSO
+        closures-abstract(LPC), closures-example(LPC), closure_guide(LPC)
+        inline-closures(LPC)
diff --git a/doc/LPC/closures-abstract b/doc/LPC/closures-abstract
new file mode 100644
index 0000000..6b1d932
--- /dev/null
+++ b/doc/LPC/closures-abstract
@@ -0,0 +1,82 @@
+Procedural elements:
+====================
+
+definition of terms:
+  <block>     : zero or more values to be evaluated.
+  <test>      : one value to be evaluated as branch or loop condition.
+  <result>    : one value to be evaluated at the end of the execution of
+                the form; the value is returned.
+  <lvalue>    : local variable/parameter, global variable, or an indexed
+                lvalue.
+  <expression>: one value to be evaluated.
+  <integer>   : an integer constant
+  <string>    : a string constant, or 0.
+used EBNF operators:
+{ }        iteration
+[ ]        option
+|        alternative
+
+forms:
+  ({#', <body> <result>})
+  ({#'? { <test> <result> } [ <result> ] })
+  ({#'?! { <test> <result> } [ <result> ] })
+  ({#'&& { test } })
+  ({#'|| { test } })
+  ({#'while <test> <result> <body>...})        loop while test evaluates non-zero.
+  ({#'do <body> <test> <result>})        loop till test evaluates zero.
+  ({#'foreach <var> <expr> <body>...})        loop over all values of <expr>.
+  ({#'foreach ({ <var>...<var> }) <expr> <body>...})
+  ({#'= { <lvalue> <value> } })                assignment
+                			other assignment operators work too.
+  case_label: <integer> | <string> | #'default
+  generalized_case_label: case_label | <integer> #'.. <integer>
+  case_label_list: case_label | ({ { generalized_case_label } })
+  case_delimiter: #', | #'break
+  ({#'switch <expression> { case_label_list <result> case_delimiter } })
+        Evaluate expression, then evaluate the result form labeled with
+        the value equal to the value evaluated from expression.
+        If no matching label exists, the value of #'switch is 0.
+  ({#'catch, <body> [, 'nolog ] [, 'publish ], [, 'reserve, <expr>  })
+        Evaluates the <body> and catches any runtime error. If the symbol
+        'nolog is also given, a caught error is not logged. If the
+        symbol 'publish is also given, master::runtime_error() is
+        called for the caught error. If the symbol 'reserve with a
+        following expression is given, this value is used as the
+        computing reserve.
+
+
+lisp similars:
+  #',                progn
+  #'?                cond
+  #'&&                and
+  #'||                or
+  #'while        do         /* but lisp has more syntactic candy here */
+  #'=                setq
+
+A parameter / local variable 'foo' is referenced as 'foo , a global
+variable as ({#'foo}) . In lvalue positions (assignment), you need not
+enclose global variable closures in arrays.
+
+Call by reference parameters are given with ({#'&, <lvalue>})
+
+Some special efuns:
+#'[                indexing
+#'[<                indexing from the end
+#'negate        unary -
+
+Unbound lambda closures
+=======================
+
+These closures are not bound to any object. They are created with the efun
+unbound_lambda() . They cannot contain references to global variables, and
+all lfun closures are inserted as is, since there is no native object for
+this closure.
+You can bind and rebind unbound lambda closures to an object with efun
+bind_lambda() You need to bind it before it can be called. Ordinary objects
+can obly bind to themselves, binding to other objects causes a privilege
+violation().
+The point is that previous_object for calls done from inside the closure
+will reflect the object doing bind_lambda(), and all object / uid based
+security will also refer to this object.
+
+
diff --git a/doc/LPC/closures-example b/doc/LPC/closures-example
new file mode 100644
index 0000000..f50fd35
--- /dev/null
+++ b/doc/LPC/closures-example
@@ -0,0 +1,202 @@
+CONCEPT
+        closures example
+
+DESCRIPTION
+        This document contains small examples of the usage of
+        (lambda-)closures. For technical details see the closures(LPC)
+        doc. For hints when to use which type of closure, see the end
+        of this doc.
+
+
+        Many Muds use 'details' to add more flavour. 'Details' are
+        items which can be looked at, but are not implemented as own
+        objects, but instead simulated by the environment.
+        Lets assume that the function
+
+          AddDetail(string keyword, string|closure desc)
+
+        adds the detail 'keyword' to the room, which, when look at,
+        returns the string 'desc' resp. the result of the execution of
+        closure 'desc' as the detail description to the player.
+
+        Now imagine that one wants to equip a room with magic runes,
+        which read as 'Hello <playername>!\n" when looked at.
+        Obviously
+
+          AddDetail("runes", sprintf( "Hello %s!\n"
+                                    , this_player()->QueryName()));
+
+        is not sufficient, as the 'this_player()' is executed to early
+        and just once: for the player loading the room.
+
+        The solution is to use closures. First, the solution using
+        lfun-closures:
+
+          private string _detail_runes () {
+            return sprintf("Hello %s!\n", this_player()->QueryName());
+          }
+            ...
+          AddDetail("runes", #'_detail_runes);
+
+        or with an inline closure:
+
+          AddDetail("runes"
+                   , (: sprintf("Hello %s!\n", this_player()->QueryName()) :)
+                   );
+
+
+        Simple? Here is the same code, this time as lambda-closure:
+
+          AddDetail( "runes"
+                   , lambda(0
+                     , ({#'sprintf, "Hello %s!\n"
+                                  , ({#'call_other, ({#'this_player})
+                                                  , "QueryName" })
+                       })
+                   ));
+
+        Why the extra ({ }) around '#'this_player'? #'this_player
+        alone is just a symbol, symbolizing the efun this_player(),
+        but call_other() needs an object as first argument. Therefore,
+        the #'this_player has to be interpreted as function to
+        evaluate, which is enforced by enclosing it in ({ }). The same
+        reason also dictates the enclosing of the whole #'call_other
+        expression into ({ }).
+        Note also the missing #'return: it is not needed. The result
+        of a lambda-closure is the last value computed.
+
+
+        Another example: Task is to reduce the HP of every living in a
+        room by 10, unless the result would be negative.
+        Selecting all livings in a room is simply
+
+          filter(all_inventory(room), #'living)
+
+        The tricky part is to reduce the HP. Again, first the
+        lfun-closure solution:
+
+          private _reduce_hp (object liv) {
+            int hp;
+            hp = liv->QueryHP();
+            if (hp > 10)
+              liv->SetHP(hp-10);
+          }
+            ...
+
+          map( filter(all_inventory(room), #'living)
+                   , #'_reduce_hp)
+
+        or as an inline closure:
+
+          map( filter(all_inventory(room), #'living)
+                   , (: int hp;
+                        hp = liv->QueryHP();
+                        if (hp > 10)
+                          liv->SetHP(hp - 10);
+                      :) );
+
+        Both filter() and map() pass the actual array item
+        being filtered/mapped as first argument to the closure.
+
+        Now, the lambda-closure solution:
+
+          map( filter(all_inventory(room), #'living)
+          , lambda( ({ 'liv })
+            , ({'#, , ({#'=, 'hp, ({#'call_other, 'liv, "QueryHP" }) })
+                    , ({#'?, ({#'>, 'hp, 10 })
+                           , ({#'call_other, 'liv, "SetHP"
+                                           , ({#'-, 'hp, 10 })
+                             })
+                      })
+              })
+            ) // of lambda()
+          );
+
+        It is worthy to point out how local variables like 'hp' are
+        declared in a lambda-closure: not at all. They are just used
+        by writing their symbol 'hp . Same applies to the closures
+        parameter 'liv .
+        The lambda-closure solution is not recommended for three
+        reasons: it is complicated, does not use the powers of
+        lambda(), and the lambda() is recompiled every time this
+        statement is executed!
+
+
+        So far, lambda-closures seem to be just complicated, and in
+        fact: they are. Their powers lie elsewhere.
+
+        Imagine a computation, like for skill resolution, which
+        involves two object properties multiplied with factors and
+        then added.
+        The straightforward solution would be a function like:
+
+          int Compute (object obj, string stat1, int factor1
+                                 , string stat2, int factor2)
+          {
+            return   call_other(obj, "Query"+stat1) * factor1
+                   + call_other(obj, "Query"+stat2) * factor2;
+          }
+
+        Each call to Compute() involves several operations (computing
+        the function names and resolving the call_other()s) which in
+        fact need to be done just once. Using lambda-closures, one can
+        construct and compile a piece of code which behaves like a
+        Compute() tailored for a specific stat/factor combination:
+
+          closure ConstructCompute (object obj, string stat1, int factor1
+                                              , string stat2, int factor2)
+          {
+            mixed code;
+
+            // Construct the first multiplication.
+            // The symbol_function() creates a symbol for the
+            // lfun 'Query<stat1>', speeding up later calls.
+            // Note again the extra ({ }) around the created symbol.
+
+            code = ({#'*, ({ symbol_function("Query"+stat1, obj) })
+                        , factor1 });
+
+            // Construct the second multiplication, and the addition
+            // of both terms.
+
+            code = ({#'+, code
+                        , ({#'*, ({ symbol_function("Query"+stat2, obj) })
+                               , factor2 })
+                   });
+
+            // Compile the code and return the generated closure.
+            return lambda(0, code);
+          }
+
+        Once the closure is compiled,
+
+          str_dex_fun = ConstructCompute(obj, "Str", 10, "Dex", 90);
+
+        it can be used with a simple 'funcall(str_dex_fun)'.
+
+
+DESCRIPTION -- When to use which closure?
+        First, a closure is only then useful if it needn't to live any
+        longer than the object defining it. Reason: when the defining
+        object gets destructed, the closure will vanish, too.
+
+        Efun-, lfun- and inline closures should be used where useful, as they
+        mostly do the job and are easy to read. The disadvantage of lfun- and
+        inline closures is that they make a replace_program() impossible
+        - but since such objects tend to not being replaceable at all, this is
+        no real loss.
+
+        Lambda closures are needed if the actions of the closure are
+        heavily depending on some data available only at runtime, like
+        the actual inventory of a certain player.
+        If you use lfun-closures and find yourself shoving around
+        runtime data in arguments or (gasp!) global variables, it is
+        time to think about using a lambda-closure, compiling the
+        value hard into it.
+        The disadvantages of lambda closures are clear: they are damn
+        hard to read, and each lambda() statement requires extra time to
+        compile the closure.
+
+
+SEE ALSO
+        closures(LPC), closure_guide(LPC), closures-abstract(LPC)
diff --git a/doc/LPC/closures2 b/doc/LPC/closures2
new file mode 100644
index 0000000..fc52894
--- /dev/null
+++ b/doc/LPC/closures2
@@ -0,0 +1,369 @@
+Closures provide a means of creating code dynamically and passing pieces
+of code as parameters, storing them in variables. One might think of them
+as a very advanced form of process_string(). However, this falls short of
+what you can actually do with them.
+
+The simplest kind of closures are efuns, lfuns or operators. For
+example, #'this_player is an example of a closure. You can assign it
+to a variable as in
+
+	closure f;
+	object p;
+	f = #'this_player;
+
+and later use either the funcall() or apply() efun to evaluate it. Like
+
+	p = funcall(f);
+
+or
+	p = apply(f);
+
+In both cases there p will afterwards hold the value of this_player().
+Of course, this is only a rather simple application. More useful
+instances of closures can be created using the lambda() efun. It is much
+like the lambda function in LISP. For example, you can do the following:
+
+	f = lambda( ({ 'x }), ({ #'environment, 'x }) );
+
+This will create a lambda closure and assign it to f. The first argument
+to lambda is an array describing the arguments (symbols) passed to the
+closure upon evaluation by funcall() or apply(). You can now evaluate f,
+for example by means of funcall(f,this_object()). This will result in
+the following steps:
+
+	1. The value of this_object() will be bound to symbol x.
+	2. environment(x) evaluates to environment(this_object())
+	   and is returned as the result of the funcall().
+
+One might wonder why there are two functions, funcall() and apply(), to
+perform the seemingly same job, namely evaluating a closure. Of course
+there is a subtle difference. If the last argument to apply() is an array,
+then each of its elements gets expanded to an additional paramater. The
+obvious use would be #'call_other as in:
+
+	mixed eval(object ob,string func,mixed *args)
+	{
+	  return apply(#'call_other,ob,func,args);
+	}
+
+This will result in calling ob->func(args[0],args[1],...,args[sizeof(args)-1]).
+Using funcall() instead of apply() would have given us ob->func(args).
+
+Of course, besides efuns there are closures for operators, like #'+,
+#'-, #'<, #'&&, etc.
+
+Well, so far closures have been pretty much limited despite their
+obvious flexibility. This changes now with the introduction of
+conditional and loop operators. For example, try:
+
+	closure max;
+	max = lambda( ({ 'x, 'y }), ({ #'? ,({ #'>, 'x, 'y}), 'x, 'y }) });
+	return funcall(max,7,3);
+
+The above example will return 7. What happened? Of course #'? is the
+conditional operator and its 'syntax' is as follows:
+
+	({ #'?, cond1, val1, cond2, val2, ..., condn, valn, valdefault });
+
+It evaluates cond1, cond2, ..., condn successively until it gets a
+nonzero result and then returns the corresponding value. If there is no
+condition evaluating to a nonzero result, valdefault gets returned. If
+valdefault is omitted, 0 gets returned. #'?! works just like #'?, except
+that the ! operator is applied to conditions before testing. Therefore,
+while #'? is somewhat like an if statement, #'?! resembles an if_not
+statement if there were one.
+
+	There are also loops:
+	({ #'do, loopbody, loopcond, loopresult })
+	will evaluate loopbody until loopcond evaluates to 0 and
+	then return the value of loopresult. Symbols my be used
+	as variables, of course.
+
+	({ #'while, loopcond, loopresult, loopbody })
+	works similar but evaluates loopcond before loopbody.
+
+There are, however, some questions open:
+
+a) How do I write down an array within a lambda closure to avoid
+   interpretation as a subclosure?
+   ({ #'member_array, 'x, ({ "abc", "xyz }) }) will obviously result in
+   an error as soon as lambda() tries to interpret "abc" as a closure
+   operator. The solution is to quote the array, as in:
+   ({ #'member_array, 'x, '({ "abc", "xyz }) }). Applying lambda() to
+   this will not result in an error. Instead, the quote will be stripped
+   from the array and the result regarded as a normal array literal. The
+   same can be achieved by using the efun quote(), e.g.:
+   ({ #'member_array, 'x, quote( ({ "abc", "xyz }) ) })
+b) Isn't it a security risk to pass, say, a closure to the master object
+   which then evaluates it with all the permissions it got?
+   Luckily, no. Each closure gets upon compilation bound to the object
+   defining it. That means that executing it first sets this_object()
+   to the object that defined it and then evaluates the closure. This
+   also allows us to call lfuns which might otherwise be undefined in
+   the calling object.
+   There is however, a variant of lambda(), called unbound_lambda(),
+   which works similar but does not allow the use of lfuns and does not
+   bind the closure to the defining object. The drawback is that trying
+   to evaluate it by apply() or funcall() will result in an error. The
+   closure first needs to be bound by calling bind_lambda().
+   bind_lambda() normally takes one argument and transforms an unbound
+   closure into a closure bound to the object executing the
+   bind_lambda().
+   Privileged objects, like the master and the simul_efun object (or
+   those authorized by the privilege_violation() function in the master)
+   may also give an object as the second argument to bind_lambda(). This
+   will bind the closure to that object. A sample application is:
+
+   dump_object(ob)
+   // will dump the variables of ob to /dump.o
+   {
+     closure save;
+     save = unbound_lambda( ({ }), ({ #'save_object, "/open/dump" }) );
+     bind_lambda(save,ob);
+     funcall(save);
+   }
+
+   bind_lambda() can also be used with efun closures.
+
+c) It might be an interesting application to create closures dynamically
+   as an alternative to writing LPC code to a file and then loading it.
+   However, how do I avoid doing exactly that if I need symbols like 'x
+   or 'y?
+   To do that one uses the quote() efun. It takes a string as its
+   argument and transforms it into a symbol. For example, writing
+   quote("x") is exactly the same as writing 'x.
+
+d) How do I test if a variable holds a closure?
+   Use the closurep() efun which works like all the other type testing
+   efuns. For symbols there is also symbolp() available.
+
+e) That means, I can do:
+   if (closurep(f)) return funcall(f); else return f; ?
+   Yes, but in the case of funcall() it is unnecessary. If funcall()
+   gets only one argument and it is not a closure it will be returned
+   unchanged. So return funcall(f); would suffice.
+
+f) I want to use a function in some object as a closure. How do I do
+   that?
+   There are several ways. If the function resides in this_object(),
+   just use #'func_name. If not, or if you want to create the function
+   dnynamically, use the efun symbol_function(). It takes a string as
+   it first and an object as its second argument and returns a closure
+   which upon evaluation calls the given function in the given object
+   (and faster than call_other(), too, if done from inside a loop,
+   since function search will be done only when calling symbol_function().
+
+g) Can I create efun closures dynamically, too?
+   Yes, just use symbol_function() with a single argument. Most useful
+   for marker objects and the like. But theoretically a security risk
+   if not used properly and from inside a security relevant object.
+   Take care, however, that, if there is a simul_efun with the same
+   name, it will be preferred as in the case of #'function. Use the
+   efun:: modifier to get the efun if you need it.
+
+h) Are there other uses of closures except using them to store code?
+   Lots. For example, you can use them within almost all of the
+   efuns where you give a function as an argument, like filter(),
+   sort_array() or walk_mapping(). sort_array(array,#'>) does indeed
+   what is expected. Another application is set_prompt(), where a
+   closure can output your own prompt based on the current time and other
+   stuff which changes all the time.
+
+Finally, there are some special efun/operator closures:
+
+#'[ indexes an array.
+#'[< does the same, but starting at the end.
+#'negate is for unary minus.
+#', may be followed by any number of closures,
+e.g.: ({ #', ({#'= 'h, 'a, }), ({#'=, 'a, 'b }), ({#'=, 'b, 'h }) })
+will swap 'a and 'b when compiled and executed.
+
+------------
+An example from Amylaar:
+
+#I have tested the replace_program() functionality with one example, which I
+#include below. The room is commonly known as /room/orc_valley.c .
+#A prerequisite to make this work is to have valued properties in room.c .
+#The property C_EXTRA_RESET, if defined, is evaluated at reset time in
+#the reset() of the used room.c .
+#Moreover, you need a function to query an unprocessed property to use
+#orc_valley.c from fortress.c (That is, don't do an automatic funcall there.)
+#If you can't supply such a function, you have to set the property "get_orc"
+#at the end of orc_valley.c 's extra_reset() with:
+#    add_prop("get_orc", lambda(0, get_orc) );
+#which will set the property to a function that returns the function that
+#is in the variable get_orc at the time you do the add_prop() call.
+#
+#Back to fortress.c : Assume you have the function successfully queried and
+#stored in the variable get_orc. Now you can compute your extra_reset()
+#function by:
+#    get_orc = lambda( 0, ({#'funcall, get_orc, 8, 40}) );
+#which creates the usual 8 orcs with an a_chat chance of 40.
+#
+#Here comes the orc_valley.c source:
+#
+#    ----------- cut here ------- cut here -------- cut here ------------
+#
+##include "room.h"
+##include "/sys/stdproperties.h"
+##undef EXTRA_RESET
+##define EXTRA_RESET extra_reset();
+#
+#extra_reset() {
+#    closure get_orc;
+#
+#    replace_program("room/room"); /* Must come first. */
+#    get_orc = lambda( ({'num_orcs, 'chat_chance}),
+#       ({#'?!, ({#'present, "orc", ({#'previous_object}) }),
+#           ({#'do,
+#               ({#'=, 'orc, ({#'clone_object, "obj/monster"}) }),
+#               ({#'=, 'i, 9}),
+#               ({#'do,
+#                   ({#'call_other, 'orc, "set_level",
+#                       ({#'+, ({#'random, 2}), 1}) }),
+#                   ({#'call_other, 'orc,
+#                       ({#'[,
+#                           quote(({"set_aggressive", "set_ac", "set_short",
+#                              "set_al", "set_ep", "set_hp", "set_race",
+#                              "set_alias", "set_name"})), ({#'-=, 'i, 1}) }),
+#                       ({#'[,
+#                           quote(({1, 0, "An orc", -60, 1014, 30, "orc",
+#                              "dirty crap", "orc"})), 'i}) }),
+#               'i, 0}),
+#               ({#'call_other, 'orc, "load_a_chat", 'chat_chance,
+#                   quote(({ "Orc says: Kill 'em!\n",
+#                       "Orc says: Bloody humans!\n",
+#                       "Orc says: Stop 'em!\n",
+#                       "Orc says: Get 'em!\n",
+#                       "Orc says: Let's rip out his guts!\n",
+#                       "Orc says: Kill 'em before they run away!\n",
+#                       "Orc says: What is that human doing here!\n",
+#                   })) }),
+#               ({#'=, 'n, ({#'*, ({#'random, 3}), 5}) }),
+#               ({#'=, 'weapon, ({#'clone_object, "obj/weapon"}) }),
+#               ({#'=, 'i, 5}),
+#               ({#'do,
+#                   ({#'call_other, 'weapon,
+#                       ({#'[,
+#                           quote(({ "set_alt_name", "set_weight", "set_value",
+#                               "set_class", "set_name"})), ({#'-=, 'i, 1}) }),
+#                       ({#'[,
+#                           quote(({ "knife", 1, 8,  5, "knife",
+#                               "knife", 1, 15, 7, "curved knife",
+#                               "axe",   2, 25, 9, "hand axe",  })),
+#                           ({#'+, 'n, 'i}) }) }),
+#               'i, 0}),
+#               ({#'transfer, 'weapon, 'orc}),
+#               ({#'command,
+#                   ({#'+, "wield ",
+#                       ({#'call_other, 'weapon, "query_name"}) }), 'orc}),
+#               ({#'move_object, 'orc, ({#'previous_object}) }),
+#           ({#'-=, 'num_orcs, 1}), 0})
+#       })
+#    );
+#    add_prop("get_orc", get_orc);
+#    get_orc = lambda( 0, ({#'funcall, get_orc, 2, 50}) );
+#    add_prop(C_EXTRA_RESET, get_orc);
+#    funcall(get_orc);
+#}
+#
+#TWO_EXIT("room/slope", "east",
+#        "room/fortress", "north",
+#        "The orc valley",
+#        "You are in the orc valley. This place is inhabited by orcs.\n" +
+#        "There is a fortress to the north, with lot of signs of orcs.\n", 1)
+#
+#    ----------- cut here ------- cut here -------- cut here ------------
+#
+Procedural elements:
+====================
+
+definition of terms:
+  <block>  : zero or more values to be evaluated.
+  <test>   : one value to be evaluated as branch or loop condition.
+  <result> : one value to be evaluated at the end of the execution of the
+             form; the value is returned.
+  <lvalue> : local variable/parameter, global variable, or an indexed lvalue.
+useded EBNF operators:
+{ }     iteration
+[ ]     option
+
+forms:
+  ({#', <body> <result>})
+  ({#'? { <test> <result> } [ <result> ] })
+  ({#'?! { <test> <result> } [ <result> ] })
+  ({#'&& { test } })
+  ({#'|| { test } })
+  ({#'while <test> <result> <body>})    loop while test evaluates non-zero.
+  ({#'do <body> <test> <result>})       loop till test evaluates zero.
+  ({#'= { <lvalue> <value> } })         assignment
+                                        other assignment operators work too.
+
+lisp similars:
+  #',           progn
+  #'?           cond
+  #'&&          and
+  #'||          or
+  #'while       do      /* but lisp has more syntactic candy here */
+  #'=           setq
+
+A parameter / local variable 'foo' is referenced as 'foo , a global
+variable as ({#'foo}) . In lvalue positions (assignment), you need not
+enclose global variable closures in arrays.
+
+Call by reference parameters are given with ({#'&, <lvalue>})
+
+Some special efuns:
+#'[             indexing
+#'[<            indexing from the end
+#'negate        unary -
+
+Unbound lambda closures
+=======================
+
+These closures are not bound to any object. They are created with the efun
+unbound_lambda() . They cannot contain references to global variables, and
+all lfun closures are inserted as is, since there is no native object for
+this closure.
+You can bind and rebind unbound lambda closures to an object with efun
+bind_lambda() You need to bind it before it can be called. Ordinary objects
+can obly bind to themselves, binding to other objects causes a privilege
+violation().
+The point is that previous_object for calls done from inside the closure
+will reflect the object doing bind_lambda(), and all object / uid based
+security will also refer to this object.
+
+
+The following is mostly vapourware.
+Well, another application would be that some things in the driver can be,
+sort of, microprogrammed.
+The master object could set some hooks in inaugurate_master(), like creating
+the code for move_object(), using a primitive low_move_object() or
+__move_object() or such. All calls of init(), exit(), etc. can thus be
+controlled on mudlib level.
+The driver would do an implicit bind_lambda() to the victim when the closure
+is used.
+
+e.g.
+({#'?, ({#'=, 'ob, ({#'first_inventory, 'destination}) }),
+    ({#'do,
+        ({#'call_other, 'ob, "init"}),
+    ({#'=, 'ob, ({#'next_inventory, 'ob}) }), 0 })
+})
+
+or
+
+({#'filter_objects, ({#'all_inventory, 'destination}), "init"})
+/* Won't show init failures due to move/destruct */
+
+is equivalent to
+
+if (ob = first_inventory(destination) ) {
+    do {
+        ob->init();
+    } while(ob = next_inventory(ob) );
+}
+
+and it's speed is mainly determined by the call_other. Thus, it shouldn't be
+noticably slower than the current C code in move_object().
+
diff --git a/doc/LPC/comments b/doc/LPC/comments
new file mode 100644
index 0000000..a3b0fd0
--- /dev/null
+++ b/doc/LPC/comments
@@ -0,0 +1,44 @@
+NAME
+        comments
+
+SYNTAX
+        /* block comment text */
+        // line comment text <end of line>
+
+
+DESCRIPTION
+        Comments are used to stored arbitrary text in the LPC program
+        source. It is a good idea if some if this text explains the
+        deeper intentions behind the actual LPC statements.
+
+        There are block comments and line comments.
+
+        Block comments start with a '/*' and end with a '*/'. They cannot
+        be nested, so
+
+          /* this /* is */ illegal */
+
+        will treat '/* this /* is */' as the comment.
+
+        Line comments start with '//' and continue until the unescaped(!)
+        end of the line (as in the new C standard).
+
+        It is not possible to next block and line comments within
+        each other. Meaning: '//' within /* ... */ has no special meaning,
+        neither does '/*' or '*/' have after a //.
+
+EXAMPLES
+        /* Simple block comment */
+
+        /* Block comments can
+           span several lines */
+
+        // Simple line comment
+
+        // Line comments can \
+           span several lines, too!
+
+        //#define LONG_MACRO The unique behaviour \
+           or line comments regarding the end of line \
+           can be used for example to comment out a \
+           large macro with just to keystrokes.
diff --git a/doc/LPC/do-while b/doc/LPC/do-while
new file mode 100644
index 0000000..8f69b2a
--- /dev/null
+++ b/doc/LPC/do-while
@@ -0,0 +1,15 @@
+NAME
+        do-while
+
+SYNTAX
+        do { statement } while(expr);
+
+DESCRIPTION
+        Execute 'statment' until 'expr' evaulates to 0.
+
+        A 'break' in the 'statement' will terminate the loop. A
+        'continue' will continue the execution from the beginning of
+        the loop.
+
+SEE ALSO
+        for(LPC), foreach(LPC), while(LPC), if(LPC), switch(LPC)
diff --git a/doc/LPC/ed0 b/doc/LPC/ed0
new file mode 100644
index 0000000..0edac7f
--- /dev/null
+++ b/doc/LPC/ed0
@@ -0,0 +1,39 @@
+NAME
+        ed0
+
+DESCRIPTION
+        When in 'ed', the prompt is ':'.
+
+        Ed has two modes, command mode and insert mode. The insert
+        mode has no prompt. You exit the insert mode by typing a
+        single '.' on a line.
+
+        All commands have the following syntax:
+
+        X,Ycmd
+
+        or
+
+        Xcmd
+
+        For example:
+
+        1,10p
+        Will print line 1 to 10.
+        1,5d
+        Will delete line 1 to 5.
+        8p
+        Will print line 8.
+        A '.' is the "current line". The current line is the last line
+        referenced. If you want to print last line + 10 more:
+        .,.+10p
+
+NOTE
+        These manpages seem a bit antique, though still correct. For a
+        better detailed help, invoke ed and use the ``h'' command.
+        Also you could look into the man page for ed(1) on you nearest
+        Unix box. And for a bit of fun you can try the good old
+        quiz(6), invoke as ``quiz function ed-command''.
+
+SEE ALSO
+        ed1(LPC), ed(E)
diff --git a/doc/LPC/ed1 b/doc/LPC/ed1
new file mode 100644
index 0000000..25f3ac2
--- /dev/null
+++ b/doc/LPC/ed1
@@ -0,0 +1,32 @@
+NAME
+        ed1
+
+DESCRIPTION
+        Commands that use a line range:
+        If no line is given, then curent line is printed.
+
+        p        Print line.
+        d        Delete line.
+        l        Print line with control characters.
+        r file        Read in a file after the line specified.
+        s        Substitute patterns. See special documentation.
+        z        Print 10 lines.
+        a        Start insert mode after specified line. Exit with
+                '.'<return>.
+        i        Start insert mode before specified line. Exit with
+                '.'<return>.
+
+        Commands used without line specification:
+
+        q        Quit. Won't work if file is changed.
+        Q        Quit and discard all changes if not saved.
+        w        Write the file out.
+        w file        Write the file out with name 'file'.
+        e file        Edit a file.
+        !cmd        Give a game command. For example "say Wait, I am busy".
+
+        As line numbers '.' is current line, and '$' is last line of
+        file. Thus '1,$p' will always print all of the file.
+
+SEE ALSO
+        ed2(LPC)
diff --git a/doc/LPC/ed2 b/doc/LPC/ed2
new file mode 100644
index 0000000..85d520e
--- /dev/null
+++ b/doc/LPC/ed2
@@ -0,0 +1,25 @@
+NAME
+        ed2
+
+DESCRIPTION
+        Substitutions are very advanced.
+
+        First a simple example:
+
+        s/apa/bepa/
+        This will substitue the 'apa' in current line to 'bepa'.
+        If an 'p' is appended, you will also immediately see the result.
+
+        1,$s/apa/bepa/
+        Same, but all lines in file. Only first occurence on every line.
+
+        Any character can used instead of '/':
+        s!apa!bepa!g
+        The 'g' specifies that all occurences of apa on this line are
+        changed to bepa.
+
+        The pattern that are supposed to be replaced, can be a regular
+        expression. See ed3 about that.
+
+SEE ALSO
+        ed3(LPC)
diff --git a/doc/LPC/ed3 b/doc/LPC/ed3
new file mode 100644
index 0000000..380c008
--- /dev/null
+++ b/doc/LPC/ed3
@@ -0,0 +1,30 @@
+NAME
+        ed3
+
+DESCRIPTION
+        Searching is done with:
+        /hello/
+        Find first line in of after current line.
+        Just // will repeat the search.
+
+        The patterns are regular expressions, where some characters
+        have a special meaning:
+        .        Match any character.
+        x*        Match any numbers of x (0 or more).
+        [abc]        Match 'a', 'b' or 'c'.
+        [0-9]        Match any digit 0 - 9.
+        [a-z]        Match any lowercase letter.
+        \x        Match 'x' where 'x' can be any character except '('
+                and ')'.
+
+EXAMPLE
+        s/ab.d/ABCD/
+        Substitute any string 'abXd' against 'ABCD' where X can be any
+        character.
+
+NOTE
+        This only half the truth, there is lots more magic in the
+        regexps.
+
+SEE ALSO
+        regexp(E), ed4(LPC)
diff --git a/doc/LPC/ed4 b/doc/LPC/ed4
new file mode 100644
index 0000000..2d5303c
--- /dev/null
+++ b/doc/LPC/ed4
@@ -0,0 +1,12 @@
+NAME
+        ed4
+
+DESCRIPTION
+        How to copy from a standard file.
+
+        Enter ed. Then do 'r /room/vill_green.c'. Now you have
+        something in the buffer. Change it into what you want it to
+        be. Then 'w /players/peter/hall.c'. Or 'w hall.c'.
+
+SEE ALSO
+        ed5(LPC)
diff --git a/doc/LPC/ed5 b/doc/LPC/ed5
new file mode 100644
index 0000000..9156ff3
--- /dev/null
+++ b/doc/LPC/ed5
@@ -0,0 +1,47 @@
+NAME
+        ed5
+
+DESCRIPTION
+        = : prints current line
+        a : append lines
+        c : change, that is, delate, than insert
+        d : delete line(s)
+        E <filename> :  discard current buffer and edit the file named
+                        <filename>
+        e <filename> : like e, but refuse if file has been changed
+        f : print current filename
+        f <filename> : set filename
+        i : insert line(s)
+        j : with no or one argument: join line with following line
+        j : with two arguments : join line range given
+        k<letter> : set mark <letter> to current line. <letter> must
+                be in the range [a-z] . The mark can be used
+                thereinafter as a line address, with a leading slash.
+                (e.g. ka to set mark a, /ap to print marked line)
+        l : print line with control characters
+        <start>,<end>m<dest> : move block (lines from start to end)
+                                behind line # dest
+        <line>m<dest>        : move single line
+        m<dest>                : move current line
+        M : remove Ctrl-M (CR) characters.
+        p : print line
+        P : print line
+        Q : quit, discarding the buffer
+        q : the same, but refuse if file has been changed since last
+            write
+        r : read in file. If no adress is given, at the last insert
+            position, if also nothing was inserted, at the end of the
+            buffer
+        s : substitute
+        <start>,<end>t<dest>        : copy block ( lines from start to end )
+                                  behind line position dest
+        <line>t<dest>                : copy single line
+        t<dest>                        : copy current line
+        w : write file
+        W : write file
+        x : write file if buffer has been changed since last change,
+            then quit
+        z : show approx. a screenful of lines
+
+SEE ALSO
+        ed6(LPC)
diff --git a/doc/LPC/ed6 b/doc/LPC/ed6
new file mode 100644
index 0000000..8b80a70
--- /dev/null
+++ b/doc/LPC/ed6
@@ -0,0 +1,32 @@
+NAME
+        ed6
+
+DESCRIPTION
+        This is the list of extended ed commands that Xio unearthed
+        somewhere, thanks!
+
+        a) never use 1,$p to print out an editfile, because you will
+          be thrown out 'cause of too much text transfereed to you.
+
+        b) $: jump to end of file.
+
+        c) ?anything? and ?? : search from bottom to up. (like '/'
+           from beginning to end of file. (also with substitutions,
+           try out..)
+
+        d) ( g/xxx/p search global xxx and print corresponding lines,
+           /xxx/s/new/old/p : search xxx, substitute new to old in this
+           line and print out. (try this concatenations with other
+           commands)
+
+        e) 1,nmx ( see ed5 ) , but also: 1,ntx : don't move the lines,
+           but make a copy of them.
+
+        f) x,y w name : save lines x to y to file name (if you don't
+           know the line numbers : '=' current line number)
+
+        g) s/$/text/p : append text to the end of current LINE and
+           print line
+
+        h) s/^/text/p : insert text at beginning og current LINE and
+           print line
diff --git a/doc/LPC/efuns b/doc/LPC/efuns
new file mode 100644
index 0000000..ca5b224
--- /dev/null
+++ b/doc/LPC/efuns
@@ -0,0 +1,16 @@
+CONCEPT
+        efuns
+
+DESCRIPTION
+        Efuns are "system calls" in the LPC driver, the C program
+        which compiles and executes the LPC programs of the mudlib.
+        These are hardcoded functions which perform basic tasks which
+        would be ineffective or impossible to be implemented in the
+        mudlib.
+
+        There are efuns for accessing the underlying filesystem, for
+        creating, moving and destructing objects, for writing
+        messages to users, for manipulation of LPC data types.
+
+SEE ALSO
+        efun(E), lfuns(LPC), applied(A), master(M)
diff --git a/doc/LPC/escape b/doc/LPC/escape
new file mode 100644
index 0000000..8518749
--- /dev/null
+++ b/doc/LPC/escape
@@ -0,0 +1,81 @@
+CONCEPT
+        character escape codes
+
+DESCRIPTION
+	Character escape codes are used to represent some common
+	special characters that would be awkward or impossible to
+	enter in the source program directly. The escape characters
+	come in two varieties: 'character escapes', which can be
+	used to represent some particular formatting and special
+	characters, and 'numeric escapes', which allow a character to
+	be specified by its numeric encoding.
+
+	Escapes begin always with a backslash '\'. If the following
+	characters could not be treated as a valid escape the backslash
+	is merely ignored.
+
+	The following character escapes are available in LPC (the code
+	may differ from platform to platform):
+
+	  \a    Code 007    Bell
+          \b    Code 008    Backspace
+          \e    Code 027    Escape
+	  \f    Code 012    Formfeed
+	  \n    Code 010    Newline
+	  \r    Code 013    Carriage-Return
+	  \t    Code 009    Tabulator
+	  \\    Code 092    Backslash itself
+	  \'    Code 039    Single quote
+	  \"    Code 034    Double quote
+
+	The single quote may appear without preceding backslash in character
+	constants, and the double quote may appear without a backslash in
+	string constants.
+
+	The numeric escapes could be used to express a character directly
+	by its code in binary, octal, decimal or hexadecimal notation.
+	
+	  \0b   Beginning of binary notation
+	  \0o   Beginning of octal notation
+	  \0x   Beginning of hexadecimal notation
+	  \x    Beginning of hexadecimal notation
+
+	A backslash followed by a digit ([0-9]) which does not map to one
+	of the above starts an escape in decimal notation.
+
+	A numeric escape terminates when N digits have been used up or
+	when the first character that is not a valid digit in that
+	notation is encountered. N is 2 for hexadeximals, 3 for
+	decimals and octals and 8 for binarys.
+
+	If the specified code is greater than 255 a warning is issued and
+	the value modulo 256 is used.
+
+EXAMPLES
+	Put a newline at the end of user output
+	  "You enter.\n"
+
+	Alert the user
+	  "Beeep.\a Wake up\n"
+
+	Put a double quote in a string
+	  "You say \"hello\"\n"
+
+	Write the line from above
+	  "\"You say \\\"hello\\\"\\n\""
+
+	Put a single quote in a string
+	  "You say 'hello'\n"
+
+	Some forms to write "abcde"
+	  "abcde"
+	  "ab\99de"              (with c's code being 99)
+	  "ab\099de"
+	  "ab\x63de"             (99 = 0x63)
+	  "ab\0x63de"
+
+	The following string consists of two characters
+	  "\0111"                (\011 and 1)
+
+	The following string consists of three characters
+	  "\0o090"               (\000 and 9 and 0)
diff --git a/doc/LPC/for b/doc/LPC/for
new file mode 100644
index 0000000..e7a988d
--- /dev/null
+++ b/doc/LPC/for
@@ -0,0 +1,36 @@
+NAME
+        for
+
+SYNTAX
+        for(init; expr2; expr3) statement;
+
+DESCRIPTION
+        Execute <init> once. Then, while <expr2> returns a non-zero
+        value, execute <statement>. Every time <statement> has been
+        executed, or a 'continue' statement has been executed, execute
+        <expr3> before next loop.
+
+        <init> is usually a series of one or more expressions (remember
+        that assignments are expressions, too), separated by commas.
+        Additionally it is also allowed to define new local variables
+        here and assign them an initial value. The scope of such variables
+        is the whole for statement.
+
+        Examples for legal <init> expressions are:
+
+           for (i = 0; ...
+           for (i = 0, j = 0; ...
+           for (i = 0, int j = i; ...
+           for (int j = 4; ...
+
+        Illegal <init> expressions are:
+
+           for (int i; ...      : no value assigned
+           for (int i += 4; ... : only plain assignments allowed
+
+        A 'break' in the 'statement' will terminate the loop. A
+        'continue' will continue the execution from the beginning of
+        the loop.
+
+SEE ALSO
+    foreach(LPC), if(LPC), do-while(LPC), while(LPC), switch(LPC)
diff --git a/doc/LPC/foreach b/doc/LPC/foreach
new file mode 100644
index 0000000..7e6060b
--- /dev/null
+++ b/doc/LPC/foreach
@@ -0,0 +1,132 @@
+NAME
+        foreach
+
+SYNTAX
+        foreach (<var> : <expr>) <statement>;
+        foreach (<var>, <var2>, ... ,<varN> : <expr>) <statement>;
+
+        foreach (<var> : <expr1> .. <expr2>) <statement>;
+        foreach (<var>, <var2>, ... ,<varN> : <expr1>..<expr2> ) <statement>;
+
+        /* MudOS compatibility only - not for new code: */
+        foreach (<var> in <expr>) <statement>;
+        foreach (<var>, <var2>, ... ,<varN> in <expr>) <statement>;
+
+DESCRIPTION
+        The instruction evaluates its range specification - either a
+        simple <expr> which can yield an array, a struct, a string, a
+        mapping or an integer, or an integer range <expr1> through
+        <expr2> - and executes <statement> once for each value in the
+        range. The respective value is assigned to <var> right before
+        <statement> is executed.
+
+        A 'break' in the <statement> will terminate the loop. A
+        'continue' will continue the execution from the beginning of
+        the loop.
+
+        Every <var> specification can declare a new local variable, whose
+        scope is the whole foreach() statement.
+
+
+        The normal form (one <expr>):
+
+            <expr> is evaluated and has to yield an array, a struct, a
+            string or a mapping (or reference to the former), or an
+            integer.
+
+            If <expr> is a array, struct, or string, the values of
+            <expr> (in case of the string, the integer values of the
+            characters) are then assigned one by one in order of
+            occurence to <var>, and <statement> is executed for every
+            assignment.
+
+            If <expr> is a mapping, the keys are assigned one by one
+            to <var>, and the values for each key are assigned in
+            order to <var2>..<varN>.  If there are more values than
+            variable, the extraneous values are ignored. Due to the
+            nature of mappings, a specific order of the keys can not
+            be guaranteed.
+
+            If <expr> evaluates to a reference to an array, mapping, or
+            string, the loop will assign references to the values into
+            the variables. This allows the loop body to change the contents
+            of the original data.
+
+            If <expr> evalutes to an integer, the loop will count up <var>
+            from 0 to <expr>-1, basically implementing a count loop.
+
+            If there are more variables than necessary, the unneeded ones
+            are not changed.
+
+
+        The ranged form (<expr1> .. <expr2>):
+
+            <expr1> and <expr2> are evaluated and must yield integers.
+            The loop will count up <var> from <expr1> to <expr2>, basically
+            implementing a counted loop.
+
+            If <expr1> is less than <expr2>, the loop will terminate at once.
+
+            If there are more than variable, the unneeded ones are not
+            changed.
+
+
+
+        WHAT HAPPENS IF <expr> IS CHANGED IN THE LOOP?
+
+        If <expr> yields an array or struct:
+         - assignments to single elements or to array ranges effect
+           the values assigned to the variable:
+             a = ({1, 2, 3})
+             foreach(x : a) { a[1..2] = ({4, 5}); write(x+" "); }
+           will write ("1 4 5 ").
+         - operations which implicitely copy the array or struct (this
+           includes range assignments which change the size) don't
+           have an effect on the loop.
+
+        If <expr> yields a mapping, the loop will run over the indices
+        the mapping had at the begin of the loop. Deleted indices are silently
+        skipped, new indices ignored, but changes of the data of existing
+        indices are acknowledged.
+
+        If <expr> yields a string, the value used at the start of the loop
+        remains.
+
+
+WARNING
+        The additional syntax forms using "in" as keyword are meant
+        to make re-engineering of MudOS objects easier. Do not use them
+        for newly written code, as they may not be available in future.
+
+
+EXAMPLES
+        // Call quit() in all interactive users
+        foreach(o : users()) o->quit();
+        foreach(object o : users()) o->quit();
+
+        // Print the contents of a mapping <m>
+        foreach(key, value : m) printf("%O:%O\n", key, value);
+        foreach(mixed key, mixed value : m) printf("%O:%O\n", key, value);
+
+        // Don't change the content of a string: s remains "FOOBAR".
+        s = "FOOBAR";
+        foreach(i : s) i += 32;
+
+        // Do change the content of a string: s will become "foobar".
+        s = "FOOBAR";
+        foreach(i : &s) i += 32;
+
+        // Count from 0 to 5
+        foreach(i : 6) printf("%d\n", i);
+
+        // Count from 1 to 6
+        foreach(i : 1 .. 6) printf("%d\n", i);
+
+HISTORY
+        LDMud 3.3.44 introduced the use of references, the loop over
+          an integer expression, and the loop over an integer range.
+        LDMud 3.3.266 added support for structs.
+
+
+SEE ALSO
+        for(LPC)
diff --git a/doc/LPC/functions b/doc/LPC/functions
new file mode 100644
index 0000000..50c39a0
--- /dev/null
+++ b/doc/LPC/functions
@@ -0,0 +1,174 @@
+CONCEPT
+        functions
+
+DESCRIPTION
+        Functions are named blocks of code which are be called with
+        a number of argument values, and which return a result value
+        to the caller.
+
+        Functions are defined in an object and are also known as
+        "local funs" or short "lfuns".
+
+
+        DEFINING A FUNCTION
+
+        A function definition takes the form
+
+          <modifiers> <type> name ( <arguments> ) {
+             statements...
+          }
+
+        The parts in detail:
+          - <modifiers> can be any one of "static", "private", "public"
+              and "protected" (see modifiers(LPC)), optionally combined
+              with "varargs" (see varargs(LPC)) and/or "nomask".
+              If not specified, the function behaves as if it was
+              specified as "public", but this visibility can be restricted
+              in derived object through non-public inheritance.
+          - <type> is the type of the result returned by the function.
+              If specified as "void", the function is compiled to return
+              the value 0 under all circumstances. If not specified, the
+              type is assumed to be "mixed", furthermore typechecking is
+              disabled for this function.
+          - name is the name of the function, e.g. "short", or "Nice_Try",
+              under which it is made known.
+          - <arguments> is a list of variable definitions in the
+              normal '<type> <name>' style, separated by comma.
+              Examples: () : no argument taken
+                        (int a) : takes on integer argument
+                        (mixed a, object *b): takes two arguments, one
+                           arbitrary type, one array of objects.
+          - { statements... } defines the code for this function. This
+              is a normal block (see block(LPC)) and as such can define
+              its own local variables.
+
+
+        DECLARING A FUNCTION
+
+        A function declaration makes the name and type of a function known
+        to the compiler with the assertion that the code for this function
+        will be provided "elsewhere".
+
+        The form is:
+
+          <modifiers> <type> name ( <arguments> );
+
+        Typical uses are:
+          - to declare in advance functions which are called before they
+            can be defined; for example if the create() function of an object
+            calls other functions which are defined after the create().
+          - to declare functions which will be provided by an inheriting
+            object.
+
+        Calling a declared but undefined function results in a runtime error.
+
+
+        CALLING A FUNCTION
+
+        Functions in other objects are called with the call_other() efun,
+        which can be shortened to '->':
+
+           ob->fun(a, b, c)
+           call_other(ob, "fun", a, b, c)
+
+        Note: See the entry H_DEFAULT_METHOD in hooks(C) for a modification
+        of this behaviour.
+
+        Functions in the same object are called just by writing their name,
+        followed by the arguments in parenthesis:
+
+           short()
+           compute(a)
+           do_that(a, "foo")
+
+        Array function arguments can be 'flattened' with the '...' operator.
+        For example:
+
+           mixed * m = ({ "foo", "bar" });
+           fun(m..., 1);
+
+        will be executed as:
+
+           fun("foo", "bar", 1);
+
+
+        If the number of values passed to the function does not match the
+        number of expected arguments (and if type checking is not enabled), the
+        driver will perform the necessary adaption at call time: excess
+        values are ignored, missing values are substituted by the number 0.
+        The values passed to the called function are massaged by the driver
+        to match the argument list
+
+
+        FUNCTIONS AND INHERITANCE
+
+        A "public" or "protected" (== "static") function defined in one
+        object is also visible in all inheriting objects. The exception from
+        this rule is when an inheriting child redefines ("overloads") the
+        inherited function with its own. When compiling with type checking,
+        the argument list of the redefined function has to match the
+        original one.
+
+        When a function is called, the driver looks for the function first
+        in the object called, and if not found there, then in the inherited
+        objects.
+
+        To explicitely call an inherited function (useful when a redefining
+        functions wants to use the original one), the "::" operator is used:
+
+            ::create()
+            ::compute(a)
+
+        The named function is searched only in the inherited objects, and
+        the first found is used.
+
+
+        If the function is inherited from several objects and a specific
+        one is to be called, the "::" can be extended to contain the
+        partial or full name of the inherited object:
+
+            inherit "/obj/cooker";
+            inherit "/obj/container";
+
+            tainer::create()
+            container::create()
+            "tainer"::create()
+            "container"::create()
+            "obj/container"::create()
+            "/obj/container"::create()
+
+        all call the create() in the container inherit. Note that the
+        name given to the :: operator is matched against the ends of
+        the inherited names.
+
+
+        One special form of this call is
+
+            efun::find_object()
+
+        which bypasses any redefinition of an efun (here find_object())
+        and directly calls the efun itself. This is only possible for
+        efun-redefinitions which do not use the "nomask" modifier.
+
+
+        Additionally, a call to a function inherited from several objects
+        can be instructed to call _all_ inherited functions through the
+        use of the wildcards "*" (match any number of arbitrary characters)
+        and "?" (match one arbitrary character):
+
+            inherit "/obj/cooker";
+            inherit "/obj/container";
+
+            "*"::create()
+            "co*"::create()
+            "*er"::create()
+
+        all call both inherited create()s. The function called this way
+        must not take arguments, and the single results from all calls are
+        combined into one array used as final result. If there is no such
+        function inherited at all, the statement will just return
+        an empty array.
+
+SEE ALSO
+        types(LPC), modifiers(LPC), varargs(LPC), references(LPC),
+        call_other(E), simul_efun(C), call_out(E)
diff --git a/doc/LPC/if b/doc/LPC/if
new file mode 100644
index 0000000..33bbff2
--- /dev/null
+++ b/doc/LPC/if
@@ -0,0 +1,39 @@
+NAME
+        if
+
+SYNTAX
+        if (expr1) statement1;
+        else if (expr2) statement2;
+        ...
+        else if (exprN) statementN;
+        else statementX;
+
+DESCRIPTION
+        The if() statement implements the conditional execution of statements.
+        The expressions 'expr1' .. 'exprN' are evaluate in the order they
+        appear until one of the expressions returns non-0 ('true'). At that
+        point, the statement associated with the expression is executed, and
+        the program continues after the if() statement. If none of the
+        expressions evaluate to 'true', the statementX in the 'else'-branch
+        is executed.
+
+        Both the 'else if' branches and the 'else' branch are optional, and
+        there can be any number of 'else if' branches - but there must be one
+        'if' branch, and the branches must be in the order given above.
+
+        Any 'else' or 'else if' always relates to the immediately preceeding
+        'if' resp. 'else if' conditional. This means that
+
+          if (a)
+          if (b) do_b;
+          else do_c;
+
+        is interpreted as
+
+          if (a) {
+            if (b) do_b;
+            else   do_c;
+          }
+
+SEE ALSO
+        for(LPC), foreach(LPC), do-while(LPC), while(LPC), switch(LPC)
diff --git a/doc/LPC/inherit b/doc/LPC/inherit
new file mode 100644
index 0000000..0e4c0f2
--- /dev/null
+++ b/doc/LPC/inherit
@@ -0,0 +1,9 @@
+NAME
+        inherit
+
+DESCRIPTION
+        The concept of inheritance and the inherit statement are
+        explained in detail in the man page for ``inheritance''.
+
+SEE ALSO
+        inheritance(C)
diff --git a/doc/LPC/inheritance b/doc/LPC/inheritance
new file mode 100644
index 0000000..23fb804
--- /dev/null
+++ b/doc/LPC/inheritance
@@ -0,0 +1,181 @@
+KONZEPT
+     inheritance
+
+BESCHREIBUNG
+     Mittels Vererbung kann man das Verhalten und/oder die implementierten
+     Methoden eines Objektes in ein neues Objekt hineinerben.
+
+     1. Wozu ist Vererbung gut
+     1.1. Erben von Implementationen: Strukturieren von Bibliotheken
+     Mit Vererbung der Implementation koennen aufeinander aufbauende und gut
+     wart-/nutzbare Strukturen geschaffen werden:
+     
+     /std/thing/description beinhaltet
+     - wie ein Objekt aussieht/welche Details es gibt
+     - wie man das Objekt finden/identifizieren kann
+     /std/thing/moving beinhaltet
+     - wie man ein Objekt bewegen kann
+     /std/thing erbt
+     - /std/thing/description und
+     - /std/thing/moving
+     - damit den Code aus beiden Objekten (und noch andere)
+
+     Sowohl thing/description als auch thing/moving sind nicht als
+     eigenstaendige Objekte sinnvoll nutzbar, sind abstrakt.
+
+     1.2. Erben von Schnittstellen und Verhalten      
+     Durch das Erben von /std/thing werden Schnittstelle und auch
+     Verhalten von /std/thing geerbt:
+     
+     -- keks.c --
+     inherit "/std/thing";
+     --
+     
+     Dadurch koennen jetzt andere Objekte, wie NPCs oder Spieler mit dem
+     Keks-Objekt so interagieren, als wenn es ein /std/thing waere.
+
+     Morgengrauen stellt eine grosse Bibliothek von miteinander sinnvoll
+     agierenden Objekten unter /std zur Verfuegung, Die dort verfuegbaren
+     Objekte sind groesstenteils selbsterklaerend, wie /std/npc,
+     /std/armour oder /std/weapon.
+
+     Das Keks-Objekt muss erweitert werden, wenn es sich vom normalen
+     Ding unterscheiden soll. Typischerweise geschieht das durch
+     Ueberschreiben der Initialisierungmethode namens "create". 
+       
+     2. Ueberschreiben/Erweitern von Verhalten/Methoden
+     2.1. Ueberschreiben
+     Um das Verhalten von geerbten Methoden zu erweitern, muss diese
+     ueberschrieben werden:
+     
+     -- keks.c --
+     ...
+     void create() {
+       SetProp(P_NAME, "Keks");
+       SetProp(P_GENDER, MALE);
+       AddId(({"keks"}));
+     }
+     --
+     
+     Allerdings wuerde jetzt der normale Code von "create" in /std/thing
+     nicht mehr ausgefuehrt werden. Mit dem 'scope'-Operator :: wird
+     innerhalb einer ueberschriebenen Methode auf deren bisherige
+     Implementation zugegriffen:
+
+     -- keks.c --
+     ...
+     void create() {
+       ::create();
+       SetProp(P_NAME, "Keks");
+       SetProp(P_GENDER, MALE);
+       AddId(({"keks"}));
+     }
+     --
+
+     Auf geerbte globale Variablen kann normal zugegriffen werden, wenn 
+     diese nicht vor direktem Zugriff durch erbende Objekte geschuetzt
+     wurden. Also in ihrer Sichtbarkeit veraendert wurde.
+     
+     Ueberschreiben von Methoden in den davon erbenden Objekten kann durch
+     das Schluesselwort 'nomask' verboten werden.
+
+     2.2. Sichtbarkeit von Methoden und Variablen
+     Es ist moeglich, Methoden und Variablen mit einem Modifikator fuer
+     ihre Sichtbarkeit zu versehen, der auch bei der Vererbung zum
+     Tragen kommt:
+     - 'public' Methoden sind von aussen/innen in Eltern/Kind zugreifbar
+     - 'protected' Methoden sind nur von innen in Eltern/Kind zugreifbar
+     - 'private' Methoden sind nur von innen in Eltern zugreifbar
+                 (also nur im definierenden Objekt selbst)   
+
+     2.3 Laufzeit-Polymorphie (vielgestaltes Verhalten)
+     Methoden werden in LPC immer erst zum Zeitpunkt ihres Aufrufs
+     gebunden, also nicht schon beim Laden. Beispielsweise koennen
+     wir unseren Keks essbar machen:
+
+     -- keks.c --
+     ...
+     void create() {
+       ...
+       AddCmd("iss&@ID", "action_essen", "Was willst du essen?");
+     }
+     
+     int action_essen() {
+       if(this_player()->eat_food(1, 0, 
+                                 "Du bekommst "+QueryPronoun(WEN)+
+				 " nicht mehr hineingestopft.\n")>0) {
+         write("Du isst "+name(WEN,1)+".\n");
+         say(this_player()->Name(WER)+" isst "+name(WEN)+".\n");
+         remove();
+       }
+       return 1;
+     }
+     --
+     
+     und jetzt in einem davon erbenden Kruemelkeks diesen beim Entfernen
+     im "remove" kruemeln lassen:
+     
+     -- kruemelkeks.c --
+     inherit "/doc/beispiele/inherit/keks.c";
+     ...
+     varargs int remove(int silent) {
+       if(!silent && living(environment()))
+         tell_object(environment(), Name(WER,1)+
+	                            " kruemelt ein letztes Mal.\n");
+       return ::remove(silent);
+     }
+     --
+     
+     Trotzdem wir "action_essen" nicht modifiziert haben, wird von dieser
+     Methode in einem Kruemelkeks immer automatisch die aktuelle und
+     kruemelende "remove" aufgerufen.
+
+     3. Multiple Inheritance
+     In LPC ist multiple Vererbung moeglich. Das heisst, man kann von 
+     mehreren Objekten erben. Das kann zu Konflikten fuehren, zum Beispiel 
+     wenn eine Methode in zwei Objekten von denen geerbt wurde vorkommt. 
+     
+     Diese Konflikte sollte man dann "per Hand" loesen in dem man diese 
+     spezielle Methode ueberschreibt und mittels des scope-Operators die 
+     gewuenschte(n) geerbt(en) Methode(n) aufruft:
+
+     inherit "/std/weapon";
+     inherit "/std/lightsource";
+
+     void create() {
+       weapon::create();
+       lightsource::create();
+       ...
+     }
+
+     void init() {
+       weapon::init();
+       lightsource::init();
+       // oder sehr generell und unkontrolliert:
+       // "*"::init();
+     }
+
+     Schwerwiegende Konflikte koennen auftreten, wenn eine gleichnamige
+     Variable aus verschiedenen Objekten geerbt wird. Die Variablen
+     existieren im letztlich erbenden Objekt zweimal und die verschiedenen
+     geerbten Methoden greifen auf ihre jeweilige Variante zu.
+
+     Beispiel ist die sog. "Masche" oder der "Diamond of Death": 
+
+                        A    (Ursprungsobjekt mit globaler Variable x)   
+                       / \
+                      B   C  (B, C erben von A und manipulieren beide x)
+                       \ /
+                        D    (D erbt von B und A)
+
+     Mit dem Schluesselwort 'virtual' kann die Doppelung beim Erben
+     in B und C unterbunden werden.
+
+SIEHE AUCH:
+     inherit
+     private, protected, public, nomask
+     virtual
+     objekte, oop
+     /doc/beispiele/inherit
+
+2.Feb 2008 Gloinson
diff --git a/doc/LPC/initialisation b/doc/LPC/initialisation
new file mode 100644
index 0000000..61f3c2b
--- /dev/null
+++ b/doc/LPC/initialisation
@@ -0,0 +1,93 @@
+CONCEPT
+
+        VARIABLE INITIALIZATION
+
+DESCRIPTION
+        Global variables, like their local counterparts, can be defined
+        with an initial value:
+
+            int * a = ({ 3, 4 });
+
+        The initialization value can be any legal LPC expression,
+        including function calls. The code for the initializations is
+        collected in a compiler-generated function __INIT() which is
+        called even before the create-hook is applied on the object.
+
+        During initialization, blueprints and clones are treated
+        slightly differently:
+
+        Blueprint variables are always all initialized using __INIT().
+
+        For clones the programmer can select whether the clone's
+        variables should also be initialized with __INIT(), or if they
+        should be assigned from the current blueprint values
+        ('shared with the blueprint'). The latter method is useful for
+        example if blueprints and clones shall share arrays or
+        mappings.
+
+        The selection is performed with the two pragmas
+        'init_variables' and 'share_variables'. The status of this
+        pragma at the point of the first variable definition counts,
+        and is applied to all variables in the program.
+
+        The clone initialization method is evaluated per-program, i.e.
+        if an inherited program defines 'share_variables' and the child
+        program doesn't, only the inherited variables are initialized
+        from the blueprint, and all others from __INIT().
+
+        The default setting for the pragma is configured into the
+        driver, but can also be chosen when starting the driver.
+        
+EXAMPLE
+        For the object
+
+          ----------
+          inherit "a";
+          int a = 4;
+          int b;
+          ----------
+
+        the compiler executes the equivalent of these __INIT() functions:
+
+        #pragma share_variables:
+
+            unknown __INIT()
+            {
+                "a"::__INIT();
+                if (clonep(this_object()))
+                {
+                    a = (blueprint of this_object())->a;
+                }
+                else
+                {
+                    a = 4;
+                }
+                return 1;
+            }
+
+
+        #pragma init_variables:
+
+            unknown __INIT()
+            {
+                "a"::__INIT();
+                a = 4;
+                return 1;
+            }
+
+
+        In either case the variable 'b' (in fact all variables) are
+        set to '0' as part of the loading/cloning process before the
+        driver performs the specific initialisation.
+
+WARNING
+        Do not call __INIT() yourself, overload, or use it directly in
+        any other way. The implementation of the variable
+        initialization may change at any time.
+
+HISTORY
+        Before LDMud 3.3.378, the choice between sharing and initializing
+          variables was a fixed configuration choice of the driver.
+
+SEE ALSO
+        pragma(LPC), create(H), invocation(D)
diff --git a/doc/LPC/inline-closures b/doc/LPC/inline-closures
new file mode 100644
index 0000000..3a2ecdd
--- /dev/null
+++ b/doc/LPC/inline-closures
@@ -0,0 +1,131 @@
+CONCEPT
+        inline closures
+
+SYNTAX
+        function <returntype> ( <arguments> ) : <context> { <code> }
+
+        (: <statements> ; <expr>, ... , <expr> :)
+
+
+DESCRIPTION
+        Inline closures are a way to program closures which are
+        compiled at the time an object is loaded, but can access
+        values from their enclosing function at runtime.
+
+        Example:
+
+          closure factory (int arg) {
+            return function int (int val) { return val * arg; };
+          }
+
+          closure f1 = factory(2);
+          closure f2 = factory(3);
+          funcall(f1, 3) -> will yield 6.
+          funcall(f2, 3) -> will yield 9.
+
+        The closure here 'inherits' the current value of the local
+        variable 'arg' at the time the closure is created. These
+        values are called the "context" of the closures - they are
+        stored in a special set of variables in the closure.
+
+        One specific feature of the closure context is that it can be
+        changed from within the closure, and that these changes remain
+        permanent:
+
+          closure factory (int arg) {
+            return function int (int val) { return val * arg++; };
+          }
+
+          closure f = factory(2);
+          funcall(f, 3) -> will yield 6.
+          funcall(f, 3) -> will now yield 9!
+
+        But changes of the closure context will not reflect on the
+        local variable it was copied from and vice versa.
+
+        In addition to the implicite context inherited from the
+        defining function, additional context variables can be defined
+        in the closure:
+
+          closure factory (int arg) {
+            return function int (int val) : int x = 2 * arg
+                                          { return val * x; };
+          }
+
+          closure f = factory(2);
+          funcall(f, 3) -> will yield 12.
+
+        It is possible to define multiple context variables with and
+        without initialisation:
+
+          closure factory (int arg) {
+            return function int (int val) : int y, x = 2 * arg;
+                                            int z
+                                          { return val * x; };
+          }
+
+        These explicite context variables are useful when the closures
+        needs to keep a state, or to improve performance:
+
+          mapping m = ...;
+          closure slow (int arg) {
+            return function mixed () { return m[arg]; }
+          }
+          closure fast (int arg) {
+            return function mixed () : mixed val = m[arg] { return val; }
+          }
+
+        In the above example, the fast() function executes the lookup
+        m[arg] only once when the inline closure is created; the
+        slow() function on the other hand returns a closures which
+        looks up m[arg] every time it is called. A second effect is
+        that the results of the slow closure change when m changes;
+        the result of the fast closure is always the same.
+
+
+        In the definition of an inline closure, some elements are
+        optional:
+
+          <returntype>     defaults to 'mixed'
+          ( <arguments> )  defaults to '(mixed $1 ...  mixed $9)'
+          : <context>      no default
+
+
+        The special (: :) form is meant for simple expressions (and
+        MudOS compatibility). The form
+
+          (: <statements> ; <expr>, ..., <expr> :)
+
+        is the shorthand notation for
+
+          function { <statements>; return <expr>, ..., <expr>; }
+
+        For example the two statements
+
+          sort_array(arr, function { return $1 < $2; } )
+          sort_array(arr, (: $1 < $2 :) )
+
+        do the same. The example also demonstrates that both the <statements>
+        and the <expr> part in this form are optional.
+
+
+
+NOTES
+        The macro __LPC_INLINE_CLOSURES__ is defined when the
+        inline closures as described here are available. If not
+        defined, the driver implements a more restricted version
+        ('(: :)' syntax only, no context variables) for backwards
+        compatibility.
+
+        Inline closures are not to be confused with inline functions
+        known from other languages.
+
+HISTORY
+        LDMud 3.2.7 implemented the older, restricted form of inline
+        closures.
+        LDMud 3.3.271 implemented the full form of inline closures.
+        LDMud 3.3.275 re-allowed statements in the (: :) form.
+
+SEE ALSO
+        closures-abstract(LPC), closures-example(LPC), closure_guide(LPC)
+        closures(LPC)
diff --git a/doc/LPC/integers b/doc/LPC/integers
new file mode 100644
index 0000000..edbd848
--- /dev/null
+++ b/doc/LPC/integers
@@ -0,0 +1,40 @@
+NAME
+        integers
+
+DESCRIPTION
+        int is the fastest data type in LPC.
+
+        An integer contains a whole number between
+        -2147483648 and 2147483647.
+
+        Operations with integers:
+          +  plus               &   AND    << SHIFT right
+          -  minus              |   OR     >> SHIFT left
+          *  multiply           ^   XOR
+          /  divide (whole)     ~   NOT    =  Assign value
+          %  divide (modulo)    +=  add    -= subtract        
+
+        The result of a boolean expression is also an integer:
+          0 (false)
+          1 (true)
+
+        Boolean operators are:
+          !  (not)
+          == (equal)
+          || (or)
+          && (and)
+
+FUNCTIONS
+        int to_int(string)
+        int to_int(float)
+        int sscanf(string str, string fmt, mixed var1, mixed var2, ...)
+        void printf(string format, ...)
+
+REMARKS
+        Single characters in strings are also integers.
+
+SEE ALSO
+        arrays, mappings, operators, strings, types
+
+LAST CHANGED
+        Wednesday, 7th May, 2003, by Amaryllis
diff --git a/doc/LPC/lfuns b/doc/LPC/lfuns
new file mode 100644
index 0000000..a9c559d
--- /dev/null
+++ b/doc/LPC/lfuns
@@ -0,0 +1,31 @@
+CONCEPT
+        lfuns
+
+DESCRIPTION
+        A lfun is a LPC function within an object which is public and can
+        be called by other objects. In OO terms, lfuns are "methods"
+        which you can send "messages" to.
+
+        Calling lfuns is done by using the efun call_other(), which
+        takes as arguments the object in which the lfun is to be called,
+        the name of the lfun to be called in the object, and additional
+        and optional arguments.
+
+        An example looks like this:
+
+        call_other(drink, "QueryShort");
+
+        This call may also be written as
+
+        drink->QueryShort();
+
+        This means call_other(object, "function", args...) can also be
+        written as object->function(args...). The second form is
+        preferred as it is easier to read.
+
+        Some lfuns have a special meaning for the LPC driver, because
+        they are applied by the interpreter instead from an LPC object.
+        To distinguish those, they are called ``applied lfuns''.
+
+SEE ALSO
+        efuns(LPC), efun(E), applied(A), master(M), call_other(E)
diff --git a/doc/LPC/lpc b/doc/LPC/lpc
new file mode 100644
index 0000000..c03df0f
--- /dev/null
+++ b/doc/LPC/lpc
@@ -0,0 +1,9 @@
+NAME
+        lpc
+
+DESCRIPTION
+        This directory contains man pages about various aspects of the
+        LPC language as it is provided by Amylaars parser/driver.
+
+SEE ALSO
+        concepts(C), driver(D), efun(E), applied(A), master(M)
diff --git a/doc/LPC/mappings b/doc/LPC/mappings
new file mode 100644
index 0000000..381e3c8
--- /dev/null
+++ b/doc/LPC/mappings
@@ -0,0 +1,474 @@
+CONCEPT
+        mappings
+
+LAST UPDATE
+        Mon, 15 Mar 1999
+
+DESCRIPTION
+
+  A step-by-step introduction to mappings:
+  ----------------------------------------
+
+  1. What is a mapping?
+
+    A mapping is a datatype which allows to store data associated to a key.
+  In other languages  they are also  known  as 'dictionaries' or  'alists'.
+  There are also alists in LPC but they are not a separate datatype but are
+  implemented on  top of arrays.  Alists are  the predecessors of mappings.
+  The keys and the values  can be of  any type.  But most common  datatypes
+  for keys are strings, integers and objects.  Others like arrays, mappings
+  or closures aren't a good choice because comparision between i.e.  arrays
+  often returns false  even if they equal  in content.  This is because the
+  driver compares i.e. two arrays by their internal pointers and not by
+  their content. The reason for this is simple: speed.
+
+    Mappings  are allways  treated  as references    when passing  them  to
+  functions. This means when you pass a mapping  to another object and this
+  object modifies the mapping the modification will  take place in a global
+  scope - visible to all objects holding this mapping in a variable.
+
+
+  2. What are mappings good for?
+
+    The term 'dictionary'  probably describes the  use  of a mapping  best.
+  Opposed  to arrays mappings don't have  a specific  order. They provide a
+  mechanism to   create  a set  of associations  between  values.  Such  an
+  association consists of a unique  key and data  that is identified by the
+  key. Think of  a dictionary  where you have  a  word and a definition  of
+  it. You use the word to lookup its definition.
+
+    Mappings can be used i.e.  to hold  aliases for commands. The key would
+  then be the  name of  the alias and  the  data the command(s) behind   an
+  alias.  Or they can be used for  the exits of a  room.  The keys would be
+  the directions where one can go  to and the associated  data would be the
+  file names of the  rooms.  But mappings can  also be used  as a kind of a
+  sparse array.   A  sparse array is  an  array where most of  the elements
+  aren't used  (occupied by 0).  I.e.  if  you want to  store values at the
+  position 0, 13  and 37642 of an  array you would  have to create an array
+  with a size of at least 37643.  This  costs a lot  of memory so a mapping
+  would be  more useful because you would  then use the  numbers 0,  13 and
+  37642 as a key and not as an index to a position  (actually the keys of a
+  mapping are sometimes  called indices  but this  is just  because the way
+  data is accessed in a mapping is similar to  arrays: by the [] operator).
+  This also allows to  query all occupied   positions of a sparse array  by
+  querying for all  the keys of  the mapping opposed  to an array where you
+  have to iterate over all elements.
+
+
+  3. How do I create a mapping?
+
+    There are several ways to do so. The most convenient is the following:
+
+      mapping map;
+      map = ([ key0: value00; ...; value0n,
+               ... : ...    ; ...; ...    ,
+               keyn: valuen0; ...; valuenn ]);
+
+    As you can see, a key may  have more than  one value assigned.  But the
+  amount of values per key must always be equal.  It  is  even  possible to
+  have mappings without any values!
+    Another  method is  to use the   efun mkmapping().  This  efun gets two
+  arguments with the first beeing an array of keys and the following beeing
+  arrays of values:
+
+      mapping map;
+      map = mkmapping (({ key0   , ..., keyn    }),
+                       ({ value00, ..., value0n }),
+                       ({ ...    , ..., ...     }),
+                       ({ valuen0, ..., valuenn }));
+
+    If the efun only gets one argument, then this argument will be taken as
+  an array of keys and a mapping  without values will  be returned.
+
+    An empty mapping can be created by using the above described methods by
+  simply ommitting the keys and values:
+
+      mapping map;
+      map = ([]);
+  or:
+      map = mkmapping(({}), ({}));
+
+    Or  by  using the efun   m_allocate().  This efun gets  as  first
+  argument the  amount  of keys which will  be  added soon and  an optional
+  second argument specifying the width of the mapping:
+
+      map = m_allocate(n, width);
+
+    The value <n>  may be a bit  confusing  since mappings shrink and  grow
+  dynamically. This value just tells the driver how 'long' this  mapping is
+  going to be  so proper memory  allocations  will be  performed to  reduce
+  the overhead of memory reallocation.  I.e.  if you want to read in a file
+  and store the  read data in  a mapping  you probably  know  the amount of
+  keys.  So you allocate  a mapping with this  efun and tell the driver how
+  much memory should  be allocated  by specifing  a proper <n>  value.
+  Thus causing  a    speedup when adding  the  read   data to the   mapping
+  afterwards.    The <width> just specifies how   many  values per key this
+  mapping is   going to have. If  no  width is given, 1  will  be  taken as
+  default.
+
+  An empty mapping created with '([])' will always have a width of 1. To
+  create empty mappings with other widths, write it as
+
+      map = ([:width ]);
+
+  <width> can be any expression returning an integer value (including
+  function calls), and in fact this notation is just a fancy way of
+  writing
+
+      map = m_allocate(0, width);
+
+
+
+  4. How can I modify the data of a mapping?
+
+    Adding a  new key is similiar to   modifying the associated  data of an
+  existing key:
+
+      map += ([ key: value0; ...; valuen ]);
+
+    Or in case only a single value should be modified:
+
+      map[key, n] = valuen;
+
+    If  <n> is out of  range or if <key> doesn't  exists and <n> is greater
+  than 0 an "Illegal index" error will be reported. If <n> is equal to 0 or
+  the mapping only has a single value per key one can abbreviate it with:
+
+      map[key] = value;
+
+    If there is no <key> (and <n> is equal to 0 or  not specified at all) a
+  new one will be added automatically.
+
+    Deletion   of a key    is  done with    the  -=  operator or  the  efun
+  m_delete(). A mapping can only be substracted by one without any values:
+
+      map -= ([ key ]);
+  or:
+      map -= ([ key0, ..., keyn ]);
+
+  The efun takes a mapping as first and a key as second argument:
+
+      m_delete(map, key);
+
+    The  efun   m_delete() returns  the mapping   but because  mappings are
+  handled as references there is no need of an assignment like:
+
+      map = m_delete(map, key);
+
+
+  5. How can I access the data stored in a mapping?
+
+    This can be done by:
+
+      valuen = map[key, n];
+
+    Or in case of a mapping with just one value per key:
+
+      value0 = map[key];
+
+    If there is no  <key> in the mapping  and <n> is  0 or not specified at
+  all (which is the same) a 0 will be returned or if <n>  is greater than 0
+  an "Illegal index" error will be reported.
+
+
+  6. How can I test for the existance of a key?
+
+    A  return value of 0 is  sufficient for most applications but sometimes
+  the ambiguity  between an existing value of  0 and  a nonexisting key can
+  lead   to  a  problem.  Therefore   one  can use   the  efun member()  or
+  mapping_contains() to check if there actually is a key in the mapping:
+
+      if (member(map, key)) {
+        ...
+      }
+  or:
+      if (mapping_contains(&value0, ..., &valuen, map, key)) {
+        ...
+      }
+
+    This also shows how  one can retrieve all values   associated to a  key
+  from a mapping in a single step. The '&' is  the reference operator which
+  is neccesary to let the efun store the values in the variables.
+
+    In case   of  mappings   with   no  values,   the  efun   member()  and
+  mapping_contains() are equal in their behaviour  and their way of calling
+  because mapping_contains() won't get any reference variables to store the
+  values in (obviously, because there aren't any).
+
+     Also normally member() is known to return the postion of an element in
+  a list (i.e.  a  character in a  string or data   in an array) and if  an
+  element couldn't be  found -1 is returned.   But in the case  of mappings
+  there are no such things as order and postion. So member() only returns 0
+  or 1.
+
+
+  7. How can I copy a mapping?
+
+    A  mapping can  be  copied   with  the  +  operator   or by the    efun
+  copy_mapping():
+
+      newmap = ([]) + map;
+  or:
+      newmap = copy_mapping(map);
+
+    A mapping should only be copied when it is neccesary to get an own copy
+  of it that  must not be  shared by other objects.
+
+
+  8. How can I get all keys of a mapping?
+
+    The  efun m_indices() gets a mapping  as argument  and returns an array
+  holding all keys defined in this mapping:
+
+      keys = m_indices(map);
+
+
+  9. How can I get all the values of a mapping?
+
+    The efun m_values() gets  a mapping as  argument  and returns  an array
+  holding all the first (second, ...) values of it.
+
+      values0 = m_values(map);     returns the first values
+      values0 = m_values(map, 0);  dito
+      values1 = m_values(map, 1);  returns the second values
+        etc
+
+
+  10. How can I determine the size of a mapping?
+
+    Because a mapping is a kind of rectangle it has two sizes: a length and
+  a width.  There are three different efuns  to query these values. The first
+  two are the  efuns sizeof(), which returns the  amount of key-value
+  associations (the length of  a mapping), and widthof(), which returns the
+  number of values per key (the width). The third is the efun get_type_info().
+  get_type_info() is meant  to be a function  to identify a datatype.   Its
+  return value is an  array of two  numerical values.  The first  specifies
+  the datatype   of the argument and   the second is a   datatype dependend
+  value. In the case of a mapping the first value  is T_MAPPING (which is a
+  value defined in  <lpctypes.h>) and the  second the amount of values  per
+  key (a.k.a.  columns or the width  of the mapping  - actually it would be
+  correct to say that the width of a mapping is the  amount of columns plus
+  one for the keys but this is uncommon).
+
+
+  11. What is the best method to iterate over a mapping?
+
+    First of all the main purpose of a mapping is not meant to  be a set of
+  data to iterate over. Afterall the keys in a mapping have no specific but
+  a random order (at least on the LPC side).  But  still it is possible and
+  sometimes even neccesary to do so.
+
+    If all key-value associations  should be processed  then one should use
+  walk_mapping().  If all keys of a mapping should be processed to create a
+  new mapping being a subset of the given one, then filter_mapping() should
+  be  used.  If all  keys  are going to  be  processed and  to create a new
+  mapping with the  same set of keys as  the given mapping, then one  would
+  use map_mapping().  But in the case of an  iteration that should/can stop
+  even if not all data is processed it is probably wise to iterate over the
+  mapping by first querying for the keys and then to iterate over them with
+  a for() or a while() loop and querying the values by 'hand'.
+
+    The efun walk_mapping() gets  a mapping as  first argument and the name
+  of a function  as second one. All the  following arguments are treated as
+  extras which  will  be  passed to the   function specified  with the  2nd
+  argument. Instead of a string for the name of a function a closure can be
+  used, too. Nothing will be returned:
+
+      ...
+      walk_mapping(map, "func", xarg0, ..., xargn);
+      ...
+
+      void func(mixed key, mixed value0, ..., mixed valuen,
+                mixed xarg0, ..., mixed xargn) {
+        ...
+      }
+
+    func() will be called for all key-value associations  and gets as first
+  argument the key.  The next arguments are the  values behind the key  and
+  are passed as references.  The  rest  of the  passed arguments are  those
+  specified as extras. Because the values are passed as references (opposed
+  to  copies) it is possible  to modify them  from  inside func() by simply
+  assigning new value to the variables <value0>, ..., <valuen>.
+
+    The efun filter_mapping() calls  a function for  each key in  a mapping
+  and creates a new mapping  which only contains key-value associations for
+  which the called function returned true (not  equal 0 that is). The first
+  argument is the mapping to iterate over and the second is a function name
+  given as a string or a closure:
+
+      ...
+      submap = filter_mapping(map, "func", xarg0, ..., xargn);
+      ...
+
+      int func(mixed key, mixed xarg0, ..., mixed xargn) {
+        ...
+      }
+
+    func() gets  as first argument the key  and the others are those passed
+  as extras to filter_mapping().
+
+    The efun map_mapping() gets a mapping as first argument and a string as
+  a function name (or again a closure) as  second argument.  Any additional
+  arguments are again used  as extras that will  be passed to the iteration
+  function. This efun returns a new mapping with the same keys as the given
+  one.  The values  returned by the function  that is invoked  for each key
+  will be used as the associated data behind each key of the new mapping:
+
+      ...
+      newmap = map_mapping(map, "func", xarg0, ..., xargn);
+      ...
+
+      mixed func(mixed key, mixed xarg0, ..., mixed xargn) {
+        ...
+      }
+
+    func() gets  as first argument the key  and the others are those passed
+  as extras to map_mapping().
+
+    Because a function can only return  a single value  (even when it is an
+  array) it restricts the use  of map_mapping() to  only allow creation  of
+  mappings with a single value per key.
+
+
+  12. Is it possible to join/intersect/cut mappings with another?
+
+    Joining mappings is only possible, if  they have the same width (amount
+  of values per key). One can use the + and += operator:
+
+      map = map1 + map2 + ... + mapn;
+      map += map1 + map2 + ... + mapn;
+
+    Intersection     of   two   mappings is    only      possible by  using
+  filter_mapping(). There is  no efun or operator  which features this. The
+  'easiest' way may be the following function:
+
+      mapping intersect_mapping(mapping map1, mapping map2) {
+        closure cl;
+
+        cl = lambda(({ 'key }), ({ #'member, map2, 'key }));
+        return filter_mapping(map1, cl, map2);
+      }
+
+    This function returns a  new mapping which   consists of all  key-value
+  associations   of  <map1>  for which  an  equal  key  could   be found in
+  <map2>. This function uses  a closure which returns 0  or 1  depending on
+  wether a key from <map1> is contained in <map2> or not.
+
+    Cutting out  all key-value associations of a   mapping for which  a key
+  could be  found in another mapping  can  be done  by using  the  - and -=
+  operator:
+
+      mapping cut_mapping(mapping map1, mapping map2) {
+        return map1 - mkmapping(m_indices(map2));
+      }
+
+    Because a maping can  only be substracted by one  without any values we
+  first have to create such by using m_indices() and mkmapping().
+
+
+  13. What are those mappings without any values (besides keys) good for?
+
+    Because the way how the driver  searches for a  key in a mapping is
+  rather fast, those mappings can be used as a  set of elements with a fast
+  method for testing if an element is  contained in the set. This technique
+  is called hashing (further  explanation   would lead  too far)  which  is
+  faster  than searching for  values  in array  (which  is done in a linear
+  fashion).
+
+    Another (maybe  more pratical) use  of these  mappings  are to create a
+  array of unique values out of an array with several equal values:
+
+      uniques = m_indices(mkmapping(array));
+
+    mkmapping() uses  <array> to  create  a mapping without any  values but
+  just keys. And  because a mapping can only  have unique keys all multiple
+  values in <array> are taken as one.  The call of m_indices() then returns
+  an  array  of  these  unique keys.  Actually we  only  make  use of those
+  mappings temporarily.
+
+
+  14. How can I convert an alist into a  mapping and vice versa?
+
+    There are no special efuns which handle such conversions. But it can be
+  done by the following functions:
+
+      mapping alist_to_mapping(mixed *alist) {
+        return apply(#'mkmapping, alist);
+      }
+
+    The efun apply() takes a closure and an array of values and passes each
+  element of the  array as an  argument  to the  closure. Because  an alist
+  consists of an array of arrays with the first beeing the list of keys and
+  the others the values associated to each key passing them as arguments to
+  the efun closure #'mkmapping via apply() causes the creation of a mapping
+  out of an alist.
+
+      mixed *mapping_to_alist(mapping map) {
+        mixed *alist;
+        symbol *vars;
+        string var;
+        closure cl;
+        int width;
+
+        width = get_type_info(map)[1];
+        alist = allocate(width + 1);
+        vars  = allocate(width + 2);
+        for (var = "a"; width; var[0]++, width--) {
+          alist[width] = ({});
+          vars[width]  = quote(var);
+        }
+        alist[0] = ({});
+        vars[0]  = 'key;
+        vars[<1] = 'alist;
+        cl = lambda(vars, ({ #'=, 'alist, ({ #'insert_alist }) + vars }));
+        walk_mapping(map, cl, &alist);
+        return alist;
+      }
+
+    This function is  a bit more  complicated  than the other  and detailed
+  description would lead   too far of   the topic.  This  function has  one
+  restriction:  it can only turn a  mappings with up to  26  values per key
+  into an  alist.    But  this  should  be   sufficient for probably    all
+  applications which use mappings.
+
+  And Hyps further comment on this:
+        The function mapping_to_alist() is also not that
+        clever because insert_alist() allways creates a new
+        alist.  A second (optional) argument to m_values() to
+        specify the value column would be better. Besides
+        this, the conversion of a mapping into an alist could
+        be done by to_array().
+
+  15. Dirty Mappings
+
+  'Dirty mappings' are nothing the LPC programmer directly is involved
+  with, however, as it relates to the way mappings are implemented
+  internally by the gamedriver. However, as this term shows up in
+  various driver statistics, it is explained here.
+
+  There are two fundamental approaches to implement mappings:
+
+    1. Store all data entries in an array-like structure, in sorted order. 
+    2. Store all data in a hashtable, each entry allocaed separately.
+
+  Method 1 is very space efficient, as it doesn't need much overhead
+  per entry; however, insertions and deletions of entries are
+  relatively slow as all other entries need to be moved.     
+  Method 2 is very fast as nothing needs to be moved in memory,
+  however it has a large overhead.
+
+  The gamedriver uses a hybrid method: at the basis is a mapping
+  implementation based on arrays. However the driver uses a hash table
+  in addition to handle all the ongoing insertions and deletions.
+  Every once in a while, the contents of the hash table are sorted
+  into the base array, reasoning that any entry surviving for longer
+  time in the hash table is worth keeping in a more space-efficient
+  manner. 'Dirty' mappings are such mappings with both an array and a
+  hash part, 'clean' mappings are those with just an array part.
+
+HISTORY
+        The ([:width ]) notation was added in LDMud 3.2.9/3.3.208 .
+
+SEE ALSO
+        alists(LPC), closures(LPC), structs(LPC), mkmapping(E),
+        walk_mapping(E)
diff --git a/doc/LPC/modifiers b/doc/LPC/modifiers
new file mode 100644
index 0000000..a30904e
--- /dev/null
+++ b/doc/LPC/modifiers
@@ -0,0 +1,182 @@
+CONCEPT
+        modifiers
+
+DESCRIPTION
+        A modifier changes the syntactic and/or semantic behaviour of
+        an object-global variable or a function in an object.
+        The existing modifiers are described below.
+        To use a modifier just prepend it to the declaration. If several
+        modifiers are to be used their order does not matter:
+
+        private int bar;                         // example for a variable
+        protected nomask int foo() { return 3; } // example for a function
+
+        For functions:
+        ~~~~~~~~~~~~~~
+        private   -- such functions can only be called with an internal
+                     call from within this file. Not even inheriting
+                     objects can call these functions. You can nevertheless
+                     build an lfun-closure with #' out of a private function
+                     (but you cannot save and restore it).
+        protected -- such functions can be called from within the object,
+                     or from inheriting objects; but in neither case
+                     with call_other(). It is possible to create #' closures
+                     or use symbol_function() from within the object.
+                     Its use is preferred over the older "static".
+        static    -- such functions can be called from within the object
+                     in either way (internal call or with call_other()).
+                     Inheriting objects can call such functions.
+                     But it is not possible to call static functions from
+                     other objects via call_other().
+                     The use of 'static' in new code is not recommended.
+                     Note that an add_action() is treated like a call
+                     from within the object except the player who got the
+                     add_action() was forced (thus it is a simple way to
+                     secure an add_action() against forces, although this
+                     method has the severe disadvantages of raising an error
+                     at the force so better use the security system).
+                     Also efuns like call_out() or input_to() can call
+                     these functions if given as a string.
+        public    -- this is the default type. Such functions can be called
+                     from within the file as well as from inheriting objects
+                     and other objects via call_other().
+                     To declare a function public only results in the
+                     impossibility to change the accessibility at the
+                     inherit statement (see below). No error will occur,
+                     only the type will not be modified by the inherit
+                     statement.
+        nomask    -- such functions cannot be overridden by inheriting
+                     objects. If you have the fun foo() defined in your
+                     object and inherit an object which also has declared
+                     a function foo() and this nomask, you will get an
+                     compile error if you try to load your object.
+                     Furthermore a shadow will fail if it tries to shadow
+                     a nomask declared function.
+        varargs   -- this changes the syntax of the function in a way that
+                     not all of the arguments in the declaration must be
+                     given at the call. This is often very usefull if some
+                     of the arguments shall be omitable (the omitted
+                     arguments are set to 0 if the function is called with
+                     fewer arguments than specified).
+                     This is mainly within the object really necessary;
+                     call_other()s usually (that is if they do not have a
+                     certain pragma ('man pragma')) do not need the called
+                     function to be declared varargs to omit any arguments,
+                     but it is good style to use this modifier to document
+                     the code by this.
+        deprecated - Whenever this function is called, a warning is issued.
+                     Usually this is done at compile-time. Exceptions are
+                     call_others and symbol_function() which warn at run-time.
+
+        For object-global variables:
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+        private   -- such variables can only be accessed from within the
+                     same object. Not even inheriting objects can access
+                     private variables.
+                     It is a good style to declare all internal variables
+                     private to prevent inheriting objects from accessing
+                     the variables directly without using functions.
+        nosave    -- such variables are neither stored with save_object()
+                     nor restored with restore_object(). This can be very
+                     useful if you want a room to use save_object() and
+                     restore_object() to save your own defined variables
+                     but not the hundreds of variables inherited from a
+                     room-class (e.g. /complex/room). You then use the modifier
+                     at the inherit statement (see below).
+                     Note that nosave and private do not overlap in any
+                     way. They are absolutely independant.
+        static    -- the old name for 'nosave'. Its use is deprecated.
+        public    -- declares the variable public. It cannot be declared
+                     private or static by inheriting. No error will occur,
+                     only the type will not be modified by the inherit
+                     statement.
+        deprecated - Whenever this variable is used, a warning is issue.
+                     Usually this is done at compile-time, but
+                     symbol_variable() warns at run-time.
+
+        It is no good style to let inheriting objects have access to
+        internal variables so declare them as private and offer functions
+        to query and change the variables if possible.
+
+        It is also possible to redeclare all variables and/or functions
+        of an inherited object for the own object at the inheriting
+        statement:
+
+        private functions nosave variables inherit "complex/room";
+        public variables inherit "complex/room";
+        private functions inherit "complex/room";
+
+        To redeclare a function or a variable declared public in the
+        inherited object to be private or protected is not possible.
+
+        There also exists a modifier explicitly for the inherit statement:
+
+        virtual   -- inherits the given object virtually. This only makes
+                     sense in a complex inherit tree.
+                     If an object is inherited normally (not virtually)
+                     twice somewhere in the inherit tree the intern
+                     variables exist twice. If inherited virtually they
+                     exist only once.
+                     Example:
+                     A inherits B and C.
+                     B inherits D.
+                     C inherits D.
+                     If the inheritance of D is virtual in B and C
+                     D's variables exist only once in A. If A changes
+                     D's variables via functions of B this also changes
+                     the variables of D as known by C.
+
+                     virtual:               non-virtual:
+                        A                        A
+                       / \                      / \
+                      B   C                    B   C
+                       \ /                     |   |
+                        D                      D   D
+
+
+        To simplify the adoption of existing code, LPC allows to specify
+        a default visibility for functions and variables, using a syntax
+        similar to the inherit syntax:
+
+          default private;
+
+            All variables and functions are by default private.
+
+          default private variables public functions;
+
+            All variables are by default private, but functions are public.
+
+        Only the modifiers 'private', 'public' and 'protected' (and 'static'
+        for functions only) are allowed here.
+
+        The default visibility thus set affects only variables/functions with
+        no explicite visibility:
+
+          default private;
+
+          int private_var;
+          public int public_var;
+
+        The definition is valid from the point of the 'default' statement
+        until the end of the file, or until the next 'default' statement:
+
+          default private;
+
+          int private_var;
+
+          default public;
+
+          int public_var;
+
+        Note that this default visibility does not affect inherits.
+
+
+HISTORY
+        The modifier 'static' for variables was renamed to 'nosave'
+        with LDMud 3.2.8. 'static' is still recognized as an alias.
+
+        The default visibility was added in LDMud 3.2.9 as experimental
+        feature.
+
+SEE ALSO
+            closures(LPC), inheritance(LPC), functions(LPC), types(LPC)
diff --git a/doc/LPC/operators b/doc/LPC/operators
new file mode 100644
index 0000000..18406a3
--- /dev/null
+++ b/doc/LPC/operators
@@ -0,0 +1,213 @@
+NAME
+        operators
+
+DESCRIPTION
+
+        These are the operators availailable in LPC. They are listed
+        in the order of precedence (low priority first):
+
+
+        expr1 , expr2        Evaluate 'expr1' and then 'expr2'. The
+                        returned value is the result of 'expr2'. The
+                        returned value of 'expr1' is thrown away.
+
+        var = expr        Evaluate 'expr', and assign the value to
+                        'var'. The new value of 'var' is the result.
+
+        var += expr        Assign the value of 'expr' + 'var' to 'var'.
+                        This is mostly equivalent to "var = var + expr".
+
+        var -= expr        Similar to '+=' above.
+        var &= expr
+        var |= expr
+        var ^= expr
+        var <<= expr
+        var >>= expr
+        var >>>= expr
+        var *= expr
+        var %= expr
+        var /= expr
+        var &&= expr
+        var ||= expr
+
+        expr1 ? expr2 : expr3
+                        Evaluates 'expr1' and branches according to
+                        its truth value. If it is true, the 'expr2' is
+                        evaluated and returned as result, else
+                        'expr3'.
+
+        expr1 || expr2        The result is true if 'expr1' or 'expr2' is
+                        true. 'expr2' is not evaluated if 'expr1' was
+                        true.
+
+        expr1 && expr2        The result is true i 'expr1' and 'expr2' is
+                        true. 'expr2' is not evaluated if 'expr1' was
+                        false.
+
+        expr1 | expr2        The result is the bitwise or of 'expr1' and
+                        'expr2'.
+                        For arrays, the union set is computed: all elements
+                        from <expr1> plus all those from <expr2> which
+                        are not in <expr1>.
+
+        expr1 ^ expr2        The result is the bitwise xor of 'expr1' and
+                        'expr2'.
+                        For arrays, the symmetric difference is computed:
+                        all elements from <expr1> which are not in <expr2>,
+                        plus all those from <expr2> which are not in <expr1>.
+
+        expr1 & expr2        The result is the bitwise and of 'expr1' and
+                        'expr2'.
+
+                        For arrays and strings, the intersection set
+                        (all elements resp. characters from expr1 which
+                        which are also in the expr2) is computed.
+                        Note: "aab" & "a" -> "aa"
+                         but  ({ 'a','a','b' }) & ({ 'a' }) -> ({ 'a' })
+                        Eventually the array behaviour will be changed
+                        to match the string behaviour.
+
+                        Intersecting an array with a mapping is equivalent
+                        to intersecting the array with the indices of the
+                        mapping: array & mapping = array & m_indices(mapping)
+
+                        Mappings can be intersected with another mapping
+                        or an array. The resulting mapping holds all
+                        those entries from the first mapping, which are
+                        also mentioned in the second mapping (as index)
+                        resp. in the array.
+
+        expr1 == expr2        Compare values. Valid for strings, numbers,
+                              objects and closures.
+
+        expr1 != expr1        Compare values. Valid for strings, numbers,
+                              objects and closures.
+
+        expr1 > expr2        Valid for strings and numbers.
+
+        expr1 >= expr2        Valid for strings and numbers.
+
+        expr1 < expr2        Valid for strings and numbers.
+
+        expr1 <= expr2        Valid for strings and numbers.
+
+        expr1 << expr2        Shift 'expr1' left by 'expr2' bits; the sign
+                              bit is not preserved.
+
+        expr1 >> expr2        Shift 'expr1' right by 'expr2' bits.
+                        This shift preserves the sign of 'expr1'.
+
+        expr1 >>> expr2        Shift 'expr1' right by 'expr2' bits.
+                        This shift does not preserve the sign of 'expr1',
+                        instead it shifts in 0 bits.
+
+        expr1 + expr2        Add 'expr1' and 'expr2'. If numbers, then
+                        arithmetic addition is used. If one of the
+                        expressions are a string, then that string is
+                        concatenated with the other value.
+                        If the expressions are arrays, the result is
+                        the right array appended to the left.
+                        If the expressions are mappings of equal width,
+                        the result is merger of the two mappings. If one
+                        key exists in both mappings, the element from the
+                        right mapping appears in the result. If the two
+                        mappings are of different width, the result is
+                        <expr1> if non-empty, and <expr2> otherwise.
+
+        expr1 - expr2        Subtract 'expr2' from 'expr1'. Valid for
+                        numbers, strings, arrays, mappings.
+                        For arrays and strings, all occurences of the
+                        elements resp. characters in 'expr2' are removed
+                        from 'expr1', and the result is returned.
+                        For mapping, all occurances of elemens in 'expr1'
+                        which have a matching key in 'expr2' are removed, and
+                        the result is returned.
+
+        expr1 * expr2        Multiply 'expr1' with 'expr2'.
+                        If strings or arrays are multiplied with a number
+                        (zero or positive), the result is a repetition of the
+                        original string or array.
+
+        expr1 % expr2        The modulo operator of numeric arguments.
+
+        expr1 / expr2        Integer division.
+
+        ++ var                Increment the value of variable 'var', and
+                        return the new value.
+
+        -- var                Decrement the value of variable 'var', and
+                        return the new value.
+
+        - var                Compute the negative value of 'var'.
+
+        ! var                Compute the logical 'not' of an integer.
+
+        ~ var                The boolean 'not' of an integer.
+
+        ( type ) var    Return the value of <var> converted to <type>.
+                        <type> can be 'string', 'int', 'object', 'float'
+                        or 'int*'. <var> must be of a specific type
+                        for a conversion to take place; if <var> is 'mixed'
+                        or unknown, the cast is purely declarative.
+                        Also, if the declared type of <var> is that of <type>,
+                        the value is not changed.
+
+                        NB. The literal number 0 is of unknown type, as
+                        it doubles as 'not initialized' for strings, objects,
+                        and arrays.
+
+                        The operator acts like the efuns
+                        to_string(), to_int(), to_object(), to_float()
+                        and to_array(). It is advisable to use the
+                        efuns directly instead of the cast.
+
+        ({ type }) var  <var> is now assumed to have the type <type>.
+                        This is purely declarative, the actual value
+                        of <var> is not changed.
+
+        var ++                Increment the value of variable 'var', and
+                        return the old value.
+
+        var --                Decrement the value of variable 'var', and
+                        return the old value.
+
+        expr1[expr2]        The array or mapping given by 'expr1' is
+                        indexed by 'expr2'.
+
+        expr1[expr2..expr3] Extracts a
+                        piece from an array or string.
+                        expr2 or expr3 may be omitted, default is the begin
+                        or end of expr1.
+                        Negative numbers for expr2 or expr3
+                        mean ``count from before the beginning'', i.e.
+                        foo[-2..-1] is an empty array or string.
+                        foo[<2..<1] gives the 2nd and last element of
+                        the array resp. chars of the string.
+
+        expr1->name(...) The symbolic form of call_other(). 'expr1'
+                        gives either an object or a string which is
+                        used as the file_name of an object, and calls
+                        the function 'name' in this object.
+
+        ident::name(...)
+                        Call the inherited function 'name' with the
+                        given parameters in the parent 'ident'.
+                        'ident' may be given as string containing the
+                        full pathname, or as identifier containing the
+                        pure basename.
+                        If 'ident' is omitted, the last inherited
+                        function of this 'name' is called.
+
+        ({ })                Array constructor.
+        ([ ])                Mapping constructor.
+
+NOTE
+        The closure operators are not described here.
+
+HISTORY
+        LDMud 3.2.9 added '>>>', '>>>=', '&&=' and '||='.
+        LDMud 3.2.10 extended '&' to mappings.
+        LDMud 3.3 extended '|' and '^' to arrays.
+
+SEE ALSO
+        arrays(LPC), alists(LPC), mappings(LPC), closures(LPC)
diff --git a/doc/LPC/pragma b/doc/LPC/pragma
new file mode 100644
index 0000000..d26f326
--- /dev/null
+++ b/doc/LPC/pragma
@@ -0,0 +1,116 @@
+NAME
+        pragma
+
+DESCRIPTION
+        The preprocessor directive #pragma can be used to select
+        several compilation options. Multiple options can be selected
+        in one #pragma directive by separating them with commas.
+
+        no_clone: The blueprint object can't be cloned.
+        no_inherit: The program can't be inherited.
+        no_shadow: The program can't be shadowed (similar to declaring
+                all functions as 'nomask').
+
+        init_variables: Clone variables are initialized by __INIT().
+        share_variables: Clone variables are initialized from the
+                blueprint.
+
+        weak_types: no type checking (this is the default).
+        strict_types: all functions must be declared with argument
+                prototypes, and the return values of call_other() must
+                be casted.
+        strong_types: all functions must be declared with complete
+                types of return value and parameters.
+        save_types: the declaration data is kept after compilation and
+                checked at runtime. This is important for type-safe
+                inheritance.
+
+        rtt_checks: runtime checks during execution of this program will be
+                enabled. The interpreter will check for correct datatypes of
+                arguments on function calls. (Later it will include checks
+                upon assignments.)
+                Don't confuse this with strong/strict_types, they only
+                check at compile time.
+                strong_types/strict_types is seriously recommended.
+                This pragma implicitly enables save_types as well.
+        no_rtt_checks: disable runtime type checks for this program (default).
+
+        pedantic: Certain warnings are treated as errors:
+                - failure to pass enough arguments to simul efuns
+        sloppy: Turns off pedantic (the default).
+
+        range_check: Use of questionable ranges (ranges of negative sizes,
+                or with bounds beyond the array's size) cause a runtime
+                warning.
+        no_range_check: Turns off range_check (the default).
+
+        warn_deprecated: Use of deprecated efuns or indexing operations
+                causes the compiler to issue a warning (the default).
+        no_warn_deprecated: Turns off warn_deprecated.
+
+        warn_empty_casts: A cast of a value to its own type generates
+                a warning (the default). Exception are casts to type
+                'mixed'.
+        no_warn_empty_casts: Turns off warn_empty_casts.
+
+        warn_missing_return: Warn if a value-returning function is missing
+                a return statement (the default). If possible, the driver
+                will try to detect this at compile time; otherwise a runtime
+                warning will be generated when the function is executed.
+                The check applies only to functions with a declared return
+                type other than 'void'.
+        no_warn_missing_return: Turn off warn_missing_return.
+
+        warn_function_inconsistent: If an inherited function is
+                overloaded with inconsistent return types or arguments,
+                a warning is generated; or if pragma_pedantic is in effect,
+                an error. By default this is active.
+        no_warn_function_inconsistent: An inherited function can
+                be overloaded with inconsistent return types or arguments,
+                as long as pragma_pedantic is not in effect.
+
+                This pragma is meant to easen the adaption of legacy
+                mudlib code - in general one should fix the warnings,
+                not turn them off.
+
+        When an object is compiled with type testing (#pragma
+        strict_types), all types are saved of the arguments for that
+        function during compilation.  If the #pragma save_types is
+        specified, then the types are saved even after compilation, to
+        be used when the object is inherited.
+
+        The following two pragmas are available if the driver was
+        compiled with DEBUG and TRACE_CODE options:
+
+        set_code_window: Sets an offset to the current program writing
+                position. Use this BEFORE a piece of code where you
+                want to check to what bytecodes it is compiled.
+        show_code_window: shows some bytes starting at or near the
+                last point set_code_window was called.
+
+EXAMPLES
+        #pragma strict_types
+        #pragma no_clone, no_inherit
+
+HISTORY
+        LDMud 3.2.7 added local_scopes, no_local_scopes, no_clone
+        and no_inherit.
+        LDMud 3.2.8 added weak_types, pedantic and sloppy.
+        LDMud 3.2.9 allowed to specify multiple pragmas in one directive.
+        LDMud 3.2.9 added (no_)warn_deprecated.
+        LDMud 3.2.10 added (no_)warn_empty_casts.
+        Starting with LDMud 3.2.10, #pragma xxx_types in an included file are
+          no longer valid only until the end of the file, but remain active
+          when processing returns to the including file.
+        LDMud 3.2.11 added (no_)warn_function_inconsistent.
+        LDMud 3.3.378 added init_variables, share_variables.
+        LDMud 3.3.357 added (no_)warn_missing_return.
+        LDMud 3.3.646 added (no_)range_check.
+        LDMud 3.5.0 removed combine_strings and no_combine_strings.
+        LDMud 3.5.0 removed local_scopes and no_local_scopes.
+        LDMud 3.5.0 removed verbose_errors (making its behaviour mandatory).
+        LDMud 3.5.0 enabled warn_deprecated by default.
+
+SEE ALSO
+        inheritance(LPC), initialisation(LPC), objects(C),
+        operators(LPC)
diff --git a/doc/LPC/preprocessor b/doc/LPC/preprocessor
new file mode 100644
index 0000000..61593f0
--- /dev/null
+++ b/doc/LPC/preprocessor
@@ -0,0 +1,23 @@
+NAME
+        preprocessor
+
+DESCRIPTION
+        The LPC driver understands the following preprocessor
+        directives:
+
+        #include, #define, #if, #ifdef, #ifndef, #else, #elif,
+        #endif, #undef
+                same as in ANSI C
+
+        #line <num>
+                line numbers start at <num> with the next line
+
+        #echo
+                the rest of the line is printed to the error output
+                (stderr), thus can be captured into a log file
+
+        #pragma
+                see the separate man page
+
+SEE ALSO
+        pragma(LPC), predefined(D)
diff --git a/doc/LPC/references b/doc/LPC/references
new file mode 100644
index 0000000..c1d60f0
--- /dev/null
+++ b/doc/LPC/references
@@ -0,0 +1,49 @@
+CONCEPT
+        references
+
+DESCRIPTION
+        Call by reference can be used to have a function that passes
+        more than one value to the caller, without using arrays that
+        have to be unpacked thereinafter.
+        There is nothing special to declare in the calling function,
+        you simply do an assignment to a parameter of the function.
+        The caller has to pass references explicitely; this is done by
+        prefixing an lvalue with '&' .
+        To pass a reference to an element of an array, you have to
+        enclose the indexed lvalue in round brackets.
+
+EXAMPLE
+
+        void assign(mixed destination, mixed source) {
+            destination = source;
+        }
+
+        void extract_number(int destination, string source) {
+            sscanf(source, "%d", destination);
+        }
+
+        void test() {
+            int i;
+            float f;
+            mixed *a;
+
+            extract_number(&i, "42 palantirs");
+            assign(&f, 3.141592653589793);
+            assign(&a, ({ i, f }));
+            assign(&(a[<0..<1]), ({1,2,3,"sink","x","y","x"}));
+            assign(&(a[5][0]), 'w');
+            assign(&(a[5][<1]), 'g');
+            printf("%O", a));
+        }
+
+        ({ /* sizeof() == 9 */
+          42,
+          3.14159,
+          1,
+          2,
+          3,
+          "wing",
+          "x",
+          "y",
+          "x"
+        })
diff --git a/doc/LPC/strings b/doc/LPC/strings
new file mode 100644
index 0000000..15820ef
--- /dev/null
+++ b/doc/LPC/strings
@@ -0,0 +1,65 @@
+NAME
+        strings
+
+DESCRIPTION
+        A string is a data type in LPC.
+
+        It consists of several ASCII characters (letters), numbers
+        and special characters. ASCII characters may contain of
+        values between -128 and 127 (e.g. 'A' (65) or '5' (53)), but
+        0 is not allowed (because strings are 'null terminated',
+        which means that marks the end of a string).
+
+        Notations for strings:
+        "abc" + "def" "ghi" + 5 + "jkl" + to_string( ({'m','n'}) )
+        == "abcdefghi5jklmn"
+
+        Special characters must be escaped with a leading '\':
+          \n   (new line)
+          \t   (tabulator)
+          \b   (backspace)
+          ...
+
+        The single characters can be accessed like an array:
+          string s;
+          int i,j;
+
+          s="test";
+
+          s[0]       (ASCII Code (value) of the first character)     ='t'
+          s[<1]      (last character)                                ='t'
+          s[0..0]    (string composed of the first char)             ="t"
+          s[1..<2]   (string from second to character before last)   ="es"
+          s[2..]     (string from third to last character)           ="st"
+          ...
+
+        String manipulations:
+          s[0]=s[0]-32    ("test" -> "Test")
+          s[1..<2]="o"    ("test" -> "tot")
+          ...
+
+FUNCTIONS
+        int strlen(string str)
+        int member(string s, int elem)
+        int strstr (string str, string str2, int pos)
+        int to_int(string)
+        mixed *to_array(string)
+        string to_string(mixed)
+        string upperstring(string str)
+        string lowerstring(string str)
+        string lower_case(string str)
+        string capitalize(string str)
+        string break_string(string str, int width, int space, int leave_lfs)
+        string sprintf(string fmt, ...)
+        int sscanf(string str, string fmt, mixed var1, mixed var2, ...)
+        string *new_explode(string str, string del)
+        string *explode(string str, string del);
+        string implode(mixed *arr, string del)
+        string *regexplode (string text, string pattern)
+        string *regexp(string *list, string pattern)
+
+SEE ALSO
+        arrays, integers, mappings, operators, types
+
+LAST CHANGED
+        12. Mar 2004 Gloinson
diff --git a/doc/LPC/structs b/doc/LPC/structs
new file mode 100644
index 0000000..217b0a6
--- /dev/null
+++ b/doc/LPC/structs
@@ -0,0 +1,227 @@
+CONCEPT
+        structs
+
+INTRODUCTION
+        structs are, next to arrays and mappings, a way to group a
+        collection of value together.
+
+        A struct holds a fixed number of values, called 'members', and
+        allows to access them by their given name. The name is resolved
+        when the LPC code is compiled, making struct member access as fast
+        as array member access.
+
+        structs are passed by reference.
+
+
+DEFINITION
+        A new struct type has to be defined at the top level of an
+        object. For example
+
+            struct Foo {
+              int        one, *two;
+              struct Bar three;
+            };
+
+        defines the new struct 'Foo' with three members: integer 'one',
+        integer array 'two', and struct Bar 'three'
+
+        It is possible to 'inherit' structs from each other. Given above
+        definition of struct Foo, the following definition
+
+            struct Quux (Foo) {
+              int four;
+            };
+
+        is equivalent to the definition
+
+            struct Quux {
+              int        one, *two;
+              struct Bar three;
+              int four;
+            };
+
+
+        The usual visibility modifiers apply, e.g.
+
+            protected struct Bang {...};
+
+
+        struct definitions are promoted through inheritance like functions,
+        with the difference that all structs live in the same flat namespace.
+        This means: a struct defined in a program is visible in _all_
+        inherited programs, regardless of how deep the inheritance is
+        nested.  This also means that in one program there must not be
+        two structs, inherited or not, with the same name.
+
+
+        To declare a struct without defining it, write:
+
+            struct Quux;
+
+        This notation is useful if you have two structs referencing
+        each other:
+
+            struct Quux;
+
+            struct Bar {
+              struct Quux quux;
+            };
+            struct Quux {
+              struct Bar bar;
+            };
+
+
+USAGE
+        To use a struct, its definition must be visible - either because it
+        is defined in the object compiled, or it has been inherited.
+        (Note: #include'ing structs does not what you think it does: in
+        LPC it constructs a new struct type whereever it is included).
+
+
+        A variable to hold a struct is defined like this:
+
+            struct Foo var;
+
+        and similar for function arguments:
+
+            void fun (struct Foo arg)
+
+
+        Just writing 'struct Foo var' however does not _create_ a struct,
+        it just creates a variable capable of holding one. To assign a value
+        to the variable upon creation, assign it with a struct value, either
+        from another variable or from a literal struct:
+
+            struct Foo var = (<Foo>);
+
+
+        Literal structs are written using (<>) as delimiters:
+
+            (<Foo>)
+                creates an empty instance of struct Foo
+
+            (<Foo> 1, ({ 2 }), bar)
+                creates an instance of struct Foo, and assigns 1 to member
+                'one', ({ 2 }) to member 'two', and the content of variable
+                bar to member 'three'.
+
+            (<Foo> two: ({ 2 }) )
+               creates an instance of struct Foo which is all empty except
+               for member 'two' which is assigned the value ({ 2 }).
+
+        It is not possible to use both named and unnamed initializers
+        in the same literal.
+
+
+        A struct member is accessed using the -> operator:
+
+            struct Foo var = ...;
+
+            var->one = 1;
+
+
+        It is possible to compute struct lookups at runtime:
+
+            struct Foo bar = ...;
+            string member = "one";
+
+            bar->(member) = 1; // sets bar->one to 1
+            bar->(0) = 1;      // sets bar->one to 1
+
+
+        When using struct values held in variables/expressions of type
+        'mixed', the 'mixed' value should to be casted to the struct
+        value. The cast can be omitted if the looked-up member exists
+        in only one struct (and its children) known to the compiler:
+
+            struct Foo { int one; };
+            struct Bar { int two; };
+            struct Baz { int two; };
+            mixed var;
+
+                        var->one  // looks up Foo->one
+            (struct Foo)var->one  // looks up Foo->one
+                        var->two  // ERROR: ambiguous lookup
+            (struct Bar)var->one  // looks up Bar->one
+
+
+USAGE IN CLOSURES
+        The #'(< operator can be used in lambda closures to create a
+        struct; the type of the struct is given by the 'template'
+        struct passed as first argument. The content of the template
+        struct is irrelevant, so an empty struct suffices. For
+        example, to create an instance of struct Foo:
+        
+            ({ #'(<, (<Foo>), 1, ({ 2 }), (<Bar>) })
+
+        The order of the member values is the order in which they
+        appear in the struct definition.
+
+        To access a struct member in a lambda closure, use the #'->
+        operator with the name of the member as double-quoted symbol
+        or literal string:
+
+            ({ #'->, struct-expression, ''one })
+            ({ #'->, struct-expression, "one" })
+
+
+MISCELLANEOUS
+        Internally structs can be identified by the ID string
+        returned from get_type_info(). This string contains the name
+        of the struct, the name of the program its type was defined in,
+        and the ID number of the program. However, do not rely on
+        a particular format of this string!
+
+        Support for structs is signaled by the macro __LPC_STRUCTS__.
+
+        Since structs are tied to the program they are defined in,
+        re-compiling a program creates new struct types which are
+        in principle incompatible to the old ones. However, the LPC
+        compiler checks if the newly compiled structs have the same
+        structure as their older counterparts of the same name
+        (and defining program). If the structures conform, the existing
+        older struct types are used instead of the new ones. This way
+        an accidental of for example /std/types.c doesn't break
+        the whole mud.
+
+
+EXAMPLES
+        Suppose we have two objects: a monster, and a monster
+        coordinate tracker, and we want to use a struct to store the
+        coordinate:
+
+          -- monster_coordinate.c --
+            struct Coordinate { int x; int y; };
+
+          -- monster_tracker.c --
+            inherit "monster_coordinate";
+
+            void track (struct Coordinate coord) { ... }
+
+          -- monster.c --
+            inherit "monster_coordinate";
+
+            int move (..) {
+              ...
+              "monster_tracker"->track( (<Coordinate> my_x, my_y) );
+            }
+
+        Note that using '#include "monster_coordinate.c"' instead of inherit
+        won't work. While the objects would compile, the first call to
+        track() would cause a runtime error of the type 
+
+          Illegal type to struct->(): struct Coordinate (/monster.c #234),
+                                      expected struct Coordinate
+                                      (/monster_tracker.c #552)
+
+
+HISTORY
+        structs were fully implemented first in LDMud 3.3.246.
+        The implementation was revised in LDMud 3.3.344.
+        The reactivation of unchanged structs in object updates was
+        implemented in LDMud 3.3.417.
+
+
+SEE ALSO
+        mappings(LPC), get_type_info(E), structp(E), to_mapping(E),
+        to_struct(E), struct_info(E), baseof(E)
diff --git a/doc/LPC/switch b/doc/LPC/switch
new file mode 100644
index 0000000..9bca596
--- /dev/null
+++ b/doc/LPC/switch
@@ -0,0 +1,93 @@
+NAME
+        switch
+
+SYNTAX
+        switch (expr) block
+
+DESCRIPTION
+        Branch to the case label in statement that matches expr.
+        If no matching case label is found (by value or by type),
+        branch to the default label in statement.
+
+        A case label has the form
+
+                case expr_n :
+
+        where expr_n must be constant, or the form
+
+                case expr_n1 .. expr_n2 :
+
+        where expr_n1 and expr_n2 must be numeric constants and
+        expr_n1 < expr_n2.
+
+        Either all case labels have to be strings or all have to be
+        numeric. Only 0 is special: it is allowed in a switch
+        statement where all other labels are strings.
+
+        A default label has the form
+
+                default :
+
+        The default label defaults to the end of statement if not
+        given explicitly.
+
+        Whenever a 'break' statement is executed inside 'statement' a
+        branch to the end of the switch statement is performed.
+
+EXAMPLE
+        Typical usage:
+
+            switch(random(100)) {
+              case 0 .. 22 : write("Nothing happens"); break;
+              case 23 .. 27 :
+                write("You are surrounded by a golden glow");
+                this_player()->heal_self(random(3));
+                break;
+              case 28 .. 32 :
+                write("The water was poisoned!\n");
+                this_player()->add_exp(this_player()->hit_player(random(4)));
+                break;
+              case 33 : write("You hear a voice whispering: "+random_hint());
+              /* fall through */
+              case 34 :
+                write("While you didn't pay attention, a water demon "
+                      "snatches a coin out of your purse!\n");
+                this_player()->add_money(-1);
+                break;
+              default : write "You hear some strange noises\n"; break;
+              case 42 : return;
+              case 99 : write("It tastes good.\n";
+            }
+
+NOTE
+        In C, the grammar for switch() is
+
+            switch (expr) statement
+
+        allowing constructs like
+
+            switch (expr)
+              while (expr2)
+              {
+              case 1: ...
+              case 2: ...
+              }
+
+        In LPC a switch has to be followed by a block that contains the
+        case labels directly. In contrast to C the group of statements
+        following a case label have their own lexical scope so that
+        variable declarations may not cross case labels.
+
+HISTORY
+        LDMud 3.2.10 constrained the grammar to require a block for the
+          switch() body, not just a statement. This differs from the C
+          syntax, but was necessary as the compiler didn't handle
+          the statement case correctly.
+        LDMud 3.3 allowed to pass values of the wrong type to switch(), the
+          driver would in that case use the default case. Before, values of
+          the wrong type caused a runtime error.
+        LDMud 3.3.718 disallowed case labels in inner blocks and variable
+          declarations that cross case labels.
+
+SEE ALSO
+        for(LPC), foreach(LPC), do-while(LPC), if(LPC), while(LPC)
diff --git a/doc/LPC/types b/doc/LPC/types
new file mode 100644
index 0000000..903a1be
--- /dev/null
+++ b/doc/LPC/types
@@ -0,0 +1,136 @@
+CONCEPT
+    types
+
+DESCRIPTION
+
+    Variables can have the following types:
+
+    o int       An integer. Normally full 32 bits signed, yielding a
+                range of at least -2,147,483,648 to 2,147,483,647. The
+                exact available range is given by the predefined
+                macros __INT_MIN__ and __INT_MAX__.
+
+                Integer values can be specified in decimal, in
+                sedecimal when preceeded by '0x' (e.g. 0x11), binary
+                when preceeded by '0b' (e.g. 0b00010001), octal when
+                preceeded by '0o' (e.g. 0o21) and as character
+                yielding the charset value for the character as the number
+                to use (e.g. '0' yields 48 on ASCII machines).
+
+                Character values are enclosed in single-quotes ('),
+                with the sequence ''' returning the single-quote
+                itself. Instead of the literal character an
+                escape-sequence can be written between the
+                single-quotes:
+                  \N   : the character code N in decimal
+                  \0xN : the character code N in sedecimal
+                  \xN  : the character code N in sedecimal
+                  \0oN : the character code N in octal
+                  \0bN : the character code N in binary
+                  \a   : BEL (0x07)
+                  \b   : Backspace (0x08)
+                  \t   : Tab (0x09)
+                  \e   : Escape (0x1b)
+                  \n   : Newline (0x0a)
+                  \f   : Formfeed (0x0c)
+                  \r   : Carriage Return (0x0d)
+                  \<other character>: the given character
+
+    o status    OUTDATED - status was planned to be an optimized
+                boolean format, but this was never actually
+                implemented. status does work; however, since it
+                is only an alias for type 'int', just use int.
+
+    o string    Strings in lpc are true strings, not arrays of characters
+                as in C (and not pointers to strings). Strings are
+                mutable -- that is, the contents of a string can be
+                modified as needed.
+
+                The text of a string is written between double-quotes
+                ("). A string can written over several lines when the
+                lineends are escaped (like a macro), however a better
+                solution is to write one string per line and let the
+                gamedriver concatenate them.
+
+                String text typically consists of literal characters,
+                but escape-sequences can be used instead of
+                characters:
+                  \<CR>     : Carriage Return (0x0d)
+                  \<CR><LF> : ignored
+                  \<LF>     : ignored
+                  \<LF><CR> : ignored
+
+                  \N   : the character code N in decimal
+                  \0xN : the character code N in sedecimal
+                  \xN  : the character code N in sedecimal
+                  \0oN : the character code N in octal
+                  \0bN : the character code N in binary
+                  \a   : BEL (0x07)
+                  \b   : Backspace (0x08)
+                  \t   : Tab (0x09)
+                  \e   : Escape (0x1b)
+                  \n   : Newline (0x0a)
+                  \f   : Formfeed (0x0c)
+                  \r   : Carriage Return (0x0d)
+                  \"   : The double quote (")
+                  \<other character>: the given character
+
+                Adjacent string literals are automatically
+                concatenated by the driver when the LPC program is
+                compiled. String literals joined with '+' are
+                concatenated by the LPC compiler as well.
+
+    o object    Pointer to an object. Objects are always passed by
+                reference.
+
+    o array     Pointer to a vector of values, which could also
+                be an alist. Arrays take the form ({ n1, n2, n3 })
+                and may contain any type or a mix of types. Arrays
+                are always passed by reference. Note that the size
+                of arrays in LPC, unlike most programming languages,
+                CAN be changed at run-time.
+
+    o mapping   An 'associative array' consisting of values indexed by
+                keys. The indices can be any kind of datatype.
+                Mappings take the form ([ key1: value1, key2: value2 ]).
+                By default, mappings are passed by reference.
+
+    o closure   References to executable code, both to local
+                functions, efuns and to functions compiled at
+                run-time ("lambda closures").
+
+    o symbol    Identifier names, which in essence are quoted strings.
+                They are used to compute lambda closures, e.g. instead
+                of ({..., 'ident, ... }) you can write declare a
+                'symbol' variable foo, compute a value for it, and then
+                create the closure as ({ ..., foo, ... })
+
+    o float     A floating point number in the absolute range
+                __FLOAT_MIN__ to __FLOAT_MAX__ (typically 1e-38 to 1e+38).
+                Floating point numbers are signified by a '.'
+                appearing, e.g. '1' is integer 1, but '1.' is
+                floating-point 1 .
+
+    o mixed     A variable allowed to take a value of any type (int,
+                string, object, array, mapping, float or closure).
+
+    o struct    A collection of values. See structs(LPC).
+
+    o union     A range of types, either of which the variable
+                can contain at runtime. See unions(LPC).
+
+    All uninitialized variables have the value 0.
+
+    The type of a variable is really only for documentation. Unless
+    you define #pragma strong_types or rtt_checks, variables can
+    actually be of any type and has no effect at all on the program.
+    However, it's extremely bad style to declare one type but use
+    another, so please try to avoid this.
+
+    A pointer to a destructed object will always have the value 0.
+
+
+SEE ALSO
+    alists(LPC), arrays(LPC), mappings(LPC), closures(LPC), structs(LPC),
+    unions(LPC), typeof(E), get_type_info(E), inheritance(LPC),
+    pragma(LPC), modifiers(LPC), escape(LPC)
diff --git a/doc/LPC/unions b/doc/LPC/unions
new file mode 100644
index 0000000..65a841d
--- /dev/null
+++ b/doc/LPC/unions
@@ -0,0 +1,30 @@
+CONCEPT
+        unions
+
+DESCRIPTION
+        Unions types are a declaration at compile time that a variable,
+        function parameter or function return value can be one of
+        several types.
+
+        Except for type checks using #pragma rtt_checks they have no
+        impact at runtime. There is no runtime union type, the concrete
+        value type is one of the possibilities of the union type.
+
+        Union types have no type names for themselves, they are declared
+        anonymously with the declaration of the variable, function
+        parameter or return type:
+
+            int|string var;
+            int|float fun(object|closure f);
+
+        When using union types as array member types they must be
+        enclosed with < >:
+
+            <int|string>* arr;    /* An array of ints and strings. */
+            int*|string*  arr;    /* Either an array of ints or
+                                     an array of strings.          */
+
+            /* There must be a whitespace between two consecutive <
+               to be not confused with the << operator:            */
+            < <int|string>*|object >* arr;
+
diff --git a/doc/LPC/varargs b/doc/LPC/varargs
new file mode 100644
index 0000000..ef21837
--- /dev/null
+++ b/doc/LPC/varargs
@@ -0,0 +1,75 @@
+CONCEPT
+    varargs
+
+DESCRIPTION
+    A function uses "varargs", short for "variable arguments", if
+    it intentionally may be called with less or more arguments
+    than formally specified.
+
+    The proper order to define a function call is:
+
+        [ modifier ] [ varargs ] [ return type ] function( args...)
+
+     Any other order will result in an error.
+
+
+    Given a function definition like this:
+
+        void fun (string arg1, int arg2, int arg3)
+
+    fun() has to be called with exactly three parameters: one
+    string and two integers.
+
+
+    If the function is defined as
+
+        varargs void fun (string arg1, int arg2, int arg3)
+
+    it is possible to call the function with just arg1, or arg1
+    and arg2. The remaining unspecified arguments (arg2 and arg3,
+    resp. arg3) are in these cases assumed to be 0.
+
+
+    To pass more arguments than specified, the functions last
+    parameter must be defined as following:
+
+        void fun (string arg1, int arg2, varargs int * arg3)
+
+    This allows fun() to be called with two or more arguments.
+    The arguments, except those assigned to the other parameters,
+    in this case arg1 and arg2, and collected into an array which
+    is then passed as arg3. For example
+
+        fun("foo", 1)       -> arg3 == ({ })
+        fun("foo", 1, 2)    -> arg3 == ({ 2 })
+        fun("foo", 1, 2, 3) -> arg3 == ({ 2, 3 })
+
+    The type of the varargs argument has to be an array of the
+    expected type (int*, object*, string*, ...); in this example,
+    only integers are allowed. To accept arguments of any kind,
+    define the parameter as 'varargs mixed' or 'varargs mixed*'.
+
+    To 'flatten' the received argument array in your own function
+    calls, use the efun apply(); e.g.:
+
+        apply(#'call_out, "bar", 1, arg3)
+
+    or the 'flatten arguments' operator:
+
+       call_out("bar", 1, arg3...)
+
+    The two varargs variants can of course be combined:
+
+        varargs void fun (string arg1, int arg2, varargs int* arg3)
+
+    defines a function which may be called with any number of
+    arguments.
+
+
+HISTORY
+    The possibility to pass more arguments than formally specified
+    was introduced in 3.2.1@132. Before, the excess arguments were
+    silently ignored.
+
+SEE ALSO
+    pragma(LPC), apply(E), modifiers(LPC)
diff --git a/doc/LPC/while b/doc/LPC/while
new file mode 100644
index 0000000..adc4708
--- /dev/null
+++ b/doc/LPC/while
@@ -0,0 +1,15 @@
+NAME
+        while
+
+SYNTAX
+        while (expr) statement;
+
+DESCRIPTION
+        While 'expr' evaluates to non 0, execute statement.
+
+        A 'break' in the 'statement' will terminate the loop. A
+        'continue' will continue the execution from the beginning of
+        the loop.
+
+SEE ALSO
+        for(LPC), foreach(LPC), do-while(LPC), if(LPC), switch(LPC)
diff --git a/doc/README b/doc/README
new file mode 100644
index 0000000..5121f9a
--- /dev/null
+++ b/doc/README
@@ -0,0 +1,54 @@
+In diesem Verzeichnis befindet sich alles, was das MorgenGrauen an
+Dokumentation zu bieten hat. Obwohl hier schon so einiges zu finden ist,
+ist die Dokumentation noch lange nicht komplett.
+Zum Teil werden die Verzeichnisse noch umstrukturiert. Was genau wo zu
+finden ist, steht unten sowie in den .readme-Dateien der jeweiligen
+Verzeichnisse.
+
+Die Hilfeseiten werden parallel im ASCII- und im HTML-Format gefuehrt.
+Die HTML-Seiten sind unter http://mg.mud.de/help/ zu finden.
+
+Bei Aenderungen an den Seiten achtet bitte auf Korrektheit. Im Zweifelsfall
+schreibt eine Mail an einen aktiven H oder EM.
+
+Die Unterverzeichnisse und Dateien hier haben folgende Bedeutungen:
+
+* Dokumentation von Befehlen und Themen innerhalb des Spiels
+  (mehr oder weniger komplett ueberarbeitet)
+   o help/   - allgemeine Themen, die ALLE betreffen
+   o pcmd/   - die Befehle, die alle Spieler beherrschen
+   o scmd/   - Seherbefehle und Hilfen zum Hausbau
+   o mcmd/   - hier sind die Magierbefehle beschrieben
+   o wiz/    - allgemeine Themen fuer Magier
+   o g.*/    - Hilfeseiten, die zur Gilde XYZ gehoeren
+   o hilfe.* - Uebersichtsseiten mit den entsprechenden Befehlen
+   o balance/- Uebersicht ueber balancerelevante Themen und Regeln
+
+* Uebersicht ueber Objekte und Funktionen MudLib (nie vollstaendig)
+   o efun/   - Funktionen, die der GameDriver zur Verfuegung stellt
+   o lfun/   - Funktionen, die die Objekte der MudLib zur Verfuegung stellen
+   o master/ - Funktionen, die das Masterobjekt zur Verfuegung stellt
+
+   o std/    - Die Objekte des Basis-MudLib
+   o obj/    - Einige hilfreiche Zusatzobjekte
+
+   o props/  - Die Properties
+   o props/properties.h
+	     - Kurzuebersicht der Properties (Einzelseiten sind aktueller)
+
+* Sonstiges
+   o 3.0/         - einige SEHR alte Hilfeseiten ueber LPmuds im Allgemeinen
+   o beispiele/   - Beispielobjekte und -raeume, muss dringend gefuellt werden
+   o concepts/    - Grundkonzepte von LPC
+   o driver/      - Befehle und Kommandozeile des GameDrivers
+   o ed/          - ein paar Hilfeseiten fuer den 'ed'itor
+   o Grundlagen/  - ein paar grundlegende Informationen; landet vielleicht
+                    mal im Kurs (s.u.)
+   o KURS/        - Hier soll mal ein MG-spezifischer LPC-Kurs hin. Der Kurs
+                    in den Unterverzeichnissen LPC-KURS/ und LPC-KURS2/ ist
+                    a) in englisch und b) nicht unbedingt fuer das
+                    Programmieren im MG geeignet. Fuers Lernen von LPC sollte
+                    er aber ausreichen.
+   o LPC/         - Datentypen und Sprachelemente von LPC
+   o misc/        - alles, was sonst nirgendwo passt
+
diff --git a/doc/about-efun+lfun-docs b/doc/about-efun+lfun-docs
new file mode 100644
index 0000000..473e384
--- /dev/null
+++ b/doc/about-efun+lfun-docs
@@ -0,0 +1,72 @@
+NAME
+	about-efun+lfun-docs
+
+AUTHOR
+	These man pages were collected from the original 2.4.5 docs,
+	from the installed docs of NightFall, TubMud and MorgenGrauen.
+
+	They were collected corrected and completed Pepel@NightFall,
+	with assistance and support by the LPC wizards of NightFall,
+	TubMud and MorgenGrauen, namely Hyp, Macbeth and Mateese. Also
+	to mention are Bumblebee, Boing, Deepthought, Demos, Hate and
+	Jof.
+
+DESCRIPTION
+	The man pages generally adhere to the following format, which
+	was inspired by the Unix man pages.
+
+	<manpage> ::= <section>+
+
+	There are one or more sections in a man page.
+
+	<section> ::= <section-name><newline><section-text><newline>
+
+	The section names are always at the beginning of a line, and
+	in all capital letters (debatable uglyness).
+
+	<section-name> ::=   'NAME' | 'CONCEPT' | 'SYNOPSIS'
+			   | 'LAST UPDATED'
+			   | 'DESCRIPTION' | 'AUTHOR' | 'BUGS'
+			   | 'CAVEATS' | 'WARNING' | 'NOTE' | 'NOTES'
+			   | 'EXAMPLE' | 'EXAMPLES'
+			   | 'SEE ALSO'
+
+	If a NAME section occurs, it should give the name of the man
+	page.
+	If a SYNOPSIS section occurs, the name of the man page canb be
+	derived from the function name, that appears in the line after
+	SYNOPSIS, which looks as follows:
+
+	<returntype><space>['*']<function-name>'('<parameter-prototypes>
+
+	SEE ALSO is followed by one or more lines that contain
+	crossreferences of the form
+
+	<crossreferences> ::=
+		<crossref>[','<white-space><crossref>]*<white-space><EOF>
+	<crossref> ::= <man-page-name>'('<chapter-abbrev>')'
+
+	The names of the referenced man pages are followed in brackets
+	by an abbreveiation for the chaper (i.e. directory) the man
+	page is in. The abbrevs are
+	E for efun/	the ``system calls'' of LPC
+	L for lfun/	member functions that the driver applies to objects
+	C for concepts/	general concepts of LPMUD and LPC
+	LPC for LPC/	about parts of the LPC language
+	M for master/	lfuns that are applied to the master object only
+	D for driver/	some info about internal operation of the driver
+
+	If you want to process these man pages by some converter
+	program, you can use these to map the chapter names to file
+	names or whatever.
+
+BUGS
+	There are no man pages supported by Amylaar himself.
+	I hope one day I can convince him to at least put these docs
+	into the driver distribution.
+
+	Meanwhile, please report any corrections / suggestions /
+	completions to <pepel@ibr.cs.tu-bs.de>
+
+SEE ALSO
+	efun(E), lfun(L), concepts(C), lpc(LPC), master(M), driver(D)
diff --git a/doc/applied/__INIT b/doc/applied/__INIT
new file mode 100644
index 0000000..dc56f6c
--- /dev/null
+++ b/doc/applied/__INIT
@@ -0,0 +1,12 @@
+SYNOPSIS
+        __INIT
+
+DESCRIPTION
+        This function is constructed automagically by the parser at
+        compiler, if the parser was compiled with #define
+        INITIALISATION__INIT. This function is not intended to be
+        defined by the lpc objects, and never to be called from lpc
+        objects. This man page is here just for completeness.
+
+SEE ALSO
+        initialisation(LPC)
diff --git a/doc/applied/add_weight b/doc/applied/add_weight
new file mode 100644
index 0000000..5f8912f
--- /dev/null
+++ b/doc/applied/add_weight
@@ -0,0 +1,24 @@
+DEPRECATED
+SYNOPSIS
+        int add_weight(int w)
+
+DESCRIPTION
+        In compat mode, this function is used by the efun transfer().
+
+        An object that can contain other objects and is not a room
+        must define this function. It is called with the extra weight
+        of the object that is moved into it. If this is ok, then it
+        has to increment the local weight count, and return true.
+        Otherwise, return false, and the new object can not be entered
+        into this object.
+
+        The function is also called with the negative weight in the
+        object that the moving leaves.
+
+        Note that no set_weight() is required by the parser.
+
+HISTORY
+        Deprecated in LDMud 3.3 as transfer() has been deprecated.
+
+SEE ALSO
+        transfer(E), query_weight(A), prevent_insert(A)
diff --git a/doc/applied/applied b/doc/applied/applied
new file mode 100644
index 0000000..b7f63b9
--- /dev/null
+++ b/doc/applied/applied
@@ -0,0 +1,12 @@
+NAME
+        applied
+
+DESCRIPTION
+        This directory contains descriptions for the lfuns used by
+        Amylaar's version of the LPC parser.
+
+        These are functions that are applied by the parser to the LPC
+        objects on various occasions.
+
+SEE ALSO
+        efun(E), master(M), concepts(C), lpc(LPC), driver(D)
diff --git a/doc/applied/can_put_and_get b/doc/applied/can_put_and_get
new file mode 100644
index 0000000..5479832
--- /dev/null
+++ b/doc/applied/can_put_and_get
@@ -0,0 +1,20 @@
+DEPRECATED
+SYNOPSIS
+        int can_put_and_get()
+
+DESCRIPTION
+        In compat mode, this function is used by the efun transfer().
+
+        Define this function in objects that are neither living nor
+        rooms if you want to make it possible to put something into
+        current object.
+
+        Return true if ok, otherwise 0. That means that default is
+        that it is not possible to put something into an object.
+
+HISTORY
+        Deprecated in LDMud 3.3 as transfer() has been deprecated.
+
+SEE ALSO
+        transfer(E), prevent_insert(A)
+
diff --git a/doc/applied/catch_msg b/doc/applied/catch_msg
new file mode 100644
index 0000000..d244af4
--- /dev/null
+++ b/doc/applied/catch_msg
@@ -0,0 +1,19 @@
+SYNOPSIS
+        void catch_msg(mixed *|struct|mapping|object msg, object obj)
+
+DESCRIPTION
+        When say(), tell_room() or tell_object() are used with an
+        non-string as message, the value will be passed to catch_msg()
+        in all living objects that can hear it, instead of writing to
+        the user resp.  sending to catch_tell(). This can be used to
+        implement communication protocols between livings. The second
+        argument denotes the object that has sent the message.
+
+HISTORY
+        LDMud 3.2.11 added tell_object() to the efuns calling this
+        lfun for symmetry reasons.
+        LDMud 3.3.686 added the use of a mapping/struct/object as message
+        value.
+
+SEE ALSO
+        say(E), tell_room(E), catch_tell(A)
diff --git a/doc/applied/catch_tell b/doc/applied/catch_tell
new file mode 100644
index 0000000..942a81a
--- /dev/null
+++ b/doc/applied/catch_tell
@@ -0,0 +1,22 @@
+SYNOPSIS
+        void catch_tell(string)
+
+DESCRIPTION
+        When a message is sent to an non-interactive object, via say(),
+        tell_object, tell_room() or write(), it will get to the function
+        catch_tell(string). The idea is to enable communications between
+        NPCs and from a user to an NPC.
+
+        Messages sent to an interactive object are also passed to that
+        object's catch_tell() lfun, _if it has one_. If the receiver
+        (or one of its shadows) doesn't have that lfun, the text is sent
+        to the socket directly. Only messages sent by an interactive
+        object to itself inside a catch_tell always written to the socket
+        immediately.
+
+        This allows to filter and process text before it is written
+        to a player.
+
+SEE ALSO
+        enable_commands(E), say(E), tell_object(E), tell_room(E),
+        write(E), snoop(E), catch_msg(A)
diff --git a/doc/applied/clean_up b/doc/applied/clean_up
new file mode 100644
index 0000000..47dfa73
--- /dev/null
+++ b/doc/applied/clean_up
@@ -0,0 +1,51 @@
+SYNOPSIS
+        int <lfun> (int refcount)
+        int <closure>(int ref, object ob)
+
+DESCRIPTION
+        The hook H_CLEAN_UP defines a lfun or a closure used to clean
+        up an object. In older drivers this was hardwired to the lfun
+        clean_up().
+
+        The function is applied by the driver when an object hasn't been
+        used for a long time, to give it a possibility to
+        self-destruct. The refcount <ref> passed as argument will be 0 for
+        clone objects, 1 for a simple loaded object, and greater when
+        the object is cloned or inherited by some existing object.  It
+        is recommended not to self_destruct the object when the
+        reference count is greater than one.
+
+        By convention, a refcount < 0 is used if some other object
+        asks the called object to clean_up.
+
+        If the function is a closure, the second argument <ob> is the
+        object to clean up.
+
+        If the hook specifies a non-existing lfun, or if the call
+        returns 0, no further attempt to clean up this object will be done.
+
+        Returning a non-zero value is only recommended when the reason
+        why the object can't self-destruct is likely to vanish without
+        the object being touched, that is, when no local function is
+        called in it, (and in compat mode also when the object is not
+        being moved around).
+
+        A typical mud configuration defines the time to wait for
+        clean_up() so long that you can assert reset() has been
+        called since the object has been touched last time.
+
+EXAMPLES
+        A clone of /std/drink defines clean_up() to self-destruct if
+        it is empty, not carried a living being and not touched for
+        a long time.
+
+        A room that inherits /std/room defines clean_up() to
+        self-destruct if it is neither inherited nor used as a
+        blueprint, is empty and was not entered for a long time.
+
+HISTORY
+        Before 3.2.1, the function was hardwired to the lfun clean_up().
+
+SEE ALSO
+        reset(A), heart_beat(A), call_out(E), destruct(E), remove(A),
+        hooks(C)
diff --git a/doc/applied/create b/doc/applied/create
new file mode 100644
index 0000000..1056e13
--- /dev/null
+++ b/doc/applied/create
@@ -0,0 +1,29 @@
+SYNOPSIS
+        void create()
+
+DESCRIPTION
+        The H_CREATE_SUPER/_OB/_CLONE hooks define the function or closure
+        to be called when the driver creates a new object. In older
+        drivers this was hardwired to the lfun create(), and a lot of
+        hook implementations still follow this tradition.
+
+        This function will be called only once on creation of the
+        object (this is when the object will be loaded or cloned).
+        Inside this function all major initialization can be done. The
+        current user and the previous object are defined but the
+        object has no environment.
+
+EXAMPLE
+        object cloner;
+        void create() {
+           cloner=this_player();
+        }
+
+        Initialize the global variable to hold the one who
+        created/cloned the object.
+
+        For 3.2.1, the mudlib may be programmed to call other lfuns
+        than create() on an objects creation.
+
+SEE ALSO
+        reset(A), init(A), __INIT(A), initialisation(LPC), hooks(C), native(C)
diff --git a/doc/applied/drop b/doc/applied/drop
new file mode 100644
index 0000000..14f2bb1
--- /dev/null
+++ b/doc/applied/drop
@@ -0,0 +1,25 @@
+DEPRECATED
+SYNOPSIS
+        int drop(void)
+        int drop(int silently)
+
+DESCRIPTION
+        In compat mode this lfun is used by the efun transfer().
+
+        It is called to check if an object wants to be moved out of
+        the inventory of a living object. drop() should return 1 to
+        prevent dropping. This is the opposite of the get() function.
+        That is because if drop() is not defined, it will always be
+        possible to drop an object.
+
+        If the object self-destructs when drop() is called, be sure to
+        return 1, as the destructed item surely not can be dropped.
+
+        Most compat mode LPC libraries to define one argument for
+        drop. If silently is true, no messages should be written.
+
+HISTORY
+        Deprecated in LDMud 3.3 as transfer() has been deprecated.
+
+SEE ALSO
+        transfer(E)
diff --git a/doc/applied/exit b/doc/applied/exit
new file mode 100644
index 0000000..575fdd3
--- /dev/null
+++ b/doc/applied/exit
@@ -0,0 +1,21 @@
+SYNOPSIS
+        void exit(object ob)
+
+DESCRIPTION
+        This function was used in compat mode drivers in context
+        with moving objects. Nowadays objects are moved by means
+        of the H_MOVE_OBJECT0/1 hooks, and use of this lfun is
+        up to the mudlib.
+
+        This function was called in the old environment everytime a
+        living object ob leaves it.
+
+        The function this_player() will return a random value, don't
+        use it at this point.
+
+        WARNING: Using this function is EXTREMELY dangerous. A single
+        bug, and you are forever (i.e. until the next reboot occurs)
+        caught in the room.
+
+SEE ALSO
+        init(A)
diff --git a/doc/applied/get b/doc/applied/get
new file mode 100644
index 0000000..655a1b0
--- /dev/null
+++ b/doc/applied/get
@@ -0,0 +1,18 @@
+DEPRECATED
+SYNOPSIS
+        int get()
+
+DESRIPTION
+        In compat mode, this function is used by the efun transfer().
+
+        If an object wants control over when it is possible to pick it
+        up, i.e. moved into a living object, then it must define
+        get(), and return 1 if ok to pick up.
+
+        id() has been called before this to identify the object.
+
+HISTORY
+        Deprecated in LDMud 3.3 as transfer() has been deprecated.
+
+SEE ALSO
+        transfer(E), drop(A)
diff --git a/doc/applied/heart_beat b/doc/applied/heart_beat
new file mode 100644
index 0000000..9876b03
--- /dev/null
+++ b/doc/applied/heart_beat
@@ -0,0 +1,47 @@
+SYNOPSIS
+        void heart_beat()
+
+DESCRIPTION
+        This function will be called automatically every
+        __HEART_BEAT_INTERVAL__ seconds. The driver will call the function
+        directly in the object, even if the function is being shadowed.
+
+        The start and stop of heart beat is controlled by the efun
+        set_heart_beat(). Be careful not to have objects with heart
+        beat running all the time, as it uses a lot of driver
+        resources. If there is an error in the heart beat routine, the
+        heart beat will be turned off for this object and the
+        master function heart_beat_error() is called. If the call
+        to the master function returns a non-zero value, the heart beat
+        will be turned back on again.
+
+        The function this_player() will return this object, but only if
+        it is living. Otherwise, this_player() will return 0.
+
+        The function will be called only if there is at least one interactive
+        user in the game.
+
+        Note that error messages will be given to the current user
+        which will be the object itself or nobody.
+
+EXAMPLE
+        object owner;
+        void create() {
+           ...
+           owner=this_player();
+           set_heart_beat(1);
+        }
+        void heart_beat() {
+           tell_object(owner, "Your heart goes: BUM BUM\n");
+        }
+
+        We have to use tell_object() because write goes to the current
+        user and this can only be the object itself or nobody.
+
+HISTORY
+        LDMud 3.3.687 made the interval time configurable at driver compile
+        time (used to be 2 seconds fixed).
+
+SEE ALSO
+        set_heart_beat(E), call_out(E), enable_commands(E),
+        heart_beat_error(M)
diff --git a/doc/applied/id b/doc/applied/id
new file mode 100644
index 0000000..bdb1fb2
--- /dev/null
+++ b/doc/applied/id
@@ -0,0 +1,17 @@
+SYNOPSIS
+        varargs int id(string str, int lvl);
+
+DESCRIPTION
+        Let the object identify itself. If str matches an id of the
+        current object then return a none zero value.
+
+        This lfun is applied for the efun present().
+
+EXAMPLE
+        int id(string str) {
+           return "sword" == str || "sword of fire" == str;
+        }
+
+SEE ALSO
+        present(E)
+        id(L)
diff --git a/doc/applied/init b/doc/applied/init
new file mode 100644
index 0000000..17675da
--- /dev/null
+++ b/doc/applied/init
@@ -0,0 +1,70 @@
+SYNOPSIS
+        void init()
+
+DESCRIPTION
+        The H_MOVE_OBJECT0/1 implement the details of moving objects.
+        In older drivers, init() was called to handle the adding of
+        actions, and a lot of hook implementations still follow this
+        tradition.
+
+        The main purpose of this function is to publish the commands
+        an object implements to other, living objects. Traditionally,
+        whenever a living object enters the vicinity of another
+        object, init() is called in the latter and this_player() will
+        point to the former object. This happens mutually should both
+        objects happen to be living.
+
+        Or more formally:
+
+            If the object O that moves is marked as living then first
+            call init() of the destination object D with this_player()
+            set to O.
+
+            Then apply the two following rules for each object C
+            inside D:
+
+                    If C is marked as living then call O->init() with
+                    this_player() set to C.
+
+                    If O is marked as living then call C->init() with
+                    this_player() set to O.
+
+            Finally, if D is marked as living then call O->init(),
+            with this_player() set to D.
+
+        Starting with 3.2.1, the actual move handling became part of the
+        object library, so a given installation may implement any other scheme
+        of calling init().
+
+        One caveat: commands defined in the player object for the player
+        himself should not be defined in init(), as these commands would be
+        added to _other_ players whenever they happen to be nearby. Instead
+        use a separate function ("add_player_commands()" or so) which
+        is called during the creation of the player.
+
+EXAMPLE
+        (This example assumes a traditional implementation of the
+         movement handling)
+
+        Lets say we have a object structure of living (l1 and l2) and
+        non living objects (n1 and n2) as the following:
+
+        l1
+           n1
+           l2
+           n2
+
+        If we now move another living object l3 into l1, the call
+        suequence of the init() functions looks like this:
+
+        l1->init()  first init() of the destination will be called
+        n1->init()  now iterate throw the inventory of the destination
+        l3->init()
+        l2->init()
+        n2->init()
+        l3->init()  and finally call init() of the object that has
+                    been moved
+
+SEE ALSO
+        add_action(E), set_environment(E), environment(E), move_object(E),
+        hooks(C)
diff --git a/doc/applied/logon b/doc/applied/logon
new file mode 100644
index 0000000..97f0373
--- /dev/null
+++ b/doc/applied/logon
@@ -0,0 +1,28 @@
+SYNOPSIS
+        int logon (void)
+        int logon (int flag)
+
+DESCRIPTION
+        When the driver created a new connection (either by accepting
+        it or by creating it with net_connect()) and bound it to an
+        object, it then calls logon() in that object.
+
+        The method should return 0 on failure, and everything else on
+        success.
+
+        If the driver attempted to create a connection in the
+        background and failed, it will call logon(-1) in the intended
+        object to inform the mudlib about the failure.
+
+        If the master attempted a secure connection in connect(E) and
+        did not set an explicit TLS callback, the call to logon() won't
+        happen until the TLS handshake is complete. If the master set
+        a TLS callback, that will be executed in place of logon().
+
+HISTORY
+        LDMud 3.2.10 added the extended meaning for net_connect().
+        LDMud 3.2.13/3.3.713 streamlined the handling of secure connections
+        during logon.
+
+SEE ALSO
+        connect(M), net_connect(E), exec(E), tls_init_connection(E)
diff --git a/doc/applied/modify_command b/doc/applied/modify_command
new file mode 100644
index 0000000..4a4b2ef
--- /dev/null
+++ b/doc/applied/modify_command
@@ -0,0 +1,27 @@
+SYNOPSIS
+        int|string <name>(string cmd)
+
+DESCRIPTION
+        After set_modify_command(mob) was called for an interactive
+        object iob, all commands for that user will be passed to
+        mob-><name>(), and the return will then be checked for
+        actions. The actual name of the lfun to call is specified
+        by the H_MODIFY_COMMAND_FNAME hook - traditionally it's
+        'modify_command'.
+
+        If the result is a string, it is the new command to execute
+        instead of the given one. Note that it is not possible to
+        make several commands from one this way!
+        If the result is a non-zero number, the given command is to
+        be ignored. In case of the closure/lfun setting this may
+        mean that the closure/lfun already executed it.
+        If the result is 0, the originally given command is to be
+        used.
+
+HISTORY
+        In 3.2.1@109 the name of the lfun to call must be specified
+        using the H_MODIFY_COMMAND_FNAME driver hook.
+
+
+SEE ALSO
+        set_modify_command(E), hooks(C)
diff --git a/doc/applied/parse_command_adjectiv_id_list b/doc/applied/parse_command_adjectiv_id_list
new file mode 100644
index 0000000..7745de9
--- /dev/null
+++ b/doc/applied/parse_command_adjectiv_id_list
@@ -0,0 +1,15 @@
+SYNOPSIS
+        string *parse_command_adjectiv_id_list(void)
+
+DESCRIPTION
+        Return all adjectives associated with this object.
+
+        Used by parse_command().
+
+EXAMPLE
+        string * parse_command_adjectiv_id_list() {
+            return ({ "iffish" });
+        }
+
+SEE ALSO
+        parse_command(E)
diff --git a/doc/applied/parse_command_id_list b/doc/applied/parse_command_id_list
new file mode 100644
index 0000000..4c8fc73
--- /dev/null
+++ b/doc/applied/parse_command_id_list
@@ -0,0 +1,10 @@
+SYNOPSIS
+        string *parse_command_id_list(void)
+
+DESCRIPTION
+        Return the normal singular names of this object.
+
+        Used by parse_command().
+
+SEE ALSO
+        parse_command(E), parse_command_pural_id_list(A)
diff --git a/doc/applied/parse_command_plural_id_list b/doc/applied/parse_command_plural_id_list
new file mode 100644
index 0000000..ee8d564
--- /dev/null
+++ b/doc/applied/parse_command_plural_id_list
@@ -0,0 +1,13 @@
+SYNOPSIS
+        string *parse_command_plural_id_list(void)
+
+DESCRIPTION
+        Return the plural names of this object.
+
+        If this function doesn't exist, the parser tries to pluralize
+        the names returned by parse_command_id_list().
+
+        Used by parse_command().
+
+SEE ALSO
+        parse_command(E), parse_command_id_list(A)
diff --git a/doc/applied/prevent_insert b/doc/applied/prevent_insert
new file mode 100644
index 0000000..a154ad9
--- /dev/null
+++ b/doc/applied/prevent_insert
@@ -0,0 +1,19 @@
+DEPRECATED
+SYNOPSIS
+        int prevent_insert()
+
+DESCRIPTION
+        In compat mode, this function is used by the efun transfer().
+
+        Define this function in objects that are neither living nor
+        rooms if you want to prevent to put something into current
+        object.
+
+        Return true if ok, otherwise 0. That means that default is
+        that it is not possible to put something into an object.
+
+HISTORY
+        Deprecated in LDMud 3.3 as transfer() has been deprecated.
+
+SEE ALSO
+        transfer(E), can_put_and_get(A)
diff --git a/doc/applied/query_weight b/doc/applied/query_weight
new file mode 100644
index 0000000..7d30b85
--- /dev/null
+++ b/doc/applied/query_weight
@@ -0,0 +1,13 @@
+DEPRECATED
+SYNOPSIS
+        int query_weight(void)
+
+DESCRIPTION
+        In compat mode this lfun is used by the efun transfer().
+        Not that no set_weight() is required by the parser.
+
+HISTORY
+        Deprecated in LDMud 3.3 as transfer() has been deprecated.
+
+SEE ALSO
+        transfer(E), add_weight(A)
diff --git a/doc/applied/remove b/doc/applied/remove
new file mode 100644
index 0000000..bb732b2
--- /dev/null
+++ b/doc/applied/remove
@@ -0,0 +1,21 @@
+SYNOPSIS
+        int remove(void)
+
+DESCRIPTION
+        remove() does some housekeeping to ensure consistency and then
+        destructs the current object.
+
+        This lfun is not applied by the parser, but by other objects
+        to tell the current object to self-destruct. remove() should
+        be supplied by the base classes of the library.  Return 1 if
+        actually self-destructed, 0 otherwise.
+
+        An alternative way to ensure the housekeeping on destruction
+        is through the use of the master apply prepare_destruct().
+
+NOTE
+        Your actual mudlib may name this lfun differently, "remove()" is
+        just the traditional name.
+
+SEE ALSO
+        destruct(E), prepare_destruct(M)
diff --git a/doc/applied/reset b/doc/applied/reset
new file mode 100644
index 0000000..db08bec
--- /dev/null
+++ b/doc/applied/reset
@@ -0,0 +1,37 @@
+SYNOPSIS
+        void reset(int arg)        /* compat mode */
+        void reset(void)           /* native mode */
+
+DESCRIPTION
+        The H_RESET hook defines the function or closure to be called
+        when the driver needs to reset an object. In older drivers
+        this was hardwired to the lfun reset(), and a lot of hook
+        implementations still follow this tradition.
+
+        In compat mode, reset() was called with arg 0 after the object
+        was compiled, and with arg != 0 every once in a while.        In
+        native mode, create() is called after compiling, and reset()
+        is called without arguments every once in a while.
+
+        So, if the argument is zero, the parser is running in compat
+        mode, and reset() may call your create() code. If create() is
+        called, you're on the new version and reset() is not called
+        for object creation. You may call reset() from create() and
+        vice versa, but make sure they do not call each other
+        recursive on either type of driver.
+
+        reset() will be called only in objects that have been used
+        since the last call to reset(), i.e. a function in them was
+        called (other than reset() or clean_up()), or it was moved
+        around.
+
+        This function can be used to reset the state of the object or
+        do some checks or what ever. The game wouldn't be fun if no
+        challenges remained.
+
+        For 3.2.1, the mudlib can be programmed to call an other lfun
+        than reset() to reset an object.
+
+SEE ALSO
+        clean_up(A), heart_beat(A), call_out(E), create(A), __INIT(A),
+        reset(H), hooks(C), initialisation(M), native(C)
diff --git a/doc/balance/artillerie b/doc/balance/artillerie
new file mode 100644
index 0000000..914278d
--- /dev/null
+++ b/doc/balance/artillerie
@@ -0,0 +1,63 @@
+Regeln fuer Artillerie-Objekte
+==============================
+
+1. Definition von Artillerie
+----------------------------
+
+Unter dem Begriff "Artillerie" fasst man alle Objekte zusammen, die
+zusaetzlich zu den vorhandenen Gildenfaehigkeiten durch ein vom
+Spieler initiiertes Kommando direkt Schaden an einem oder mehreren
+Gegnern verursachen.
+
+Waffen und Ruestungen, welche per Kommando Schaden verursachen (z. B.
+Eisstab, Ring vom Schlammdrachen), fallen unter diese
+Definition. Waffen und Ruestungen, die "von sich aus" (ueblicherweise
+per Hit-/DefendFunc) Schaden verursachen (z. B. Todesdrachenpanzer,
+Goblinring), fallen nicht unter diese Definition, sind aber natuerlich
+nach wie vor genehmigungspflichtig.
+
+2. Basisanforderungen
+---------------------
+ 
+Solche Artillerie muss folgenden Anforderungen genuegen:
+
+ a. Artillerie _muss_ P_ATTACK_BUSY beachten (setzen/abfragen).
+ b. Artillerie _muss_ bei Verwendung Konzentrationspunkte 
+    verbrauchen.
+ c. Artillerie darf nicht (bzw. nur begrenzt) gehortet werden
+    koennen.
+ d. Artillerie darf bei Paralyse nicht angewendet werden koennen
+    (P_DISABLE_ATTACK).
+ e. Artillerie muss durch Setzen der Property P_IS_ARTILLERY 
+    gekennzeichnet sein. 
+ f. Artillerie, die Munition benutzt oder selbst Munition ist (wie z.B.
+    Wurfsterne), muss das Unitobjekt und den dortigen Mechanismus zum
+    Zerfall von Objekten nutzen. Dabei sind P_UNIT_DECAY_INTERVAL und
+    P_UNIT_DECAY_QUOTA so zu setzen, dass die Munition eine Halbwertszeit
+    zwischen 5 und 10  Tagen hat, der ihrer Verfuegbarkeit angemessen
+    ist. Dies laesst sich durch geeignetes Einstellen des
+    Prozentsatzes und/oder der Resetzeit erreichen.
+
+    Beispiele:
+    Setzt man p=1% Zerfall pro Reset an, dann muss der Reset
+    fuer eine Halbwertszeit von 5 Tagen dann 
+    t=ln(0.5)/ln(0,99)*5*24*3600 s dauern, das sind 6224 s.
+
+    Moechte man lieber den normalen Reset, der im Mittel 45 min, d.h. 160
+    Resets in 5 Tagen betraegt, so erhaelt man folgenden Prozentsatz:
+    p = 1-0,5^(1/160) d.h. ca. 0,43%.
+ g. Artillerie ist immer genehmigungspflichtig.
+
+Details werden fallweise entschieden.
+
+
+3. Inkraftreten
+---------------
+
+Diese Regeln treten am 5. August 2003 in Kraft.
+Revision am 5. April 2008
+Revision am 7. April 2011
+Revision am 24. August 2011
+
+--------------------------------------------------------------------------
+Letzte Aenderung: Mi, 24.8. 2011 von Humni
diff --git a/doc/balance/attribute b/doc/balance/attribute
new file mode 100644
index 0000000..c1b7f9b
--- /dev/null
+++ b/doc/balance/attribute
@@ -0,0 +1,45 @@
+
+ ATTRIBUTVERAENDERUNGEN
+
+    Positive Veraenderungen an Spielerattributen sind auf jeden Fall von
+    der Balance zu genehmigen. Dabei gelten folgende Regeln:
+
+   - Soll eine Attributveraenderung durch das Tragen/Zuecken von Ruestungen
+    oder Waffen ausgeloest werden, geschieht dies ueber das Setzen der
+    Property P_M_ATTR_MOD. Auch negative Veraenderungen sind von der Balance
+    zu genehmigen, da diese Property mit P_X_ATTR_MOD interagiert.
+   - Soll schon der Besitz eines Objektes die Attributveraenderung
+    ausloesen, muss P_X_ATTR_MOD gesetzt werden. Auch negative 
+    Veraenderungen sind von der Balance zu genehmigen, da diese Property 
+    mit P_M_ATTR_MOD interagiert.
+   - Soll eine Attributveraenderung ohne Beruecksichtigung der Properties
+    P_M_ATTR_MOD und P_X_ATTR_MOD verändert werden, geschieht das ueber die
+    Property P_TIMED_ATTR_MOD. 
+
+
+    Attributveraenderungen sind mit der Balance abzuklaeren.
+
+    Als Regeln sieht die Balance vor:
+    - Bei Objekten mit einem einzelnen Bonus darf +10 nicht ueberschritten 
+    werden.
+    - Bei Objekten mit einem einzigen Malus darf -4 nicht unterschritten
+    werden.
+    - Bei Objekten mit mehreren positiven oder negativen Veraenderungen
+    darf die Summe +4 bzw. -4 nicht ueber/unterschreiten.
+    - Es duerfen nicht mehr als 2 Attribute in einem Objekt geaendert
+    werden. Die Differenz darf 6 nicht ueberschreiten.
+    - Ja hoeher die Attributsveraenderung, um so schlechter sollte das
+    Objekt sonst sein (keine AC 50 mit Ausdauer +10 oder auch -4).
+    - Alle Objekte, die Attribute veraendern, muessen Ruestungs- oder
+    Waffenslots belegen. Ausnahme sind Krankheiten, die der Spieler
+    nicht steuern kann.
+
+ SIEHE AUCH
+
+     balance, ruestungen, waffen, fernwaffen, uniques, npcs,
+     resistenzen, kampfobjekte, grenzwerte
+
+
+------------------------------------------------------------------------------
+Last modified: Thu 2011-04-07 by Humni
+
diff --git a/doc/balance/attributsveraenderungen b/doc/balance/attributsveraenderungen
new file mode 100644
index 0000000..ddd6bf0
--- /dev/null
+++ b/doc/balance/attributsveraenderungen
@@ -0,0 +1,47 @@
+
+ ATTRIBUTVERAENDERUNGEN
+
+    Positive Veraenderungen an Spielerattributen sind auf jeden Fall von
+    der Balance zu genehmigen. Dabei gelten folgende Regeln:
+
+   - Soll eine Attributveraenderung durch das Tragen/Zuecken von Ruestungen
+    oder Waffen ausgeloest werden, geschieht dies ueber das Setzen der
+    Property P_M_ATTR_MOD. Auch negative Veraenderungen sind von der Balance
+    zu genehmigen, da diese Property mit P_X_ATTR_MOD interagiert.
+   - Soll schon der Besitz eines Objektes die Attributveraenderung
+    ausloesen, muss P_X_ATTR_MOD gesetzt werden. Auch negative 
+    Veraenderungen sind von der Balance zu genehmigen, da diese Property 
+    mit P_M_ATTR_MOD interagiert.
+   - Soll eine Attributveraenderung ohne Beruecksichtigung der Properties
+    P_M_ATTR_MOD und P_X_ATTR_MOD verändert werden, geschieht das ueber die
+    Property P_TIMED_ATTR_MOD. 
+
+
+    Attributveraenderungen sind mit der Balance abzuklaeren.
+
+    Als Regeln sieht die Balance vor:
+    - Bei Objekten mit einem einzelnen Bonus darf +10 nicht ueberschritten 
+    werden.
+    - Bei Objekten mit einem einzigen Malus darf -4 nicht unterschritten
+    werden.
+    - Bei Objekten mit mehreren positiven oder negativen Veraenderungen
+    darf die Summe +4 bzw. -4 nicht ueber/unterschreiten.
+    - Es duerfen nicht mehr als 2 Attribute in einem Objekt geaendert
+    werden. Die Differenz darf 6 nicht ueberschreiten.
+    - Ja hoeher die Attributsveraenderung, um so schlechter sollte das
+    Objekt sonst sein (keine AC 50 mit Ausdauer +10 oder auch -4).
+    - Alle Objekte, die Attribute veraendern, muessen Ruestungs- oder
+    Waffenslots belegen. Ausnahme sind Krankheiten, die der Spieler
+    nicht steuern kann und Aehnliches. Damit sind auch Stellen verboten,
+    an der Spieler derartige Krankheiten gezielt bekommen und loswerden
+    kann. Im Zweifel entscheidet die Balance.
+
+ SIEHE AUCH
+
+     balance, ruestungen, waffen, fernwaffen, uniques, npcs,
+     resistenzen, kampfobjekte, grenzwerte
+
+
+------------------------------------------------------------------------------
+Last modified: Thu 2011-06-10 by Humni
+
diff --git a/doc/balance/balance b/doc/balance/balance
new file mode 100644
index 0000000..658d8c5
--- /dev/null
+++ b/doc/balance/balance
@@ -0,0 +1,73 @@
+
+Kurzer Abriss unseres Aufgabenbereiches:
+---------------------------------------
+
+1) Was wird von uns begutachtet?
+
+   Alle Ruestungen und Waffen, die ueber eine DefendFunc 
+   verfuegen, die fuer Spieler von Nutzen ist.
+
+   Alle Ruestungen und Waffen, die ueber eine HitFunc
+   verfuegen, die fuer Spieler von Nutzen ist.
+
+   Alle Ruestungen und Waffen, deren AC/WC die Genehmigungs-
+   grenze ueberschreitet. Auch solche, bei denen dies erst
+   in einer Hit- oder DefendFunc der Fall ist.
+
+   Alle Ruestungen und Waffen, die einen genehmigungs-
+   pflichtigen Schadenstyp enthalten.
+   
+   Alle Objekte, die in irgendeiner Weise das Kampfgeschehen
+   beeinflussen.
+
+2) Was entscheiden wir fuer Gilden?
+
+   Nur Kaempfer-Boni in Waffen und Ruestungen (Waffenschlag, Finte). 
+   Alle anderen Gilden, z.B. Unterstuetzungen fuer Zauberer-Sprueche, 
+   Chaoskomponenten unterliegen dem zustaendigen GildenMagier und 
+   der GildenBalance.
+
+   Selbst ueber Einschraenkungen fuer Gilden haben wir nicht zu 
+   entscheiden. Wenn ein Magier sein Objekt nur fuer Chaoten nutz-
+   bar machen moechte, macht er das eben. Oder wenn er Tanjian aus-
+   schliessen moechte ebenfalls. Das nennt sich dann Programmier-
+   freiheit.
+
+3) Was ist mit Objekten, die keine Waffe/Ruestung sind?
+
+   Hier unterliegen alle Objekte unserer Begutachtung, die irgend-
+   wie eine kampfrelevante Bedeutung haben. Dazu zaehlt:
+
+   - Schaden verursachen koennen (Saeurekugeln)
+   - Paralysetools (graue Steine)
+   - Begleit-Npc (Einhorn, Feuerelementar)
+   - Informationen ueber eingehende Schadenstypen geben
+   - Waffen/Ruestungen manipulieren koennen (Geisterhauch, Blutstropfen)
+   - Informationen ueber Npc, Raeume, Reset-Zeiten usw. ausgeben
+   - Werte manipulieren (Attribute oder Geschwindigkeit erhoehen)
+
+   Ein Sonderfall stellen hier Objekte dar, die vom Typ AT_MISC oder
+   WT_MISC sind. Fuer diese gilt:
+
+   - Sie duerfen keinerlei positive Veraenderungen im Spieler vor-
+     nehmen
+   - Sie duerfen keinerlei kampfrelevante Bedeutung haben (im Sinne 
+     von Spell-/Skill-/Gegner-Manipulation, Attributsveraenderungen, 
+     Heilungen, Informationen u.a.) oder sonstwie einen Kampf be-
+     einflussen
+   - Sie duerfen ueber keine Hit- oder DefendFunc verfuegen. Die AC 
+     bzw. WC solcher Objekte ist immer 0
+
+4) Worauf ist besonders zu achten?
+
+   Die Grenzwerte bei Waffen und Ruestungen sollen den fuer diesen 
+   Typ geltenden Wert nur im seltensten Fall ueberschreiten. Dies
+   gilt auch fuer Werte einer Defend- oder HitFunc.
+
+   Boni aus einer Defend- oder HitFunc sind IMMER per random() zu
+   geben!
+
+   Besonders gute Objekte haben ueber Restriktionen zu verfuegen.
+
+   Besonders gute Objekte sollten auch Nachteile haben.
+
diff --git a/doc/balance/begleitnpcs b/doc/balance/begleitnpcs
new file mode 100644
index 0000000..d8554a5
--- /dev/null
+++ b/doc/balance/begleitnpcs
@@ -0,0 +1,22 @@
+BEGLEITNPCS
+-----------
+
+Manche NPCs unterstuetzen den Spieler im Kampf und laufen mit ihm mit.
+Als Regeln fuer diese NPCs hat die Balance folgende Regeln aufgestellt:
+
+a. NPCs _muessen_ sich im Spieler registrieren.
+b. Man darf nur einen Kampfhelfer zur gleichen Zeit beschwoeren, ausnahmen
+koennen statische NPCs nach Absprache sein.
+c. Kein Kampfhelfer darf eine staerkere Resistenz als -0.5 haben
+d. Ist ein Kampfhelfer in einer bestimmten Kathegorie (Angriff, verteidigung
+...) deutlich besser als Durchschnittliche Gilden-NPCs, muss er entsprechende
+Nachteile mitbringen. Denkbar waeren z.B.: Kurze Haltbarkeit, teuer in der
+Anschaffung, teuer im Unterhalt, kann nicht betankt/geheilt/bewegt werden, hat
+nur wenig LP, grosse Anfaelligkeiten usw.
+e. Im Normalfall sollten Begleit-NPCs nicht in Teams eintreten. Eine Ausnahme
+koennte z.B. ein Bogenschuetze, der sich in die zweite Reihe stellt oder etwas
+in der Art sein. 
+
+Zum Registrieren der NPCs siehe RegisterHelperNPC und UnregisterHelperNPC.
+
+2011-02-22, Humni
diff --git a/doc/balance/fernwaffen b/doc/balance/fernwaffen
new file mode 100644
index 0000000..e070984
--- /dev/null
+++ b/doc/balance/fernwaffen
@@ -0,0 +1,94 @@
+Mit Fernwaffen sind uebrigens ausnahmslos Waffen gemeint, die Munition 
+benoetigen, nicht etwa Speere oder dergleichen. Alle Fernwaffen sind 
+ausnahmslos genehmigungspflichtig, das gilt auch fuer jegliche Munition. 
+     
+Properties in Fernwaffen und ihre Bedeutung:
+
+     P_WC
+        Vorsicht mit dieser Property. Bei Fernwaffen gibt sie _nur_ den
+        Schaden bei Zweckentfremdung der Waffe als Knueppel an. 
+        Dementsprechend ist dieser Wert extrem niedrig zu halten.
+        Standardwert ist hier 30, der auch nur in Ausnahmefaellen 
+        ueberschritten werden sollte. Kaum eine Armbrust oder ein Bogen 
+        taugt nunmal als grossartige Nahkampfwaffe.
+
+     P_QUALITY
+        Wird nur beim Nahkampf mit der Waffe beachtet. Standardmaessig auf
+        100 gesetzt, da Boegen und Armbrueste leicht beschaedigt werden,
+        wenn man damit auf jemanden einpruegelt.
+
+     P_HIT_FUNC 
+        HitFunc fuer den _Nahkampf_. Hat beim Schuss mit der Waffe keinen
+        Einfluss. 
+                
+     P_NR_HANDS
+        Boegen und Armbrueste sind in jedem Fall zweihaendig. Einhaendige
+        Fernwaffen sind aber denkbar (Schlingen zum Schleudern kleiner 
+        Steine z.B.)
+        
+     P_SHOOTING_WC
+        Die Basis-Waffenklasse der Fernwaffe. Zu ihr wird die Waffenklasse
+        der Munition addiert, um den endgueltigen Angriffswert beim Schuss
+        zu berechnen.
+     
+     P_RANGE 
+        Reichweite der Waffe in Metern. Wichtig, wenn aus Containern 
+        (Wachtuermen, Schiffen, etc.) nach aussen geschossen wird.
+        Damit das funktioniert, muss dieser Wert hoeher sein als der
+        im Container definierte (steht dort in der P_SHOOTING_AREA).
+    
+     P_STRETCH_TIME
+        Anzahl der Runden, die zum Laden/Spannen der Waffe benoetigt
+        werden. 1 ist hier der Standardwert, das bedeutet, es kann jede
+        Runde geschossen werden.
+     
+     P_AMMUNITION
+        Benoetigter Munitionstyp. Hier ist eine der moeglichen Konstanten
+        (MUN_*) einzusetzen (z.B. MUN_ARROW fuer Boegen).
+     
+     P_NOGET
+        Hat bei Fernwaffen eine zusaetzliche Bedeutung. Wenn gesetzt, muss
+        die Waffen nicht gezueckt werden, um sie abfeuern zu koennen. Das
+        ist z.B. fuer Katapulte gedacht, die im Raum stehen.
+        
+     Fuer die Munition gibt es kein Standardobjekt. Wichtig ist nur, dass 
+     die entsprechenden Properties gesetzt sind. Normalerweise sollte die 
+     Munition natuerlich eine Unit sein, aber auch Einzelobjekte (ein
+     besonderer Pfeil oder ein grosser Stein fuer ein Katapult) sind 
+     moeglich.
+
+Properties fuer die Munition sind:
+     
+     P_SHOOTING_WC
+        Die Waffenklasse der Munition. Wird zur WC der Waffe addiert.
+        
+     P_DAM_TYPE
+        Schadenstyp der Munition. Sollte normalerweise DT_PIERCE fuer 
+        Pfeile aller Art und DT_BLUDGEON fuer stumpfe Munition wie Steine
+        sein. Magische Schadensarten sind aber natuerlich moeglich.
+        
+     P_HIT_FUNC
+        HitFunc, die beim Schuss mit der Munition benutzt wird.
+        
+     Ausserdem muss in der Munition mittels AddId() der entsprechende
+     Munitionstyp gesetzt werden, z.B. MUN_ARROW.
+
+Genehmigungsgrenzen:
+-------------------
+     Alle Waffen dieser Art sind grundsaetzlich genehmigungspflichtig.
+     Folgende Werte sollten allerdings Obergrenzen darstellen, die
+     im Normalfall nicht zu Ueberschreiten sind:
+     
+     Waffe kann jede Runde abgefeuert werden:  P_SHOOTING_WC 100
+     Waffe braucht eine Ladezeit            :  P_SHOOTING_WC 130
+     
+     Die Obergrenze fuer Munition liegt bei :  P_SHOOTING_WC 60.
+
+     Vorsichtig mit P_SHOOTING_AREA in Raeumen/Containern. 
+
+     Bisher ist dieses Schiessen von Raum zu Raum weitestgehend ungetestet,
+     und es ist nicht klar, welche Probleme das verursachen kann. Wenn 
+     eventuelle Ziele keine Moeglichkeit haben, sich zu wehren oder 
+     wegzulaufen, ist schnell jegliche Balance dahin. Die Regionsmagier
+     haben bei Abnahme von Gebieten darauf zu achten, dass diese Property
+     nur in wenigen, gut begruendeten Raeumen gesetzt wird.
diff --git a/doc/balance/grenzwerte b/doc/balance/grenzwerte
new file mode 100644
index 0000000..f2fc1a6
--- /dev/null
+++ b/doc/balance/grenzwerte
@@ -0,0 +1,58 @@
+ GRENZWERTE
+
+    Waffen:
+   
+      Einhaendige Waffen  :    ab P_WC >= 140
+      Zweihaendige Waffen :    ab P_WC >= 175
+
+      Fuer Waffen die einen nichtphysikalischen Schadenstyp enthalten:
+
+      Einhaendige Waffen  :    ab P_WC >= 120
+      Zweihaendige Waffen :    ab P_WC >= 150
+
+      Genehmigungspflichtig sind auch generell Waffen, die als Schadens-
+      typ DT_TERROR, DT_SOUND, DT_AIR oder DT_SQUEEZE enthalten, unabhaengig
+      von der WC.
+
+      Der Schadenstyp DT_EXPLOSION wird nicht mehr genehmigt.
+
+      Alle Waffen mit HitFunc oder entsprechender Funktion muessen genehmigt
+      werden (Es sei denn diese wirken nur bei !interactive() oder erhoehen 
+      den Schaden nicht).
+
+    Ruestungen:
+
+      +--------------+--------+----------------------------+
+      | Ruestungstyp | MAX_AC | Genehmigungsgrenze (inkl.) |
+      +--------------+--------+----------------------------+
+      | AT_AMULET    |    2   |             --             |
+      | AT_ARMOUR    |   50   |             38             |
+      | AT_BELT      |    2   |             --             |
+      | AT_BOOT      |    6   |              5             |
+      | AT_CLOAK     |   10   |              8             |
+      | AT_GLOVE     |    5   |              5             |
+      | AT_HELMET    |   15   |             13             |
+      | AT_QUIVER    |    0   |             --             |
+      | AT_RING      |    2   |             --             |
+      | AT_SHIELD    |   40   |             28             |
+      | AT_TROUSERS  |   15   |             13             |
+      | AT_MISC      |    0   |             --             |
+      +--------------+--------+----------------------------+
+
+    Ruestungen mit DefendFunc o.ae. muessen generell genehmigt werden 
+    (siehe Waffen).
+
+    Ruestungen und Waffen vom Typ AT_MISC oder WT_MISC duerfen keiner-
+    lei positive Veraenderungen im Spieler hervorrufen, keine Stats
+    veraendern oder sonstwie kampfrelevante Bedeutung haben. Die WC/AC
+    solcher Objekte ist immer 0 und wird auch nicht anders genehmigt.
+
+ SIEHE AUCH
+
+     balance, ruestungen, fernwaffen, uniques, npcs, schadenstypen
+     attributsveraenderungen, resistenzen, kampfobjekte
+
+
+------------------------------------------------------------------------------
+ LETZTE AeNDERUNG:
+    Don, 03.01.02, 12:00:00 von Tilly
diff --git a/doc/balance/kaempferproperties b/doc/balance/kaempferproperties
new file mode 100644
index 0000000..a7ed271
--- /dev/null
+++ b/doc/balance/kaempferproperties
@@ -0,0 +1,9 @@
+Properties in Waffen fuer Trves und ihre Hoechstwerte:
+-----------------------------------------------------
+
+K_THROWING_WEAPON         Waffenwurf            ==> Max:  50
+K_BRAWLING_WC             Waffenschlag          ==> Max:  30
+K_WEAPON_SHATTER          Waffenbruch           ==> Max:  50
+K_DISTRACTING_WEAPON      Finte / Waffentrick   ==> Max:  50
+K_CRITICAL_HIT            Todesstoss            ==> Max: 100
+
diff --git a/doc/balance/kaempferwaffen b/doc/balance/kaempferwaffen
new file mode 100644
index 0000000..0666316
--- /dev/null
+++ b/doc/balance/kaempferwaffen
@@ -0,0 +1,143 @@
+
+      Spezial-Waffen fuer die Kaempfergilde
+      -------------------------------------
+                                   
+Fuer die Waffen bzw. Ruestungen muss /p/kaempfer/kampf.h includet werden.
+  
+  
+
+Zuerst einmal was ueber den Weapon-Type. Zum hundertesten male der Hinweis,
+dass es nicht nur Schwerter gibt! Obwohl die Kaempfer jede beliebige
+Waffe benutzen koennen, gibt es doch, je nach Rasse, sehr grosse Unter-
+schiede. Nur um ein Beispiel zu nenne:
+Ein Hobbit, der alle Werte auf 100% hat, hat mit dem Knochenschaelmesser
+(WC 145) einen hoeheren Angriffswert als mit einer Lanze (WC 200)!!!
+
+
+1) Parierwaffen
+
+  Parierwaffen eigenen sich vor allem zum Parieren, wie z.B. der Sai.
+  Da man mit solchen Waffen oft auch die gegnerische Waffe festhalten
+  kann, gilt der Bonus auch fuer den Block. Parierwaffen haben meistens
+  eine nicht so hohe WC.
+  Es wird die Property P_EFFECTIVE_AC gesetzt.
+  Normale Waffen, die zusaetzlich zum Parieren geeignet sind:
+    P_EFFECTIVE_AC: 1 - 15
+  Reine Parierwaffen mit niedriger WC:
+    P_EFFECTIVE_AC: 20 - 30
+  
+2) Wurfwaffen
+
+  Wurfwaffen sind speciell ausbalanziert, besitzen meist keinen richtigen
+  Griff etc. Aus diesem Grunde sollte ihre WC nicht zu hoch sein.
+  Es wird K_THROWING_WEAPON gesetzt. Der Wert sollte zwischen 1-50 
+  liegen, wobei wirklich nur sehr gute Wurfwaffen mit niedrigerer
+  WC Werte zwischen 35 - 50 haben sollten.
+  
+3) Waffen mit ungewoehnichen Angriffsmoeglichkeiten
+
+  Man kann an Waffen auch an ungewoehnlicher Stelle zusaetzliche
+  Angriffsmoeglichkeiten anbauen. So koennte z.B. die Parierstange
+  bei einem Schwert aus Klingen bestehen, oder das Ende des Stiels
+  bei einer Axt in einem Dorn enden. Beim Waffenschlag wird mit
+  diesen Extrawaffen gearbeitet. Diese Besonderheiten (Klinge am 
+  Pommel des Griffs, etc) sollten natuerlich auch in P_LONG
+  erwaehnt werden, schliesslich sind sie ja mit blossem Auge
+  zu erkennen.
+  Property: K_BRAWLING_WC mit Werten zwischen 1 - 30
+  Weiterhin besteht die Moeglichkeit dieser zusaetzlichen Angriffs-
+  moeglichkeit einen eigenen Schadenstyp zu geben. Dazu setzt man
+  die Property K_BRAWLING_DT (analog zu P_DAM_TYPE).
+
+4) Waffen, die andere Waffen zerstoeren sollen
+  
+  Als Kaempfer kann man versuchen, die Waffe des Gegners zu beschaedigen.
+  Dafuer eignen sich natuerlich besonders schwere Waffen, vor allem
+  z.B. Haemmer. Man koennte natuerlich Waffen konstruieren, die besonders
+  dafuer geeignet sind. Dafuer wird K_WEAPON_SHATTER gesetzt.
+  Der Wert sollte zwischen 1 - 50 liegen.
+  
+5) Waffen, die besonders gut fuer den KO-Schlag sind
+  
+  Der Kaempfer kann versuchen einen Gegner zu betaeuben. Dies geschied
+  in der Regel durch einen Schlag auf den Kopf. Je hoeher das Gewicht
+  der Waffe, desto besser. Es gibt natuerlich Waffen, die dafuer besonders
+  geeignet sind (z.B Todstschlaeger). Dann wird K_KO als Property gesetzt.
+  Der Wert sollte zwischen 1 - 50 liegen. 
+ 
+6) Waffen, die den Gegner besonders gut ablenken koennen
+  
+  Es gibt natuerlich Waffen, die den Gegner leicht ablenken koennen.
+  Dies ist fuer Finten und den Waffentrick sehr nuetzlich. Eine solche
+  Waffe ist z.B. der singende Speer, der den Gegner (und den Traeger)
+  fuerchterlich nervt. Gesetzt wird K_DISTRACTING_WEAPON, wobei
+  der Wert zwischen 1 - 50 liegen sollte.
+ 
+7) Waffen, die beim Todesstoss besonders effektiv sind
+
+  Man kann sich Waffen vorstellen, die speziell fuer den Todesstoss
+  geeignet sind. Vor allem magische Waffen, die z.B. die Seele aus dem
+  geschwaechten Koerper des Gegners reissen, sind vorstellbar. Oder
+  Waffen mit besonders langen, spitzen und duennen Klingen, die sich
+  tief in den Gegner bohren. Es wird K_CRITICAL_HIT gesetzt, der
+  Wert liegt zwischen 1 und 100, wobei 100 eine Verdopplung des 
+  Schadens ergibt!!! Also wirklich sehr vorsichtig verwenden!!!!!
+
+
+8) Schilde fuer den Schildstoss
+
+  Ist ein Schild extra fuer den Schildstoss angefertigt (hat es z.B. einen
+  Dorn montiert, mit dem man gefaehrlich den Gegner rammen kann) so
+  kann im Schild P_EFFECTIVE_WC gesetzt werden. Ausserdem ist es moeglich
+  einen bestimmten Schadenstyp mit P_DAM_TYPE anzugeben (Feuerschild).
+                                      
+9) Special-Ruestungen
+
+  Folgende Ruestungstypen koennen fuer die Kaempfer modifiziert werden:
+  AT_TROUSERS; AT_HELMET; AT_ARMOUR; AT_BOOT. Dabei sind drei verschiedene
+  Sachen moeglich. 
+  a) P_EFFECTIVE_AC wird gesetzt, wenn die Ruestung durch besondere
+     DefendFunc's einen hoeheren Schutz als die AC macht
+  b) Die Ruestung soll auch als Waffe zu verwenden sein (Stiefel beim
+     Kampftritt, Hose beim Kniestoss, Helm beim Kopfstoss und Ruestung
+     beim Ellbogenschlag). z.B. waeren Dornen an den Stiefeln denkbar.
+     Dadurch werden die Stiefel ja nicht als Schutz besser, aber als
+     Waffe. Deshalb P_EFFECTIVE_WC setzen. Den Wert nicht hoeher als
+     doppelte AC.
+     [Boing:]
+     Wenn man der Ruestung wirklich einen Attackebonus geben moechte,
+     dann muss P_EFFECTIVE_WC hoeher sein, als P_AC der Ruestung!
+     Da im Falle, wenn P_EFFECTIVE_WC nicht gesetzt ist, P_AC als
+     Angriffswert genommen wird, waere das ansonsten eine Schwaechung!
+     Das kann man natuerlich gezielt einsetzen, wenn man eine Ruestung
+     machen will, die sehr gut schuetzt, aber nur geringe Kaempferboni
+     aufweist. 
+     Beispiel: 
+        Ruestung mit ac 40 und keiner eff_wc: angriffswert ist 40
+        Ruestung mit ac 40 und eff_wc 20:     angriffswert ist 20
+        Ruestung mit ac 40 und eff_wec 60:    angriffswert ist 60
+  c) Die Ruestung macht einen besonderen Schadenstyp. z.B. Flammenstiefel,
+     die beim Kampftritt DT_FIRE und DT_BLUDGEON machen, oder Hosen
+     mit Spikes an den Knien -> DT_PIERCE. Es sollte immer ein
+     physikalischer Schaden vorhanden sein. Zusaetzlich waere jeder
+     magische Schaden denkbar, der Phantasie sind keine Grenzen gesetzt.
+     Natuerlich sollten solche Specialsachen auch in P_LONG der Ruestung
+     auftauchen. Die Kaempfer haben aber die Moeglichkeit Ruestungen
+     einzuschaetzen und sowas zu entdecken.
+     
+
+
+  Bitte alle fuer die Kaempfer geaenderten Waffen und Ruestungen
+  bei mir absegnen lassen, ich moechte den Ueberblick nicht verlieren :))
+  Ausserdem sollten die Werte nicht gleich zu hoch gewaehlt werden.
+  Die Maximalwerte sollten so gut wie nie vergeben werden. 
+  Vorsicht!!! Werden die Werte ueber die Grenzen erhoeht, wird ein 
+  Kaempfer mit so einer Waffe viel zu stark. Bis jetzt hab ich noch keine
+  Sicherheitsfunktion eingebaut, was sich aber aendern wird, wenn 
+  es jemand uebertreibt :))
+  [Boing:] Leider wurde es uebertrieben, also ist jetzt eine Sicherheits-
+  funktion drin.
+
+
+Ciao Zardoz
+     
diff --git a/doc/balance/kampfobjekte b/doc/balance/kampfobjekte
new file mode 100644
index 0000000..e31793d
--- /dev/null
+++ b/doc/balance/kampfobjekte
@@ -0,0 +1,31 @@
+    Hierzu zaehlen alle Sachen, die irgendeinen Einfluss auf den Kampf nehmen
+    und weder `/std/weapon.c' noch `/std/armour.c' sind. Also die sogenannte
+    Artillerie, Eisstab und artverwandtes, Wurfsterne, Parasteine, Bumi und
+    unterstuetzende NPC.
+
+    Prinzipiell sind alle diese Sachen genehmigungspflichtig.
+    
+    Auto-Selbstfahrer, also Sachen, die ohne Eingriff des Spielers agieren,
+    sind unerwuenscht und sollten vermieden werden. Sorry fuer die
+    Laggeplagten...
+
+    Kampfobjekte sollten P_ATTACK_BUSY setzen und auch vor der Anwendung
+    abfragen, damit sie nicht unbegrenzt hintereinander genutzt werden
+    koennen. Magische Sachen sollten entweder aufgeladen werden muessen oder
+    ihre magische Energie verlieren, damit sie nicht unendlich haltbar sind.
+    Ausserdem hat Magie normalerweise auch unerwuenschte Nebenwirkungen. Die
+    Spieler sollen die moeglichen Vorteile gegen Nachteile oder Nebenwirkungen
+    des Gegenstands abwaegen. Auch bei diesen Objekten *muss* P_INFO gesetzt
+    werden, um eine Begruendung fuer die besondere Wirkung und z.B. einen
+    Hinweis auf die Benutzung zu liefern.
+    
+    Sie sollten keinesfalls kaeuflich erworben werden koennen.
+
+    Objekte, die Auskunft ueber ein- und/oder ausgehende Schaeden geben, 
+    sind genehmigungspflichtig. Solche Objekte sollten nach Moeglichkeit
+    eine Waffe oder Kleidungsstueck - dies jedoch nicht AT_MISC - sein.
+    Dass solche Objekte auch ueber Luecken in der Angabe der Schaeden und
+    Nachteile verfuegen sollten, ist eigentlich klar. 
+    Solche Nachteile liessen sich ueber eine Mindest-Schadenshoehe oder
+    random realisieren. Informationen ueber mehrere Schadenstypen durch 
+    ein und das selbe Objekt sind nicht erwuenscht.
diff --git a/doc/balance/modifyskillattribute b/doc/balance/modifyskillattribute
new file mode 100644
index 0000000..e072791
--- /dev/null
+++ b/doc/balance/modifyskillattribute
@@ -0,0 +1,100 @@
+ModifySkillAttribute()
+
+FUNKTION:
+    public int ModifySkillAttribute(string atrname, mixed value, 
+                                    int duration)
+
+DEFINIERT IN:
+    /std/living/skill_attributes.c
+
+ARGUMENTE:
+    <atrname>   string
+                Name des zu veraendernden Attributes
+                (Definiert in /sys/living/skill_attributes.h)
+
+    <value>     int oder closure
+                Wert des Modifikators
+                oder
+                eine Closure, welche bei Abfrage des betreffenden SAs
+                abgefragt um den Modifikator zu bestimmen.
+
+    <duration>  int
+                Dauer in Sekunden
+
+BESCHREIBUNG:
+    Aendert temporaer, d.h. fuer eine bestimmte Zeit, ein Skill-Attribut eines
+    Lebewesen, indem ein Modifikator hinzugefuegt wird.
+    
+    Der Standardwert eines SA wird von P_SKILL_ATTRIBUTE_OFFSETS festgelegt
+    oder ist 100, wenn besagte Property leer ist.
+    Alle Modifikatoren (negativ wie positiv) werden addiert und bilden
+    zusammen mit dem Standardwert eine Gesamtsumme.
+    Bei allen SAs ausser SA_QUALITY wird diese Gesamtsumme noch mit
+    SA_QUALITY (welches sich damit auf alle anderen Skill-Attribute auswirkt)
+    multipliziert und das Ergebnis stellt den Endwert des SA dar.
+    (Beispiel s.u.)
+
+    Der Wert eines Modifikators muss zwischen -1000 und 1000 liegen. Der
+    Gesamtwert eines SA kann 10 nicht unter- und 1000 nicht ueberschreiten.
+
+    Falle <value> eine Closure ist, wird diese Closure jedesmal ausgefuehrt,
+    wenn das entsprechende SA abgefragt wird. Der Rueckgabewert dieser Closure
+    stellt dann den Wert des Modifikators dar. Auch dieser muss zwischen -1000
+    und 1000 liegen. Gibt die Closure keinen int zurueck, wird der Modifikator
+    geloescht.
+
+    Gueltige Skill-Attribute sind momentan:
+    * SA_QUALITY:  Allgemeine Qualitaet
+    * SA_DAMAGE:   Schaden, den das Lebewesen macht
+    * SA_SPEED:    Geschwindigkeit des Lebewesens
+    * SA_DURATION: Spell-/Skilldauer
+    * SA_ENEMY_SAVE: identisch zu SA_SPELL_PENETRATION (OBSOLET!)
+    * SA_SPELL_PENETRATION: Chance des _Casters_, einen Spell durch ein
+                            P_NOMAGIC durchzukriegen.
+    * SA_RANGE:     Reichweite des Lebewesens (eher unbenutzt)
+    * SA_EXTENSION:  "Ausdehnung" (unbenutzt)
+
+RUECKGABEWERT:
+    SA_MOD_OK              wenn der Modifikator gesetzt wurde
+    SA_TOO_MANY_MODS       wenn die max. Anzahl an Mods schon erreicht ist.
+    SA_MOD_TOO_SMALL       wenn der Mod zu klein ist
+    SA_MOD_TOO_BIG         wenn der Mod zu gross ist
+    SA_MOD_INVALID_ATTR    wenn das gewuenschte SA gar nicht existiert
+    SA_MOD_INVALID_OBJECT  wenn das setzende Objekt ungueltig ist
+    Wenn man nur wissen will, ob die Operation erfolgreich war, empfiehlt es
+    sich, auf == SA_MOD_OK zu pruefen.
+
+BEMERKUNGEN:
+    Nachdem ein Objekt, welches Modifikatoren setzte, zerstoert wurde, werden
+    die Modifikatoren spaetestens ungueltig, sobald in dem manipulierten
+    Lebewesen erneut ModifySkillAttribute() gerufen wird! Bei Closures ist der
+    Mod sofort weg.
+
+BEISPIELE:
+    // sei PL ein Spieler, den mein NPC schwaechen will:
+    PL->ModifySkillAttribute(SA_QUALITY, -75, 13);
+    // Fuer 13s wird SA_QUALITY um 75 reduziert. Dies wirkt sich auf alle
+    // anderen SAs aus! (s. drittes Beispiel)
+
+    // sei PL ein Lebewesen, welchem ich fuer 11s 2 Schlaege pro Kampfrunde
+    // zusaetzlich geben moechte:
+    PL->ModifySkillAttribute(SA_SPEED, 200, 11);
+    // wenn keine weiteres Modifikatoren wirken, hat PL jetzt 3 Schlaege pro
+    // Kampfrunde (Basiswert 100 + 200 == 300 => 3).
+
+    Angenommen, ein Lebewesen hat einen Basiswert von 130 auf SA_SPEED und 100
+    auf SA_QUALITY (P_SKILL_ATTRIBUTE_OFFSETS) und nun 3 Modifikatoren
+    gesetzt: SA_SPEED +100, SA_SPEED -30 und SA_QUALITY von -10:
+    Zunaechst wird SA_QUALITY bestimmt: 100 - 10 = 90  => 0.9
+    Anschliessend wird SA_SPEED bestimmt: 130 + 100 - 30 = 200 => 2
+    Nun wird SA_SPEED noch mit SA_QUALITY multipliziert: 2 * 0.9 = 1.8
+    Das Lebewesen hat nun also im Endeffekt 1.8 Schlaege pro Kampfrunde.
+
+    
+SIEHE AUCH:
+    P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS,
+    QuerySkillAttribute(), QuerySkillAttributeModifier(),
+    RemoveSkillAttributeModifier()
+
+-----------------------------------------------------------------------------
+07.08.2008, Zesstra
diff --git a/doc/balance/multiobjekte b/doc/balance/multiobjekte
new file mode 100644
index 0000000..46086a5
--- /dev/null
+++ b/doc/balance/multiobjekte
@@ -0,0 +1,47 @@
+MULTIOBJEKTE:
+
+	a. Was sind Multiobjekte?
+
+	Multiobjekte sind Multiwaffen oder Multiruestungen.
+
+	b. Multiwaffen
+
+	Multiwaffen sind Waffen, die mehrere Funktionen haben koennen. Das 
+	klassische Beispiel sind Waffen, die mehrere Schadensarten verursachen
+	koennen, und diese z.B. auf Kommando wechseln koennen. Oder auch die
+	Waffengattung.
+
+	Ebenfalls als Multiwaffen werden Waffen behandelt, bei denen im 
+	geringen Umkreis um eine Fundstelle viele aehnliche Waffen auffindbar
+	sind, die sich z.B. nur in der Gattung unterscheiden (ein 
+	Quetschschwert, eine Quetschkeule, ein Quetschstab, ein Quetschspeer..
+	oder : Ein Feuerschwert, ein Eisschwert, ein Saeureschwert, ein
+	Blitzschwert, ein Wasserschwert...)
+
+	c. Multiruestungen
+
+	Multiruestungen sind analog Ruestugnen, die gegen bestimmte Schaeden
+	schuetzen und entweder selbst in Schadensart wandelbar sind, oder wo
+	es viele gleichartige in einem geringen Umkreis gibt. (Blitzhelm,
+	Blitzhose, Blitzpanzer, Blitzring... oder Feuerring, Wasserring,
+	Blitzring, Eisring...). Analoges gilt fuer die Schadensart der
+	Ruestung fuer die Kaempfergilde.
+
+	d. Regel
+
+	Multiobjekte duerfen in einem geringen Umkreis nur in maximal 4 
+	Varianten vorkommen oder von/fuer Spieler herstellbar sein.
+
+	Diese Regelung ist schwammig, aber sie soll verhindern, dass es ein
+	universelles Ausruestungsgebiet gibt.
+
+	Was ein geringer Umkreis ist, ob Waffen oder Ruestungen als
+	Multiobjekte gelten, ob die Tatbestaende also fuer den konkreten
+	Programmierungssachverhalt gelten, entscheidet die Balance nach
+	Auslegung und evtl. Regelfortbildung dem Sinn bzw. der Historie
+	dieser Regel nach.
+
+	Als Ansprechpartner fuer diese Regel steht die Balance zur
+	Verfuegung.
+
+Letzte Aenderung: Humni, 2011-01-15
diff --git a/doc/balance/parierwaffen b/doc/balance/parierwaffen
new file mode 100644
index 0000000..d7e38b4
--- /dev/null
+++ b/doc/balance/parierwaffen
@@ -0,0 +1,7 @@
+Aktuelle Grenzwerte:
+====================
+
+  Parier-Typ   Genehmigungsgrenze
+  ------------ --------------------
+  PARRY_ONLY   Wie Ruestungen vom Typ AT_SHIELD
+  PARRY_TOO    Generelle Genehmigungspflicht
diff --git a/doc/balance/properties b/doc/balance/properties
new file mode 100644
index 0000000..e849ab6
--- /dev/null
+++ b/doc/balance/properties
@@ -0,0 +1,194 @@
+P_AC                  : ArmourClass, Wert der den Schutz einer Ruestung 
+                        (P_ARMOURS,P_ARMOUR_TYPE) angibt
+
+P_ATTACK_BUSY         : Anzahl der moeglichen Aktionen eines Lebewesens pro
+                        Kampfrunde (1 HeartBeat). Bei Spielern ist dies 1, 
+                        bei Sehern max. 5. Wegen des hoeheren Wertes bei
+                        Sehern ist darauf zu achten, das hier ADDIERT wird
+                        und nicht einfach nur auf 1 gesetzt.
+                        Siehe auch: bman kampfobjekte
+
+P_ATTRIBUTES          : Attribute eines Spielers, koennen durch Objekte,
+                        Flueche und/oder Krankheiten manipuliert werden.
+                        Siehe auch: bman attribute
+
+P_ATTRIBUTES_MODIFIER : Hier werden Attribut-Modifier gespeichert, die 
+                        ueber einen laengeren Zeitraum wirken sollen.
+                        Bekannteste Beispiele sind wohl der Todes-Malus
+                        und der Frosch-Malus. Normale Aenderungen sollten
+                        per P_X_ATTR_MOD oder P_M_ATTR_MOD realisiert 
+                        werden
+                        Siehe auch: bman attribute
+
+P_COMBATCMDS          : Beinhaltet Befehle, Schadenshoehe und -arten in 
+                        Kampfobjekten, damit diese auch von NPC benutzt
+                        werden koennen.
+                        Siehe auch: bman kampfobjekte
+
+P_CURSED              : Objekte in denen hier ein String oder Int-Wert ge-
+                        setzt ist, koennen nicht abgelegt werden. Kleriker
+                        haben die Faehigkeit, zu entfluchen
+
+P_DAMAGED             : Grad der Beschaedigung einer Waffe oder Ruestung.
+                        Wird meistens per waffe->Damage(x) realisiert. Kann
+                        bei div. Schmieden wieder auf 0 gesetzt werden, Trves
+                        koennen es durch Waffenschaerfen sogar selbst
+
+P_DAM_TYPE            : Schadenstyp, den eine Ruestung oder Waffe macht
+                        Siehe auch: bman schadenstypen
+
+P_DEFEND_FUNC         : Gesetzt wenn eine Ruestung eine DefendFunc definiert
+                        hat. Werte einer DefendFunc sind IMMER per random
+                        zu geben, Ausnahme: negativer Rueckgabewert. Auch
+                        hier ist darauf zu achten, das P_WC + Rueckgabewert
+                        nicht ueber den Grenzwert kommen
+                        Siehe auch: bman grenzwerte, bman ruestungen
+
+P_DISABLE_ATTACK      : Gesetzt wenn das Lebewesen ausnahmsweise mal nicht
+                        angreifen kann. Es wird die Anzahl der Kampfrunden
+                        (also HeartBeats) gesetzt, in denen die Paralyse
+                        wirkt. Neue Paralyse-Tools sind nicht gern gesehen
+                        und haben wenig Chancen auf Genehmigung
+
+P_EFFECTIVE_AC        : Die effektive ArmourClass einer Ruestung. Ist in
+                        einer Ruestung noch eine P_DEFEND_FUNC definiert,
+                        so betraegt ist P_EFFECTIVE_AC = P_AC + 2 * Mittelwert
+                        des dortigen Rueckgabewertes
+
+P_EFFECTIVE_WC        : Die effektive WeaponClass einer Waffe oder Ruestung.
+                        Ist in einer Waffe eine P_HIT_FUNC definiert, so be-
+                        rechnet sich die P_EFFECTIVE aus der Summe von P_WC
+                        und dem doppelten Mittelwert des dortigen Rueckgabe-
+			wertes
+
+P_HANDS               : Enthaelt mehrere Eintraege, die Meldung, Staerke
+                        eines Angriffes mit blossen Haenden und den oder
+                        die dabei verursachten Schadenstypen beinhalten
+
+P_HIT_FUNC            : Gesetzt, wenn eine Waffe oder Ruestung eine HitFunc
+                        definiert hat. Die Werte muessen IMMER per random
+                        gegeben werden. Auch hier sind einzig negative Rueck-
+                        gabewerte die Ausnahme. Darauf zu achten ist, das 
+                        P_AC + Rueckgabewert nicht den Grenzwert ueber-
+                        schreiten
+                        Siehe auch: bman grenzwerte
+
+P_HP                  : Aktuelle Lebenspunkte (HealthPoints) eines Lebe-
+                        wesens
+
+P_HP_DELAY            : Numerischer Wert, der angibt, wieviele HeartBeats
+                        notwendig sind, damit sich die P_HP um 1 regenieren
+
+P_HP_HOOKS            : Was fuer Objekte sollen bei einer Aenderung der P_HP
+                        benachrichtigt werden? Bekanntestes Beispiel ist 
+                        hier sicher der Teddy aus der Nibelungenquest
+
+P_LEP                 : LEvelPoints, absolute Stufenpunkte eines Spielers.
+                        Ist manchmal sinnvoller, P_LEP abzufragen anstatt
+                        P_LEVEL
+
+P_M_ATTR_MOD          : Mapping mit Attributen die veraendert werden, wenn
+                        das Lebewesen diese RUESTUNG oder WAFFE traegt oder
+                        zueckt. Jedes Attribut kann nur durch einen Modifier
+                        beeinflusst werden. Ist also ein Attribut blockiert,
+                        kann die Ruestung/Waffe nicht angezogen/gezueckt
+                        werden. Fuer Krankheiten usw. gibt es P_X_ATTR_MOD
+                        Siehe auch: bman attribute
+
+P_M_HEALTH_MOD        : Mapping mit dem die max. P_HP und max. P_SP eines
+                        Lebewesens manipuliert werden koennen, wenn es diese
+                        RUESTUNG oder WAFFE traegt oder zueckt. Es erfolgt
+                        keinerlei Blockade. Fuer Krankheiten usw. gibt es 
+                        P_X_HEALTH_MOD
+
+P_NOMAGIC             : Wert zwischen 0 (default) und 100, der den Grad an-
+                        gibt, mit welcher Wahrscheinlichkeit Magie keine
+                        Wirkung erzielt. Kann in Raeumen, Npc und Objekten
+                        gesetzt werden. Von Spieler nicht gern gesehen :)
+
+P_NR_HANDS            : Wieviel freie Haende sind notwendig, um diese Waffe
+                        oder diesen Schild zu zuecken?
+ 
+P_PARRY_WEAPON        : In Waffen gesetzt wenn es sich um eine Parierwaffe
+                        handelt
+                        Siehe auch: bman parierwaffen
+
+P_PURSUERS            : Beinhaltet alle Objekte/Npc die den Spieler momentan
+                        verfolgen
+
+P_QUALITY             : Beliebiger Wert in Waffen. Setzt man ihn auf n, so wird
+                        die Waffe bei jedem n-ten Schlag um 1 Punkt be-
+                        beschaedigt (P_DAMAGED also um 1 erhoeht) und dieser 
+                        von der P_AC abgezogen, der Schaden laesst sich in
+                        einer Schmiede reparieren.
+                       
+P_REMOVE_FUNC         : Funktion die vor dem Ausziehen einer Ruestung auf-
+                        gerufen wird
+                        Siehe auch: bman ruestungen
+
+P_RESISTANCE          : Was fuer Resistenzen sind gesetzt? Enthaelt ein 
+                        Array der Schadenstypen, gegen die das Lebewesen
+                        resistent sein soll. P_RESISTANCE_STRENGHTS ist hier
+                        viel genauer und sollte deswegen verwendet werden
+
+P_RESISTANCE_MODIFIER : Hier steht die Summe aller Modifikatoren, die 
+                        Resistenzen und Anfaelligkeiten betreffen. Diese
+                        Propertie sollte NIE direkt manipuliert werden
+
+P_RESISTANCE_STRENGHTS: Huebscher Typo bei Realisierung von Anfaelligkeiten
+                        und Resistenzen eines Lebenwesens :-)
+
+P_RESISTANCE_STRENGTHS: Was fuer Resistenzen oder Anfaelligkeiten hat das
+                        Lebewesen? Gesetzt wird ein Mapping mit den
+                        Schadenstypen und ein entsprechender numerischer 
+                        Wert. Dieser Wert geht von -1 .. 0 .. 1, ist er
+                        negativ, so ist das Lebewesen resistent, ist er 
+                        positiv, so ist das Lebewesen anfaellig
+
+P_RESTRICTIONS        : Wird vor dem Zuecken oder Anziehen einer Waffe oder
+                        Ruestung geprueft. Hier lassen sich diverse Werte
+                        abfragen, die das verhindern
+                        Siehe auch: bman restriktionen
+
+P_SP                  : SpellPoints, aktuelle Konzentrationspunkte eines
+                        Lebewesens
+
+P_SP_DELAY            : Numerischer Wert, der angibt, wieviele HeartBeats
+                        notwendig sind, damit sich die P_SP um 1 regenieren
+
+P_UNWIELD_FUNC        : Funktion, die vor dem Wegstecken einer Waffe auf-
+                        gerufen wird
+
+P_VULNERABILITY       : Empfindlichkeiten eines Npc/Spielers, sollte ueber
+                        P_RESISTANCE_STRENGTHS realisiert werden
+                         
+P_WC                  : WeaponClass, Wert der die Guete einer Waffe angibt.
+                        Absoluter Oberwert ist 200
+                        Siehe auch: bman grenzwerte
+
+P_WEAPON_TYPE         : Um was fuer eine Waffe handelt es sich? Keule, Speer
+                        oder Axt? Oder was anderes? 
+                        Siehe auch: bman waffen
+
+P_WEAR_FUNC           : Funktion die vor dem Anziehen einer Ruestung auf-
+                        gerufen wird. Sie kann das Anziehen verhindern, hier
+                        ist oftmals ein Eintrag in P_RESTRICTIONS sinnvoller
+                        Siehe auch: bman restriktionen
+
+P_WIELD_FUNC          : Funktion, die vor dem Zuecken einer Waffe aufgerufen
+                        wird. Sie kann das Zuecken verhindern. Oftmals ist
+                        da ein Eintrag per P_RESTRICTIONS vorteilhafter
+                        Siehe auch: bman restriktionen
+
+P_X_ATTR_MOD          : Mapping mit Attributen die veraendert werden, wenn
+                        das Lebewesen dieses OBJEKT bei sich hat. Ist fuer
+                        Krankheiten u.ae. gedacht. Bekanntes Beispiel sind
+                        die Flueche, die man sich auf Akhar Nth'tar weg-
+                        holen kann
+                        Siehe auch: bman attribute
+
+P_X_HEALTH_MOD        : Mapping mit dem die max. P_HP und max. P_SP eines
+                        Lebewesens veraendert werden, das dieses OBJEKT bei
+                        sich traegt. Ohne nachgesehen zu haben sag ich mal,
+                        das es so z.B. beim Rattenblut gemacht wird
+                        Siehe auch: bman kampfobjekte
diff --git a/doc/balance/resistenzen b/doc/balance/resistenzen
new file mode 100644
index 0000000..f2b92a9
--- /dev/null
+++ b/doc/balance/resistenzen
@@ -0,0 +1,59 @@
+
+ RESISTANCE MODIFIER:
+    Soll ein Objekt in einem Spieler ResistanceModifier setzen, gelten
+    folgende Regeln:
+
+    a) Es muss sich um eine Ruestung handeln (in ganz seltenen Faellen
+       werden auch Waffen mit dieser Moeglichkeit erlaubt). Bei Ruestungen
+       muss _nicht_ AddResistanceModifier() benutzt werden, sondern es 
+       genuegt, P_RESISTANCE_STRENGTH in der Ruestung zu setzen.  Dabei 
+       werden _anders_ als bei AddResistanceModifer() Prozentwerte der 
+       maximal erlaubten Resistenz fuer den entsprechenden Ruestungstyp 
+       angegeben. Diese werden beim Tragen der Ruestung automatisch
+       in tatsaechliche Resistenzen des Traegers umgerechnet.
+       (Beispiel siehe "man P_RESISTANCE_STRENGTHS").
+
+    b) Das Objekt muss natuerlich genehmigt werden.
+
+    c) Die Summe aller Resistenzen darf max. -0.15 betragen. Ausserdem
+       muessen zu jedem Schadenstyp gleichzeitig Empfindlichkeiten in
+       mindestens gleicher Staerke bei einem anderen Schadenstyp gesetzt
+       werden oder die Resistenzen muessen mit anderen Nachteilen (z.B.
+       Aufloesung des Objekte bei Angriff mit einem bestimmten Schadenstyp)
+       ausgeglichen werden.
+       
+       Bei Ruestungen darf maximal eine relative Resistenz von 
+       (logischerweise) 100% eingetragen werden. 100% in der Property
+       P_RESISTANCE_STRENGTH einer Ruestung bedeuten folgende Resistenzen
+       im Traeger:
+       
+       AT_ARMOR,
+       AT_SHIELD : -0.15
+       
+       AT_CLOAK,
+       AT_RING,
+       AT_AMULET : -0.10
+       
+       AT_MISC   : nicht gestattet!
+
+       andere    : -0.05
+       
+    d) Zur leichteren 'Identifizierbarkeit' sollten die ResistanceModifier
+       sollten die gesetzten Modifier auch in dem setzenden Objekt als
+       P_RESISTANCE_STRENGTHS gesetzt werden. Bei Ruestungen MUSS dies
+       geschehen (siehe a) ).
+
+    e) Es duerfen keine mechanischen Resistenzen gesetzt werden. Schutz
+       vor mechanischen Angriffen wird durch die Ruestungen sowieso 
+       schon gewaehrt (im Gegensatz zu Schutz vor nichtmechanischen). Und
+       NEIN, da gibt es keine Ausnahmen!
+
+ SIEHE AUCH
+
+     balance, ruestungen, waffen, fernwaffen, uniques, npcs,
+     attributsveraenderungen, kampfobjekte, grenzwerte
+
+
+------------------------------------------------------------------------------
+ LETZTE AeNDERUNG:
+    2003-08-29, Zook.
diff --git a/doc/balance/restriktionen b/doc/balance/restriktionen
new file mode 100644
index 0000000..838bb7d
--- /dev/null
+++ b/doc/balance/restriktionen
@@ -0,0 +1,30 @@
+Es ist moeglich, Waffen und Ruestungen zu beschraenken, so dass sie
+nur von Spielern benutzt werden koennen, die gewisse Kriterien erfuellen.
+Diese Pruefung wird allerdings _nur_ beim Zuecken oder Anziehen geprueft.
+Sollte sich die entsprechende Eigenschaft des Spielers waehrend der
+Benutzung aendern, kann er oder sie das entsprechende Teil weiter
+nutzen, bis es ausgezogen/weggesteckt wird.
+
+Um solche Restriktionen zu implementieren, muss ein Eintrag in die
+Property P_RESTRICTIONS erfolgen. Was kann dort alles eingetragen
+werden?
+
+- Mindestwerte fuer alle Attribute (Geschicklichkeit etc.)
+- Mindestwerte fuer - Questpunkte
+                    - Spielerlevel
+                    - Erfahrungspunkte
+- Spielerrasse oder eine Liste von ein- bzw. ausgeschlossenen Rassen
+- Gildenlevel (macht nur wenig Sinn)
+- Seherstatus
+- Maximalwerte fuer Alkohol, Essen, Trinken
+- Gesinnung (nach oben und unten)
+- Koerpergroesse (nach oben und unten)
+- Anzahl der freien Haende
+
+Die Bedingungen sind beliebig zu kombinieren, man kann also eine Waffe
+programmieren, die nur von ueber 2 Meter grossen satanischen Hobbits
+gezueckt werden kann, die einen leeren Magen haben. (Vermutlich eine
+riesige Fleischgabel...)
+Fuer gute Waffen und Ruestungen sind allerdings vermutlich in erster Linie
+die Restriktionen Spielerlevel, Seherstatus und vielleicht noch Attribute
+interessant. Vielleicht auch noch Erfahrungspunkte.
diff --git a/doc/balance/ruestungen b/doc/balance/ruestungen
new file mode 100644
index 0000000..a77a735
--- /dev/null
+++ b/doc/balance/ruestungen
@@ -0,0 +1,128 @@
+Allgemeines und generelles ueber Ruestungen:
+-------------------------------------------
+
+Properties:
+
+        P_WEIGHT
+           Bitte realistisch halten. Ringe mit weit ueber 100 Gramm sind
+           Schwachsinn, ebenso Hosen mit Gewichten unter 200 usw.
+           Orientierungen an mittelalten Ruestungen; bei neueren treten zum
+           Teil laecherliche Werte auf, die bei Gelegenheit angepasst werden
+           muessen.
+
+        P_VALUE
+           Wert der Ruestungen sollte auch nicht zu gross sein und sich ein
+           wenig an der AC orientieren. Ebenfalls: RMs, schaut genau hin.
+
+        P_ARMOUR_TYPE
+           Bitte sinnvoll benutzen! Kleider als Hosen definieren oder
+           aehnliches ist unsinnig und sollte nicht genehmigt werden. Sind mal
+           wieder die RMs fuer zustaendig. Bitte achtet drauf!
+
+        Folgende Ruestungstypen sind moeglich:
+
+            AT_ARMOUR
+               Alles was irgendwie den Torso schuetzt. Also vorn und hinten,
+               wie ein Pullover, ein Kettenhemd, ein Panzer etc.
+            AT_CLOAK
+               Umhaenge, auch im weiteren Sinn wie Decken und Schleier. Im
+               Prinzip das, was normalerweise nur den Ruecken schuetzt, bei
+               Bedarf aber auch vorn herum gewickelt werden koennte.
+            AT_HELMET
+               Kopfbedeckungen jeder Art, vom normalen Hut ueber Kronen bis
+               hin zu Stirnbaendern (wenn sie schuetzen sollen)
+            AT_TROUSERS
+               Hosen. Alles was zum ueberwiegenden Teil dazu gedacht ist, die
+               Beine und/oder den Popo zu schuetzen, also auch Schuerzen oder
+               Leggins. Natuerlich gehoeren auch Badehosen oder Lendenschuerze
+               hierher. AC dann selbstverstaendlich gering.
+            AT_BOOT
+               Schuhe, Stiefel und Fussbekleidungen jeder Art.
+            AT_GLOVE
+               Handschuhe oder alles, was man so zum Schutz der oberen
+               Extremitaeten benutzt, wie Armschoner, Glacehandschuhe,
+               Faeustlinge, Boxhandschuhe etc.
+            AT_QUIVER
+               Koecher und aehnliches, in denen man Munition fuer
+               Schusswaffen unterbringen kann. Schuetzen tut sowas
+               natuerlich nicht.
+            AT_SHIELD
+               Alles, was man so anstelle der eigenen Arme in einen
+               gegnerischen Schlag halten kann und das nicht offiziell als
+               Waffe deklariert ist. Es sollte nicht grade aus Papier
+               bestehen, und das Gewicht ist mit entscheidend fuer die Guete
+               des Schildes. Sie werden sehr wenig im MG genutzt, was
+               eigentlich seltsam ist. Schliesslich erreicht ein guter Schild
+               die Guete von Helm, Hose und Handschuhen zusammen oder 3/4 der
+               Qualitaet einer Ruestung. Andererseits: es gibt auch nicht sehr
+               viele Schilde. Da herrscht Bedarf!
+            AT_RING
+               Ringe. Prinzipiell sollte gelten, das Ringe praktisch keine     
+	             Schutzwirkung haben (also AC 1 oder max. 2). Nur, und dafuer
+	             sind die Dinger da, wenn sie magisch sind koennen sie
+	             zusaetzliche Funktionen haben.
+            AT_AMULET
+               Im Prinzip dasselbe wie bei AT_RING, nur werden die Dinger
+               meist an Kordeln um den Hals oder als Broschen an den Klamotten
+               getragen, koennten also je nach Groesse tatsaechlich mehr
+               Schutz bieten als ein Ring. Aber auch hier gilt: AC>2 schreit
+               nach Erklaerung und sollte magischen Dingern vorbehalten
+               bleiben.
+            AT_BELT
+               Guertel aller Art (z.B. Waffenguertel oder Magisterguertel
+               der Zauberer). Schutzwirkung hat sowas natuerlich kaum.
+            AT_MISC
+               Alles, was man sonst noch so anziehen kann, was aber eher als
+               Zierrat gedacht ist. AC immer 0. Bitte *keine*
+               Kleidungsstuecke, die in eine der anderen Kategorien passen,
+               als AT_MISC definieren. Dann lieber die AC sehr tief. Wenn es
+               eh als Gag gedacht ist koennen die Spieler sich auch bei Bedarf
+               umziehen.
+
+        P_EFFECTIVE_AC
+           Falls eine DefendFunc vorhanden ist und die regulaere AC
+           veraendert, sollte sie gesetzt werden. Es wird der
+           Durchschnittswert der AC incl. der DefendFunc gesetzt. Dient der
+           Kaempfergilde zur Einschaetzung, wird auch von Gilden evtl. zur
+           Berechnung von Zusatzschutz oder weiteren Effekten verwendet.
+
+        P_DAM_TYPE
+           Auch Ruestungen koennen einen Damage-Typ haben. Nutzen tut das
+           bisher nur die Kaempfergilde, aber schaden tut's keinem. Default
+           ist DT_BLUDGEON.
+
+        P_NOBUY
+           Alle Ruestungen ab 2/3 der maximal fuer den jeweiligen Ruestungstyp
+           zulaessigen AC werden beim Verkauf im Laden einbehalten. Dennoch
+           sollten besondere Ruestungen P_NOBUY gesetzt haben. Insbesondere
+           waere das fuer alles mit DefendFuncs zu wuenschen, aber auch
+           Sachen, die als Gag gedacht sind. Dafuer koennen sich die Spieler
+           ruhig etwas recken.
+
+        P_DAMAGED
+            Diese Property (sie gibt den Grad der Beschaedigung einer Waffe
+            oder Ruestung an) sollte man _nicht_ per Hand setzen. Stattdessen
+            ruft man in der Ruestung Damage(int) auf. Ein positiver Parameter
+            bedeutet eine Beschaedigung, ein negativer Reparatur um diesen
+            Wert. In der Funktion werden alle notwendigen Bedingungen
+            geprueft (maximale Ruestungsklasse etc).
+
+
+Spezialruestungen/Ruestungen mit Sonderfunktion:
+
+       Alle Ruestungen, die ueber eine DefendFunc oder aehnliches verfuegen
+       sind genehmigungspflichtig.
+
+       Prinzipiell sollten die geltenden Grenzwerte nicht ueberschritten 
+       werden; Ausnahmen koennen unter Umstaenden genehmigt
+       werden. Immer ist der Return-Wert per random() zurueckzuliefern, da der
+       Wert ohne weiteres random() aufaddiert wird.
+
+       Saemtliche Sonderfunktionen, wie Heilungen, Sonderattacken auf Gegner,
+       Waffenbeschaedigungen etc. muessen genehmigt werden.
+
+       Die Properties, mit denen Handschuhe 'handfrei' bzw 'fingerfrei' gemacht
+       werden, duerfen nur vergeben werden, wenn die Handschuhe den Schaden der Hand
+       nicht veraendern und die Beschreibung der Handschuhe dazu passt.
+
+------------------- LETZTE AENDERUNG: Humni, 2011-10-13
diff --git a/doc/balance/schadenstypen b/doc/balance/schadenstypen
new file mode 100644
index 0000000..41896f2
--- /dev/null
+++ b/doc/balance/schadenstypen
@@ -0,0 +1,48 @@
+Schadenstypen:
+
+Es werden zwei Arten von Schadenstypen unterschieden:
+
+a) physikalische Schadenstypen
+
+   DT_BLUDGEON      Schlagschaden, z.B. Keulen
+   DT_EXPLOSION     Schaden durch eine Explosion
+   DT_PIERCE        Stechschaden, z.B. Lanzen
+   DT_RIP           Reissender Schade, z.B. Krallen
+   DT_SLASH         Schnittschaden, z.B. Schwerter
+   DT_SQUEEZE       Quetschschaden, z.B. Tentakel
+   DT_WHIP          Peitschenschaden, z.B. Peitschen
+
+   Alle physikalischen Schadenstypen stehen auch in dem Mapping
+   PHYSICAL_DAMAGE_TYPES.
+
+b) magische Schadenstypen
+
+   DT_ACID          Saeureschaden
+   DT_AIR           Luft(mangel)schaden
+   DT_COLD          Kaelteschaden
+   DT_FIRE          Feuerschaden
+   DT_HOLY          Heiliger Schaden
+   DT_LIGHTNING     Blitzschaden
+   DT_MAGIC         Genereller magischer Schaden
+   DT_POISON        Giftschaden
+   DT_SOUND         Laermschaden
+   DT_TERROR        Angstschaden
+   DT_UNHOLY        Unheiliger/daemonischer Schaden
+   DT_WATER         Wasserschaden
+
+   Alle magischen Schadenstypen stehen auch in dem Mapping
+   MAGICAL_DAMAGE_TYPES.
+
+Waffen duerfen maximal 50% homogenen magischen Schaden machen. 
+Die Summe der magischen Schaeden darf maximal 66% betragen. 
+Es _muss_ immer mindestens ein physikalischer Schaden gesetzt 
+sein. Der Anteil an physikalischem Schaden betraegt demzufolge
+immer mindestens 34%. Solche Waffen sind generell genehmigungs-
+pflichtig.
+
+Genehmigungspflichtig sind auch generell Waffen, die als Schadens-
+typ DT_TERROR, DT_SOUND, DT_AIR oder DT_SQUEEZE enthalten.
+
+Der Schadenstyp DT_EXPLOSION wird nicht mehr genehmigt.
+
+
diff --git a/doc/balance/techniken b/doc/balance/techniken
new file mode 100644
index 0000000..9c10eae
--- /dev/null
+++ b/doc/balance/techniken
@@ -0,0 +1,108 @@
+****************************************************************************
+* Dieser Text ist veraltet. Die Techniken werden von der Mudlib nicht      *
+* ausgewertet und momentan auch von keiner Gilde (Ausnahme: die Tanjian    *
+* zeigt sie an, tut aber nix damit.                                        *
+****************************************************************************
+----------------------------------------------------------------------------
+     P_TECHNIQUE: Techniken, mit denen Waffen eingesetzt werden koennen
+----------------------------------------------------------------------------
+
+TQ_THRASH - "Schlagtechnik"
+
+    Die vom Verstaendnis her einfachste Technik: Man nehme sich einen
+    Gegenstand,  der gross genug ist und halbwegs  brauchbare  Dichte 
+    besitzt - also nicht gerade federleicht  fuer seine Groesse ist - 
+    und haue drauf.  Egal ob Henkersaxt,  Stock,  Stuhl,  Bierflasche 
+    (ganz), Knueppel, Keule oder Bratpfanne,  das und aehnliches sind 
+    brauchbare  'Waffen',  um mit dieser Technik Erfolg zu haben.  Es 
+    ist eine schlagende Bewegung,  also das gewollte schwunghafte Zu-
+    sammenfuehren zweier Koerper, fuer gewoehnlich Waffe und Gegner.
+
+
+TQ_THRUST - "Stosstechnik"
+
+    Auch diese Technik erfreut sich zumindest in Kneipenschlaegereien
+    grosser Beliebtheit: Das Stossen.  Mit einem vorzugsweise spitzen
+    Gegenstand wie Speer, Dolch, Bierflasche (zerbrochen) oder Helle-
+    barde  wird dem Gegner ein Loch in den Leib  gestossen,  im Falle 
+    eines   stumpfen Gegenstandes wie z.B.  einem Kampfstock oder dem 
+    eigenen  Zeigefinger oder Knoechel zielt man auf Vitalpunkte oder
+    Weichteile und erzielt auch damit beeindruckende Ergebnisse.  Das
+    Gewicht der Waffe ist  weniger von Bedeutung,  da  der Akteur bei 
+    einem korrekt ausgefuehrtem seine eigene Masse mit einsetzt.
+
+
+TQ_STROKE - "Streichtechnik"
+
+    Ein etwas eigenwillig anmutender Begriff,  aber bei genauerer Be-
+    trachtung hat  diese Technik tatsaechlich etwas mit Streicheln zu
+    tun:  Die wichtigste Komponente der Bewegung fuehrt mehr oder we-
+    niger am  Gegner _entlang_ und nicht auf ihn zu.  Man stelle sich 
+    ein Schwert vor, das geschmeidig durch die Kehle eines Orks glei-
+    tet  und eine Menge Blut  freisetzt oder ein Pergamentblatt,  das
+    man aus der Hand gezogen bekommt  (und ebenfalls eine Menge  Blut
+    freisetzt).  In den allermeisten Faellen ist also eine moeglichst
+    scharfe Schneide im Spiel und, auch wenn schmerzhafte Erfahrungen
+    mit  Pargamentkanten gelegentlich gegenteiliges  vermuten lassen, 
+    je schaerfer die Schneide, desto weniger Druck in Richtung feind-
+    lichen  Zielkoerper  muss fuer  einen  "durchschneidenden Erfolg" 
+    ausgeuebt werden.
+
+
+TQ_WHIP - "Peitschtechnik"
+
+    Unter der Peitschtechnik wird nun alles zusammengefasst,  was den
+    Umgang mit beweglichen Elementen an der Waffe betrifft.  Egal, ob
+    Peitsche a la George Lucas, neunschwaenzige Katze, Manriki-Gusari
+    (eine halbmeter lange Kette mit Gewichten an den Enden), ein- bis
+    dreikoepfigem  beketteten Morgenstern oder gar Dreschflegel,  sie 
+    sind zumindestteilweise sehr unterschiedlich konzipiert (so fehlt
+    der  Peitsche am aeusseren Ende das Gewicht,  so dass jenes durch
+    eine gegenlaeufige Bewegung beschleunigt werden muss), haben aber
+    eines gemeinsam: Der Schaden wird durch ein ueber die normale Be-
+    wegung des Kaempfers  hinaus beschleunigtes Teil der Waffe verur-
+    sacht. Durch jene Beweglichkeit der  Waffe wird ein sehr  grosses 
+    Mass an Koordinationsvermoegen vom Kaempfer abverlangt.
+
+----------------------------------------------------------------------------
+
+Vermischtes
+
+    - Waffen koennen  sich fuer mehrere  Techniken eignen.  Mit einem
+      Katana, dem Schwert der Samurai, beispielsweise kann man in die
+      ungeschuetzten Partien des Gegners stechen,  dem Gegner mit der 
+      Streichtechnik tiefe Schnitte in die Unterseiten der Arme  (ein
+      durch typische Samurairuestungen schlecht geschuetzter Bereich)
+      zufuegen, und mit der beruehmten halben Koerperdrehung dem in-
+      zwischen taumelndem Kontrahenten den Kopf abschlagen. 
+
+    - Waffen koennen sich, obwohl von der gleichen Gattung, fuer ver-
+      schiedene Techniken eignen.  Ein spitzer Dolch mag eine stumpfe
+      Klinge haben  und nur fuer ausschliesslich stossende  Praktiken
+      zu gebrauchen zu sein, waehrend ein abgerundetes Kuechenmesser,
+      ebenfalls vom Typ "Zyn", fuer kantiges Zuschlagen und eventuell
+      auch fuer schnittige Streichtechniken herhalten kann.
+
+    - Je nach Zweck und Koennen wird die beste zu verwendende Technik 
+      variieren:  Wenn es um arme Grashalme geht,  wird die Sense mit 
+      schneidenden Bewegungen gefuehrt  (schoen in der  Milka-Werbung 
+      zu sehen,  fuer die, die es partout nicht glauben wollen),  bei 
+      einer Bauernrevolte mag das gute Stueck jedoch auch mit anderen 
+      Techniken effektiv (und vielleicht sogar effektiver) eingesetzt 
+      werden, wer weiss, wer war schon dabei...?  Selbst bei normalen
+      Waffen wie Schwertern  wuerde ein Ungeuebter  selten versuchen,  
+      mit Streichtechniken Schaden zu verursachen, denn das Zustechen 
+      ist schlicht einfacher.
+
+    - Es wird immer  besondere Waffen geben.  So  sind beispielsweise
+      das Zweililien und  die Hellebarde  beide dem Typ "Kzrok" (fuer
+      nicht-Trves: Stangenwaffen) zuzuordnen, die Techniken  weichen,
+      bedingt  durch die Vielseitigkeit  der Waffen,  jedoch von  der
+      Norm ab: Das Zweililien, an jedem  Ende eine lange und  scharfe
+      Klinge,  kann  ebenso  vielseitig  gehandhabt  werden  wie  ein 
+      Schwert,  waehrend die Hellebarde (eine Mischung aus  Lanze und
+      Axt) durch ihre unausgewogene Gewichtsverteilung  und dem damit
+      verbundenen Potenzial an Schwung schlichtweg DIE Waffe der Wahl 
+      fuer feige Zwerge ist:  Schwingen wie eine grosse  Axt und  den 
+      Gegner auf Distanz halten koennen.  Gut,  dass es keine  feigen 
+      Zwerge gibt ;o)
diff --git a/doc/balance/waffen b/doc/balance/waffen
new file mode 100644
index 0000000..44fa6e3
--- /dev/null
+++ b/doc/balance/waffen
@@ -0,0 +1,112 @@
+Allgemeines und generelles zu Waffen:
+------------------------------------
+
+   P_WC
+        Die WC sollte einigermassen "realistisch" gewaehlt werden. Die
+        Verantwortung hierfuer obliegt den jeweiligen RMs. Sie sollte
+        zwischen ca. 35 und 200 liegen. Auf jeden Fall sind die aktuellen
+        Genehmigungsgrenzen zu beachten. Sollte die WC diese Grenzen
+        ueberschreiten, unterliegt die Waffe ausser der Genehmigung durch
+        den RM der Beurteilung durch das Waffengremium.
+
+   P_NR_HANDS
+        Waffen ueber einer effektiven WC von 150 muessen zweihaendig sein.
+        Ausnahmen koennen unter Umstaenden genehmigt werden, zum Beispiel
+        wenn die Waffe schwer erreichbar oder zahlenmaessig begrenzt, eine
+        Questbelohnung etc. ist. Alle einhaendigen Waffen ueber WC 140 sind
+        in jedem Fall genehmigen zu lassen.
+
+        Messer muessen generell einhaendig sein!
+
+   P_WEIGHT 
+        Bitte realistisch halten. Damit ist *nicht* das RL-Gewicht
+        gemeint, sondern man sollte am besten vergleichbare Waffen des
+        MG als Massstab nutzen. Da hier z.T. gravierende Diskrepanzen 
+        bestehen, evtl. mal mehrere vergleichen. Die Verantwortung 
+        hierfuer obliegt den RMs.
+
+        Waffen mit einem Gewicht von ueber 4000 Gramm sollten normalerweise
+        auch zweihaendig sein oder muessen der Balance vorgelegt werden.
+	
+   P_VALUE
+      Wie bei P_WEIGHT sind die RMs gefragt: Augenmass zaehlt. Werte
+      ueber 10000 oder so sind zwar nett, aber sinnlos und unrealistisch.
+
+   P_DAM_TYPE
+      Jede Waffe, die aus physikalischem Material besteht (also faktisch
+      alles mit Hardware) *muss* einen physikalischen Schadenstyp haben.
+
+   P_WEAPON_TYPE
+      WT_SWORD, WT_AXE,  WT_CLUB, WT_SPEAR, WT_KNIFE, WT_AMMU, WT_MAGIC,
+      WT_WHIP, WT_STAFF, WT_MISC, WT_RANGED_WEAPON 
+
+   P_DAMAGED
+      Diese Property (sie gibt den Grad der Beschaedigung einer Waffe
+      oder Ruestung an) sollte man _nicht_ per Hand setzen. Stattdessen
+      ruft man in der Waffe Damage(int) auf. Ein positiver Parameter
+      bedeutet eine Beschaedigung, ein negativer Reparatur um diesen
+      Wert. In der Funktion werden alle notwendigen Bedingungen
+      geprueft (minimale/maximale Waffenklasse etc).
+
+   P_EFFECTIVE_WC
+      Hier kann die evtl durch eine HitFunc veraenderte WC angegeben
+      werden. Der Durchschnittswert soll da stehen. Die Kaempfergilde
+      kann das in gewissen Grenzen abschaetzen und es wird auch fuer
+      die Guete von Zusatzangriffen von Gilden genutzt.
+
+   P_EFFECTIVE_AC
+      Fuer Paradewaffen setzen. Werte unbedingt mit Boing absprechen!
+
+   P_NOBUY
+      Waffen ab WC 150 werden beim Verkauf im Laden zurueckbehalten. Es
+      sollte aber auch fuer Waffen, die HitFuncs enthalten, P_NOBUY
+      gesetzt werden.
+
+Spezialwaffen/Waffen mit Sonderfunktion
+
+   ** ALLE Waffen mit HitFunc oder entsprechender Fkt. muessen   **
+   ** genehmigt werden!                                          **
+
+   Solche Waffen muessen ueber ein P_INFO verfuegen und irgendwo in ihrer
+   Beschreibung oder im P_INFO mindestens eine Andeutung ueber die
+   Herkunft oder den Grund ihrer besonderen Faehigkeit haben.
+
+   Auch Spezialwaffen sollten nach Moeglichkeit nicht ueber eine
+   EFFECTIVE_WC von 200 hinausgehen. Der Return-Wert der HitFunc, sofern
+   er von 0 abweicht, MUSS per random() zurueckgegeben werden, da er ohne
+   weiteres random() auf die WC aufaddiert wird.
+
+   Zu beachten ist, dass man bei Waffen, die nur fuer NPCs mehr Schaden 
+   machen sollen, nicht (nur) ueber P_RACE prueft, ob der Benutzer ein 
+   solcher ist. Es ist denkbar, dass Spieler ihre Rasse temporaer ver-
+   aendern koennen. Waffen die nur dann besser zuschlagen, wenn es
+   keinem Spieler zuguten kommen kann (!interactive, nicht zueckbar 
+   durch Hilfs-NPC etc.), muessen nicht genehnigt werden.
+
+   Waffen, die Monster vergiften (also nicht nur P_DAM_TYPE DT_POISON
+   haben) sind zwar nicht grundsaetzlich verboten, aber doch unerwuenscht.
+   Sie sind auf jeden Fall genehmigungspflichtig. Ausserdem sollte die
+   Wahrscheinlichkeit einer Vergiftung pro Kampfrunde max. bei 1% liegen.
+
+Parierwaffen
+       
+   Parierwaffen sind Waffen, die die Verteidigung unterstuetzen.  
+   Eine Waffe wird als Parierwaffe verwendet, wenn die Property
+   P_PARRY gesetzt ist. Folgende Werte sind moeglich:
+       
+   PARRY_NOT     Die ist KEINE Parierwaffe (=default).
+       
+   PARRY_ONLY    Dies ist eine reine Parierwaffe.
+
+   PARRY_TOO     Diese Waffe wird sowohl als Parierwaffe als auch
+                 als Angriffswaffe benutzt
+       
+   Die Schutzwirkung der Parierwaffe wird wie bei Ruestungen ueber die
+   Property P_AC gesetzt. Ueber die Property P_DEFEND_FUNC kann wie
+   bei Ruestungen eine DefendFunc gesetzt werden.
+       
+   Waffen mit PARRY_ONLY unterliegen den gleichen P_AC-Grenzwerten
+   wie Ruestungen vom Typ AT_SHIELD. Waffen mit PARRY_TOO oder einer
+   DefendFunc muessen generell genehmigt werden.
+
+---------- LETZTE AENDERUNG: Humni, 2011-10-12
diff --git a/doc/beispiele/AddCmd/Einfuehrung.AddCmd.txt b/doc/beispiele/AddCmd/Einfuehrung.AddCmd.txt
new file mode 100644
index 0000000..eadf6f9
--- /dev/null
+++ b/doc/beispiele/AddCmd/Einfuehrung.AddCmd.txt
@@ -0,0 +1,174 @@
+Hallo MitmagierInnen *g*,
+
+Ok, dann gehts mal ein bischen zur Sache:
+
+/std/thing/commands.c wurde so erweitert, dass man auch komplexe Syntax
+direkt im AddCmd vorparsen kann.
+
+Dazu ein kurzes Beispiel:
+-------------------------
+
+In einem Objekt (ein Busch) findet sich folgende Syntaxdefinition.
+
+ AddCmd("pfluecke|ernte&fruechte|beeren&@ID","cmd_pfluecken",
+        "Was willst Du denn @verben?|Wo willst Du denn die Beeren @verben?");
+
+Der erste Parameter definiert die Syntax. Das Zeichen & trennt verschiedene
+zu parsende Items:
+
+1. pfluecke|ernte
+2. fruechte|beeren
+3. @ID
+
+Unter 1. finden sich die Verben - das sind die gleichen, die man in der
+alten Version auch belegen konnte. Die Regel reagiert also auf "pfluecke"
+oder auf "ernte".
+
+Alle weiteren Regeln muessen erfuellt werden, damit der zweite Parameter
+(die Funktion) aufgerufen wird. @ID steht dabei fuer die ID des Objektes,
+in dem das AddCmd steht. Hier also der Busch.
+
+Dazu einige Beispiele:
+
+a) > pfluecke beeren
+ -> erfuellt 1 und 2. Aber nicht 3. => Fehlermeldung.
+
+b) > ernte von busch
+ -> erfuellt 1 und 3, jedoch 2 nicht. => Fehlermeldung.
+
+c) > pfluecke fruechte von busch
+ -> erfuellt 1, 2 und 3 -> busch->cmd_pfluecken() wird aufgerufen. Das "von"
+    ist Fuellwerk. Davon kann beliebig viel im String sein. Sie werden 
+    ignoriert.
+    Es sind also auch unsinnige Syntaxe richtig, solange der String die 
+    Items erufellt.
+
+Im Fall c) wird das Verhalten des Busches durch die Funktion "cmd_pfluecken"
+definiert, wie auch in der alten Version von AddCmd.
+
+Was passiert aber in den Faellen a) und b)? Dafuer ist der dritte
+Parameter da:
+  "Was willst Du denn @VERBen?|Wo willst Du denn die Beeren @VERBen?");
+
+Hier sind zwei Fehlermeldungen, durch | getrennt, definiert:
+
+x) Was willst Du denn @VERBen?
+y) Wo willst Du denn die Beeren @VERBen?
+
+Erst wird geprueft, ob 2. erfuellt ist. Falls nicht, gibt es Fehlermeldung x)
+Dann wird auf 3. geprueft. Ist das nicht erfuellt (aber 2. schon) gibt es
+Fehlermeldung y).
+
+Im Fall a sind 1 und 2 erfuellt. Demnach wird y) ausgegeben. @VERB wird
+dabei durch das benutzte Verb ersetzt (das abschliessende en, bzw e wird
+abgeschnitten):
+ Wo willst Du denn die Beeren pfluecken?
+
+Im Fall b ist 1 erufellt, 2 aber schon nicht. Daher gibt es Fehlermeldung
+x). Auf 3. wird nicht mehr geprueft.
+ Was willst Du denn ernten?
+
+Wie schon erwaehnt erfuellt c) alle Bedingungen und es gibt keine Ausgabe -
+Statt dessen kann man das Pfluecken in der Funktion abhandeln.
+
+In den Faellen 1 und 2 wird die Fehlermeldung ueber notify_fail()
+abgehandelt. Ergo wird hier anderen Befehlen von anderen Objekten noch
+eine Chance gegeben. Gleiches gilt fuer die Funktion cmd_pfluecken(), wenn
+deren Rueckgabewert 0 ist. Auch hier gibt es die Analogie zum alten AddCmd.
+
+Gibt cmd_pfluecken() einen Wert ungleich 0 zurueck, wird die Suche nach
+der richtigen Syntax danach abgebrochen, so dass auch kein anderes Objekt
+mehr gefragt wird (wie gehabt).
+
+Das ist auch fuer Forscherpunkte wichtig. FP werden generell nur bei einem
+Rueckgabewert ungleich 0 vergeben.
+
+Eine kleine Erweiterung der Beispielsyntax:
+-------------------------------------------
+
+ AddCmd("pfluecke|ernte&fruechte|beeren&@ID@\impossible",0,
+  "Was willst Du denn @VERBen?|Wo willst Du denn die Beeren @VERBen?|"
+  "Du pflueckst ein paar Beeren und isst sie auf.^@WER isst ein paar
+  Beeren.");
+
+Eine neue Regel:
+
+4. \impossible
+
+Und eine neue Fehlermeldung:
+z) Du pflueckst ein paar Beeren und isst sie auf.^@WER isst ein paar Beeren.
+
+Zur Regel:
+
+Die Regel ist nicht erfuellbar, da Spieler das \i nicht erzeugen
+koennen. Zwangslaeufig gibt es auch keine Funktion, die aufgerufen werden
+koennte.
+
+Dafuer gibt es eine Fehlermeldung, die ein neues Element enthaelt. Das
+^. Wird diese Meldung ausgegeben ist das genau wie ein return 1 in der
+Funktion. Die Syntax wird als richtig anerkannt. (Es kann hierfuer also
+auch FP geben).
+
+Der Text vor dem ^ geht an den Spieler, alles dahinter geht an die Spieler
+im Raum. Steht hinter dem ^ nichts, gibt es keine Raummeldung.
+
+Auf diese Weise kann man leicht ein Raumkommando erstellen, dass nur
+Textausgaben macht, aber keine Funktionalitaet enthaelt. Es ist keine
+eigenstaendige Funktion mit irgendwelchem eigenen Parsing mehr noetig.
+
+Das @WER wird durch this_player()->Name() ersetzt, so dass man auch einen
+Persoenlichen bezug in den Meldungen herstellen kann.
+
+Abwaertskompatibel
+------------------
+
+Die Erweiterungen von AddCmd erlauben ein einfacheres Erstellen von
+Standard-Kommandos, ohne dass man sich mit dem Parsen in Funktionen
+beschaeftigen muss.
+
+Die Aenderung ist vollstaendig abwaertskompatibel. Wer sich also sagt,
+das das alles viel zu kompliziert sei, kann weiterhin:
+
+ AddCmd(({"pfluecke","ernte"}),"cmd_pfluecken");
+
+benutzen. Das Verhalten ist haargenau das selbe wie bisher. Dementsprechend
+ist auch kaum Aufwand beim Einpflegen dieser Aenderung notwendig.
+
+Zur Beachtung
+-------------
+
+Ueberall, wo direkt auf P_COMMANDS zugegriffen wird, kann es prinzipiell
+zu Problemen kommen, da sich die Struktur des Mappings und der Zugriff
+darauf geaendert hat.
+
+Im Folgeartikel findet sich eine Liste mit allen Objekten, die das machen. In
+den oeffentlichen Verzeichnissen werde ich mich mit den Magiern in Verbindung
+setzen oder selbst kontrollieren, ob Aenderungen notwendig sind.
+
+Objekte in den Players-Verzeichnissen werde ich nur in Ausnahmefaellen
+anpassen. Zur Erinnerung: Angeschlossenes gehoert nicht nach /players/.
+
+Der Code ist auf Kompatibilitaet mit dem alten System ausgelegt, dennoch
+gibt es ein paar Aenderungen. Zum Beispiel ist P_COMMANDS keine echte
+Property mehr sondern eine lokale Variable. Demzufolge wird P_COMMANDS
+bei "xprop" nicht mehr angezeigt. Die Schnittstelle wird durch _set_
+und _query_funktionen realisiert. Die Mappings werden _immer_ als Kopien
+rausgegeben, so dass man damit nicht versehentlich Unsinn machen kann.
+
+Schlusswort
+-----------
+
+Dieser Artikel stellt nur eine Einleitung in die Aenderung und deren
+Moeglichkeiten dar und ist keinesfalls vollstaendig. Wer mehr darueber wissen
+will, ist eingeladen, sich die Manpage zu "AddCmd" und zu den Beispielen
+"AddCmd_bsp" anzuschauen.
+
+Die Seiten sind aus dem Regenbogen "geliehen" und werden in den kommenden
+Tagen noch auf die Beduerfnisse des Morgengrauen angepasst.
+
+Mein Dank geht an Gloinson, der die Idee hatte, die Anpassungen vorzunehmen
+und Migration des Codes ins MorgenGrauen uebernommen hat.
+
+Falls nun noch Fragen sind, nur zu! :)
+
+V*,
diff --git a/doc/beispiele/AddCmd/busch.c b/doc/beispiele/AddCmd/busch.c
new file mode 100644
index 0000000..da3c5b3
--- /dev/null
+++ b/doc/beispiele/AddCmd/busch.c
@@ -0,0 +1,58 @@
+inherit "/std/thing";
+#include <properties.h>
+#include <moving.h>
+#include <language.h>
+
+#pragma strict_types,save_types,rtt_checks
+
+protected void create()
+{
+   ::create();
+
+   SetProp(P_GENDER, NEUTER);
+   SetProp(P_NAME, "Gebuesch");
+   SetProp(P_SHORT,"Ein Gebuesch");
+   SetProp(P_LONG,"Du stehst vor einem gaanz normalen Gebuesch. Es traegt "
+                  "Fruechte. Und eventuell\nkann man darin etwas finden.\n");
+   SetProp(P_NOGET,"Es ist festgewachsen, eventuell kann man es ausgraben?\n");
+
+   SetProp(P_WEIGHT,5000);
+   SetProp(P_SIZE,100);
+
+   AddId(({"busch","gebuesch"}));
+
+   AddDetail(({"fruechte","frucht"}),
+     "Es scheinen Beeren zu sein. Vielleicht kannst Du sie pfluecken?\n");
+   AddDetail("beeren",
+     "Pflueck sie doch, vielleicht bringt das ja was.\n");
+
+   // Nur wenn die Syntax erfuellt ist, wird cmd_pfluecken() aufgerufen.
+   // "pfluecke beeren von busch" etc.
+   AddCmd("pfluecke|ernte&fruechte|beeren&@ID","cmd_pfluecken",
+          "Was willst Du denn @verben?|Wo willst Du denn die Beeren @verben?");
+
+   // suchen gibt nur eine Meldung aus. Dafuer braucht man kuenftig keine
+   // Funktionen mehr.
+   AddCmd("such|suche|durchsuch|durchsuche&@ID&\nimpossible",0, 
+          "Wo willst Du @VERBen?|Du durchsuchst das Gebuesch, findest aber nichts.^"
+          "@WER1 durchsucht ein Gebuesch, findet aber nichts.");
+
+   // Graben geht eh nicht. Daher nur Fehlermeldungen.
+   // Das ^ sagt, dass hier ein return1 zurueckgegeben wird. Es gibt aber keine 
+   // Raummeldung.
+   AddCmd("grab|grabe&@ID&aus@\nimpossible",0,
+          "Was willst Du graben?|Du willst das Gebuesch ausgraben?|"
+          "Die Wurzeln scheinen tief zu rechen. Das wird nichts.^");
+}
+
+int cmd_pfluecken(string arg, mixed *param)
+{
+    object obj;
+    obj=clone_object(__DIR__"obst");
+    write("Verwundert pflueckst Du "+(obj->name())+" vom Busch. Komisch.\n");
+
+    // Das hier ist ein Beispiel fuer AddCmd, daher mach ich mir nich 
+    // die Muehe das richtig zu machen. Is eh nur fuer Magier!
+    obj->move(this_player(),M_GET|M_NOCHECK);
+    return 1;
+}
diff --git a/doc/beispiele/AddCmd/obst.c b/doc/beispiele/AddCmd/obst.c
new file mode 100644
index 0000000..8efb471
--- /dev/null
+++ b/doc/beispiele/AddCmd/obst.c
@@ -0,0 +1,232 @@
+/* Hinweis zu diesem Beispielobjekt: Lebensmittel lassen sich besser von
+ * /std/food ableiten, das bringt viele Funktionalitaeten mit, die man sonst
+ * muehsam selber basteln muss.
+ */
+
+inherit "/std/thing";
+
+#include <moving.h>
+#include <properties.h>
+#include <wizlevels.h>
+
+#define SAETTIGUNG 2
+#define HEILUNG 20
+#define EAT_DELAY 1200 // 20 Minuten
+
+#define BS78(x) break_string(x,78)
+
+protected void create()
+{
+  ::create();
+
+  // Gemeinsamer Teil des create
+  AddId("obst");
+  SetProp( P_VALUE, 60+random(10) );
+
+  // AddCmd( ({"iss","esse"}), "act_essen");  
+  // new style AddCmd
+  AddCmd( "iss|esse&@ID","act_essen","Was willst Du denn essen?");
+
+  // Nach ca. 10 Minuten resetet das Obst, im Reset wird es destructet, 
+  // so spare ich call_outs
+  set_next_reset(600);
+
+  // Name, ID, Gender, Desc und Gewicht sind Abhaengig von der Obstart
+  switch (random(11)){
+  default:
+    SetProp( P_GENDER, MALE );
+    SetProp( P_NAME, "Apfel" );
+    AddId( "apfel" );
+    SetProp( P_SHORT, "Ein Apfel" );
+    SetProp( P_LONG, BS78(
+      "Ein saftiger Apfel. Dir laeuft das Wasser im Munde zusammen."
+    ));
+    SetProp( P_WEIGHT, 80 );
+    break;
+  case 1:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Birne" );
+    AddId( "birne" );
+    SetProp( P_SHORT, "Eine Birne" );
+    SetProp( P_LONG, BS78(
+      "Eine koestliche, reife Birne. Die ist sicher lecker."
+    ));
+    SetProp( P_WEIGHT, 90 );
+    break;
+  case 2:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Banane" );
+    AddId( "banane" );
+    SetProp( P_SHORT, "Eine Banane" );
+    SetProp( P_LONG, BS78(
+      "Die Banane sieht wirklich lecker aus, am besten gleich essen."
+    ));
+    SetProp( P_WEIGHT, 110 );
+    break;  
+  case 3:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Kiwi" );
+    AddId( "kiwi" );
+    SetProp( P_SHORT, "Eine Kiwi" );
+    SetProp( P_LONG, BS78(
+      "Klein und gruen, aber mit leckeren Innenleben. Yam yam."
+    ));
+    SetProp( P_WEIGHT, 50 );
+    break;  
+  case 4:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Erdbeere" );
+    AddId( "erdbeere" );
+    SetProp( P_SHORT, "Eine Erdbeere" );
+    SetProp( P_LONG, BS78(
+      "Eine ueberdurchschnittlich grosse Erdbeere. Sie "
+      "ist sicher suess und saftig."
+    ));
+    SetProp( P_WEIGHT, 20 );
+    break;  
+  case 5:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Kirsche" );
+    AddId( "kirsche" );
+    SetProp( P_SHORT, "Eine Kirsche" );
+    SetProp( P_LONG, BS78(
+      "Zwar nur klein ist diese Kirsche, aber so dunkel wie sie "
+      "aussieht, ist sie sicher total suess und lecker."
+    ));
+    SetProp( P_WEIGHT, 15 );
+    break;  
+  case 6:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Orange" );
+    AddId( "orange" );
+    SetProp( P_SHORT, "Eine Orange" );
+    SetProp( P_LONG, BS78(
+      "Eine grosse, gelbe Orange. Eine von diesen suessen, die sich so "
+      "leicht schaelen lassen und keine Zicken machen, so wie Saftorangen."
+    ));
+    SetProp( P_WEIGHT, 90 );
+    break;  
+  case 7:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Mandarine" );
+    AddId( "mandarine" );
+    SetProp( P_SHORT, "Eine Mandarine" );
+    SetProp( P_LONG, BS78(
+      "Suess und saftig und gesund. So muss das Essen im Paradies "
+      "gewesen sein."
+    ));
+    SetProp( P_WEIGHT, 60 );
+    break;  
+  case 8:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Zitrone" );
+    AddId( "zitrone" );
+    SetProp( P_SHORT, "Eine Zitrone" );
+    SetProp( P_LONG, BS78(
+      "Sauer, sauer und nochmals sauer. Aber ultralecker. Na, sabberst Du "
+      "schon auf die Tastatur?"
+    ));
+    SetProp( P_WEIGHT, 60 );
+    break;  
+  case 9:
+    SetProp( P_GENDER, MALE );
+    SetProp( P_NAME, "Granatapfel" );
+    AddId( "granatapfel" );
+    SetProp( P_SHORT, "Ein Granatapfel" );
+    SetProp( P_LONG, BS78(
+      "Er ist zwar etwas schwieriger, den zu essen, aber der Aufwand "
+      "lohnt sich."
+    ));
+    SetProp( P_WEIGHT, 90 );
+    break;  
+  case 10:
+    SetProp( P_GENDER, FEMALE );
+    SetProp( P_NAME, "Pflaume" );
+    AddId( "pflaume" );
+    SetProp( P_SHORT, "Eine Pflaume" );
+    SetProp( P_LONG, BS78(
+      "Eine grosse, blaue Pflaume. Lass sie Dir doch schmecken."
+    ));
+    SetProp( P_WEIGHT, 20 );
+    break;
+  }
+}
+
+void reset()
+{
+  object env = environment(this_object());
+
+  if (env) {
+    if (query_once_interactive(env)){
+      // Mein Env is ein User
+      tell_object(env, BS78(
+        capitalize(this_object()->name(WER))+" verschwindet mit einem "+
+        "\"PLOPP\" aus deinem Inventar. Da scheint Magie im Spiel zu sein."
+      ));
+    } else if (sizeof(all_inventory(env)&users())){
+      // In meinem Environment sind User (Es ist ein Raum)
+      tell_room(env, BS78(
+        capitalize(this_object()->name(WER))+" verschwindet mit einem "+
+        "\"PLOPP\". Da scheint Magie im Spiel zu sein."
+      ));
+    }
+  }
+
+  // Objekt zerstoeren
+  remove(1);
+}
+
+static int act_essen(string args)
+{
+    // Nur ein Demo-Objekt
+    if (!IS_LEARNING(this_player()))
+    {
+      write("Schwups, nun ist @@name@@ verschwunden. War wohl eine Illusion.");
+      remove(1);
+    }
+
+    // Der Syntaxtest ist unnoetig, der ist schon im new style
+    // AddCmd() eingebaut.
+
+    // Wenn das Objekt ein Environment hat (hoff ich doch)
+    // und das Environment nicht this_player() ist, 
+    // hat der Spieler das Obst nich im Inv - das geht doch nicht ...
+    if (environment(this_object()) && (environment(this_object()) != this_player()) )
+    {
+      write(BS78(
+        "Du solltest "+ this_object()->name(WER,1) + " erstmal nehmen."
+      ));
+      return 1;
+    }
+
+    // DEBUG ("Satt?");
+    if (this_player()->eat_food(SAETTIGUNG))
+    {
+      // DEBUG("Noe!");
+      if (this_player()->check_and_update_timed_key(EAT_DELAY,"vanion_zach_obst")==-1)
+      {
+        write(BS78(
+          "Du isst genuesslich "+this_object()->name(WEN,0)+
+          ". Du fuehlst Dich gestaerkt."
+        ));
+        say(BS78(
+          this_player()->name()+" isst mit vollem Genuss "+this_object()->name(WEN,0)+". "
+          "Dir laeuft das Wasser im Munde zusammen."
+        ));
+        // Heilen und aufessen :)
+        this_player()->heal_self(HEILUNG);
+      }
+      else { // if (check_and_update_timed_key())
+        // Wenn es noch zu frueh ist, wieder welches zu essen
+        // Keine Heilung, aber Saettigung
+        write(BS78(
+          "Du solltest "+this_object()->name(WEN,1)+" lieber jemandem geben, "
+          "den Du magst, statt alles selbst zu futtern, findest Du nicht? "
+          "Deine Gier hat Dir jetzt nur einen vollen Bauch und ein schlechtes "
+          "Gewissen bescheert."
+        ));
+      } // end if (check_and_update_timed_key())
+      if (!remove()) destruct(this_object());
+    } // end of eat_food
+    return 1;
+}
diff --git a/doc/beispiele/Praxis-Kurs/README b/doc/beispiele/Praxis-Kurs/README
new file mode 100644
index 0000000..99a8dd0
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/README
@@ -0,0 +1,16 @@
+In diesem Verzeichnis befindet sich ein kleiner "Praxis LPC-Kurs".
+Im Prinzip sind es verschiedene gut dokumentierte LPC-Objekte die
+aufeinander aufbauen und in denen alles notwendige erklaert wird.
+Wer also schon mal irgendwo programmiert hat und sich nur an die
+LPC-Umgebung gewoehnen muss, fuer den ist dieser Mini-Kurs sicher
+genau das richtige. Fuer jemand der noch nie programmiert hat ist
+dieser Kurs alleine aber sicher nicht geeignet um programmieren zu
+lernen. Die Files sollten in der Alphabetischer Reihenfolge und da
+die Files aufeinander aufbauen, auch vollstaendig durchgegangen
+werden.
+Bei dem Verzeichnis zauberwald handelt es sich um ein kleines und
+dadurch ueberschaubares Gebiet von mir, das nicht eine Ansammlung
+von AddDetails darstellt, sondern auch komplexere Funktionen wie
+Virtual Compiler oder Heilstellen enthaelt.
+
+                                             Padreic
diff --git a/doc/beispiele/Praxis-Kurs/hello_world.c b/doc/beispiele/Praxis-Kurs/hello_world.c
new file mode 100644
index 0000000..8109e06
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/hello_world.c
@@ -0,0 +1,37 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Auch wenn dieses Objekt noch keinerlei tieferen Sinn hat, so ist es doch
+// bereits ein vollstaendiges Objekt (bereits eine einzige Funktion reicht
+//  fuer ein LPC-Object aus).
+
+// Die 3 Funktionen in diesem Objekt haben darueber hinaus noch eine
+// ganz besondere Bedeutung. Jede dieser 3 Funktionen wird vom Game-Driver
+// im laufenden Betrieb bei besonderen Anlaessen aufgerufen.
+
+protected void create()
+// Diese Funktion wird aufgerufen sobald dieses Objekt geclont wird.
+{
+   // gibt an den Spieler der dieses Objekt clont eine Meldung aus.
+   tell_object(this_player(), "Hello World!\n");
+}
+
+void init()
+// Diese Funktion wird aufgerufen, sobald ein Spieler oder ein NPC in
+// Reichweite dieses Objektes kommt: Also entweder wenn ein Lebewesen in
+// das Objekt bewegt wird oder umgekehrt oder wenn ein Lebewesen in die
+// Umgebung eines Objektes kommt oder umgekehrt.
+{
+   // gibt wieder eine Meldung an den Spieler aus...
+   tell_object(this_player(), ("Hello again :).\n");
+}
+
+void reset()
+// Diese Funktion wird im beruemten Reset aufgerufen, den Du ja sicher auch
+// schon als Spieler kennengelernt hast (Also alle 30-60 Minuten).
+// Ausnahme: Wenn das Objekt laengere Zeit mit keinem anderen Objekt
+// kommuniziert hat, wird diese Funktion vorlaeufig nicht mehr aufgerufen!
+{
+  // Hier kann man nun auch irgendetwas machen. Ein write("..") haette
+  // hier jedoch keinen Effekt, da kein Spieler diese Funktion ausgeloest
+  // hat und daher nicht bekannt ist, an wen die Meldung denn gehen soll...
+}
diff --git a/doc/beispiele/Praxis-Kurs/juwelen.c b/doc/beispiele/Praxis-Kurs/juwelen.c
new file mode 100644
index 0000000..c1070a6
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/juwelen.c
@@ -0,0 +1,66 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Dieses ist ein erstes Objekt das so oder aehnlich tatsaechlich im
+// MorgenGrauen vorkommen koennte.
+
+// Jedes Objekt im MorgenGrauen braucht bereits eine solche Vielzahl von
+// Standardfunktionen, dass es ziemlich unmoeglich ist, diese alle in jedem
+// Objekt zu definieren. Daher "erbt" man diese Funktionen von einem
+// Standardobjekt.
+// "Erben" bedeutet hierbei, das man auf alle Funktionen, die bereits im
+// Standardobjekt definiert sind, zugreifen kann.
+//
+// Die folgende Zeile erklaert, dass man das Objekt an der Position
+//  /std/thing.c "erben" moechte.
+inherit "/std/thing";
+
+
+// Die Funktion folgender Zeile kann man sich recht einfach wie folgt
+// vorstellen: Wenn der Game-Driver dieses Objekt hier compiliert, dann
+// tut er so, als wuerde die Datei /sys/properties.h genau an dieser Stelle
+// hier im Code stehen.
+//
+// Die Datei properties.h beinhaltet einfach nur haufenweise Defines fuer
+// die haufenweise Properties.
+//
+// Anmerkung: Alle Defines in dieser Datei starten uebrigens mit einem 'P_'.
+// Am Besten solltest Du einfach mal kurz in /doc/properties.h reinsehn
+// und ein bisschen rumlesen
+//  (keine Angst, die muss man nicht alle kennen :).
+#include <properties.h>
+
+protected void create()
+{
+  // Die Funktion create() wurde naemlich bereits in /std/thing.c
+  // beschrieben, kann aber nicht mehr ueber create() aufgerufen werden, da
+  // dann ja wieder diese Funktion hier aufgerufen wuerde
+  // (wodurch wir dann eine Endlos-Rekursion haetten).
+  // Kurzschreibweise waere ::create(); wenn man nur von einem Objekt erbt.
+  thing::create(); // oder auch einfach ::create();
+
+  // Auch diese Funktion wurde aus /std/thing geerbt.
+  // SetProp() ist eine der wichtigsten Funktionen ueberhaupt, wenn es darum
+  // geht, ein Objekt zu beschreiben. Mit dieser Funktion kannst Du naemlich
+  // zahlreiche Eigenschaften (engl. properties) des Objektes festlegen.
+  SetProp(P_SHORT, "Einige wertvolle Juwelen");      // die Kurzbeschreibung
+  SetProp(P_LONG, "Die Juwelen glitzern verlockend.\n"); // Langbeschreibung
+  SetProp(P_NAME, "Juwelen"); // der eigentliche Name
+  SetProp(P_NAME_ADJ, "wertvoll"); // das Adjektiv vor dem Namen
+  SetProp(P_GENDER, FEMALE); // Geschlecht (kann auch MALE oder NEUTER sein)
+  SetProp(P_WEIGHT, 5000); // dieses Objekt wiegt 5kg
+  SetProp(P_VALUE, 10000); // das Objekt ist insgesamt 10000 Muenzen Wert
+  
+  // Mit dieser Funktion kann man eine id angeben, ueber die das Objekt
+  // ansprechbar ist.
+  // Anmerkung: Auch diese Funktion ist wieder von std/thing geerbt, im
+  //   folgenden werde ich dies aber nicht mehr bei jeder Funktion extra
+  //   angeben. Wenn nicht anders angegeben, handelt es sich ab jetzt
+  //   naemlich _immer_ um ererbte Funktionen.
+  AddId("juwelen");
+  
+  // In diesem Fall benoetigt man noch ein weiteres Adjektiv, da man das
+  // Objekt ja auch mit wertvolle Juwelen ansprechen koennen moechte.
+  // z.B.: unt wertvolle juwelen
+  //       gib wertvolle juwelen an padreic
+  AddAdjective("wertvolle");
+}
diff --git a/doc/beispiele/Praxis-Kurs/los.c b/doc/beispiele/Praxis-Kurs/los.c
new file mode 100644
index 0000000..f3b41e8
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/los.c
@@ -0,0 +1,118 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include <properties.h> // wieder unsere allgemeinen Propertys
+#include <moving.h>     // einige Defines zum Bewegen von Objekten (s.u.)
+
+inherit "/std/thing";
+
+protected void create()
+{
+  ::create();
+   // Objekt ueber seine Properties beschreiben...
+   SetProp(P_SHORT, "Ein Rubbellos");
+   SetProp(P_LONG,
+    "Du kannst dieses Los aufrubbeln um zu sehen, ob Du einen grossen "
+    "Schatz\ngewonnen hast.\n");
+   SetProp(P_NAME, "Rubbellos");
+   SetProp(P_ARTICLE, 1); // ist eigentlich bereits Defaultwert
+   SetProp(P_GENDER, NEUTER);
+   SetProp(P_VALUE, 1000);
+   SetProp(P_WEIGHT, 500);
+   SetProp(P_INFO, "Deine Gewinnchancen bei diesen Losen sind nicht "
+                   "sonderlich gut.\n");
+   SetProp(P_MAGIC, 0); // (einfach nur, um mal alle Properties zu benutzen)
+   AddId("los"); // noch eine id angeben...
+
+   // Mit Hilfe dieser neuen wichtigen Funktion ist es moeglich, Befehle zu
+   // definieren, ueber die man irgendetwas ausloesen koennen soll:
+   // Und zwar wird sobald ein Spieler den Befehl rubble oder rubbel
+   // benutzt, die Funktion _rubbeln() hier im Objekt aufgerufen. Da diese
+   // Funktion bisher ja noch nicht definiert ist, muss diese natuerlich
+   // auch noch programmiert werden.
+   AddCmd(({"rubble", "rubbel"}), "_rubbeln");
+}
+
+// Diese Funktion sieht gleich um einiges komplexer aus als die Funktionen
+// create(), init() und reset(), die bisher benutzt wurden.
+// Das static am Anfang erklaert nur, dass diese Funktion nicht von aussen,
+// sondern nur von innerhalb des Objektes aufgerufen werden kann.
+// Das "int" anstelle des "void" bedeutet, dass die Funktionen ein Ergebnis
+// zurueckliefert. Da diese Funktion in Verbindung mit AddCmd() benutzt
+// wird, hat dieser Rueckgabewert auch eine besondere Bedeutung:
+//   Eine 1 bedeutet, dass der Befehl fertig abgearbeitet wurde.
+//   Eine 0 bedeutet, das Objekt konnte mit dem Befehl nichts anfangen, der
+//    Gamedriver muss also noch in weiteren Objekten anfragen, die der
+//    Spieler bei sich traegt.
+// Der String 'str', den die Funktion als Parameter uebergeben bekommt,
+// enthaelt das, was der Spieler ausser dem eigentlichen Verb eingegeben
+// hat (Woerter wie 'und', 'ein', 'der', 'die', 'das' ... werden hierbei
+//  zuvor herausgefiltert)
+// Bsp.:   rubbel los      ->  _rubbeln("los")
+//         rubbel katze    ->  _rubbeln("katze")
+//         rubbel los auf  ->  _rubbeln("los auf")
+public int _rubbeln(string str)
+{
+   // Die Funktion notify_fail() ist wieder eine Funktion des Gamedrivers:
+   // Und zwar ist es moeglich hier eine Meldung anzugeben, die anstelle
+   // eines "Wie bitte?" kommt, falls kein Objekt den Befehl richtig
+   // abgearbeitet hat.
+   notify_fail("Syntax: rubbel los auf\n"); // eigentlich efun::notify_fail()
+
+   // Wenn der uebergebene String ungleich "los auf" ist, dann fuehlt sich
+   // das Objekt nicht angesprochen, kann das Verb also nicht komplett
+   // abarbeiten und gibt deshalb eine 0 zurueck.
+   if (str!="los auf") return 0;
+
+   // Auch die Funktion random() ist wieder eine Funktion des Gamedriver:
+   // Und zwar liefert sie eine ganzzahlige Zufallszahl zwischen 0 und n-1
+   //  (wobei n die uebergebene Zahl ist). In diesem Fall also zwischen
+   // 0 und 99.
+   if (random(100)<92) { // sollte diese Zahl < 92 sein, dann tue Folgendes:
+     write("Du rubbelst das Los auf. Leider war es jedoch nur eine Niete.\n"
+          +"Veraergert laesst Du das Los deshalb fallen.\n");
+   }
+   else { // sollte die Zahl nicht < 92 gewesen sein, dann tue Folgendes:
+     object ob; // bereitstellen einer Hilfsvariablen
+
+     write("Du rubbelst das Los auf und strahlst vor Freude. Es war der "
+          +"absolute Hauptgewinn.\nSofort kommt ein Bote herein und "
+          +"ueberreicht Dir Deinen Gewinn.\n");
+
+     // Mit clone_object() kann man ein beliebiges Objekt Clonen, indem man
+     // einfach den entsprechenden Filenamen als Parameter uebergibt.
+     ob=clone_object("/doc/beispiele/Praxis-Kurs/juwelen");
+
+     // Nun kommen gleich 3 neue Dinge auf einmal...
+     // Mit -> wird eine Funktion in einem anderen Objekt aufgerufen
+     //  (alternativ auch: call_other(ob,move,this_player(), M_GET); )
+     // Die Funktion, die hierbei aufgerufen werden soll, heisst move().
+     // Diese Funktion ist in allen Objekten definiert, die /std/thing erben.
+     // Somit koennen wir also fest davon ausgehen, dass sie auch in unseren
+     // Juwelen vorhanden ist.
+     // this_player() ist eine sehr wichtige Gamedriver-Funktion, da sie
+     // uns das Lebewesen zurueckliefert, das gerade aktiv durch einen Befehl
+     // den aktuellen Funktionsaufruf gestartet hat.
+     // M_GET ist lediglich ein Define, das in moving.h definiert ist.
+     // Naeheres hierzu findet man auch in <man move>.
+     ob->move(this_player(), M_GET);
+     // ACHTUNG: um dieses Beispiel simpel zu halten, wird hier darauf
+     // verzichtet, zu pruefen, ob diese Bewegung ueberhaupt funktioniert
+     // hat. Normalerweise muss man in diesem Fall (misslungene Bewegung)
+     // eine Fehlerbehandlung durchfuehren (z.B. ob wieder entfernen,
+     // Meldung an den Spieler ausgeben).
+   }
+
+   // Die Funktion say() gibt an alle Spieler im Raum des aktiven Spielers
+   // eine Nachricht aus, aber nicht an den betroffenen Spieler selbst!
+   // Die Funktion Name(), die hier im Spieler aufgerufen wird, wertet
+   // dessen Propertie P_NAME aus und dekliniert den Namen im angegebenen
+   // Fall.
+   say(this_player()->Name(WER)+" rubbelt ein Los auf.\n");
+
+   // Und nun soll sich das Objekt selbst entfernen (zerstoeren).
+   remove();
+
+   // Da der Befehl ja komplett abgearbeitet wurde, geben wir eine 1
+   // zurueck.
+   return 1;
+}
diff --git a/doc/beispiele/Praxis-Kurs/milch.c b/doc/beispiele/Praxis-Kurs/milch.c
new file mode 100644
index 0000000..66b6173
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/milch.c
@@ -0,0 +1,91 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Anmerkung: Heutzutage gibt es fuer Lebensmittel (bzw. alle Dinge, die
+// man essen oder trinken kann) ein Standardobjekt namens /std/food,
+// welches viele Funktionalitaet mitbringt, die man ansonsten selber
+// muehsam basteln muss. Die Verwendung ist dringend empfohlen.
+
+#include <properties.h> // wieder unsere allgemeinen Properties
+
+inherit "/std/thing";
+
+// globale Variable, die angibt, wie voll die Flasche ist. Es sind 5
+// Portionen enthalten.
+int menge = 5;
+
+protected void create()
+{
+   ::create();
+   // Objekt ueber seine Properties beschreiben...
+   // P_SHORT und P_LONG werden direkt als Funktion implementiert (s.u.)
+   SetProp(P_NAME, "Milchflasche");
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_VALUE, 80);
+   SetProp(P_WEIGHT, 1000);
+   AddId(({"flasche", "milchflasche"}));
+   AddCmd(({"trink", "trinke"}), "_trinken");
+}
+
+// Anstelle von P_SHORT Kurzbeschreibung ueber Funktion short().
+// Dies ist nicht immer moeglich, da nicht zwangslaeufig zu jeder Propertie
+// eine gleichnamige Funktion existiert.
+// Es ist allerdings noch sog. Querymethoden (siehe dazu <man QueryProp> und
+// <man Query> bei Bedarf).
+public string short()
+{
+   string str;
+   switch(menge) {
+     case 1: str="Eine fast leere Milchflasche.\n"; break;
+     case 2: str="Eine bald leere Milchflasche.\n"; break;
+     case 3: str="Eine halbvolle Milchflasche.\n";  break;
+     case 4: str="Eine fast volle Milchflasche.\n"; break;
+     case 5: str="Eine volle Milchflasche.\n";      break;
+     default: str="Eine leere Milchflasche.\n";
+   }
+   return str;
+}
+
+public string long()
+{
+   if (menge>1)
+      return "Eine Flasche mit leckerer Vollmilch.\n";
+   else
+      return "Die Milchflasche ist bald leider schon alle, Du solltest "
+             "Dich vielleicht mal\nnach Nachschub umsehn.\n";
+}
+
+public int _trinken(string str)
+{
+   notify_fail("Syntax: trinke aus milchflasche\n");
+
+   // Falls die ersten vier Zeichen in dem uebergebenen String ungleich
+   // "aus " sind, dann fuehlt sich das Objekt nicht angesprochen, kann das
+   // Verb also nicht komplett abarbeiten und gibt deshalb eine 0 zurueck.
+   if (str[0..3]!="aus ") return 0;
+
+   // Ich benutze nun alles ab dem vierten Zeichen und pruefe, ob sich das
+   // Objekt davon angesprochen fuehlt. Hierzu dient die Funktion id().
+   // Grosser Vorteil: Uebersichtlich und spaeteres Ergaenzen von Ids bzw.
+   // Adjektiven geht sehr einfach und erspart lange if()-Abfragen.
+   if ( !id(str[4..]) ) return 0;
+
+   if (menge<=0) {
+     write("Die Milchflasche ist leider schon leer :(.\n");
+   }
+   else {
+     // drink_soft() ist eine Funktion, die in allen Lebewesen im
+     // Morgengrauen definiert ist und ueber die man sowohl Abfragen als
+     // auch hochsetzen von P_DRINK vornehmen sollte.
+     if (this_player()->drink_soft(10)) {
+
+       // heal_self() ist auch in allen Lebewesen definiert und heilt bei
+       // dem Lebewesen Lebens- und Konzentrationspunkte.
+       this_player()->heal_self(10);
+       write("Genuesslich trinkst Du einen Schluck Milch.\n");
+       say(this_player()->Name(WER)+" trinkt einen Schluck Vollmilch,\n");
+       menge--;
+     }
+     else write("Soviel kannst Du leider nicht mehr trinken.\n");
+   }
+   return 1;
+}
diff --git a/doc/beispiele/Praxis-Kurs/npc.c b/doc/beispiele/Praxis-Kurs/npc.c
new file mode 100644
index 0000000..39a54fd
--- /dev/null
+++ b/doc/beispiele/Praxis-Kurs/npc.c
@@ -0,0 +1,115 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include <properties.h>
+#include <attributes.h>
+#include <combat.h>
+#include <guard.h>
+#include <moving.h>
+#include <new_skills.h>
+
+// Ein NPC wird nicht von /std/thing direkt geerbt, sondern von /std/npc.
+// Da /std/npc aber seinerseits wieder von /std/thing erbt, sind im NPC auch
+// saemtliche Funktionen definiert, die bereits in /std/thing enthalten sind.
+inherit "/std/npc";
+
+void create()
+{
+   ::create();
+   // create_default_npc() setzt schon mal einige wichtige Properties wie
+   // P_ATTRIBUTES automatisch...
+   create_default_npc(20, 300);
+
+   // Keine Angst: Es muessen keineswegs immer alle diese Properties benutzt
+   // werden, auch wenn ich sie jetzt einmal alle angebe, um eine Uebersicht
+   // zu geben, was man alles ueber Properties steuern kann...
+   SetProp(P_SHORT, "Ein fieser Ork");
+   SetProp(P_LONG, "Der Ork schaut Dich grimmig an.\n");
+   SetProp(P_NAME, "Ork");
+   SetProp(P_NAME_ADJ, "fies");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_MAGIC, 0);
+   SetProp(P_MATERIAL, MAT_MISC_LIVING);
+
+   // nun komen einige wirklich neue Properties
+   SetProp(P_INFO, "Der Ork ist ein ganz gemeiner... :)\n");
+   SetProp(P_ALIGN, -500); // Alignment des Gegners
+   SetProp(P_RACE, "Ork"); // Rasse des NPCs
+   SetProp(P_AGGRESSIVE, 1); // greift aggressiv jeden an
+   SetProp(P_ATTRIBUTES, ([A_INT:5, A_DEX:10, A_STR:25, A_CON:10]));
+   SetProp(P_SIZE, 134); // Groesse in cm
+   SetProp(P_MAX_HP, 300); // max. Lebenspunkte
+   SetProp(P_HP, 300); // Lebenspunkte
+   SetProp(P_MAX_SP, 200); // max. Magiepunkte
+   SetProp(P_SP, 200); // Magiepunkte
+   SetProp(P_BODY, 80); // Grundruestungsschutz des Koerpers
+   SetProp(P_MAX_HANDS, 2); // kaempft mit zwei Haenden...
+   SetProp(P_HANDS, ({" mit blossen Haenden", 150}));
+   SetProp(P_NOMAGIC, 20); // 20% Resistenz gegen Spells
+   SetProp(P_GUARD, 20); // Der NPC laesst sich ggf. weglocken
+   SetProp(P_NO_GLOBAL_ATTACK, 0); // wird von 'toete alles' erfasst
+   SetProp(P_NO_ATTACK, 0);  // kann man den NPC ueberhaupt angreifen?
+   SetProp(P_FRIEND, 0); // soll der NPC in Spells als Freund erfasst
+                         // werden?
+   SetProp(P_RESISTANCE, DT_FIRE);  // Resistenzen
+   SetProp(P_VULNERABILITY, DT_HOLY);  // Empfindlichkeiten
+   SetProp(P_FOOD, 0);
+   SetProp(P_MAX_FOOD, 100);
+   SetProp(P_DRINK, 0);
+   SetProp(P_MAX_DRINK, 100);
+   SetProp(P_ALCOHOL, 0);
+   SetProp(P_MAX_ALCOHOL, 100);
+   SetProp(P_XP, QueryProp(P_MAX_HP)*QueryProp(P_HANDS)[0]*5); // Erfahrung
+   SetProp(P_MURDER_MSG, "Ich komme doch eh wieder!\n"); // Moerdermeldung
+   SetProp(P_KILL_NAME, "Ein fieser Testork"); // noetig falls != P_NAME
+   SetProp(P_KILL_MSG, "Das kommt davon wenn man sich mit mir anlegt.\n");
+   SetProp(P_DIE_MSG, "Der Ork schreit ein letztes mal laut auf.\n");
+   SetProp(P_NOCORPSE, 0); // soll der NPC eine Leiche hinterlassen?
+   SetProp(P_HEAL, -10); // wieviel LP bekommt man beim Leichen essen...
+
+   // der Ork ist Mitglied der Abenteurergilde...
+   SetProp(P_GUILD, "abenteurer"); // in die Abenteuergilde mit ihm...
+   SetProp(P_GUILD_LEVEL, 20);
+   ModifySkill("feuerball",([SI_SKILLABILITY:10000]),1,"abenteurer");
+
+   // nun noch eine andere Art zu zaubern...
+   SetProp(P_SPELLRATE, 10);
+   AddSpell(100, 400,
+     "Der Ork tritt Dich einmal feste zwischen die Beine.\n",
+     "Der Ork tritt @WEN einmal feste zwischen die Beine.\n", DT_BLUDGEON);
+
+   // was soll der NPC mit ihm gegebenen Gegenstaenden machen...
+   SetProp(P_REJECT, ({REJECT_DROP, "Damit kann ich nichts anfangen.\n"}));
+
+   // und natuerlich auch noch eine id fuer den ork
+   AddId("ork");
+
+   // Der NPC hat immer einige Juwelen bei sich.
+   AddItem("/doc/beispiele/Praxis-Kurs/juwelen");
+}
+
+// Diese Funktion wird aufgerufen, wenn man einen Gegenstand bekommt...
+public void give_notify(object ob)
+{
+   if (ob->id("milchflasche")) // Milch annehmen und einen Spruch aufsagen
+     write("Der Ork sagt: Ohh.... Danke fuer die leckere Milch.\n");
+   else ::give_notify(ob); // Gegenstand fallen lassen
+}
+
+// Diese Funktion wird aufgerufen, wenn uns jemand im Kampf Schaden zufuegen
+// moechte...
+public varargs int Defend(int dam, mixed dam_type, mixed spell, object enemy)
+{
+   if (!random(4))
+     write("Der Ork weicht Deinem Angriff geschickt aus.\n");
+   else
+     return ::Defend(dam, dam_type, spell, enemy);
+}
+
+public void Attack(object enemy)
+{
+  // das Kommando 'Feuerball' eingeben. Da der NPC Mitglied der
+  // Abenteurergilde ist (s.o.), spricht er also den Spell, falls er genug
+  // Magiepunkt dafuer hat.
+  if (!random(3)) command_me("feuerball");
+  ::Attack(enemy);
+}
diff --git a/doc/beispiele/fernwaffen/kurzbogen.c b/doc/beispiele/fernwaffen/kurzbogen.c
new file mode 100644
index 0000000..93623e5
--- /dev/null
+++ b/doc/beispiele/fernwaffen/kurzbogen.c
@@ -0,0 +1,32 @@
+inherit "/std/ranged_weapon";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  if (!clonep(this_object())) return;
+  ::create();
+
+  SetProp(P_SHORT, "Ein Kurzbogen");
+  SetProp(P_INFO,
+    "Die Syntax lautet: schiesse <geschoss> auf <ziel>\n");
+  SetProp(P_NAME, "Kurzbogen");
+  SetProp(P_LONG, break_string(
+    "Mit diesem Kurzbogen kann man sicher nicht weit schiessen."));
+  SetProp(P_MATERIAL, MAT_MISC_WOOD);
+
+  AddId("kurzbogen");
+  SetProp(P_GENDER, MALE);
+  SetProp(P_WEIGHT, 800);
+  SetProp(P_VALUE, 300);
+
+  SetProp(P_WC, 10);
+  SetProp(P_DAM_TYPE, DT_BLUDGEON);
+
+  SetProp(P_SHOOTING_WC, 60);
+  SetProp(P_NR_HANDS, 2);
+  SetProp(P_WEAPON_TYPE, WT_RANGED_WEAPON);
+  SetProp(P_AMMUNITION, MUN_ARROW);
+  SetProp(P_STRETCH_TIME, 1);
+  SetProp(P_RANGE, 10);
+}
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/langbogen.c b/doc/beispiele/fernwaffen/langbogen.c
new file mode 100644
index 0000000..7956dd3
--- /dev/null
+++ b/doc/beispiele/fernwaffen/langbogen.c
@@ -0,0 +1,32 @@
+inherit "/std/ranged_weapon";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  if (!clonep(this_object())) return;
+  ::create();
+
+  SetProp(P_SHORT, "Ein Langbogen");
+  SetProp(P_INFO,
+    "Die Syntax lautet: schiesse <geschoss> auf <ziel>\n");
+  SetProp(P_NAME, "Langbogen");
+  SetProp(P_LONG, break_string(
+    "Mit diesem Langbogen kann man bestimmt hervorragend weit schiessen."));
+  SetProp(P_MATERIAL, MAT_MISC_WOOD);
+
+  AddId("langbogen");
+  SetProp(P_GENDER, MALE);
+  SetProp(P_WEIGHT, 800);
+  SetProp(P_VALUE, 300);
+
+  SetProp(P_WC, 30);
+  SetProp(P_DAM_TYPE, DT_BLUDGEON);
+
+  SetProp(P_SHOOTING_WC, 120);
+  SetProp(P_NR_HANDS, 2);
+  SetProp(P_WEAPON_TYPE, WT_RANGED_WEAPON);
+  SetProp(P_AMMUNITION, MUN_ARROW);
+  SetProp(P_STRETCH_TIME, 2);
+  SetProp(P_RANGE, 30);
+}
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/npc.c b/doc/beispiele/fernwaffen/npc.c
new file mode 100644
index 0000000..3544d44
--- /dev/null
+++ b/doc/beispiele/fernwaffen/npc.c
@@ -0,0 +1,29 @@
+inherit "/std/npc";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  ::create();
+  AddId(({"npc", "gegner", "ziel"}));
+  SetProp(P_NAME, "Ziel");
+  SetProp(P_GENDER, NEUTER);
+  SetProp(P_SHORT, "Ein Ziel");
+
+  SetProp(P_HP, 1000);
+  SetProp(P_BODY, 100);
+}
+
+varargs int Defend(int dam, string* dam_type, mixed spell, object enemy) {
+  int predam = dam;
+  int result = ::Defend(dam, &dam_type, &spell, enemy);
+  
+  string str = break_string(sprintf(
+    "Die Zielscheibe sagt: %d Schaden rein und fuer %d getroffen.",
+    predam, result), 78);
+
+  tell_room(load_object(__PATH__(0)"zielraum"), str);
+  tell_room(load_object(__PATH__(0)"schussraum"), str);
+
+  return result;
+}
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/path.h b/doc/beispiele/fernwaffen/path.h
new file mode 100644
index 0000000..d284140
--- /dev/null
+++ b/doc/beispiele/fernwaffen/path.h
@@ -0,0 +1,3 @@
+#pragma rtt_checks, save_types
+#pragma pedantic,  range_check
+#pragma warn_empty_casts, warn_missing_return, warn_function_inconsistent
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/pfeile.c b/doc/beispiele/fernwaffen/pfeile.c
new file mode 100644
index 0000000..f4b11a3
--- /dev/null
+++ b/doc/beispiele/fernwaffen/pfeile.c
@@ -0,0 +1,41 @@
+inherit "/std/unit";
+
+#include "./path.h"
+#include <properties.h>
+#include <class.h>
+
+void create() {
+  if (!clonep(this_object())) return;
+  ::create();
+
+  SetProp(P_NAME, ({"Pfeil", "Pfeile"}) );
+  SetProp(P_LONG, break_string(
+    "Ein paar einfache Holzpfeile.", 78));
+  SetProp(P_GENDER, MALE);
+  SetProp(P_AMOUNT, 1);
+  SetProp(P_SHOOTING_WC, 40);
+  SetProp(P_DAM_TYPE, ({DT_PIERCE}));
+  SetProp(P_WEAPON_TYPE, WT_AMMU);
+  SetProp(P_MATERIAL, MAT_MISC_WOOD);
+
+  SetGramsPerUnits(120,1);
+  SetCoinsPerUnits(25,1);
+
+  AddId(MUN_ARROW);
+  AddSingularId("pfeil");
+  AddPluralId("pfeile");
+  AddClass(CL_AMMUNITION);
+
+  SetProp(P_HIT_FUNC, this_object());
+}
+
+int HitFunc(object enemy) {
+  if(!random(5)) {
+    tell_object(environment(), break_string(
+      "Der Pfeil schnurrt vom Bogen und dabei splittert das Holz "
+      "etwas. Gratiswiderhaken, das ist ja toll!", 78));
+    return 20;
+  }
+
+  return 0;
+}
\ No newline at end of file
diff --git a/doc/beispiele/fernwaffen/schussraum.c b/doc/beispiele/fernwaffen/schussraum.c
new file mode 100644
index 0000000..79179c9
--- /dev/null
+++ b/doc/beispiele/fernwaffen/schussraum.c
@@ -0,0 +1,34 @@
+inherit "/std/room";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  ::create();
+
+  SetProp(P_LIGHT, 1);
+  SetProp(P_INT_SHORT, "Auf einem Baum");
+  SetProp(P_INT_LONG, break_string(
+    "Du hockst auf einem Baum und kannst auf die Lichtung unter Dir sehen. "
+    "'schau runter' hilft sicherlich, Ziele auszumachen."));
+
+  AddDetail("runter", function string { 
+                        return __PATH__(0)"zielraum"->int_long(this_player());
+                      });
+
+  AddItem(__PATH__(0)"langbogen", REFRESH_REMOVE);
+  AddItem(__PATH__(0)"kurzbogen", REFRESH_REMOVE);
+  AddItem(__PATH__(0)"pfeile", REFRESH_REMOVE, ([P_AMOUNT: 20]));
+
+  AddExit("zielraum", __PATH__(0)"zielraum");
+  load_object(__PATH__(0)"zielraum");
+
+  SetProp(P_TARGET_AREA, __PATH__(0)"zielraum"); // anderer Raum beschiessbar
+  SetProp(P_SHOOTING_AREA, 15);                  // 15 Entfernung
+}
+
+// nur wegen des P_NEVER_CLEAN im Zielraum und nur hier in doc relevant
+public varargs int remove(int silent) {
+  __PATH__(0)"zielraum"->remove();
+  return ::remove();
+}
diff --git a/doc/beispiele/fernwaffen/zielraum.c b/doc/beispiele/fernwaffen/zielraum.c
new file mode 100644
index 0000000..6177032
--- /dev/null
+++ b/doc/beispiele/fernwaffen/zielraum.c
@@ -0,0 +1,19 @@
+inherit "/std/room";
+
+#include "./path.h"
+#include <properties.h>
+
+void create() {
+  ::create();
+
+  SetProp(P_LIGHT, 1);
+  SetProp(P_INT_SHORT, "Auf einer Lichtung");
+  SetProp(P_INT_LONG, break_string(
+    "Auf dieser Lichtung steht ein Baum, der verdaechtig viele Aeste hat, "
+    "von denen man auf die Lichtung gut sehen kann."));
+  SetProp(P_NEVER_CLEAN, 1); // damit der Raum auch da bleibt
+
+  AddItem(__PATH__(0)"npc", REFRESH_REMOVE);
+
+  AddExit("schussraum", __PATH__(0)"schussraum");
+}
diff --git a/doc/beispiele/food/banane.c b/doc/beispiele/food/banane.c
new file mode 100644
index 0000000..8882f4f
--- /dev/null
+++ b/doc/beispiele/food/banane.c
@@ -0,0 +1,114 @@
+/*
+Beispiel fuer eine Banane, die in einem Haps weg ist,
+aber eine Schale hat, die uebrig bleibt und genau wie die
+komplette Banane vergammelt und vergeht.
+*/
+
+#include <food.h>
+
+inherit "/std/food";
+
+string _query_long() {
+  string m = "Du haeltst ";
+  if (is_not_empty()) {
+    m += "eine Banane in der Hand.";
+    if (!is_bad())
+      m += " Sie ist schoen gelb und ohne braune Flecken.";
+    else
+      m += " Sie ist total braun und schon ganz matschig.";
+
+  } else {
+    m += "eine Bananenschale in der Hand.";
+    if (is_bad())
+      m += " Sie ist ganz verschimmelt.";
+  }
+  return break_string(m);
+}
+
+void create() {
+  if (!clonep(this_object())) {
+    set_next_reset(-1);
+    return;
+  }
+  ::create();
+
+  SetProp(P_SHORT,"Eine schoene reife Banane");
+  SetProp(P_NAME, "Banane");
+  SetProp(P_GENDER,FEMALE);
+  SetProp(P_VALUE,20); // ohne Schale
+  SetProp(P_WEIGHT,50); // ohne Schale
+  // SetProp(P_POTION,1); // ist eh Standard
+  SetProp(P_CONSUME_MSG,
+    "@WER2 schaelt eine Banane und isst sie genuesslich.");
+  SetProp(P_EATER_MSG,
+    "Du schaelst eine Banane und isst sie genuesslich.");
+  SetProp(P_BAD_MSG,
+    "Die Banane wird ganz matschig und schlecht.");
+  SetProp(P_REMOVE_MSG,
+    "Die Banane ist so verschimmelt, dass Du sie entsorgst.");
+  SetProp(P_EMPTY_MSG,
+    "Aber das ist doch nur eine BananenSCHALE, die willst Du nicht essen!");
+
+  SetProp(P_MATERIAL,([MAT_MISC_PLANT:100]));
+
+  SetProp(P_EMPTY_PROPS, ([
+    P_SHORT:"Eine Bananenschale",
+    P_NAME:"Bananenschale",
+    P_EMPTY_IDS:({"schale","bananenschale","banane"}),
+    P_VALUE:5, // Wert der Bananenschale
+    P_WEIGHT:5  // Gewicht der Bananenschale
+  ]));
+
+  //SetProp(P_RESET_LIFETIME,1); // ist eh Standard
+  SetProp(P_DESTROY_BAD,300); // verdorbene Bananen verschwinden nach 5 Min
+
+  SetProp(P_FOOD,50); // Fuellgrad der Banane
+  SetProp(P_HP,5);
+  SetProp(P_SP,5);
+
+  AddId(({"banane"}));
+
+}
+
+// Der Behaelter vergammelt auch
+public int make_destroy() {
+  if (!::make_destroy()) {
+    return remove(1);
+  }
+  return 1;
+}
+
+public int make_empty() {
+  SetProp(P_BAD_MSG,
+    "Die Bananenschale wird ganz schimmlig.");
+  SetProp(P_REMOVE_MSG,
+    "Die Bananenschale zersetzt sich vollstaendig.");
+  return ::make_empty();
+}
+
+// parent methode immer aufrufen und pruefen!!
+void make_bad() {
+  if (!::make_bad()) {
+    if (is_not_empty()) {
+      SetProp(P_SHORT,"Eine matschige Banane");
+      AddAdjective(({"matschige","matschigen"}));
+      SetProp(P_EATER_MSG,"Du lutschst die matschige Banane aus ihrer"
+        "Schale. Baeh, die schmeckt ueberhaupt nicht mehr.");
+      SetProp(P_CONSUME_MSG,
+        "@WER2 lutscht eine matschige Banane aus ihrer Schale.");
+      // Die Schale ist dann natuerlich auch vergammelt
+      SetProp(P_EMPTY_PROPS, ([
+        P_SHORT:"Eine verschimmelte Bananenschale",
+        P_NAME:"Bananenschale",
+        P_EMPTY_IDS:({"schale","bananenschale","banane"}),
+        P_EMPTY_ADJ:({"verschimmelte","verschimmelten"}),
+        P_VALUE:5, // Wert der Bananenschale
+        P_WEIGHT:5  // Gewicht der Bananenschale
+      ]));
+    } else {
+      message(P_BAD_MSG);
+      SetProp(P_SHORT,"Eine verschimmelte Bananenschale");
+      AddAdjective(({"verschimmelte","verschimmelten"}));
+    }
+  }
+}
diff --git a/doc/beispiele/food/wasserflasche.c b/doc/beispiele/food/wasserflasche.c
new file mode 100644
index 0000000..3c62c13
--- /dev/null
+++ b/doc/beispiele/food/wasserflasche.c
@@ -0,0 +1,92 @@
+/*
+Beispiel fuer ein tragbares Getraenk in einer Flasche.
+*/
+
+#include <food.h>
+
+inherit "/std/food";
+
+string _query_long() {
+  string m = "Du siehst eine Glasflasche,";
+  if (is_not_empty()) {
+    m += " in der sich Wasser befindet.";
+    if (!is_bad())
+      m += " Es ist glasklar und sieht irgendwie verlockend aus.";
+    else
+      m += " Es ist truebe und sieht nicht gerade verlockend aus.";
+
+    m += " Die Flasche ist ";
+    switch (to_int((QueryProp(P_PORTIONS)-1)/2.5)) {
+      case 0:
+        m += "fast leer.";
+        break;
+      case 1:
+        m += "halb voll.";
+        break;
+      case 2:
+        m += "fast voll.";
+        break;
+      case 3:
+        m += "voll.";
+        break;
+      default:
+        m += "nicht leer.";
+    }
+  } else {
+    m += " in der frueher mal Wasser war.";
+  }
+  return break_string(m);
+}
+
+void create() {
+  if (!clonep(this_object())) {
+    set_next_reset(-1);
+    return;
+  }
+  ::create();
+
+  SetProp(P_SHORT,"Eine Flasche mit Wasser");
+  SetProp(P_NAME, "Wasserflasche");
+  SetProp(P_GENDER,FEMALE);
+  SetProp(P_VALUE,5); // pro Portion (ohne Flasche)
+  SetProp(P_WEIGHT,50); // pro Portion (ohne Flasche)
+  SetProp(P_PORTIONS,10);
+  SetProp(P_DESTROY_BAD,0); // verdorbenes Wasser wird nicht zerstoert
+  SetProp(P_CONSUME_MSG,
+    "@WER2 trinkt aus einer Flasche. Wasser laeuft ueber @WENQPPNS2 Kinn.");
+  SetProp(P_EATER_MSG,
+    "Du trinkst Wasser aus der Flasche. Etwas laeuft Dir ueber das Kinn.");
+  SetProp(P_BAD_MSG,
+    "Das Wasser in der Flasche wird truebe.");
+
+  SetProp(P_MATERIAL,([MAT_GLASS:15, MAT_WATER:85]));
+
+  SetProp(P_EMPTY_PROPS, ([
+    P_SHORT:"Eine leere Flasche",
+    P_NAME:"Flasche",
+    P_EMPTY_IDS:({"flasche"}),
+    P_EMPTY_ADJ:({"leere","leeren"}),
+    P_MATERIAL:([MAT_GLASS:100]),
+    P_VALUE:5, // Wert der Flasche ohne Wasser
+    P_WEIGHT:20  // Gewicht der Flasche ohne Wasser
+  ]));
+
+  SetProp(P_RESET_LIFETIME,3); // 3 Resets, ehe das Wasser truebe wird
+  SetProp(P_DRINK,50); // Fuellgrad pro Schluck
+  SetProp(P_DISTRIBUTION,10); // Punkte Heilung pro Heartbeat
+  SetProp(P_HP,30); // pro Schluck
+  SetProp(P_SP,30); // pro Schluck
+
+  AddId(({"flasche","wasserflasche","wasser"}));
+  AddAdjective(({"volle","vollen"}));
+
+}
+
+// parent methode immer aufrufen und pruefen!!
+void make_bad() {
+  if (!::make_bad() && is_not_empty()) {
+    // die Trinkmeldung aendern wir mal
+    SetProp(P_EATER_MSG,"Du trinkst truebes Wasser aus der Flasche. "
+      "Das war wohl nicht so gut. Dir wird ganz uebel!");
+  }
+}
\ No newline at end of file
diff --git a/doc/beispiele/kekse/keks.c b/doc/beispiele/kekse/keks.c
new file mode 100644
index 0000000..f4a2ab5
--- /dev/null
+++ b/doc/beispiele/kekse/keks.c
@@ -0,0 +1,28 @@
+/* Einfaches Beispiel zur Demonstration von Vererbung.
+   ACHTUNG: Dieses Beispiel stellt _kein_ sinnvolles Lebensmittelobjekt dar.
+            Hierfuer sollte /std/food verwendet werden, siehe auch
+            /doc/beispiele/food/
+*/
+
+#include <properties.h>
+#include <moving.h>
+inherit "/std/thing";
+
+protected void create() {
+  ::create();
+  SetProp(P_NAME, "Keks");
+  SetProp(P_GENDER, MALE);
+  AddId(({"keks"}));
+  AddCmd("iss&@ID", "action_essen", "Was willst du essen?");
+}
+
+public int action_essen(string cmd) {
+  if(this_player()->eat_food(1, 0, 
+                            "Du bekommst "+QueryPronoun(WEN)+
+                            " nicht mehr hineingestopft.\n")>0) {
+    write("Du isst "+name(WEN,1)+".\n");
+    say(this_player()->Name(WER)+" isst "+name(WEN)+".\n");
+    remove(1);
+  }
+  return 1;
+}
diff --git a/doc/beispiele/kekse/kruemelkeks.c b/doc/beispiele/kekse/kruemelkeks.c
new file mode 100644
index 0000000..2fee85a
--- /dev/null
+++ b/doc/beispiele/kekse/kruemelkeks.c
@@ -0,0 +1,15 @@
+/* Einfaches Beispiel zur Demonstration von Vererbung.
+   ACHTUNG: Dieses Beispiel stellt _kein_ sinnvolles Lebensmittelobjekt dar.
+            Hierfuer sollte /std/food verwendet werden, siehe auch
+            /doc/beispiele/food/
+*/
+
+#include <properties.h>
+inherit __DIR__"keks";
+
+varargs int remove(int silent) {
+  if(!silent && living(environment()))
+    tell_object(environment(), Name(WER,1)+
+                               " kruemelt ein letztes Mal.\n");
+  return ::remove(silent);
+}
diff --git a/doc/beispiele/master/access_rights.c b/doc/beispiele/master/access_rights.c
new file mode 100644
index 0000000..367e909
--- /dev/null
+++ b/doc/beispiele/master/access_rights.c
@@ -0,0 +1,13 @@
+// Wenn ein Verzeichnis fuer ein Objekt nicht schreibbar ist, kann der
+// Besitzer des Verzeichnisses eine Datei access_rights anlegen, die
+// dieses Recht vergibt.
+// Da DOC hier eigentlich nicht schreiben darf, war das hier noetig.
+// Ein Magier wird das fuer die eigenen Verz. idR nicht brauchen.
+
+int access_rights( string user, string pfad ) {
+  if( user=="DOC" && pfad=="opferstocklog" ) {
+  	// DOC darf opferstocklog schreiben
+	return 1;
+  }
+  return 0;
+}
diff --git a/doc/beispiele/master/opferstock.c b/doc/beispiele/master/opferstock.c
new file mode 100644
index 0000000..048a461
--- /dev/null
+++ b/doc/beispiele/master/opferstock.c
@@ -0,0 +1,142 @@
+#include <defines.h>
+#include <properties.h>
+#include <moving.h>
+//
+// By Rumata@MorgenGrauen 3/99
+//
+// Beispieldatei fuer die Benutzung von Mastern und Klienten.
+//
+// Ich gehe hier nicht auf die "normalen" Funktionen ein.
+
+inherit "/std/thing";
+
+#define OS_MASTER "/doc/beispiele/master/opferstockmaster"
+
+void create()
+{
+	if(IS_BLUE(ME)) return;
+	::create();
+	SetProp( P_NAME, "Opferstock" );
+	SetProp( P_GENDER, MALE );
+	SetProp( P_VALUE, 1000 + random(2000) );
+	AddId( ({"stock","inschrift","opferstock"}) );
+	SetProp( P_SHORT, "In einer Ecke steht ein Opferstock" );
+	SetProp( P_LONG,
+		"Der Opferstock besteht aus solidem Holz. Vorne auf dem Kasten ist eine\n"
+	+	"Inschrift zu sehen, die Du lesen kannst.\n"
+	+	"@@contents@@"
+	);
+	SetProp( P_READ_MSG,
+		">>>>>>>>>>>> Fuer den Aufbau eines Orkwaisenhauses <<<<<<<<<<<<\n"
+	+	"In den letzten Jahren wurden immer wieder unschuldige Orkkinder\n"
+	+	"durch brutale Abenteurer ihrer Eltern beraubt. Bitte unter-\n"
+	+	"stuetzen Sie mit einer kleinen Spende den Aufbau eines Waisen-\n"
+	+	"hauses fuer diese bemitleidenswerten Kreaturen.\n"
+	);
+	AddDetail( "holz", "Solide und so gut wie unzerbrechlich.\n" );
+	SetProp( P_NOGET,
+		"Der Opferstock ist nicht ohne Grund am Boden festgenagelt.\n" );
+	AddCmd( "spende","spende" );
+	AddCmd( ({"stecke","steck"}), "stecken" );
+	AddCmd( "oeffne","oeffne" );
+	AddCmd( ({"brich","breche"}),"breche" );
+}
+
+contents()
+{
+	switch(QueryProp(P_VALUE))
+	{
+	case 0:
+		return "Er ist leer.\n";
+	case 1:
+		return "Er enthaelt:\nEine Muenze.\n";
+	default:
+		return "Er enthaelt:\n"+QueryProp(P_VALUE)+" Muenzen.\n";
+	}
+}
+
+stecken( str )
+{
+	string was, worein;
+	if( !str || sscanf(str,"%s in %s",was,worein)!=2 || !id(worein) ) return 0;
+	return spende( str );
+}
+
+spende( str )
+{
+	int anz, newAl;
+	string arg;
+	
+	notify_fail( "Wieviele Muenzen willst Du denn spenden?\n" );
+	if( !str || str=="" )
+		return 0;
+	if( sscanf(str,"%d %s",anz,arg)== 2 )
+		str = arg;
+	else
+	{
+		if( str=="eine muenze" || str=="ein goldstueck" )
+		{
+			anz = 1;
+			str = "muenze";
+		}
+		else
+			return 0;
+	}
+	if( anz<=0 || 
+		member(({"muenze","goldstueck","muenzen","goldstuecke"}), str)==-1
+	)
+		return 0;
+	if( anz>PL->QueryMoney() )
+	{
+		write( "So viel Geld hast Du nicht.\n" );
+		return 1;
+	}
+	PL->AddMoney(-anz);
+	SetProp(P_VALUE,QueryProp(P_VALUE)+anz);
+
+	// Hier wird der Master aufgerufen, der das Alignment der Spieler
+	// dann aendert.
+	if( OS_MASTER->addAlignment( PL, anz/3 ) > 0 ) {
+		// Eigentlich könnte man hier auch die Meldung ausgeben, aber
+		// der Spieler soll den Unterschied zwischen Alignment geaendert
+		// unt Alignment nicht geaendert sehen koennen.
+	}
+	write( "Du hast wahrhaft das Gefuehl, etwas Gutes getan zu haben.\n" );
+
+	say( capitalize(PL->name(WER))+" spendet "+anz
+		+ ((anz==1)?" Muenze.\n":" Muenzen.\n") );
+	return 1;
+}
+
+oeffne( str )
+{
+	int newAl;
+	
+	notify_fail( "WAS willst Du oeffnen?\n" );
+	if( !id(str) )
+		return 0;
+	OS_MASTER->addAlignment( PL, -30 );
+	write( "Allein schon der Gedanke....\n" );
+	return 1;
+}
+
+breche( str )
+{
+	string arg;
+	notify_fail( "WAS willst Du aufbrechen?\n" );
+	if( !str )
+		return 0;
+	if( sscanf(str,"%s auf",arg)==1 )
+		str = arg;
+	if( !id(str) )
+		return 0;
+	write( "Dein lautes Getoese ruft einen Teufel herbei, der Dich gleich\n"
+	+	"mit in die Hoelle nimmt.\n"
+	);
+	say( capitalize(PL->name(WER))+" versucht, den Opferstock aufzubrechen.\n"
+	+ "Gleich erscheint ein Teufel, um "+PL->QueryPronoun(WEN)
+	+	" in die Hoelle zu reissen.\n" );
+	PL->move("/d/unterwelt/raeume/qualenraum",M_GO,"zur Hoelle","faehrt");
+	OS_MASTER->addAlignment( PL, -200 );
+	return 1;
+}
diff --git a/doc/beispiele/master/opferstockmaster.c b/doc/beispiele/master/opferstockmaster.c
new file mode 100644
index 0000000..33a081f
--- /dev/null
+++ b/doc/beispiele/master/opferstockmaster.c
@@ -0,0 +1,120 @@
+/*
+ * Beispieldatei fuer einen einfachen Master, der Spielerdaten auch
+ * ueber reboots, resets und updates hinweg speichert, und gleichzeitg
+ * dafuer sorgt, dass die Datenmengen nicht immer groesser werden.
+ *
+ * By: Rumata@MorgenGrauen 3/99
+ *
+ */
+
+// Von diesem Objekt gibt es keine Clones, sondern nur die Blueprint.
+// Das Konstrukt if( clonep(ME) ) destruct(this_object()); ist dadurch
+// obsolet.
+#pragma no_clone
+
+#include <properties.h>
+#include <defines.h>
+
+// Ort, an dem die Daten gespeichert werden koennen. Die Endung .o
+// wird vom System angehaengt.
+#define SAVEFILE "/doc/beispiele/master/opferstocklog"
+
+// Dieses ist der Klient, der diesen Master benutzt. Dieser Wert wird
+// in diesem Programm zwar nicht benutzt, steht hier aber, damit man
+// weiss, wofuer dieser Master gut ist.
+#define CLIENT "/doc/beispiele/master/opferstock"
+
+// Es braucht kein Objekt inheritet werden, da wir keinerlei Spiel-
+// Funktionitaet brauchen. Der Master kann nicht genommen, bewegt oder
+// sonstwie innherlab des Muds benutzt werden. Insbesondere sollen
+// im savefile zum Master keine Properties oder so auftauchen.
+// inhert "/std/thing";
+
+// Um diese Daten geht es.
+// Das Mapping speichert zu jedem Spieler, wann das letzte Mal durch einen
+// der Klienten das Alignment geaendert wurde. Alte Daten werden bei
+// Gelegenheit geloescht.
+mapping data;
+
+void purge();
+
+void create() {
+
+  // Damit Schreibzugriff auf Savefile moeglich.
+  seteuid(getuid());
+
+  if( restore_object( SAVEFILE ) ) {
+    purge();
+  } else {
+    data = ([]);
+    save_object( SAVEFILE ); // Damit Savefile und Daten immer synchron sind.
+  }
+}
+
+// Diese Funktion testet einen einzelnen Eintrag, ob er veraltet ist.
+// (ist nicht Jahr 2038-fest :-)
+int notExpired( string name, int date ) {
+  return time() - date < 86400;
+}
+
+// Das Mapping untersuchen, ob Eintraege vorhanden sind, die nicht
+// mehr benoetigt werden.
+// (In diesem Fall sind das Eintraege, die aelter als einen Tag sind.)
+// Es reicht uns, diese Funktion einmal pro reboot auszufuehren. Bei
+// anderen Anwendungen koennte das natuerlich haeufiger noetig sein.
+void purge() {
+  data = filter_indices( data, #'notExpired );
+  save_object( SAVEFILE );
+}
+
+// Diese Funktion ist die eingetliche Funktion, die "gemastert" werden
+// soll, also für mehrere Opferstoecke gemeinsam benutzt wird.
+// Der Opferstock uebergibt das Spielerobjekt und die gewuenschte
+// Alignmentaenderung, als Ergebnis wird 1 geliefert, wenn eine Aenderung
+// vorgenommen wurde (0 sonst) und das Alignment des Spielers entsprechend
+// gesetzt.
+int addAlignment( object player, int align ) {
+  int newAlign;
+  string name;
+
+  /*
+  // Falls man verhindern will, dass nur der Klient auf die Daten zugreift,
+  // kann man hier noch Abfragen einbauen, typischerweise sieht das dann so
+  // aus:
+  if( object_name(previous_object())[0..xxx] != CLIENT ) return -1;
+  // oder
+  if( geteuid(previous_object()) != geteuid() ) return -1;
+  // etc. etc.
+  */
+
+  name = geteuid(player);
+
+  // Nur eine Aenderung pro Tag.
+  // Wir benutzen hier, dass data[name] == 0 ist, falls data den Namen nicht
+  // enthaelt!
+  if( notExpired( name, data[name] ) ) return 0;
+
+  // Daten setzen und speichern.
+  data[name] = time();
+  save_object( SAVEFILE );
+
+  // Maximale Aenderung: 200
+  if( align < -200 ) align = -200;
+  if( align > 200 ) align = 200;
+
+  newAlign = player->QueryProp( P_ALIGN ) + align;
+
+  // Kappung bei +-1000
+  if( newAlign < -1000 ) newAlign = -1000;
+  if( newAlign > 1000 ) newAlign = 1000;
+ 
+  player->SetProp( P_ALIGN, newAlign );
+  return 1;
+}
+
+// Schlussbemerkung:
+//
+// Gewitzte Programmierer koennten den Klient und den Master in einer
+// Datei zusammen ablegen. Die Blueprint wird als Master, die Clones werden
+// als Klienten benutzt. Ich habe das hier bewusst anders gemacht und empfehle
+// das auch als Vorbild, weil so der Code wesentlich besser zu verstehen ist.
diff --git a/doc/beispiele/misc/bspmon1.c b/doc/beispiele/misc/bspmon1.c
new file mode 100644
index 0000000..8ba85fc
--- /dev/null
+++ b/doc/beispiele/misc/bspmon1.c
@@ -0,0 +1,78 @@
+/*
+** Ein ganz normales Standard-monster ohne Besonderheiten
+** (von Boing)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+// den Standard-NPC der Mudlib erben.
+inherit "/std/npc";
+
+#include <properties.h>
+#include <language.h>
+
+protected void create()
+{
+  ::create();    /* Nicht vergessen, ohne das geht nichts */
+
+/* Die Kurzbeschreibung wird zum Beispiel angezeigt wenn man in einen Raum
+   mit dem Monster reinlaeuft */
+  SetProp(P_SHORT, "Beispielmonster");
+
+/* Beim Anschauen des Monsters wird die long-description angezeigt */
+  SetProp(P_LONG, "Ein Beispielmonster ohne Besonderheiten.\n");
+
+/* Ein Name muss sein, da sonst z.B. im Todesfall 'Leiche von 0' daliegt */
+  SetProp(P_NAME, "Monster");
+
+/* Das Geschlecht des Monsters. Als Geschlechter sind */
+/* die in <language.h> definierten Symbole NEUTER, MALE   */
+/* und FEMALE zulaessig.                                  */
+  SetProp(P_GENDER, NEUTER);
+
+/* Ein Monster braucht mindestens eine ID, unter der man es ansprechen kann */
+/* Es kann aber auch mehrere verschiedene ID's haben.                       */
+  AddId("monster");
+  AddId("beispielmonster");
+
+/* Zuerst sollte man dem Monster einen Grundlevel geben. */
+/* Die Spellpunkte und die Lebenpunkte sowie die Attribute werden dann */
+/* automatisch angepasst. */
+  create_default_npc( 10 );
+
+/* Nun machen wir es etwas widerstandsfaehiger, indem wir P_BODY setzen.  */
+/* Nie P_TOTAL_AC oder P_AC setzen, P_TOTAL_AC wird automatisch berechnet */
+/* und P_AC ist nur fuer Ruestungen da.                                   */
+  SetProp(P_BODY, 55);
+
+/* Das Monster schlaegt mit blossen Haenden zu, also wird P_HANDS gesetzt.   */
+/* Auch hier weder P_TOTAL_WC noch P_WC setzen.                              */
+  SetProp(P_HANDS, ({" mit seinen Haenden", 55}));
+/*                  ^ dieses Leerzeichen ist wichtig                         */
+/* Beim Kampf erscheint nun: 'Das Monster greift Dich mit seinen Haenden an' */
+/* 55 entspricht der Waffenklasse                                            */
+
+/* Gesinnung des Monsters, 0 ist neutral, negativ boese und positiv gut */
+  SetProp(P_ALIGN, 100);  /* Einigermassen nett, aber nichts besonderes */
+
+/* Die Rasse des Monsters */
+  SetProp(P_RACE, "Irgendnerasse");
+
+/* Erfahrungspunkte des Monsters, beim Tod erhaelt der 'Killer' ein   */
+/* hundertstel dieses Wertes. Schon im Kampf erhaelt man bei jedem    */
+/* Schlag weapon_class*schaden/10 punkte (weapon_class hier 55), also */
+/* insgesamt weapon_class*hit_points/10.                              */
+  SetProp(P_XP, 10000);
+
+/* Die Groesse des Monsters in cm. Dies wird bei einigen Kampfbefehlen */
+/* ausgewertet, sowie bei einigen Identifikationsspruechen von Gilden  */
+  SetProp(P_SIZE,180);
+
+/* Weitere Werte: P_(MAX)_FOOD, P_(MAX)_DRINK, P_(MAX)_ALCOHOL,       */
+/* P_MSGIN, P_MSGOUT, P_MMSGIN, P_MMSGOUT, P_MAX_HANDS, P_USED_HANDS  */
+
+}
diff --git a/doc/beispiele/misc/bspmon2.c b/doc/beispiele/misc/bspmon2.c
new file mode 100644
index 0000000..95f3909
--- /dev/null
+++ b/doc/beispiele/misc/bspmon2.c
@@ -0,0 +1,199 @@
+/*
+** Ein Beispielmonster mit div Extras (von Boing, aktualisiert von Wim+Zesstra)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/npc";
+
+#include <properties.h>
+#include <language.h>
+#include <combat.h>    // fuer die damage types
+#include <moving.h>    // fuer REJECT_KEEP   
+#include <class.h>     // fuer AddClass 
+#include <new_skills.h> // fuer SP_* bei AddSpell
+
+protected void create()
+{
+  ::create();       /* WICHTIG!!! */
+
+/* Standard-Knofiguration (Erlaeuterungen siehe bspmon1.c): */
+  SetProp(P_SHORT, "Ein Zauberer");
+  SetProp(P_LONG, "Dieser Zauberer zaubert wie wild und schwingt dabei "
+    "seinen langen Bart.\n");
+  SetProp(P_NAME, "Zauberer");
+  SetProp(P_GENDER, MALE);
+  AddId("zauberer");
+  create_default_npc(18);
+  SetProp(P_ALIGN, -700);   /* Brrr, ist der boese .... */
+  SetProp(P_BODY, 125);
+  SetProp(P_HANDS, ({" mit seinem langen Bart", 185}) );
+  SetProp(P_SIZE,180);
+  SetProp(P_MAX_HANDS, 2);  /* Anzahl der Haende (default ist 2) */
+  // set_living_name() setzt einen Namen, mit der der Zauberer z.B. mit einem
+  // 'finde' gefunden werden kann. Fuer die meisten NPC ist dies nicht noetig.
+  // Speziell sollte man keine generischen Bezeichnungen hier anmelden, wenn
+  // schon, dann individuelle Namen.
+  /* set_living_name("zauberer"); */
+
+/* Mit AddClass() und P_RACE wird festgelegt, in welche Gruppe von Lebe-  */
+/* wesen der NPC gehoert, welche mit is_class_member(mixed str) abgefragt */
+/* werden kann. Im Minimalfall ist der NPC von der Klasse, die bei P_RACE */
+/* eingetragen ist. Mit AddClass() koennen aber noch weitere Eigen-       */
+/* schaften hinzugefuegt werden.                                          */
+
+  SetProp(P_RACE,"Superduperzauberer");
+  AddClass( ({ CL_HUMAN, CL_MAMMAL }) );
+
+/* Mit P_RESISTANCE und P_VULNERABILITY werden fixe Werte (50%) fuer      */
+/* Resistenzen respektive Anfaelligkeiten gesetzt                         */
+/* Die Liste der moeglichen Schadensarten ist in /sys/combat.h definiert. */  
+/* z.B.  SetProp(P_RESISTANCE, ({ DT_MAGIC }));                           */
+/*       SetProp(P_VULNERABILITY, ({ DT_COLD }))                          */
+/*                                                                        */
+/* Mit P_RESISTANCE_STRENGTHS koennen Resistenzen und Anfaelligkeit       */
+/* konfiguriert werden. Diese Property enthaelt ein Mapping von           */
+/* von Schadensarten enthaelt. Negative Faktoren bis maximal -1.0         */ 
+/* (=Immunitaet) geben Resistenzen, positive Werte Anfaelligkeiten an.    */
+
+  SetProp(P_RESISTANCE_STRENGTHS, ([ DT_MAGIC: -0.5, DT_COLD: 2.0]) );					      
+
+/* Durch diesen Befehl wird eine Waffe geclont, sofern sie nicht im Raum  */
+/* herumliegt (in dem Fall wird sie vom NPC aufgehoben), und gezueckt     */ 
+/* (definiert in /std/npc/items.c resp. /sys/npc.h)                       */
+
+  AddItem("/doc/beispiele/misc/bspwaffe1", CLONE_WIELD);
+/* Und noch eine Ruestung clonen und anziehen.                            */  
+  AddItem("/doc/beispiele/misc/bspruest1", CLONE_WEAR);
+
+/* Jetzt wird gezaubert ....     */
+
+/* SetProp(P_SPELLRATE,) legt die Wahrscheinlichkeit fest, mit der ein   */
+/* Zauberspruch durchgefuehrt wird, hier 40%                            */
+  SetProp(P_SPELLRATE,40);
+
+/* Mit AddSpell() wird ein Zauberspruch hinzugefuegt. Das erste Argument  */
+/* ist so etwas wie die relative Wahrscheinlichkeit des Spruchs im        */
+/* Vergleich zu den anderen, hier beim ersten spruch 1 beim zweiten 2,    */
+/* das heisst in 20% der Faelle wird der erste Zauberspruch genommen und  */
+/* in 40% der zweite und in 60% der dritte.                               */
+/* Das zweite Argument ist der maximale Schaden, entsprechend der WC      */
+/* einer Waffe oder P_HANDS beim waffenlosen Kampf.                       */
+/* Die zwei weiteren Argumente sind die Meldungen die der angegriffene    */
+/* Spieler selbst und eventuelle Zuschauer erhalten. Hierbei stehen @WER, */
+/* @WEN, @WEM und @WESSEN fuer den Namen des Opfers im entsprechenden     */
+/* Fall.                                                                  */
+/* Das 5. Argument ist optional und gibt den Schadenstyp an, fehlt er     */
+/* wird DT_MAGIC angenommen.                                              */  
+/* Im 6. Arugument kann eine Funktion stehen, die bei dem Spruch ausge-   */
+/* fuehrt werden soll,                                                    */
+/* Das siebte uebergibt die Spell Parameter, hier ist wichtig, dass bei   */
+/* physikalischen Schaeden auch SP_PHYSICAL_ATTACK gesetzt wird, da sonst */
+/* einige Gilden den "Zauberspruch" abwehren koennen (siehe SpellDefend)  */
+
+  AddSpell(20,60, 
+	   "  Der Zauberer wirft einen Feuerball nach Dir.\n",
+	   "  Der Zauberer wirft einen Feuerball nach @WEM.\n",
+	   ({ DT_FIRE }) );
+  AddSpell(40,95,
+	   "  Der Zauberer beschwoert einen Sturm ueber deinem Kopf hervor.\n",
+	   "  Der Zauberer beschwoert einen Sturm ueber @WESSEN Kopf hervor.\n",
+	   ({ DT_AIR, DT_LIGHTNING }) );  
+  AddSpell(60,50,
+           "  Der Zauberer tritt Dich hinterlistig.\n",
+	   "  Der Zauberer tritt nach @WEM.\n",
+	   ({ DT_BLUDGEON }), 0,
+	   ([SP_SHOW_DAMAGE:1, SP_PHYSICAL_ATTACK:1]) );  	   
+
+
+/* Reden kann der Zauberer auch von alleine, hier kommen die chats:     */
+
+/* Das erste Argument ist die Wahrscheinlichkeit, mit der das Monster
+ * einen Spruch bringt (weniger ist mehr!). Das zweite Argument ist die Liste
+ * der Sprueche (oder Aktionen).
+ */
+
+  SetChats(2, ({
+  "Der Zauberer laeuft im Kreis herum.\n",
+  "Der Zauberer stolpert ueber seinen Bart.\n",
+  "Der Zauberer sagt: Heh Du! Was machst Du da?\n",
+  "Der Zauberer murmelt ein paar seltsame Worte in seinen Bart.\n",
+  "Der Zauberer bricht in unkontrolliertes Gelaechter aus.\n",
+  "Der Zauberer sagt: Hast mir mal ne Mark, ey?\n",
+  "Der Zauberer sagt: Wenn ich diesen Olpp erwische ...\n",
+  "Der Zauberer zaubert ein Kaninchen aus seinem Hut.\n"
+  }) );
+
+/* Das selbe fuer Sprueche die waehrend eines Kampfes kommen sollen    */
+
+  SetAttackChats(20, ({
+  "Der Zauberer macht: Buh!\n",
+  "Der Zauberer wirft mit weissen Maeusen nach Dir.\n",
+  "Der Zauberer sagt: Das war ein grosser Fehler!\n",
+  "Der Zauberer beisst Dich in den Arm.\n",
+  "Der Zauberer zaubert gruene Punkte auf deine Wange.\n",
+  "Der Zauberer verwandelt sich in eine Kroete.\n",
+  "Der Zauberer verschwindet und taucht hinter Dir wieder auf.\n"
+  }) );
+
+/* Wenn er stirbt soll eine besondere Meldung erscheinen. */
+  SetProp( P_DIE_MSG, " loest sich in Luft auf.\n" );
+/* Dann soll natuerlich auch kein Leichnam rumliegen */
+  SetProp( P_NOCORPSE, 1 );
+ 
+/* Nun wollen wir den Zauberer noch auf ein paar Fragen antworten lassen    */
+/* AddInfo(DEFAULT_INFO,) setzt die Antwort auf alle Fragen, wo der         */
+/* Schluessel nicht bekannt ist. Der Name des Zauberers wird immer vor den  */
+/* String gesetzt. (SetProp(P_DEFAULT_INFO, ist obsolet und sollte nicht    */
+/* mehr angewendet werden.)                                                 */ 
+
+  AddInfo(DEFAULT_INFO,"sagt: Keine Ahnung, von was Du redest.\n",0,
+                       "sagt zu @WEM: Keine Ahnung, von was Du redest.\n");
+
+/* Die bekannten Schluessel werden mit AddInfo dazugefuegt, das erste       */
+/* Argument ist das Wort (oder die Liste von Woertern), zu der der Zauberer */
+/* befragt werden kann, das zweite Argument ist die entsprechende Antwort.  */
+/* ist das dritte Argument gesetzt, so wird die Antwort automatisch umge-   */
+/* brochen und bekommt den Text des Arguments vor jede Zeile gestellt.      */
+/* Das vierte, ebenfalls optionale, Argument wird sofern gesetzt an die     */
+/* umstehenden Personen ausgegeben, dadurch laesst sich ein Fluestern oder  */
+/* eine spielerabhaengige Antwort realisieren.                              */
+
+  AddInfo("kaninchen",
+  "sagt: Die hol ich immer aus meinem Hut.\n");
+  AddInfo("zauberei",
+  "sagt: Ich bin ein Meister der Zauberei.\n");
+  AddInfo(({"maus", "maeuse"}),
+  "sagt: Maeuse sind meine Lieblingstiere.\n"); 
+  
+  AddInfo( ({"tier","tiere"}), 
+          "Oh, hauptsaechlich beschaeftige ich mich mit Kaninchen und Maeusen.",
+          "fluestert Dir zu: ",
+          "fluestert mit @WEM.\n");
+
+/* Normalerweile nehmen Monster alles was man ihnen gibt, ohne einen Ton */
+/* zu sagen. Will man dort ein anderes Verhalten, so tut man das so:     */
+/* Moeglich sind auch REJECT_GIVE (= zurueckgeben) REJECT_DROP (=fallen  */
+/* lassen. */
+  SetProp( P_REJECT, ({ REJECT_KEEP, "Der Zauberer sagt: Dankeschoen.\n" }) );
+
+/* Der Zauberer kann auch zusaetzliche Verben haben, die nur er selber
+ * benutzen kann, kein anderes Living. Diese koennen mit add_action() im
+ * create eines NPC angemeldet werden (und idR NUR in dieser Funktion und NUR
+ * in Lebewesen, nicht in sonstigen Objekten! */
+  add_action("nasebohren", "bohreinnase");
+
+/* Verben, die Spieler in Gegenwart des Zauberers koennen sollen, werden     */
+/* mit AddCmd angemeldet. */
+}
+
+int nasebohren( string str ) // str ist das, was hinter dem verb eingegeben wurde.
+{
+   say( "Der Zauberer bohrt mit dem Stab in seiner Nase.\n" );
+   return 1; // Verb war erfolgreich.
+}
+
diff --git a/doc/beispiele/misc/bspraum1.c b/doc/beispiele/misc/bspraum1.c
new file mode 100644
index 0000000..3483095
--- /dev/null
+++ b/doc/beispiele/misc/bspraum1.c
@@ -0,0 +1,78 @@
+/* /doc/beispiele/misc/bspraum1.c von Rumata */
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/room";
+
+#include <properties.h>
+#include <language.h>
+
+protected void create()
+{
+    ::create();
+
+    SetProp( P_INT_SHORT, "Ein kleines Schreibzimmer" );
+    SetProp( P_INT_LONG,
+        "Du stehst in einem kleinen Schreibzimmer.\n"
+         "Es gehoerte wohl irgendwann einmal einem Magier, aber nun\n"
+         "ist dieser Raum verwaist und rottet vor sich hin.\n"
+         "Ein grosser Schreibtisch in der Mitte des Raumes scheint\n"
+         "noch einigermassen gut erhalten zu sein. Durch die Tuer\n"
+         "im Norden faellt etwas Licht hinein.\n"
+    );
+    SetProp( P_LIGHT, 1 );
+    SetProp( P_INDOORS, 1 );
+
+    AddDetail( ({ "schreibtisch", "tisch" }),
+        "Auf dem Tisch liegt eine dicke Staubschicht.\n"
+        "Eine Schublade findest Du ebenfalls.\n"
+    );
+    AddDetail( ({ "staub", "staubschicht", "schicht" }),
+        "Du malst gelangweilt einige Kreise in den Staub.\n"
+    );
+    AddDetail( "schublade",
+        "So sehr Du Dich anstrengst; Du kannst sie nicht bewegen.\n"
+    );
+    AddDetail( "tuer" ,
+        "Sie steht seit Jahren offen und ist in dieser Lage\n"
+        "hoffnungslos festgerostet.\n"
+    );
+
+    AddCmd( ({ "schliesse", "oeffne", "bewege", "schliess", "beweg" }), 
+            "beweg_etwas" );
+    AddExit( "norden", "players/rumata/workroom" );
+}
+
+public int beweg_etwas( string str )
+{
+    notify_fail( "Was willst Du denn bewegen ?" );
+    if( str == "tuer" )
+    {
+        write( "Die Tuer ist hoffnungslos festgerostet.\n" );
+        return 1;
+    }
+    if ( str == "lade" || str == "schublade" )
+    {
+        write( "Die Schublade klemmt einfach nur.\n" );
+        return 1;
+    }
+    if ( query_verb() == "bewege" &&
+        ( str == "tisch" || str == "schreibtisch" ) )
+    {
+        tell_object(this_player(),
+            "Der Tisch scheint am Boden festgeschraubt zu sein.\n"
+        );
+        tell_room(this_object(),
+            this_player()->name(WER,2)+" zerrt am Schreibtisch.\n"
+        );
+        return 1;
+    }
+ // offenbar passte nix, Kommando nicht erfolgreich abgearbeitet. Ggf. weitere
+ // versuchen und/oder die notify_fail-Meldung ausgeben.
+    return 0;
+}
+
diff --git a/doc/beispiele/misc/bspruest1.c b/doc/beispiele/misc/bspruest1.c
new file mode 100644
index 0000000..10e3b0e
--- /dev/null
+++ b/doc/beispiele/misc/bspruest1.c
@@ -0,0 +1,38 @@
+/*
+** Eine Beispielruestung
+** (von Boing)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/armour";
+
+#include <properties.h>
+#include <combat.h>
+#include <language.h>
+
+protected void create()
+{
+  ::create();   /* WICHTIG!!! */
+
+/* Standardkonfiguration, genaueres siehe /doc/beispiele/bspwaffe1.c    */
+  SetProp(P_SHORT, "Ein grauer Umhang");
+  SetProp(P_LONG, "Es ist ein langer grauer Umhang aus einem feinen Material.\n");
+  SetProp(P_NAME, "Umhang");
+  SetProp(P_GENDER, MALE);
+  AddId("umhang");
+  SetProp(P_WEIGHT, 250);
+  SetProp(P_VALUE, 200);
+
+/* Zur Waffe fehlt nicht mehr viel, nur noch die Ruestungsklasse (AC)    */
+/* setzen und einen Ruestungstyp setzen. Die Typen sind in sys/combat.h  */
+/* definiert. Richtlinien zu Ruestungsklassen der verschiedenen Typen    */
+/* stehen momentan in /players/boing/waffen.                             */
+
+  SetProp(P_ARMOUR_TYPE, AT_CLOAK);
+  SetProp(P_AC, 8);
+}
diff --git a/doc/beispiele/misc/bsptransporter1.c b/doc/beispiele/misc/bsptransporter1.c
new file mode 100644
index 0000000..3e26020
--- /dev/null
+++ b/doc/beispiele/misc/bsptransporter1.c
@@ -0,0 +1,132 @@
+inherit "std/transport";
+
+/* wolke.c Ein Beispiel zur Programmierung eines Transporters */
+/* von Rumata (mit kleinen Bugfixes von Wargon ;) */
+
+#include <properties.h>
+#include <language.h>
+
+create()
+{
+  ::create();
+  SetProp( P_NAME, "Woelkchen" );
+  AddId( ({ "wolke", "woelkchen" }) );
+  SetProp( P_GENDER, NEUTER );
+  SetProp( P_INT_SHORT, "Auf einer kleinen Wolke" );
+  SetProp( P_INT_LONG,
+	  "Du sitzt auf einer kleinen Wolke, die zwischen Jofs und Rumatas\n"
+	  +	"Arbeitszimmer hin- und herpendelt. Wenn sie niedrig fliegt, kannst\n"
+	  +	"Du bestimmt von ihr heruntersteigen.\n"
+	  );
+  SetProp( P_SHORT, "Eine kleine Wolke" );
+  SetProp( P_LONG,
+	  "Diese suesse kleine Cumuluswolke schwebt zwischen Jofs und Rumatas\n"
+	  +	"Arbeitszimmer hin und her. Vielleicht kannst Du auf sie draufsteigen.\n"
+	  );
+  SetProp(P_LIGHT, 1 );
+  SetProp(P_TRANSPARENT,1);
+  // Man soll auf(in) die Wolke und von ihr herunter schauen koennen.
+    
+  /*** Meldungen, die Transporter geben koennen ***/
+  
+  SetProp( P_DEPARTMSG, ({
+    "Die Wolke steigt in die Luft.\n", 
+    "Die Wolke fliegt davon.\n"
+  }) );
+  // Die erste Meldung ist fuer Leute auf der Wolke.
+  // Die zweite fuer Leute in dem Raum, in dem die Wolke ankommt.
+      
+  SetProp( P_ARRIVEMSG, ({
+    "Die Wolke naehert sich dem Boden von @@QueryArrived@@.\n",
+    "Eine kleine Wolke schwebt herab.\n"
+  }) );
+  // Die erste Meldung ist fuer Leute auf der Wolke.
+  // Die zweite fuer Leute in dem Raum, aus dem die Wolke abreist.
+    
+  SetProp( P_ENTERMSG, ({
+    "steigt auf die Wolke",
+    "kommt auf die Wolke"
+  }) );
+  // Die erste Meldung ist fuer den Raum, aus dem der Spieler kommt.
+  // (=Raum). Die zweite Meldung ist fuer Spieler in dem Raum, in
+  // den der Spieler geht (=Transporter).
+	
+  SetProp( P_LEAVEMSG, ({
+    "steigt von der Wolke",
+    "steigt von der Wolke"
+  }) );
+  // Die erste Meldung ist fuer den Raum, aus dem der Spieler kommt.
+  // (=Transporter). Die zweite Meldung ist fuer Spieler in dem Raum,
+  // in den der Spieler geht (=Raum).
+      
+  SetProp( P_LEAVEFAIL, "Die Wolke schwebt viel zu hoch" );
+  // Meldung, die kommt, wenn ein Spieler den Transporter verlassen
+  // will, aber dieser an keinem Raum angelegt hat.
+  // Ist der Parameter ein String (so wie hier), so bekommt nur
+  // der betreffende Spieler die Meldung, wenn sie ein Array aus
+  // 2 Elementen ist, bekommt der Spieler die erste und alle
+  // anderen Spieler im Transporter die zweite (mit dem Namen
+  // des Spielers davor).
+  // Moeglich waere also auch:
+  /*
+     SetProp( P_LEAVEFAIL, ({
+     "Die Wolke schwebt viel zu hoch zum Herunterspringen",
+     "faellt fast von der Wolke"
+     }) );
+  */
+
+  SetProp( P_ENTERFAIL, "Es passen nur 5 Passagiere auf die Wolke.\n" );
+  // Diese Meldung bekommt der Spieler, wenn er versucht, einen
+  // vollen Transporter zu betreten. Hier ist nur eine Meldung
+  // (an den Spieler) vorgesehen.
+
+  SetProp( P_MAX_PASSENGERS, 5 );
+  // Maximale Anzahl der Spieler, die sich im Transporter befinden
+  // koennen. Fuer Gegenstaende gibt es keine Beschraenkung.
+
+  /* Verben */
+  AddCmd( ({ "steig", "steige", "spring", "springe" }), "steige" );
+
+  /* Kurs */
+  AddRoute( "players/rumata/workroom", 30, 20, "Rumatas Arbeitszimmer" );
+  // Hier wird der Raum /players/rumata/workroom als Anlegeplatz
+  // in den Kurs eingefuegt. Der Transporter verweilt 30sek in diesem
+  // Raum und faeht dann 20sek lang, bis er den naechten Punkt
+  // erreicht. Danach kann man noch den Code angeben, der bei
+  // QueryArrived zurueckgegeben wird, setzen. Wird kein Code
+  // gesetzt, wo wird dort ein Leerstring zurueckgegeben. 0 wird
+  // dann zurueckgegeben, wenn der Transporter an keinem Raum angelegt
+  // hat.
+
+  AddMsg( "Die Wolke treibt nun im Wind Richtung Jofs Arbeitszimmer.\n", 30 );
+  // Hier wird eine Meldung ausgegeben, und der Transporter reist 30sek lang
+  // weiter.
+
+  AddMsg( "Die Wolke beginnt zu sinken.\n", 10 );
+  AddRoute( "players/jof/workroom", 30, 20, "Jofs Arbeitszimmer" );
+  AddMsg( "Die Wolke treibt nun im Wind Richtung Rumatas Arbietszimmer.\n", 30 );
+  AddMsg( "Die Wolke beginnt zu sinken.\n", 10 );
+  // Nach dem Letzten Haltepunkt wird der Kurs wieder von vorn
+  // befahren.
+ 	
+  Start();
+  // Lasse den Transporter am ersten dieser Haltepunkte starten.
+}
+
+steige(str)
+{
+  string arg, arg2;
+  
+  if (sscanf( str, "auf %s", arg ) > 0 && id(old_explode(arg," ")[0]))
+    return Enter();
+  // Wenn sicher ist, dass der Spieler die Wolke BEsteigen will,
+  // kann man mit return Enter() alle weiteren Tests durchfuehren.
+
+  if (sscanf( str, "von %s", arg ) > 0 && id(old_explode(arg, " ")[0]))
+    return Leave();
+  // Das selbe gilt fuer das ABsteigen und Leave().
+  // Verben sollten nach Enter() oder Leave() keine weiteren Befehle
+  // enthalten.
+}
+
+
diff --git a/doc/beispiele/misc/bspwaffe1.c b/doc/beispiele/misc/bspwaffe1.c
new file mode 100644
index 0000000..259ae2a
--- /dev/null
+++ b/doc/beispiele/misc/bspwaffe1.c
@@ -0,0 +1,56 @@
+/*
+** Eine Beispielwaffe
+** (von Boing)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/weapon";
+
+#include <properties.h>     /* Definition der Properties */
+#include <combat.h>         /* Definition der kampfspezifischen Konstanten */
+#include <language.h>       /* Definition von MALE, FEMALE, WER, ... */
+
+protected void create()
+{
+  ::create();   /* WICHTIG!!! */
+
+/* Kurzbeschreibung fuer Darstellung in inventories */
+  SetProp(P_SHORT, "Ein Knueppel");
+
+/* Beschreibung des Knueppels */
+  SetProp(P_LONG, 
+  "Dieser Knueppel ist ziemlich normal, er ist aus festem Holz gefertigt und\n"+
+	  "man kann ihn als Waffe benutzen.\n");
+
+/* Name und Geschlecht sind wichtig, jedes Objekt braucht das */
+  SetProp(P_NAME, "Knueppel");
+  SetProp(P_GENDER, MALE);
+
+/* Jedes Objekt braucht eine oder mehrere Id's */
+  AddId("knueppel");
+
+/* Wert und Gewicht */
+  SetProp(P_VALUE, 300);
+  SetProp(P_WEIGHT, 1250);   /* in Gramm */
+
+/* Nun die wirklich Waffenspezifischen Dinge:                   */
+/* Waffen- und Schadensarten sind in /sys/combat.h definiert    */
+  SetProp(P_WEAPON_TYPE, WT_CLUB);
+  SetProp(P_DAM_TYPE, DT_BLUDGEON);
+
+/* Die Waffenklasse muss im Bereich zwischen 1 und 200 liegen   */
+  SetProp(P_WC, 125);
+  
+/* Anzahl der benoetigten Haende, um die Waffe zu zuecken.      */
+/* Waffen mit einer WC groesser 150, sollten auf jeden Fall     */
+/* Zweihaender sein, bei Sonderfaellen bitte an den Erzmagier   */
+/* fuer Waffen wenden. Wenn nichts gesetzt wird, ist die Waffe  */
+/* ein Zweihaender.                                             */
+  SetProp(P_NR_HANDS, 1);
+}
+
diff --git a/doc/beispiele/misc/krankheit.c b/doc/beispiele/misc/krankheit.c
new file mode 100644
index 0000000..c5816a3
--- /dev/null
+++ b/doc/beispiele/misc/krankheit.c
@@ -0,0 +1,66 @@
+/*  Paracelsus: Eine Krankheit
+**
+**      Beispiel fuer die Verwendung von P_X_ATTR_MOD und P_X_HEALTH_MOD
+**
+**      Diese Krankheit setzt alle Attribute herab und erniedrigt
+**      zusaetzlich P_MAX_HP und P_MAX_SP um jew. 20 (zusaetzlich zu den
+**      Auswirkungen der Attributsenkungen).
+**      Gestartet wird die Krankheit, indem sie einfach in das Opfer
+**      bewegt wird.
+**      Man beachte, dass im remove() die P_X_*-Properties ein leeres
+**      Mapping zugewiesen bekommen und keine 0. Nur so werden die
+**      Krankheitsfolgen rueckgaengig gemacht.
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/thing";
+
+#include <properties.h>
+#include <moving.h>
+#include <language.h>
+#include <class.h>
+
+protected void create()
+{
+    ::create();
+
+    // ausnahmsweise darf dieses Objekt mal kein P_SHORT+P_LONG haben...
+    SetProp(P_SHORT,0);
+    SetProp(P_LONG, 0);
+    SetProp(P_INVIS, 1); // unsichtbar machen.
+    SetProp(P_NAME,"Krankheit");
+    SetProp(P_GENDER,FEMALE);
+    // wichtig, sonst wiegt die Krankheit 1kg (Standardgewicht fuer thing) 
+    SetProp(P_WEIGHT,0);
+    SetProp(P_VALUE,0);
+    SetProp(P_MATERIAL,MAT_MISC_MAGIC);
+    SetProp(P_NODROP,1); // Nicht wegwerfbar.
+
+// ----> Dieser Abschnitt sorgt fuer fiese Statabzuege
+
+    SetProp(P_X_HEALTH_MOD,
+    ([
+        P_HP : -20,   // Max. Lebenspunkte um 20 runter
+        P_SP : -20    // Max. Konzentrationspunkte um 20 runter
+    ]) );
+    SetProp(P_X_ATTR_MOD,
+    ([
+        A_CON : -1,   // Ausdauer um 1 runter, reduziert auch max. LP!
+        A_DEX : -1,   // Geschicklichkeit um 1 runter
+        A_INT : -2,   // Intelligenz um 2 runter, reduziert auch max. KP!
+        A_STR : -4,   // Staerke um 4 runter
+    ]) );
+
+// <----
+
+    AddId( ({"PARA\nSICK\nEXAMPLE"}) );
+
+    AddClass(CL_DISEASE); // Damit Kleriker helfen koennen.
+    SetProp(P_LEVEL,15);  // Aber nicht ganz so einfach zu entfernen
+}
+
diff --git a/doc/beispiele/misc/lebensring.c b/doc/beispiele/misc/lebensring.c
new file mode 100644
index 0000000..f82ea5e
--- /dev/null
+++ b/doc/beispiele/misc/lebensring.c
@@ -0,0 +1,56 @@
+/* Paracelsus: Lebensring
+**
+**    Ein Beispiel fuer die Anwendung von P_M_HEALTH_MOD
+**
+**    Zieht ein Spieler diesen Ring an, so erhoehen sich seine maximalen
+**    Lebenspunkte dabei um 10, waehrend seine max. Konzentrationspunkte
+**    um 5 erniedrigt werden.
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/armour";
+
+#include <properties.h>
+#include <armour.h>
+#include <language.h>
+#include <combat.h>
+
+protected void create()
+{
+    ::create();
+
+    SetProp(P_SHORT,"Ein Lebensring");
+    SetProp(P_LONG,
+        "Ein kleiner Ring aus einem seltsamen, gruenen Material.\n");
+    SetProp(P_INFO,
+        "Dieser Ring unterstuetzt die Gesundheit.\n"+
+        "Dabei schwaecht er leider den Geist.\n");
+    SetProp(P_NAME,"Lebensring");
+    SetProp(P_GENDER,MALE);
+    SetProp(P_WEIGHT,80);
+    SetProp(P_VALUE,2000+random(501));
+    SetProp(P_ARMOUR_TYPE,AT_RING);
+    SetProp(P_AC,0); // keine Schutzwirkung im Kampf
+    SetProp(P_MATERIAL,MAT_MISC_MAGIC);
+
+// ---->
+
+    SetProp(P_M_HEALTH_MOD,
+    ([
+        P_HP : 10,      // Max. LP um 10 erhoehen
+        P_SP : -5       // Max. KP um 5 verringern
+    ]) );
+
+// <----
+
+    AddId( ({"ring","lebensring"}) );
+
+    AddDetail( "material",
+        "Es ist gruen.\n");
+}
+
diff --git a/doc/beispiele/misc/seherhaus.c b/doc/beispiele/misc/seherhaus.c
new file mode 100644
index 0000000..ea127e4
--- /dev/null
+++ b/doc/beispiele/misc/seherhaus.c
@@ -0,0 +1,136 @@
+/*
+Kurze Uebersicht der Termini:
+
+P_HAUS_ERLAUBT     Propertie, die das Bauen eines Hauses im Raum er-
+                   laubt oder verbietet. Default auf 0
+                   Syntax: xcall $h->SetProp(P_HAUS_ERLAUBT,x)
+                   
+Save()             Muss nach Aenderungen am Haus aufgerufen werden.
+                   Syntax: xcall /d/seher/haeuser/tillyhaus->Save()
+
+Okay, also ein Seher moechte, dass sein Haus 1) unsichtbar ist, 2) mit
+einem anderen Kommando betreten werden soll und 3) nicht auf die id 
+<haus> hoert sondern auf eine andere:
+
+Zu 1): Ganz einfach, man tippe 
+
+       'xcall /d/seher/haeuser/tillyhaus->SetProp(P_SHORT,0)' und
+       'xcall /d/seher/haeuser/tillyhaus->Save()'
+
+Zu 2) und 3): Das ist nicht so einfach, sondern muss ueber den Raum, in 
+              dem das Haus steht, gemacht werden. Deswegen folgend nun 
+              ein Beispiel zu Funktionen in so einem Raum.
+
+
+Folgende Dinge stehen natuerlich schon im Raum, sonst liesse er sich
+nicht laden :-)              
+*/
+
+#pragma strong_types, save_types, rtt_checks
+
+inherit "/std/room";
+
+#include <properties.h>
+#include <language.h>
+#include <moving.h>
+
+/*
+   Fuer properties und sonstige Definitionen zum Seherhaus.
+*/
+#include "/d/seher/haeuser/haus.h"
+
+/*
+   Aus Gruenden der Uebersichtlichkeit ziehen viele Magier vor, den Hauskrams
+   in eine separate Funktion zusammenzufassen.
+*/
+private void haus_create();
+
+/*
+Es folgt nun das normale create() eines Raumes
+*/
+void create(){
+  ::create();
+  /* ... div. Konfiguration des Raum ... */
+
+  /*
+  Das extra-create() muss natuerlich aufgerufen werden
+  */  
+  haus_create();
+}      
+
+/*
+Hier kommen wir nun zu der Fkt, die alles am Seherhaus verwaltet
+*/
+private void haus_create()
+{
+  object ob = find_object(HAUSNAME("tilly")); // findet Haus von Tilly
+
+  /*
+  Wenn das Haus im Raum steht. Hat den Vorteil, dass bei einem Verlegen
+  des Hauses, Cmd's usw nicht mehr verfuegbar sind -> Keine evtl Bugs :)
+  */
+  if(objectp(ob))
+  {
+    /*
+    Der Spieler wollte es ja nicht anders
+    */
+    ob->RemoveCmd(({"betret","betritt","betrete"}));
+    ob->RemoveId("haus");
+    ob->RemoveId("haus von tilly");
+    ob->AddId("steinhaufen");
+    
+    AddDetail(({"haufen","steinhaufen"}),"Da ist doch ein kleiner Spalt? "
+     +"Vielleicht kannst Du auf den Steinhaufen klettern?\n");
+
+    AddCmd(({"kletter","klettere"}),"kletter_cmd");
+  }
+}
+
+public int kletter_cmd(string str)
+{
+  object ob = find_object(HAUSNAME("tilly"));
+
+  _notify_fail("Wo moechtest Du hinklettern?\n");
+
+  if(!str) return 0;
+
+  if(str=="auf haufen" || str=="auf steinhaufen")
+  {
+    if(objectp(ob))
+    {
+      /*
+      Das ist die Meldung, die ein Spieler bekommt, wenn das Seherhaus
+      abgeschlossen ist und er versucht, es zu 'betreten'.
+      */
+      notify_fail("Du kletterst auf den Haufen, doch der Spalt ist zu "
+       "schmal fuer Dich.\n");
+       
+      if(!(ob->QueryProp(H_DOORSTAT) & D_CLOSED))
+      {
+        tell_object(this_player(),
+            "Du kletterst auf den Steinhaufen, rutschst den Spalt runter "
+             "und findest Dich urploetzlich in einer schummrigen Hoehle.\n");
+        tell_room(this_object(),this_player()->name()+" klettert auf einen "
+          "Steinhaufen und ist ploetzlich verschwunden.",({this_player()}));
+        tell_room(RAUMNAME("tilly",0),this_player()->name()+
+          " faellt fluchend herein.\n");
+        this_player()->move(RAUMNAME("tilly",0),M_GO|M_SILENT,0);
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+  
+/*
+Natuerlich gibt es noch viel mehr Moeglichkeiten rund um Seherhaeuser, 
+doch sollte dies erstmal reichen. Zu beachten ist bei solcher Vorgehens-
+weise, dass ein 'schliesse|oeffne haus' evtl zu Fehlermeldungen fuehrt.
+Dem Spieler sei nahegelegt, es doch mit 'oeffne haustuer' zu versuchen.
+
+HAUSNAME und RAUMNAME (u.a.) sind Defines aus dem haus.h. Man sollte sich
+dieses File anschauen und die dortigen Defines uebernehmen. Dann bugt auch 
+nichts, falls mal etwas an den Haeusern umgestellt wird.
+
+Tilly, 20. Mai 2001, 00:10:24h
+*/
diff --git a/doc/beispiele/misc/statkrallen.c b/doc/beispiele/misc/statkrallen.c
new file mode 100644
index 0000000..a0ae4c3
--- /dev/null
+++ b/doc/beispiele/misc/statkrallen.c
@@ -0,0 +1,61 @@
+/* Paracelsus: Statkrallen
+**
+**     Beispiel fuer die Verwendung von P_M_ATTR_MOD
+**
+**     Zieht ein Spieler diese Krallen an, so erhoeht sich seine Staerke
+**     um 2. Gleichzeitig wird das Erhoehen seiner Geschicklichkeit durch
+**     andere Ruestungen/Waffen blockiert. 
+**     Die Krallen koennen nur angezogen werden, wenn weder A_STR noch
+**     A_DEX durch eine andere Ruestung/Waffe blockiert wird.
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+
+#include <properties.h>
+#include <language.h>
+#include <combat.h>
+
+inherit "/std/armour";
+
+protected void create()
+{
+    ::create();
+
+    SetProp(P_SHORT,"Statkrallen");
+    SetProp(P_LONG,
+        "Diese krallenbewehrten Handschuhe schimmern blaeulich.\n");
+    SetProp(P_NAME,"Statkrallen");
+    SetProp(P_INFO,"Die Krallen machen staerker.\n");
+    SetProp(P_GENDER,FEMALE);
+    SetProp(P_NOBUY,1); // wird bei Verkauf im laden zerstoert.
+    SetProp(P_WEIGHT,800);
+    SetProp(P_VALUE,5000+random(2000));
+    SetProp(P_ARMOUR_TYPE,AT_GLOVE);
+    SetProp(P_AC,2);
+    SetProp(P_EFFECTIVE_WC,15);
+    SetProp(P_MATERIAL,
+    ([
+        MAT_LEATHER    : 60,
+        MAT_MISC_METAL : 40
+    ]) );
+
+// ---->
+
+    SetProp(P_M_ATTR_MOD,
+    ([
+        A_STR : 2,  // Staerke um 2 erhoehen
+        A_DEX : 0   // Geschicklichkeit blockieren
+    ]) );
+
+// <----
+
+    AddId( ({"handschuhe","krallen"}) );
+
+    AddDetail( "schimmer",
+        "Ein blaeulicher Schimmer liegt auf den Krallen.\n");
+}
+
diff --git a/doc/beispiele/precompiler/konstanten.c b/doc/beispiele/precompiler/konstanten.c
new file mode 100644
index 0000000..687d1a3
--- /dev/null
+++ b/doc/beispiele/precompiler/konstanten.c
@@ -0,0 +1,50 @@
+// Mit dem Praecompiler lassen sich symbolische Konstanten definieren. Dies
+// z.B. sinnvoll, wenn eine Zahl eine bestimmte Bedeutung hat. Z.b. hat die
+// Zahl 42 an sich keine fixe Bedeutung, hier ist die jedoch die Antwort!
+#define ANTWORT 42
+// Schreibt man nun irgendwo im Code ANTWORT, ersetzt der Praecompiler jedes
+// Vorkommen von ANTWORT durch 42.
+
+// auch komplexere Konstanten sind moeglich, z.B. ein Argument eines Defines:
+#define ROOM(x) ("/d/ebene/zesstra/advent/room/"+x)
+// Dies dient meist, um sich Schreibarbeit zu sparen. Formuliert man nach
+// diesem #define ein ROOM("weg1"), erzeugt der Praecompiler hieraus:
+// ("/d/ebene/zesstra/advent/room/weg1")
+
+// Weiteres Beispiel:
+#define BS(x) break_string(x, 78)
+// erzeugt also aus BS("langer text") ein break_string("langer text",78)
+
+// Es gehen auch mehrere Argumente:
+#define BS(x,y) break_string(x, 78, y)
+// BS("langer text", 78, "Zesstra sagt: ")
+//   -> break_string("langer text", 78, "Zesstra sagt: ")
+
+// Solche Defines lassen sich schachteln:
+#define HOME(x) ("/d/ebene/zesstra/advent/"+x)
+#define ROOM(x) (HOME("room/"+x))
+// Ein ROOM("weg1") wird nun durch (HOME("room/"+"weg1")) ersetzt
+// und dieses wiederum durch ein 
+// (("/d/ebene/zesstra/advent/"+"room/"+"weg1")), was letztendlich ein
+// (("/d/ebene/zesstra/advent/room/weg1")) ist.
+
+// Letzteres wird haeufig benutzt bei der Erstellung von Gebieten um sich bei
+// Umzuegen Arbeit zu sparen: zieht das Gebiet um (z.B. von /players/zesstra/
+// nach /d/ebene/zesstra/advent/, reicht es aus, HOME zu aendern und man muss
+// nicht 150mal den kompletten Pfad im Code aendern.
+
+// moechte man ein Define ueber mehrere Zeilen definieren, muss der
+// Zeilenumbruch mit einem \ escaped  werden:
+#define LOG(x) log_file("bla",\
+    "Dies ist ein laengerer Text.\n")
+// WICHTIG: Hinter dem \ darf KEIN Leerzeichen, Tab o.ae. stehen!
+
+// Tips:
+// * Damit man Defines schnell als solche erkennt, sollten alle Defines
+//   grossgeschrieben werden: z.B. PL vs. pl
+// * von komplexen Defines wird abgeraten, weil sie schnell Uebersicht 
+//   und Effizienz ruinieren koennen
+// * einige haeufig benutzte Defines finden sich in <defines.h>
+// * der Driver definiert bestimmte Defines automatisch. Eine Liste
+//   findet sich in /doc/driver/predefined
+
diff --git a/doc/beispiele/rotaugenvampire/.readme b/doc/beispiele/rotaugenvampire/.readme
new file mode 100644
index 0000000..a2ceeb6
--- /dev/null
+++ b/doc/beispiele/rotaugenvampire/.readme
@@ -0,0 +1,3 @@
+Drei Beispielmonster, die wichtige Basiseigenschaften von NPCs sowie
+die Vererbung demonstrieren. Angelehnt an bspmon1.c von Boing.
+(Zesstra)
diff --git a/doc/beispiele/rotaugenvampire/rotaugenvampir.c b/doc/beispiele/rotaugenvampire/rotaugenvampir.c
new file mode 100644
index 0000000..ca464d5
--- /dev/null
+++ b/doc/beispiele/rotaugenvampire/rotaugenvampir.c
@@ -0,0 +1,135 @@
+/*
+   Ein Beispiel-NPC (von Zesstra, angelehnt an Boings bspmon1.c)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+// Einige Warnungen werden als Fehler betrachtet (empfohlen)
+#pragma pedantic, range_check
+// Schaltet bestimmte Warnungen ein (empfohlen)
+#pragma warn_deprecated, warn_empty_casts, warn_missing_return
+#pragma warn_function_inconsistent
+
+// Erbt den Standard-NPC / das Standard-Monster
+inherit "/std/npc";
+
+// Inkludiert Definitionen fuer Properties und einige Konstanten
+#include <properties.h>
+#include <language.h>
+#include <class.h> // Konstanten fuer AddClass()
+
+// create() wird beim Erzeugen des Objekt vom Driver gerufen und initialisiert
+// diesen NPC. Es bekommt kein Argument, gibt keinen Wert zurueck (Typ: void)
+// und kann nicht von ausserhalb des Objektes gerufen werden (protected).
+protected void create()
+{
+  // Nicht vergessen, ohne das geht nichts. Fuehrt das create() des geerbten
+  // /std/npc aus und initialisiert den Standard-NPC.
+  ::create();
+
+/* Die Kurzbeschreibung wird zum Beispiel angezeigt wenn man in einen Raum
+   mit dem Monster reinlaeuft */
+  SetProp(P_SHORT, "Rotaugenvampir");
+
+/* Beim Anschauen des Monsters wird die long-description angezeigt,
+ * Zeilenumbruch nach Bedarf nach 78 Zeichen. */
+  SetProp(P_LONG, break_string(
+    "Ein finster aussehender Rotaugenvampir.",78));
+
+/* Ein Name muss sein, da sonst z.B. im Todesfall 'Leiche von 0' daliegt */
+  SetProp(P_NAME, "Rotaugenvampir");
+  SetProp(P_NAME_ADJ,"ausgemergelt");
+  
+/* Das Geschlecht des Monsters. Als Geschlechter sind */
+/* die in <language.h> definierten Symbole NEUTER, MALE   */
+/* und FEMALE zulaessig.                                  */
+  SetProp(P_GENDER, MALE);
+
+/* Ein Monster braucht mindestens eine ID, unter der man es ansprechen kann */
+/* Es kann aber auch mehrere verschiedene ID's haben.                       */
+  AddId( ({"vampir","rotaugenvampir"}) );
+
+/* Zuerst sollte man dem Monster einen Grundlevel geben. */
+/* Setzt Standardwerte fuer P_LEVEL, P_MAX_HP (Lebenspunkte), P_MAX_SP
+ * (Magiepunkte), P_HANDS, P_BODY, P_XP und die Attribute A_STR, A_INT, A_DEX
+ * und A_CON. Alle koennen spaeter noch geaendert werden.
+ */
+  create_default_npc( 25 );
+
+/* Nun machen wir es etwas widerstandsfaehiger, indem wir P_BODY setzen.  */
+/* Nie P_TOTAL_AC oder P_AC setzen, P_TOTAL_AC wird automatisch berechnet */
+/* und P_AC ist nur fuer Ruestungen da.                                   */
+  SetProp(P_BODY, 55);
+
+/* Das Monster schlaegt mit blossen Haenden zu, also wird P_HANDS gesetzt.   */
+/* Auch hier weder P_TOTAL_WC noch P_WC setzen.                              */
+  SetProp(P_HANDS, ({" mit seinen Haenden", 135}));
+/*                    ^ dieses Leerzeichen ist wichtig                       */
+/* Beim Kampf erscheint nun: 'Das Monster greift Dich mit seinen Haenden an' */
+/* 135 entspricht der Waffenklasse                                            */
+
+/* Gesinnung des Monsters, 0 ist neutral, negativ boese und positiv gut */
+  SetProp(P_ALIGN, -100);  /* etwas boese, aber nichts besonderes */
+
+/* Die Rasse des Monsters */
+  SetProp(P_RACE, "Vampir");
+
+/* Erfahrungspunkte des Monsters, beim Tod erhaelt der 'Killer' ein   */
+/* hundertstel dieses Wertes. Schon im Kampf erhaelt man bei jedem    */
+/* Schlag weapon_class*schaden/10 punkte (weapon_class hier 55), also */
+/* insgesamt weapon_class*hit_points/10.                              */
+/* Ab 200000 gibt der NPC einen Stufenpunkt, ab 600000 2 Stufenpunkte */
+  SetProp(P_XP, 130000);
+  
+/* Die Groesse des Monsters in cm. Dies wird bei einigen Kampfbefehlen */
+/* ausgewertet, sowie bei einigen Identifikationsspruechen von Gilden.
+ * Irgendwas zwischen 170 und 190 cm.  */
+  SetProp(P_SIZE, 170 + random(21));
+
+/* Ein Gewicht (in Gramm) sollte der NPC haben, irgendwas zwischen 40 und 48
+ * kg.
+ */
+  SetProp(P_WEIGHT, 40000 + random(8000));
+
+/* Weitere Werte: P_(MAX)_FOOD, P_(MAX)_DRINK, P_(MAX)_ALCOHOL,       */
+/* P_MSGIN, P_MSGOUT, P_MMSGIN, P_MMSGOUT, P_MAX_HANDS                */
+
+/* Spezielle Infos (fuer den Identifiziere-Spruch) */
+  SetProp(P_INFO, break_string(
+    "Der Rotaugenvampir laesst sich vielleicht mit Knoblauch vertreiben.",
+    78));
+
+/* NPC koennen einer Klasse angehoeren und Waffen koennten z.B. gegen
+ * bestimmte Klassen/Rassen besonders (in)effektiv sein.
+ */
+  AddClass(({CL_VAMPIRE,CL_UNDEAD}));
+
+/* Resistenzen (negativ) und Anfaelligkeiten (positiv) */
+  SetProp(P_RESISTANCE_STRENGTHS, ([
+        DT_BLUDGEON:0.2,DT_RIP:0.2,
+        DT_MAGIC: -0.2, DT_COLD: -0.1, DT_TERROR: -0.8 ]) );
+  
+// Wer hat den Spieler gekillt und was sagt man dann?
+  SetProp(P_KILL_NAME,"Ein Rotaugenvampir");
+  SetProp(P_KILL_MSG,({"Grossartig %s! Ein weiteres Opfer fuer Zesstra!", 
+                       MSG_SAY}));
+
+  // beschwerde auf -moerder
+  SetProp(P_MURDER_MSG,"Du steckst doch mit Jof im Bunde, %s!");
+  SetProp(P_DIE_MSG," bricht stoehnend zusammen.\n");
+
+  // Auch NPC sollten Details haben:
+  AddDetail( ({"augen","augenlider","lider"}), break_string(
+    "Der Rotaugenvampir schaut Dich mit weit aufgerissenen, rot "
+    "schimmernden Augen wild an.",78));
+  // ...
+
+  // riecht der nach was? -> AddSmells()
+  
+  // Kann man den nach was fragen? -> AddInfo().
+
+}
+
diff --git a/doc/beispiele/rotaugenvampire/rotaugenvampirmagier.c b/doc/beispiele/rotaugenvampire/rotaugenvampirmagier.c
new file mode 100644
index 0000000..a6c5aaf
--- /dev/null
+++ b/doc/beispiele/rotaugenvampire/rotaugenvampirmagier.c
@@ -0,0 +1,77 @@
+/*
+   Ein magisch begabter Beispiel-NPC (von Zesstra, angelehnt an Boings
+   bspmon1.c)
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+// Einige Warnungen werden als Fehler betrachtet (empfohlen)
+#pragma pedantic, range_check
+// Schaltet bestimmte Warnungen ein (empfohlen)
+#pragma warn_deprecated, warn_empty_casts, warn_missing_return
+#pragma warn_function_inconsistent
+
+// Dieser NPC soll ein Rotaugenvampir sein, der ein paar Spells kann. Und nen
+// Rotaugenvampir gibt es schon. Also einfach den normalen Rotaugenvampir
+// aus diesem Verzeichnis erben.
+inherit __DIR__+"rotaugenvampir";
+
+// Inkludiert Definitionen fuer Properties
+#include <properties.h>
+
+protected void create()
+{
+  // Nicht vergessen, ohne das geht nichts. Fuehrt das create() des geerbten
+  // Rotaugenvampir aus und konfiguriert ihn.
+  ::create();
+
+/* Die Kurzbeschreibung wird zum Beispiel angezeigt wenn man in einen Raum
+   mit dem Monster reinlaeuft */
+  SetProp(P_SHORT, "Rotaugenvampirmagier");
+
+/* Beim Anschauen des Monsters wird die long-description angezeigt,
+ * Zeilenumbruch nach Bedarf nach 78 Zeichen. */
+  SetProp(P_LONG, break_string(
+    "Ein finster aussehender Rotaugenvampir in einer Kutte.",78));
+
+/* Ein Name muss sein, da sonst z.B. im Todesfall 'Leiche von 0' daliegt */
+  SetProp(P_NAME, "Rotaugenvampirmagier");
+  SetProp(P_NAME_ADJ,"listenreich");
+
+  // fast alle Eigenschaften uebernehmen wir einfach unveraendert unveraendert
+  // vom normalen Rotaugenvampir. Die Hands nicht, der Magier haut nicht so
+  // gut zu...
+  SetProp(P_HANDS, ({" mit seinen Haenden", 85}));
+
+  // ok, spielt wenig Rolle in diesem Fall, aber damits stilecht ist, kriegt
+  // der hier jetzt etwas mehr an Magiepunkten (spellpoints)
+  SetProp(P_MAX_SP, 350);
+
+  // und noch ein paar Spells
+  // Anmerkung: diese Spells haben nichts mit irgendwelchen Gildenspells zu
+  // tun und - ja, tatsaechlich - verbrauchen keine Magiepunkte...
+
+  // wahrscheinlichkeit in % pro runde, einen Spell zu casten:
+  SetProp(P_SPELLRATE,30);
+  // Ein Spell, der 100 Schadenspunkte macht und in 60% der Faelle ausgewaehlt
+  // wird. Erste Meldung geht an den Spieler, die zweite an den Raum.
+  // Schadenstyp ist Schlagschaden.
+  AddSpell(60,100,
+    break_string(Name(WER) + " macht eine Handbewegung vor Deinem Gesicht. "
+      "So abgelenkt stolperst Du in faellst hart zu Boden.",78),
+    break_string(Name(WER) + " macht eine Handbewegung vor @WESSEN Gesicht. "
+      "@WER stolpert und faellt hart auf den Boden.",78),
+    ({DT_BLUDGEON}) );
+  // Ein Spell, der 800 Schadenspunkte macht und in 40% der Faelle ausgewaehlt
+  // wird. Schadenstyp: Feuer.
+  AddSpell(40,800,
+    break_string(Name(WER) + " schaut Dich mit brennenden Augen "
+      "durchdringend an. Du glaubst, innerlich zu verbrennen.",78),
+    break_string(Name(WER) + " schaut @WEN mit gluehenden Augen an. "
+      "@WER kruemmt sich vor Schmerzen.",78),
+    ({DT_FIRE}) );
+}
+
diff --git a/doc/beispiele/rotaugenvampire/rotaugenvampirmagierin.c b/doc/beispiele/rotaugenvampire/rotaugenvampirmagierin.c
new file mode 100644
index 0000000..b506e1e
--- /dev/null
+++ b/doc/beispiele/rotaugenvampire/rotaugenvampirmagierin.c
@@ -0,0 +1,48 @@
+/*
+   Ein magisch begabter Beispiel-NPC (von Zesstra, angelehnt an Boings
+   bspmon1.c)
+   In diesem Fall soll eine Magierin sein, die aber die gleichen Stats wie der
+   maennliche Kollege hat.
+*/
+
+// Diese Pragmas sorgen dafuer, dass der Driver darauf achtet, dass bei
+// Funktionsargumenten, -Rueckgabewerten und teilweise bei Zuweisung von
+// Werten an Variablen der richtige Datentyp verwendet wird (z.b. kein string
+// anstelle eines int verwendet wird). Sollte in keinem Objekt fehlen.
+#pragma strong_types, save_types, rtt_checks
+// Einige Warnungen werden als Fehler betrachtet (empfohlen)
+#pragma pedantic, range_check
+// Schaltet bestimmte Warnungen ein (empfohlen)
+#pragma warn_deprecated, warn_empty_casts, warn_missing_return
+#pragma warn_function_inconsistent
+
+// Dieser NPC soll eine Rotaugenvampirmagierin sein. Und nen
+// Rotaugenvampirmagier gibt es schon. Also einfach den normalen
+// Rotaugenvampirmagier aus diesem Verzeichnis erben.
+inherit __DIR__+"rotaugenvampirmagier";
+
+// Inkludiert Definitionen fuer Properties
+#include <properties.h>
+#include <language.h> // fuer FEMALE-Define
+
+protected void create()
+{
+  // Nicht vergessen, ohne das geht nichts. Fuehrt das create() des geerbten
+  // Rotaugenvampirmagiers aus und konfiguriert ihn.
+  ::create();
+
+  // Geschlecht aendern.
+  SetProp(P_GENDER, FEMALE);
+
+  // Kurz- und Langbeschreibung aendern.
+  SetProp(P_SHORT, "Rotaugenvampirmagierin");
+  SetProp(P_LONG, break_string(
+    "Eine finster aussehende Rotaugenvampirmagierin in einer Kutte.",78));
+
+  // Name anpassen
+  SetProp(P_NAME, "Rotaugenvampirmagierin");
+
+  // Meldung anpassen.
+  SetProp(P_HANDS, ({" mit ihren Haenden", 85}));
+}
+
diff --git a/doc/beispiele/shadow/aa.c b/doc/beispiele/shadow/aa.c
new file mode 100644
index 0000000..179d7e3
--- /dev/null
+++ b/doc/beispiele/shadow/aa.c
@@ -0,0 +1,8 @@
+     void fun() {
+         printf("%O [a] fun()\n", this_object());
+     }
+
+     void fun3() {
+         printf("%O [a] fun3()\n", this_object());
+     }
+
diff --git a/doc/beispiele/shadow/bb.c b/doc/beispiele/shadow/bb.c
new file mode 100644
index 0000000..9c77090
--- /dev/null
+++ b/doc/beispiele/shadow/bb.c
@@ -0,0 +1,13 @@
+     int fun() {
+         printf("%O [b] fun()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun();
+     }
+
+     void fun2() {
+         printf("%O [b] fun2()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun3();
+         this_object()->fun3();
+     }
+
+     void do_shadow(object target) { shadow(target, 1); }
+
diff --git a/doc/beispiele/shadow/cc.c b/doc/beispiele/shadow/cc.c
new file mode 100644
index 0000000..8aa60ed
--- /dev/null
+++ b/doc/beispiele/shadow/cc.c
@@ -0,0 +1,11 @@
+     int fun() {
+         printf("%O [c] fun()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun();
+     }
+
+     void fun3() {
+         printf("%O [c] fun3()\n", this_object());
+     }
+
+     void do_shadow(object target) { shadow(target, 1); }
+
diff --git a/doc/beispiele/shadow/loadme.c b/doc/beispiele/shadow/loadme.c
new file mode 100644
index 0000000..9d6e4d5
--- /dev/null
+++ b/doc/beispiele/shadow/loadme.c
@@ -0,0 +1,24 @@
+void create() {
+     object a, b, c;
+
+     if (find_object("/doc/beispiele/shadow/aa"))
+       destruct(find_object("/doc/beispiele/shadow/aa"));
+     a = load_object("/doc/beispiele/shadow/aa");
+     if (find_object("/doc/beispiele/shadow/bb"))
+       destruct(find_object("/doc/beispiele/shadow/bb"));
+     b = load_object("/doc/beispiele/shadow/bb");
+     if (find_object("/doc/beispiele/shadow/cc"))
+       destruct(find_object("/doc/beispiele/shadow/cc"));
+     c = load_object("/doc/beispiele/shadow/cc");
+
+     b->do_shadow(a);
+     c->do_shadow(a);
+     printf("--- a->fun() ---\n");
+     a->fun();
+     printf("--- b->fun() ---\n");
+     b->fun();
+     printf("--- c->fun() ---\n");
+     c->fun();
+     printf("--- b->fun2() ---\n");
+     b->fun2();
+}
diff --git a/doc/beispiele/ssp/README b/doc/beispiele/ssp/README
new file mode 100644
index 0000000..bd1cad1
--- /dev/null
+++ b/doc/beispiele/ssp/README
@@ -0,0 +1,3 @@
+Diese Dateien sind nur als Beispiele zu verwenden und nicht in einem
+anderen Mud als dem MorgenGrauen fuer Spieler zugaenglich zu machen.
+  Boing
diff --git a/doc/beispiele/ssp/files.h b/doc/beispiele/ssp/files.h
new file mode 100644
index 0000000..8c5951a
--- /dev/null
+++ b/doc/beispiele/ssp/files.h
@@ -0,0 +1,13 @@
+#define SM(x) ("/doc/beispiele/ssp/"+x)
+#define L1(x) (SM("l1/"+x))
+#define L2(x) (SM("l2/"+x))
+#define L3(x) (SM("l3/"+x))
+#define L4(x) (SM("l4/"+x))
+#define L5(x) (SM("l5/"+x))
+#define L6(x) (SM("l6/"+x))
+#define MON(x) (SM("mon/"+x))
+#define OBJ(x) (SM("obj/"+x))
+
+#define LOG_OBJ "/players/boing/obj/logobj"
+#define PFLANZE "/doc/beispiele/ssp/mon/pflanze"
+#define MMONST "/doc/beispiele/ssp/mon/metallmonster"
diff --git a/doc/beispiele/ssp/l1/m1x1.c b/doc/beispiele/ssp/l1/m1x1.c
new file mode 100644
index 0000000..f954372
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x1.c
@@ -0,0 +1,30 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der Raum ist gefuellt\n"+
+  "mit grau-blauem Rauch, der von dem grossen Drachen stammt, der ihn be-\n"+
+  "wohnt. Es ist sehr warm hier drin und an den Waenden und an der Decke\n"+
+  "kondensiert der Dampf zu kleinen Tropfen. Der einzige Ausgang liegt im\n"+
+  "Osten.\n");
+  AddDetail("raum", "Ein Drache wohnt hier normalerweise.\n");
+  AddDetail(({"drache", "drachen"}), "Er scheint gerade nicht da zu sein.\n");
+  AddDetail("rauch", "Der Rauch zieht zum Ausgang im Osten hinaus.\n");
+  AddDetail(({"wand", "waende", "boden", "decke", "metall", "stahl"}), "Alles hier ist aus reinem Stahl.\n");
+  AddDetail("dampf", "Er kondensiert an den Waenden.\n");
+  AddDetail(({"wasser", "kondenswasser"}), "Es tropft zu Boden.\n");
+  AddDetail("tropfen", "Sie tropfen auf den Boden.\n");
+  AddDetail("ausgang", "Er liegt im Osten.\n");
+  AddItem(MON("stahldrache"), REFRESH_REMOVE);
+  AddExit("osten",L1("m2x1"));
+}
diff --git a/doc/beispiele/ssp/l1/m1x2.c b/doc/beispiele/ssp/l1/m1x2.c
new file mode 100644
index 0000000..c91355a
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x2.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. In dieser gemuetlichen\n"+
+  "Ecke (natuerlich nur fuer Metall liebende Lebewesen) hat sich wohl eine\n"+
+  "der merkwuerdigen Titanwalzen eingenistet, auf jeden Fall ist der Boden\n"+
+  "dermassen plattgewalzt, wie es nur diese Art schaffen kann. Der Gang\n"+
+  "selbst fuehrt hier nach Sueden und Osten.\n");
+  AddDetail("ecke", "Richtig nett hier ...\n");
+  AddDetail(({"wand", "waende", "decke", "metall"}), "Alles hier ist aus Metall.\n");
+  AddDetail(({"walze", "titanwalze"}), "Die Titanwalze scheint gerade nicht daheim zu sein.\n");
+  AddDetail("boden", "Der Boden ist absolut platt.\n");
+  AddDetail("gang", "Ein aus Metall gearbeiteter Gang.\n");
+  AddExit("sueden",L1("m1x3"));
+  AddExit("osten",L1("m2x2"));
+  AddItem(MON("titanwalze"), REFRESH_REMOVE);
+}
diff --git a/doc/beispiele/ssp/l1/m1x3.c b/doc/beispiele/ssp/l1/m1x3.c
new file mode 100644
index 0000000..6093029
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x3.c
@@ -0,0 +1,24 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Eine lange Metallroehre\n"+
+  "fuehrt weiter von Sueden nach Norden und scheint kein Ende zu nehmen. Deine\n"+
+  "Schritte hallen blechern durch die Gaenge und informieren deren Bewohner\n"+
+  "ueber Deine Anwesenheit.\n");
+  AddDetail(({"metallroehre", "roehre", "gang", "gaenge"}), "Du befindest Dich in einer langen Metallroehre.\n");
+  AddDetail("metall", "Das Metall sieht sehr stabil aus.\n");
+  AddDetail(({"boden", "decke", "wand", "waende"}), "Alles ist aus Metall.\n");
+  AddDetail("bewohner", "Hier scheinen keine zu sein.\n");
+  AddExit("norden",L1("m1x2"));
+  AddExit("sueden",L1("m1x4"));
+}
diff --git a/doc/beispiele/ssp/l1/m1x4.c b/doc/beispiele/ssp/l1/m1x4.c
new file mode 100644
index 0000000..a279aad
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x4.c
@@ -0,0 +1,24 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Die Metallroehre, in der\n"+
+  "Du Dich befindest fuehrt von Sueden nach Norden. Auch hier klingt der Boden\n"+
+  "unter Deinen Fuessen recht hohl, es ist wohl wirklich etwas Besonderes\n"+
+  "darunter. Allerdings sind keinerlei Anzeichen fuer einen Zugang zu sehen.\n");
+  AddDetail(({"gang", "roehre", "metallroehre"}), "Der Gang fuehrt nach Norden und Sueden.\n");
+  AddDetail("metall", "Hartes, glaenzendes Metall.\n");
+  AddDetail(({"wand", "waende", "boden", "decke"}), "Alles ist aus Metall.\n");
+  AddDetail("zugang", "Es ist keiner zu sehen.\n");
+  AddExit("norden",L1("m1x3"));
+  AddExit("sueden",L1("m1x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m1x5.c b/doc/beispiele/ssp/l1/m1x5.c
new file mode 100644
index 0000000..694fb6a
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m1x5.c
@@ -0,0 +1,31 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include <moving.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der voellig mit Metall\n"+
+  "verkleidete Gang macht hier eine Biegung von Osten nach Norden, wo er\n"+
+  "in die schwarze Dunkelheit fuehrt. Deine Schritte hallen hier leicht nach,\n"+
+  "es scheint sich wohl ein Hohlraum unter dem Boden zu befinden.\n");
+  AddDetail("metall", "Es scheint Eisen oder Stahl zu sein.\n");
+  AddDetail(({"eisen", "stahl"}), "Du weisst nicht genau, ob es Eisen oder Stahl ist.\n");
+  AddDetail(({"gang", "roehre"}), "Der Gang macht einen Knick.\n");
+  AddDetail("dunkelheit", "Sie verschlingt alles.\n");
+  AddDetail(({"wand", "waende", "boden", "decke"}), "Alles ist aus Metall.\n");
+  AddDetail("hohlraum", "Du kannst keine Hinweise auf einen Zugang finden.\n");
+  AddDetail("zugang", "Du siehst keinen.\n");
+  AddDetail(({"knick", "biegung"}), "So nennt sich sowas halt ... ich kann nix dafuer!\n");
+  AddItem(MON("kampfblech"), REFRESH_REMOVE);
+  
+  AddExit("norden", L1("m1x4"));
+  AddExit("osten",L1("m2x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m2x1.c b/doc/beispiele/ssp/l1/m2x1.c
new file mode 100644
index 0000000..d4e7ae7
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x1.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Dieser Gang hier ist aus\n"+
+  "reinstem Stahl gefertigt, der in Deinem Licht matt funkelt. Aus einer\n"+
+  "Kammer im Westen dringen Rauchschwaden hervor und ein Schnauben ist zu\n"+
+  "hoeren. Du kannst es allerdings auch vorziehen, nach Sueden dem Unheil\n"+
+  "zu entgehen.\n");
+  AddDetail(({"gang", "gaenge", "roehre", "roehren"}), "Der Gang macht eine Biegung von Sueden nach Westen.\n");
+  AddDetail(({"boden", "decke", "wand", "waende", "metall", "stahl"}), "Alles hier ist aus hartem Stahl.\n");
+  AddDetail("kammer", "Im Westen liegt eine Kammer.\n");
+  AddDetail(({"rauchschwaden", "rauch", "schwaden"}), "Der Rauch zieht durch ein paar Ritzen in der Decke ab.\n");
+  AddDetail(({"ritze", "ritzen"}), "Die Ritzen haben nichts Bemerkenswertes an sich.\n");
+  AddDetail("schnauben", "Von wem wohl das Schnauben kommt?\n");
+  AddExit("westen",L1("m1x1"));
+  AddExit("sueden",L1("m2x2"));
+}
diff --git a/doc/beispiele/ssp/l1/m2x2.c b/doc/beispiele/ssp/l1/m2x2.c
new file mode 100644
index 0000000..8cefccd
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x2.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Hier verzweigt sich der\n"+
+  "Gang in verschiedene Metallroehren, die nach Norden, Sueden und Westen\n"+
+  "fuehren. Ausserdem ist in der Decke ein kleines Loch, durch das eine\n"+
+  "Leiter nach oben fuehrt.\n");
+  AddDetail(({"gang", "gaenge", "metallroehre", "metallroehren", "roehre", "roehren"}), "Gaenge fuehren in die verschiedensten Richtungen.\n");
+  AddDetail(({"wand", "waende", "boden", "metall"}), "Hier ist einfach alles aus Metall.\n");
+  AddDetail("leiter", "Die Leiter fuehrt durch ein Loch in der Decke nach oben.\n");
+  AddDetail(({"loch", "decke"}), "In der Decke ist ein Loch.\n");
+  AddExit("sueden",L1("m2x3"));
+  AddExit("norden",L1("m2x1"));
+  AddExit("westen",L1("m1x2"));
+  AddExit("oben", L1("oben"));
+}
diff --git a/doc/beispiele/ssp/l1/m2x3.c b/doc/beispiele/ssp/l1/m2x3.c
new file mode 100644
index 0000000..f291ac2
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x3.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der Gang, in dem Du\n"+
+  "Dich befindest fuehrt schnurgerade von Norden nach Sueden. Die Waende\n"+
+  "reflektieren das Licht und Deine Schritte erzeugen einen metallischen\n"+
+  "Klang auf dem Boden.\n"); 
+  AddDetail(({"boden", "wand", "waende", "decke", "metall"}), "Alles ist aus Metall.\n");
+  AddDetail("gang", "Er fuehrt nach Norden und Sueden.\n");
+  AddDetail("licht", "Es kommt irgendwoher.\n");
+  AddDetail("schritte", "Wenn Du laeufst, machst Du Schritte, das wusstest Du aber, oder?\n");
+  AddDetail("klang", "Der Klang ist nicht sonderlich interessant, aber zweifellos vorhanden.\n");
+  AddExit("norden",L1("m2x2"));
+  AddExit("sueden",L1("m2x4"));
+  AddItem(MON("dosenoeffner"), REFRESH_REMOVE);
+}
diff --git a/doc/beispiele/ssp/l1/m2x4.c b/doc/beispiele/ssp/l1/m2x4.c
new file mode 100644
index 0000000..674b44e
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x4.c
@@ -0,0 +1,22 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der voellig mit Metall\n"+
+  "ausgeschlagene Gang macht hier einen scharfen Knick von Norden nach Osten\n"+
+  "und verschwindet dort in der Dunkelheit.\n");
+  AddDetail(({"wand", "waende", "boden", "decke", "metall"}), "Alles hier ist aus Metall.\n");
+  AddDetail("gang", "Der Gang fuehrt nach Norden und Osten.\n");
+  AddDetail("dunkelheit", "Du kannst hingehen und schauen, ob sie dann noch da ist.\n");
+  AddExit("norden",L1("m2x3"));
+  AddExit("osten",L1("m3x4"));
+}
diff --git a/doc/beispiele/ssp/l1/m2x5.c b/doc/beispiele/ssp/l1/m2x5.c
new file mode 100644
index 0000000..95b0c3d
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m2x5.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <rooms.h>
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Die Waende des Ganges,\n"+
+  "der von Osten nach Westen (oder andersrum) verlaeuft, sind mit glaenzendem\n"+
+  "Metall ausgekleidet. Irgendwie kommt Dir diese Umgebung ziemlich seltsam\n"+
+  "vor, aber keine Sorge, es kommt noch viel schlimmer!\n");
+  AddDetail(({"gang", "roehre"}), "Der Gang verlaeuft von Osten nach Westen.\n");
+  AddDetail(({"wand", "waende", "decke", "boden"}), "Alles ist aus glaenzendem Metall.\n");
+  AddDetail("metall", "Das Metall ist an einer Stelle leicht eingedellt.\n");
+  AddDetail(({"delle", "stelle", "beule"}), "Da wollte wohl jemand mit dem Kopf durch die Wand.\n");
+  AddExit("osten",L1("m3x5"));
+  AddExit("westen",L1("m1x5"));
+  AddItem(MON("dosenoeffner"), REFRESH_REMOVE);
+  AddItem(MON("dosenoeffner"), REFRESH_REMOVE);
+}
diff --git a/doc/beispiele/ssp/l1/m3x1.c b/doc/beispiele/ssp/l1/m3x1.c
new file mode 100644
index 0000000..30022f4
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x1.c
@@ -0,0 +1,31 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist am Eingang zum Hoehlenlabyrinth der Schreckensspitze. Etwas Licht\n"+
+  "dringt vom Ausgang im Norden herein, doch im Sueden lauert die pechschwarze\n"+
+  "Dunkelheit.\n");
+  AddDetail("eingang", "Es ist der Eingang zu mehr, als Du denkst.\n");
+  AddDetail("boden", "Der Boden besteht aus grauem Fels.\n");
+  AddDetail("fels", "Der Fels ist nicht besonders interessant, nur grau.\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind von Orkblut beschmutzt.\n");
+  AddDetail(({"orkblut", "blut"}), "Orks werden hier wohl zum Spass gemetzelt.\n");
+  AddDetail("decke", "Ueber Deinem Kopf, das wird Dir hier noch oefters passieren.\n");
+  AddDetail(({"hoehlenlabyrinth", "labyrinth", "hoehlen"}), "Diese Labyrinth erstreckt sich ueber etliche Ebenen, viel Spass beim\nErkunden.\n");
+  AddDetail("licht", "Das letzte Tageslicht.\n");
+  AddDetail("ausgang", "Der Ausgang aus der Dunkelheit.\n");
+  AddDetail("dunkelheit", "Das wird Dir dort unten noch oefters begegnen.\n");
+  AddItem(MON("ork"), REFRESH_REMOVE);
+  AddItem(MON("ork"), REFRESH_REMOVE);
+  AddExit("norden", "/d/gebirge/room/spitze4");
+  AddExit("sueden",L1("m3x2"));
+}
diff --git a/doc/beispiele/ssp/l1/m3x2.c b/doc/beispiele/ssp/l1/m3x2.c
new file mode 100644
index 0000000..d913527
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x2.c
@@ -0,0 +1,29 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Ein schmaler Gang, der\n"+
+  "von Norden nach Sueden fuehrt, ist hier durch den harten Fels gehauen.\n"+
+  "Der Gang ist nur grob behauen, ein Zeichen dafuer, dass hier nicht Zwerge\n"+
+  "am Werk waren, sondern boese Wesen, wahrscheinlich Orks.\n");
+  AddDetail("fels", "Der Fels ist hart und nur grob behauen.\n");
+  AddDetail(({"gang", "gaenge"}), "Der Gang fuehrt von Norden nach Sueden.\n");
+  AddDetail("boden", "Auf dem Boden siehst Du zahlreiche Ueberreste von Abenteurern, die nicht\nvorsichtig genug waren.\n");
+  AddDetail(({"rest", "ueberrest", "reste", "ueberreste", "abenteurer"}),
+  "Uhoh ... blutige Sache ...\n");
+  AddDetail("blut", "Weia ...\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind aus Fels und nicht sonderlich interessant.\n");
+  AddDetail("decke", "Wenn Du ueberlegst, was da alles ueber Deinem Kopf schwebt ... ohoh!\n");
+  AddDetail(({"ork", "orks"}), "Davon hat es sicher einige in der Naehe.\n");
+  AddDetail(({"zwerg", "zwerge"}), "Zwerge haben hiermit nichts zu tun!\n");
+  AddExit("sueden",L1("m3x3"));
+  AddExit("norden",L1("m3x1"));
+}
diff --git a/doc/beispiele/ssp/l1/m3x3.c b/doc/beispiele/ssp/l1/m3x3.c
new file mode 100644
index 0000000..f84fce5
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x3.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der schmale Gang macht\n"+
+  "hier eine Biegung von Norden nach Osten, wo er jeweils in die Dunkelheit\n"+
+  "fuehrt.\n");
+  AddDetail("gang", "Der Gang macht eine Biegung.\n");
+  AddDetail("dunkelheit", "Schwarze Dunkelheit.\n");
+  AddDetail("boden", "Auf dem Boden ist nichts Besonderes zu sehen.\n");
+  AddDetail("decke", "Die Decke ist total langweilig.\n");
+  AddDetail(({"wand", "waende"}), "An der Wand haengt eine Hand.\n");
+  AddDetail("hand", "Ach nee, hat sich nur gereimt.\n");
+  AddDetail("biegung", "Sie fuehrt nach Norden und Osten.\n");
+  AddExit("norden",L1("m3x2"));
+  AddExit("osten",L1("m4x3"));
+  AddItem(MON("ork"), REFRESH_REMOVE);
+}
diff --git a/doc/beispiele/ssp/l1/m3x4.c b/doc/beispiele/ssp/l1/m3x4.c
new file mode 100644
index 0000000..549492a
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x4.c
@@ -0,0 +1,39 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include <moving.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Metallbeschlagene Waende\n"+
+  "umringen Dich im Norden, Osten und Sueden waehrend ein roehrenartiger Gang\n"+
+  "nach Westen fuehrt. Ausserdem befindet sich im Boden ein Loch, durch das\n"+
+  "eine Leiter nach unten fuehrt.\n");
+  AddDetail("loch", "Was einen da unten wohl erwarten mag?\n");
+  AddDetail("leiter", "Die Leiter fuehrt nach unten.\n");
+  AddDetail("boden", "Im Boden ist ein Loch.\n");
+  AddDetail(({"wand", "waende", "decke", "metall"}), "Alles ist aus Metall.\n");
+  AddDetail(({"roehre", "gang"}), "Der Gang fuehrt nach Westen.\n");
+  AddItem(MON("titanwalze"), REFRESH_REMOVE);
+  AddExit("westen",L1("m2x4"));
+  AddSpecialExit("unten", "unten");
+}
+
+unten()
+{
+  if (present("titanwalze"))
+  {
+    write("Die Titanwalze laesst Dich nicht vorbei.\n");
+    return 1;
+  }
+  this_player()->move(L2("m3x4"), M_GO, "nach unten");
+  this_player()->SetProp("boing:drom_marker", 1);
+  return 1;
+}
diff --git a/doc/beispiele/ssp/l1/m3x5.c b/doc/beispiele/ssp/l1/m3x5.c
new file mode 100644
index 0000000..69c58fa
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m3x5.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der roehrenartige Gang\n"+
+  "fuehrt von Osten nach Westen durch die Dunkelheit, nur hier glaenzt das\n"+
+  "Metall in Deinem Licht.\n");
+  AddDetail(({"gang", "roehre"}), "Wer wohl diesen Gang angelegt hat?\n");
+  AddDetail("dunkelheit", "Du kannst sie nicht erreichen, solange Du Dein Licht an laesst.\n");
+  AddDetail("metall", "Alles hier ist aus blankem Metall.\n");
+  AddDetail("boden", "Ziemlich uninteressant.\n");
+  AddDetail(({"wand", "waende"}), "Hey! Da ist eine Inschrift!\n");
+  AddDetail("inschrift", "Das ist etwas, was man lesen kann.\n");
+  AddReadDetail("inschrift", "Du liest: Boing war hier.\n");
+  AddDetail("decke", "Ist sie nicht huebsch?\n");
+  AddExit("osten",L1("m4x5"));
+  AddExit("westen",L1("m2x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m4x1.c b/doc/beispiele/ssp/l1/m4x1.c
new file mode 100644
index 0000000..a64351e
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x1.c
@@ -0,0 +1,38 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Du hast die Hoehle eines\n"+
+  "schrecklichen Untiers erreicht. Der Gestank ist wirklich grauenerregend\n"+
+  "und der Anblick rumliegender Knochen und halb verwester Koerperteile von\n"+
+  "armen Opfern tut sein Uebriges, um Dir den Appetit zu verderben. Der\n"+
+  "einzige Ausgang aus diesem Loch befindet sich im Osten.\n");
+  AddDetail(({"hoehle", "loch"}), "Ein uebles Loch, in das Du hier geraten bist.\n");
+  AddDetail("gestank", "Dir wird beinahe schlecht.\n");
+  AddDetail(({"teile", "koerperteile"}), "Buah, das ist ja widerlich.\n");
+  AddDetail("ausgang", "Der Ausgang ist im Osten.\n");
+  AddSpecialDetail("knochen", "knochen");
+  AddDetail(({"wand", "waende"}), "Die Waende sind langweilig und grau.\n");
+  AddDetail("decke", "Die Decke ist uninteressant.\n");
+  AddDetail("boden", "Die verwesenden Koerperteile auf dem Boden sind kein schoener Anblick.\n");
+  AddExit("osten",L1("m5x1"));
+  AddItem(MON("trollmops"), REFRESH_REMOVE);
+}
+
+knochen()
+{
+   if (present("trollmops"))
+      return "Der Trollmops laesst nicht zu, dass Du sein Abendessen durchwuehlst.\n";
+
+   if (this_player()->FindPotion("Du wuehlst in den Knochen herum und findest einen Zaubertrank.\n"))
+      return "";
+   return "Du wuehlst in den Knochen herum, findest aber nichts.\n";
+}
diff --git a/doc/beispiele/ssp/l1/m4x2.c b/doc/beispiele/ssp/l1/m4x2.c
new file mode 100644
index 0000000..1456ef2
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x2.c
@@ -0,0 +1,41 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Das hier scheint wohl\n"+
+  "der Aufenthaltsraum von ein paar stinkenden Trollen zu sein. Eine Menge\n"+
+  "alter Knochen liegen auf dem Boden rum und in der Ecke stinkt ein grosser\n"+
+  "Haufen Trollkot vor sich hin. Alles in allem kein gemuetlicher Ort,\n"+
+  "vielleicht solltest Du ihn nach Sueden verlassen.\n");
+  AddDetail("knochen", "Die Knochen wurden von Trollen abgenagt.\n");
+  AddDetail("boden", "Auf dem Boden liegen Knochen.\n");
+  AddDetail("decke", "Die Decke hier ist nicht so grauenhaft interessant, ich wette es wird\ninteressanter, wenn Du ein paar Ebenen tiefer vordringst.\n");
+  AddDetail(({"ebene", "ebenen"}), "Tja, wenn Du wuesstest wieviele Hohlraeume sich unter Dir befinden, dann\nwuerdest Du hier nicht so ruhig stehen.\n");
+  AddDetail(({"hohlraum", "hohlraeume"}), "Erkunde sie! Sofort!\n");
+  AddDetail(({"wand", "waende"}), "Sie sind verschmiert und ekelhaft.\n");
+  AddDetail("troll", "Keiner da! Aetschbaetsch!\n");
+  AddDetail("ecke", "Wuerg!\n");
+  AddDetail(({"trollkot", "kot", "haufen"}), "Igitt! Das stinkt ja erbaermlich.\n");
+  AddExit("sueden",L1("m4x3"));
+  AddItem(MON("troll"), REFRESH_REMOVE);
+  AddItem(MON("troll"), REFRESH_REMOVE);
+  AddCmd("erkunde", "erkunden");
+}
+
+erkunden(str)
+{ 
+   notify_fail("Was moechtest Du erkunden?\n");
+   if (!str || (str!="hohlraum" && str !="hohlraeume"))
+      return 0;
+   write("Also ein bisschen mehr musst Du da schon fuer tun.\n");
+   return 1;
+}
diff --git a/doc/beispiele/ssp/l1/m4x3.c b/doc/beispiele/ssp/l1/m4x3.c
new file mode 100644
index 0000000..37472a9
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x3.c
@@ -0,0 +1,31 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der durch den harten\n"+
+  "Fels gehauene Gang verzweigt sich hier nach Norden, Osten und Westen.\n"+
+  "Du stellst fest, dass vom Norden her ein ziemlich unangenehmer Geruch\n"+
+  "kommt.\n");
+  AddDetail("fels", "Der Fels wurde von Orks oder Trollen bearbeitet, und das ziemlich schlecht.\n");
+  AddDetail(({"gang", "gaenge"}), "Der Gang verzweigt sich hier.\n");
+  AddDetail("geruch", "Man koennte es auch Gestank nennen.\n");
+  AddDetail("gestank", "Wenn der Himmel hier sichtbar waere, wuerde es zu ihm stinken.\n");
+  AddDetail("boden", "Auf dem Boden findest Du nichts von Bedeutung.\n");
+  AddDetail("decke", "Grauer Fels.\n");
+  AddDetail(({"wand", "waende"}), "An der Wand siehst Du eine Inschrift.\n");
+  AddDetail("inschrift", "Du kannst sie lesen.\n");
+  AddReadDetail("inschrift", "Du liest: Nicht alles, was man nicht sieht, ist auch wichtig.\n");
+  AddDetail(({"orks", "trolle"}), "Die laufen hier irgendwo rum ... oder liegen tot in der Ecke.\n");
+  AddDetail("ecke", "In dieser Ecke sind jedenfalls keine.\n");
+  AddExit("norden",L1("m4x2"));
+  AddExit("osten",L1("m5x3"));
+  AddExit("westen",L1("m3x3"));
+}
diff --git a/doc/beispiele/ssp/l1/m4x4.c b/doc/beispiele/ssp/l1/m4x4.c
new file mode 100644
index 0000000..be0485f
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x4.c
@@ -0,0 +1,28 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Dies ist zweifellos die\n"+
+  "Heimat eines der beruechtigten Eisenfresser, die Waende sehen auch schon\n"+
+  "ganz zernagt aus. Der einzige Ausgang fuehrt nach Sueden.\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind aus reinem Eisen und wurden von einem Eisenfresser schon\nziemlich stark misshandelt.\n");
+  AddDetail("boden", "Der Boden ist aus Metall und funkelt im Licht. Solltest Du natuerlich Nacht-\nsicht haben, dann funkelt es nur in Deiner Einbildung.\n");
+  AddDetail("decke", "Die Decke hat eine gewaltige Last zu tragen.\n");
+  AddDetail("last", "Frag mich nicht wieviele Tonnen Gestein sich ueber Dir befinden.\n");
+  AddDetail("gestein", "Sowas gibt es im Gebirge, wenn es auch hier nicht so offensichtlich ist.\n");
+  AddDetail("gebirge", "Ach hoer doch auf ...\n");
+  AddDetail("eisenfresser", "Der hat sich wohl zu Tode gefressen.\n");
+  AddDetail(({"metall", "eisen"}), "Es glaenzt matt.\n");
+  AddDetail("ausgang", "Er liegt im Sueden.\n");
+  AddItem(MON("eisenfresser"), REFRESH_REMOVE);
+  AddExit("sueden",L1("m4x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m4x5.c b/doc/beispiele/ssp/l1/m4x5.c
new file mode 100644
index 0000000..d64774b
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m4x5.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Die metallischen Roehren\n"+
+  "verzweigen sich hier nach Norden, Osten und Westen. Im Norden scheint etwas\n"+
+  "Unangenehmes zu lauern, merkwuerdige Geraeusche dringen von dort hierher.\n");
+  AddDetail(({"wand", "waende", "roehre", "roehren", "gaenge", "gang"}), "Die Gaenge sind voellig mit Metall ausgekleidet.\n");
+  AddDetail("metall", "Das Metall glaenzt silbern.\n");
+  AddDetail("unangenehmes", "Wer weiss, was sich dort verbirgt ...\n");
+  AddDetail("boden", "Du bist froh, dass es hier einen Boden gibt, sonst wuerdest Du tief fallen.\n");
+  AddDetail("decke", "Die Decke ist metallisch und glaenzt.\n");
+  AddDetail(({"geraeusch", "geraeusche"}), "Es quietscht.\n");
+  AddExit("norden",L1("m4x4"));
+  AddExit("osten",L1("m5x5"));
+  AddExit("westen",L1("m3x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m5x1.c b/doc/beispiele/ssp/l1/m5x1.c
new file mode 100644
index 0000000..5865a91
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x1.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der grob behauene Gang\n"+
+  "macht hier eine Biegung von Sueden nach Westen, wo er in einem schwarzen\n"+
+  "Loch verschwindet, aus dem ein fuerchterlicher Gestank dringt.\n"); 
+  AddDetail("gang", "Der Gang fuehrt in die Dunkelheit.\n");
+  AddDetail("dunkelheit", "Schwarze, lichtlose Dunkelheit.\n");
+  AddDetail("loch", "Hier lauert irgend etwas Schreckliches.\n");
+  AddDetail("gestank", "Der Gestank ist wirklich grauenhaft.\n");
+  AddDetail("boden", "Hoppla, hier liegen Fleischfetzen rum, im Westen scheint wohl was zu wueten.\n");
+  AddDetail(({"fleischfetzen", "fetzen", "fleisch"}), "Ist ja eklig!\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind verschmiert.\n");
+  AddDetail("decke", "Gaehn.\n");
+  AddExit("westen",L1("m4x1"));
+  AddExit("sueden",L1("m5x2"));
+}
diff --git a/doc/beispiele/ssp/l1/m5x2.c b/doc/beispiele/ssp/l1/m5x2.c
new file mode 100644
index 0000000..75f6a5f
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x2.c
@@ -0,0 +1,26 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Ein mit roher Gewalt in\n"+
+  "den Fels genagter Gang fuehrt von Sueden nach Norden. Du spuerst, dass\n"+
+  "hinter jeder Ecke Orks oder anderes uebles Gezuecht lauern koennen.\n");
+  AddDetail(({"gang", "gaenge"}), "Der Gang fuehrt von Sueden nach Norden.\n");
+  AddDetail("fels", "Es ist ein harter Fels, der von boesen Wesen durchbohrt wurde.\n");
+  AddDetail(({"ork", "orks", "gezuecht"}), "Momentan siehst Du keine Orks, aber das kann sich ja schnell aendern.\n");
+  AddDetail("boden", "Blanker Fels.\n");
+  AddDetail("fels", "Das wird allmaehlich langweilig.\n");
+  AddDetail("decke", "An der Decke haengt eine bunte Girlande.\n");
+  AddDetail("girlande", "Wer die wohl da aufgehaengt hat?\n");
+  AddDetail(({"wand", "waende"}), "Da gibt es nichts interessantes zu sehen.\n");
+  AddExit("norden",L1("m5x1"));
+  AddExit("sueden",L1("m5x3"));
+}
diff --git a/doc/beispiele/ssp/l1/m5x3.c b/doc/beispiele/ssp/l1/m5x3.c
new file mode 100644
index 0000000..b7d4ce7
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x3.c
@@ -0,0 +1,32 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <moving.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Steinebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Dunkle Gaenge fuehren\n"+
+  "nach Norden, Sueden und Westen. Der suedliche Gang ist etwas merkwuerdig,\n"+
+  "denn sein Eingang ist mit glaenzendem Metall seltsam beschlagen.\n");
+  AddDetail(({"felsboden", "boden"}), "Der blanke Felsboden geht im Sueden in Metall ueber.\n");
+  AddDetail(({"gang", "gaenge"}), "Es sind Gaenge der Orks.\n");
+  AddDetail("eingang", "Im Sueden glaenzen die Waende, die mit Metall beschlagen sind.\n");
+  AddDetail(({"wand", "waende"}), "Die Waende sind da ... wie immer.\n");
+  AddDetail("decke", "Die Decke ist nicht interessant.\n");
+  AddDetail("fels", "Grauer Fels.\n");
+  AddDetail("metall", "Es scheint Eisen zu sein.\n");
+  AddDetail("eisen", "Ja, zweifellos, es ist Eisen.\n");
+  AddExit("westen",L1("m4x3"));
+  AddExit("norden",L1("m5x2"));
+  AddExit("sueden",L1("m5x4"));
+
+  AddItem(MON("orkchef"), REFRESH_REMOVE);
+}
+
diff --git a/doc/beispiele/ssp/l1/m5x4.c b/doc/beispiele/ssp/l1/m5x4.c
new file mode 100644
index 0000000..b95d15e
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x4.c
@@ -0,0 +1,25 @@
+inherit "std/room";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Der Gang, der hier von\n"+
+  "Norden nach Sueden fuehrt, aehnelt mehr einer Roehre, denn alles ist voll-\n"+
+  "staendig aus einem glaenzenden Metall. Du fragst Dich, wer wohl diese\n"+
+  "Gaenge angelegt hat.\n");
+  AddDetail(({"gang", "gaenge", "roehre", "rohr"}), "Die Gaenge sind voellig mit Metall ausgekleidet.\n");
+  AddDetail("metall", "Das Metall glaenzt silbern.\n");
+  AddDetail(({"wand", "waende"}), "Die Waende glaenzen silbern.\n");
+  AddDetail("boden", "Sei froh, dass er da ist.\n");
+  AddDetail("decke", "Die Decke ist wirklich ziemlich langweilig.\n");
+  AddExit("norden",L1("m5x3"));
+  AddExit("sueden",L1("m5x5"));
+}
diff --git a/doc/beispiele/ssp/l1/m5x5.c b/doc/beispiele/ssp/l1/m5x5.c
new file mode 100644
index 0000000..4f99ba1
--- /dev/null
+++ b/doc/beispiele/ssp/l1/m5x5.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+
+create()
+{
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Metallebene");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Eigentlich koennte man\n"+
+  "es auch fast Roehrenlabyrinth nennen, denn Du befindest Dich in einer\n"+
+  "solchen, die hier eine Biegung von Norden nach Westen macht. Die Waende\n"+
+  "sind aus einem glaenzenden Metall gefertigt, was Dir ziemlich merkwuerdig\n"+
+  "vorkommt.\n");
+  AddDetail(({"wand", "waende", "roehre", "roehren", "gaenge", "gang"}), "Die Gaenge sind voellig mit Metall ausgekleidet.\n");
+  AddDetail("metall", "Das Metall glaenzt silbern.\n");
+  AddDetail("boden", "Der Boden ist aus Metall.\n");
+  AddDetail("decke", "Selbst die Decke glaenzt metallisch, Du fragst Dich, wer das angelegt hat.\n");
+  AddDetail("biegung", "Die Biegung fuehrt von Norden nach Westen.\n");
+  AddItem(MON("kampfblech"), REFRESH_REMOVE);
+  AddExit("norden",L1("m5x4"));
+  AddExit("westen",L1("m4x5"));
+}
diff --git a/doc/beispiele/ssp/l1/oben.c b/doc/beispiele/ssp/l1/oben.c
new file mode 100644
index 0000000..f3bc039
--- /dev/null
+++ b/doc/beispiele/ssp/l1/oben.c
@@ -0,0 +1,27 @@
+inherit "std/room";
+ 
+#include <properties.h>
+#include <rooms.h>
+#include "../files.h"
+ 
+create()
+{
+  replace_program("std/room");
+  ::create();
+  SetProp(P_LIGHT, 0);
+  SetProp(P_INDOORS, 1);
+  SetProp(P_INT_SHORT, "Beim Knochenschaeler");
+  SetProp(P_INT_LONG,
+  "Du bist im Hoehlenlabyrinth der Schreckensspitze. Dieser kleine Raum ist\n"+
+  "die Heimat eines fuerchterlichen Ungeheuers, die Heimat des schrecklichen\n"+
+  "Knochenschaelers. Im Boden des Raums ist ein kleines Loch, durch das eine\n"+
+  "Leiter nach unten fuehrt.\n");
+  AddDetail("raum", "Der Raum ist ziemlich klein.\n");
+  AddDetail(({"wand", "decke", "waende", "metall"}), "Alles ist aus Metall.\n");
+  AddDetail(({"boden", "loch"}), "Im Boden ist ein Loch, durch das eine Leiter nach unten fuehrt.\n");
+  AddDetail("leiter", "Die Leiter fuehrt nach unten.\n");
+  AddDetail("ungeheuer", "Der Knochenschaeler ist einfach fuerchterlich.\n");
+  AddDetail("knochenschaeler", "Zum Glueck ist er gerade nicht daheim.\n");
+  AddItem(MON("knochenschaeler"), REFRESH_REMOVE);
+  AddExit("unten", L1("m2x2"));
+}
diff --git a/doc/beispiele/ssp/mon/dosenoeffner.c b/doc/beispiele/ssp/mon/dosenoeffner.c
new file mode 100644
index 0000000..46d627c
--- /dev/null
+++ b/doc/beispiele/ssp/mon/dosenoeffner.c
@@ -0,0 +1,24 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit MMONST;
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   AddId(({"dosenoeffner", "oeffner"}));
+   AddAdjective(({"mobiler", "mobilen"}));
+   SetProp(P_SHORT, "Ein mobiler Dosenoeffner");
+   SetProp(P_LONG, "Der Dosenoeffner moechte Dir sicherlich den Kopf mit seinen scharfen\nSchneideraedern oeffnen.\n");
+   SetProp(P_NAME, "Dosenoeffner");
+   SetProp(P_GENDER, 1);
+   SetProp(P_LEVEL, 12);
+   SetProp(P_MAX_HP, 120);
+   SetProp(P_ALIGN, -123);
+   SetProp(P_BODY, 80);
+   SetProp(P_HANDS, ({" mit scharfen Schneideraedern", 50}));
+   SetProp(P_XP, 30000);
+   SetProp(P_SIZE, random(20)+40);
+   set_living_name("dosenoeffner");
+}
diff --git a/doc/beispiele/ssp/mon/eisenfresser.c b/doc/beispiele/ssp/mon/eisenfresser.c
new file mode 100644
index 0000000..ba7b041
--- /dev/null
+++ b/doc/beispiele/ssp/mon/eisenfresser.c
@@ -0,0 +1,28 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit MMONST;
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   AddId(({"eisenfresser", "fresser"}));
+   SetProp(P_SHORT, "Ein Eisenfresser");
+   SetProp(P_LONG,
+   "Eisenfresser ernaehren sich ausschliesslich von Eisen, allerdings sind\n"+
+   "sie so kurzsichtig, dass sie erstmal in alles reinbeissen, was sie\n"+
+   "irgendwie wahrnehmen.\n");
+   SetProp(P_NAME, "Eisenfresser");
+   SetProp(P_GENDER, 1);
+   SetProp(P_LEVEL, 14);
+   SetProp(P_MAX_HP, 150);
+   SetProp(P_ALIGN, -215);
+   SetProp(P_BODY, 75);
+   SetProp(P_HANDS, ({" mit eisenbeschlagenen Zaehnen", 55}));
+   SetProp(P_XP, 42000);
+   SetProp(P_AGGRESSIVE, 1);
+   SetProp(P_SIZE, random(200)+50);   /* Naja, kurzsichtig halt... ;-) */
+   set_living_name("eisenfresser");
+   AddItem( OBJ("eisenklumpen") );
+}
diff --git a/doc/beispiele/ssp/mon/kampfblech.c b/doc/beispiele/ssp/mon/kampfblech.c
new file mode 100644
index 0000000..e218d01
--- /dev/null
+++ b/doc/beispiele/ssp/mon/kampfblech.c
@@ -0,0 +1,36 @@
+#include <properties.h>
+#include <combat.h>
+#include "../files.h"
+
+inherit "std/npc";
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Kampfblech");
+   SetProp(P_LONG, 
+   "Das Kampfblech sieht irgendwie aus wie ein normales Backblech, nur\n"+
+   "viel gefaehrlicher!\n");
+   SetProp(P_NAME, "Kampfblech");
+   SetProp(P_GENDER, 0);
+   AddId(({"blech", "kampfblech","\nkampfblech"}));
+   SetProp(P_LEVEL, 8);
+   SetProp(P_MAX_HP, 100);
+   SetProp(P_ALIGN, -33);
+   SetProp(P_BODY, 70);
+   SetProp(P_HANDS, ({" mit eisenharten Schlaegen", 60}));
+   SetProp(P_XP, 30000);
+   SetProp(P_SIZE, 40);
+   SetProp(P_RACE, "Metallmonster");
+   SetProp(P_VULNERABILITY, ({ DT_WATER }));
+   SetProp(P_NOCORPSE, 1);
+   SetProp(P_DIE_MSG, " faellt laut scheppernd um.\n");
+   set_living_name("kampfblech");
+}
+
+die()
+{
+   clone_object(OBJ("kampfblech"))->move(environment());
+   ::die();
+}
diff --git a/doc/beispiele/ssp/mon/knochenschaeler.c b/doc/beispiele/ssp/mon/knochenschaeler.c
new file mode 100644
index 0000000..84c1e3b
--- /dev/null
+++ b/doc/beispiele/ssp/mon/knochenschaeler.c
@@ -0,0 +1,43 @@
+#include <properties.h>
+#include <combat.h>
+#include "../files.h"
+
+inherit MMONST;
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Der Knochenschaeler");
+   SetProp(P_LONG,
+   "Der Knochenschaeler geht um, geht um\n"+
+   "Der Knochenschaeler geht um, geht um\n"+
+   "Sein Messer so lang, wie tausend grosse Zaehne\n"+
+   "Wie tausend grosse Zaehne, sein Messer so lang\n"+
+   "Er schneidet Dich in Stuecke, portionsgerecht und fein\n"+
+   "Er schneidet Dich in Stuecke, und keiner tuts ihm gleich\n"+
+   "Er schaelt die Knochen, er quaelt Deinen Geist\n"+
+   "Er schaelt die Knochen, er quaelt Deinen Geist\n"+
+   "Habet acht, habet acht! Seiet vorsichtig, habet Acht!\n"+
+   "Schau Dich um, schau Dich um\n"+
+   "Schau Dich um, Du wirst der naechste sein\n");
+   SetProp(P_NAME, "Knochenschaeler");
+   SetProp(P_GENDER, 1);
+   AddId(({"schaeler", "knochenschaeler"}));
+   SetProp(P_LEVEL, 18);
+   SetProp(P_MAX_HP, 300);
+   SetProp(P_ALIGN, -789);
+   SetProp(P_HANDS, ({" mit seinem langen Messer", 145}) );
+   SetProp(P_BODY, 110);
+   SetProp(P_XP, 220000);
+   SetProp(P_AGGRESSIVE, 1);
+   SetProp(P_SIZE, 220);
+   set_living_name("knochenschaeler");
+   clone_object(OBJ("schaelmesser"))->move(this_object());
+   command("zuecke messer");
+}
+
+QueryArticle(c, d, f)
+{
+   return ::QueryArticle(c, 1, f);
+}
diff --git a/doc/beispiele/ssp/mon/metallmonster.c b/doc/beispiele/ssp/mon/metallmonster.c
new file mode 100644
index 0000000..5482186
--- /dev/null
+++ b/doc/beispiele/ssp/mon/metallmonster.c
@@ -0,0 +1,28 @@
+inherit "std/npc";
+
+#include <properties.h>
+#include <combat.h>
+#include "../files.h"
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_NOCORPSE, 1);
+   SetProp(P_RACE, "Metallmonster");
+   SetProp(P_DIE_MSG, " zerfaellt in seine Bestandteile.\n");
+   SetProp(P_VULNERABILITY, ({ DT_WATER }));
+}
+
+die()
+{
+   create_blech();
+   ::die();
+}
+
+create_blech()
+{
+   object b;
+   b = clone_object(OBJ("blech"));
+   b->move(environment(this_object()));
+}
diff --git a/doc/beispiele/ssp/mon/ork.c b/doc/beispiele/ssp/mon/ork.c
new file mode 100644
index 0000000..975e596
--- /dev/null
+++ b/doc/beispiele/ssp/mon/ork.c
@@ -0,0 +1,26 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit "std/npc";
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein grimmiger Ork");
+   SetProp(P_LONG, "Der Ork schaut Dich unfreundlich an und wedelt mit seinem Krummschwert.\n");
+   SetProp(P_NAME, "Ork");
+   SetProp(P_GENDER, 1);
+   AddId("ork");
+   SetProp(P_RACE, "Ork");
+   SetProp(P_LEVEL, 10);
+   SetProp(P_MAX_HP, 130);
+   SetProp(P_ALIGN, -250);
+   SetProp(P_XP, 90000);
+   SetProp(P_BODY, 50);
+   SetProp(P_SIZE, random(20)+110);
+   set_living_name("ork");
+   seteuid(getuid(this_object()));
+   AddItem(OBJ("krummschwert"),CLONE_WIELD);
+   AddItem(OBJ("orkhose"),CLONE_WEAR);
+}
diff --git a/doc/beispiele/ssp/mon/orkchef.c b/doc/beispiele/ssp/mon/orkchef.c
new file mode 100644
index 0000000..2d6e6cd
--- /dev/null
+++ b/doc/beispiele/ssp/mon/orkchef.c
@@ -0,0 +1,29 @@
+inherit "std/npc";
+
+#include <properties.h>
+#include "../files.h"
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Anfuehrer der Orks");
+   SetProp(P_LONG, "Dies ist ein fetter, stinkender Ork-Haeuptling, der Dir alles \nandere als freundlich gesonnen ist.\n");
+   SetProp(P_NAME, "Ork");
+   SetProp(P_GENDER, 1);
+   AddId(({"ork", "anfuehrer", "haeuptling"}));
+   SetProp(P_RACE, "Ork");
+   SetProp(P_LEVEL, 16);
+   SetProp(P_MAX_HP, 220);
+   SetProp(P_ALIGN, -280);
+   SetProp(P_XP, 160000);
+   SetProp(P_BODY, 60);
+   SetProp(P_SIZE, random(20)+130);
+   set_living_name("orkchef");
+   seteuid(getuid(this_object()));
+   AddItem(OBJ("saebel"),CLONE_WIELD);
+   AddItem(OBJ("orkhose"),CLONE_WEAR);
+   AddItem(OBJ("orkhelm"),CLONE_WEAR);
+}
+
+      
diff --git a/doc/beispiele/ssp/mon/stahldrache.c b/doc/beispiele/ssp/mon/stahldrache.c
new file mode 100644
index 0000000..b4efcac
--- /dev/null
+++ b/doc/beispiele/ssp/mon/stahldrache.c
@@ -0,0 +1,39 @@
+#include <properties.h>
+#include <combat.h>
+#include "../files.h"
+
+inherit MMONST;
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Stahldrache");
+   SetProp(P_LONG,
+   "Der Stahldrache ist ein ernstzunehmender Gegner, gepanzert mit Platten\n"+
+   "aus reinem Stahl ist es schwer, ihm irgendwie Schaden zuzufuegen.\n");
+   SetProp(P_NAME, ({"Stahldrache", "Stahldrachen", "Stahldrachen", "Stahldrachen"}));
+   SetProp(P_GENDER, 1);
+   AddId(({"drache", "stahldrache", "drachen", "stahldrachen"}));
+   SetProp(P_RACE, "Drache");
+   SetProp(P_LEVEL, 20);
+   SetProp(P_MAX_HP, 400);
+   SetProp(P_ALIGN, -250);
+   SetProp(P_HANDS, ({" mit staehlernen Klauen", 150}));
+   SetProp(P_BODY, 130);
+   SetProp(P_XP, 300000);
+   SetProp(P_SIZE, random(50)+250);
+   SetChats(40, ({
+      "Der Stahldrache schnaubt laut.\n",
+      "Der Stahldrache schaut Dich mit staehlernem Blick an.\n",
+      "Der Stahldrache waelzt sich herum.\n",
+      "Der Stahldrache spuckt etwas stahlblaues Feuer.\n",
+   }) );
+   AddSpell(1, 115, "Der Stahldrache spuckt stahlblaues Feuer auf Dich.\n",
+  	            "Der Stahldrache spuckt stahlblaues Feuer auf @WEN.\n",
+	    DT_FIRE);
+   SetProp(P_SPELLRATE,20);
+   clone_object(OBJ("gummistiefel"))->move(this_object());
+   clone_object(OBJ("stahlschwert"))->move(this_object());
+   set_living_name("stahldrache");
+}
diff --git a/doc/beispiele/ssp/mon/titanwalze.c b/doc/beispiele/ssp/mon/titanwalze.c
new file mode 100644
index 0000000..23113e6
--- /dev/null
+++ b/doc/beispiele/ssp/mon/titanwalze.c
@@ -0,0 +1,30 @@
+#include <properties.h>                    
+#include <combat.h>
+#include "../files.h"
+
+inherit MMONST;
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Eine Titanwalze");
+   SetProp(P_LONG, "Pass nur auf, dass diese Titanwalze Dir nicht ueber die Zehen rollt.\nBei diesem Gewicht koennte das auesserst unangenehme Folgen haben.\n");
+   SetProp(P_NAME, "Titanwalze");
+   SetProp(P_GENDER, 2);
+   AddId(({"walze", "titanwalze"}));
+   SetProp(P_LEVEL, 14);
+   SetProp(P_MAX_HP, 170);
+   SetProp(P_ALIGN, 120);
+   SetProp(P_XP, 51000);
+   SetProp(P_BODY, 90);
+   SetProp(P_HANDS, ({" mit wuchtigen Schlaegen", 60}));
+   SetProp(P_SIZE, 210);
+   SetProp(P_DIE_MSG, " zerfaellt in ihre Bestandteile.\n");
+   SetAttackChats(30, ({
+   "Die Titanwalze versucht Dich platt zu walzen.\n",
+   "Die Titanwalze macht: Rumpel, polter ...\n",
+   "Die Titanwalze roehrt.\n"}));
+   set_living_name("titanwalze");
+   AddItem(OBJ("titanring")); 
+}
diff --git a/doc/beispiele/ssp/mon/troll.c b/doc/beispiele/ssp/mon/troll.c
new file mode 100644
index 0000000..8eb1043
--- /dev/null
+++ b/doc/beispiele/ssp/mon/troll.c
@@ -0,0 +1,28 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit "std/npc";
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Troll");
+   SetProp(P_LONG, "Ein Troll wie aus dem Bilderbuch: Gross, haesslich und dumm.\n");
+   SetProp(P_NAME, "Troll");
+   SetProp(P_GENDER, 1);
+   SetProp(P_RACE, "Troll");
+   AddId("troll");
+   SetProp(P_LEVEL, 15);
+   SetProp(P_MAX_HP, 200);
+   SetProp(P_ALIGN, -417);
+   SetProp(P_XP, 120000);
+   SetProp(P_BODY, 35);
+   SetProp(P_SIZE, random(40)+199);
+   set_living_name("troll");
+   seteuid(getuid(this_object()));
+   AddItem(OBJ("trolldolch"),CLONE_WIELD);
+   AddItem(OBJ("steinring"),CLONE_WEAR);
+   AddItem(OBJ("lkhemd"),CLONE_WEAR);
+}
+      
diff --git a/doc/beispiele/ssp/mon/trollmops.c b/doc/beispiele/ssp/mon/trollmops.c
new file mode 100644
index 0000000..5830796
--- /dev/null
+++ b/doc/beispiele/ssp/mon/trollmops.c
@@ -0,0 +1,31 @@
+#include <properties.h>
+#include "../files.h"
+
+inherit "std/npc";
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Trollmops");
+   SetProp(P_LONG, 
+   "Dies ist einer der sagenumwobenen, blutruenstigen Trollmoepse. Hervor-\n"+
+   "gegangen aus der misslungenen Kreuzung zwischen einem Troll und einem\n"+
+   "Mops, terrorisieren diese grausamen Bestien jetzt die Welt. Flieh, so-\n"+
+   "lange Du noch kannst.\n");
+   SetProp(P_NAME, "Trollmops");
+   SetProp(P_GENDER, 1);
+   AddId("trollmops");
+   AddId("troll");
+   AddId("mops");
+   SetProp(P_RACE, "Troll");
+   SetProp(P_LEVEL, 20);
+   SetProp(P_MAX_HP, 350);
+   SetProp(P_ALIGN, -735 - random(100));
+   SetProp(P_HANDS, ({" mit blutverschmierten Krallen", 200 +random(10)}));
+   SetProp(P_XP, 350000);
+   SetProp(P_BODY, 140 + random(40));
+   SetProp(P_SIZE, random(20)+105);  /* Da sind die Groessen der Eltern drin */
+   set_living_name("trollmops");
+   SetProp(P_AGGRESSIVE, 1);
+}
diff --git a/doc/beispiele/ssp/obj/blech.c b/doc/beispiele/ssp/obj/blech.c
new file mode 100644
index 0000000..5c5c2ec
--- /dev/null
+++ b/doc/beispiele/ssp/obj/blech.c
@@ -0,0 +1,16 @@
+#include <properties.h>
+
+inherit "/std/thing";
+
+create() {
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein altes Blech");
+  SetProp(P_LONG, "Das sind die Ueberreste eines Metallmonsters.\n");
+  SetProp(P_NAME, "Blech");
+  SetProp(P_GENDER, 0);
+  AddId("blech");
+  AddAdjective(({"alt", "altes"}));
+  SetProp(P_WEIGHT, 1100);
+  SetProp(P_VALUE, random(QueryProp(P_MAX_HP))+100);
+}
diff --git a/doc/beispiele/ssp/obj/eisenklumpen.c b/doc/beispiele/ssp/obj/eisenklumpen.c
new file mode 100644
index 0000000..bac122b
--- /dev/null
+++ b/doc/beispiele/ssp/obj/eisenklumpen.c
@@ -0,0 +1,16 @@
+#include <properties.h>
+
+inherit "/std/thing";
+
+create() {
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Klumpen Eisen");
+  SetProp(P_LONG, "Sieht aus, als haette da schon jemand dran rumgenagt. Derjenige muss\naber sehr stabile Zaehne gehabt haben.\n");
+  SetProp(P_NAME, "Klumpen");
+  SetProp(P_GENDER, 1);
+  AddId(({"klumpen", "eisen", "klumpen eisen"}));
+  SetProp(P_MATERIAL, MAT_IRON);
+  SetProp(P_WEIGHT, 2438);
+  SetProp(P_VALUE, random(750));
+}
diff --git a/doc/beispiele/ssp/obj/gummistiefel.c b/doc/beispiele/ssp/obj/gummistiefel.c
new file mode 100644
index 0000000..ea4728e
--- /dev/null
+++ b/doc/beispiele/ssp/obj/gummistiefel.c
@@ -0,0 +1,37 @@
+#include <properties.h>
+#include <language.h>
+#include <combat.h>
+#include "../files.h"
+ 
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Paar Gummistiefel");
+   SetProp(P_LONG, "Damit bekommt man sicher keine nassen Fuesse.\n");
+   SetProp(P_NAME, "Paar Gummistiefel");
+   SetProp(P_GENDER, 0);
+   AddId(({"stiefel", "gummistiefel", "paar", "paar stiefel"}));
+   SetProp(P_ARMOUR_TYPE, AT_BOOT);
+   SetProp(P_AC, 0);
+   SetProp(P_WEIGHT, 700);
+   SetProp(P_VALUE, 120);
+   SetProp(P_REMOVE_FUNC, this_object());
+}
+
+RemoveFunc()
+{
+   object env;
+   if ((env=environment(QueryProp(P_WORN)))==find_object(L2("m2x1")) ||
+       env==find_object(L2("m1x1")))
+   {
+      write("Das waere keine so tolle Idee hier die Gummistiefel auszuziehen.\n");
+      return 0;
+   }
+   return 1;
+}
+       
+
+
diff --git a/doc/beispiele/ssp/obj/kampfblech.c b/doc/beispiele/ssp/obj/kampfblech.c
new file mode 100644
index 0000000..63c953a
--- /dev/null
+++ b/doc/beispiele/ssp/obj/kampfblech.c
@@ -0,0 +1,22 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein totes Kampfblech");
+  SetProp(P_LONG, "Sieht aus wie ein normales Kampfblech, nur tot. Ausserdem ueberrascht Dich der merkwuerdige Griff.\n");
+  SetProp(P_NAME, "Kampfblech");
+  SetProp(P_NAME_ADJ, "tot");
+  SetProp(P_GENDER, 0);
+  SetProp(P_ARMOUR_TYPE, AT_SHIELD);
+  SetProp(P_AC, 12);
+  SetProp(P_WEIGHT, 850);
+  SetProp(P_VALUE, 420);
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  SetProp(P_INFO, "Ziemlicher Schwachsinn dieses Objekt, oder nicht?\n");
+  AddId(({"schild", "blech", "kampfblech", "totes kampfblech"}));
+  AddDetail("griff", "Mit Hilfe des Griffs kannst Du das tote Kampfblech als Schild benutzen.\n");
+}
diff --git a/doc/beispiele/ssp/obj/krummschwert.c b/doc/beispiele/ssp/obj/krummschwert.c
new file mode 100644
index 0000000..659ff02
--- /dev/null
+++ b/doc/beispiele/ssp/obj/krummschwert.c
@@ -0,0 +1,22 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/weapon";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Krummschwert");
+  SetProp(P_LONG, "Das Krummschwert sieht aus, als haette es einmal einem Ork gehoert.\n");
+  SetProp(P_NAME, "Krummschwert");
+  SetProp(P_GENDER, 0);
+  SetProp(P_WC, 130 + random(15));
+  SetProp(P_VALUE, 1200 + random(200));
+  SetProp(P_WEIGHT, 1100 + random(100));
+  SetProp(P_WEAPON_TYPE, WT_SWORD);
+  SetProp(P_DAM_TYPE, DT_SLASH);
+  SetProp(P_NR_HANDS, 1);
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  AddId("schwert");
+  AddId("krummschwert");
+}
diff --git a/doc/beispiele/ssp/obj/lkhemd.c b/doc/beispiele/ssp/obj/lkhemd.c
new file mode 100644
index 0000000..5c381bc
--- /dev/null
+++ b/doc/beispiele/ssp/obj/lkhemd.c
@@ -0,0 +1,19 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein leichtes Kettenhemd");
+  SetProp(P_LONG, "Ein nicht sonderlich gut gearbeitetes Kettenhemd. Anziehen kann man\nes aber trotzdem.\n");
+  SetProp(P_NAME, "Kettenhemd");
+  SetProp(P_GENDER, 0);
+  SetProp(P_ARMOUR_TYPE, AT_ARMOUR);
+  SetProp(P_AC, 18);
+  SetProp(P_WEIGHT, 1700);
+  SetProp(P_VALUE, 1200 +random(100));
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  AddId(({"kettenhemd", "hemd"}));
+}
diff --git a/doc/beispiele/ssp/obj/orkhelm.c b/doc/beispiele/ssp/obj/orkhelm.c
new file mode 100644
index 0000000..36d6a8b
--- /dev/null
+++ b/doc/beispiele/ssp/obj/orkhelm.c
@@ -0,0 +1,20 @@
+inherit "std/armour";
+ 
+#include <properties.h>                    
+#include <combat.h>
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Orkhelm");
+  SetProp(P_LONG, "Ein stabiler Helm, der schon ausgiebig von einem stinkenden Ork\ngetragen wurde.\n");
+  SetProp(P_NAME, "Orkhelm");
+  SetProp(P_GENDER, 1);
+  SetProp(P_ARMOUR_TYPE, AT_HELMET);
+  SetProp(P_AC, 7);
+  SetProp(P_WEIGHT, 450);
+  SetProp(P_VALUE, 350);
+  SetProp(P_MATERIAL, ([MAT_MISC_METAL:95, MAT_SLIME:5]));
+  AddId(({"helm", "orkhelm"}));
+}
diff --git a/doc/beispiele/ssp/obj/orkhose.c b/doc/beispiele/ssp/obj/orkhose.c
new file mode 100644
index 0000000..8ba0056
--- /dev/null
+++ b/doc/beispiele/ssp/obj/orkhose.c
@@ -0,0 +1,19 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Eine Orkhose");
+  SetProp(P_LONG, "Die Beinbekleidung von Orks.\n");
+  SetProp(P_NAME, "Hose");
+  SetProp(P_GENDER, 2);
+  SetProp(P_ARMOUR_TYPE, AT_TROUSERS);
+  SetProp(P_AC, 7);
+  SetProp(P_WEIGHT, 555);
+  SetProp(P_VALUE, 480 + random(40));
+  SetProp(P_MATERIAL, ([MAT_CLOTH:99, MAT_SHIT:1]));
+  AddId(({"hose", "hosen", "orkhose", "orkhosen"}));
+}
diff --git a/doc/beispiele/ssp/obj/saebel.c b/doc/beispiele/ssp/obj/saebel.c
new file mode 100644
index 0000000..3aec958
--- /dev/null
+++ b/doc/beispiele/ssp/obj/saebel.c
@@ -0,0 +1,23 @@
+inherit "std/weapon";
+
+#include <properties.h>                    
+#include <combat.h>
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein schartiger Saebel");
+  SetProp(P_LONG, "Der Saebel ist schartig, koennte aber trotzdem recht brauchbar sein.\n");
+  SetProp(P_NAME, "Saebel"); 
+  SetProp(P_GENDER, 1);
+  SetProp(P_WC, 144);
+  SetProp(P_VALUE, 1525);
+  SetProp(P_WEIGHT, 1264);
+  SetProp(P_WEAPON_TYPE, WT_SWORD);
+  SetProp(P_DAM_TYPE, DT_SLASH);
+  SetProp(P_NR_HANDS, 1);
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  AddId("saebel");
+  AddAdjective(({"schartig", "schartiger", "schartigen"}));
+}
diff --git a/doc/beispiele/ssp/obj/schaelmesser.c b/doc/beispiele/ssp/obj/schaelmesser.c
new file mode 100644
index 0000000..2b0b686
--- /dev/null
+++ b/doc/beispiele/ssp/obj/schaelmesser.c
@@ -0,0 +1,25 @@
+inherit "std/weapon";
+
+#include <combat.h>
+#include <properties.h>
+
+create()
+{
+  if (!clonep(this_object())) return;
+   ::create();
+   SetProp(P_SHORT, "Ein Knochenschaelmesser");
+   SetProp(P_LONG, 
+	   "Ein Messer so lang, wie tausend grosse Zaehne\n"+
+	   "Wie tausend grosse Zaehne, ein Messer so lang\n"+
+	   "So lang, wie tausend grosse, grosse Zaehne\n");
+   SetProp(P_NAME, "Knochenschaelmesser");
+   SetProp(P_GENDER, 0);
+   AddId(({"knochenschaelmesser", "schaelmesser", "messer"}));
+   SetProp(P_WC, 145);
+   SetProp(P_NR_HANDS, 1),
+   SetProp(P_WEAPON_TYPE, WT_KNIFE);
+   SetProp(P_DAM_TYPE, DT_SLASH);
+   SetProp(P_VALUE, 1610);
+   SetProp(P_WEIGHT, 1150);
+   SetProp(P_MATERIAL, MAT_MISC_METAL);
+}
diff --git a/doc/beispiele/ssp/obj/stahlschwert.c b/doc/beispiele/ssp/obj/stahlschwert.c
new file mode 100644
index 0000000..4446898
--- /dev/null
+++ b/doc/beispiele/ssp/obj/stahlschwert.c
@@ -0,0 +1,21 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/weapon";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Stahlschwert");
+  SetProp(P_LONG, "Dieses Schwert hat eine Klinge aus reinem Stahl, mit der man seine Gegner\nwohl ziemlich gut niedermachen kann. Das Schwert ist recht schwer und\nlaesst sich nur mit zwei Haenden fuehren.\n");
+  SetProp(P_NAME, "Stahlschwert");
+  SetProp(P_GENDER, 0);
+  SetProp(P_WC, 175);
+  SetProp(P_VALUE, 1750 + random(100));
+  SetProp(P_WEIGHT, 2926);
+  SetProp(P_WEAPON_TYPE, WT_SWORD);
+  SetProp(P_DAM_TYPE, DT_SLASH);
+  SetProp(P_NR_HANDS, 2);
+  SetProp(P_MATERIAL, MAT_STEEL);
+  AddId(({"schwert", "stahlschwert", "\nsspstahlschwert"}));
+}
diff --git a/doc/beispiele/ssp/obj/steinring.c b/doc/beispiele/ssp/obj/steinring.c
new file mode 100644
index 0000000..5da09a7
--- /dev/null
+++ b/doc/beispiele/ssp/obj/steinring.c
@@ -0,0 +1,19 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/armour";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Steinring");
+  SetProp(P_LONG, "Ein kleiner Ring, voellig aus einem grauen Stein.\n");
+  SetProp(P_NAME, "Steinring");
+  SetProp(P_GENDER, 1);
+  SetProp(P_ARMOUR_TYPE, AT_RING);
+  SetProp(P_AC, 2);
+  SetProp(P_WEIGHT, 270);
+  SetProp(P_VALUE, 300 +random(150));
+  SetProp(P_MATERIAL, MAT_MISC_STONE);
+  AddId(({"ring", "steinring"}));
+}
diff --git a/doc/beispiele/ssp/obj/titanring.c b/doc/beispiele/ssp/obj/titanring.c
new file mode 100644
index 0000000..389de66
--- /dev/null
+++ b/doc/beispiele/ssp/obj/titanring.c
@@ -0,0 +1,18 @@
+inherit "std/armour";
+
+#include <properties.h>
+#include <combat.h>
+
+create()
+{
+  ::create();
+  SetProp(P_SHORT, "Ein Titanring");
+  SetProp(P_LONG, "Ein Ring aus Titan.\n");
+  SetProp(P_NAME, "Titanring");
+  SetProp(P_GENDER, 1);
+  AddId(({"titanring", "ring"}));
+  SetProp(P_ARMOUR_TYPE, AT_RING);
+  SetProp(P_AC, 2);
+  SetProp(P_WEIGHT, 280);
+  SetProp(P_VALUE, 520);
+}
diff --git a/doc/beispiele/ssp/obj/trolldolch.c b/doc/beispiele/ssp/obj/trolldolch.c
new file mode 100644
index 0000000..fd06092
--- /dev/null
+++ b/doc/beispiele/ssp/obj/trolldolch.c
@@ -0,0 +1,21 @@
+#include <properties.h>
+#include <combat.h>
+inherit "std/weapon";
+ 
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, "Ein Trolldolch");
+  SetProp(P_LONG, "Ein langer, scharfer Dolch, dem Gestank nach muss er einem Troll\ngehoert haben.\n");
+  SetProp(P_NAME, "Trolldolch");
+  SetProp(P_GENDER, 1);
+  SetProp(P_WC, 119);
+  SetProp(P_VALUE, 1000 +random(400));
+  SetProp(P_WEIGHT, 500 +random(50));
+  SetProp(P_WEAPON_TYPE, WT_KNIFE);
+  SetProp(P_DAM_TYPE, DT_PIERCE);
+  SetProp(P_NR_HANDS, 1);
+  SetProp(P_MATERIAL, MAT_MISC_METAL);
+  AddId(({"dolch", "trolldolch"}));
+}
diff --git a/doc/beispiele/testobjekte/.readme b/doc/beispiele/testobjekte/.readme
new file mode 100644
index 0000000..56ff41f
--- /dev/null
+++ b/doc/beispiele/testobjekte/.readme
@@ -0,0 +1,13 @@
+
+Hier liegen Test-Objekte zu man-pages. Unterschieden wird momentan nur nach:
+- xxx_testobj -> das kann man laden und ggf clonen
+- xxx_testraum -> den kann man betreten
+
+Der Praefix deutet an, fuer welche Features (also man-pages) der Testcode geschrieben wurde. Die man-page selbst nennt diesen Dateinamen hier, insofern:
+* bitte mit Bedacht veraendern - pruefen, welche Funktionalitaet
+  beispielhaft gezeigt werden soll und das nicht loeschen
+* bitte Dateinamen nur veraendern, wenn ihr euch sicher seid, _alle_
+  darauf verweisenden man-pages ebenfalls geaendert zu haben
+
+Verantwortlich: Gloinson
+
diff --git a/doc/beispiele/testobjekte/attack_busy_sensitive_testobj.c b/doc/beispiele/testobjekte/attack_busy_sensitive_testobj.c
new file mode 100644
index 0000000..4225d88
--- /dev/null
+++ b/doc/beispiele/testobjekte/attack_busy_sensitive_testobj.c
@@ -0,0 +1,105 @@
+inherit "/std/thing";

+#include <properties.h>

+#include <new_skills.h>

+#include <sensitive.h>

+

+private action_puste(string str);

+private int counter;

+

+void create() {

+  if (!clonep(this_object())) return;

+  ::create();

+  counter = 2+random(4);

+  

+  SetProp(P_NAME, "Pusteblume");

+  SetProp(P_SHORT, "Eine kleine Pustblume");

+  SetProp(P_LONG, break_string(

+    "Eine abgebluehte Pflanze, die jetzt wie ein kleiner, weisser Ball "

+	"aussieht. Die fiedrigen Samen fliegen bestimmt prima.", 78));

+  AddDetail("samen", "Er sieht sehr fein und leicht aus.\n");

+  SetProp(P_GENDER,FEMALE);

+  SetProp(P_MATERIAL, MAT_MISC_PLANT);

+  SetProp(P_NOBUY, 1);

+  SetProp(P_VALUE, random(10));

+

+  SetProp(P_INFO, "Starker Wind taete ihr nicht gut.\n");

+

+  AddId(({"blume", "pusteblume", "loewenzahn"}));

+  SetProp(P_COMBATCMDS,(["puste loewenzahn":

+                         ([C_HEAL: 5])]));

+

+  SetProp(P_SENSITIVE,({({SENSITIVE_ATTACK, DT_AIR, 20}),

+                        ({SENSITIVE_INVENTORY, DT_AIR, 20})}));

+ 

+  AddCmd("puste&@ID", #'action_puste, "Puste wen oder was (an)?");

+}

+

+private action_puste(string str) {

+  if(environment()!=this_player()) {

+    notify_fail("Dazu solltest du "+name(WEN,1)+" haben.\n");

+	return 0;

+  }

+  if (this_player()->QueryProp(P_ATTACK_BUSY)) {

+    write("Du hast dafuer momentan einfach nicht mehr die Puste.\n");

+    return 1;

+  }

+  this_player()->SetProp(P_ATTACK_BUSY, 1);

+

+  if(counter<0) {

+    write(break_string("Du pustest sinnlos auf "+name(WEN, 2)+".", 78));

+	say(break_string(this_player()->Name(WER)+

+	  " pustet wie daemlich gegen "+name(WEN, 0)+".", 78));

+	return 1;

+  } else {

+    write(break_string(

+      "Du pustest "+name(WEN, 2)+" vorsichtig an, einige Samen "

+      "loesen sich und fliegen taumelnd in deinem Atem davon."+

+	  (counter<0?" Es bleibt nur noch ein nutzloser Strunk.":""), 78));

+    say(break_string(

+      this_player()->Name(WER)+" pustet sachte gegen "+name(WEN, 0)+" und "

+	  "du schaust verzueckt den davonfliegenden Samen nach.", 78));

+  }

+	

+  object who = this_player()->QueryEnemy();

+  

+  if(objectp(who)) {

+    if(!interactive(this_player())) {

+      who->ModifySkillAttribute(SA_SPEED, 80+random(10), 6);

+	  this_player()->heal_self(5);

+	} else

+	  who->ModifySkillAttribute(SA_SPEED, 90+random(10), 4);

+  }

+

+  counter--;

+  if(counter<0) {

+    call_out(#'remove, 10+random(60));

+	AddId("strunk");

+	SetProp(P_NAME, "Strunk");

+	SetProp(P_SHORT, "Der Strunk einer Pusteblume");

+	SetProp(P_LONG, "Ein haesslicher, leerer Strunk.\n");

+	SetProp(P_GENDER, MALE);

+  }

+  return 1;

+}

+

+private void notify_env_destroy() {

+  object ob = environment();

+  while(ob && !living(ob)) ob = environment(ob);

+  if(objectp(ob))

+    tell_object(ob, "Der Wind zerblaest "+name(WEN, 2)+".\n");

+  remove(1);

+}

+

+varargs void trigger_sensitive_attack() {

+  notify_env_destroy();

+}

+

+varargs void trigger_sensitive_inv() {

+  notify_env_destroy();

+}

+

+varargs int remove(int silent) {

+  if(!silent && living(environment()))

+    tell_object(environment(), "Du wirfst "+name(WEN, 2)+" weg.\n");

+  return ::remove(silent);

+}
\ No newline at end of file
diff --git a/doc/beispiele/testobjekte/command_me_testraum.c b/doc/beispiele/testobjekte/command_me_testraum.c
new file mode 100644
index 0000000..29086ce
--- /dev/null
+++ b/doc/beispiele/testobjekte/command_me_testraum.c
@@ -0,0 +1,33 @@
+#include <properties.h>
+inherit "/std/room";
+
+void create() {
+  ::create();
+  SetProp(P_LONG, "AddCmd-Testraum, Kommandos "
+                  "\"kriech\" und \"schleiche&heran|herum\".");
+  AddCmd("schleiche&heran|herum", "action_schleichen");
+  AddExit("gilde", "/gilden/abenteurer");
+}
+
+void init() {
+  ::init();
+  add_action("action_kriechen", "kriech", 1);
+}
+
+static action_schleichen(string str) {
+  string tmp = this_player()->QueryProp(P_RACE);
+  if(tmp[<1]=='e') tmp=tmp[0..<2];
+  write(break_string("Du versuchst leise zu schleichen, dabei passiert "
+    "dir aber ein allzu "+
+	(tmp=="Mensch"?"menschliches":lower_case(tmp)+"isches")+
+	" Missgeschick. Verflucht!", 78));
+  this_player()->command_me("\\furze");
+  return 1;
+}
+
+static int action_kriechen(string str) {
+  write(break_string("Deine Knie tun zu sehr weh dafuer.", 78));
+  tell_room(this_object(), break_string(this_player()->Name(WER)+
+    " knackt mit den Knien.", 78));
+  return 1;
+}
\ No newline at end of file
diff --git a/doc/beispiele/testobjekte/modifyskillspell_test.c b/doc/beispiele/testobjekte/modifyskillspell_test.c
new file mode 100644
index 0000000..3c58342
--- /dev/null
+++ b/doc/beispiele/testobjekte/modifyskillspell_test.c
@@ -0,0 +1,103 @@
+// ModifySkill-Beispiel fuer einem Spell. Erlaeuterung auf man-Page
+// und im Objekt selbst
+inherit "/std/thing";
+#include <new_skills.h>
+#include <properties.h>
+#include <wizlevels.h>
+#include <break_string.h>
+
+static int skillset(string str);
+static int skillunset(string str);
+
+void create() {
+  if(!clonep(this_object())) {
+    set_next_reset(-1);
+    return;
+  }
+
+  ::create();
+  set_next_reset(7200);
+
+  SetProp(P_NAME, "Skillbeispiel");
+  SetProp(P_SHORT, "Eine Skillbeispiel");
+  SetProp(P_LONG, break_string(
+    "Mit \"skillset\" kann man sich den Skill (eigentlich Spell) "
+    "\"fnrx\" setzen.\n"+
+    "Durch \"skillunset\" wird der Skill geloescht.\n"
+    "Das zaehlt deshalb als Spell, weil er kleingeschrieben und "
+    "damit direkt vom Spieler (also dir) als Kommando via UseSpell() "
+    "ausfuehrbar ist.", 78, 0, BS_LEAVE_MY_LFS));
+  SetProp(P_GENDER, NEUTER);
+  AddId(({"beispiel", "skillbeispiel", "spellbeispiel",
+          "skill", "spell"}));
+  
+  AddCmd("skillset", #'skillset);
+  AddCmd("skillunset", #'skillunset);
+}
+
+// Testfunktion, weil im Code dazu aufgefordert wird, das Objekt auch
+// mal zu wegzulegen. Spieler sollten nicht an sich herumfummeln.
+private static int _checkLearner(object pl) {
+  if(!IS_LEARNER(this_player())) {
+    notify_fail("Du bist kein Magier, deshalb geht das nicht.\n");
+    call_out(#'remove, 1);
+    return 0;
+  }
+  return 1;
+}
+
+static int skillset(string str) {
+  if(!_checkLearner(this_player()))
+    return 0;
+
+  if(this_player()->QuerySkill("fnrx")) {
+    notify_fail("Du kannst den Skill schon.\n");
+    return 0;
+  }
+
+  this_player()->ModifySkill("fnrx",
+    ([SI_CLOSURE: function int (object caster, string skill, mapping sinf) {
+            caster->LearnSkill("fnrx", 1);
+            tell_object(caster, "Peng! Dein Skillwert steigt auf "+
+                                caster->QuerySkillAbility("fnrx")+".\n");
+                    return 1;
+                  },
+      SI_SKILLABILITY: 8432]), 100, "ANY");
+  tell_object(this_player(), break_string(
+    "Der Skill ist gesetzt. Tipp doch ein paar Mal \"fnrx\" und schau den "
+    "Code unter "+load_name(this_object())+" an, damit du siehst, dass der "
+    "Skill jetzt nur aus einem Eintrag in dir und einer ueber UseSpell() "
+    "gerufenen Funktion in diesem Objekt besteht. Der Skill ist kein "
+    "Kommando in einem anderen Objekt.\n\n"
+    "Wenn du dieses Objekt weglegst, funktioniert also alles weiter. "
+    "Zerstoerst du aber das Objekt (oder dich mit \"ende\", funktioniert "
+    "die Skillfunktion nicht mehr.\n"
+    "Schau dir auch xeval this_player()->QuerySkill(\"fnrx\") an.", 78, 0,
+    BS_LEAVE_MY_LFS));
+  return 1;
+}
+
+// Here be dragons!
+// Bitte benutzt die folgende Art von Manipulation der Skills nur dann,
+// wenn ihr genau wisst, was ihr tut. In anderen Worten: NICHT MACHEN!
+// Und wenn, dann NUR AM EIGENEN MAGIEROBJEKT, NICHT AN SPIELERN!
+static int skillunset(string str) {
+  if(!_checkLearner(this_player()))
+    return 0;
+
+  // per Query() das Mapping an der _query_*-Fun vorbei direkt holen
+  mapping skills = this_player()->Query(P_NEWSKILLS);
+  // ... und manipulieren (wirkt sich wegen Referenz direkt aus)
+  if(mappingp(skills) && mappingp(skills["ANY"]) &&
+     member(skills["ANY"], "fnrx")) {
+    efun::m_delete(skills["ANY"], "fnrx");
+    tell_object(this_player(), "Erledigt.\n");
+  } else
+    tell_object(this_player(), "Nichts zu erledigen.\n");
+  
+  return 1;
+}
+
+void reset() {
+  remove();
+}
diff --git a/doc/beispiele/testobjekte/netdead_info_testraum.c b/doc/beispiele/testobjekte/netdead_info_testraum.c
new file mode 100644
index 0000000..b2d8a71
--- /dev/null
+++ b/doc/beispiele/testobjekte/netdead_info_testraum.c
@@ -0,0 +1,69 @@
+// Beispielraum fuer P_NETDEAD_INFO-Funktionalitaet
+#include <properties.h>
+#include <break_string.h>
+inherit "/std/room";
+     
+string create_destiny(mixed val);
+int create_room(string dir);
+
+void create() {
+  ::create();
+
+  if (clonep(this_object())) {
+    // setze Informationen, die in einem Netztoten gespeichert werden sollen
+    Set(P_NETDEAD_INFO, random(5));
+    SetProp(P_INT_LONG, break_string(
+      "Wenn du hier einschlaefst, wird der Raum nach 30s zerstoert. Beim "
+      "Aufwachen wirst du an die Blueprint dieses Raums die Info "+
+      QueryProp(P_NETDEAD_INFO)+" uebergeben. Diese wird aus dieser Info "
+      "einen Raumpfad ermitteln, in den du bewegt wirst.", 78));
+  } else {
+    // Blueprint: hier kann man zu einem Cloneraum gehen
+    AddExit("cloneraum", #'create_room);
+    SetProp(P_INT_LONG, break_string(
+      "Zum Testen einfach den Ausgang 'cloneraum' benutzen. Es wird dann "
+      "ein Raum geclont, in den man bewegt wird. Wenn man dort einschlaeft, "
+      "wird der geclonte Raum nach circa 30s zerstoert.\n"
+      "Beim Aufwachen werden die im Spieler gespeicherten Informationen des "
+      "geclonten (und nunmehr zerstoerten) Raumes benutzt, um einen "
+      "alternativen Aufwachraum (Klerusgilde, Karategilde, Wald oder Port "
+      "Vain) zu bestimmen.\n"
+      "Andernfalls wuerde der Spieler in der Abenteurergilde erwachen.", 78,
+      0, BS_LEAVE_MY_LFS));
+  }
+
+  // Set-Method, um die Informationen aus P_NETDEAD_INFO beim Aufwachen
+  // in der Blueprint auswerten zu koennen
+  Set(P_NETDEAD_INFO, #'create_destiny, F_SET_METHOD);
+  SetProp(P_LIGHT, 1);
+}
+     
+// Raum entfernen, normalerweise so KEINE GUTE IDEE!
+void BecomesNetDead(object pl) {
+  call_out(#'remove, 30);
+}
+
+// erzeuge einen Cloneraum und bewege den Spieler dahin
+int create_room(string dir) {
+  object dest = clone_object(object_name(this_object()));
+  this_player()->move(dest, M_NOCHECK);
+  return 1;
+}
+     
+// Set-Method fuer P_NETDEAD_INFO: gibt Pfad zurueck
+// benutze die Informationen aus dem jetzt aufwachenden Netztoten, um einen
+// alternativen Aufwachraum zu ermitteln, da der Einschlafraum zerstoert ist
+string create_destiny(mixed val) {
+  if (intp(val)) {
+    switch (val) {
+      case 0:
+        return "/d/ebene/room/PortVain/po_haf1";
+      case 1:
+        return "/gilden/klerus";
+      case 2:
+        return "/gilden/karate";
+      default:
+    }
+    return "/d/ebene/room/waldweg4";
+  }
+}
diff --git a/doc/beispiele/virtual/.readme b/doc/beispiele/virtual/.readme
new file mode 100644
index 0000000..7cbded2
--- /dev/null
+++ b/doc/beispiele/virtual/.readme
@@ -0,0 +1,2 @@
+Ein einfaches Beispiel fuer per virtual compiler erzeugte Objekte von Zesstra
+und ein leicht komplexeres von Hate.
diff --git a/doc/beispiele/virtual/hate/v_room.c b/doc/beispiele/virtual/hate/v_room.c
new file mode 100644
index 0000000..59c28fd
--- /dev/null
+++ b/doc/beispiele/virtual/hate/v_room.c
@@ -0,0 +1,12 @@
+inherit "/std/room";
+
+#include <properties.h>
+#include <defines.h>
+
+create()
+{
+        if(IS_BLUE(this_object())) return;
+        ::create();
+        previous_object()->CustomizeObject();
+        call_out(symbol_function("QueryObject", find_object(OBJECTD)), 2);
+}
diff --git a/doc/beispiele/virtual/hate/vr_compiler.c b/doc/beispiele/virtual/hate/vr_compiler.c
new file mode 100644
index 0000000..1a50d0b
--- /dev/null
+++ b/doc/beispiele/virtual/hate/vr_compiler.c
@@ -0,0 +1,85 @@
+// MorgenGrauen MUDlib
+//
+// VR_COMPILER.C -- virtual room compiler
+//
+// $Date: 2002/08/28 09:57:18 $
+// $Revision: 1.3 $
+/* $Log: vr_compiler.c,v $
+ * Revision 1.3  2002/08/28 09:57:18  Rikus
+ * auf strong_types umgestellt
+ *
+ * Revision 1.2  1994/07/27 14:48:18  Jof
+ * suid
+ *
+ * Revision 1.1  1994/02/01  19:47:57  Hate
+ * Initial revision
+ *
+*/
+
+// principle:
+// 	- inherit this object into your own 'virtual_compiler.c'
+//  - customize Validate() and CustomizeObject() for you own sake
+//  
+//  * Validate() checks if a room filename given as argument (without path)
+//    is valid and returns this filename with stripped '.c'!!
+//  * CustomizeObject() uses the previous_object()->Function() strategy to
+//    customize the standard object (for example to set a description)
+//
+// Properties: P_VALID_NAME, P_MIN_X, P_MAX_X, P_MIN_Y, P_MAX_Y
+
+#pragma strong_types
+
+inherit "/std/virtual/v_compiler";
+
+#define NEED_PROTOTYPES
+
+#include <thing/properties.h>
+#include <defines.h>
+#include <v_compiler.h>
+#include "/obj/virtual/vr_compiler.h"
+#include <sys_debug.h>
+
+void create()
+{
+  ::create();
+  SetProp(P_VALID_NAME, "raum");
+}
+
+string Validate(string file)
+{
+  int x,y;
+  string path, name;
+
+  file = ::Validate(file);
+	if((sscanf(file, "%s[%d,%d]", name, x, y) == 3) &&
+			name == QueryProp(P_VALID_NAME) &&
+		  (x >= QueryProp(P_MIN_X) && x <= QueryProp(P_MAX_X)) &&
+		  (y >= QueryProp(P_MIN_Y) && y <= QueryProp(P_MAX_Y))
+		)
+      return file;
+}
+
+mixed CustomizeObject()
+{
+	string path, file, name;
+	int x,y;
+
+	if(!(file = ::CustomizeObject())) return 0;
+
+	path = QueryProp(P_COMPILER_PATH);
+	sscanf(file, "%s[%d,%d]", name, x, y);
+	name = QueryProp(P_VALID_NAME);
+	if(y < QueryProp(P_MAX_Y))
+	    previous_object()->AddExit("norden", 
+		path+"/"+name+"["+(x  )+","+(y+1)+"]");
+	if(y > QueryProp(P_MIN_Y))
+	    previous_object()->AddExit("sueden", 
+		path+"/"+name+"["+(x  )+","+(y-1)+"]");
+	if(x < QueryProp(P_MAX_X))
+	    previous_object()->AddExit("osten" , 
+		path+"/"+name+"["+(x+1)+","+(y  )+"]");
+	if(x > QueryProp(P_MIN_X))
+	    previous_object()->AddExit("westen", 
+		path+"/"+name+"["+(x-1)+","+(y  )+"]");
+}
+
diff --git a/doc/beispiele/virtual/hate/vr_compiler.h b/doc/beispiele/virtual/hate/vr_compiler.h
new file mode 100644
index 0000000..673fc54
--- /dev/null
+++ b/doc/beispiele/virtual/hate/vr_compiler.h
@@ -0,0 +1,33 @@
+// MorgenGrauen MUDlib
+//
+// V_COMPILER.H -- a general virtual compiler object
+//
+// $Date: 1994/02/01 19:47:57 $
+// $Revision: 1.1 $
+/* $Log: vr_compiler.h,v $
+ * Revision 1.1  1994/02/01  19:47:57  Hate
+ * Initial revision
+ *
+*/
+
+#include <v_compiler.h>
+
+#ifndef __VR_COMPILER_H__
+#define __VR_COMPILER_H__
+
+#define P_VALID_NAME	"valid_name"
+#define P_MIN_X				"min_x"
+#define P_MAX_X				"max_x"
+#define P_MIN_Y				"min_y"
+#define P_MAX_Y				"max_y"
+
+#endif // __V_COMPILER_H__
+
+#ifdef NEED_PROTOTYPES
+
+#ifndef __VR_COMPILER_H_PROTO__
+#define __VR_COMPILER_H_PROTO__
+
+#endif // __VR_COMPILER_H_PROTO__
+
+#endif //NEED_PROTOTYPES
diff --git a/doc/beispiele/virtual/zesstra/std_arena.c b/doc/beispiele/virtual/zesstra/std_arena.c
new file mode 100644
index 0000000..de2e5a2
--- /dev/null
+++ b/doc/beispiele/virtual/zesstra/std_arena.c
@@ -0,0 +1,20 @@
+inherit "/std/room";
+
+#pragma strong_types,save_types,rtt_checks
+#include <properties.h>
+
+protected void create()
+{
+    if(!clonep(TO))
+        return;
+    ::create();
+
+    SetProp(P_INT_LONG, break_string(
+          "Du stehst hier in einer voellig leeren Arena."
+          "Gegen wen solltest Du hier denn gleich kaempfen...?",78));
+    SetProp(P_INT_SHORT, "In einer Arena");
+    SetProp(P_LIGHT, 1);
+    SetProp(P_INDOORS,0);
+
+    AddExit("raus", "/gilden/abenteurer");
+}
diff --git a/doc/beispiele/virtual/zesstra/virtual_compiler.c b/doc/beispiele/virtual/zesstra/virtual_compiler.c
new file mode 100644
index 0000000..36753df
--- /dev/null
+++ b/doc/beispiele/virtual/zesstra/virtual_compiler.c
@@ -0,0 +1,32 @@
+inherit "/std/virtual/v_compiler.c";
+
+#pragma strong_types,rtt_checks,save_types
+
+#include <thing/properties.h>
+
+#define NEED_PROTOTYPES
+#include <v_compiler.h>
+#undef NEED_PROTOTYPES
+
+protected void create() {
+    ::create();
+
+    // jeder Spieler kriegt eine "Kopie" von std_arena als Raum.
+    SetProp(P_STD_OBJECT, __DIR__"std_arena");
+    SetProp(P_COMPILER_PATH, __DIR__);
+}
+
+public string Validate(string file)
+{
+    string raum, spieler;
+    //.c abschneiden
+    file=::Validate(file);
+    // wenn das gewuenscht file dem Schema "arena|spielername" folgt, ist es
+    // zulaessig.
+    if(sscanf(file,"%s|%s",raum,spieler)==2 && raum=="arena")
+       return file;
+
+    // nicht zulaessig.
+    return 0;
+}
+
diff --git a/doc/beispiele/zauberwald/files.h b/doc/beispiele/zauberwald/files.h
new file mode 100644
index 0000000..8525d78
--- /dev/null
+++ b/doc/beispiele/zauberwald/files.h
@@ -0,0 +1,25 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#define HOME(x) "/doc/beispiele/"+x
+#define WALD(x) HOME("zauberwald/"+x)
+#define ROOM(x) WALD("room/"+x)
+#define NPC(x)  WALD("npc/"+x)
+#define OBJ(x)  WALD("obj/"+x)
+
+#include <defines.h>
+#include <properties.h>
+#include "/p/service/padreic/mnpc/mnpc.h"
+
+#define BS(x) break_string(x, 78)
+#define PO    previous_object()
+#define DEBUG(x) tell_object(find_player("padreic"), x);
+
+#define SAECKCHEN "/d/wald/padreic/obj/saeckchen.c"
+
+
+#define ZAUBERWALD "\npadreiczauberwald" /* gesetzt wenn man im wald ist */
+#define AGGRESSIVE_TIME 900              /* zeit bis zur befriedung */
+#define ZAUBERWALDNPC WALDID("npc")
+#define AUSGANG     "\npadreicausgang"   /* die letzte Bewegung */
+#define WALDID(x)   ZAUBERWALD+x
+#define EXTRA_LONG   "\npadreiczusatzlong" /* zur ergaenzung zur VC-long */
diff --git a/doc/beispiele/zauberwald/npc/arina.c b/doc/beispiele/zauberwald/npc/arina.c
new file mode 100644
index 0000000..9e08e25
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/arina.c
@@ -0,0 +1,101 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <new_skills.h>
+#include "/p/zauberer/zauberer.h"
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Arina die Waldfee");
+   SetProp(P_LONG,
+      "Vor Dir steht Arina die weise Waldfee. Sie ist die Lehrerin des Waldes und\n"
+     +"unterrichtet die Pixies. In ihrer Hand haelt sie einen kleinen Zeigestock mit\n"
+     +"dem sie alles moegliche erklaert und Buchstaben in den Sand zeichnet. Auch\n"
+     +"Arina ist, genauso wie ihre Schwesten, bildhuebsch, doch ihr gestrenger Blick\n"
+     +"floesst jedem in ihrer Naehe grossen Respekt ein.\n");
+   SetProp(P_NAME, "Arina");
+   SetProp(P_ARTICLE, 0);
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_LEVEL, 80);
+   SetProp(P_ATTRIBUTES, (["int":80,"con":40,"str":16,"dex":50]) );
+   SetProp(P_DISABLE_ATTACK, -10000); // is nich :)
+   SetProp(P_BODY, 80);
+   SetProp(P_MAX_SP, 2000);
+   SetProp(P_SP, 2000);
+   SetProp(P_MAX_HP, 700);
+   SetProp(P_HP, 700);
+   SetProp(P_ALIGN, 400);
+   SetProp(P_RACE, "Fee");
+   SetProp(P_SIZE, 160+random(16));
+   SetProp(P_ALCOHOL, 0);
+   SetProp(P_CORPSE, OBJ("feenleiche"));
+   SetProp(P_MAX_ALCOHOL, 0); // kein rauschen :)
+   AddAdjective("wunderschoen");
+   AddId(({"arina", "fee", "waldfee", WALDID("fee")}));
+   SetProp(P_HANDS, ({" mit ihren zarten Haenden", 150, DT_BLUDGEON}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPELL_PENETRATION: 200]));
+   SetProp(P_XP, 800*200*5*2);
+   SetProp(P_GUILD, "zauberer");
+   SetProp(P_Z_NO_MATERIAL, 1);
+   SetProp(P_DEFAULT_INFO, "schweigt und laechelt Dich einfach nur freundlich an.\n");
+   ModifySkill("verletze",
+      ([SI_SKILLABILITY:9000, SI_SPELLCOST:0,
+        SI_SPELLFATIGUE:0, SI_NO_CONSEQUENCES:10000,
+        SI_SKILLRESTR_USE:([P_GUILD_LEVEL:0,SR_FREE_HANDS:0]),
+        SI_ARMOUR_RESTR:0]),0,"zauberer");
+   SetProp(P_GUILD, 0);
+   SetProp(P_RESISTANCE_STRENGTHS,
+      ([DT_POISON: 0.15,
+        DT_MAGIC: -0.3 ]) );
+   AddItem(OBJ("stock"), CLONE_WIELD);
+   AddItem(OBJ("kleid"), CLONE_WEAR);
+   if (file_size(SAECKCHEN)>0) AddItem(SAECKCHEN, CLONE_NEW);
+}
+
+void Attack(object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write("Die Fee macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+   if (enemy) ::Attack(enemy);
+   SetProp(P_GUILD, "zauberer");
+   command("verletze mit "+({"feuer", "magie", "eis", "wasser", "wind"})[random(5)] );
+   SetProp(P_GUILD, 0);
+}
+
+int Defend(int dam, mixed dts, mixed spell, object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write(Name(WER)+" macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+
+   if ((!spell || (mappingp(spell) && spell[SP_PHYSICAL_ATTACK])) && !random(3)) {
+      tell_room(environment(), Name(WER)+" weicht schnell einen Schritt zurueck und weicht Deinem Angriff aus.\n");
+      dam=0;
+   }
+   return (int)::Defend(dam, dts, spell, enemy);
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/arina\n");
+}
+
+void die()
+{
+  log_file("padreic/kill", ctime(time())+" Arina wurde von "+get_killer()+" getoetet.\n");
+  ::die();
+}
diff --git a/doc/beispiele/zauberwald/npc/laufeiche.c b/doc/beispiele/zauberwald/npc/laufeiche.c
new file mode 100644
index 0000000..0649276
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/laufeiche.c
@@ -0,0 +1,124 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <moving.h>
+#include <new_skills.h>
+
+inherit NPC("stdnpc");
+inherit MNPC_MOVING;
+
+void create()
+{
+   if (!clonep(ME)) return;
+   stdnpc::create();
+   moving::mnpc_create();
+   SetProp(P_NAME_ADJ, "alt");
+   SetProp(P_NAME, "Eiche");
+   SetProp(P_SHORT, "Eine alte Eiche");
+   SetProp(P_MSGOUT, "wandert");
+   SetProp(P_LONG,
+     "Vor Dir steht eine sehr sehr alte Eiche. Doch diese Eiche ist keine\n"
+    +"gewoehnliche Eiche, wie Du sie bereits an vielen anderen Stellen gesehn hast.\n"
+    +"Diese Eiche lebt! Du kannst deutlich einen Mund, eine Nase und sogar zwei\n"
+    +"Ohren erkennen. Sie ist eigentlich sehr friedlich gesonnen, kann aber auch\n"
+    +"sehr sehr boese werden, wenn es jemand wagt die Ruhe des Waldes zu stoeren.\n");
+   SetProp(P_RACE, "eiche");
+   SetProp(P_LEVEL, 50);
+   SetProp(P_ATTRIBUTES, (["int":50,"con":50,"str":70,"dex":15]) );
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_MAX_HP, 500);
+   SetProp(P_HP, 500);
+   SetProp(P_ALIGN, 500);
+   SetProp(P_BODY, 100);
+   SetProp(P_SIZE, 650+random(151));
+   AddAdjective("alt");
+   AddId(({"eiche", "eichen", WALDID("eiche") }));
+   SetProp(P_HANDS, ({" mit einem ihrer langen Aeste",400, DT_WHIP}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPEED:180]));
+   SetProp(P_NOCORPSE, 1);
+   SetProp(P_XP, 500*400*5);
+   SetProp(P_DEFAULT_INFO, "bleibt absolut regungslos und reagiert ueberhaupt nicht.\n");
+   SetProp(P_RESISTANCE_STRENGTHS,
+    ([DT_SLASH:     0.1,
+      DT_MAGIC:    -1.0,
+      DT_BLUDGEON: -0.5,
+      DT_POISON:    0.25,
+      DT_HOLY:     -1.0,
+      DT_RIP:       0.25,
+      DT_FIRE:      0.25,
+      DT_PIERCE:   -0.5,
+      DT_WHIP:     -1.0 ]) );
+   SetProp(MNPC_AREA, ({ ROOM("weg2"), ROOM("lichtung") }) );
+   SetProp(MNPC_RANDOM, 10);
+   SetProp(MNPC_DELAY, 8);
+   SetProp(MNPC_WALK_TIME, 600);
+   SetProp(MNPC_FLAGS, MNPC_WALK|MNPC_NO_WALK_IN_FIGHT|MNPC_ONLY_EXITS);
+}
+
+static string _query_info()
+{
+   if (!PL || PL->QueryProp(ZAUBERWALD)<=time())
+      return "Die alte Eiche ist Dir sehr friedlich gesonnen. Es ist jedoch auch sicher\n"
+            +"klug dieses nicht zu aendern, da sie mit ihren Aesten wohl auch sehr kraeftig\n"
+            +"zuschlagen kann.\n";
+   return "Du hast den Zorn der alten Eiche auf Dich gezogen, das war ganz und gar nicht\n"
+         +"klug von Dir. Jetzt lebe auch mit den Konsequenzen....\n";
+}
+
+int remove()
+// wenn eine Eiche getoetet wird, dann verlangsamt das den reset der Eiche
+// die auf weg2 blockt. In der Regel steht ja auch so schon immer eine der
+// wanderden Eichen dort. Dies soll verhindern, das gerade eine Eiche resetet
+// wenn man eine tod hat.
+{
+   call_other(ROOM("weg2"), "delay_reset");
+   catch(call_other(QueryProp(MNPC_HOME), "delay_reset", 900+random(3600)));
+   return (int)::remove();
+}
+
+// wenn man den MNPC mit einem anderen stdnpc kombiniert muessen einige
+// funktionen per Hand ueberschrieben werden....
+
+void reset()
+{
+   stdnpc::reset();
+   moving::mnpc_reset();
+}
+
+void init()
+{
+   stdnpc::init();
+   moving::mnpc_init();
+}
+
+varargs int move(mixed dest, int meth, string dir, string out, string in)
+{
+   int i;
+
+   // extra fuer den Zauberwald eingebaut
+   if (environment() && object_name(environment())==ROOM("weg2")) {
+      // wenn es die einzige Eiche ist, dann bleibt sie hier stehn,
+      // bewacht den Weg und bewegt sich nicht mehr hier weg!
+      object *inv;
+
+      inv = all_inventory(environment()) - ({ ME });
+      for (i=sizeof(inv)-1; i>=0; i--)
+         if (BLUE_NAME(inv[i])==NPC("laufeiche")) break;
+      if (i<0) return ME_CANT_LEAVE_ENV;
+   }
+   //////////////////////////////////////
+   i=(int)stdnpc::move(dest, meth, dir, out, in);
+   if (i!=1) return i;
+   moving::mnpc_move();
+   return 1;
+}
+
+int PreventFollow(object dest)
+{  return moving::mnpc_PreventFollow(dest);  }
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/laufeiche\n");
+}
diff --git a/doc/beispiele/zauberwald/npc/pixie.c b/doc/beispiele/zauberwald/npc/pixie.c
new file mode 100644
index 0000000..7ed953d
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/pixie.c
@@ -0,0 +1,150 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <moving.h>
+#include <combat.h>
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ein kleiner Pixie");
+   SetProp(P_SIZE, 55+random(11));
+   SetProp(P_LONG, BS(
+     "Der Pixie ist etwa "+QueryProp(P_SIZE)+"cm gross und sieht vermutlich einem "
+    +"kleinen pumeligen Menschenkind am aehnlichsten. Wie alle Pixies scheint er "
+    +"sehr verspielt zu sein und nichts als Unfug im Kopf zu haben, Du solltest "
+    +"Dich also vor ihm ihn acht nehmen. Auch wenn er aussieht wie ein Kind, sich "
+    +"benimmt wie ein Kind, so kann er Dir mit seiner Magie sicher uebel zu spieln."));
+   SetProp(P_INFO, /* kleine Warnung fuer die Kaempfer :) */
+     "Man sollte sich immer vor der Magie der Pixies in acht nehmen, sie ist nicht\n"
+    +"unbedingt gefaehrlich, aber es koennen die unerwartesten Dinge geschehn. So\n"
+    +"ist durchaus von Leuten bekannt die einen Kampf als kleine Ratte beendeten,\n"
+    +"oder deren Schwert im Kampf ploetzlich zu Scheisse zerfloss...\n");
+   SetProp(P_NAME_ADJ, "klein");
+   SetProp(P_NAME, "Pixie");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_RACE, "pixie");
+   SetProp(P_ATTRIBUTES, (["int":30,"con":20,"str":15,"dex":30]) );
+   SetProp(P_LEVEL, 20);
+   SetProp(P_MAX_HP, 600);
+   SetProp(P_HP, 600);
+   SetProp(P_MAX_SP, 800);
+   SetProp(P_SP, 800);
+   SetProp(P_ALIGN, 250);
+   SetProp(P_HANDS, ({" mit seinen kleinen Haenden", 150, DT_BLUDGEON}) );
+   SetProp(P_XP, 600*150*5);
+   AddAdjective("klein");
+   AddId("pixie");
+}
+
+// teleporter Ziele im Gebiet. Der Pixie will ja einfach nur ein bisschen
+// Aergern und nicht helfen (ein Pixiekampf ist kein Ausgang :)
+#define DEST ({"lichtungno", "lichtungso", "lichtungn", "lichtungs", \
+               "lichtungnw", "lichtungsw", "lichtungo", "lichtungw", \
+               "weg2", "stein"})
+
+void Attack(object enemy)
+{
+   object ob, weapon;
+   
+   ob=SelectEnemy();
+   if (ob) switch(random(7*8)) { // jede 8te Runde ein Zauberspruch...
+      case 0: // in Frosch verwandeln...
+        if (!ob->QueryProp(P_FROG)) {
+          tell_object(ob, "Der Pixie dreht Dir eine lange Nase und verwandelt Dich in einen Frosch.\n");
+          say(BS("Der Pixie dreht "+ob->name(WEM)+" eine lange Nase und verwandelt "
+                +ob->QueryPronoun(WEN)+" in einen Frosch,"), ob);
+          ob->SetProp(P_FROG, 1);
+          return;
+        }
+        break;
+      case 8..10: // einfach nur nerviger Teleport innerhalb des Gebiets :)
+        tell_object(ob,
+          "Der Pixie schliesst kurz seine Augen und eh Du Dich versiehst, verschwimmt\n"
+         +"alles um Dich herum...\n");
+        say(BS("Der Pixie schliesst kurz seine Augen und ploetzlich loest sich "
+              +ob->name(WER)+" in Luft auf."), ob);
+        ob->move(ROOM(DEST[random(sizeof(DEST))]), M_TPORT|M_NOCHECK|M_SILENT);
+        return;
+      case 16: // Geschlecht aendern... :)
+        tell_object(ob,
+          "Der Pixie grinst breit bis ueber beide Ohren und schaut Dich an, Du weisst\n"
+         +"gar nicht wie Dir geschieht, aber irgendetwas aendert sich an Deinem Koerper.\n");
+        say(BS("Der Pixie grinst "+ob->name(WEN)+" breit an. Ploetzlich "
+         +(ob->QueryProp(P_GENDER)==FEMALE
+         ? "verschwinden ihre Brueste und es waechst ihr ploetzlich ein Bart."
+         : "verschwindet sein Bart und ihm wachsen zwei neue Brueste.")), ob);
+        if (ob->QueryProp(P_GENDER)==FEMALE)
+          ob->SetProp(P_GENDER, MALE);
+        else ob->SetProp(P_GENDER, FEMALE);
+        return;
+      case 24:
+        if (objectp(weapon=ob->QueryProp(P_WEAPON))) {
+           weapon->DoUnwield(1);
+           // verfluchte Waffen nicht betreffen :))
+           if (!objectp(weapon->QueryProp(P_WIELDED))) {
+              string str1, str2;
+              str1=str2=(weapon)->name(WER);
+              if (str1[0..2]=="ein") {
+                str1="D"+str1;
+                str2="s"+str2;
+              }
+              tell_object(ob, BS(
+               "Der Pixie starrt Dir in die Augen und schnippst einmal kurz mit seinen "
+              +"Fingern. Ploetzlich zerrint "+str1+" in Deinen Haenden zu einem Haufen "
+              +"Scheisse."));
+              say(BS("Der Pixie starrt "+weapon->name(WEM)+" in die Augen und "
+                    +"schnippst einmal kurz mit den Fingern. Ploetzlich "
+                    +"zerrint "+weapon->name(WEM)+" "+str2
+                    +" in einen Haufen Scheisse."), ob);
+              weapon->remove();
+              if (weapon) destruct(weapon);
+              return;
+           }
+        }
+        break;
+      case 32:
+        if (!ob->QueryProp(P_BLIND)) {
+          tell_object(ob, BS(
+             "Der Pixie haelt sich die Hand vor die Augen und grinst breit. Ploetzlich "
+            +"merkst Du, wie alles ganz dunkel um Dich rum wird..."));
+          say(BS("Der Pixie haelt sich die Hand vor die Augen und grinst breit. "
+                +ob->name(WER)
+                +" schaut daraufhin ziemlich irritiert in die Gegend."), ob);
+          ob->SetProp(P_BLIND, 1);
+          return;
+        }
+        break;
+      case 40:
+        if (ob->QueryProp(P_POISON)<3 && ob->QueryProp(P_MAX_POISON)>=3) {
+          tell_object(ob, BS(
+             "Der Pixie streicht sich mit der Hand zufrieden ueber seinen Bauch und schaut "
+            +"Dich dabei an. Ploetzlich wird Dir richtig uebel..."));
+          say(BS("Der Pixie streicht sich mit seiner Hand zufrieden ueber seinen Bauch und\n"
+                +"schaut "+ob->name(WEM)+" dabei in die Augen. Ploetzlich wird "+ob->name(WEM)
+                +" ganz uebel."), ob);
+          ob->SetProp(P_POISON, 3);
+          return;
+        }
+        break;
+      case 48:
+        if (!ob->QueryProp(P_DEAF)) {
+          tell_object(ob, "Der Pixie haelt sich die Ohren zu und grinst breit.\n");
+          say(BS("Der Pixie haelt sich die Ohren zu und grinst dabei "
+                +ob->name(WEN)+" an."), ob);
+          ob->SetProp(P_DEAF, 1);
+          return;
+        }
+        break;
+      default:
+   }
+   if (enemy && present(enemy, environment())) ::Attack(enemy);
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/pixie\n");
+}
diff --git a/doc/beispiele/zauberwald/npc/riese.c b/doc/beispiele/zauberwald/npc/riese.c
new file mode 100644
index 0000000..a68a3e2
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/riese.c
@@ -0,0 +1,92 @@
+// (c) 2003 by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <properties.h>
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   create_default_npc(30, 2500);
+   SetProp(P_ARTICLE, 0);
+   SetProp(P_SHORT, "Grimmbart Felsenschieber");
+   SetProp(P_LONG,
+     "Vor Dir sitzt der Riese Grimmbart Felsenschieber. Eigentlich scheint er\n"
+    +"ein sehr gutmuetiger und freundlicher Riese zu sein. Aber irgendwie wirkt\n"
+    +"er derzeit sehr traurig.\n");
+
+   SetProp(P_NAME, "Grimmbart Felsenschieber");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_SIZE, 297);
+   SetProp(P_ALIGN, 200);
+   SetProp(P_RESISTANCE_STRENGTHS,
+     ([DT_HOLY:-1.0,
+       DT_UNHOLY:0.5,
+       DT_MAGIC:0.25,
+       DT_POISON:-0.25,
+       DT_WHIP:-0.6,
+       DT_BLUDGEON:-0.3,
+       DT_PIERCE:-0.1,
+       DT_SLASH:-0.1
+     ]));
+
+   AddInfo(({"felsen", "fels"}),
+     "Ich liebe es meine Muskeln anzuspannen und Felsen zu schieben.",
+     "antwortet: ");
+   AddInfo("schieben",
+     "Ich habe doch keine Felsen mehr die ich schieben koennte.");
+   AddInfo(({"trauer", "traurigkeit"}),
+     "Frueher da habe ich den ganzen Tag hier meine Felsen hin- und "
+    +"hergeschoben, aber nun hat Ulinia mir verboten hier im Wald mit "
+    +"den Felsen zu spielen und ich musste sie alle wegtragen :o(",
+     "jammert: ");
+   AddInfo("tag", "Ja so ein Tag ist ganz schoen lang ohne Felsen",
+     "sagt: ");
+   AddInfo("ulinia",
+      "Eine richtig bloede Fee und haette sie ihre doofen Zauberkraefte nicht,"
+     +"koennte sie uns hier auch nicht alle so rumkommandieren *mopper*.",
+     "sagt: ");
+   AddInfo("grund",
+      "Nur weil mir einmal ausversehen ein klitzekleiner Fels in den Tuempel "
+     +"gefallen ist, musste ich all meine schoenen Felsen aus dem Wald bringen.",
+     "sagt: ");
+   AddInfo("tuempel",
+      "Bloeder Tuempel, wer braucht den schon!", "antwortet gereizt: ");
+   AddInfo("zauberkraefte",
+      "Ich freu mich schon richtig auf den Tag, an dem Ulinias Zauberkraefte "
+     +"nachlassen!",
+      "sagt: ");
+   AddInfo(({"wald", "zauberwald"}),
+      "Wenn es hier wieder ganz viele schoene Felsen gaebe, waer er wieder das "
+     +"reinste Paradies.", "antwortet: ");
+   AddInfo("paradies",
+      "Ja frueher war der Wald hier einmal das reinste Paradies.", "antwortet: ");
+
+   SetChats(3,
+     ({Name(WER)+" sagt: Ich bin so traurig.\n",
+       Name(WER)+" schluchzt: meine schoenen Felsen.. wuaaahhhhh\n",
+       Name(WER)+" sagt: nie wieder werde ich Felsen schieben koennen.\n",
+       Name(WER)+" sagt: F E L S E N !\n",
+       Name(WER)+" jammert: Die Welt ist so furchtbar ungerecht!\n",
+       Name(WER)+" fragt: Wie soll ich so bloss weiterleben?\n"
+     }));
+   
+   AddId("riese");
+   AddId("grimmbart");
+   AddId("felsenschieber");
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))
+    +"getoetet von /zauberwald/riese\n");
+}
+
+void die()
+{
+  log_file("padreic/kill", ctime(time())+" Grimmbart wurde von  "+get_killer()
+    +" getoetet.\n");
+  ::die();
+}
diff --git a/doc/beispiele/zauberwald/npc/stdnpc.c b/doc/beispiele/zauberwald/npc/stdnpc.c
new file mode 100644
index 0000000..a2b3d2f
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/stdnpc.c
@@ -0,0 +1,39 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit "/std/npc";
+inherit "/p/service/mupfel/getkill";
+
+void create()
+{
+   ::create();
+   SetProp(ZAUBERWALDNPC, 1);
+   SetProp(P_AGGRESSIVE, ([P_RACE:(["Dunkelelf":1, 0:0.0]) ]));
+}
+
+int AutoAttack(object ob)
+{
+   if (ob && ob->QueryProp(ZAUBERWALD)>time()) return 1;
+   return ::AutoAttack(ob);
+}
+
+int InsertEnemy(object ob)
+{
+   int ret, is_enemy;
+   is_enemy=IsEnemy(ob);
+   ret=(int)::InsertEnemy(ob);
+   if (!is_enemy) { // alle anderen Zauberwald-NPCs im Raum verstaendigen
+      filter_objects(
+        filter_objects(all_inventory(environment())-users(), "QueryProp", ZAUBERWALDNPC),
+        "InsertEnemy", ob
+      );
+   }
+   return ret;
+}
+
+int Defend(int dam, mixed dts, mixed spell, object enemy)
+{
+   if (enemy) enemy->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+   return (int)::Defend(dam, dts, spell, enemy);
+}
diff --git a/doc/beispiele/zauberwald/npc/titina.c b/doc/beispiele/zauberwald/npc/titina.c
new file mode 100644
index 0000000..adce062
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/titina.c
@@ -0,0 +1,114 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <new_skills.h>
+#include "/p/zauberer/zauberer.h"
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Titina die Waldfee");
+   SetProp(P_LONG,
+      BS("Vor Dir steht Titina die Waldfee. Ihr langes goldenes Haar weht "
+     +"leicht im Wind und das einzige was sie bedeckt, ist ein leichtes Blaetterkleid "
+     +"das ihre weiblichen Rundungen ausserordentlich gut zur Geltung bringt. "
+     +"Ihre schoenen blauen Augen, tun ein uebriges um Dich ganz wahnsinnig zu machen."));
+   SetProp(P_NAME, "Titina");
+   SetProp(P_ARTICLE, 0);
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_LEVEL, 80);
+   SetProp(P_ATTRIBUTES, (["int":60,"con":40,"str":16,"dex":50]) );
+   SetProp(P_DISABLE_ATTACK, -10000); // is nich :)
+   SetProp(P_BODY, 80);
+   SetProp(P_MAX_SP, 2000);
+   SetProp(P_SP, 2000);
+   SetProp(P_MAX_HP, 600);
+   SetProp(P_HP, 600);
+   SetProp(P_ALIGN, 400);
+   SetProp(P_RACE, "Fee");
+   SetProp(P_SIZE, 160+random(16));
+   SetProp(P_ALCOHOL, 0);
+   SetProp(P_CORPSE, OBJ("feenleiche"));
+   SetProp(P_MAX_ALCOHOL, 0); // kein rauschen :)
+   AddAdjective("wunderschoen");
+   AddId(({"titina", "fee", "waldfee", WALDID("fee")}));
+   SetProp(P_HANDS, ({" mit ihren zarten Haenden", 150, DT_BLUDGEON}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPELL_PENETRATION: 100]));
+   SetProp(P_XP, 800*200*5*2);
+   SetProp(P_GUILD, "zauberer");
+   SetProp(P_Z_NO_MATERIAL, 1);
+   SetProp(P_DEFAULT_INFO, "schweigt und laechelt Dich einfach nur freundlich an.\n");
+   ModifySkill("verletze",
+      ([SI_SKILLABILITY:8000, SI_SPELLCOST:0,
+        SI_SPELLFATIGUE:0, SI_NO_CONSEQUENCES:10000,
+        SI_SKILLRESTR_USE:([P_GUILD_LEVEL:0,SR_FREE_HANDS:0]),
+        SI_ARMOUR_RESTR:0]),0,"zauberer");
+   SetProp(P_GUILD, 0);
+   SetProp(P_RESISTANCE_STRENGTHS,
+      ([DT_UNHOLY: 0.25,
+        DT_AIR:    0.3,
+        DT_POISON: 0.15]) ); // sonst selten in benutzung :)
+
+   AddItem(OBJ("kamm"), CLONE_WIELD);
+   AddItem(OBJ("kleid"), CLONE_WEAR);
+   if (file_size(SAECKCHEN)>0) AddItem(SAECKCHEN, CLONE_NEW);
+}
+
+static string _query_long()
+{
+   if (!PL || PL->QueryProp(P_GENDER)==FEMALE)
+      return Query(P_LONG)
+        +"Ihr ueberhebliches laecheln bringt Dich jedoch total zur Weissglut, so eine\n"
+        +"Zicke hier den ganzen Tag rumzusitzen und sich nur die Haare zu kaemmen.\n";
+   return Query(P_LONG)
+     +"Mit ihrem charmanten laecheln, zieht sie Dich sofort in ihren Bann und Du\n"
+     +"wuerdest ihr jeden Wunsch erfuellen, so sie denn einen aeussern wuerde.\n";
+}
+
+void Attack(object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write("Die Fee macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+   if (enemy) ::Attack(enemy);
+   SetProp(P_GUILD, "zauberer");
+   command("verletze mit "+({"feuer", "magie", "eis", "wasser", "gift",
+                             "wind", "saeure", "laerm"})[random(8)] );
+   SetProp(P_GUILD, 0);
+}
+
+int Defend(int dam, mixed dts, mixed spell, object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write(Name(WER)+" macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+
+   if ((!spell || (mappingp(spell) && spell[SP_PHYSICAL_ATTACK])) && !random(4)) {
+      tell_room(environment(), Name(WER)+" weicht schnell einen Schritt zurueck und weicht Deinem Angriff aus.\n");
+      dam=0;
+   }
+   return (int)::Defend(dam, dts, spell, enemy);
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/titina\n");
+}
+
+void die()
+{
+  log_file("padreic/kill", ctime(time())+" Titina wurde von "+get_killer()+" getoetet.\n");
+  ::die();
+}
diff --git a/doc/beispiele/zauberwald/npc/ulinia.c b/doc/beispiele/zauberwald/npc/ulinia.c
new file mode 100644
index 0000000..7ea596e
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/ulinia.c
@@ -0,0 +1,160 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <moving.h>
+#include <new_skills.h>
+#include "/p/zauberer/zauberer.h"
+
+inherit NPC("stdnpc");
+
+string info_tarnzauber()
+{
+   object ob;
+   if (present("\ntarnzauber", PL))
+      return "sagt: Ich habe Dich doch bereist verzaubert.\n";
+   ob=clone_object(OBJ("tarnzauber"));
+   ob->move(PL, M_NOCHECK);
+   ob->Initialize(PL);
+   return "sagt: Nun gut, so sei es...\n"
+         +"macht eine weite Handbewegung und Du fuehlst wie Du Dich verwandelst.\n"
+         +"sagt: Viel Glueck!";
+}
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ulinia die Waldfee");
+   SetProp(P_LONG,
+      BS("Ueber dem Teich schwebt Ulinia die Waldfee. Ihr langes goldenes Haar weht "
+     +"leicht im Wind und das einzige was sie bedeckt, ist ein leichtes Blaetterkleid "
+     +"das ihre weiblichen Rundungen ausserordentlich gut zur Geltung bringt. "
+     +"In der Hand haelt sie einen kleinen Zauberstab, mit dem sie hoch ueber allem thront."));
+   SetProp(P_NAME, "Ulinia");
+   SetProp(P_ARTICLE, 0);
+   SetProp(P_GENDER, FEMALE);
+   SetProp(P_LEVEL, 80);
+   SetProp(P_ATTRIBUTES, (["int":80,"con":40,"str":16,"dex":50]) );
+   SetProp(P_DISABLE_ATTACK, -10000); // is nich :)
+   SetProp(P_BODY, 80);
+   SetProp(P_MAX_SP, 2000);
+   SetProp(P_SP, 2000);
+   SetProp(P_MAX_HP, 800);
+   SetProp(P_HP, 800);
+   SetProp(P_ALIGN, 400);
+   SetProp(P_RACE, "Fee");
+   SetProp(P_SIZE, 160+random(16));
+   SetProp(P_ALCOHOL, 0);
+   SetProp(P_CORPSE, OBJ("feenleiche"));
+   SetProp(P_MAX_ALCOHOL, 0); // kein rauschen :)
+   AddAdjective("wunderschoen");
+   AddId(({"fee", "waldfee", "ulinia", WALDID("fee")}));
+   SetProp(P_HANDS, ({" mit ihren zarten Haenden", 150, DT_BLUDGEON}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPELL_PENETRATION: 250]));
+   SetProp(P_XP, 800*200*5*2);
+   SetProp(P_GUILD, "zauberer");
+   SetProp(P_Z_NO_MATERIAL, 1);
+   SetProp(P_DEFAULT_INFO, "schweigt und laechelt Dich einfach nur freundlich an.\n");
+   AddInfo(({"quest", "hilfe", "aufgabe", "dunkelelfenamulett", "delfenamulett"}),
+     "Ohh in der Tat haette ich da eine Aufgabe fuer Dich, aber ich muss Dich "
+    +"warnen, das sie nicht ganz ungefaehrlich ist.\n"
+    +"Ein befreundeter Kobold berichtete mir von einem lange verschollenen Buch, "
+    +"dass in der Bibliothek der Dunkelelfen wieder aufgetaucht ist. In diesem "
+    +"Buch ist unter anderem von einem alten Amulett die Rede, mit dessen Hilfe "
+    +"die Dunkelelfen ihre alte Macht wiedererlangen und erneut Furcht und "
+    +"Schrecken ueber das gesamte Morgengrauen bringen koennten. "
+    +"Wenn Du die Gefahr nicht scheust, waere es ausserordentlich nett wenn Du "
+    +"Dich nach Zzerenzzen begeben wuerdest und dort nach dem Amulett suchst.\n"
+    +"Solltest Du das Amulett tatsaechlich finden, so ist es wichtig das es "
+    +"auf keinen Fall in die Hand der Dunkelelfen geraet und zerstoert wird.",
+    "antwortet: ");
+   AddInfo("gefahr",
+     "Nun Du wirst Dich mitten unter die Dunkelelfen begeben muessen um "
+    +"zu ihrer Bibliothek gelangen zu koennen. In Zzerenzzen wirst Du "
+    +"hierbei voellig auf Dich allein gestellt sein.\n"
+    +"Alles was ich hierbei fuer Dich tun kann, ist einen Tarnzauber zu "
+    +"sprechen der Dich aeusserlich in einen Dunkelelfen verwandelt. "
+    +"Aber vorsicht, spaetestens wenn Du Dich in einen Kampf verwickelst, "
+    +"wird sich der Zauber loesen.", "sagt: ");
+   AddInfo("tarnzauber", #'info_tarnzauber, "");
+   AddInfo(({"furcht", "schrecken", "macht"}),
+     "Ja frueher waren die Dunkelelfen sehr sehr maechtig und alle "
+    +"friedliebenden Geschoepfe dieser Welt sollten hoffen das sie "
+    +"nie wieder ihre alte Macht erlangen werden.", "antwortet: ");  
+   AddInfo("amulett",
+     "Nun leider weiss ich auch nichts genaues ueber das Amulett. Ich bin "
+    +"nicht mal sicher ob es existiert oder je existiert hat. Aber sollte "
+    +"es noch existieren, muss es auf jeden Fall zerstoert werden!", "sagt: ");
+   AddInfo("kobold",
+     "Ich habe versprochen ihn nicht zu verraten und so kann ich Dir nichts "
+    +"weiter ueber ihn sagen.", "antwortet: ");
+   AddInfo(({"buch", "bibliothek"}),
+     "Ich denke am besten begibst Du Dich in die Hoehle des Loewen und versuchst "
+    +"in der Bibliothek der Dunkelelfen selbst ein Blick in dies Buch zu werfen.\n"
+    +"Wenn ich das noch recht in Erinnerung habe, handelt es sich hierbei um "
+    +"das Buch eines Dunkelelfen names Teyrion.", "sagt: ");
+   AddInfo("loewen", "Das ist doch bloss eine Redewendung.", "sagt: ");
+   AddInfo("redewendung", "Na das sagt man halt so...", "sagt: ");
+   AddInfo(({"hoehle", "zzerenzzen"}),
+     "Der Eingang nach Zzerenzzen liegt in der naehe von Wilhelmsburg gut hinter "
+    +"einem Wasserfall versteckt.", "sagt: ");
+   ModifySkill("verletze",
+      ([SI_SKILLABILITY:10000, SI_SPELLCOST:0,
+        SI_SPELLFATIGUE:0, SI_NO_CONSEQUENCES:10000,
+        SI_SKILLRESTR_USE:([P_GUILD_LEVEL:0,SR_FREE_HANDS:0]),
+        SI_ARMOUR_RESTR:0]),0,"zauberer");
+   SetProp(P_GUILD, 0);
+   SetProp(P_RESISTANCE_STRENGTHS,
+      ([DT_UNHOLY: 0.25,
+        DT_POISON: 0.15, 
+        DT_MAGIC: -0.3]) );
+
+   AddItem(OBJ("zauberstab"), CLONE_WIELD);
+   AddItem(OBJ("kleid"), CLONE_WEAR);
+   if (file_size(SAECKCHEN)>0) AddItem(SAECKCHEN, CLONE_NEW);
+}
+
+void Attack(object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write("Die Fee macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+   if (enemy) ::Attack(enemy);
+   SetProp(P_GUILD, "zauberer");
+   command("verletze mit "+({"feuer", "magie", "eis", "wasser", "gift",
+                             "wind", "saeure", "laerm"})[random(8)] );
+   SetProp(P_GUILD, 0);
+}
+
+int Defend(int dam, mixed dts, mixed spell, object enemy)
+{
+   int normal_speed;
+   normal_speed=(enemy->QueryProp(P_SKILL_ATTRIBUTE_OFFSETS)||([]))[SA_SPEED]||100;
+   if (enemy && enemy->QuerySkillAttribute(SA_SPEED) > normal_speed) {
+      write(Name(WER)+" macht eine beruhigende Handbewegung und ploetzlich fuehlst Du Dich\n"
+           +"ruhig und Du merkst wie Du allmaehlich wieder langsamer wirst...\n");
+      enemy->ModifySkillAttribute(SA_SPEED, -20, 180);
+   }
+
+   if ((!spell || (mappingp(spell) && spell[SP_PHYSICAL_ATTACK])) && !random(3)) {
+      tell_room(environment(), Name(WER)+" weicht schnell einen Schritt zurueck und weicht Deinem Angriff aus.\n");
+      dam=0;
+   }
+   return (int)::Defend(dam, dts, spell, enemy);
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/ulinia\n");
+}
+
+void die()
+{
+  log_file("padreic/kill", ctime(time())+" Ulinia wurde von "+get_killer()+" getoetet.\n");
+  ::die();
+}
diff --git a/doc/beispiele/zauberwald/npc/waechter.c b/doc/beispiele/zauberwald/npc/waechter.c
new file mode 100644
index 0000000..55c1a10
--- /dev/null
+++ b/doc/beispiele/zauberwald/npc/waechter.c
@@ -0,0 +1,87 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <combat.h>
+#include <new_skills.h>
+
+inherit NPC("stdnpc");
+
+void create()
+{
+   ::create();
+   SetProp(P_NAME, "Waechter des Waldes");
+   SetProp(P_SHORT, "Der Waechter des Waldes");
+   SetProp(P_LONG,
+     "Vor Dir steht eine sehr sehr alte Eiche. Doch diese Eiche ist keine\n"
+    +"gewoehnliche Eiche, wie Du sie bereits an vielen anderen Stellen gesehn hast.\n"
+    +"Diese Eiche lebt! Du kannst deutlich einen Mund, eine Nase und sogar zwei\n"
+    +"Ohren erkennen. Sie ist eigentlich sehr friedlich gesonnen, kann aber auch\n"
+    +"sehr sehr boese werden, wenn es jemand wagt die Ruhe des Waldes zu stoeren.\n");
+   SetProp(P_RACE, "eiche");
+   SetProp(P_AGGRESSIVE, 0);
+   SetProp(P_LEVEL, 100);
+   SetProp(P_ATTRIBUTES, (["int":80,"con":100,"str":100,"dex":20]) );
+   SetProp(P_GENDER, MALE);
+   SetProp(P_MAX_HP, 1000);
+   SetProp(P_HP, 1000);
+   SetProp(P_ALIGN, 500);
+   SetProp(P_BODY, 100);
+   SetProp(P_SIZE, 1500);
+   SetProp(P_DISABLE_ATTACK, -10000); // is nich :)
+   AddId(({"eiche", "waechter","waechter des waldes", WALDID("waechtereiche") }));
+   SetProp(P_HANDS, ({" mit einem seiner langen Aeste",550,DT_WHIP}) );
+   SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPEED:210]));
+   SetProp(P_NOCORPSE, 1);
+   SetProp(P_XP, 1000*550*5);
+   SetProp(P_DEFAULT_INFO, "bleibt absolut regungslos und reagiert ueberhaupt nicht.\n");
+   SetProp(P_RESISTANCE_STRENGTHS,
+    ([DT_SLASH:     0.1,
+      DT_MAGIC:    -1.0,
+      DT_BLUDGEON: -0.5,
+      DT_POISON:    0.25,
+      DT_HOLY:     -1.0,
+      DT_RIP:       0.25,
+      DT_FIRE:      0.25,
+      DT_PIERCE:   -0.5,
+      DT_WHIP:     -1.0 ]) );
+   AddCmd(({"osten", "westen"}), "cmd_blocken");
+}
+
+static string _query_info()
+{
+   if (!PL || PL->QueryProp(ZAUBERWALD)<=time())
+      return "Die alte Eiche ist Dir sehr friedlich gesonnen. Es ist jedoch auch sicher\n"
+            +"klug dieses nicht zu aendern, da sie mit ihren Aesten wohl auch sehr kraeftig\n"
+            +"zuschlagen kann.\n";
+   return "Du hast den Zorn der alten Waechtereiche auf Dich gezogen, das war ganz und\n"
+         +"gar nicht klug von Dir. Jetzt lebe auch mit den Konsequenzen....\n";
+}
+
+static int cmd_blocken()
+{
+   if (PL->QueryProp(P_RACE)=="Dunkelelf" &&
+       PL->QueryProp(AUSGANG)==query_verb()) {
+      write(BS(Name(WER, 1)+" laesst Dich nicht vorbei.")
+           +break_string("Du solltest hier besser verschwinden, "
+                        +"so Typen wie Du sind hier nicht gern gesehn!",
+                        78, Name(WER, 1)+" sagt: "));
+      return 1;
+   }
+   if (PL && PL->QueryProp(ZAUBERWALD) &&
+       PL->QueryProp(AUSGANG)==query_verb()) {
+      write(BS(Name(WER, 1)+" steht Dir da leider im Weg und laesst Dich nicht vorbei."));
+      return 1;
+   }
+}
+
+int remove()
+{
+   call_other(ROOM("weg1"), "delay_reset");
+   return (int)::remove();
+}
+
+void NotifyPlayerDeath(object who, object killer, object lost_exp)
+{
+  if (!who || killer!=ME) return; // uninteressant
+  log_file("padreic/kill", ctime(time())+" "+capitalize(getuid(who))+" getoetet von /zauberwald/waechter\n");
+}
diff --git a/doc/beispiele/zauberwald/obj/feenleiche.c b/doc/beispiele/zauberwald/obj/feenleiche.c
new file mode 100644
index 0000000..0e7e034
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/feenleiche.c
@@ -0,0 +1,24 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <moving.h>
+
+inherit "std/corpse";
+
+int mampf( string str )
+{
+   object ob;
+   if (QueryDecay()<3) return (int)::mampf(str);
+   notify_fail("Was moechtest Du essen?\n");
+   if (!str || !id(str)) return 0;
+   if (!PL->eat_food(8)) return 1; // fehlermeldung gibt eat_food aus
+   if (!objectp(ob=present(WALDID("leichenmp"), PL))) {
+      ob=clone_object(OBJ("leichenmp"));
+      ob->move(PL, M_NOCHECK|M_GET);
+   }
+   ob->new_corpse();
+   PL->restore_spell_points(50+random(100));
+   write("Du merkst wie die noch im Koerper verbliebene Energie in Dich ueberfliesst.\n");
+   remove();
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/obj/hahnenfuss.c b/doc/beispiele/zauberwald/obj/hahnenfuss.c
new file mode 100644
index 0000000..8992e46
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/hahnenfuss.c
@@ -0,0 +1,32 @@
+#include <items/kraeuter/kraeuterliste.h>
+#include <items/kraeuter/kraeuter.h>
+#include "../files.h"
+
+inherit STDPLANT;
+
+void create()
+{
+   ::create();
+   customizeMe(WASSER_HAHNENFUSS_WEISS);
+}
+
+/*varargs int move(mixed dest, int method)
+{
+   // die Einwohner des Zauberwalds sehen es nicht gerne, wenn jemand ihre
+   // magischen Pflanzen pflueckt...
+   int res;
+   res=(int)::move(dest, method);
+   if (res!=1) return res;
+   if (environment()) 
+     environment()->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+   return 1;
+}*/
+
+protected void NotifyMove(object dest, object oldenv, int method) {
+  if ( !oldenv && objectp(dest) && query_once_interactive(dest) &&
+       strstr(object_name(environment(dest)),"zauberwald")>-1) {
+    dest->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+  }
+  return ::NotifyMove(dest, oldenv, method);
+}
+
diff --git a/doc/beispiele/zauberwald/obj/kamm.c b/doc/beispiele/zauberwald/obj/kamm.c
new file mode 100644
index 0000000..b26d6f8
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/kamm.c
@@ -0,0 +1,39 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/weapon";
+
+#include "../files.h"
+#include <combat.h>
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ein langer Kamm");
+   SetProp(P_NAME, "Kamm");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_LONG,
+     "Dieser schoene Kamm gehoerte einmal einer Waldfee die damit immer ihr schoenes\n"
+    +"langes Haar kaemmte...\n");
+   AddAdjective("kamm");
+   AddId("kamm");
+   SetProp(P_WEAPON_TYPE, WT_CLUB);
+   SetProp(P_DAM_TYPE, DT_PIERCE);
+   SetProp(P_NR_HANDS, 1);
+   SetProp(P_WC, 100);
+   SetProp(P_VALUE, 100);
+   SetProp(P_NOBUY, 1);
+   SetProp(P_MATERIAL, ({ MAT_MISC_MAGIC, MAT_HORN }) );
+   AddCmd("kaemme", "cmd_kaemmen");
+}
+
+static int cmd_kaemmen(string str)
+{
+   notify_fail("Was moechtest Du denn kaemmen?\n");
+   if (str!="haare") return 0;
+   write("Eitel wie Du bist, versuchst Du Dir mit dem Kamm die Haare zu kaemmen, doch\n"
+        +"irgendwie ist er ein bisschen zu gross fuer Deine Haare.\n");
+   say(BS("Eitel wie "+PL->QueryPronoun()+" ist, kaemmt sich "+PL->name(WER)
+         +" die Haare. Doch irgendwie ist der Kamm ein bisschen zu gross fuer "
+         +PL->QueryPossPronoun(NEUTER, WEN, 1)+" kurzen Haare."));
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/obj/kleid.c b/doc/beispiele/zauberwald/obj/kleid.c
new file mode 100644
index 0000000..f52e157
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/kleid.c
@@ -0,0 +1,38 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/armour";
+
+#include "../files.h"
+#include <combat.h>
+
+void create()
+{
+   ::create();
+   SetProp(P_NAME, "Blaetterkleid");
+   SetProp(P_SHORT, "Ein Blaetterkleid");
+   SetProp(P_GENDER, NEUTER);
+   SetProp(P_LONG,
+     "Das Blaetterkleid stammt von einer Waldfee und war genau auf ihre Rundungen\n"
+    +"und ihre Groesse abgepasst. Du hast leider nicht die geringste Chance, dieses\n"
+    +"Kleid jemals tragen zu koennen.\n");
+   AddId(({"kleid", "blaetterkleid"}));
+   SetProp(P_MATERIAL, MAT_MISC_WOOD);
+   SetProp(P_ARMOUR_TYPE, AT_ARMOUR);
+   SetProp(P_VALUE, 500);
+   SetProp(P_NOBUY, 1);
+   SetProp(P_AC, 10);
+   SetProp(P_WEAR_FUNC, ME);
+}
+
+int WearFunc(object me, int silent)
+{
+   if (!PL || query_once_interactive(PL) || getuid(PL)!=getuid() ||
+       PL->QueryProp(P_RACE)!="Fee") {
+      if (!silent)
+        write("Dieses Kleid war genau auf die Rundungen und die Groesse der Waldfee\n"
+             +"angepasst von der es stammt. Du hast leider nicht die geringste Chance,\n"
+             +"dieses Kleid jemals tragen zu koennen.\n");
+      return 0;
+   }
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/obj/leichenmp.c b/doc/beispiele/zauberwald/obj/leichenmp.c
new file mode 100644
index 0000000..aea7c10
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/leichenmp.c
@@ -0,0 +1,81 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+/* Changelog:
+   * 09.11.06 Zesstra
+     object_info()[11] durch query_next_reset() ersetzt.
+     */
+#include "../files.h"
+
+inherit "/std/thing";
+
+static int leichen;
+
+void create()
+{
+    leichen=0;
+    if (!clonep(ME))
+       set_next_reset(-1);
+    else {
+       ::create();
+       SetProp(P_INVIS, 1);
+       SetProp(P_NODROP, 1);
+       SetProp(P_NEVERDROP, 1);
+       AddId(WALDID("leichenmp"));
+       set_next_reset(3600*3); // erster reset nach 3h
+    }
+}
+
+int remove()
+{
+    closure clo;
+    if (environment()) {
+      clo=environment()->Query(P_MAX_SP, F_QUERY_METHOD);
+      if (clo && to_object(clo)==ME)
+          environment()->Set(P_MAX_SP, 0, F_QUERY_METHOD);
+    }
+    destruct(ME);
+    return 1;
+}
+
+int calculate_mp()
+{
+    int mp;
+    switch(leichen) {
+       case 1:  mp = 5;  break;
+       case 2:  mp = 9;  break;
+       case 3:  mp = 12; break;
+       case 4:  mp = 14; break;
+       case 5:  mp = 15; break;
+       default: mp = 0;
+    }
+    SetProp(P_X_HEALTH_MOD, ([P_SP:mp]) );
+}
+
+void new_corpse()
+{
+    closure clo;
+    clo=PL->Query(P_MAX_SP, F_QUERY_METHOD);
+    if (clo && to_object(clo)!=ME) {
+       call_out("remove", 0);
+       return;
+    }
+    if (leichen<5) {
+       leichen++;
+       set_next_reset(3600+3);
+    }
+    else set_next_reset( (query_next_reset(ME)-time())+3600 );
+    calculate_mp();
+}
+
+void reset()
+{
+   leichen--;
+   if (environment()) {
+      tell_object(environment(), "Du spuerst wie Deine mentalen Kraefte schwaecher werden...\n");
+      if (environment()->QueryProp(P_SP) > environment()->QueryProp(P_MAX_SP))
+          environment()->SetProp(P_SP, environment()->QueryProp(P_MAX_SP));
+   }
+   calculate_mp();
+   if (leichen<=0)
+      remove();
+   else set_next_reset(3600);
+}
diff --git a/doc/beispiele/zauberwald/obj/stock.c b/doc/beispiele/zauberwald/obj/stock.c
new file mode 100644
index 0000000..f79d5e4
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/stock.c
@@ -0,0 +1,26 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/weapon";
+
+#include "../files.h"
+#include <combat.h>
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ein kleiner Zeigestock");
+   SetProp(P_NAME, "Zeigestock");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_LONG,
+     "Ein kleiner Stock, mit dem man gut Dinge zeigen oder in den Sand malen kann.\n");
+   AddAdjective("klein");
+   AddId(({"stock", "zeigestock"}));
+   SetProp(P_WEAPON_TYPE, WT_STAFF);
+   SetProp(P_SIZE, 120);
+   SetProp(P_DAM_TYPE, DT_BLUDGEON);
+   SetProp(P_NR_HANDS, 1);
+   SetProp(P_WC, 120);
+   SetProp(P_VALUE, 300);
+   SetProp(P_NOBUY, 1);
+   SetProp(P_MATERIAL, MAT_MISC_WOOD);
+}
diff --git a/doc/beispiele/zauberwald/obj/tarnzauber.c b/doc/beispiele/zauberwald/obj/tarnzauber.c
new file mode 100644
index 0000000..c226494
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/tarnzauber.c
@@ -0,0 +1,78 @@
+// (c) 2003 by Padreic (Padreic@mg.mud.de)
+// Das Objekt realisiert einen Tarnzauber, aehnlich
+// dem Tarnhelm. Jedoch ohne Shadow und nur auf die
+// Rasse beschraenkt.
+
+#include <properties.h>
+#include <language.h>
+#include <moving.h>
+#include <defines.h>
+
+inherit "/std/thing";
+
+static string race;
+
+create()
+{
+  if (!clonep(this_object())) return;
+  ::create();
+  SetProp(P_SHORT, 0);
+  SetProp(P_LONG, "Tarnzauber");
+  SetProp(P_NAME, "Tarnzauber");
+  SetProp(P_INVIS, 1);
+  SetProp(P_GENDER, MALE);
+  SetProp(P_VALUE,  0);
+  SetProp(P_NOGET, 1);
+  SetProp(P_WEIGHT, 0);
+  Set(P_DEFEND_FUNC, ME);
+  AddId("\ntarnzauber");
+}
+
+// die NPCs im Zauberwald durchschauen den Zauber... :o)
+string _query_race()
+{
+   if (previous_object(1) && getuid(previous_object(1))==getuid())
+      return previous_object()->_query_race()||race;
+   return "Dunkelelf";
+}
+
+void Initialize(object pl)
+{
+   object *armours;
+   pl->Set(P_RACE, #'_query_race, F_QUERY_METHOD);
+   armours=(pl->QueryProp(P_ARMOURS));
+   if (member(armours, ME)>=0) return 0;
+   pl->SetProp(P_ARMOURS, armours+({ ME }));
+   race=pl->Query(P_RACE);
+}
+
+int QueryDefend(string *dtyp, mixed spell, object enemy)
+{
+  mixed am;
+  // noch ein paar paranoide Sicherheitsabfragen... :o)
+  if (!previous_object() ||
+      !pointerp(am=previous_object()->QueryProp(P_ARMOURS)) ||
+      member(am, ME)==-1) return 0;
+  tell_object(previous_object(), "Dein Tarnzauber loest sich auf.\n");
+  remove();
+}
+
+int DefendFunc(string *dtyp, mixed spell, object enemy)
+{
+   return QueryDefend(dtyp, spell, enemy);
+}
+
+varargs int move(mixed dest, int method)
+// beim Tod soll sich der Zauber entfernen und auch nirgends rumfliegen
+{
+   int res;
+   res=(int)::move(dest, method);
+   if (!living(environment())) remove();
+   return res;
+}
+
+varargs int remove(int silent)
+{
+  if (living(environment())) environment()->Set(P_RACE,0,F_QUERY_METHOD);
+  return (int)::remove(silent);
+}
diff --git a/doc/beispiele/zauberwald/obj/zauberstab.c b/doc/beispiele/zauberwald/obj/zauberstab.c
new file mode 100644
index 0000000..1e01fa6
--- /dev/null
+++ b/doc/beispiele/zauberwald/obj/zauberstab.c
@@ -0,0 +1,36 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/weapon";
+
+#include "../files.h"
+#include <combat.h>
+
+void create()
+{
+   ::create();
+   SetProp(P_SHORT, "Ein Zauberstab");
+   SetProp(P_NAME, "Zauberstab");
+   SetProp(P_GENDER, MALE);
+   SetProp(P_LONG,
+     "Dies war einmal der Zauberstab einer Waldfee aus dem Zauberwald. In dem Stab\n"
+    +"liegt sicherlich noch eine grosse Magie verborgen, doch nutzen kannst Du sie\n"
+    +"nicht.\n");
+   AddId(({"stab", "zauberstab"}));
+   SetProp(P_WEAPON_TYPE, WT_CLUB);
+   SetProp(P_DAM_TYPE, ({ DT_MAGIC, DT_BLUDGEON }) );
+   SetProp(P_NR_HANDS, 1);
+   SetProp(P_WC, 140);
+   SetProp(P_VALUE, 800);
+   SetProp(P_NOBUY, 1);
+   SetProp(P_HIT_FUNC, ME);
+   SetProp(P_MATERIAL, ({ MAT_MISC_MAGIC, MAT_MISC_WOOD }) );
+}
+
+int HitFunc(object enemy)
+{
+    object ob;
+    ob=QueryProp(P_WIELDED);
+    if (ob && !query_once_interactive(ob) && getuid(ob)==getuid() &&
+        ob->QueryProp(P_RACE)=="Fee") return 100+random(300);
+    return 0;
+}
diff --git a/doc/beispiele/zauberwald/room/eingang.c b/doc/beispiele/zauberwald/room/eingang.c
new file mode 100644
index 0000000..058a05e
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/eingang.c
@@ -0,0 +1,48 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Auf einem kleinen Waldweg");
+   SetProp(P_INT_LONG,
+     "Du stehst auf einem kleinen Waldweg der nach Westen hin tiefer in den Wald\n"
+    +"hinein fuehrt. Nach Osten kannst Du jedoch auch wieder zurueck zur Kreuzung\n"
+    +"gelangen. Alles ist hier recht duester, denn das Zweigdach der Baeume laesst\n"
+    +"kaum noch Sonnenlicht hindurch.\n");
+   AddDetail("wald", QueryProp(P_INT_LONG));
+   AddDetail(({"boden", "weg", "erde", "waldweg"}),
+     "Der Weg wurde nicht richtig angelegt und es scheint auch nicht so, als wuerde\n"
+    +"ihn jemand pflegen. Dennoch wachsen keinerlei Pflanzen auf dem Weg und Du\n"
+    +"gehst auf der blossen Erde.\n");
+   AddDetail(({"wegrand", "wegesrand", "gestruepp"}),
+     "Am Wegesrand wachsen einige alte Baeume und andere Pflanzen die zusammen ein\n"
+    +"undurchdringliches Gestruepp ergeben. Dir bleibt also nichts weiter uebrig, als\n"
+    +"nur den Weg nach Westen oder nach Osten zu folgen.\n");
+   AddDetail(({"baeume", "alter"}),
+     "Das Alter der Baeume laesst sich nicht genau bestimmen, sie scheinen jedoch\n"
+    +"sehr sehr alt zu sein. In einem der Baeume siehst Du ein kleines Baumhaus.\n");
+   AddDetail(({"pflanzen", "farne", "straeucher"}),
+     "Verschiedene Straeucher, Farne und zahlreiche Baeume zieren den Wegesrand.\n"
+    +"Du entdeckst dabei aber nichts weiter auffaelliges.\n");
+   AddDetail(({"osten", "kreuzung"}),
+     "Wenn Du dem Weg nach Osten hin folgst, kannst Du zurueck zur Kreuzung gelangen.\n");
+   AddDetail(({"zweige", "zweigdach", "sonnenlicht", "licht", "dach", "westen"}),
+     "Das Zweigdach der Baeume laesst hier so wenig Sonnenlicht hindurch, das Du ein\n"
+    +"Stueck weiter im Westen kaum noch ohne eigene Lichtquelle weiterkommen kannst.\n"
+    +"Du solltest Dich also besser nicht ohne eigene Lichtquelle tiefer in den Wald\n"
+    +"hinein wagen.\n");
+   AddDetail(({"fackel", "lampe", "licht", "lichtquelle", "lichtspruch"}),
+     "Wenn Du beabsichtigst weiter nach Westen zu gehn, solltest Du eine Fackel,\n"
+    +"eine Lampe oder sonst irgendeine Lichtquelle mitnehemn. Zumindest ist es dort\n"
+    +"sehr dunkel.\n");
+   AddDetail(({"wolke", "wolken", "sonne", "himmel"}),
+     "Der Himmel ist durch das dichte Dach der Zweige, nicht mehr zu sehn.\n");
+   AddExit("osten", "/d/unterwelt/raeume/wald4");
+   AddExit("westen", ROOM("weg1"));
+}
diff --git a/doc/beispiele/zauberwald/room/huette.c b/doc/beispiele/zauberwald/room/huette.c
new file mode 100644
index 0000000..e19a272
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/huette.c
@@ -0,0 +1,129 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+// Ein Raum zum schoenen einbinden eines Seherhauses in den Wald
+
+#include "../files.h"
+#include <moving.h>
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 1);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Mitten im Wald");
+   SetProp(P_INT_LONG,
+     "Du stehst nun inmitten des Zauberwalds genau vor einer riesigen Buche unter\n"
+    +"der jemand eine kleine Huette gebaut hat. Ringsumher stehen weitere Buesche\n"
+    +"und Baeume und bilden eine dichte Vegetation, doch im Vergleich zu dieser\n"
+    +"riesigen Buche wirkt alles andere wirklich mickrig. Durch das dichte\n"
+    +"Blaetterdach dringt nur wenig Licht und so wundert es auch nicht das der\n"
+    +"Boden hier relativ feucht ist und die Pflanzen so gut gedeihen koennen. Nach\n"
+    +"Norden fuehrt als einziger Ausgang ein kleiner Trampelpfad zur Lichtung.\n");
+   AddDetail(({"natur", "wald", "zauberwald"}), QueryProp(P_INT_LONG));
+   AddDetail(({"buesche", "baeume", "vegetation", "pflanzen", "farne"}),
+     "Rings um die Huette herscht eine wilde Vegetation. Es wachsen verschiedenste\n"
+    +"Farne und Buesche und eine vielfalt verschiedenster Baeume. Alles zusammen\n"
+    +"bildet eine fast undurchdringliche Vegetation.\n");
+   AddDetail(({"licht", "blaetterdach"}),
+     "Durch das relativ dichte Blaetterdach der hohen Baeume, faellt eigentlich nur\n"
+    +"sehr wenig Licht durch und so ist es hier doch schon relativ duester, auch\n"
+    +"wenn man noch nicht unbedingt eine eigene Lichtquelle braucht um etwas sehen\n"
+    +"zu koennen.\n");
+   AddDetail("lichtquelle",
+     "Eine eigene Lichtquelle ist hier nicht unbedingt erforderlich, da dann doch\n"
+    +"noch genuegend Licht durch das Blaetterdach durchdringt.\n");
+   AddDetail("himmel",
+     "Es scheint Dir als wuerde die Sonne gerade scheinen, auch wen das dichte\n"
+    +"Blaetterdach die meisten Sonnenstrahlen nicht hindurch laesst.\n");
+   AddDetail("boden",
+     "Der Boden ist hier eigentlich, mit Ausnahme des Trampelpfads natuerlich,\n"
+    +"ziemlich zugewachsen und von zahlreichen Pflanzen ueberwuchert.\n");
+   AddDetail("erde",
+     "Die Erde ist hier ueberall ein wenig lehmig, aber wirklich besonderes kannst\n"
+    +"Du an der Erde nicht entdecken.\n");
+   AddDetail(({"trampelpfad", "ausgang", "pfad"}),
+     "Der Trampelpfad scheint doch relativ oft benutzt zu werden, denn die Erde ist\n"
+    +"fast voellig bloss gelegt und die wenigen Pflanzen die dann doch versuchen ihn\n"
+    +"zu bewachsen sind fast alle niedergetrampelt.\n");
+   AddDetail(({"lichtung", "norden"}),
+     "Vielleicht solltest Du einfach dem Trampelpfad nach Norden folgen und Dir die\n"
+    +"Lichtung einfach aus der Naehe anschauen.\n");
+   AddDetail(({"buche", "riesige buche"}),
+     "Eichen sollst Du weichen, Buchen sollst Du suchen!\n");
+   AddDetail(({"eiche", "eichen"}),
+     "Du siehst zwar alles moegliche an Baeumen hier, aber Eichen befinden sich zum\n"
+    +"Glueck nicht dadrunter.\n");
+   AddDetail(({"glueck", "frage"}),
+     "Ob es soetwas wie Glueck ueberhaupt gibt, ist wohl eher eine philosophische\n"
+    +"Frage und etwas wo man stundenlang drueber diskutieren koennte. Fuer den\n"
+    +"Moment beschliesst Du jedenfalls lieber die schoene Natur zu geniessen und\n"
+    +"dem zwitschern der Voegel zu lauschen, als Dich mit soetwas zu beschaeftigen.\n");
+   AddDetail(({"voegel", "zipfel", "baumzipfel", "zipfel der baeume"}),
+     "Oben in den Zipfeln der Baeume kannst Du wage einige Voegel erkennen, doch um\n"
+    +"diese naeher spezifizieren zu koennen, sind diese dann doch zu weit weg.\n");
+   AddDetail("moment",
+     "Geniesse den Moment und lebe Dein Leben!\n");
+   AddDetail("ruhe",
+     "Die Ruhe wird hier und da lediglich vom zwitschern einiger Voegel unterbrochen.\n");
+   AddSpecialDetail(({"huette"}), "det_huette");
+   AddSounds(SENSE_DEFAULT,
+     "Es ist hier wirklich herrlich ruhig und nur hier und da hoerst Du das\n"
+    +"zwitschern einiger Voegel. Natur pur.\n");
+   AddSounds(({"voegel", "zwitschern", "voegel zwitschern"}),
+     "Du lauschst dem zwitschern der Voegel und geniesst die himmlische Ruhe.\n");
+   AddCmd(({"such", "suche"}), "cmd_suchen");
+   AddCmd(({"geniess", "geniesse"}), "cmd_geniessen");
+   AddCmd(({"leb", "lebe"}), "cmd_leben");
+   AddCmd(({"kletter", "klettere"}), "cmd_klettern");
+   AddExit("norden", ROOM("lichtungs"));
+}
+
+static string det_huette()
+// Langbeschreibung nicht fest setzen, damit der Spieler sie selbst
+// aendern kann.
+{
+   object ob;
+   if (ob=present("\nmorgeneshaus", ME))
+      return ob->long();
+}
+
+static int cmd_suchen(string str)
+{
+   notify_fail("WAS moechtest Du suchen?\n");
+   if (str!="buchen" && str!="buche") return 0;
+   write("Du brauchst nicht lange suchen und schon entdeckt Du eine riesige Buche vor\n"
+        +"Dir, aber eigentlich waere es wohl auch eher erstaunlich, wenn Du diese\n"
+        +"riesige Buche direkt vor Deiner Nase uebersehen wuerdest :).\n");
+   return 1;
+}
+
+static int cmd_geniessen(string str)
+{
+   notify_fail("WAS moechtest Du geniessen?\n");
+   if (str!="moment" && str!="den moment" && str!="ruhe") return 0;
+   write("Du haeltst einen Moment inne und geniesst die himmlische Ruhe, die nur durch\n"
+        +"das zwitschern einiger Voegel durchbrochen aber nicht gestoert wird.\n");
+   return 1;
+}
+
+static int cmd_leben(string str)
+{
+   notify_fail("WAS moechtest Du leben?\n");
+   if (str!="leben" && str!="mein leben" && str!="dein leben") return 0;
+   write("Nun, wenn die Welt so einfach waere das Du mit einem simplen Kommando Dein\n"
+        +"ganzes Leben steuern koenntest, dann waer die Welt doch wirklich langweilig,\n"
+        +"oder? Ich will doch stark hoffen, das es sooo weit noch nicht bei Dir ist :).\n");
+   return 1;
+}
+
+static int cmd_klettern(string str)
+{
+   notify_fail("WOHIN oder WORAUF moechtest Du klettern?\n");
+   if (member(({"auf baum", "auf baumzipfel", "baum hoch",
+                "buche hoch", "auf buche"}), str)==-1) return 0;
+   write("Du versuchst vergeblich die riesige Buche hochzuklettern, doch die unteren\n"
+        +"Aeste haengen leider bereits viel zu hoch, um diese erklimmen zu koennen.\n");
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/room/schule.c b/doc/beispiele/zauberwald/room/schule.c
new file mode 100644
index 0000000..a97acc4
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/schule.c
@@ -0,0 +1,78 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   AddSpecialDetail(({"pixieschule", "schule", "sandplatz", "waldschule"}), "_query_int_long");
+   AddDetail(({"spuren", "kampfplatz", "sand"}),
+     "Die Spuren im Sand deuten auf einen laengeren Kampf hin, der hier getobt\n"
+    +"haben muss. Wer auch immer ihn verloren hat, er hat sich wacker gewehrt.\n");
+   AddDetail("wald",
+     "Was meinst Du eigentlich, wo Du gerad die ganze Zeit rumlaeufst? Mach einfach\n"
+    +"die Augen auf und schau Dir alles in Ruhe an.\n");
+   AddDetail("ruhe", "In der Ruhe liegt die Kraft...\n");
+   AddDetail(({"augen", "details", "kampfzauber", "kopf", "freund"}),
+     "Nu uebertreib mal nich, nicht jedes Substantiv verbirgt wirklich ein\n"
+    +"sinnvolles Detail.\n");
+   AddDetail("kraft",
+     "Wow! Deine Kraft ist ploetzlich auf 32 angestiegen...\n"
+    +"Das hast Du jetzt aber nicht wirklich geglaubt, oder?\n"
+    +"Wieso untersuchst Du solche Details eigentlich?\n");
+   AddSpecialDetail("zeit", "det_zeit");
+   AddDetail(({"pixies", "bloedsinn", "unfug", "zauberwesen", "streich"}), 
+     "Pixies sind kleine Zauberwesen, die nichts als Unfug im Kopf haben. Wie\n"
+    +"niemand sonst nutzen sie ihre magischen Faehigkeiten nicht um jemanden zu\n"
+    +"heilen oder fuer Kampfzauber. Nein sie nutzen sie um jemanden zu Aergern\n"
+    +"oder ihm einen Streich zu spielen. Einen Pixie zum Freund zu haben, kann\n"
+    +"sicher sehr unterhaltsam sein, auf die Dauer aber wohl auch ziemlich\n"
+    +"anstrengend.\n");
+   AddSpecialDetail("boden", "det_boden");
+   AddDetail("halbkreis",
+     "Einige Pixies sitzen im Halbkreis um Arina herum und hoeren gespannt zu, wie\n"
+    +"sie ihnen einen spannende Geschichte erzaehlt.\n");
+   AddDetail(({"geschichten", "sprache"}),
+     "Wenn Arina doch bloss in einer Sprache sprechen wuerde, Die Du verstehst...\n"
+    +"Ihre Geschichten hoeren sich jedenfalls ausserordentlich spannend an. *seufz*\n");
+   AddDetail("himmel", "Der Himmel ist klar und nahezu wolkenfrei.\n");
+   AddDetail(({"osten", "ausgang", "lichtung", "weg", "waldweg"}),
+     "Der einzige Ausgang von hier, ist der kleine Waldweg im Osten der zurueck\n"
+    +"zur grossen Lichtung fuehrt.\n");
+   SetProp(P_INT_SHORT, "Die Pixieschule");
+   AddExit("osten", ROOM("lichtungnw"));
+   AddItem(NPC("pixie"), REFRESH_MOVE_HOME);
+   AddItem(NPC("pixie"), REFRESH_MOVE_HOME);
+   AddItem(NPC("pixie"), REFRESH_MOVE_HOME);
+   AddItem(NPC("arina"), REFRESH_REMOVE, 1);
+}
+
+static string det_boden()
+{
+   if (present(WALDID("fee"), ME))
+      return GetDetail("halbkreis");
+   return GetDetail("sand");
+}
+
+static string det_zeit()
+{  return "Wir haben genau "+dtime(time())[<8..]+".\n"; }
+
+static string _query_int_long()
+{
+   if (present(WALDID("fee"), ME))
+      return "Du befindest Dich in der Waldschule der Pixies. Einige Pixies sitzen im\n"
+            +"Halbkreis um die Waldfee Arina rum und hoeren gespannt ihren Geschichten zu.\n"
+            +"Gelegentlich erhebt sich Arina um mit einem Stock etwas in den Sand zu\n"
+            +"zeichnen, oder um einen der Pixies zu ermahnen weil er wieder irgendeinen\n"
+            +"verrueckten Bloedsinn gemacht hat. Da sich ringsherum der dichte Wald\n"
+            +"anschliesst, ist der einzige Ausgang, der Weg zurueck nach Osten auf die\n"
+            +"grosse Lichtung.\n";
+   return "Du stehst auf einem kleinen Sandplatz mitten im Wald. Hier und da siehst Du\n"
+         +"im Sand noch deutlich die Spuren eines Kampfes. Umgeben wird dieser Platz\n"
+         +"von einem dichten Wald, so dass der einzige Ausgang der Weg zurueck nach\n"
+         +"Osten zur grossen Lichtung ist.\n";
+}
diff --git a/doc/beispiele/zauberwald/room/stdlichtung.c b/doc/beispiele/zauberwald/room/stdlichtung.c
new file mode 100644
index 0000000..341ee6e
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/stdlichtung.c
@@ -0,0 +1,157 @@
+// (c) by Thomas Winheller (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <moving.h>
+
+inherit ROOM("stdroom");
+inherit "/std/room/kraeuter";
+
+void maybe_replace_program()
+// dieser Standardraum, darf _nicht_ replaced werden...
+{ }
+
+int tuempel_ex(string exit, mapping map_ldfied)
+{   return map_ldfied[exit]==ROOM("tuempel");  }
+
+static int plant;
+
+void create()
+{
+   int i;
+   string tuempel, dir;
+   mixed tmp;
+
+   if (!clonep(ME)) return;
+   ::create();
+   plant=0;
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Am Rande der Zauberlichtung");
+   SetProp(EXTRA_LONG, "");
+   if (PO) dir=(PO->CustomizeObject());
+   if (!dir) return;
+   dir=(["o":"ost", "w":"west", "n":"nord", "s":"sued",
+         "no":"nordost", "nw":"nordwest",
+         "so":"suedost", "sw":"suedwest"])[dir[8..]];
+   tuempel=filter(m_indices(QueryProp(P_EXITS)||([])), "tuempel_ex", ME, QueryProp(P_EXITS)||([]))[0][0..<3];
+   dir=capitalize(dir); tuempel=capitalize(tuempel);
+   SetProp(P_INT_LONG, BS(
+     "Du stehst am "+dir+"rand der grossen Lichtung inmitten des Zauberwalds. "
+    +tuempel+"lich von hier, befindet sich genau in der Mitte der "
+    +"Lichtung ein kleiner Tuempel in dessen Wasser sich das Sonnenlicht in "
+    +"allen Farben des Regenbogens spiegelt. Hier und da stehen um den Teich "
+    +"herum vereinzelt einige Eichen die sich irgendwie zu bewegen "
+    +"scheinen und ab und zu siehst Du wie sich einige kleine Pixies aus "
+    +"dem Wald heraus ans Wasser trauen. Die Eichen jedoch, halten immer "
+    +"einen deutlichen Abstand zum Wasser."+QueryProp(EXTRA_LONG)));
+   AddDetail(({"raum", lower_case(dir)+"rand", "zauberwald"}), QueryProp(P_INT_LONG));
+   AddDetail(({"pixies", "zauberwesen", "unfug"}),
+     "Pixies sind kleine verspielte Zauberwesen, die hier im Zauberwald wohnen. Um\n"
+    +"einem von ihnen zu begegnen wirst Du hier im Wald sicher nich lange suchen\n" 
+    +"muessen, doch vorsicht, sie haben nichts als Unfug im Kopf...\n");
+   AddDetail(({"farben", "regenbogen", "computer"}),
+     "Noch nie einen Regenbogen gesehn? Hmm.. dann sitzt Du wirklich eindeutig\n"
+    +"zuviel vor Deinem Computer...\n");
+   AddDetail("abstand",
+     "Wieso sie diesen Abstand halten kannst Du nicht nachvollziehn, aber mehr als\n"
+    +"ein paar Meter gehen sie nie an den alten Weiher dran.\n");
+   AddDetail(({"sonne", "sonnenstrahlen", "sonnenlicht", "himmel", "herz"}),
+     "Zahlreiche warme Sonnenstrahlen erwaermen Dein Herz und Du bist richtig\n"
+    +"gluecklich. Solch ein Idyllisches Plaetzchen willst Du am liebsten nie\n"
+    +"wieder verlassen. Fehlt eigentlich nur noch ein Partner, mit dem man\n"
+    +"hier gemeinsam in der Sonne liegen und das rauschen des Wassers geniessen\n"
+    +"kann.\n");
+   AddDetail("partner", "Den musst Du Dir schon selbst mitbringen...\n");
+   AddDetail(({"wald", "zauberwald"}),
+     "Du befindest Dich quasi mittem ihn ihm. Rund herum um die Lichtung schliesst\n"
+    +"sich ein dichter Wald an.\n");
+   AddDetail(({"eiche", "eichen"}),
+     "Hier befindet sich gerade keine, so dass Du sie nich naeher ansehn kannst.\n");
+   AddDetail(({"lichtung", "rand", "plaetzchen"}), QueryProp(P_INT_LONG));
+   AddDetail(({"wasser", "tuempel", "teich", lower_case(tuempel)+"en", "mitte"}),
+     "Wenn Du Dir den Tuempel in der Mitte der Lichtung etwas naeher ansehen\n"
+    +"moechtest, solltest Du vielleicht einfach noch ein bisschen naeher rangehn.\n");
+   AddDetail(({"waldweg", "weg"}),
+     "Ueber den Waldweg kannst Du den Wald wieder verlassen wenn Du moechtest.\n");
+   AddDetail(({"boden"}),
+     "Der Boden ist hier nirgends nackt sichtbar, sondern ist mit einem schoenen\n"
+    +"gruenen Rasenteppich bedeckt. Nicht zu hoch und nicht zu tief, offensichtlich\n"
+    +"bedarf diese Grasart keinerlei Pflege oder aber irgendjemand pflegt diesen\n"
+    +"Rasen hier seeehhhhrrr gruendlich.\n");
+   AddDetail(({"grasart", "rasen", "art", "gras", "rasenteppich", "halme"}),
+     "Du schaust Dir den Rasen noch einmal gruendlich an und streichst mit Deiner\n"
+    +"Hand durch die Halme. Was auch immer das fuer eine Art ist, solch einen Rasen\n"
+    +"hast Du noch nicht gesehn.\n");
+   AddDetail("hand",
+     "Sei lieber vorsichtig, sonst ist die Hand schneller ab als Du denkst...\n");
+   AddDetail("pflege",
+     "Ob jemand diesen Rasen pflegt, bzw. _wer_ kannst Du nicht entdecken...\n");
+   AddSounds(({"rauschen", "wasser"}), "Leise hoerst Du das rauschen des Wassers....\n");
+}
+
+#define VERB (["iss": "essen", "esse": "essen", "pflueck": "pfluecken", "pfluecke": "pfluecken"])
+
+static int cmd_pilze(string str)
+{
+   notify_fail("Was moechtest Du "+VERB[query_verb()]+"?\n");
+   if (str!="pilz" && str!="pilze") return 0;
+   if (plant>time()) {
+      write("Du solltest die Pilze erstmal in Ruhe wieder etwas nachwachsen lassen.\n");
+      return 1;
+   }
+   if (PL->QueryProp(ZAUBERWALD)<=time()) {
+      write("Du bist nur Gast hier und die Bewohner des Zauberwalds, sehen es nicht gerne\n"
+           +"wenn man hier einfach so die Pilze pflueckt.\n");
+      return 1;
+   }
+   plant=time()+300;
+   write("Du pflueckst Dir einige Pilze und isst sie. Anschliessend geht es Dir\n"
+        +"bedeutend besser.\n");
+   PL->reduce_hit_points( negate(100+random(100)) );
+   return 1;
+}
+
+static int cmd_farne(string str)
+{
+   int food;
+   notify_fail("Was moechtest Du "+VERB[query_verb()]+"?\n");
+   if (str!="farn" && str!="farne") return 0;
+   if (PL->QueryProp(ZAUBERWALD)<=time()) {
+      write("Du bist nur Gast hier und die Bewohner des Zauberwalds, sehen es nicht gerne\n"
+           +"wenn man hier einfach so den Farn abreisst.\n");
+      return 1;
+   }
+   // das tanken am Wasser ist umsonst, es heilt dabei wie ein
+   // mittleres Kneipenessen das genau 1 Muenze kostet. Geheilt werden nur HP
+   // Ein Missbrauch ist im Wald ausgeschlossen, bzw. man muesste den
+   // gesamten Wald leermetzeln und kann dann hier tanken bis zum naechsten
+   // reset. Bei Kosten von einer Muenze pro Heilung ist es sehr fraglich
+   // ob sich das lohnt.... :)
+   food=(PL->QueryProp(P_MAX_FOOD)) - (PL->QueryProp(P_FOOD));
+   if (food>10) food=10; // nie mehr als fuer 10 food tanken...
+   if (food <= 0 || !PL->eat_food(food, 1)) {
+      write("Du bist so voll, Du kannst leider wirklich nichts mehr essen...\n");
+      return 1;
+   }
+   write("Du pflueckst ein wenig von dem Farn und isst ihn. Sogleich spuerst Du, wie es\n"
+        +"Dir allmaehlich wieder besser geht...\n");
+   if (PL->eat_food(food)) { // food gutschreiben erfolgreich?
+      PL->buffer_hp(food*6, 8);
+      PL->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+   }
+   return 1;
+}
+
+static int cmd_sueden()
+{
+   if (PL->QueryProp(ZAUBERWALD)>time()) {
+      write("Du versuchst in den Wald zu fluechten, doch die Farne und Buesche bilden\n"
+           +"eine pflanzliche Barriere und lassen Dich nicht hindurch.\n");
+      return 1;
+   }
+   write("Du machst einen Schritt hin nach Sueden und sofort biegen sich auf magische\n"
+        +"Weise die Farne und Buesche zur Seite und geben einen Trampelpfad nach Sueden\n"
+        +"frei.\n");
+   PL->move(ROOM("huette"), M_GO, "durch die Buesche nach Sueden", "zwaengt sich");
+   return 1;
+}
diff --git a/doc/beispiele/zauberwald/room/stdroom.c b/doc/beispiele/zauberwald/room/stdroom.c
new file mode 100644
index 0000000..35297e6
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/stdroom.c
@@ -0,0 +1,52 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+inherit "std/room";
+
+#include "../files.h"
+#include <moving.h>
+
+static string sounds();
+
+void create()
+{
+   ::create();
+   SetProp(P_NO_TPORT, NO_TPORT);
+   AddSmells(SENSE_DEFAULT,
+     "Der Duft vom Harz der Baeume und einiger sonstiger Pflanzen liegt in der Luft.\n"
+    +"Man merkt sofort, Du stehst mittem im Wald.\n");
+   AddSounds(SENSE_DEFAULT, #'sounds);
+   AddSounds(({"voegel", "voegeln", "zwitschern"}),
+     "Das herrliche zwitschern der Voegel, ist das einzige das die Ruhe im Wald\n"
+    +"durchbricht.\n");
+}
+
+static string sounds()
+{
+   if (sizeof(filter_objects(all_inventory(), "InFight")))
+      return "Der Laerm des Kampfes stoert die Ruhe des Waldes und uebertoent alles.\n";
+   if (sizeof(filter(all_inventory(), #'query_once_interactive))>1)
+      return "Es ist unheimlich still hier im Wald und nur das zwitschern einiger Voegel\n"
+            +"ist zu hoeren.\n";
+   return "Du hast das Gefuehl, als waerst Du ganz allein hier im Wald. Alles ist ruhig\n"
+         +"und nur hier und da vernimmst Du das zwitschern einiger Voegel.\n";
+}
+
+varargs void delay_reset(int time)
+// NPCs koennen boing resets verhindern
+{
+   if (time)
+      set_next_reset(time);
+   else set_next_reset(3600);
+}
+
+int _normalfunction()
+{
+  mixed z;
+  int i;
+  z=this_player()->QueryProp(AUSGANG);
+  this_player()->SetProp(AUSGANG, query_verb());
+  i=(int)::_normalfunction();
+  if (!i) this_player()->SetProp(AUSGANG, z);
+  return i;
+}
+              
\ No newline at end of file
diff --git a/doc/beispiele/zauberwald/room/stein.c b/doc/beispiele/zauberwald/room/stein.c
new file mode 100644
index 0000000..cd74b07
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/stein.c
@@ -0,0 +1,112 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Bei einem Stein");
+   AddSpecialDetail(({"ort", "wald", "platz"}), "_query_int_long");
+   AddDetail("stein",
+     "Der Stein ist, durch die Sonnenstrahlen ordentlich aufgeheizt, angenehm warm\n"
+    +"und bietet eigentlich den idealen Platz um es sich gut gehn zu lassen und in\n"
+    +"der Sonne zu liegen.\n");
+   AddDetail(({"sonne", "himmel", "sonnenstrahlen", "strahlen"}),
+     "Der blaue Himmel ist nahezu wolkenfrei und so strahlt die Sonne in voller\n"
+    +"Pracht oben am Himmel und ihre Strahlen prasseln auf Deine Haut.\n");
+   AddDetail(({"boden", "weg", "waldweg", "erde"}),
+     "Ein ganz normaler Waldweg halt, ein bisschen sandig, einige kleine Aestchen\n"
+    +"ganz normal halt.\n");
+   AddSpecialDetail("zeit", "det_zeit");
+   AddDetail(({"aestchen", "stoeckchen"}),
+     "Ganz kleine heruntergefallene Stoeckchen, durch reges drueber laufen\n"
+    +"im Laufe der Zeit kleingemalen und vom Wetter aufgeloest...\n");
+   AddDetail("wetter",
+     "Auch wenn hier heute die Sonne scheint, gibt es natuerlich auch hier\n"
+    +"gelegentlich verregnete Tage.\n");
+   AddDetail("tage", "Naja... allzuviele sind es jedoch nicht.\n");
+   AddDetail(({"nordosten", "lichtung", "ausgang", "weiher"}),
+     "Im Nordosten kannst Du immer noch die grosse Lichtung mit den wandernden Eichen\n"
+    +"und dem verwunschenen Weiher erkennen.\n");
+   AddDetail(({"eichen", "wandernde eichen"}),
+     "Im Nordosten auf der Lichtung hast Du vorhin wandernde Eichen gesehn,\n"
+    +"vielleicht solltest Du einfach nochmal zurueck gehn und sie Dir naeher\n"
+    +"anschaun.\n");
+   AddDetail(({"wolke", "wolken", "schaefchenwolke"}),
+     "Der Himmel ist eigentlich wolkenfrei nur hier und da zieht mal eine kleine\n"
+    +"Schaefchenwolke vorbei.\n");
+   AddExit("nordosten", ROOM("lichtungsw"));
+   AddItem(NPC("titina"), REFRESH_REMOVE, 1);
+   AddCmd(({"setz", "setze", "leg", "lege", "kletter", "klettere"}), "cmd_setzen");
+   AddCmd(({"steh", "stehe"}), "cmd_aufstehn");
+}
+
+#define STEIN WALDID("stein")
+
+void init()
+{
+  if (PL) PL->SetProp(STEIN, 0);
+  ::init();
+}
+
+static int cmd_aufstehn(string str)
+{
+    if (!PL->QueryProp(STEIN)) return 0;
+    if (str!="auf" && str!="von stein auf") {
+       notify_fail("Von was moechtest Du aufstehn?\n");
+       return 0;
+    }
+    PL->SetProp(STEIN, 0);
+    write("Du kletterst also vom Stein wieder runter und stehst auf.\n");
+    return 1;
+}
+
+#define VERB(x) (["setz": "setzt", "leg": "legst", "kletter": "kletterst"])[x]
+
+static int cmd_setzen(string str)
+{
+   string verb;
+   verb=query_verb();
+   if (verb && verb[<1]=='e') verb=verb[0..<2];
+   if (str!="auf stein" && str!="stein" && str!="von stein") {
+      notify_fail(BS("Wohin moechtest Du "
+                 +(verb!="kletter" ? "Dich " : "")+verb+"en?"));
+      return 0;
+   }
+   if (PL->QueryProp(STEIN)) {
+      if (verb!="kletter" || str=="auf stein") {
+         write("Du sitzt doch bereits auf dem Stein!\n");
+         return 1;
+      }
+      PL->SetProp(STEIN, 0);
+      write("Du kletterst also vom Stein wieder runter und stehst auf.\n");
+      return 1;
+   }
+
+   write(BS("Entspannt "+VERB(verb)+" Du "+(verb!="kletter" ? "Dich " : "")
+        +"auf den Stein und geniesst die Sonne."));
+   PL->SetProp(STEIN, time());
+   return 1;
+}
+
+static string det_zeit()
+{  return "Wir haben genau "+dtime(time())[<8..]+".\n"; }
+
+static string _query_int_long()
+{
+   if (present(WALDID("fee"), ME))
+      return
+        "Hier mitten im Wald steht ein grosser Stein, auf dem Titina die wunderschoene\n"
+       +"Waldfee sitzt und sich in aller Ruhe ihr langes goldenes Haar kaemmt. Die\n"
+       +"Sonne strahlt genau auf den Stein und es ist wohl wirklich der gemuetlichste\n"
+       +"Ort auf Erden. Links und rechts vom Weg schliesst der dichte Wald an und so\n"
+       +"ist der einzige Ausgang Richtung Nordosten zurueck zur Lichtung.\n";
+   return "Hier mitten im Wald steht ein grosser Stein, der von der Sonne ordentlich\n"
+         +"aufgeheizt wird und ihn zu einem traumhaften Ort fuer alle Sonnenliebhaber\n"
+         +"macht. Links und rechts vom Weg schliesst direkt der dichte Wald an und so\n"
+         +"ist der einzige Ausgang Richtung Nordosten zurueck zur Lichtung.\n";
+}
diff --git a/doc/beispiele/zauberwald/room/tuempel.c b/doc/beispiele/zauberwald/room/tuempel.c
new file mode 100644
index 0000000..6f22d86
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/tuempel.c
@@ -0,0 +1,179 @@
+// (c) by Thomas Winheller (Padreic@mg.mud.de)
+
+#include "../files.h"
+#include <moving.h>
+
+inherit ROOM("stdroom");
+inherit "/std/room/kraeuter";
+
+void create()
+{
+   ::create();
+   SetProp(P_LIGHT, 2);
+   SetProp(P_INDOORS, 0);
+   SetProp(P_INT_SHORT, "An einem verwunschenden Weiher");
+   AddSpecialDetail(({"ort", "weiher"}), "_query_int_long");
+   AddDetail(({"seerosen", "farben", "farbenvielfalt"}),
+     "Auf dem Wasser schwimmen zahlreiche Seerosen in allen Farben des Regenbogens\n"
+    +"eine solche Farbenvielfalt wie hier, hast Du bisher noch nirgendwo sonst\n"
+    +"gesehn.\n");
+   AddDetail("regenbogen", "Derzeit steht keiner am Himmel.\n");
+   AddDetail(({"libelle", "libellen", "atmosphaere", "summen"}),
+     "Hier und da schwirren ueber dem Weiher einige Libellen herum. Ihr Summen\n"
+    +"verbreitet eine richtig idyllische Atmosphaere an diesem Ort.\n");
+   AddDetail(({"pixies", "zauberwesen"}),
+     "Pixies sind kleine verspielte Zauberwesen, die hier im Zauberwald wohnen. Um\n"
+    +"einem von ihnen zu begegnen wirst Du hier im Wald sicher nich lange suchen\n"
+    +"muessen, doch vorsicht, sie haben nichts als Unfug im Kopf...\n");
+   AddDetail(({"wald", "zauberwald", "punkt"}),
+     "Der verwunschene Weiher ist mehr oder weniger der zentrale Punkt hier im\n"
+    +"Zauberwald. Er liegt mitten auf einer grossen Lichtung umgeben vom dichten\n"
+    +"Wald der Pixies\n");
+   AddDetail(({"lichtung", "mitte"}),
+     "Der Weiher befindet sich genau in der Mitte der Lichtung, sieh Dich halt\n"
+    +"einfach mal um.\n");
+   AddDetail(({"boden", "ufer"}),
+     "Das Ufer des Weihers besteht aus zahlreichen Steinen die bis in den Weiher\n"
+    +"hineinreichen. Auf und zwischen diesen Steinen sind jedoch ueberall zahlreiche\n"
+    +"kleine und mittlere Pflanzen gewachsen.\n");
+   AddDetail(({"stein", "steine"}), "Ein Stein ist ein Stein ist ein Stein ist ein Stein ist ein Stein.\n");
+   AddDetail("pflanzen",
+     "Die verschiedensten Pflanzen wachsen zwischen den Steinen empor und begruenen\n"
+    +"das Ufer. An einer Stelle kannst Du sogar weissen Wasser-Hahnenfuss wachsen\n"
+    +"sehen.\n");
+   AddDetail(({"wasser", "schimmer", "schimmern"}),
+     "Das Wasser ist irgendwie recht trueb und es geht ein sehr seltsames Schimmern\n"
+    +"von ihm aus. Irgendetwas besonderes hat es mit diesem Wasser auf sich, das\n"
+    +"spuerst Du genau. Du weisst jedoch nicht, ob es etwas gutes oder etwas boeses\n"
+    +"ist.\n");
+   AddDetail(({"himmel", "luft", "sonne", "waerme", "strahlen", "sonnenstrahlen"}),
+     "Die Sonne steht hoch am Himmel und fuellt diesen Ort mit einer herrlichen\n"
+    +"Waerme und ihre Strahlen reflektieren im Wasser in allen erdenklichen Farben.\n");
+   AddExit("norden", ROOM("lichtungn"));
+   AddExit("nordosten", ROOM("lichtungno"));
+   AddExit("nordwesten", ROOM("lichtungnw"));
+   AddExit("osten", ROOM("lichtungo"));
+   AddExit("westen", ROOM("lichtungw"));
+   AddExit("sueden", ROOM("lichtungs"));
+   AddExit("suedwesten", ROOM("lichtungsw"));
+   AddExit("suedosten", ROOM("lichtungso"));
+   AddItem(NPC("ulinia"), REFRESH_REMOVE, 1);
+   AddCmd(({"bad", "bade", "schwimm", "schwimme", "tauch", "tauche"}), "cmd_schwimmen");
+   AddCmd(({"trink", "trinke"}), "cmd_trinken");
+   AddCmd(({"pflueck", "pfluecke"}), "cmd_pfluecken");
+   // Detail per Hand hinzufuegen, da GetPlant anstelle von AddPlant
+   // verwendet wird.
+   AddPlantDetail(OBJ("hahnenfuss"));
+}
+
+static int cmd_trinken(string str)
+{
+   int drink;
+   object ob;
+   if (member(({"wasser", "wasser aus teich", "wasser aus tuempel",
+                "wasser aus see", "aus teich", "aus tuempel", "aus wasser",
+                "aus see"}), str)==-1) {
+      notify_fail("Was moechtest Du trinken?\n");
+      return 0;
+   }
+   if ((ob=present(WALDID("fee"), ME)) && !ob->IsEnemy(PL)) {
+      write(BS("Die Waldfee scheint Deinen Entschluss ein wenig von dem "
+         +"Wasser zu kosten, bemerkt zu haben und straft Dich mit einem "
+         +"mahnenden Blick ab. Du ueberlegst es Dir also noch einmal und "
+         +"laesst von Deinem Vorhaben ab."));
+      return 1;
+   }
+   // das tanken am Wasser ist umsonst, es heilt dabei wie ein
+   // Kneipengetraenk das genau 1 Muenze kostet. Geheilt werden nur SP
+   // Ein Missbrauch ist im Wald ausgeschlossen, bzw. man muesste den
+   // gesamten Wald leermetzeln und kann dann ueben bis zum naechsten
+   // reset. Bei Kosten von einer Muenze pro Heilung ist es sehr fraglich
+   // ob sich das lohnt.... :)
+   drink=(PL->QueryProp(P_MAX_DRINK)) - (PL->QueryProp(P_DRINK));
+   if (drink>10) drink=10; // nie mehr als fuer 10 soak tanken...
+   if (drink <= 0 || !PL->drink_soft(drink, 1)) {
+      write("Du bist so voll, Du kannst leider wirklich nichts mehr trinken...\n");
+      return 1;
+   }
+   write("Du gehst an den Rand des Weihers und nimmst einen kraeftigen Schluck von dem\n"
+        +"Wasser. Sogleich spuerst Du, wie Deine mentalen Kraefte langsam gestaerkt\n"
+        +"werden.\n");
+   if (PL->drink_soft(drink)) { // soak gutschreiben erfolgreich?
+      PL->buffer_sp(drink*6, 5);
+      PL->SetProp(ZAUBERWALD, time()+AGGRESSIVE_TIME);
+   }
+   return 1;
+}
+
+static int cmd_schwimmen(string str)
+{
+   string verb;
+
+   // besondere Eigenschaft der schluesselwoerter ausnutzen... :)
+   verb=(query_verb()||"");
+   if (verb[<1]!='e') verb+="e";
+   if (member(({"in teich", "in weiher", "in tuempel", "in see"}), str)==-1) {
+      notify_fail("Worin willst Du "+verb+"n?\n");
+      return 0;
+   }
+   str=capitalize(str[3..]); // "in " abschneiden...
+   if (present(WALDID("fee"), ME)) {
+      write(BS("Die Waldfee scheint Deinen Entschluss im "+str+" "+verb
+         +"n zu gehn irgendwie bemerkt zu haben und straft Dich mit einem "
+         +"mahnenden Blick ab. Deine Lust zum "+capitalize(verb)
+         +"n sinkt sogleich gegen null, denn Du verspuerst keine grosse "
+         +"Lust Dich mit der Waldfee anzulegen."));
+      return 1;
+   }
+   write(BS("Mutig gehst Du einen Schritt ins Wasser, da ueberkommt Dich auch "
+           +"schon ein seltsames kribbeln am ganzen Koerper. In windeseile "
+           +"hast Du den "+str+" auch schon wieder verlassen."));
+   return 1;
+}
+
+static int cmd_pfluecken(string str)
+{
+   object ob;
+   notify_fail("WAS moechtest Du pfluecken?\n");
+   if (member(({"hahnenfuss",
+                "wasser-hahnenfuss",
+                "weisser hahnenfuss",
+                "weisser wasser-hahnenfuss"}), str)<0) return 0;
+   if ((ob=present(WALDID("fee"), ME)) && !ob->IsEnemy(PL)) {
+      write(BS("Die Waldfee scheint Dein Vorhaben bemerkt zu haben und "
+         +"straft Dich mit einem mahnenden Blick ab. Du ueberlegst es Dir "
+         +"wieder anders und laesst von Deinem Vorhaben ab, solange die "
+         +"Fee hier wacht."));
+      return 1;
+   }
+   ob=GetPlant(OBJ("hahnenfuss"));
+   if (objectp(ob)) {
+      if (ob->move(PL, M_GET)==1)
+          write(BS("Vorsichtig pflueckst Du "+ob->name(WEN, 1)
+                  +" und nimmst "+ob->QueryPronoun(WEN)+" an Dich."));
+      else write(BS("Vorsichtig pflueckst Du "+ob->name(WEN, 1)+" kannst "
+                  +ob->QueryPronoun(WEN)+" aber nicht nehmen."));
+   }
+   else if (!ob)
+      write(BS("Der Hahnenfuss ist noch nicht wieder weit genug "
+              +"nachgewachsen um ihn pfluecken zu koennen."));
+   return 1;
+}
+
+static string _query_int_long()
+{
+   if (present(WALDID("fee"), ME))
+      return
+        "Du stehst nun an einem kleinen verwunschenen Weiher, inmitten des Zauberwalds.\n"
+       +"Auf dem Wasser schwimmen zahlreiche Seerosen in den verschiedensten Farben\n"
+       +"und hier und dort schwirrt eine Libelle in der Luft. Mitten ueber dem Weiher\n"
+       +"schwebt eine wunderschoene Waldfee in der Luft und scheint den Weiher zu\n"
+       +"bewachen. Irgendetwas geheimnisvolles scheint es mit dem Weiher auf sich\n"
+       +"zu haben, nur was?\n";
+   return
+     "Du stehst nun an einem kleinen verwunschenen Weiher, inmitten des Zauberwalds.\n"
+    +"Auf dem Wasser schwimmen zahlreiche Seerosen in den verschiedensten Farben und\n"
+    +"hier und dort schwirrt eine Libelle in der Luft. Alles scheint hier sehr\n"
+    +"friedlich zu sein, fast ein wenig zu friedlich. Irgendetwas geheimnisvolles\n"
+    +"scheint es mit diesem Weiher auf sich zu haben, nur was?\n";
+}
diff --git a/doc/beispiele/zauberwald/room/virtual_compiler.c b/doc/beispiele/zauberwald/room/virtual_compiler.c
new file mode 100644
index 0000000..1cc4d5c
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/virtual_compiler.c
@@ -0,0 +1,133 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include <properties.h>
+#include <v_compiler.h>
+#include "../files.h"
+#include "/p/service/padreic/kraeuter/plant.h"
+
+inherit "std/virtual/v_compiler";
+
+create()
+{
+  ::create();
+  SetProp(P_STD_OBJECT, ROOM("stdlichtung"));
+  SetProp(P_COMPILER_PATH, ROOM(""));
+}
+
+string Validate(string file)
+{
+  file=::Validate(file);
+  switch(file) { 
+     case "lichtungso":
+     case "lichtungo":
+     case "lichtungno":
+     case "lichtungn":
+     case "lichtungs":
+     case "lichtungnw":
+     case "lichtungw":
+     case "lichtungsw":  return file;
+     default:
+  }
+}
+         
+mixed CustomizeObject()
+{
+  string file;
+  file=Validate(::CustomizeObject());
+  if (!random(3)) PO->AddItem(NPC("laufeiche"), REFRESH_DESTRUCT, ([MNPC_HOME: ROOM(file)]) );
+  switch(file) {
+     case "lichtungno":
+       PO->AddExit("westen", ROOM("lichtungn"));
+       PO->AddExit("sueden", ROOM("lichtungo"));
+       PO->AddExit("suedwesten", ROOM("tuempel"));
+       PO->AddExit("suedosten", ROOM("weg2"));
+       PO->SetProp(EXTRA_LONG,
+         " Im Suedosten befindet sich der Waldweg, ueber den Du den Wald wieder "
+        +"verlassen kannst.");
+       return file;
+
+     case "lichtungo":
+       PO->AddExit("norden", ROOM("lichtungno"));
+       PO->AddExit("sueden", ROOM("lichtungso"));
+       PO->AddExit("westen", ROOM("tuempel"));
+       PO->AddExit("osten", ROOM("weg2"));
+       PO->SetProp(EXTRA_LONG,
+         " Im Osten befindet sich der Waldweg, ueber den Du den Wald wieder "
+        +"verlassen kannst.");
+       return file;
+
+     case "lichtungso":
+       PO->AddExit("westen", ROOM("lichtungs"));
+       PO->AddExit("norden", ROOM("lichtungo"));
+       PO->AddExit("nordwesten", ROOM("tuempel"));
+       PO->AddExit("nordosten", ROOM("weg2"));
+       PO->SetProp(EXTRA_LONG,
+         " Im Nordosten befindet sich der Waldweg, ueber den Du den Wald wieder "
+        +"verlassen kannst.");
+       PO->AddItem(NPC("riese"), REFRESH_DESTRUCT);
+       return file;
+
+     case "lichtungs":
+       PO->AddExit("westen", ROOM("lichtungsw"));
+       PO->AddExit("osten", ROOM("lichtungso"));
+       PO->AddExit("norden", ROOM("tuempel"));
+       PO->SetProp(EXTRA_LONG,
+         " In der Wiese siehst Du an einer Stelle etwas Klee wachsen.");
+       PO->AddPlant(BITTERKLEE);
+       // "klee" _nach_ dem AddPlant einfuegen, damit die restlichen Details
+       // wie Bitterklee trotzdem noch eingefuegt werden
+       PO->RemoveDetail(({"klee"}));
+       PO->AddDetail(({"stelle", "klee"}),
+         "Bei der Stelle scheint es sich unzweifelhaft um Bitterklee zu handeln.\n");
+       PO->AddCmd("sueden", "cmd_sueden");
+       return file;
+
+     case "lichtungn":
+       PO->AddExit("westen", ROOM("lichtungnw"));
+       PO->AddExit("osten", ROOM("lichtungno"));
+       PO->AddExit("sueden", ROOM("tuempel"));
+       PO->SetProp(EXTRA_LONG, " Am Rand der Wiese entdeckt Du einige kleine Pilze im Gras.");
+       PO->AddCmd(({"esse", "iss", "pflueck", "pfluecke"}), "cmd_pilze");
+       PO->AddDetail(({"pilz", "pilze", "schimmer"}),
+         "Die Pilze haben einen aeusserst seltsamen metallischem Schimmer und\n"
+        +"verbreiten einen sehr angenehmen suesslichen Duft im Raum.\n");
+       PO->AddSmells(({"pilz", "pilze"}),
+         "Die Pilze verbreiten einen sehr suesslichen Duft.\n");
+       PO->AddSmells("duft", "Der Duft ist eigentlich sehr befreiend und angenehm.\n");
+       return file;
+
+     case "lichtungnw":
+       PO->AddExit("westen", ROOM("schule"));
+       PO->AddExit("osten", ROOM("lichtungn"));
+       PO->AddExit("sueden", ROOM("lichtungw"));
+       PO->AddExit("suedosten", ROOM("tuempel"));
+       PO->SetProp(EXTRA_LONG,
+         " Nach Westen kannst Du ein Stueck in den Wald hinein gehn.");
+       return file;
+
+     case "lichtungw":
+       PO->AddExit("norden", ROOM("lichtungnw"));
+       PO->AddExit("sueden", ROOM("lichtungsw"));
+       PO->AddExit("osten", ROOM("tuempel"));
+       PO->SetProp(EXTRA_LONG, " Am Waldrand stehen einige blaeuliche Farne.");
+       PO->AddCmd(({"esse", "iss", "pflueck", "pfluecke"}), "cmd_farne");
+       PO->AddDetail(({"farn", "farne"}),
+         "Die blaeulichen Farne sind wirklich sehr merkwuerdig. soetwas hast Du bisher\n"
+        +"noch nirgendwo gesehn. Irgendetwas besonderes hat es sicherlich damit auf sich.\n");
+       return file;
+
+     case "lichtungsw":
+       PO->AddExit("osten", ROOM("lichtungs"));
+       PO->AddExit("norden", ROOM("lichtungw"));
+       PO->AddExit("nordosten", ROOM("tuempel"));
+       PO->AddExit("suedwesten", ROOM("stein"));
+       PO->SetProp(EXTRA_LONG,
+         " Nach Suedwesten kannst Du ein Stueck in den Wald hinein gehn.");
+       return file;
+
+     default: return 0;
+  }
+  return file;
+}
+
+int NoParaObjects() { return 1; }
diff --git a/doc/beispiele/zauberwald/room/weg1.c b/doc/beispiele/zauberwald/room/weg1.c
new file mode 100644
index 0000000..169b73f
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/weg1.c
@@ -0,0 +1,75 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 0);
+   SetProp(P_INT_SHORT, "Auf einem Waldweg im Zauberwald");
+   AddDetail(({"blaetterdach", "dach", "baeume"}),
+     "Die Baeume rechts und links des Weges bilden ueber dem Weg ein so dichtes\n"
+    +"Blaetterdach, das so gut wie ueberhaupt kein Sonnenlicht mehr auf den Weg\n"
+    +"scheint.\n");
+   AddSpecialDetail("szene", "_query_int_long");
+   AddSpecialDetail(({"weg", "weges", "waldweg", "boden"}), "det_weg");
+   AddDetail(({"licht", "sonnenlicht", "sonnenstrahlen"}),
+     "Durch das dichte Blaetterdach schaffen es die Sonnenstrahlen nur noch sehr\n"
+    +"vereinzelt bis auf den Weg durchzukommen. Dadurch ist es hier unten relativ\n"
+    +"Feucht, kalt und dunkel.\n");
+   AddDetail(({"himmel", "sonne", "wolke", "wolken"}),
+     "Das Blaetterdach ist hier so dicht, das Du den Himmel nicht mal mehr erahnen\n"
+    +"kannst. Du weisst nicht mal, ob es regnet oder ob die Sonne scheint.\n");
+   AddDetail("feucht",
+     "Bloss weil feucht grossgeschrieben ist es noch lange kein Substantiv, wenn\n"
+    +"ueberhaupt heisst es dann _Feuchtigkeit_ :).\n");
+   AddDetail("substantiv", "Nicht jedes Substantiv ist ein sinnvolles Detail :)\n");
+   AddDetail("feuchtigkeit", "Ein wenig feucht, wie man es halt aus jedem Wald so kennt.\n");
+   AddDetail("kaelte",
+     "Durch das wenige Sonnenlicht, das bis nach hier unten durchdringt, ist es\n"
+    +"hier verhaeltnismaessig frisch.\n");
+   AddDetail("dunkelheit",
+     "Wenn es hell ist, ist es nicht mehr dunkel und wenn es nicht hell ist, kannst\n"
+    +"Du nicht viel sehn. Wie also willst Du die Dunkelheit untersuchen :)?\n");
+   AddDetail("_feuchtigkeit_", "Meine Guete, nimm doch nich immer alles gleich _so_ woertlich.\n");
+   AddDetail("guete", "Sei lieber vorsichtig, soo guetig bin ich nu auch nicht :).\n");
+   AddDetail(({"lichtquelle", "nachtsicht"}),
+     "Hier ist es eigentlich verdammt dunkel und ohne Nachtsicht oder eine eigene\n"
+    +"Lichtquelle, koenntest Du hier _nichts_ sehn.\n");
+   AddDetail(({"ausgang", "osten"}),
+     "Wenn Du dem Weg Richtung Osten folgst, dann kommst Du ziemlich bald wieder\n"
+    +"Richtung Ausgang.\n");
+   AddDetail(({"stueck", "wald", "westen"}),
+     "Naja.. Du stehst zwar schon im Wald drin, aber nach Westen hin, gehst es noch\n"
+    +"ein Stueck tiefer hinein.\n");
+   AddExit("osten", ROOM("eingang"));
+   AddExit("westen", ROOM("weg2"));
+   AddItem(NPC("waechter"), REFRESH_REMOVE, 1);
+}
+
+static string det_weg()
+{
+   if (present(WALDID("waechtereiche"), ME))
+      return "Mitten auf dem Weg steht der Waechter des Waldes und kontrolliert sehr genau,\n"
+            +"wer in den Wald hinein darf und wer nicht. Eigentlich ist er jedoch den\n"
+            +"meisten immer sehr friedlich gesonnen.\n";
+   return "Der Weg fuehrt hier nach Westen noch ein Stueck tiefer in den Wald hinein,\n"
+         +"nach Osten kannst Du jedoch wieder in Richtung Ausgang des Zauberwalds gehn.\n";
+}
+
+static string _query_int_long()
+{
+   if (present(WALDID("waechtereiche"), ME))
+      return "Hier ist es jetzt richtig duester und ohne eigene Lichtquelle koenntest Du\n"
+            +"nichts mehr sehn, da so gut wie ueberhaupt kein Licht mehr durch das\n"
+            +"Blaetterdach auf den Weg scheint. Mitten in dieser eigentlich lebens-\n"
+            +"unfreundlichen Szene, steht eine grosse alte Eiche mitten auf dem Weg.\n";
+   return "Hier ist es jetzt richtig duester und ohne eigene Lichtquelle koenntest Du\n"
+         +"hier nichts mehr sehn, da so gut wie ueberhaupt kein Licht mehr durch das\n"
+         +"Blaetterdach auf den Weg scheint. Du kannst noch ein Stueck tiefer in den\n"
+         +"Wald hinein und nach Westen gehn, oder aber zurueck Richtung Kreuzung nach\n"
+         +"Osten.\n";
+}
diff --git a/doc/beispiele/zauberwald/room/weg2.c b/doc/beispiele/zauberwald/room/weg2.c
new file mode 100644
index 0000000..0d06169
--- /dev/null
+++ b/doc/beispiele/zauberwald/room/weg2.c
@@ -0,0 +1,93 @@
+// (c) by Padreic (Padreic@mg.mud.de)
+
+#include "../files.h"
+
+inherit ROOM("stdroom");
+
+void create()
+{
+   ::create();
+   SetProp(P_INDOORS, 0);
+   SetProp(P_LIGHT, 1);
+   SetProp(P_INT_SHORT, "Am Rande einer Lichtung im Zauberwald");
+   AddSpecialDetail(({"wald", "zauberwald"}), "_query_int_long");
+   AddDetail(({"westen", "lichtung", "plaetzchen", "idyllisches plaetzchen"}),
+     "Im Westen befindet sich eine grosse Lichtung mit einem kleinen Tuempel, am\n"
+    +"Rande der Lichtung stehen vereinzelt noch einige Baeume aber zum Tuempel hin,\n"
+    +"wird es dann mehr und mehr nur noch Gras das den Boden bedeckt.\n");
+   AddDetail(({"rasen", "gras"}),
+     "Am besten betrittst Du die Lichtung einfach und schaust Dir den Rasen\n"
+    +"naeher an.\n");
+   AddDetail("tuempel",
+     "Wenn Du Dir den Tuempel naeher ansehen moechtest, dann solltest Du schon\n"
+    +"ein Stueck naeher rangehen.\n");
+   AddDetail(({"stueck", "raum"}),
+     "Na wenigstens einen Raum weiter solltest Du schon gehn.\n");
+   AddDetail("schatten",
+     "Hier befindest Du Dich noch im Schatten der Baeume, die Lichtung im Westen\n"
+    +"liegt jedoch komplett in der waermenden Sonne.\n");
+   AddSpecialDetail("sonne", "det_sonne");
+   AddDetail(({"wegesrand", "baeume", "wegrand", "rand"}),
+     "Am Wegesrand stehen einige Baeume die ein schoenes Blaetterdach ueber den Weg\n"
+    +"spannen und den Weg in ihren Schatten legen.\n");
+   AddDetail(({"himmel", "blaetterdach", "dach", "licht", "sonnenstrahlen", "wolken", "wolke"}),
+     "Das Blaetterdach ist ziemlich dicht, so dass Du nicht soo viel sehen kannst,\n"
+    +"aber einige Sonnenstrahlen durchbrechen das Dach und erreichen den Weg.\n");
+   AddDetail(({"weg", "boden", "erde", "ausgang", "osten", "richtung"}),
+     "Im Westen fuehrt der Weg zu einer grossen Lichtung, waehrend er nach Osten hin\n"
+    +"Richtung Ausgang des Zauberwalds fuehrt.\n");
+   AddDetail("voegel", "Du kannst sie deutlich hoeren, bekommst aber keinen zu sehn.\n");
+   AddExit("osten", ROOM("weg1"));
+   AddExit("suedwesten", ROOM("lichtungso"));
+   AddExit("westen", ROOM("lichtungo"));
+   AddExit("nordwesten", ROOM("lichtungno"));
+   AddCmd("osten", "cmd_osten");
+   AddItem(NPC("laufeiche"), REFRESH_DESTRUCT);
+}
+
+static string det_sonne()
+{
+   if (PL) PL->SetProp(P_BLIND, 1);
+   return "Du schaust fasziniert in die Sonne und untersucht sie naeher, doch das war\n"
+         +"wohl ein grosser Fehler, denn ploetzlich wird es ganz ganz dunkel um Dich rum.\n";
+}
+
+void init()
+{
+   // wenn man von westen kommt und keine blockende Eiche hier ist, dann
+   // so betrachten als waere man aus dem osten gekommen
+   if (query_once_interactive(PL) && !present(WALDID("eiche")))
+      PL->SetProp(AUSGANG, "westen");
+   ::init();
+}
+
+static int cmd_osten()
+// wenn gerade eine Eiche hierhin gelaufen ist, kommen feindliche
+// Spieler nicht mehr vorbei :)
+{
+   if (PL && PL->QueryProp(AUSGANG)!="westen" &&
+       PL->QueryProp(ZAUBERWALD)>time() && present(WALDID("eiche"), ME)) {
+      if (present(WALDID("eiche 2"), ME))
+         write("Die Eichen stehen Dir dabei leider im Weg und lassen Dich nicht vorbei.\n");
+      else write("Die Eiche steht Dir dabei leider im Weg und laesst Dich nicht vorbei.\n");
+      return 1;
+   }
+}
+
+static string _query_int_long()
+{
+   if (!PL || PL->QueryProp(ZAUBERWALD)<=time())
+     return
+      "Du stehst nun mitten im Zauberwald. Im Westen erstreckt sich vor Dir eine\n"
+     +"grosse Lichtung, auf die Du muehelos gelangen kannst. Nach Osten hin fuehrt\n"
+     +"ein schmaler Weg zurueck zum Ausgang des Waldes. Alles scheint hier sehr\n"
+     +"friedlich zu sein, die Voegel zwitschern und das Blaetterdach ist hier auch\n"
+     +"nicht mehr so dicht wie im Osten, so dass einige Sonnenstrahlen den Weg\n"
+     +"erreichen. Es zieht Dich foermlich nach Westen auf die Lichtung, mitten auf\n"
+     +"dieses sonnige idyllische Plaetzchen.\n";
+   return "Nichts wie raus hier. Es war ganz und gar keine gute Idee hier im Wald Deiner\n"
+         +"Aggressivitaet freien Lauf zu lassen. Du kannst von Glueck haben, wenn Du mit\n"
+         +"einem blauen Auge davon kommst und den Wald noch lebend verlassen kannst.\n"
+         +"Nach Westen gelangst Du auf die grosse Lichtung, ratsamer waere jedoch wohl\n"
+         +"eher der Waldweg im Osten, ueber den Du den Zauberwald wieder verlassen kannst.\n";
+}
diff --git a/doc/concepts/.synonym b/doc/concepts/.synonym
new file mode 100644
index 0000000..06bb40a
--- /dev/null
+++ b/doc/concepts/.synonym
@@ -0,0 +1,19 @@
+effizient effizienz
+optimieren effizienz
+optimierung effizienz
+optimal effizienz
+performanz effizienz
+speicher memory
+swap memory
+swapping memory
+objekt objects
+objekte objects
+objektorientiert oop
+objektorientierung oop
+property properties
+props properties
+terminal terminals
+stil goodstyle
+style goodstyle
+guterstil goodstyle
+kosten ticks
diff --git a/doc/concepts/concepts b/doc/concepts/concepts
new file mode 100644
index 0000000..54bfae0
--- /dev/null
+++ b/doc/concepts/concepts
@@ -0,0 +1,9 @@
+NAME
+        concepts
+
+DESCRIPTION
+        This directory contains man pages about basic concepts of the
+        LPC language as it is provided by Amylaars parser/interpreter.
+
+SEE ALSO
+        driver(D), efun(E), applied(A), master(M), lpc(LPC)
diff --git a/doc/concepts/effizienz b/doc/concepts/effizienz
new file mode 100644
index 0000000..3f99c48
--- /dev/null
+++ b/doc/concepts/effizienz
@@ -0,0 +1,222 @@
+Effizienz
+ BESCHREIBUNG:
+     Effizienz in der Programmierung ist leider nicht ganz so einfach zu
+     beschreiben, da es viel mit der zugrundeliegenden Verarbeitung der
+     Programme zu tun hat. Es geht ganz gut am Beispiel.
+
+     Generell haben Lesbarkeit und Wartbarkeit von Code Vorrang vor dessen
+     Effizienz, gerade weil die wirklich arbeitslastigen Methoden in der Lib
+     stecken. Ausserdem ist es im Allgemeinen nicht empfehlenswert, (viel)
+     Aufwand in die Optimierung von Code zu stecken, solange nicht klar ist,
+     dass dies ueberhaupt notwendig ist.
+     Les-/Wartbarkeit und effizienter Stil schliessen sich aber nicht aus und
+     einige (einfache) Grundregeln lassen sich einfach einhalten.
+
+     Fuer diejenigen unter euch, die gerade erst mit LPC zusammenstossen
+     gibt es (*) an den besonders wichtigen Stellen. Auf Dauer solltet ihr
+     aber mal alle Eintraege ueberfliegen. Den ersten koennen alle hier
+     beherzigen:
+
+     LPC wird beim Laden nicht optimiert:
+      Das was ihr schreibt, wird auch so ausgefuehrt, es werden keine
+      Schleifen optimiert, keine unnoetigen Zuweisungen entfernt, nichts
+      wird veraendert:
+      - ueberlegt euch also euren Code gut, wenn er an kritischen Stellen
+        steht oder sehr viel Rechenzeit kostet (zB geschachtelte Schleifen)
+      - testet einfach mal Varianten und fragt auf -lpc nach Optimierung!
+
+     call_out und heart_beat erzeugen konstante Last:
+      Jeder call_out() steht in einer Liste, die im selben Takt wie der
+      heart_beat() durchsucht wird. Beides kostet Zeit. Beide Methoden
+      verhindern zudem das Ausswappen des entsprechenden Objektes. Deshalb
+      schalten sich Raummeldungen (AddRoomMessage funktioniert ueber
+      call_out()) und der heart_beat() von /std/npc nach dem Verlassen des
+      Raumes durch den letzten Spieler selbst aus.
+ *    - bitte achtet darauf, unnoetige call_out/heart_beat zu vermeiden.
+        (Insbesondere sich bewegende NPCs sollten sich auch irgendwann
+         wieder abschalten - es gibt einen funktionierenden MNPC mit diesen
+         Eigenschaften unter /p/service/padreic/mnpc.)
+      - fuer regelmaessige Aufrufe in einem Objekt, wo der genaue Zeitpunkt
+        nicht auf einige Sekunden ankommt,  bietet sich auch reset() mit
+        set_next_reset() an
+      - statt call_out()-Ketten in einem Raum laufen zu lassen, kann man
+        sich auch die letzte Aktivierung merken und bei einem init()
+        wieder ein entsprechend langes call_out() starten
+
+     Speicher und das Drumherum:
+      Die Speichersituation ist nicht mehr verzweifelt. Das heisst aber
+      nicht, dass damit geschlampt werden kann. Gleichzeitig ist die
+      Reservierung von Speicher und die Garbage Collection, das Einsammeln
+      freigegebenen Speichers bei Freigaben von Variablen (wie bei x+y,
+      x=0 (x,y==array/mapping)) immer kostspielig. Folgend ein paar
+      Tipps dazu:
+      Groesse:
+      - wenn moeglich, globale Variablen nach Nutzung freigeben - ggf.
+        #defines benutzen: Vorsicht jedoch bei Mapping/Array (siehe unten)
+      - globale oder in Properties abgespeicherte Mappings/Arrays/
+        Strings klein halten und nur dynamisch erweitern
+      - programmiert man an vielen Stellen gleichen Code, dann ist es
+        sinnvoll, diesen in eine eigene Datei/Klasse zu giessen und von
+        dieser zu erben - das spart Speicher und laesst sich besser warten
+      - replace_program bitte nur benutzen, wenn man weiss, was es bewirkt,
+        /std/room verwendet es bereits automagisch
+ *    - Objekte in Raeumen und NPCs sollten per AddItem() addiert werden,
+        da die generelle Aufraeumfunktion /std/room::clean_up() dann weiss
+        ob der Raum entfernt werden kann
+      - es sollte keine ewigen Objektquellen geben
+      - Blueprints:
+        - Soll es immer nur ein Objekt von etwas geben, stellt die Blueprint
+          per AddItem(...,...,1) dort hin.
+          Achtung: Blueprints neu zu laden, ist teuer im Vergleich zum clonen.
+                   Gerade bei NPCs (die beim Tod zerstoert werden), sollte
+                   man das im Hinterkopf behalten.
+        - Die BP von geclonten Objekten muss nicht immer initialisiert werden,
+          speziell bei komplexen Objekten kann es sich lohnen, die
+          Initialisierung der BP im create abzubrechen. (Denn meistens ist nur
+          ihr Programm interessant)
+          protected void create() {
+            if(!clonep(this_object())) {
+              set_next_reset(-1);   // falls die Clones im reset() was
+              return;               // machen
+            }
+            ::create(); ...
+          }
+      
+     Kosten:
+ *    - es lohnt, lokale Mappings oder Arrays mit bekannter Groesse via
+        allocate() oder m_allocate() vor Belegung in voller benoetiger
+        Groesse zu reservieren:
+        statt:
+          int *x = ({}); foreach(int i: 10) x+=({i});
+        lieber:
+          int *x = allocate(10); foreach(int i: 10) x[i] = i;
+ *    - wiederholtes Ausschneiden (slice) aus Arrays vermeiden, dabei wird
+        staendig Speicher neu alloziiert und benutzter Speicher freigegeben:
+        statt:
+          int *x; ...; while(sizeof(x)) { x[0]...; x=[1..x]; }
+        lieber:
+          int *x; ...; i=sizeof(x); while(j<i) { x[j]...; j++; }
+ *    - direkte Mapping/Array ({}), ([]) in Methoden (zB ueber #define)
+        sparen zwar globalen Platz, kosten aber Konstruktionszeit bei jedem
+        Aufruf dieser Methoden - fuer haeufig gerufene Methoden sollten
+        grosse Datenstrukturen einmal global konstruiert werden
+        statt:    #define GROSSES_MAPPING ([....])
+                  void haeufige_fun() { ... GROSSES_MAPPING ... }
+        lieber:   mapping GROSSES_MAPPING = ([....]);
+                  void haeufige_fun() { ... GROSSES_MAPPING ... }
+ *    - diverse efuns sind genauso schnell zugreifbar wie Variablen,
+        muessen also nur zugewiesen werden, wenn sich der Wert aendern kann:
+        this_player(), this_interactive(), environment(), previous_object(),
+        this_object().
+ *    - statt all_inventory() einer Variablen zuzuweisen und darueber
+        zu iterieren, kann man oft mit first_inventory() und next_inventory()
+        ein Inventory durchgehen
+
+     Methoden:
+      Die Methoden eines Objektes werden in einer Liste gespeichert, die
+      beim Aufruf einer Methode ueber call_other() (oder o->fun())
+      durchgesehen wird. Das hat folgende Konsequenzen:
+ *    - jede oeffentliche Methode wird bei call_other() durchsucht und
+        das kostet Zeit, wenn eine Methode also nicht oeffentlich sein
+        muss, dann schreibt auch ein "protected" davor, wenn sie in den
+        erbenden Klassen nicht sichtbar sein muss: "private"
+      - nutzt ihr eine fremde Methode mehrfach (zB QueryProp), dann ist es
+        an sehr kritischen Stellen sinnvoll, diese einmal zu suchen und an
+        eine Lfun-Closure zu binden, weitere Aufrufe sind schneller:
+         closure cl;
+         cl=symbol_function("QueryProp",this_player());
+         funcall(cl, P_LEVEL); funcall(cl, P_SIZE); ...
+      Nebenbei bemerkt:
+      - es gibt in LPC kein sog. fruehes Binden, "this_object()->function();"
+        ist fast immer unnoetig und fast immer nur ein Zeichen fuer Faulheit die
+        richtigen Prototypen zu inkludieren/formulieren.
+
+     Lambdas:
+      Lambda-Closures sind nicht nur schwer zu lesen, sondern oft auch langsamer
+      als andere Closures. Speziell wird bei jedem Auftreten von lambda() die
+      Lambda neu erzeugt.
+      Nehmt euch die Zeit aus einer Lambda-Closure eine Lfun-Closure zu
+      machen oder sie zumindest an eine globale Closure-Variable zu binden,
+      damits sie schnell ausgefuehrt werden kann. #define bietet sich hier
+      nicht an.
+      statt:  filter(users(),
+                       lambda(({'x}), ({#'call_other,'x,
+                                    "QueryProp",P_SECOND})));
+      lieber: private static int _isasec(object o) {
+                return o->QueryProp(P_SECOND);
+              }
+              ...
+              filter(users(), #'_isasec);
+      oder:   closure cl;
+              cl=lambda(({'x}), ... );
+              ...
+              filter(users(), cl);
+      oder:
+      Bessere Alternative zu Lambdas sind uebrigens inline-closures (man
+      inline-closures), die deutlich schneller und einfacher zu lesen sind.
+              filter(users(), function mixed (pl)
+                              {
+                                pl->QueryProp(P_SECOND);
+                              }
+                    );
+
+
+     Simul-efun und die Last der Vergangenheit:
+      Es gibt einige Simul-Efuns, die anstelle einer aehnlichen Efun verwendet
+      werden, aber langsamer sind. Beispiel: die sefun m_copy_delete() macht
+      fast das gleiche wie m_delete(), erzeugt aber vorher immer eine Kopie.
+      Wenn man diese nicht braucht, sollte man m_delete() den Vorzug geben.
+
+
+     Generelle Bemerkungen:
+ ***  - LAG entsteht vor allem dann, wenn zu viele Dinge auf einmal
+        identifiziert, bewegt, geladen, gecloned oder kopiert werden
+        sollen (in nur einem Kommando, in einem reset(), ...)
+        - zerlegt solche Aufgaben mit call_out/heart_beat in Haeppchen
+        - lasst es einen Erzmagier durchsehen
+ *    - Variablen sind immer auf 0 initialisiert,
+        allocate()-Arrays sind mit 0 oder Wunschwert initialisiert.
+      - gleicher Code sollte aus Schleifen sollten entfernt werden,
+        zB bei Iteration ueber ein Array gehoert das sizeof() vor die
+        Schleife, nicht in den Test
+ *    - beim Identifizieren eindeutiger Objekte ist present_clone()
+        wesentlich billiger als ein present() + geschuetzten IDs
+ *    - aus Arrays koennen mittels "-" viele identische Werte auf einmal
+        entfernt werden, es ist also sinnvoll bei Loeschoperationen
+        zu loeschende Werte auf einen bestimmten Wert zu setzen und diesen
+        dann mittels array-=({wert}) zu entfernen.
+        Wir entfernen alle getoeteten NPC, d.h. alle geloeschten Objekte
+        aus einer Liste: meinelistemitnpcs-=({0})
+      - efuns sind oft schneller als eigene Konstrukte, gerade was
+        Arrays betrifft. Pauschalisiert kann das nicht werden, man muss
+        auch immer die noetige Reservierung von Speicher mitbetrachten!
+        Zusammen mit einer Referenz sind sort_array(), filter(), map() etc.
+        dennoch oft euer Freund:
+        statt:   t=allocate(0);
+                 for (i=sizeof(a1); i--; )
+                   if (member(a2,a1[i])>=0) t+=({a1[i]});
+        lieber:  private static mixed _is_member(mixed x, a) {
+                   if (member(a,x)>=0) return 1;
+                   else return 0;
+                 }
+                 ...
+                 t=filter(a1, #'_is_member, &a2);
+        oder hier noch besser:
+                   t=a1&a2;
+      - x&y ist bei zwei grossen Arrays manchmal die schlechtere Wahl:
+        statt:   t=all_inventory(TO)&users();       // zwei Arrays
+        lieber:  t=filter(all_inventory(TO),        // ein Array!
+                          #'query_once_interactive);
+        Eventuell lohnt es sich hier, gleich mit first_inventory() und
+        next_inventory() ueber den Raum zu iterieren und auf allen
+        query_once_interactive() die gewuenschten Operationen vorzunehmen.
+      - foreach() ist oft gegenueber for() die bessere Alternative (etwas
+        schneller, einfacher formuliert)
+      - weitere schnelle efuns:
+        query_verb(), interactive(), query_once_interactive(), living(),
+        stringp(), intp(), closurep(), objectp(), ...
+
+ SIEHE AUCH:
+     memory, objekte, mudrechner, goodstyle, ticks
+
+ 6. Sep 2012 Gloinson
diff --git a/doc/concepts/erq b/doc/concepts/erq
new file mode 100644
index 0000000..378d59d
--- /dev/null
+++ b/doc/concepts/erq
@@ -0,0 +1,578 @@
+CONCEPT
+        erq - External Request Demon
+
+DESCRIPTION
+        Up to version 3.2.1@61, LPMud utilized two external programs
+        in an ad-hoc manner to solve problems: the 'hname' program to
+        resolve IP addresses into meaningful hostnames, and the
+        'indent' program to properly indent LPC files.
+        In version 3.2.1@61 both functions were united in a
+        generalized 'erq' process, to which additional functions may
+        be attached. Unfortunately it was never documented by Amylaar,
+        so the information presented here had to be reverse engineered
+        from the sources - better take it with a grain of salt.
+
+        The erq feature is available if the driver is compiled with
+        ERQ_DEMON defined (in config.h).
+
+        When the driver starts up, it tries to fork off the program
+        'BINDIR/erq --forked <other args>' (with BINDIR defined in
+        the Makefile). If this succeeds, the erq may talk with
+        the driver through stdin and stdout (piped through AF_UNIX
+        sockets). The erq has to signal its successfull start by
+        writing the character '1' back to the driver.
+
+        The erq has to understand these commandline arguments:
+
+          --forked: explained above
+          --execdir <dir>: The directory where the callable executables
+                    can be found. If not specified, ERQ_DIR is used.
+                    <dir> must not end in a '/' and should be absolute.
+
+        At runtime, the erq may be changed/removed from within the
+        mudlib using the efun attach_erq_demon(). This efun is given
+        an interactive object as argument, and takes the connection
+        away(!) from this object and stores it as the erq connection
+        to use (an old erq connection is closed first). The object
+        (which now no longer is interactive) is then no longer needed,
+        but may continue to exist.
+        The erq attached this way of course has to use the sockets it
+        opened to communicate with the driver.
+
+        Most of the communication between erq and driver is going to
+        be initiated by the driver (the erq has to look up the
+        hostnames for given IP addresses), but using the efun
+        send_erq() the mudlib may talk with the erq as well.
+
+        The communication between driver and erq is done using
+        messages of specified structures and constants (defined in
+        util/erq.h resp. sys/erq.h). The 'int32's are signed integers
+        of four byte length, and are sent with the MSByte first.
+        Every message must be sent atomically!
+
+        The head of the messages is always the same:
+
+          struct erq_msghead {
+            int32  msglen;  /* Total size of message in bytes */
+            int32  handle;  /* Identification number */
+          }
+
+        The 'handle' number is set by the driver (do not make
+        assumptions about its value) and is used to associated the erq
+        responses with the pending requests. This way the erq is free
+        to respond in an order different to those of the incoming
+        requests.
+
+        The messages send to the erq follow this symbolic format:
+
+          struct to_erq_msg {
+            int32  msglen;
+            int32  handle;
+            char   request;
+            char   data[0];
+          }
+
+        The 'request' denotes which service is requested from the erq,
+        the size and content of 'data' depends on the requested
+        service.
+
+        The answer message from the erq to the driver (if there is one
+        at all) may have two forms:
+
+          struct from_erq_msg {
+            int32  msglen;
+            int32  handle;
+            char   data[0];
+          }
+
+          struct from_erq_keep_msg {
+            int32        msglen;
+            const int32  keep = ERQ_KEEP_HANDLE;
+            int32        handle;
+            char         data[0];
+          }
+
+        The replied data from the erq is stored in 'data', which size
+        and content depends on the request answered. The answer is
+        identified by 'header.handle'. Normally, one request results
+        in just one response sent by the erq using struct from_erq_msg,
+        so the handle is recycled after this response.
+        Shall the erq send several responses (or break one response
+        into several parts), the struct from_erq_keep_msg has to be
+        used for all but the last response - this message with its
+        included special handle keeps the real handle alive.
+
+
+        Mudlib generated erq-calls specify the 'request' and the
+        'data' to be sent, and receive the 'data' replied. When
+        dealing with spawned programs, the first byte of the returned
+        'data' determines the content type of the received message.
+        The actual 'data' which the lpc programs get to see is sent
+        and retrieved as arrays of byte integers (integers in the
+        range of 0..255).
+
+
+        The actual interface between erq demon and driver is limited
+        to the general message formats and the hostname lookup
+        mechanism. The driver is meant to withstand erq demon failures
+        at least in a garbage-in garbage-out fashion. You could add
+        new requests to the erq demon, or write your own from scratch,
+        without changing the driver.
+
+
+        Currently five services are predefined in the supplied
+        erq-demon (util/erq.c in the driver source archive): looking
+        up a hostname, execution, forking or spawning an external
+        program, authentification of a connection, and handling of
+        external UDP/TCP connections. As mentioned above, only the
+        hostname-lookup is a true must.
+
+        For a program to be executable for erq, it must be placed in
+        or below ERQ_DIR (defined in config.h). On most unix systems,
+        it is possible to use a symlink instead of the whole program
+        if you want a standard binary. You could even symlink entire
+        directories like /usr/sbin, but chances are you make a big
+        security hole this way :-)
+
+
+        Hostname lookup:
+
+          request  : ERQ_RLOOKUP
+          data sent: struct in_addr.s_addr addr // the address to resolve
+          data recv: struct in_addr.s_addr addr // the resolved address
+                     char[]                name // the hostname (if any)
+
+          If the sent address can't be resolved, just the address is
+          to be returned. The string need not be 0-terminated.
+
+
+        Hostname lookup:
+
+          request  : ERQ_LOOKUP
+          data sent: char[]                name // the name to resolve
+          data recv: struct in_addr.s_addr addr // the resolved address
+
+          If the sent address can't be resolved, no data is returned (the
+          driver will get a message with just the header).
+
+
+        Hostname lookup - IPv6:
+
+          request  : ERQ_RLOOKUPV6
+          data sent: char[] addr  // the address to resolve
+          data recv: char[] data  // the resolved name
+
+          If the address could be resolved, the returned data is a string,
+          with exactly one space, in the form "<addr> <name>". <addr> is
+          the address passed to the erq, <name> is the hostname of the
+          address or, if there is no reverse-IPv6 entry for <addr>, the
+          IPv6 address which may or may not be different from <addr>.
+
+          If the address can not be resolved, the returned data is
+          an error message without a space (currently, just "invalid-format"
+          and "out-of-memory" are returned).
+
+
+        Execute/Fork program:
+
+          request  : ERQ_EXECUTE/ERQ_FORK
+          data sent: char[] command  // the command to execute
+          data recv: char   status = CHILD_FREE
+                     char   rc       // the success/error code
+                     char   info     // additional information
+
+          The erq executes the sent command using the execv().
+          The erq does the processing of the command line arguments
+          (which must not contain '\') and checks the validity of the
+          command (it must not start with '/' nor contain '..'), which
+          is interpreted relative to ERQ_DIR.
+          The external program is executed from a fork()ed instance of
+          the erq, however, with ERQ_EXECUTE the erq waits until the
+          external program finished before replying its response, with
+          ERQ_FORK the response is immediately sent back.
+
+          Possible return codes are:
+            ERQ_OK         : Operation succeeded.
+            ERQ_E_ARGLENGTH: Too long command.
+            ERQ_E_ARGFORMAT: Illegal argument given (contains '\');
+            ERQ_E_ARGNUMBER: Too much arguments (>= 96).
+            ERQ_E_ILLEGAL  : Command from outside ERQ_DIR requested.
+            ERQ_E_PATHLEN  : Commandpath too long.
+            ERQ_E_FORKFAIL : Command could not be forked;
+                             info holds the errno value.
+
+          ERQ_EXECUTE features some more return codes:
+            ERQ_OK         : Operation succeeded, <info> holds the exit status.
+            ERQ_SIGNALED   : Command terminated the signal <info>.
+            ERQ_E_NOTFOUND : No process found to wait() for.
+            ERQ_E_UNKNOWN  : Unknown exit condition from wait().
+
+
+        Spawn program:
+
+          request  : ERQ_SPAWN
+          data sent: char[] command  // the command to execute
+          data recv: Spawn failed:
+                     char   rc       // the error code (see ERQ_FORK)
+                     char   info     // additional information
+          data recv: Spawn succeeded:
+                     char   rc = ERQ_OK
+                     char[] ticket        // the spawn ticket.
+
+          The erq executes the sent command as if given an ERQ_FORK
+          command, but returns additional information about the
+          started process to allow further communication.
+          In contrast to ERQ_FORK, ERQ_SPAWNED processes may be
+          controlled via ERQ_KILL, receive data from the mud via
+          ERQ_SEND on their stdin, and output from their stdout/stderr
+          is sent back to the mud.
+          The spawned process is identified by its <ticket> (don't
+          make any assumptions about its length or content), the transaction
+          itself by <handle>.
+
+
+        Send data to spawned program:
+
+          request  : ERQ_SEND
+          data sent: char[]  ticket // the addressed process ticket.
+                     char[]  text   // the text to send.
+          data recv: char    rc     // the success/error code.
+                     int32   info   // opt: additional info.
+
+          The <text> is sent to the stdin of the spawned process
+          identified by <ticket>.
+
+          Possible return codes are:
+            ERQ_OK          : Operation succeeded, no <info> is replied.
+            ERQ_E_TICKET    : The given ticket is invalid, no <info> replied.
+            ERQ_E_INCOMPLETE: Only <info> chars of the text have been
+                              sent.
+                              If a callback is specified, the erq will send
+                              a ERQ_OK message once all data has been sent
+                              (this may never happen).
+            ERQ_E_WOULDBLOCK: Error E_WOULDBLOCK (also stored in <info>)
+                              happened while sending the text.
+            ERQ_E_PIPE      : Error E_PIPE (also stored in <info>)
+                              happened while sending the text.
+            ERQ_E_UNKNOWN   : The error with code <info> happened
+                              while sending the data.
+
+         Amylaar-erq doesn't try to re-send the remaining data after
+         a ERQ_E_INCOMPLETE, so there will never be an ERQ_OK.
+
+
+        Send a signal to a spawned program:
+
+          request  : ERQ_KILL
+          data sent: char[]  ticket // the addressed process ticket
+                     int32   signal // the signal to send
+          data recv: char    rc     // the success/error code
+
+          The <signal> is sent to the spawned process identified by <ticket>.
+
+          Possible return codes are:
+            ERQ_OK          : Operation succeeded, no <info> is replied.
+            ERQ_E_TICKET    : The given ticket is invalid, no <info> replied.
+            ERQ_E_ILLEGAL   : The given signal is illegal.
+
+
+        Data replies from spawned programs:
+
+          data recv: char   out_or_err  // type of text output
+                     char[] text        // text output by child process
+
+          The child process controlled by the erq did output <text>
+          on stdout (<out_or_err> == ERQ_STDOUT) resp. on stderr
+          (<out_or_err> == ERQ_STDERR).
+
+
+        Exit notifications from spawned programs:
+
+          data recv: char   rc          // the exit code
+                     char   info        // additional information.
+
+          The child process controlled by the erq did terminate.
+          Possible exit codes are:
+            ERQ_EXITED    : Process exited with status <info>.
+            ERQ_SIGNALED  : Process terminated by signal <info>.
+            ERQ_E_UNKNOWN : Process terminated for unknown reason.
+
+
+        Authentificate connection (see rfc 931):
+
+          request  : ERQ_AUTH
+          data sent: struct sockaddr_in remote // the address to check
+                     int32              port   // the mud port
+             or
+          data sent: int32  remote_ip    // remote ip to check
+                     int16  remote_port  // remote port to check
+                     int16  local_port   // the mud port
+
+          data recv: char[]             reply  // the data received by authd
+
+          The erq attempts to connect the authd on the remote system
+          and to verify the connection between the remote port and the
+          mud port. The latter will normally be the port number of the
+          socket on besides of the gamedriver, retrieveable by
+          query_ip_number().
+
+          The answer from the authd (one line of text) if there is any
+          is returned as result.
+
+          The second form of the ERQ_AUTH command is recognized by
+          the xerq as alternative.
+
+
+        Open an UPD port:
+
+          request  : ERQ_OPEN_UDP
+          data sent: char[2] port   // the port number to open (network order)
+          data recv: Open failed:
+                     char    rc     // the success/error code.
+                     char    info   // opt: additional info.
+          data recv: Open succeeded:
+                     char   rc = ERQ_OK
+                     char[] ticket  // the connection ticket.
+
+          The erq opens an UDP-port on the host machine with the given
+          port number.
+          Possible exit codes are:
+            ERQ_OK          : Operation succeeded.
+            ERQ_E_ARGLENGTH : The port number given does not consist
+                              of two bytes.
+            ERQ_E_NSLOTS    : The max number of child processes (given
+                              in <info>) is exhausted.
+            ERQ_E_UNKNOWN   : Error <info> occured in one of the system
+                              calls done to open the port.
+
+          Once the port is open, it is treated as if is just another
+          spawned program.
+
+
+        Send data over an UDP port:
+
+          request  : ERQ_SEND
+          data sent: char[]                ticket // the addressed port's ticket.
+                     struct in_addr.s_addr addr   // address of receiver.
+                     struct addr.sin_port  port   // port of receiver.
+                     char[]                text   // the text to send.
+          data recv: char   rc     // the success/error code.
+                     int32  info   // opt: additional info.
+
+          The <text> is sent from our port <ticket> to the network
+          address <addr>, port <port>.
+
+          Possible return codes are:
+            ERQ_OK          : Operation succeeded, no <info> is replied.
+            ERQ_E_TICKET    : The given ticket is invalid, no <info> replied.
+            ERQ_E_INCOMPLETE: Only <info> chars of the text have been
+                              sent. The erq will send a ERQ_OK message
+                              once all data has been sent.
+            ERQ_E_WOULDBLOCK: Error E_WOULDBLOCK (also stored in <info>)
+                              happened while sending the text.
+            ERQ_E_PIPE      : Error E_PIPE (also stored in <info>)
+                              happened while sending the text.
+            ERQ_E_UNKNOWN   : The error with code <info> happened
+                              while sending the data.
+
+
+        Close an UDP port:
+
+          request  : ERQ_KILL
+          data sent: char[]  ticket // the addressed port's ticket
+                     int32   signal // the signal to send (ignored)
+          data recv: char    rc = ERQ_OK
+
+          The port <ticket> is closed. The <signal> must be sent, but
+          its value is ignored.
+
+
+        Data received over an UDP connection:
+
+          data recv: char                  out_or_err = ERQ_STDOUT
+                     struct in_addr.s_addr addr    // ip-address of sender
+                     struct addr.sin_port  port    // port of sender
+                     char[]                text    // data received
+
+          The UPD port controlled by the erq did receive <text> over
+          the network from the sender at <addr>, reply port number <port>.
+
+
+        Open an TCP to listen for connections:
+
+          request  : ERQ_LISTEN
+          data sent: struct addr.sin_port port   // the port number to open
+          data recv: Open failed:
+                     char    rc     // the success/error code.
+                     char    info   // opt: additional info.
+          data recv: Open succeeded:
+                     char   rc = ERQ_OK
+                     char[] ticket  // the connection ticket.
+
+          The erq opens an TCP-port on the host machine with the given
+          port number to listen for connections.
+          Possible exit codes are:
+            ERQ_OK          : Operation succeeded.
+            ERQ_E_ARGLENGTH : The port number given does not consist
+                              of two bytes.
+            ERQ_E_NSLOTS    : The max number of child processes (given
+                              in <info>) is exhausted.
+            ERQ_E_UNKNOWN   : Error <info> occured in one of the system
+                              calls done to open the port.
+
+          Once the port is open, it is treated as if is just another
+          spawned program.
+
+
+        Open an TCP port:
+
+          request  : ERQ_OPEN_TCP
+          data sent: struct in_addr.s_addr ip   // the ip to address
+                     struct addr.sin_port  port // the port to address
+          data recv: Open failed:
+                     char    rc     // the success/error code.
+                     char    info   // opt: additional info.
+          data recv: Open succeeded:
+                     char   rc = ERQ_OK
+                     char[] ticket  // the connection ticket.
+
+          The erq opens an TCP-port on the host machine and tries to connect
+          it to the address <ip>:<port>.
+          Possible exit codes are:
+            ERQ_OK          : Operation succeeded.
+            ERQ_E_ARGLENGTH : The port number given does not consist
+                              of two bytes.
+            ERQ_E_NSLOTS    : The max number of child processes (given
+                              in <info>) is exhausted.
+            ERQ_E_UNKNOWN   : Error <info> occured in one of the system
+                              calls done to open the port.
+
+          Once the port is open, it is treated as if is just another
+          spawned program.
+
+
+        Send data over a TCP connection:
+
+          request  : ERQ_SEND
+          data sent: char[]  ticket // the addressed process ticket.
+                     char[]  text   // the text to send.
+          data recv: char    rc     // the success/error code.
+                     int32   info   // opt: additional info.
+
+          The <text> is sent to the stdin of the spawned process
+          identified by <ticket>.
+
+          Possible return codes are:
+            ERQ_OK          : Operation succeeded, no <info> is replied.
+            ERQ_E_TICKET    : The given ticket is invalid, no <info> replied.
+            ERQ_E_INCOMPLETE: Only <info> chars of the text have been
+                              sent. The erq will send a ERQ_OK message
+                              once all data has been sent.
+            ERQ_E_WOULDBLOCK: Error E_WOULDBLOCK (also stored in <info>)
+                              happened while sending the text.
+            ERQ_E_PIPE      : Error E_PIPE (also stored in <info>)
+                              happened while sending the text.
+            ERQ_E_UNKNOWN   : The error with code <info> happened
+                              while sending the data.
+
+
+        Data ready to read on TCP connection:
+
+          data recv: char    out_or_err = ERQ_OK
+                     char[]  ticket  // ticket of this connection
+
+          There is data available to read on the specified TCP connection.
+
+
+        Data received over a TCP connection:
+
+          data recv: char    out_or_err = ERQ_STDOUT
+                     char[]  text    // data received
+
+          The TCP port controlled by the erq did receive <text>.
+
+
+        TCP connection closes on error:
+
+          data recv: char    out_or_err = ERQ_E_UNKNOWN
+                     char    errno   // errno from socket operation
+
+          The TCP connection caused an error <errno> and has been closed.
+
+
+        TCP connection closed:
+
+          data recv: char    out_or_err = ERQ_EXITED
+
+          The TCP connection closed regularily (End Of File).
+
+
+        Connection pending on TCP socket:
+
+          data recv: char    out_or_err = ERQ_STDOUT
+
+          The TCP 'listen' port controlled by the erq received
+          a connection request.
+
+
+        Accept a pending connections:
+
+          request  : ERQ_ACCEPT
+          data sent: char[]  ticket // the ticket of this socket
+          data recv: Accept failed:
+                     char    rc     // the success/error code.
+                     char    info   // opt: additional info.
+          data recv: Accept succeeded:
+                     char    rc = ERQ_OK
+                     struct in_addr.s_addr ip    // remote side's ip
+                     struct addr.sin_port  port  // remote side's port
+                     char[]                ticket  // the new ticket.
+
+          The erq accepts a new connection on an accept-TCP-port, creates
+          an child and ticket for it and returns its ticket together with
+          the remote's side <ip>:<port> number (in network byte order).
+          Possible exit codes are:
+            ERQ_OK          : Operation succeeded.
+            ERQ_E_ARGLENGTH : The port number given does not consist
+                              of two bytes.
+            ERQ_E_NSLOTS    : The max number of child processes (given
+                              in <info>) is exhausted.
+            ERQ_E_TICKET    : the ticket didn't match
+            ERQ_E_UNKNOWN   : Error <info> occured in one of the system
+                              calls done to open the port.
+
+          Once the port is open, it is treated as if is just another
+          spawned program.
+
+
+EXAMPLE
+        Assume you have a script 'welcome-mail' to send a welcome mail
+        to a new player. Put this script into the directory for the callable
+        executables, then you can use it like this:
+
+        void erq_response(mixed * data)
+        {
+            write_file( "WELCOMELOG"
+                      , sprintf("rc %d, info %d\n", data[0], data[1]));
+        }
+
+        void send_mail(string player_name, string player_email)
+        {
+            send_erq( ERQ_EXECUTE
+                    , "welcome-mail '"+player_name+"' '"+player_email+"'"
+                    , #'erq_response);
+        }
+
+
+HISTORY
+        The erq was introduced with 3.2.1@61.
+        ERQ_AUTH was introduced with 3.2.1@81.
+        ERQ_SEND, ERQ_SPAWN, ERQ_KILL were introduced with 3.2.1@82.
+        ERQ_OPEN_UDP, ERQ_OPEN_TCP, ERQ_LIST were introduced with 3.2.1@98.
+        ERQ_RLOOKUPV6 was introduced in 3.2.8.
+        LDMud 3.2.9 added the '--execdir' argument to erq, and the ERQ_OK
+          after ERQ_E_INCOMPLETE protocol.
+
+SEE ALSO
+        attach_erq_demon(E), send_erq(E), stale_erq(M), rfc 931
+        query_ip_number(E)
diff --git a/doc/concepts/files b/doc/concepts/files
new file mode 100644
index 0000000..56e6e64
--- /dev/null
+++ b/doc/concepts/files
@@ -0,0 +1,16 @@
+CONCEPT
+        files
+
+DESCRIPTION
+        As a wizard, you are working with files. Each file represents
+        the bulding plan for one or more objects (except text or doc files
+        of course).
+
+        The mudlib has a root, and when working with filenames, you
+        can always specify a full pathname from the root by starting
+        with a '/' (slash) at the beginning of the file name.
+
+        (oops, truncated - why when where did it happen?)
+
+SEE ALSO
+        objects(C), create(A), reset(A)
diff --git a/doc/concepts/goodstyle b/doc/concepts/goodstyle
new file mode 100644
index 0000000..15ea04b
--- /dev/null
+++ b/doc/concepts/goodstyle
@@ -0,0 +1,74 @@
+Guter Stil
+ BESCHREIBUNG:
+     Guten Stil kann man lernen. Zumindest in der Programmierung. Guter Stil
+     bedeutet vor allem: Schreib es so, das andere es lesen und verstehen
+     koennen. (Ansonsten werde /secure/-Erzmagier, die muessen aufgrund
+     eingebauter Paranoia selbstverschluesselnd schreiben.)
+
+     Lernen kann man auch am Beispiel, unter /d/gebirge/room/,
+     /d/gebirge/obj/, /d/gebirge/mon/, /doc/beispiele/ ist sauberer Code
+     zu finden.
+
+     Tipps zum Aussehen:
+     - Programmzeilen nicht laenger als 80 Zeichen schreiben, denn 80 Zeichen
+       breite Fenster sind immer noch die Regel
+       - Code kann auf der naechsten Zeile weiterfuehren:
+         filter(all_inventory(environment(TP)),
+		      #'einetollesortierfunktion, &extravariablen);
+       - Strings koennen (ohne Addition mit +) unterbrochen werden:
+         "Jemand "<EOL>    "jammert" == "Jemand jammert"
+         "Jemand \<EOL>jammert"      == "Jemand jammert"
+
+     - Bloecke (mit {} umrandeter Code) einruecken, damit man den
+       geplanten Programmfluss gut erkennen kann
+       - 2 bis 4 Zeichen, nicht gleich ein ganzes Tab (siehe erste Regel)
+       - die { und } ruhig in einzelen Zeilen schreiben
+
+     - Variablen in dem Block deklarieren, in dem sie gebraucht werden,
+       dadurch sind sie schneller zu finden
+
+     - #define nicht uebertreiben, wenn komplexe Funktionen damit gebaut
+       sind, uebersieht der Leser den Code oft nicht mehr
+       - #define sollten in #includeten Headerdateien stehen
+       - wenn es eine oft benutzte Funktion ist, schreib sie als Lfun
+       - ist es vielleicht schon in /sys/*.h oder /secure/*.h definiert?
+
+     Tipps zum Code:
+     - objektorientiert programmieren
+       - das was andere nicht von aussen sehen oder aufrufen muessen, mit
+         "protected" oder "private" bei Vererbung verstecken
+
+     - return mitten im Code wenn moeglich vermeiden, da der Programmfluss
+       damit aufgesplittert wird - ein einziger Funktionsausgang ist
+       uebersichtlicher
+       - Ausnahme hiervon kann aber sein, (die meisten) Ausschlussbedingungen
+         fuer irgendwas am Anfang einer Funktion abzupruefen und die Funktion
+         dann auch sofort zu verlassen.
+      
+     - korrekte Typen bei Variablen und Typen verwenden, damit der Leser
+       erkennt welches Ding was ist
+       - #pragma strong_types oder gar #pragma strict_types hilft
+       - Auch Typpruefungen zur Laufzeit (#pragma rtt_checks) verwenden
+       - bei Objekten, die geerbt werden, immer auch  #pragma save_types
+
+     Tipps zu Dateien:
+     - unterteilt eure Gegenden am besten in verschiedene Verzeichnisse,
+       dann findet man sich schnell zurecht:
+       - NPCs, Objekte, Raeume, Master (ggf. Waffen, Ruestungen wenn zu viel)
+
+     - Pfade sollten in einer zentralen #include Datei stehen, welche dann
+       relativ #included werden kann. Damit erleichtert man spaeteren Magiern
+       eventuell noetige Verzeichnisaenderungen.
+       statt:	AddItem("/d/ebene/<magier>/sumpf/npc/schleimi", ...);
+       lieber:
+         #include "../local.h"
+           [enthaelt ein
+            #define SUMPFNPC(x) ("/d/ebene/<magier>/sumpf/npc/" x)]
+		     ...
+		     AddItem(SUMPFNPC("schleimi"), ...);
+
+ SIEHE AUCH:
+     inheritance, effizienz, pragma, oop
+
+05.06.2014, Zesstra
+
diff --git a/doc/concepts/hooks b/doc/concepts/hooks
new file mode 100644
index 0000000..108da08
--- /dev/null
+++ b/doc/concepts/hooks
@@ -0,0 +1,144 @@
+CONCEPT
+        driver hooks
+
+DESCRIPTION
+        To allow a greater flexibility of the muds, the gamedrivers
+        since 3.2.1 moved several once hardcoded 'underground'
+        activities from the driver into the mudlib. This includes for
+        example the differences between compat and native mode.
+
+        The hooks are set with the privileged efun set_driver_hook().
+        Some of the hooks are mandatory, some not. Most hooks accept
+        unbound lambda closures as values, some also lfun closures or
+        even strings.
+        The hooks are identified by an ordinal number, for which
+        symbolic names are defined in /sys/driverhooks.h.
+
+        H_MOVE_OBJECT0
+        H_MOVE_OBJECT1
+          Mandatory hooks to implement the efun void move_object().
+
+
+        H_LOAD_UIDS
+        H_CLONE_UIDS
+          Mandatory hooks to determine the uid and euid of loaded or cloned
+          objects.
+
+
+        H_CREATE_SUPER
+        H_CREATE_OB
+        H_CREATE_CLONE
+          Optional hooks to initialize an object after creation.
+
+          H_CREATE_SUPER is called for blueprints implicitely loaded
+          by inheritance, H_CREATE_OB for explicitely loaded
+          blueprints/objects, and H_CREATE_CLONE for cloned objects.
+
+
+        H_RESET
+          Optional hook to reset an object.
+
+
+        H_CLEAN_UP
+          Optional hook to clean up an object.
+
+
+        H_DEFAULT_METHOD
+          Optional hook to provide default implementation for unresolved
+          calls.
+
+
+        H_DEFAULT_PROMPT
+          Optional hook for the command prompt. If this hook is not used,
+          the driver will use "> " as the command prompt.
+
+
+        H_PRINT_PROMPT
+          Optional hook to print the current command prompt. If this hook is
+          not set, the driver will just print the prompt to the user.
+
+
+        H_COMMAND
+          Optional hook to parse and execute commands. If this hook is used,
+          it bypasses the normal command parsing done by the driver (including
+          the MODIFY_COMMAND and NOTIFY_FAIL hooks).
+
+
+        H_MODIFY_COMMAND
+          Optional hook to modify commands (both entered or given by a
+          call to command()) before the parser sees them (this includes
+          special commands like 'status').
+
+
+        H_MODIFY_COMMAND_FNAME
+          Mandatory hook specifying the name of the 'modify_command'
+          lfun to call for newly entered commands as result of a
+          set_modify_command().
+
+
+        H_NOTIFY_FAIL
+          Mandatory hook to issue the default message if an entered
+          command couldn't be parsed and no notify_fail() command is
+          in effect.
+
+
+        H_SEND_NOTIFY_FAIL
+          Optional hook to send the notify fail message, regardless
+          of how it was determined, to the player. If the hook is not
+          set, the message is delivered using tell_object() internally.
+
+
+        H_NO_IPC_SLOT
+          Optional hook specifying the message given to logins
+          rejected due to space limitations (MAX_PLAYER).
+
+
+        H_INCLUDE_DIRS
+          Semi-mandatory hook specifying the directories where <>-type
+          include files are searched (this includes ""-includes not
+          found as specified).
+
+
+        H_AUTO_INCLUDE
+          Optional hook specifying a string to be included before
+          the source of every compiled LPC object.
+
+
+        H_TELNET_NEG
+          Optional hook to specifiy how to perform a single telnet
+          negotiation.  If not set, most telnet options are rejected (read:
+          only a very minimal negotiation takes place).
+
+
+        H_NOECHO
+          Optional hook to specifiy how to perform the telnet actions
+          to switch the echo mode (used for e.g. password input_to()s).
+          If not set, a default handling is performed.
+
+          IMPORTANT: If this hook is used, the control of all telnet
+          negotiation is transferred to the mudlib (you must combine it
+          with H_TELNET_NEG to conform to the telnet protocol).
+
+
+        H_ERQ_STOP
+          Optional hook to notify the mudlib about the termination of
+          the erq demon.
+
+
+HISTORY
+        The hooks concept was introduced in 3.2.1
+        H_MOVE_OBJECT0/1 were introduced in 3.2.1@1
+        H_CLEAN_UP was introduced in 3.2.1@34
+        H_MODIFY_COMMAND was introduced in 3.2.1@51.
+        H_MODIFY_COMMAND_FNAME was 'hooked' in 3.2.1@109.
+        H_NOTIFY_FAILE and H_NO_IPC_SLOT were introduced in 3.2.1@55.
+        H_INCLUDE_DIRS was introduced in 3.2.1@57.
+        H_TELNET_NEG was introduced in 3.2.1@60.
+        H_NOECHO and H_ERQ_STOP were introduced in 3.2.1@85.
+        H_COMMAND was introduced in 3.2.7.
+        H_SEND_NOTIFY_FAIL and H_AUTO_INCLUDE were introduced in 3.2.9.
+        H_DEFAULT_METHOD was introduced in 3.3.113.
+        H_DEFAULT_PROMPT and H_PRINT_PROMPT were introduced in 3.3.163.
+
+SEE ALSO
+        native(C), set_driver_hook(E), all in (H)
diff --git a/doc/concepts/hsregexp b/doc/concepts/hsregexp
new file mode 100644
index 0000000..04266be
--- /dev/null
+++ b/doc/concepts/hsregexp
@@ -0,0 +1,99 @@
+SYNOPSIS
+        Henry Spencer Regular Expressions
+
+
+DESCRIPTION
+        This document describes the regular expressions supported by the
+        implementation by Henry Spencer (the traditional package for
+        LPMud).
+
+
+OPTIONS
+        The following bitflag options modify the behaviour of the
+        regular expressions - both interpretation and actual matching.
+
+        The efuns may understand additional options.
+
+          RE_EXCOMPATIBLE
+
+        If this bit is set, the pattern is interpreted as the UNIX ed
+        editor would do it: () match literally, and the \( \) group
+        expressions.
+
+
+REGULAR EXPRESSION DETAILS
+        A regular expression is a pattern that is matched against  a
+        subject string from left to right. Most characters stand for
+        themselves in a pattern, and match the corresponding charac-
+        ters in the subject. As a trivial example, the pattern
+
+          The quick brown fox
+
+        matches a portion of a subject string that is  identical  to
+        itself.  The  power  of  regular  expressions comes from the
+        ability to include alternatives and repetitions in the  pat-
+        tern.  These  are encoded in the pattern by the use of meta-
+        characters, which do not stand for  themselves  but  instead
+        are interpreted in some special way.
+
+        There are two different sets of meta-characters: those  that
+        are  recognized anywhere in the pattern except within square
+        brackets, and those that are recognized in square  brackets.
+        Outside square brackets, the meta-characters are as follows:
+
+          .       Match any character.
+
+          ^       Match begin of line.
+
+          $       Match end of line.
+
+          \<      Match begin of word.
+
+          \>      Match end of word.
+
+          \B      not at edge of a word (supposed to be like the emacs
+                  compatibility one in gnu egrep)
+
+          x|y     Match regexp x or regexp y.
+
+          ()      Match enclosed regexp like a 'simple' one (unless
+                  RE_EXCOMPATIBLE is set).
+
+          x*      Match any number (0 or more) of regexp x.
+
+          x+      Match any number (1 or more) of regexp x.
+
+          [..]    Match one of the characters enclosed.
+
+          [^ ..]  Match none of the characters enclosed. The .. are to
+                  replaced by single characters or character ranges:
+
+          [abc]   matches a, b or c.
+
+          [ab0-9] matches a, b or any digit.
+
+          [^a-z]  does not match any lowercase character.
+
+          \c      match character c even if it's one of the special
+                  characters.
+
+
+NOTES
+        The \< and \> metacharacters from Henry Spencers package
+        are not available in PCRE, but can be emulate with \b,
+        as required, also in conjunction with \W or \w.
+
+        In LDMud, backtracks are limited by the EVAL_COST runtime
+        limit, to avoid freezing the driver with a match
+        like regexp(({"=XX==================="}), "X(.+)+X").
+
+
+AUTHOR
+        Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
+        Henry Spencer, University of Torronto (henry@utzoo.edu)
+        Joern Rennecke
+        Ian Phillipps
+
+
+SEE ALSO
+        regexp(C), pcre(C)
diff --git a/doc/concepts/imp b/doc/concepts/imp
new file mode 100644
index 0000000..27d9ab9
--- /dev/null
+++ b/doc/concepts/imp
@@ -0,0 +1,63 @@
+CONCEPT
+        imp
+
+LAST UPDATED
+        Deepthought, 10-Nov-92
+        Pepel,             18-Nov-93
+
+DESRIPTION
+        This document describes IMP, the intermud message protocol,
+        also known as Intermud-1.
+
+        Imp messages are exchanged between muds using UDP
+        (unreliable datagram protocol) packets. Each mud provides
+        a connection endpoint which is given by the ip host address
+        and the UDP port number. Muds may then send messages to
+        this port by using the efun send_udp(). The applied function
+        receive_udp will be called by the driver in the master
+        object if a imp message arrives at the mud's UDP port.
+
+        Imp message packets have the following format:
+
+        password@objectname@functionname[[@argument]...]
+
+        <password> is the connection password to verify incoming
+        imp packets. It is encoded using crypt(E) and compared to
+        the stored password. Each mud participating in the imp
+        network has a secret password which is encoded by the
+        admin and distributed to remote muds with which the mud
+        should have direct connection. Encryted passwords may also
+        propagated to other muds over already secure channels.
+
+        <objectname> is a logical name which is not to be confused
+        with mudlib object filenames. It is used by receive_msg in
+        the master object to route the message to another object by
+        associating the logical object name with a real mudlib file
+        name. A good idea would be to reserve a special directory
+        for imp objects, e.g. /secure/net/<objectname>.
+
+        <functionname> is the function which is called by the master
+        object in the object described by <objectname>.
+
+        <argument> are additional arguments which are handed to the
+        function <functionname>. The exact definition of functions
+        and arguments are left to the imp applications.
+
+AUTHOR
+        originally Deepthought
+
+NOTE
+        The above is only particularly correct nowadays. Recently a
+        package name ``inetd'' was published, that is based on the IMP
+        mechanism in the driver (send_udp() and receive_udp()), but
+        it uses a different message format. That package seems to
+        enjoy much publicity and is installed in a number of muds. For
+        details look into the inetd description.
+
+        An other method of inter mud connection is the Mudlink
+        package, which uses a normal user connection that is connected
+        to a special user object, and an auxiliary process that does
+        the connection to other muds.
+
+SEE ALSO
+        send_udp(E), receive_udp(M), intermud(C)
diff --git a/doc/concepts/inheritance b/doc/concepts/inheritance
new file mode 100644
index 0000000..46bf338
--- /dev/null
+++ b/doc/concepts/inheritance
@@ -0,0 +1,177 @@
+CONCEPT
+        Inheritance
+
+DESCRIPTION
+        Have you noticed how many objects in the system have the same
+        functionality in common? Let's look at rooms for instance, they
+        all have the ability to host people and provide commands. It's
+        not that every room is programmed with the same basic functions
+        again and again, rather it will use a model room and then make
+        some special changes to it. That doesn't work by copying the
+        file.. Ouch! Don't replicate code! But by putting a tiny inherit
+        declaration
+        
+                inherit "<model-class>";
+                
+        at the beginning of your new file. This must come before any local
+        ariables or functions. Once inherited your class will behave just
+        like the model class, because all the public methods are available
+        to the outside world. Now it is in your hands to change such an
+        inherited behaviour. You have the following tools to do so:
+
+        * Access to variables
+
+        It is one of the best design decisions in LPC that variables
+        are not accessible from outside, but you can use inherited
+        variables just as if they were your own. Modifiers apply however.
+
+        * Method overloading
+
+                int method_that_also_exists_in_the_model() {
+                        <your new code>
+                }
+
+        You can simply rewrite a method that is also defined in the model
+        class, and thus change how it behaves. Contrary to other languages
+        in LPC method overloading only matches the name of the method, so
+        even by changing the amount and type of parameters you will mask
+        out the original version of the method. You can even apply other
+        modifiers to it as the original.
+
+        * Calling inherited methods
+
+                int method_that_also_exists_in_the_model() {
+                        <your new code>
+                        return ::method_that_also_exists_in_the_model();
+                }
+
+        You can add to the behaviour of a method by redefining it,
+        then calling it from within your new version. You can actually
+        call inherited methods from anywhere in your code. The double
+        colon tells the compiler you are looking for the inherited
+        variant.
+
+EXAMPLE
+
+        Let's imagine very simple food in a file called "/the/food.c":
+
+                // unless "modified" variables are accessible by inheritors
+                int vitamins = 10;
+
+                // please overload this function with your own description
+                public short() { return "something edible"; }
+
+                // let's do some standard action for food
+                public consume() {
+                        this_player() -> nourish(vitamins);
+                        destruct(this_object());
+                }
+
+        And now someone else decides to do some italian cooking in a
+        file called "/the/fusilli.c"
+
+                inherit "/the/food";
+
+                // we have our own variables.
+                int gone_cold = 0;
+
+                // and we simply redefine the short() function to replace it
+                public short() {
+                    // description changes depending on gone_cold
+                    return "a "+( gone_cold ? "stinking" : "steaming" )
+                            +" plate of fusilli";
+                }
+
+                // we have a new function to make food go cold
+                private deteriorate() {
+                    gone_cold = 1;
+                    write("The fusilli have gone cold.\n");
+                }
+
+                // assume this gets called at creation
+                private create() {
+                    // we can access the variable we inherited from food.c
+                    vitamins = 44;           // tomato has plenty of vitamins
+
+                    // go cold in 5 minutes
+                    call_out( #'deteriorate, 5 * 60 );
+                }
+
+                // we can overload the function even with new parameters
+                public consume(how) {
+                    // fetch the name of the person, or use "Someone"
+                    string name = this_player() -> name() || "Someone";
+
+                    if (!gone_cold) {
+                        write("You enjoy a delicious plate of fusilli.\n");
+                        say(name +" guzzles a plate of hot fusilli.\n");
+                    }
+                    else if (how == "quickly") {
+                        write("You eat the fusilli so quickly you "
+                              "hardly notice they have gone cold.\n");
+                        say(name +" wolfs down a plate of cold fusilli.\n");
+                    }
+                    else {
+                        write("You eye the plate and wonder if you "
+                              "really feel like eating cold fusilli.\n");
+                        return; // don't eat
+                    }
+
+                    // and here comes the most important part:
+                    // we execute consume() from food.c, so we
+                    // actually inherit its behaviour.
+                    ::consume();
+                }
+
+ADVANCED USAGE
+
+        * Doing multiple inheritance
+
+        While the Java(TM) language has so-called interfaces as a kludge,
+        LPC doesn't need them as it supports real multiple inheritance.
+        A very powerful feature, it lets you combine the behaviour of
+        several classes into a new one. Simply put several lines of
+        inherit declarations underneath each other. If you have name
+        collisions in the namespace of inherited methods, you will have
+        to address them explicitely with a "the/file"::method(args) syntax.
+
+        * Wildcarded multiple inheritance
+
+        LDMUD 3.2.1@117 introduces an advanced voodoo syntax which allows
+        you to call several methods in model classes at once, but for some
+        technical reasons it cannot pass any arguments. This works by
+        writing a glob type match ('*' and '?' wildcards) into the string
+        in front of the double colon, as in "*"::create(). I wouldn't
+        recommend you to use this, it's better to be clearly conscious of
+        what you inherit and do. But if you're desperate, there you go.
+
+ADVANCED EXAMPLE
+
+          inherit "foo";
+          inherit "bar";
+          inherit "baz";
+          inherit "ball";
+
+          reset() {
+                "ba?"::reset();
+                // calls bar::reset() and baz::reset()
+
+                "ba*"::reset();
+                // calls bar::reset(), baz::reset() and ball::reset()
+
+                "*"::reset();
+                // calls every inherited reset() function.
+
+                "ball"::rejoice("Listen to italectro today!");
+                // only explicit filename of model class allows
+                // passing arguments to the inherited method
+          }
+
+AUTHOR
+        symlynX of PSYC and Nemesis, with a little help from Someone
+
+SEE ALSO
+        functions(LPC), initialisation(LPC), modifiers(LPC), pragma(LPC),
+        overloading(C)
+        function_exists(efun), functionlist(efun), inherit_list(efun),
+        symbol_variable(efun), variable_exists(efun), variable_list(efun).
diff --git a/doc/concepts/intermud b/doc/concepts/intermud
new file mode 100644
index 0000000..abe2b4f
--- /dev/null
+++ b/doc/concepts/intermud
@@ -0,0 +1,224 @@
+CONCEPT
+        intermud
+
+DESCRIPTION
+        There are several intermud protocols which define how (players on)
+        different muds can communicate with each other. The protocols are
+        in general not muddriver or mudlib dependant, though the number of
+        implementations is limited.
+
+        This text is about the rather old widely spread 'Zebedee Intermud',
+        which is also called 'Intermud 2' altough it differs quite a lot
+        from the real Intermud 2 protocol.
+
+        Full information on the newer Intermud 3 could be found on the
+        web at http://www.imaginary.com/protocols/intermud3.html so there
+        is no discussion here - the following is just about Zebedee Intermud
+        (aka Intermud 2).
+
+        Zebedee Intermud communication is handled by the /secure/inetd
+        object, originally written by Nostradamus for Zebedee with some
+        extensions that are discussed in inetd(C). How the data is
+        actually sent across the network is described in intermud.basic(C).
+
+SERVICES
+        Note that the fields "NAME" and "UDP_PORT" should be present in
+        every message. Very common are the fields "ID" (used whenever an
+        reply is expected) and "SND" (the sender: he should receive the
+        reply). These fields will not be mentioned in the list below.
+
+        Request types are listed on the leftmost row (e.g. "REQ=channel"),
+        associated header are listed indented.
+
+        "channel"
+            The channel-request is used for sending a message on any
+            channel. The "CMD" field is optional and may be omitted for
+            normal messages. Note that you should not send an history or
+            list request to _all_ known muds!
+
+            "CHANNEL"
+                The channel on which a message is send (the standard
+                channels are "intermud", "intercode", "interadm", "d-chat",
+                "d-code" and "d-adm"; on the d-channels German is spoken)
+
+            "DATA"
+                The message to be send (not used with history/list request)
+
+            "CMD"
+                The body of this header may be:
+                ""        for normal intermud messages,
+                "emote"   if the message is an emote/gemote,
+                "history" for an history request: the last 20 lines of
+                          this channel will be shown.
+                "list"    to list all remote users listening to this channel
+
+            "EMOTE"     (optional)
+                The body is 1 if the message is an emote.
+                The body is 2 if the message is a gemote.
+
+        "finger"
+            Retreive information about a player or creator on a remote mud.
+
+            "DATA"
+                The player of whom information is requested
+
+        "locate"
+            Check whether a certain player is logged on at a remote mud.
+            This request is usually send to all known muds at the same time.
+
+            "user"
+                Name of the person who requests the information.
+                This is used by the sending mud only and has to be included
+                in the reply.
+
+            "vbs"
+                The verbose option has only two pre-defined values:
+                1 Even report when the result was negative
+                2 Don't do timeouts, but keep waiting
+                This is used by the sending mud only and has to be included
+                in the reply.
+
+            "fnd"
+                The found option is only used in the reply and it's value
+                is either 1 (success) or 0 (failure). The absence of a
+                found parameter indicates failure as well.
+
+            "DATA"
+                The player to find.
+
+        "man"
+            Retreive a manual page from a remote mud. Many muds don't
+            support this feature...
+
+            "DATA"
+                The name of the requested manual page
+
+        "mail"
+            An extension to the standard protocol, by Alvin@Sushi. This is
+            used to send mails from one mud to another.
+
+            "udpm_status"
+                This field should only be used in the reply and indicates
+                how mail is handled. Currently there are four pre-defined
+                values for the status field:
+                0 time out
+                1 delivered ok
+                2 unknown player
+                3 in spool (will be delivered later)
+
+            "udpm_writer"
+                Name of the person who wrote this mail
+
+            "udpm_spool_name"
+                Should be returned as sent, this value is used to remove
+                the mail from the spool directory after it has been
+                delivered (or refused)
+
+            "udpm_subject"
+                Subject of the mail message
+
+            "DATA"
+                The body of the mail (the actual message)
+
+        "ping"
+            A ping request has only the standard fields, the reply is
+            usually a short string like " is alive."
+
+        "query"
+            Get standard information about another mud. This is the only
+            command of which the reply may not include a load of rubbish,
+            but should only hold the requested information, so that it can
+            be parsed by the server.
+
+            "DATA"
+                The following queries are pretty much standard:
+                "commands" List all commands that are supported by the inetd
+                "email"    The email-address of the mud administrator(s)
+                "hosts"    A listing of all hosts in a special format [t.b.d.]
+                "inetd"    The version number of the inetd used
+                "list"     The list of all items which can be queried
+                "info"     A short human-readable string with practically
+                           "query" information
+                "mud_port" The portnumber that players connect to on login
+                "time"     The local time for this mud
+                "users"    A list of the people that are active in this mud
+                "version"  The version of the mud-driver (and library)
+                "www"      The URL of the mud's web page (e.g.
+                           http://mud.stack.nl/)
+
+        "reply"
+            This request method is used for _all_ replies.
+
+            "DATA"
+                A human-readable string, containing the reply to a given query
+
+            "RCPNT"
+                The same name as in the "SND" field or the query; Usually
+                this is the name of the player who initiated the query
+
+            "QUERY"
+                This field is only used in a response to a "query" request
+                and should be equal to the "DATA" field of that request
+
+            "vbs"
+                This field is only used in a response to a "locate" request
+                and should be equal to the "vbs" field of that request
+
+            "user"
+                This field is only used in a response to a "locate" request
+                and should be equal to the "user" field of that request
+
+            "fnd"
+                This field is only used in a response to a "locate" request
+                and should be 1 if the player was located and 0 otherwise
+
+        "tell"
+            Say something to a player on another mud.
+
+            "RCPNT"
+                Name of the player to whom you are talking
+
+            "DATA"
+                Whatever you wish to say to this person
+
+            Optional emote-tos are handles are also handled as tells, so
+            muds without emote-to support display them as reasonable readable
+            tell message.
+
+            "RCPNT"
+                Name of the player to whom you are talking
+
+            "METHOD"
+                The body of this header may be:
+                "emote"   if the message is an emote
+                "gemote"  if the message is a genitiv emote
+
+            "DATA"
+                The text to be emoted prepended with "*" and appended
+                with "* ". If you display the emote you have to cut the
+                stars off. Muds that do not process emote-tos display the
+                emote as tell message with the stars as indication of
+                the message's emote meaning.
+
+        "who"
+            List the people that are active on a remote mud. The anwer
+            usually contains some active information about the players,
+            like titles, levels or age.
+
+            "DATA"
+                Not supported by many muds. Introduced August 1997.
+                Additional switch(es) (blanc separated) that change the
+                appearence of the resulting list. The switches normally
+                resemble the switches used inside of that mud for the 'who'
+                command.  Typical values include:
+                "short" "s" "-short" "-s" "kurz":
+                    Return a concise listing.
+                "alpha" "a" "alphabetisch" "-alpha" "-a"
+                    Sort the players alphabetically.
+
+AUTHOR
+        Information taken from Outerspaces documentation to be found
+        on http://mud.stack.nl/intermud/
+
+SEE ALSO
+        inetd(C), intermud.basic(C), imp(C)
diff --git a/doc/concepts/intermud.basic b/doc/concepts/intermud.basic
new file mode 100644
index 0000000..901967f
--- /dev/null
+++ b/doc/concepts/intermud.basic
@@ -0,0 +1,151 @@
+CONCEPT
+        intermud.basic
+
+DESCRIPTION
+        Here is how intermud data is sent across the internet - specific
+        for Zebedee Intermud (aka Intermud 2).
+
+ADVANCED PROTOCOL
+        This file was originally written as a brief outline of the intermud
+        protocol for use by developers interested in incorperating similar,
+        compatible intermud protocols into their own mud systems. It is
+        included here as it provides a much more detailed description of the
+        intermud protocol than that provided by the original PROTOCOL file,
+        and hence may be of use to LpMud developers. 
+
+PACKET PROTOCOL / FORMAT
+        All information is transferred as a string via a UDP port (each mud
+        has 1 send and 1 receive port). This kindof transfer is inherently
+        unreliable, but it's fast and doesn't use up file descriptors.
+        The format of the strings (packets) is as follows: 
+
+           header1:body1|headerN:bodyN|DATA:body-data
+
+        In other words, a header name, followed by a : and then the data
+        associated with this header. Each header/body pair is separated by
+        the | character. This means that headers and their body cannot
+        contain the | character. You should check for this in outgoing
+        packets to aviod decoding errors at the recieving end. The exception
+        to this is the DATA field. If it is present, it is ALWAYS positioned
+        at the end of the packet. Once a DATA header is found, everything
+        following it is interpreted as the body of the DATA field. This
+        means it can contain special characters without error and it is
+        used to carry the main body or data of all packets. 
+
+        By convention, predefined system fields will use capital letters for
+        field headers and custom headers used by specific applications will
+        use lowercase names to avoid clashes. The defined system fields are
+        generally refered to by a set of macros which are defined in a
+        common header file for clarity. 
+
+        There is one exception to this header format; If the data is too
+        large to be transmitted in one single packet, it will be split into
+        packets of convenient size, each with a special unique packet header
+        to enable them to be reassembled at the receiving end. These
+        headers are of the format: 
+
+          PKT:mudname:packet-id:packet-number/total-packets|rest-of-packet
+
+        In this case, the mudname and packet-id combine to form a unique id
+        for the packet. The packet-number and total-packets information is
+        used to determine when all buffered packets have been received. The
+        rest-of-packet part is not parsed, but is stored while the receiver
+        awaits the other parts of the packet. When/if all parts have been
+        received they are concatenated and decoded as a normal packet. 
+
+PACKET ENCODING / DECODING
+        Only 2 generic data types are fully suported within the inetd code
+        itself (namely strings and integers), though others can easily be
+        used by converting them to one of the supported data types before
+        transfer and converting back again in receipt. The LpMud "object"
+        data type is converted to a string automatically by the inetd on
+        encoding, but no such conversion is carried out on decoding. 
+
+        On encoding integers are simply converted to a corresponding string.
+        Strings are left untouched as long as there is no ambiguity as to
+        wether they should be decoded as a string or an integer. In this
+        case of ambiguity, the string is prepended with a $ character. If
+        the first character of a string is the $ character, it is escaped
+        by prepending another $ character. On decoding, any string with a $
+        as its first character will have it removed and will then be treated
+        as a string. Any remaining strings that can be converted to an
+        integer and then back to a string with no loss of information are
+        considered to be integers. Any remaining strings are treated as
+        such and are left unaltered. 
+
+DEFINED SYSTEM HEADERS
+        "RCPNT" (RECIPIENT)
+            The body of this field should contiain the recipient the message
+            is to be sent to if applicable. 
+        "REQ" (REQUEST)
+            The name of the intermud request that is being made of the
+            receiving mud. Standard requests that should be supported by
+            all systems are "ping" (PING), "query" (QUERY), and "reply"
+            (REPLY). The PING request is used to determine wether or not a
+            mud is active. The QUERY request is used to query a remote mud
+            for information about itself (look at the udp/query module for
+            details of what information can be requested). The REPLY request
+            is special in that it is the request name used for all replies
+            made to by mud B to an initial request made by a mud A. It is
+            mud A's responsibility to keep track of the original request
+            type so that the reply can be handled appropriately. 
+        "SND" (SENDER)
+            The name of the person or object which sent the request or to
+            whom replies should be directed. This is essential if a reply
+            is expected. 
+        "DATA" (DATA)
+            This field should contain the main body of any packet. It is
+            the only field that can contain special delimiting characters
+            without error. 
+
+        The following headers are used internally by the inetd and should
+        not be used by external objects: 
+        "HST" (HOST)
+            The IP address of the host from which a request was received.
+            This is set by the receiving mud and is not contained in
+            outgoing packets. 
+        "ID" (ID)
+            The packet id. This field is simply an integer which is set by
+            the sending inetd. The number is incremented each time a packet
+            is sent (zero is never used). This field is only needed if a
+            reply is expected. REPLY packets _must_ include the original
+            request id. This is _not_ done by the inetd. 
+        "NAME" (NAME)
+            The name of the local mud. Used for security checking and to
+            update host list information. 
+        "PKT" (PACKET)
+            A special header reserved for packets which have been split.
+            See PACKET PROTOCOL / FORMAT. 
+        "UDP" (UDP_PORT)
+            The UDP port the local mud is receiving on. Used for security
+            checking and updating host list information. 
+        "SYS" (SYSTEM)
+            Contains special system flags. The only system flag used at
+            present is TIME_OUT. This is included in packets returned due
+            to an expected reply timing out to differentiate it from an
+            actual reply. 
+
+UDP REQUESTS / MODULES
+        The following are standard request types that must be supported
+        by all systems: 
+        "ping" (PING)
+            This module should return a REPLY packet that contains the
+            original requests ID in it's ID field and the SENDER in it's
+            RECIPIENT field. It should also include an appropriate string
+            in the DATA field, eg. "Mud-Name is alive.\n" 
+        "query" (QUERY)
+            This module expects the type of query requested to appear in the
+            recieved DATA field. It should return a REPLY packet containing
+            the original ID in the ID field, the SENDER in it's RECIPIENT
+            field, and the query type in a QUERY field. The DATA field should
+            contain the information requested. 
+
+        For details of how other intermud requests operate, look at the
+        relevant module code. 
+
+AUTHOR
+        Information taken from Outerspaces documentation to be found 
+        on http://mud.stack.nl/intermud/
+
+SEE ALSO
+        inetd(C), intermud(C)
diff --git a/doc/concepts/lpc b/doc/concepts/lpc
new file mode 100644
index 0000000..1e5911e
--- /dev/null
+++ b/doc/concepts/lpc
@@ -0,0 +1,64 @@
+* What is LPC?
+
+LPC is the language in which LPmud objects are written.
+LPC stands for Lars Pensj| C.  As one might surmise from the name,
+LPC is based on the syntax of C.  LPC provides the C while loop, for loop,
+if statement, switch statement, a variant of sscanf, and integer data type,
+(LPC also provides other data types not in C such as the object and the
+mapping).  LPC uses C's syntax for defining and calling functions and for
+declaring variables.  Note that LPC's version of the string datatype is
+much different from that provided by C.  See the LPC tutorial on syntax
+and language constructs for more information.
+
+Here are some differences between LPC and C:
+
+There is no need for a function named "main" in LPC objects (although there
+is one called "create").
+
+The efuns (or system calls) provided by the gamedriver are different than
+those typically found in the C library (libc.a).
+
+There is no malloc().  However, there is an allocate(int value) efun that
+lets space be allocated for arrays.  Note that the argument to 'allocate'
+is not in units of bytes, but rather in units of elements.
+
+Memory is never explicitly deallocated.  The gamedriver keeps track of
+how many times a given piece of data has been referenced.  When the
+reference count goes to zero (when no object has a copy of that variable),
+then the space used by the variable is reclaimed (garbage collected).
+
+The string data type in LPC is closer to that provided by BASIC than that
+provided by C.  Strings are not declared as arrays of characters but rather
+as a basic intrinsic type.  Strings may be concatenated using the '+' operator.
+
+For example, the LPC statements:
+
+string ack;
+
+ack = foo + bar;
+
+are equivalent to the C statements:
+
+char *ack;
+
+ack = (char *)malloc(strlen(foo) + 1);
+strcpy(ack,foo);
+ack = (char *)realloc(strlen(ack) + strlen(bar) + 1);
+strcat(ack,bar);
+
+Note: ack[i] may not appear as an lvalue (i.e. ack[i] = 'a'; will not
+work as expected).
+
+LPC is an interpreted language (however it is compiled into an internal
+compact tokenized form before being interpreted).
+
+LPC has no structures or unions.  In fact, the -> operator is used to
+indicate a call to another object.  The mapping datatype can serve
+as an effective substitute for structures in some situations.
+
+sscanf does not work in the same way as in C.  arguments to sscanf need not
+be pointers (since LPC does not have the explicit pointer data type).  Also,
+sscanf(arg,"%s %s",str1,str2) does not operate as the C programmer would
+expect.  In C, the first word of arg would be copied into str1 and the
+second word of arg into str2.  In LPC, the first word is copied into str1
+and the _remainder_ of arg is copied into str2.
diff --git a/doc/concepts/mail b/doc/concepts/mail
new file mode 100644
index 0000000..c08508c
--- /dev/null
+++ b/doc/concepts/mail
@@ -0,0 +1,73 @@
+CONCEPT:
+	mail
+
+
+DESCRIPTION:
+	This document describes the mail system used in Nightfall.
+	The idea is to make a central mail handling object which
+	accepts and distributes mail between users. Mail is stored in
+	the /mail directory. save_object is used to save mail
+	information in mail files in this directory. Only the mail
+	demon object and the owner of the mail file can access it.
+
+	A number of mail readers will probably available which access
+	the mail files. A typical mail user agent has commands to
+	read mail contained in the user's mail file, to reply to
+	messages, to forward, delete, save them. A folder structure
+	can be implemented. Outgoing mail is given to the mail demon
+	object by the user agent for distribution. The mailreader
+	should implement multiple recipients - carbon copy, cc and
+	blind carbon copy, bcc. Carbon copy means alternate recipients
+	to which the message should be sent. Blind carbon copy is the
+	same, but the recipients won't be listed in the received
+	message.
+
+	Save file format (sort of formal notation):
+
+	mixed *folders = ({
+	   ({ string name1; string name2; ... string nameN; })
+	   ({ mixed *msgs1; mixed *msgs2; ... mixed *msgsN; })
+	})
+
+	The array variable <folders> contains a number of folder
+	structures containing the actual messages. There are special
+	folders which are reserved: mail, newmail. New mail will
+	be delivered into the newmail folder. This is the only hard
+	coded requirement (the mail demon will simply deposit new
+	mail there). The folder name 'mail' should be used for read
+	mail. Other folders can be dynamically created by the user
+	agent.
+
+	Each msgs field is an array of messages:
+
+	mixed *msgs = ({ mixed *message1; ... mixed *messageM })
+
+	A message is represented as an array with the following fields:
+
+	mixed *message = ({
+	   string from;
+	   string sender;
+	   string recipient;
+	   string *cc;
+	   string *bcc;
+	   string subject;
+	   string date;
+	   string id;
+	   string body;
+	})
+
+	The mailer demon (/secure/mailer, or /obj/mailer) provides
+	the following functions:
+
+	DeliverMail(mixed *message)
+	  Hand a mail message over to the mailer demon. The mailer
+	  demon extracts recipients from the recipient, cc and bcc
+	  fields and removes the bcc information. It then deposits
+	  the message to the mail files of all recipients. A valid
+	  message is shown above.
+
+	int FingerMail(string user)
+	  Gives the number of unread messages a user has.
+
+
+SEE ALSO:
diff --git a/doc/concepts/mccp b/doc/concepts/mccp
new file mode 100644
index 0000000..f3e31fb
--- /dev/null
+++ b/doc/concepts/mccp
@@ -0,0 +1,100 @@
+CONCEPT
+        mccp - The Mud Client Compression Protocol
+
+DESCRIPTION
+        Informations and code taken from the MCCP Homepage
+        http://www.randomly.org/projects/MCCP/
+
+        MCCP is implemented as a Telnet option [RFC854, RFC855]. The server
+        and client negotiate the use of MCCP as they would any other telnet
+        option. Once agreement has been reached on the use of the option,
+        option subnegotiation is used to determine acceptable compression
+        methods to use, and to indicate the start of a compressed data stream. 
+
+        If the driver is compiled with MCCP Support there is a
+        define __MCCP__.
+
+        The driver currently supports both versions of mccp. If your mud
+        has a H_NOECHO hook you have to find out if the client supports
+        mccp. Without this hook you still have to start neogotiation.
+
+        All sub-negotiation is done by the efuns start_mccp_compress() and
+        end_mccp_compress() whether you have this hook or not.
+
+        Notice: when the client uses compressions all binary_message calls
+                are executed with flag=3. This is because writing to the
+                socket would disturb zlib stream.
+        
+        mccp-efuns:
+
+          start_mccp_compress(int telopt) (only needed with H_NOECHO)
+          end_mccp_compress(int telopt)   (only needed with H_NOECHO)
+          query_mccp(object player)
+          query_mccp_stats(object player)
+
+       Initiating MCCP without H_NOECHO hook:
+
+          if(!query_mccp()){
+            binary_message(({ IAC, WILL, TELOPT_COMPRESS2 }),1)
+            binary_message(({ IAC, WILL, TELOPT_COMPRESS }),1)
+          }
+
+          the driver will parse the clients answers and start compression.
+          (The connection might already be compressed, because although the
+           documentation says clients should not negotiate from themselfes,
+           zmud e.g. does.)
+
+          You can start and stop compression manually by efuns
+          when you are sure client supports compression :)
+
+
+       Initiating MCCP compression with H_NOECHO hook:
+
+          If your mudlib uses the H_NOECHO driver-hook you decided to do
+          all the negotiation by yourself:
+
+          Server Commands
+          IAC WILL COMPRESS indicates the sender supports version 1 of the
+                            protocol, and is willing to compress data it sends. 
+
+          IAC WILL COMPRESS2 indicates the sender supports version 2, and is
+                             willing to compress data it sends. 
+
+          IAC WONT COMPRESS indicates the sender refuses to compress data using
+                            version 1. 
+
+          IAC WONT COMPRESS2 indicates the sender refuses to compress data
+                             using version 2. 
+
+          Client Commands
+          IAC DO COMPRESS indicates the sender supports version 1 of the
+                          protocol, and is willing to decompress data received. 
+
+          IAC DO COMPRESS2 indicates the sender supports version 2 or above,
+                           and is willing to decompress data received. 
+
+          IAC DONT COMPRESS indicates the sender refuses to support version 1.
+                            If compression was previously negotiated and is
+                            currently being used, the server should terminate
+                            compression. 
+
+          IAC DONT COMPRESS2 indicates the sender refuses to support version 2.
+                             If compression was previously negotiated and is
+                             currently being used, the server should terminate
+                             compression
+
+          After you found out whether the client supports mccp or not you can
+          start compression with start_mccp_compress(TELOPT_COMPRESS2) or
+          start_mccp_compress(TELOPT_COMPRESS). ( you could start it without
+          checking but some players would protest :) )
+
+AUTHOR
+        Bastian Hoyer (dafire@ff.mud.de) (some text taken from project page)
+
+HISTORY
+        Added in LDMud 3.3.447, backported to LDMud 3.2.10.
+
+SEE ALSO
+        start_mccp_compress(E), end_mccp_compress(E), query_mccp(E),
+        query_mccp_stats(object player)
+
diff --git a/doc/concepts/memory b/doc/concepts/memory
new file mode 100644
index 0000000..9524eb3
--- /dev/null
+++ b/doc/concepts/memory
@@ -0,0 +1,56 @@
+CONCEPT
+        memory
+        swapping
+
+DESCRIPTION
+
+        TODO: This is out of date. Also document the relation with reset
+
+        (Collected from the Changelogs of the driver source)
+
+        The swapping algorithm has been changed. A test is done for
+        every object, comparing to a time stamp. If the object hasn't
+        been touched for a while, it could be subject for swapping.
+        Here comes the new thing: the function 'clean_up()' will be
+        called in the object. If the object still remains, the old
+        swapping algorithm will continue. That means that objects that
+        would never be subject to swapping (cloned objects) now have a
+        chance to self-destruct. It also means that rooms that
+        contains no important data can self-destruct. Self-destruction
+        saves more memory than swapping, as swapping only frees the
+        program code, while self-destruction also frees the internal
+        object representation.
+
+        The call of clean_up() has been modified. There is a constant
+        in config.h that defines how long time until clean_up is
+        called in an object. This call is independent of reset() and
+        swapping. It is recommended that the swapping time is
+        something short, like 10 minutes to 30 minutes, while the time
+        to clean_up is longer.
+
+        Fixed several bugs in the swap/reset/clean_up logic.
+        Recommended values are that the swap time is short (less than
+        30 minutes), and that reset time is medium (aprox 60 minutes),
+        and that time to clean_up is long (greater than 1.5h hours).
+        Any feedback of how to best tune these values are welcome. The
+        call of reset will be done once, and not yet again until the
+        object has been touched. This enables reset'ed objects to stay
+        swapped out. If you have a mudlib that has no ojbects that
+        defines 'clean_up', then you may better define this time as 0,
+        which means never call clean_up (and thus never swap the
+        object in needlessly). A well implemented usage of clean_up is
+        better than the swap algorithm, as even cloned objects can be
+        cleaned up and a self destruction is more efficient than
+        swapping (memory wise).
+
+        Changed mechanism of calling clean_up() slightly. Only objects
+        that defines the function will be called. And, only clean_up()
+        that returns non-zero will be called again. This will minimize
+        calls of clean_up(), while still cost very litte to maintain.
+
+        clean_up() now gets a flag as argument, which will be non-zero
+        if the the program of this object is used for inheritance by
+        other objects.
+
+SEE ALSO
+        clean_up(A), slow_shut_down(M), quota_demon(M), malloc(D)
diff --git a/doc/concepts/mysql b/doc/concepts/mysql
new file mode 100644
index 0000000..4fb6dee
--- /dev/null
+++ b/doc/concepts/mysql
@@ -0,0 +1,205 @@
+CONCEPT
+            mysql - mySQL support
+
+DESCRIPTION
+        On hosts with the mySQL package installed, the driver can be
+        configured to interface with the mySQL database. If that is done,
+        the driver defines the macro __MYSQL__ for LPC programs and
+        activates a number of efuns.
+
+        -- Configuration --
+
+        Create a dedicated user in the mySQL database for the driver.
+        Enter this username and password in the file pkg-mysql.c, function
+        mysql_real_connect(), and compile the driver (the username and
+        password are built into the driver for security reasons).
+        If you chose to not create either a username and/or a password,
+        leave the corresponding entry at 0.
+
+        Use mysqladmin to create any databases you want to provide - the
+        names are later used in the efun db_connect() to connect to
+        the databases.
+
+
+        -- Usage --
+
+        The idea behind SQL-support is that you can swap large amounts of
+        data into a database where it can be accessed very easily.
+        As mySQL "limits" the number of connections to 100 and as every
+        connection to the mySQL-server takes time, you should use
+        database serverobjects in your MUD which constantly keep the
+        connection to the mySQL-server.
+
+        To connect to your mySQL-server, use the efun db_connect(). It
+        takes only one argument which is the name of the database (which
+        must exist).  The return-value of db_connect() is an integer
+        representing the unique handle to the database with which you will
+        identify your connection later.
+
+        To send or retrieve data from this connection, use db_exec(). The
+        first parameter for all efuns dealing with an open connection is
+        always the handle and so is the first argument the handle and the
+        second one the command you want to issue. The return-value is
+        either 0 if there was an error in your command (this can have
+        various reasons), otherwise your handle is returned again. A typical
+        SQL-statement to retrieve data would be like this:
+
+                select aliases.command from aliases where (name = 'mario' AND
+                  alias regexp 'l.*')
+
+        As you know, mySQL accepts either " or ' to classify strings for
+        parameters.  Most likely, you will pass variables and don't know
+        whether they contain one or more of these key-chars (or even other
+        chars that need to be converted). mySQL provides a function for
+        converting just any string into an acceptable argument and this is
+        implemented in db_conv_string().
+
+        So the above example with variables looks like this:
+
+                select aliases.command from aliases where (name ='"+
+                  db_conv_string(name)+"' AND alias regexp '"+
+                  db_conv_string(mask)+"')
+
+        I left out the db_exec()-stuff, more complete examples will follow.
+
+        After you initiated a statement that should return rows from the
+        database, use db_fetch() to retrieve the data. db_fetch() returns
+        the data row by row and not all at once. You need to call it until
+        it returns 0. THIS IS IMPORTANT! If stop calling db_fetch() before
+        it reaches the end of data, serious inconsistencies can happen.
+
+        If you used a DELETE- or UPDATE-statement, you cannot call db_fetch(),
+        but you might be interested in the number of deleted/changed rows
+        which can be queried with db_affected_rows().
+
+        After all operations are done in the database, you should use
+        db_close() to close the connection again. If you are using a
+        database-server-concept, place it in the remove()-function.
+
+        The SQL-efuns have some built-in optimization-features to speed up
+        often used connections. To get a list of all open connections to the
+        mySQL-server, use db_handles() which returns an array of integers
+        with all open handles.
+
+
+        -- Security --
+
+        Most SQL efuns (unless execute by the master or the simul-efun object)
+        trigger a privilege_violation ("mysql", "<efun_name>"). If a more
+        finegrained control is desired, overload the individual efuns with a
+        nomask simul-efun.
+
+        The unprivileged efuns are:
+
+          db_conv_string()
+
+
+EXAMPLE
+        A simple server to store aliases could be implemented like this:
+
+        /*
+        **  CREATION:
+        **
+        **  create table aliases (
+        **      name varchar(15) not NULL,
+        **      alias varchar(20) not NULL,
+        **      command varchar(255) not NULL,
+        **      primary key (name, alias));
+        */
+
+        #define DATABASE "mud"
+
+        private int handle;
+
+        public void create()
+        {
+            handle = db_connect(DATABASE);
+        }
+
+        public int remove()
+        {
+            if ( handle )
+                db_close(handle);
+            destruct(ME);
+            return !ME;
+        }
+
+        public int AddAlias(string alias, string command, object ob)
+        {
+            if ( !handle )
+                handle = db_connect(DATABASE);
+            if ( !db_exec(handle,
+                          "insert into aliases (name, alias, command) values "
+                          "('" + getuid(ob) + "','" + db_conv_string(alias)
+                               + "','"+
+                          db_conv_string(command) + "')") )
+                return -1;
+            return 1;
+        }
+
+        public int RemoveAlias(string alias, object ob)
+        {
+            int res;
+
+            if ( !handle )
+                handle = db_connect(DATABASE);
+            res = db_exec(handle,
+                          "delete from aliases where (name = '"+
+                          getuid(ob) + "' AND alias = '"
+                                     + db_conv_string(alias)+
+                          "')");
+            if ( !res )
+                return 0;
+            res = db_affected_rows(handle);
+            return (res > 0)?1:-1;
+        }
+
+        public mixed *QueryAliases(string mask, object ob)
+        {
+            mixed *result;
+            string *tmp;
+
+            if ( !handle )
+                handle = db_connect(DATABASE);
+            if ( !db_exec(handle,
+                          "select aliases.alias, aliases.command from aliases where "
+                          "(name = '" + getuid(ob)+
+                          "' AND alias regexp '" + db_conv_string(mask) + "')") )
+                return ({ });
+            result = ({ });
+            while ( sizeof(tmp = db_fetch(handle)) )
+                result += ({ tmp });
+            return result;
+        }
+
+        public string QueryAlias(string alias, object ob)
+        {
+            mixed *result;
+            string *tmp;
+
+            if ( !handle )
+                handle = db_connect(DATABASE);
+            if ( !db_exec(handle,
+                          "select aliases.command from aliases where "
+                          "(name = '" + getuid(ob)+
+                          "' AND alias = '" + db_conv_string(alias) + "')") )
+                return 0;
+            result = ({ });
+            while ( sizeof(tmp = db_fetch(handle)) )
+                result += tmp;
+            return sizeof(result)?result[0]:0;
+        }
+
+
+AUTHOR
+        Mark Daniel Reidel and others.
+
+HISTORY
+        mySQL support was added as a package in 3.2.8 and became and
+        integral driver part in 3.2.9.
+        LDMud 3.2.11 added a privilege_violation() call for each efun.
+
+SEE ALSO
+        pgsql(C), db_affected_rows(E), db_conv_string(E), db_close(E),
+        db_connect(E), db_exec(E), db_fetch(E), db_handles(E),
+        db_insert_id(E), db_coldefs(E), db_error(E), privilege_violation(A)
diff --git a/doc/concepts/native b/doc/concepts/native
new file mode 100644
index 0000000..13cf008
--- /dev/null
+++ b/doc/concepts/native
@@ -0,0 +1,170 @@
+CONCEPT
+        driver modes / native driver mode
+
+DESCRIPTION
+        During the evolution of LPMud there has been a hiatus as the
+        old driver became too restricting for the demands of modern
+        muds: it did a lot of things the mudlib could do better or
+        completely different. Removing these things from the driver
+        weren't a problem, but to keep compatible with the existing
+        mudlibs (namely the well-known 2.4.5 lib), it was possible to
+        undo these changes. First by setting a runtime option, then
+        by compiling the driver either in 'compat' or in 'native' mode.
+
+        Starting with 3.2.1, the distinction between compat and native
+        mode is more and more transferred into the mudlib, with the
+        future goal of having a modeless driver.
+
+        Starting with 3.2.7, native mode no longer exists as such,
+        only 'plain' (quasi a superset of 'native' and 'compat')
+        and 'compat' mode, and since 3.2.9 the mode selection can be
+        made via commandline option.
+
+        The main mode of the driver is determined at compile time
+        by preprocessor symbols to be defined/undefined in config.h:
+
+          COMPAT_MODE: when defined, the compat mode specifics are activated
+                       by default.
+
+        Additional modifications can be achieved by the specification
+        of commandline arguments (most of them have a default setting
+        entry in config.h as well):
+
+          strict-euids: when active, euid usage is enforced.
+          compat:       when active, the compat mode is used.
+
+        Following is the description of the changes (de) activated by
+        these defines. A shorthand notation is used: 'compat' means
+        'if compat mode is active' and '!compat' means 'if
+        compat mode is not active', etc.
+
+
+        Predefined Preprocessor Symbols
+          If compat, the symbols COMPAT_FLAG and __COMPAT_MODE__ are
+          defined for all LPC programs.
+          If strict-euids, the symbol __STRICT_EUIDS__ is defined
+          for all LPC programs.
+          For compatibility reasons, the symbol __EUIDS__ is defined
+          for all LPC programs all the time.
+
+
+        Preloading Of Objects
+          The driver has the possibility to preload objects before the
+          game is actually opened to the world. This is done by
+          calling master->epilog(), which has to return 0 or an array.
+          If its an array, its elements (as long as they are strings)
+          are given one by one as argument to master->preload() which
+          may now preload the objects (or do anything else).
+
+
+        Initialisation Of Objects
+          It is task of the mudlib (through the driver hooks) to call
+          the initialisation lfuns in newly created objects. The
+          following table shows the traditional calls:
+
+                  mode        : init call : reset call
+           --------------------------------------------
+            !compat & !native :  create() :  reset(1)
+            !compat &  native :  create() :  reset()
+             compat & !native :  reset(0) :  reset(1)
+             compat &  native :  reset(0) :  reset(1)
+
+          If INITIALIZATION_BY___INIT was defined, the lfun __INIT()
+          is called first on creation to initialize the objects
+          variables.
+
+
+        Movement Of Objects
+          The efun move_object() is implemented in the mudlib through
+          driver hooks and the set_environment() efun.
+          move_object() itself exists just for convenience and
+          compatibility.
+
+          In original native mode, move_object() could applied only to
+          this_object() as the object to move, and it called the lfun
+          exit() in the old environment if in compat mode. As a side
+          effect, the lfun exit() may not be target of add_action()s
+          in compat mode.
+
+          In compat mode, objects may be moved using the transfer()
+          efun. It does make assumptions about the design of the
+          mudlib, though, as it calls the lfuns query_weight(),
+          can_put_and_get(), get(), prevent_insert() and add_weight().
+
+
+        Efuns In General
+          creator(), transfer()
+            These exist only in compat mode (creator() is
+            identical with getuid()).
+
+          object_name(),function_exists()
+            In !compat mode, the returned filenames start with a
+            leading '/', in compat mode they don't.
+
+          parse_command()
+            This command exists in two versions: the old is used with
+            compat, the new with !compat. However,
+            SUPPLY_PARSE_COMMAND must be defined in config.h in both
+            cases (this efun is not very useful at all).
+
+          process_string()
+            If this_object() doesn't exist, it defaults to this_player()
+            and receives the backbone uid (returned by master->get_bb_uid())
+            as euid. If strict-euids, this uid must not be 0.
+
+        Userids and Effective Userids
+          This is probably the most important difference between the
+          modes.
+
+          LPMud always had userids (uids) attributing the objects,
+          though they were called 'creator names' in compat mode.
+          Internally, the compat mode uses the 'creator names' as
+          (e)uid.
+
+          With the introduction of native/plain mode, additionally
+          'effective userids' (euids) were introduced to improve
+          security handling (which was only a partial success).
+          The hardcoded handling of euids and uids was quite complex
+          and too mudlib-insensitive, so most of it got moved from the
+          driver into the mudlib with 3.2.1.
+
+          In strict-euids mode, only objects with a non-zero euid may load
+          or create new objects.
+
+          --- In Detail ---
+
+            Userids of the Master
+              The masters (e)uid is determined by a call to
+              master->get_master_uid().
+              In strict-euids mode, the result has to be a string,
+                otherwise the driver won't start up at all. If the result is
+                valid it is set as the masters uid and euid.
+              In !strict-euids mode, the result may be any value: 0 or a
+                string are treated as the uid to set, a non-zero integer
+                leads to the use of the uid set in the default 'global'
+                wizlist entry, and any other value defaults to 0.
+                The euid is either set to the returned string (if any),
+                or to 0.
+              The masters uid is determined only on startup this way,
+              at runtime the uids of a reloaded master determined as
+              for every object by a call to the appropriate driver
+              hooks.
+
+            Userids of New Objects
+              To determine the (e)uids for a new object (loaded or
+              inherited, or cloned), the appropriate driver hook is
+              evaluated (H_LOAD_UIDS, H_CLONE_UIDS) and the result set
+              as (e)uid. The result may be a single value, in which case the
+              euid is set to 0, or an array ({ uid, euid }).
+              In strict-euids mode, both uid and euid must be 0 or a string,
+                any other value causes the load/clone to fail.
+              In !strict-euids mode, the uid (however returned) may also be
+                a non-zero integer to use the uid of the global
+                wizlist entry as uid. The euid is then
+                set to either 0 or the second entry of the returned
+                array if it's a string.
+
+          --- ---
+
+SEE ALSO
+        hooks(C), uids(C), move_object(E), initialisation(LPC)
diff --git a/doc/concepts/negotiation b/doc/concepts/negotiation
new file mode 100644
index 0000000..ed2318f
--- /dev/null
+++ b/doc/concepts/negotiation
@@ -0,0 +1,316 @@
+CONCEPT
+        Telnet Negotiations
+
+DESCRIPTION
+        The telnet protocol is used to control textbased connections
+        between a client (the 'telnet' program or a mud client) and a
+        server (the game driver). Most of the options offered by the
+        protocol are optional and need to be negotiated between the
+        client and the server.  Consequently, and due to their
+        specialized nature, mud clients don't have to support the full
+        telnet option feature set.
+
+        For the server to find out if a client supports the telnet
+        protocol at all, one good approach is to a simple, commonly
+        used telnet command to the client. If the client reacts
+        conform to the protocol (or sends telnet commands itself), the
+        mud can continue to negotiate further options. If the client
+        does not react, the mud can safely refrain from further
+        negotiations.
+
+        The following list is a more or less comprehensive overview of
+        the telnet related RFCs (available for example on
+        http://www.faqs.org/rfcs):
+
+	 RFC Titel                                              rel. Code
+
+	 495 TELNET Protocol Specification
+	 513 Comments on the new TELNET specifications
+	 559 Comments on the new TELNET Protocol and its Implem
+	 595 Some Thoughts in Defense of the TELNET Go-Ahead
+	 596 Second Thoughts on Telnet Go-Ahead
+	 652 Telnet Output Carriage-Return Disposition Option   NAOCRD     10
+	 653 Telnet Output Horizontal Tabstops Option           NAOHTS     11
+	 654 Telnet Output Horizontal Tab Disposition Option    NAOHTD     12
+	 655 Telnet Output Formfeed Disposition Option          NAOFFD     13
+	 656 Telnet Output Vertical Tabstops Option             NAOVTS     14
+	 657 Telnet Output Vertical Tab Disposition Option      NAOVTD     15
+	 658 Telnet Output Linefeed Disposition                 NAOLFD     16
+	 698 Telnet Extended Ascii Option                       X-ASCII    17
+	 727 Telnet Logout Option                               LOGOUT     18
+	 728 A Minor Pitfall in the Telnet Protocol
+	 735 Revised TELNET Byte Macro Option                   BM         19
+	 749 Telnet SUPDUP-OUTPUT Option                        SUPDUP     22
+	 764 Telnet Protocol Specification
+	 779 Telnet SEND-LOCATION Option                        SENDLOC    23
+	 818 The Remote User Telnet Service
+	 854 Telnet Protocol Specification
+	 855 Telnet Option Specifications
+	 856 Telnet Binary Transmission                         BINARY      0
+	 857 Telnet Echo Option                                 ECHO        1
+	 858 Telnet Suppress Go Ahead Option                    SGA         3
+	 859 Telnet Status Option                               STATUS      5
+	 860 Telnet Timing Mark Option                          TM          6
+	 861 Telnet Extended Options - List Option              EXOPL     255
+	 884 Telnet Terminal Type Option                        TTYPE      24
+	 885 Telnet End of Record Option                        EOR        25
+	 930 Telnet Terminal Type Option                        TTYPE      24
+	 933 Output Marking Telnet Option                       OUTMRK     27
+	 946 Telnet Terminal Location Number Option             TTYLOC     28
+	1043 Telnet Data Entry Terminal Option DODIIS Implement DET        20
+	1053 Telnet X.3 PAD Option                              X.3-PAD    30
+	1073 Telnet Window Size Option                          NAWS       31
+	1079 Telnet Terminal Speed Option                       TSPEED     32
+	1080 Telnet Remote Flow Control Option                  FLOWCTRL   33
+	1091 Telnet Terminal-Type Option                        TTYPE      24
+	1096 Telnet X Display Location Option                   XDISPLOC   35
+	1116 Telnet Linemode Option                             LINEMODE   34
+	1143 The Q Method of Implementing TELNET Option Negotia
+	1184 Telnet Linemode Option                             LINEMODE   34
+	1372 Telnet Remote Flow Control Option                  FLOWCTRL   33
+	1408 Telnet Environment Option                          ENVIRON    36
+	1571 Telnet Environment Option Interoperability Issues
+	1572 Telnet Environment Option                          NEWENV     39
+	2066 Telnet Charset Option                              CHARSET    42
+	2217 Telnet Com Port Control Option                     COMPORT    44
+	2877 5250 Telnet Enhancements
+
+        All negotiations start with the special character IAC which is
+        defined in /usr/include/arpa/telnet.h (or in
+        src/driver/telnet.h for 3.2(.1)) and has the decimal value of
+        255. Negotiations are based on different telnetoptions (their
+        values are defined in telnet.h too). Before a negotiation can
+        start the client and the server have to agree that they
+        support the option.
+        This works in the following way:
+
+        If a client wants to send something to the server it has to
+        send 'IAC WILL option' (For terminaltype negotation this would
+        be the 3 bytes 255,251,24; again, check telnet.h) to confirm
+        that it is able to do that. If the server is supporting that
+        option and wants to receive something it sends 'IAC DO option'
+        (255,253,option)
+
+        If one side is receiving an 'IAC WILL option' and has not yet
+        sent with DO or DONT it has to respond with either 'IAC DO
+        option' if it will support this negotiation or 'IAC DONT
+        option' if it won't.
+
+        If one side is receiving an 'IAC DO option' and has not yet
+        sent a WILL or WONT it has to reply with either 'IAC WILL
+        option' if it supports the option or 'IAC WONT option' if not.
+
+        A small example: Lets assume we want to negotiating
+        terminaltype. (TELOPT_TTYPE with value 24). client is the
+        telnet executable on the playerside, the server is the
+        gamedriver.
+
+                client                        server
+            IAC WILL TTYPE
+                                    IAC DO TTYPE
+
+        Or:
+                                    IAC DO TTYPE
+            IAC WILL TTYPE
+
+        After this we are ready to transfer the terminaltype from the
+        client to the server as explained below.
+
+        Now we are ready to start the real negotiations. I explain the
+        3 options I have currently implemented.
+
+        First TerminalType aka TTYPE aka 24 aka TELOPT_TTYPE assuming
+        the client and the server have exchanged WILL/DO.
+
+        The server is now free to send 'IAC SB TELOPT_TTYPE
+        TELQUAL_SEND IAC SE' which will be replied with 'IAC SB
+        TELOPT_TTYPE TELQUAL_IS terminaltype IAC SE' where
+        terminaltype is a non-zero terminated string (it's terminated
+        by the IAC) (For values look up telnet.h) AND switch the
+        client's terminalemulation to 'terminaltype'. terminaltype is
+        case-insensitive. terminal-type may be UNKNOWN. The server may
+        repeat the SEND request and the client will respond with the
+        next preferred terminaltype. If this is the same as the
+        previous received, it marks the end of the list of
+        terminaltypes. The next SEND request will start the
+        terminaltypes from the beginning.
+
+        Example: (we have exchanged WILL/DO already)
+                  client                                server
+                                        IAC SB TTYPE SEND IAC SE
+        IAC SB TTYPE IS VT200 IAC SE
+                                        IAC SB TTYPE SEND IAC SE
+        IAC SB TTYPE IS VT100 IAC SE
+                                        IAC SB TTYPE SEND IAC SE
+        IAC SB TTYPE IS VT52 IAC SE
+                                        IAC SB TTYPE SEND IAC SE
+        IAC SB TTYPE IS VT52 IAC SE
+        /* this marks that we have all terminaltypes. We decide to use the
+         * vt200 mode so we have to skip to VT200
+         */
+                                        IAC SB TTYPE SEND IAC SE
+        IAC SB TTYPE IS VT200 IAC SE
+
+
+        Next important option is NAWS (31) or WindowSizeNegotiation.
+
+        This one is a bit easier than terminaltype. After having
+        received a IAC DO NAWS from the server, the client will reply
+        with IAC WILL NAWS and immediately after that send IAC SB NAWS
+        columns_high columns_low lines_high lines_low IAC SE where
+        xx_low refers to the lowbyte of xx and xx_high refers to the
+        highbyte of xx. This will be automagically resent at every
+        windowresize (when the client gets a SIGWINCH for example) or
+        at your request with 'IAC SB NAWS SEND IAC SE'.
+
+        Example: (WILL/DO exchanged)
+                client                                server
+        IAC SB NAWS 0 80 0 24 IAC SE         /* the standard vt100 windowsize */
+                                        /* no reply */
+
+        And, a bit less important but most complex, the LINEMODE (34)
+        option. It was implemented it due to the fact, that
+        some weird DOS telnets would not work otherwise. Implemented
+        are only the absolute basic feature, which is the actual
+        switching the telnet to linemode. After exchanging WILL/DO the
+        server sends a modechange request to the client using IAC SB
+        LINEMODE LM_MODE MODE_EDIT IAC SE, which should turn on local
+        commandline-editing for the client. If a client supports
+        LINEMODE it HAS to support this modechange. The client will
+        reply with IAC SB LINEMODE LM_MODE MODE_EDIT|MODE_ACK IAC SE
+        (x|y is bitwise or). Thats it for linemode. (You will perhaps
+        receive other IAC SB LINEMODEs with other LM_xxx ... you may
+        ignore them. (At least IRIX 5.x sends IAC SB LINEMODE LM_SLC
+        .... IAC SE which declares the local characterset.)).
+
+        Example: (WILL/DO negotiated)
+
+                client                                        server
+                                                IAC SB LINEMODE LM_MODE
+                                                       MODE_EDIT IAC SE
+        IAC SB LINEMODE LM_MODE
+          MODE_EDIT|MODE_ACK IAC SE
+
+        Note: The option is much more funnier as it looks here, it for
+          example supports a mixed mode between linemode and
+          charactermode... flushing the input at certain characters (at
+          ESC or TAB for shell-like commandline completition). We suggest
+          reading RFC 1184.
+
+        You might be interested in TELOPT_XDISPLAYLOC and TELOPT_ENVIRON too.
+
+        Now, how to implement this using LDMud?
+
+        0. Patch src/driver/comm1.c, function init_telopts() to include
+            telopts_do[TELOPT_XXX] = reply_h_telnet_neg;
+            telopts_dont[TELOPT_XXX] = reply_h_telnet_neg;
+            telopts_will[TELOPT_XXX] = reply_h_telnet_neg;
+            telopts_wont[TELOPT_XXX] = reply_h_telnet_neg;
+           for every telnet negotiation you want to use.
+           Do not overwrite the TELOPT_ECHO and TELOPT_SGA hooks.
+
+           Alternatively, set the driver hook H_NOECHO in master.c:
+           this diverts _all_ telnet data into the mudlib.
+
+        1. Add a new driver hook to master.c just below the others.
+                set_driver_hook(H_TELNET_NEG,"telnet_neg"),
+        2. Make a telnet.h for your mudlib... just change the arrays in
+                src/driver/telnet.h.
+        3. define a function
+
+                void telnet_neg(int cmd, int option, int * optargs)
+
+           in your interactive objects (login.c , shells, player.c or
+           whereever). And note, in ALL objects, through which a
+           player is handed through (in TAPPMud these are login.c and
+           player.c). [Ok, master.c is interactive for a very short
+           time too, but it won't accept input, will it?]
+           'cmd' will be TELCMD_xxxx (see telnet.h), 'option' one of
+           TELOPT_xxxx and 'optargs' will be an array of ints (bytes in
+           fact) when 'cmd' is SB.
+           Parse 'cmd'/'option' and reply with appropiate answers
+           using binary_message() (appropiate meaning sending the
+           right DO/DONT/WILL/WONT if not sent before and using the SB
+           return values).
+        3.1. Sent IAC DO TTYPE IAC DO NAWS IAC DO LINEMODE at the
+           first time you can do it (before cat()ing /WELCOME perhaps).
+        3.2. Note all sent and received WILL/WONT/DO/DONT options for
+           conforming to the standard, avoiding endless loops and for
+           easy debugging :)
+        3.3. Pass those recevied/sent data and other data when the
+           interactive object is changed (from login.c to player.c or
+           at other bodychanges). Clear the data when the player goes
+           linkdead or quits. You won't need to save this data.
+        3.4. Lower_case() terminaltypes... ;)
+        3.5. Use reasonable defaultvalues if the client does not
+           support one of the options. (columns 80,lines 24 if not
+           NAWS, unknown or vt100 for no terminaltype)
+
+        The WILL/WONT/DO/DONT data is best saved in a mapping looking
+        like this:
+          ([ "received": ([ option1: DO_DONT_OR_0;WILL_WONT_OR_0, ... ])
+           , "sent"    : ([ option1: DO_DONT_OR_0;WILL_WONT_OR_0, ... ])
+          ])
+
+        (Ok, it can be done better. But not without confusing *me*
+        more.)
+
+        Before sending anything check
+          TN["sent"][option,0_if_do_dont_or_1_if_will_wont]
+        so you don't enter endless loops, save network traffic and the
+        like.
+
+        The windowsize is best saved in the players environment
+        variables so that he can modify them later on. (Or in two
+        integers in the player object...). Use for these values is
+        clear I think.
+
+        The terminaltypes received using above mentioned method are
+        best stored in an array. The actual set terminaltype is best
+        stored in an environment variable where the player can modify
+        it. Upon modifying it the IAC SB TTYPE SEND IAC SE cycle
+        should be started to match the emulation to the entered new
+        terminaltype. You then may use data retrieved from
+        /etc/termcap (man 5 termcap) or /usr/lib/terminfo/*/* (SysVID,
+        man 5 terminfo) to implement terminalcontrol codes dependend
+        on the terminaltype. /etc/termcap may prove to be the easiest
+        way tough /usr/lib/terminfo/*/* is the newer (and better) SysV
+        way of doing it.
+
+        [Anyone got a description of the internal terminfo format for
+        me? -Marcus]
+
+        LINEMODE replies may be left alone if only using the mode
+        change to MODE_EDIT
+
+        Some statistics about what clients support telnet negotiations:
+
+        Tinyfugue and some other mudclients usually do not support
+        negotiations.
+        Except for TF, which supports the Telnet End-Of-Record option
+        as marker for the end of the prompt. So if you send IAC EOR
+        after every prompt, it will print the prompt always in the
+        input window. (Do not forget to negotiate that. First IAC WILL
+        TELOPT_EOR/wait for IAC DO TELOPT_EOR). Newer versions of
+        TF will support NAWS and there will be a patch for TTYPE
+        negotiation available soon.
+
+        All telnets able to do negotiations I've encountered support
+        the TTYPE option.
+        HP9.x,Irix5.x,Linux,EP/IX,CUTELNET/NCSATELNET (Novell) and
+        perhaps more support NAWS.
+        At least Irix5.x,Linux,CU/NCSATELNET support LINEMODE.
+        SUN does not support NAWS and LINEMODE neither in SunOS 4.1.3
+        nor in Solaris 2.3.
+
+        For getting RFCs you can for example use
+        ftp://ftp.uni-erlangen.de/pub/doc/rfc/
+
+
+BUGS
+        Not all aspects of the options are mentioned to keep this doc
+        at a reasonable size. Refer to the RFCs to get more confused.
+
+CREDITS
+        Provided by Marcus@TAPPMud (Marcus Meissner,
+        <msmeissn@cip.informatik.uni-erlangen.de>).
diff --git a/doc/concepts/news b/doc/concepts/news
new file mode 100644
index 0000000..cacefb4
--- /dev/null
+++ b/doc/concepts/news
@@ -0,0 +1,88 @@
+CONCEPT:
+	news
+
+
+DESCRIPTION:
+	This document describes the news system used in Nightfall.
+	News is intended to provide a general system for bulletin
+	boards and similar objects. It is similar to the Usenet
+	news system. Articles are stored in a central area, /news.
+	Articles (Messages) are stored as files within this
+	directory. Only the news demon object is allowed to write
+	and read in the /news directory. Interfaceing to the
+	news demon is done via interface functions in the news
+	demon.
+	
+	Typically news are read and written by a bulletin
+	board object or by a newsreader. Player buletin boards
+	should of course be limited to specific news groups.
+	A newsreader might be intelligent in that it autmatically
+	shows new messages. Groups may be moderated, then only the
+	moderator can write there. There are also flags whether a
+	board is a wiz_only board and who may remove messages.
+
+	Security is in several levels. It may be 0, then every
+	effective userid might read and write and delete articles,
+	although the news demon will still look for the match of
+	the sender field with certain group requirements. This level
+	of security is to make it possible to create groups
+	accessible by bulletin boards which have no euid.
+
+	Security level 1 means that euid check is done, for reading
+	and writing. This still allows for bulltin boards, but those
+	must have root euid and thus the ability to seteuid to the
+	euid of the object using the bulletin board (normally the
+	player). This feature requires native gamedriver mode.
+
+	Saved news file format (formal notation):
+
+	int security;	/* wheter euid check is done, 0 or 1 */
+	mixed *accesslist = ({
+	   mixed *readaccess;    /* who can read messages */
+	   mixed *writeaccess;   /* who can write messages */
+	   mixed *deleteaccess;  /* who can delete messages */
+	   mixed *controlaccess; /* who can control the accesslist */
+	})
+	mixed *messages = ({
+	   mixed *msg1; mixed *msg2; ... mixed *msgN;
+	})
+
+	An access entry can be be one of the following:
+	- an effective userid (string)
+	- one of the keywords "wizard", "all", "author"
+	- a wizard level (integer) which is required minimal
+	- an array of one of the plain types above (Alternative).
+
+	A message looks as follows:
+
+	mixed *message = ({
+	   string author;       /* who wrote the message */
+	   string subject;      /* the subject */
+	   string *groups;      /* news groups where this was posted */
+	   int date;            /* date of message written */
+	   string messageid;    /* a unique string */
+	   string *referenceid; /* list of references */
+	   int expire;          /* when message expires */
+	   string body;         /* the contents of the message */
+	})
+
+	The news demon (/secure/news, or /obj/news) provides the
+	following functions:
+
+	int success = PostMessage(mixed *message)
+	  Tells the demon to insert the message in the news database.
+	  Depending on security level, euid or message.author is
+	  checked if this is allowed.
+
+	int success = DeleteMessage(string *groups, string messageid)
+	  Remove a message from the database.
+
+	mixed *messagelist = ReadMessageHeaders(string group)
+	  Get all message headers (complete info, but without
+	  body) of newsgroup <group>.
+
+	mixed *message = ReadMessage(string *groups, string messageid)
+	  Retrieve a message from the database.
+
+
+SEE ALSO:
diff --git a/doc/concepts/objects b/doc/concepts/objects
new file mode 100644
index 0000000..b9c7eb9
--- /dev/null
+++ b/doc/concepts/objects
@@ -0,0 +1,25 @@
+CONCEPT
+        objects
+
+LAST UPDATED
+        never
+
+DESCRIPTION
+        An object consists of a collection of functions (also called
+        'methods') and data (variables) on which the functions operate.
+        The only way to manipulate the data contained in an object is
+        via one of the functions defined by the object.
+
+        Every single thing in a mud is an object.  Rooms are objects.
+        Weapons are objects.  Even your character is an object (a special
+        kind of object called "interactive" but still an object in most
+        every respect).  Each object (except possibly virtual objects) in
+        the mud is associated with some file written in LPC (in the mud's
+        directory structure) that describes how the object is to interact
+        with the gamedriver and the rest of the objects in the mud.
+
+AUTHOR
+        Someone
+
+SEE ALSO
+        files(C), inheritance(C), create(A), reset(A)
diff --git a/doc/concepts/oop b/doc/concepts/oop
new file mode 100644
index 0000000..5146a7e
--- /dev/null
+++ b/doc/concepts/oop
@@ -0,0 +1,76 @@
+OOP
+ BESCHREIBUNG:
+     OOP steht fuer "Object-Orientierte Programmierung":
+
+     Wenn du weisst, wie man in einer prozeduralen Sprache programmiert
+     (C, PASCAL, BASIC), dann hast du bereits viele der Faehigkeiten, die
+     noetig sind um effektiv in LPC zu Programmieren. Die Hauptfaehigkeit,
+     die du brauchen wirst, ist die Begabung deine Ideen in eine Reihe von
+     Schritten zu unterteilen, so dass der Computer diese fuer dich
+     ausfuehren kann.
+
+     LPC ist aber auch eine (imperative, strukturierte) objektorientierte
+     Sprache. OOP haelt dazu an, sich zuerst um die Daten zu kuemmern und
+     dann um die Methoden mit denen diese Daten manipuliert werden:
+     Ein Spieler ist zuerst einmal ein Haufen von Attributen und Punkten
+     und seinem Namen, wie auf diese eingewirkt werden kann wird danach
+     geklaert. Ein Spielerobjekt kommuniziert und kooperiert mit vielen
+     anderen Objekten hier.
+
+     Im Folgenden sind einige der Kriterien objektorientierter Programmierung
+     aufgefuehrt:
+
+     Klassen:
+	Eine Klasse beschreibt das Verhalten einer Gruppe gleichartiger
+	Objekte. Beispielsweise kann man Lebewesen als eine Klasse ansehen,
+	weil man alle Objekte in Lebewesen und nicht-Lebewesen einteilen
+	kann. Hat man einen konkretes Monster und einen konkreten Spieler in
+	einem Raum, dann sind dies Objekte (Instanzen). Man kann von einer
+	Menge gleichartiger Objekte sagen, dass sie zu ein- und derselben
+	Klasse gehoeren. 
+
+     Abstraktion:
+	Jedes Objekt im System verkoerpert als abstraktes Modell einen
+	"Arbeiter", der Auftraege erledigen kann, seinen Zustand berichten
+	und aendern kann und mit den anderen Objekten im System kommunizieren
+	kann, ohne offen zu legen, wie diese seine Faehigkeiten implementiert
+	sind.
+	[So kann man einem Objekt den Auftrag Defend(1000, DT_FIRE, ...)
+	 geben. In MG werden lebende Objekte diesen Auftrag durch Aenderung
+	 ihres Zustandes - LP-Abzug oder Magiereaktion - erfuellen.]
+
+     Kapselung
+	Auch das "Verbergen von Information" genannt, sorgt K. dafuer, dass
+	Objekte den internen Zustand anderer Objekte nicht in unerwarteter
+	Weise aendern koennen; nur den eigenen Methoden eines Objektes soll
+	es erlaubt sein, auf den internen Zustand direkt zuzugreifen. Alle
+	Sorten von Objekten praesentieren nach aussen Schnittstellen (man
+	properties), die darueber bestimmen, wie andere Objekte mit ihnen
+	wechselwirken koennen.
+	[Siehe vor allem man properties]
+	
+     Polymorphie
+	Zeiger zu Objekten koennen es mit sich bringen, dass bei der Auswahl
+	eines konkreten Objektes seine Klasse (sein Typ) nicht offensichtlich
+	ist. Trotzdem werden Nachrichten an so selektierte Objekte korrekt
+	der tatsaechlichen Klasse zugeordnet. Wenn diese Zuordnung erst zur
+	Laufzeit aufgeloest wird, dann wird dieses Verhalten Polymorphismus
+	(auch: spaete Bindung oder dynamische Bindung) genannt.
+	[In LPC ist dynamische Bindung der Standard. Ueberschreibt man also
+	 in einem NPC die(), dann wird auf jeden Fall die neue Methode
+	 aufgerufen, wenn der NPC aus do_damage() heraus in sich die() ruft.]
+
+     Vererbung
+	Organisiert und erleichtert Polymorphie, indem neue Objekte definiert
+	und erzeugt werden koennen, die Spezialisierungen schon existierender
+	Objekte sind. Solche neuen Objekte koennen das vorhandene Verhalten
+	uebernehmen und erweitern, ohne dass dieses Urverhalten neu
+	implementiert werden muss. Typischerweise wird das dadurch erreicht,
+	dass Objekte zu Klassen und zu Hierarchien von Klassen gruppiert
+	werden, in denen sich die Gemeinsamkeiten im Verhalten ausdruecken.
+	[Siehe man vererbung]
+
+ SIEHE AUCH:
+     objekte, inheritance, goodstyle
+
+ 22. Maerz 2004 Gloinson
diff --git a/doc/concepts/overloading b/doc/concepts/overloading
new file mode 100644
index 0000000..06209e9
--- /dev/null
+++ b/doc/concepts/overloading
@@ -0,0 +1,48 @@
+CONCEPT
+        overloading
+
+DESCRIPTION
+        This concept is strongly connected with the concept of inheritance.
+        A function is called 'overloaded' if it is defined more than once
+        in an object. This can happen if the object inherits other objects
+        which have defined a function with the same name.
+        Usually the overloading is wanted and intended by the inheriting
+        object to change the behaviour of the function it overloads.
+        To call the overloaded functions from the overloading object the
+        ::-operator is used.
+        From outside the object only one of the functions can be called
+        via call_other() or the like; this will be the topmost of all
+        overloaded functions.
+
+        Normally an overloading function is declared the same way as the
+        overloaded function, this means it has the same number and types
+        of arguments. If an object wants to change the behaviour of the
+        function in a way that it can get more arguments than the original
+        function, it has to use the modifier 'varargs' or a compiler error
+        will be raised.
+
+EXAMPLE
+        File /players/alfe/a.c:
+
+            foo() { write("A"); }
+
+        File /players/alfe/b.c:
+
+            foo() { write("B"); }
+
+        File /players/alfe/c.c:
+
+            inherit "players/alfe/a";
+            inherit "players/alfe/b";
+
+            foo() {
+              a::foo();
+	      b::foo();
+	      write("C");
+	    }
+
+	To call "players/alfe/c"->foo() will now result in the output of
+	ABC.
+
+SEE ALSO
+        modifiers(LPC), inheritance(C), functions(LPC)
diff --git a/doc/concepts/pcre b/doc/concepts/pcre
new file mode 100644
index 0000000..f863ffd
--- /dev/null
+++ b/doc/concepts/pcre
@@ -0,0 +1,1422 @@
+SYNOPSIS
+        PCRE - Perl-compatible regular expressions
+
+
+DESCRIPTION
+        This document describes the regular expressions supported by the
+        PCRE package. When the package is compiled into the driver, the
+        macro __PCRE__ is defined.
+
+        Most of this manpage is lifted directly from the original PCRE
+        manpage (dated January 2003).
+
+        The PCRE library is a set of functions that implement  regular
+        expression  pattern  matching using the same syntax and semantics
+        as Perl  5,  with  just  a  few  differences  (see below).  The
+        current  implementation  corresponds  to  Perl 5.005, with some
+        additional features  from  later  versions.  This  includes  some
+        experimental,  incomplete  support for UTF-8 encoded strings.
+        Details of exactly what is  and  what is not supported are given
+        below.
+
+
+PCRE REGULAR EXPRESSION DETAILS
+
+       The  syntax  and semantics of the regular expressions supported by PCRE
+       are described below. Regular expressions are also described in the Perl
+       documentation  and in a number of other books, some of which have copi-
+       ous examples. Jeffrey Friedl's "Mastering  Regular  Expressions",  pub-
+       lished  by  O'Reilly, covers them in great detail. The description here
+       is intended as reference documentation.
+
+       The basic operation of PCRE is on strings of bytes. However,  there  is
+       also  support for UTF-8 character strings. To use this support you must
+       build PCRE to include UTF-8 support, and then call pcre_compile()  with
+       the  PCRE_UTF8  option.  How  this affects the pattern matching is men-
+       tioned in several places below. There is also a summary of  UTF-8  fea-
+       tures in the section on UTF-8 support in the main pcre page.
+
+       A  regular  expression  is  a pattern that is matched against a subject
+       string from left to right. Most characters stand for  themselves  in  a
+       pattern,  and  match  the corresponding characters in the subject. As a
+       trivial example, the pattern
+
+         The quick brown fox
+
+       matches a portion of a subject string that is identical to itself.  The
+       power of regular expressions comes from the ability to include alterna-
+       tives and repetitions in the pattern. These are encoded in the  pattern
+       by  the  use  of meta-characters, which do not stand for themselves but
+       instead are interpreted in some special way.
+
+       There are two different sets of meta-characters: those that are  recog-
+       nized  anywhere in the pattern except within square brackets, and those
+       that are recognized in square brackets. Outside  square  brackets,  the
+       meta-characters are as follows:
+
+         \      general escape character with several uses
+         ^      assert start of string (or line, in multiline mode)
+         $      assert end of string (or line, in multiline mode)
+         .      match any character except newline (by default)
+         [      start character class definition
+         |      start of alternative branch
+         (      start subpattern
+         )      end subpattern
+         ?      extends the meaning of (
+                also 0 or 1 quantifier
+                also quantifier minimizer
+         *      0 or more quantifier
+         +      1 or more quantifier
+                also "possessive quantifier"
+         {      start min/max quantifier
+
+       Part  of  a  pattern  that is in square brackets is called a "character
+       class". In a character class the only meta-characters are:
+
+         \      general escape character
+         ^      negate the class, but only if the first character
+         -      indicates character range
+         [      POSIX character class (only if followed by POSIX
+                  syntax)
+         ]      terminates the character class
+
+       The following sections describe the use of each of the meta-characters.
+
+
+BACKSLASH
+
+       The backslash character has several uses. Firstly, if it is followed by
+       a non-alphameric character, it takes  away  any  special  meaning  that
+       character  may  have.  This  use  of  backslash  as an escape character
+       applies both inside and outside character classes.
+
+       For example, if you want to match a * character, you write  \*  in  the
+       pattern.   This  escaping  action  applies whether or not the following
+       character would otherwise be interpreted as a meta-character, so it  is
+       always  safe to precede a non-alphameric with backslash to specify that
+       it stands for itself. In particular, if you want to match a  backslash,
+       you write \\.
+
+       If  a  pattern is compiled with the PCRE_EXTENDED option, whitespace in
+       the pattern (other than in a character class) and characters between  a
+       # outside a character class and the next newline character are ignored.
+       An escaping backslash can be used to include a whitespace or #  charac-
+       ter as part of the pattern.
+
+       If  you  want  to remove the special meaning from a sequence of charac-
+       ters, you can do so by putting them between \Q and \E. This is  differ-
+       ent  from  Perl  in  that  $  and  @ are handled as literals in \Q...\E
+       sequences in PCRE, whereas in Perl, $ and @ cause  variable  interpola-
+       tion. Note the following examples:
+
+         Pattern            PCRE matches   Perl matches
+
+         \Qabc$xyz\E        abc$xyz        abc followed by the
+                                             contents of $xyz
+         \Qabc\$xyz\E       abc\$xyz       abc\$xyz
+         \Qabc\E\$\Qxyz\E   abc$xyz        abc$xyz
+
+       The  \Q...\E  sequence  is recognized both inside and outside character
+       classes.
+
+       A second use of backslash provides a way of encoding non-printing char-
+       acters  in patterns in a visible manner. There is no restriction on the
+       appearance of non-printing characters, apart from the binary zero  that
+       terminates  a  pattern,  but  when  a pattern is being prepared by text
+       editing, it is usually easier  to  use  one  of  the  following  escape
+       sequences than the binary character it represents:
+
+         \a        alarm, that is, the BEL character (hex 07)
+         \cx       "control-x", where x is any character
+         \e        escape (hex 1B)
+         \f        formfeed (hex 0C)
+         \n        newline (hex 0A)
+         \r        carriage return (hex 0D)
+         \t        tab (hex 09)
+         \ddd      character with octal code ddd, or backreference
+         \xhh      character with hex code hh
+         \x{hhh..} character with hex code hhh... (UTF-8 mode only)
+
+       The  precise  effect of \cx is as follows: if x is a lower case letter,
+       it is converted to upper case. Then bit 6 of the character (hex 40)  is
+       inverted.   Thus  \cz becomes hex 1A, but \c{ becomes hex 3B, while \c;
+       becomes hex 7B.
+
+       After \x, from zero to two hexadecimal digits are read (letters can  be
+       in  upper or lower case). In UTF-8 mode, any number of hexadecimal dig-
+       its may appear between \x{ and }, but the value of the  character  code
+       must  be  less  than  2**31  (that is, the maximum hexadecimal value is
+       7FFFFFFF). If characters other than hexadecimal digits  appear  between
+       \x{  and }, or if there is no terminating }, this form of escape is not
+       recognized. Instead, the initial \x will be interpreted as a basic hex-
+       adecimal escape, with no following digits, giving a byte whose value is
+       zero.
+
+       Characters whose value is less than 256 can be defined by either of the
+       two  syntaxes for \x when PCRE is in UTF-8 mode. There is no difference
+       in the way they are handled. For example, \xdc is exactly the  same  as
+       \x{dc}.
+
+       After  \0  up  to  two further octal digits are read. In both cases, if
+       there are fewer than two digits, just those that are present are  used.
+       Thus  the sequence \0\x\07 specifies two binary zeros followed by a BEL
+       character (code value 7). Make sure you supply  two  digits  after  the
+       initial zero if the character that follows is itself an octal digit.
+
+       The handling of a backslash followed by a digit other than 0 is compli-
+       cated.  Outside a character class, PCRE reads it and any following dig-
+       its  as  a  decimal  number. If the number is less than 10, or if there
+       have been at least that many previous capturing left parentheses in the
+       expression,  the  entire  sequence  is  taken  as  a  back reference. A
+       description of how this works is given later, following the  discussion
+       of parenthesized subpatterns.
+
+       Inside  a  character  class, or if the decimal number is greater than 9
+       and there have not been that many capturing subpatterns, PCRE  re-reads
+       up  to three octal digits following the backslash, and generates a sin-
+       gle byte from the least significant 8 bits of the value. Any subsequent
+       digits stand for themselves.  For example:
+
+         \040   is another way of writing a space
+         \40    is the same, provided there are fewer than 40
+                   previous capturing subpatterns
+         \7     is always a back reference
+         \11    might be a back reference, or another way of
+                   writing a tab
+         \011   is always a tab
+         \0113  is a tab followed by the character "3"
+         \113   might be a back reference, otherwise the
+                   character with octal code 113
+         \377   might be a back reference, otherwise
+                   the byte consisting entirely of 1 bits
+         \81    is either a back reference, or a binary zero
+                   followed by the two characters "8" and "1"
+
+       Note  that  octal  values of 100 or greater must not be introduced by a
+       leading zero, because no more than three octal digits are ever read.
+
+       All the sequences that define a single byte value  or  a  single  UTF-8
+       character (in UTF-8 mode) can be used both inside and outside character
+       classes. In addition, inside a character  class,  the  sequence  \b  is
+       interpreted  as  the  backspace character (hex 08). Outside a character
+       class it has a different meaning (see below).
+
+       The third use of backslash is for specifying generic character types:
+
+         \d     any decimal digit
+         \D     any character that is not a decimal digit
+         \s     any whitespace character
+         \S     any character that is not a whitespace character
+         \w     any "word" character
+         \W     any "non-word" character
+
+       Each pair of escape sequences partitions the complete set of characters
+       into  two disjoint sets. Any given character matches one, and only one,
+       of each pair.
+
+       In UTF-8 mode, characters with values greater than 255 never match  \d,
+       \s, or \w, and always match \D, \S, and \W.
+
+       For  compatibility  with Perl, \s does not match the VT character (code
+       11).  This makes it different from the the POSIX "space" class. The  \s
+       characters are HT (9), LF (10), FF (12), CR (13), and space (32).
+
+       A  "word" character is any letter or digit or the underscore character,
+       that is, any character which can be part of a Perl "word". The  defini-
+       tion  of  letters  and digits is controlled by PCRE's character tables,
+       and may vary if locale- specific matching is taking place (see  "Locale
+       support"  in  the  pcreapi  page).  For  example,  in the "fr" (French)
+       locale, some character codes greater than 128  are  used  for  accented
+       letters, and these are matched by \w.
+
+       These character type sequences can appear both inside and outside char-
+       acter classes. They each match one character of the  appropriate  type.
+       If  the current matching point is at the end of the subject string, all
+       of them fail, since there is no character to match.
+
+       The fourth use of backslash is for certain simple assertions. An asser-
+       tion  specifies a condition that has to be met at a particular point in
+       a match, without consuming any characters from the subject string.  The
+       use  of subpatterns for more complicated assertions is described below.
+       The backslashed assertions are
+
+         \b     matches at a word boundary
+         \B     matches when not at a word boundary
+         \A     matches at start of subject
+         \Z     matches at end of subject or before newline at end
+         \z     matches at end of subject
+         \G     matches at first matching position in subject
+
+       These assertions may not appear in character classes (but note that  \b
+       has a different meaning, namely the backspace character, inside a char-
+       acter class).
+
+       A word boundary is a position in the subject string where  the  current
+       character  and  the previous character do not both match \w or \W (i.e.
+       one matches \w and the other matches \W), or the start or  end  of  the
+       string if the first or last character matches \w, respectively.
+
+       The  \A,  \Z,  and \z assertions differ from the traditional circumflex
+       and dollar (described below) in that they only ever match at  the  very
+       start  and  end  of the subject string, whatever options are set. Thus,
+       they are independent of multiline mode.
+
+       They are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options. If the
+       startoffset argument of pcre_exec() is non-zero, indicating that match-
+       ing is to start at a point other than the beginning of the subject,  \A
+       can  never  match.  The difference between \Z and \z is that \Z matches
+       before a newline that is the last character of the string as well as at
+       the end of the string, whereas \z matches only at the end.
+
+       The  \G assertion is true only when the current matching position is at
+       the start point of the match, as specified by the startoffset  argument
+       of  pcre_exec().  It  differs  from \A when the value of startoffset is
+       non-zero. By calling pcre_exec() multiple times with appropriate  argu-
+       ments, you can mimic Perl's /g option, and it is in this kind of imple-
+       mentation where \G can be useful.
+
+       Note, however, that PCRE's interpretation of \G, as the  start  of  the
+       current match, is subtly different from Perl's, which defines it as the
+       end of the previous match. In Perl, these can  be  different  when  the
+       previously  matched  string was empty. Because PCRE does just one match
+       at a time, it cannot reproduce this behaviour.
+
+       If all the alternatives of a pattern begin with \G, the  expression  is
+       anchored to the starting match position, and the "anchored" flag is set
+       in the compiled regular expression.
+
+
+CIRCUMFLEX AND DOLLAR
+
+       Outside a character class, in the default matching mode, the circumflex
+       character  is  an  assertion which is true only if the current matching
+       point is at the start of the subject string. If the  startoffset  argu-
+       ment  of  pcre_exec()  is  non-zero,  circumflex can never match if the
+       PCRE_MULTILINE option is unset. Inside a  character  class,  circumflex
+       has an entirely different meaning (see below).
+
+       Circumflex  need  not be the first character of the pattern if a number
+       of alternatives are involved, but it should be the first thing in  each
+       alternative  in  which  it appears if the pattern is ever to match that
+       branch. If all possible alternatives start with a circumflex, that  is,
+       if  the  pattern  is constrained to match only at the start of the sub-
+       ject, it is said to be an "anchored" pattern.  (There  are  also  other
+       constructs that can cause a pattern to be anchored.)
+
+       A  dollar  character  is an assertion which is true only if the current
+       matching point is at the end of  the  subject  string,  or  immediately
+       before a newline character that is the last character in the string (by
+       default). Dollar need not be the last character of  the  pattern  if  a
+       number  of alternatives are involved, but it should be the last item in
+       any branch in which it appears.  Dollar has no  special  meaning  in  a
+       character class.
+
+       The  meaning  of  dollar  can be changed so that it matches only at the
+       very end of the string, by setting the  PCRE_DOLLAR_ENDONLY  option  at
+       compile time. This does not affect the \Z assertion.
+
+       The meanings of the circumflex and dollar characters are changed if the
+       PCRE_MULTILINE option is set. When this is the case, they match immedi-
+       ately  after  and  immediately  before  an  internal newline character,
+       respectively, in addition to matching at the start and end of the  sub-
+       ject  string.  For  example,  the  pattern  /^abc$/ matches the subject
+       string "def\nabc" in multiline mode, but not  otherwise.  Consequently,
+       patterns  that  are  anchored  in single line mode because all branches
+       start with ^ are not anchored in multiline mode, and a match  for  cir-
+       cumflex  is  possible  when  the startoffset argument of pcre_exec() is
+       non-zero. The PCRE_DOLLAR_ENDONLY option is ignored  if  PCRE_MULTILINE
+       is set.
+
+       Note  that  the sequences \A, \Z, and \z can be used to match the start
+       and end of the subject in both modes, and if all branches of a  pattern
+       start  with  \A it is always anchored, whether PCRE_MULTILINE is set or
+       not.
+
+
+FULL STOP (PERIOD, DOT)
+
+       Outside a character class, a dot in the pattern matches any one charac-
+       ter  in  the  subject,  including a non-printing character, but not (by
+       default) newline.  In UTF-8 mode, a dot matches  any  UTF-8  character,
+       which  might  be  more than one byte long, except (by default) for new-
+       line. If the PCRE_DOTALL option is set, dots match  newlines  as  well.
+       The  handling of dot is entirely independent of the handling of circum-
+       flex and dollar, the only relationship being  that  they  both  involve
+       newline characters. Dot has no special meaning in a character class.
+
+
+MATCHING A SINGLE BYTE
+
+       Outside a character class, the escape sequence \C matches any one byte,
+       both in and out of UTF-8 mode. Unlike a dot, it always matches  a  new-
+       line.  The  feature  is  provided  in Perl in order to match individual
+       bytes in UTF-8 mode.  Because it breaks up UTF-8 characters into  indi-
+       vidual  bytes,  what  remains  in  the  string may be a malformed UTF-8
+       string. For this reason it is best avoided.
+
+       PCRE does not allow \C to appear in lookbehind assertions (see  below),
+       because in UTF-8 mode it makes it impossible to calculate the length of
+       the lookbehind.
+
+
+SQUARE BRACKETS
+
+       An opening square bracket introduces a character class, terminated by a
+       closing square bracket. A closing square bracket on its own is not spe-
+       cial. If a closing square bracket is required as a member of the class,
+       it  should  be  the first data character in the class (after an initial
+       circumflex, if present) or escaped with a backslash.
+
+       A character class matches a single character in the subject.  In  UTF-8
+       mode,  the character may occupy more than one byte. A matched character
+       must be in the set of characters defined by the class, unless the first
+       character  in  the  class definition is a circumflex, in which case the
+       subject character must not be in the set defined by  the  class.  If  a
+       circumflex  is actually required as a member of the class, ensure it is
+       not the first character, or escape it with a backslash.
+
+       For example, the character class [aeiou] matches any lower case  vowel,
+       while  [^aeiou]  matches  any character that is not a lower case vowel.
+       Note that a circumflex is just a convenient notation for specifying the
+       characters which are in the class by enumerating those that are not. It
+       is not an assertion: it still consumes a  character  from  the  subject
+       string, and fails if the current pointer is at the end of the string.
+
+       In  UTF-8 mode, characters with values greater than 255 can be included
+       in a class as a literal string of bytes, or by using the  \x{  escaping
+       mechanism.
+
+       When  caseless  matching  is set, any letters in a class represent both
+       their upper case and lower case versions, so for  example,  a  caseless
+       [aeiou]  matches  "A"  as well as "a", and a caseless [^aeiou] does not
+       match "A", whereas a caseful version would. PCRE does not  support  the
+       concept of case for characters with values greater than 255.
+
+       The  newline character is never treated in any special way in character
+       classes, whatever the setting  of  the  PCRE_DOTALL  or  PCRE_MULTILINE
+       options is. A class such as [^a] will always match a newline.
+
+       The  minus (hyphen) character can be used to specify a range of charac-
+       ters in a character  class.  For  example,  [d-m]  matches  any  letter
+       between  d  and  m,  inclusive.  If  a minus character is required in a
+       class, it must be escaped with a backslash  or  appear  in  a  position
+       where  it cannot be interpreted as indicating a range, typically as the
+       first or last character in the class.
+
+       It is not possible to have the literal character "]" as the end charac-
+       ter  of a range. A pattern such as [W-]46] is interpreted as a class of
+       two characters ("W" and "-") followed by a literal string "46]", so  it
+       would  match  "W46]"  or  "-46]". However, if the "]" is escaped with a
+       backslash it is interpreted as the end of range, so [W-\]46] is  inter-
+       preted  as  a  single class containing a range followed by two separate
+       characters. The octal or hexadecimal representation of "]" can also  be
+       used to end a range.
+
+       Ranges  operate in the collating sequence of character values. They can
+       also  be  used  for  characters  specified  numerically,  for   example
+       [\000-\037].  In UTF-8 mode, ranges can include characters whose values
+       are greater than 255, for example [\x{100}-\x{2ff}].
+
+       If a range that includes letters is used when caseless matching is set,
+       it matches the letters in either case. For example, [W-c] is equivalent
+       to [][\^_`wxyzabc], matched caselessly, and if character tables for the
+       "fr"  locale  are  in use, [\xc8-\xcb] matches accented E characters in
+       both cases.
+
+       The character types \d, \D, \s, \S, \w, and \W may  also  appear  in  a
+       character  class,  and add the characters that they match to the class.
+       For example, [\dABCDEF] matches any hexadecimal digit. A circumflex can
+       conveniently  be  used with the upper case character types to specify a
+       more restricted set of characters than the matching  lower  case  type.
+       For  example,  the  class  [^\W_]  matches any letter or digit, but not
+       underscore.
+
+       All non-alphameric characters other than \, -, ^ (at the start) and the
+       terminating ] are non-special in character classes, but it does no harm
+       if they are escaped.
+
+
+POSIX CHARACTER CLASSES
+
+       Perl supports the POSIX notation  for  character  classes,  which  uses
+       names  enclosed by [: and :] within the enclosing square brackets. PCRE
+       also supports this notation. For example,
+
+         [01[:alpha:]%]
+
+       matches "0", "1", any alphabetic character, or "%". The supported class
+       names are
+
+         alnum    letters and digits
+         alpha    letters
+         ascii    character codes 0 - 127
+         blank    space or tab only
+         cntrl    control characters
+         digit    decimal digits (same as \d)
+         graph    printing characters, excluding space
+         lower    lower case letters
+         print    printing characters, including space
+         punct    printing characters, excluding letters and digits
+         space    white space (not quite the same as \s)
+         upper    upper case letters
+         word     "word" characters (same as \w)
+         xdigit   hexadecimal digits
+
+       The  "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13),
+       and space (32). Notice that this list includes the VT  character  (code
+       11). This makes "space" different to \s, which does not include VT (for
+       Perl compatibility).
+
+       The name "word" is a Perl extension, and "blank"  is  a  GNU  extension
+       from  Perl  5.8. Another Perl extension is negation, which is indicated
+       by a ^ character after the colon. For example,
+
+         [12[:^digit:]]
+
+       matches "1", "2", or any non-digit. PCRE (and Perl) also recognize  the
+       POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but
+       these are not supported, and an error is given if they are encountered.
+
+       In UTF-8 mode, characters with values greater than 255 do not match any
+       of the POSIX character classes.
+
+
+VERTICAL BAR
+
+       Vertical bar characters are used to separate alternative patterns.  For
+       example, the pattern
+
+         gilbert|sullivan
+
+       matches  either "gilbert" or "sullivan". Any number of alternatives may
+       appear, and an empty  alternative  is  permitted  (matching  the  empty
+       string).   The  matching  process  tries each alternative in turn, from
+       left to right, and the first one that succeeds is used. If the alterna-
+       tives  are within a subpattern (defined below), "succeeds" means match-
+       ing the rest of the main pattern as well as the alternative in the sub-
+       pattern.
+
+
+INTERNAL OPTION SETTING
+
+       The  settings  of  the  PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and
+       PCRE_EXTENDED options can be changed  from  within  the  pattern  by  a
+       sequence  of  Perl  option  letters  enclosed between "(?" and ")". The
+       option letters are
+
+         i  for PCRE_CASELESS
+         m  for PCRE_MULTILINE
+         s  for PCRE_DOTALL
+         x  for PCRE_EXTENDED
+
+       For example, (?im) sets caseless, multiline matching. It is also possi-
+       ble to unset these options by preceding the letter with a hyphen, and a
+       combined setting and unsetting such as (?im-sx), which sets  PCRE_CASE-
+       LESS  and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED,
+       is also permitted. If a  letter  appears  both  before  and  after  the
+       hyphen, the option is unset.
+
+       When  an option change occurs at top level (that is, not inside subpat-
+       tern parentheses), the change applies to the remainder of  the  pattern
+       that follows.  If the change is placed right at the start of a pattern,
+       PCRE extracts it into the global options (and it will therefore show up
+       in data extracted by the pcre_fullinfo() function).
+
+       An option change within a subpattern affects only that part of the cur-
+       rent pattern that follows it, so
+
+         (a(?i)b)c
+
+       matches abc and aBc and no other strings (assuming PCRE_CASELESS is not
+       used).   By  this means, options can be made to have different settings
+       in different parts of the pattern. Any changes made in one  alternative
+       do  carry  on  into subsequent branches within the same subpattern. For
+       example,
+
+         (a(?i)b|c)
+
+       matches "ab", "aB", "c", and "C", even though  when  matching  "C"  the
+       first  branch  is  abandoned before the option setting. This is because
+       the effects of option settings happen at compile time. There  would  be
+       some very weird behaviour otherwise.
+
+       The  PCRE-specific  options PCRE_UNGREEDY and PCRE_EXTRA can be changed
+       in the same way as the Perl-compatible options by using the  characters
+       U  and X respectively. The (?X) flag setting is special in that it must
+       always occur earlier in the pattern than any of the additional features
+       it turns on, even when it is at top level. It is best put at the start.
+
+
+SUBPATTERNS
+
+       Subpatterns are delimited by parentheses (round brackets), which can be
+       nested.  Marking part of a pattern as a subpattern does two things:
+
+       1. It localizes a set of alternatives. For example, the pattern
+
+         cat(aract|erpillar|)
+
+       matches  one  of the words "cat", "cataract", or "caterpillar". Without
+       the parentheses, it would match "cataract",  "erpillar"  or  the  empty
+       string.
+
+       2.  It  sets  up  the  subpattern as a capturing subpattern (as defined
+       above).  When the whole pattern matches, that portion  of  the  subject
+       string that matched the subpattern is passed back to the caller via the
+       ovector argument of pcre_exec(). Opening parentheses are  counted  from
+       left  to right (starting from 1) to obtain the numbers of the capturing
+       subpatterns.
+
+       For example, if the string "the red king" is matched against  the  pat-
+       tern
+
+         the ((red|white) (king|queen))
+
+       the captured substrings are "red king", "red", and "king", and are num-
+       bered 1, 2, and 3, respectively.
+
+       The fact that plain parentheses fulfil  two  functions  is  not  always
+       helpful.   There are often times when a grouping subpattern is required
+       without a capturing requirement. If an opening parenthesis is  followed
+       by  a question mark and a colon, the subpattern does not do any captur-
+       ing, and is not counted when computing the  number  of  any  subsequent
+       capturing  subpatterns. For example, if the string "the white queen" is
+       matched against the pattern
+
+         the ((?:red|white) (king|queen))
+
+       the captured substrings are "white queen" and "queen", and are numbered
+       1  and 2. The maximum number of capturing subpatterns is 65535, and the
+       maximum depth of nesting of all subpatterns, both  capturing  and  non-
+       capturing, is 200.
+
+       As  a  convenient shorthand, if any option settings are required at the
+       start of a non-capturing subpattern,  the  option  letters  may  appear
+       between the "?" and the ":". Thus the two patterns
+
+         (?i:saturday|sunday)
+         (?:(?i)saturday|sunday)
+
+       match exactly the same set of strings. Because alternative branches are
+       tried from left to right, and options are not reset until  the  end  of
+       the  subpattern is reached, an option setting in one branch does affect
+       subsequent branches, so the above patterns match "SUNDAY"  as  well  as
+       "Saturday".
+
+
+NAMED SUBPATTERNS
+
+       Identifying  capturing  parentheses  by number is simple, but it can be
+       very hard to keep track of the numbers in complicated  regular  expres-
+       sions.  Furthermore,  if  an  expression  is  modified, the numbers may
+       change. To help with the difficulty, PCRE supports the naming  of  sub-
+       patterns,  something  that  Perl  does  not  provide. The Python syntax
+       (?P<name>...) is used. Names consist  of  alphanumeric  characters  and
+       underscores, and must be unique within a pattern.
+
+       Named  capturing  parentheses  are  still  allocated numbers as well as
+       names. The PCRE API provides function calls for extracting the name-to-
+       number  translation  table from a compiled pattern. For further details
+       see the pcreapi documentation.
+
+
+REPETITION
+
+       Repetition is specified by quantifiers, which can  follow  any  of  the
+       following items:
+
+         a literal data character
+         the . metacharacter
+         the \C escape sequence
+         escapes such as \d that match single characters
+         a character class
+         a back reference (see next section)
+         a parenthesized subpattern (unless it is an assertion)
+
+       The  general repetition quantifier specifies a minimum and maximum num-
+       ber of permitted matches, by giving the two numbers in  curly  brackets
+       (braces),  separated  by  a comma. The numbers must be less than 65536,
+       and the first must be less than or equal to the second. For example:
+
+         z{2,4}
+
+       matches "zz", "zzz", or "zzzz". A closing brace on its  own  is  not  a
+       special  character.  If  the second number is omitted, but the comma is
+       present, there is no upper limit; if the second number  and  the  comma
+       are  both omitted, the quantifier specifies an exact number of required
+       matches. Thus
+
+         [aeiou]{3,}
+
+       matches at least 3 successive vowels, but may match many more, while
+
+         \d{8}
+
+       matches exactly 8 digits. An opening curly bracket that  appears  in  a
+       position  where a quantifier is not allowed, or one that does not match
+       the syntax of a quantifier, is taken as a literal character. For  exam-
+       ple, {,6} is not a quantifier, but a literal string of four characters.
+
+       In UTF-8 mode, quantifiers apply to UTF-8  characters  rather  than  to
+       individual bytes. Thus, for example, \x{100}{2} matches two UTF-8 char-
+       acters, each of which is represented by a two-byte sequence.
+
+       The quantifier {0} is permitted, causing the expression to behave as if
+       the previous item and the quantifier were not present.
+
+       For  convenience  (and  historical compatibility) the three most common
+       quantifiers have single-character abbreviations:
+
+         *    is equivalent to {0,}
+         +    is equivalent to {1,}
+         ?    is equivalent to {0,1}
+
+       It is possible to construct infinite loops by  following  a  subpattern
+       that can match no characters with a quantifier that has no upper limit,
+       for example:
+
+         (a?)*
+
+       Earlier versions of Perl and PCRE used to give an error at compile time
+       for  such  patterns. However, because there are cases where this can be
+       useful, such patterns are now accepted, but if any  repetition  of  the
+       subpattern  does in fact match no characters, the loop is forcibly bro-
+       ken.
+
+       By default, the quantifiers are "greedy", that is, they match  as  much
+       as  possible  (up  to  the  maximum number of permitted times), without
+       causing the rest of the pattern to fail. The classic example  of  where
+       this gives problems is in trying to match comments in C programs. These
+       appear between the sequences /* and */ and within the  sequence,  indi-
+       vidual * and / characters may appear. An attempt to match C comments by
+       applying the pattern
+
+         /\*.*\*/
+
+       to the string
+
+         /* first command */  not comment  /* second comment */
+
+       fails, because it matches the entire string owing to the greediness  of
+       the .*  item.
+
+       However,  if  a quantifier is followed by a question mark, it ceases to
+       be greedy, and instead matches the minimum number of times possible, so
+       the pattern
+
+         /\*.*?\*/
+
+       does  the  right  thing with the C comments. The meaning of the various
+       quantifiers is not otherwise changed,  just  the  preferred  number  of
+       matches.   Do  not  confuse this use of question mark with its use as a
+       quantifier in its own right. Because it has two uses, it can  sometimes
+       appear doubled, as in
+
+         \d??\d
+
+       which matches one digit by preference, but can match two if that is the
+       only way the rest of the pattern matches.
+
+       If the PCRE_UNGREEDY option is set (an option which is not available in
+       Perl),  the  quantifiers are not greedy by default, but individual ones
+       can be made greedy by following them with a  question  mark.  In  other
+       words, it inverts the default behaviour.
+
+       When  a  parenthesized  subpattern  is quantified with a minimum repeat
+       count that is greater than 1 or with a limited maximum, more  store  is
+       required  for  the  compiled  pattern, in proportion to the size of the
+       minimum or maximum.
+
+       If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equiv-
+       alent  to Perl's /s) is set, thus allowing the . to match newlines, the
+       pattern is implicitly anchored, because whatever follows will be  tried
+       against  every character position in the subject string, so there is no
+       point in retrying the overall match at any position  after  the  first.
+       PCRE normally treats such a pattern as though it were preceded by \A.
+
+       In  cases  where  it  is known that the subject string contains no new-
+       lines, it is worth setting PCRE_DOTALL in order to  obtain  this  opti-
+       mization, or alternatively using ^ to indicate anchoring explicitly.
+
+       However,  there is one situation where the optimization cannot be used.
+       When .*  is inside capturing parentheses that  are  the  subject  of  a
+       backreference  elsewhere in the pattern, a match at the start may fail,
+       and a later one succeed. Consider, for example:
+
+         (.*)abc\1
+
+       If the subject is "xyz123abc123" the match point is the fourth  charac-
+       ter. For this reason, such a pattern is not implicitly anchored.
+
+       When a capturing subpattern is repeated, the value captured is the sub-
+       string that matched the final iteration. For example, after
+
+         (tweedle[dume]{3}\s*)+
+
+       has matched "tweedledum tweedledee" the value of the captured substring
+       is  "tweedledee".  However,  if there are nested capturing subpatterns,
+       the corresponding captured values may have been set in previous  itera-
+       tions. For example, after
+
+         /(a|(b))+/
+
+       matches "aba" the value of the second captured substring is "b".
+
+
+ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
+
+       With both maximizing and minimizing repetition, failure of what follows
+       normally causes the repeated item to be re-evaluated to see if  a  dif-
+       ferent number of repeats allows the rest of the pattern to match. Some-
+       times it is useful to prevent this, either to change the nature of  the
+       match,  or  to  cause it fail earlier than it otherwise might, when the
+       author of the pattern knows there is no point in carrying on.
+
+       Consider, for example, the pattern \d+foo when applied to  the  subject
+       line
+
+         123456bar
+
+       After matching all 6 digits and then failing to match "foo", the normal
+       action of the matcher is to try again with only 5 digits  matching  the
+       \d+  item,  and  then  with  4,  and  so on, before ultimately failing.
+       "Atomic grouping" (a term taken from Jeffrey  Friedl's  book)  provides
+       the  means for specifying that once a subpattern has matched, it is not
+       to be re-evaluated in this way.
+
+       If we use atomic grouping for the previous example, the  matcher  would
+       give up immediately on failing to match "foo" the first time. The nota-
+       tion is a kind of special parenthesis, starting with  (?>  as  in  this
+       example:
+
+         (?>\d+)foo
+
+       This  kind  of  parenthesis "locks up" the  part of the pattern it con-
+       tains once it has matched, and a failure further into  the  pattern  is
+       prevented  from  backtracking into it. Backtracking past it to previous
+       items, however, works as normal.
+
+       An alternative description is that a subpattern of  this  type  matches
+       the  string  of  characters  that an identical standalone pattern would
+       match, if anchored at the current point in the subject string.
+
+       Atomic grouping subpatterns are not capturing subpatterns. Simple cases
+       such as the above example can be thought of as a maximizing repeat that
+       must swallow everything it can. So, while both \d+ and  \d+?  are  pre-
+       pared  to  adjust  the number of digits they match in order to make the
+       rest of the pattern match, (?>\d+) can only match an entire sequence of
+       digits.
+
+       Atomic  groups in general can of course contain arbitrarily complicated
+       subpatterns, and can be nested. However, when  the  subpattern  for  an
+       atomic group is just a single repeated item, as in the example above, a
+       simpler notation, called a "possessive quantifier" can  be  used.  This
+       consists  of  an  additional  + character following a quantifier. Using
+       this notation, the previous example can be rewritten as
+
+         \d++bar
+
+       Possessive  quantifiers  are  always  greedy;  the   setting   of   the
+       PCRE_UNGREEDY option is ignored. They are a convenient notation for the
+       simpler forms of atomic group. However, there is no difference  in  the
+       meaning  or  processing  of  a possessive quantifier and the equivalent
+       atomic group.
+
+       The possessive quantifier syntax is an extension to the Perl syntax. It
+       originates in Sun's Java package.
+
+       When  a  pattern  contains an unlimited repeat inside a subpattern that
+       can itself be repeated an unlimited number of  times,  the  use  of  an
+       atomic  group  is  the  only way to avoid some failing matches taking a
+       very long time indeed. The pattern
+
+         (\D+|<\d+>)*[!?]
+
+       matches an unlimited number of substrings that either consist  of  non-
+       digits,  or  digits  enclosed in <>, followed by either ! or ?. When it
+       matches, it runs quickly. However, if it is applied to
+
+         aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+       it takes a long time before reporting  failure.  This  is  because  the
+       string  can  be  divided  between  the two repeats in a large number of
+       ways, and all have to be tried. (The example used [!?]  rather  than  a
+       single  character  at the end, because both PCRE and Perl have an opti-
+       mization that allows for fast failure when a single character is  used.
+       They  remember  the last single character that is required for a match,
+       and fail early if it is not present in the string.)  If the pattern  is
+       changed to
+
+         ((?>\D+)|<\d+>)*[!?]
+
+       sequences  of non-digits cannot be broken, and failure happens quickly.
+
+
+BACK REFERENCES
+
+       Outside a character class, a backslash followed by a digit greater than
+       0 (and possibly further digits) is a back reference to a capturing sub-
+       pattern earlier (that is, to its left) in the pattern,  provided  there
+       have been that many previous capturing left parentheses.
+
+       However, if the decimal number following the backslash is less than 10,
+       it is always taken as a back reference, and causes  an  error  only  if
+       there  are  not that many capturing left parentheses in the entire pat-
+       tern. In other words, the parentheses that are referenced need  not  be
+       to  the left of the reference for numbers less than 10. See the section
+       entitled "Backslash" above for further details of the handling of  dig-
+       its following a backslash.
+
+       A  back  reference matches whatever actually matched the capturing sub-
+       pattern in the current subject string, rather  than  anything  matching
+       the subpattern itself (see "Subpatterns as subroutines" below for a way
+       of doing that). So the pattern
+
+         (sens|respons)e and \1ibility
+
+       matches "sense and sensibility" and "response and responsibility",  but
+       not  "sense and responsibility". If caseful matching is in force at the
+       time of the back reference, the case of letters is relevant. For  exam-
+       ple,
+
+         ((?i)rah)\s+\1
+
+       matches  "rah  rah"  and  "RAH RAH", but not "RAH rah", even though the
+       original capturing subpattern is matched caselessly.
+
+       Back references to named subpatterns use the Python  syntax  (?P=name).
+       We could rewrite the above example as follows:
+
+         (?<p1>(?i)rah)\s+(?P=p1)
+
+       There  may be more than one back reference to the same subpattern. If a
+       subpattern has not actually been used in a particular match,  any  back
+       references to it always fail. For example, the pattern
+
+         (a|(bc))\2
+
+       always  fails if it starts to match "a" rather than "bc". Because there
+       may be many capturing parentheses in a pattern,  all  digits  following
+       the  backslash  are taken as part of a potential back reference number.
+       If the pattern continues with a digit character, some delimiter must be
+       used  to  terminate  the back reference. If the PCRE_EXTENDED option is
+       set, this can be whitespace.  Otherwise an empty comment can be used.
+
+       A back reference that occurs inside the parentheses to which it  refers
+       fails  when  the subpattern is first used, so, for example, (a\1) never
+       matches.  However, such references can be useful inside  repeated  sub-
+       patterns. For example, the pattern
+
+         (a|b\1)+
+
+       matches any number of "a"s and also "aba", "ababbaa" etc. At each iter-
+       ation of the subpattern,  the  back  reference  matches  the  character
+       string  corresponding  to  the previous iteration. In order for this to
+       work, the pattern must be such that the first iteration does  not  need
+       to  match the back reference. This can be done using alternation, as in
+       the example above, or by a quantifier with a minimum of zero.
+
+
+ASSERTIONS
+
+       An assertion is a test on the characters  following  or  preceding  the
+       current  matching  point that does not actually consume any characters.
+       The simple assertions coded as \b, \B, \A, \G, \Z,  \z,  ^  and  $  are
+       described above.  More complicated assertions are coded as subpatterns.
+       There are two kinds: those that look ahead of the current  position  in
+       the subject string, and those that look behind it.
+
+       An  assertion  subpattern  is matched in the normal way, except that it
+       does not cause the current matching position to be  changed.  Lookahead
+       assertions  start with (?= for positive assertions and (?! for negative
+       assertions. For example,
+
+         \w+(?=;)
+
+       matches a word followed by a semicolon, but does not include the  semi-
+       colon in the match, and
+
+         foo(?!bar)
+
+       matches  any  occurrence  of  "foo" that is not followed by "bar". Note
+       that the apparently similar pattern
+
+         (?!foo)bar
+
+       does not find an occurrence of "bar"  that  is  preceded  by  something
+       other  than "foo"; it finds any occurrence of "bar" whatsoever, because
+       the assertion (?!foo) is always true when the next three characters are
+       "bar". A lookbehind assertion is needed to achieve this effect.
+
+       If you want to force a matching failure at some point in a pattern, the
+       most convenient way to do it is  with  (?!)  because  an  empty  string
+       always  matches, so an assertion that requires there not to be an empty
+       string must always fail.
+
+       Lookbehind assertions start with (?<= for positive assertions and  (?<!
+       for negative assertions. For example,
+
+         (?<!foo)bar
+
+       does  find  an  occurrence  of "bar" that is not preceded by "foo". The
+       contents of a lookbehind assertion are restricted  such  that  all  the
+       strings it matches must have a fixed length. However, if there are sev-
+       eral alternatives, they do not all have to have the same fixed  length.
+       Thus
+
+         (?<=bullock|donkey)
+
+       is permitted, but
+
+         (?<!dogs?|cats?)
+
+       causes  an  error at compile time. Branches that match different length
+       strings are permitted only at the top level of a lookbehind  assertion.
+       This  is  an  extension  compared  with  Perl (at least for 5.8), which
+       requires all branches to match the same length of string. An  assertion
+       such as
+
+         (?<=ab(c|de))
+
+       is  not  permitted,  because  its single top-level branch can match two
+       different lengths, but it is acceptable if rewritten to  use  two  top-
+       level branches:
+
+         (?<=abc|abde)
+
+       The  implementation  of lookbehind assertions is, for each alternative,
+       to temporarily move the current position back by the  fixed  width  and
+       then try to match. If there are insufficient characters before the cur-
+       rent position, the match is deemed to fail.
+
+       PCRE does not allow the \C escape (which matches a single byte in UTF-8
+       mode)  to appear in lookbehind assertions, because it makes it impossi-
+       ble to calculate the length of the lookbehind.
+
+       Atomic groups can be used in conjunction with lookbehind assertions  to
+       specify efficient matching at the end of the subject string. Consider a
+       simple pattern such as
+
+         abcd$
+
+       when applied to a long string that does  not  match.  Because  matching
+       proceeds from left to right, PCRE will look for each "a" in the subject
+       and then see if what follows matches the rest of the  pattern.  If  the
+       pattern is specified as
+
+         ^.*abcd$
+
+       the  initial .* matches the entire string at first, but when this fails
+       (because there is no following "a"), it backtracks to match all but the
+       last  character,  then all but the last two characters, and so on. Once
+       again the search for "a" covers the entire string, from right to  left,
+       so we are no better off. However, if the pattern is written as
+
+         ^(?>.*)(?<=abcd)
+
+       or, equivalently,
+
+         ^.*+(?<=abcd)
+
+       there  can  be  no  backtracking for the .* item; it can match only the
+       entire string. The subsequent lookbehind assertion does a  single  test
+       on  the last four characters. If it fails, the match fails immediately.
+       For long strings, this approach makes a significant difference  to  the
+       processing time.
+
+       Several assertions (of any sort) may occur in succession. For example,
+
+         (?<=\d{3})(?<!999)foo
+
+       matches  "foo" preceded by three digits that are not "999". Notice that
+       each of the assertions is applied independently at the  same  point  in
+       the  subject  string.  First  there  is a check that the previous three
+       characters are all digits, and then there is  a  check  that  the  same
+       three characters are not "999".  This pattern does not match "foo" pre-
+       ceded by six characters, the first of which are  digits  and  the  last
+       three  of  which  are not "999". For example, it doesn't match "123abc-
+       foo". A pattern to do that is
+
+         (?<=\d{3}...)(?<!999)foo
+
+       This time the first assertion looks at the  preceding  six  characters,
+       checking that the first three are digits, and then the second assertion
+       checks that the preceding three characters are not "999".
+
+       Assertions can be nested in any combination. For example,
+
+         (?<=(?<!foo)bar)baz
+
+       matches an occurrence of "baz" that is preceded by "bar" which in  turn
+       is not preceded by "foo", while
+
+         (?<=\d{3}(?!999)...)foo
+
+       is another pattern which matches "foo" preceded by three digits and any
+       three characters that are not "999".
+
+       Assertion subpatterns are not capturing subpatterns,  and  may  not  be
+       repeated,  because  it  makes no sense to assert the same thing several
+       times. If any kind of assertion contains capturing  subpatterns  within
+       it,  these are counted for the purposes of numbering the capturing sub-
+       patterns in the whole pattern.  However, substring capturing is carried
+       out  only  for  positive assertions, because it does not make sense for
+       negative assertions.
+
+
+CONDITIONAL SUBPATTERNS
+
+       It is possible to cause the matching process to obey a subpattern  con-
+       ditionally  or to choose between two alternative subpatterns, depending
+       on the  result  of  an  assertion,  or  whether  a  previous  capturing
+       subpattern  matched  or not. The two possible forms of conditional sub-
+       pattern are
+
+         (?(condition)yes-pattern)
+         (?(condition)yes-pattern|no-pattern)
+
+       If the condition is satisfied, the yes-pattern is used;  otherwise  the
+       no-pattern  (if  present)  is used. If there are more than two alterna-
+       tives in the subpattern, a compile-time error occurs.
+
+       There are three kinds of condition. If the text between the parentheses
+       consists  of  a  sequence  of digits, the condition is satisfied if the
+       capturing subpattern of that number has previously matched. The  number
+       must  be  greater than zero. Consider the following pattern, which con-
+       tains non-significant white space to make it more readable (assume  the
+       PCRE_EXTENDED  option)  and  to  divide it into three parts for ease of
+       discussion:
+
+         ( \( )?    [^()]+    (?(1) \) )
+
+       The first part matches an optional opening  parenthesis,  and  if  that
+       character is present, sets it as the first captured substring. The sec-
+       ond part matches one or more characters that are not  parentheses.  The
+       third part is a conditional subpattern that tests whether the first set
+       of parentheses matched or not. If they did, that is, if subject started
+       with an opening parenthesis, the condition is true, and so the yes-pat-
+       tern is executed and a  closing  parenthesis  is  required.  Otherwise,
+       since  no-pattern  is  not  present, the subpattern matches nothing. In
+       other words,  this  pattern  matches  a  sequence  of  non-parentheses,
+       optionally enclosed in parentheses.
+
+       If the condition is the string (R), it is satisfied if a recursive call
+       to the pattern or subpattern has been made. At "top level", the  condi-
+       tion  is  false.   This  is  a  PCRE  extension. Recursive patterns are
+       described in the next section.
+
+       If the condition is not a sequence of digits or  (R),  it  must  be  an
+       assertion.   This may be a positive or negative lookahead or lookbehind
+       assertion. Consider  this  pattern,  again  containing  non-significant
+       white space, and with the two alternatives on the second line:
+
+         (?(?=[^a-z]*[a-z])
+         \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
+
+       The  condition  is  a  positive  lookahead  assertion  that  matches an
+       optional sequence of non-letters followed by a letter. In other  words,
+       it  tests  for the presence of at least one letter in the subject. If a
+       letter is found, the subject is matched against the first  alternative;
+       otherwise  it  is  matched  against  the  second.  This pattern matches
+       strings in one of the two forms dd-aaa-dd or dd-dd-dd,  where  aaa  are
+       letters and dd are digits.
+
+
+COMMENTS
+
+       The sequence (?# marks the start of a comment which continues up to the
+       next closing parenthesis. Nested parentheses  are  not  permitted.  The
+       characters  that make up a comment play no part in the pattern matching
+       at all.
+
+       If the PCRE_EXTENDED option is set, an unescaped # character outside  a
+       character class introduces a comment that continues up to the next new-
+       line character in the pattern.
+
+
+RECURSIVE PATTERNS
+
+       Consider the problem of matching a string in parentheses, allowing  for
+       unlimited  nested  parentheses.  Without the use of recursion, the best
+       that can be done is to use a pattern that  matches  up  to  some  fixed
+       depth  of  nesting.  It  is not possible to handle an arbitrary nesting
+       depth. Perl has provided an experimental facility that  allows  regular
+       expressions to recurse (amongst other things). It does this by interpo-
+       lating Perl code in the expression at run time, and the code can  refer
+       to the expression itself. A Perl pattern to solve the parentheses prob-
+       lem can be created like this:
+
+         $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x;
+
+       The (?p{...}) item interpolates Perl code at run time, and in this case
+       refers  recursively to the pattern in which it appears. Obviously, PCRE
+       cannot support the interpolation of Perl  code.  Instead,  it  supports
+       some  special  syntax for recursion of the entire pattern, and also for
+       individual subpattern recursion.
+
+       The special item that consists of (? followed by a number greater  than
+       zero and a closing parenthesis is a recursive call of the subpattern of
+       the given number, provided that it occurs inside that  subpattern.  (If
+       not,  it  is  a  "subroutine" call, which is described in the next sec-
+       tion.) The special item (?R) is a recursive call of the entire  regular
+       expression.
+
+       For  example,  this  PCRE pattern solves the nested parentheses problem
+       (assume the  PCRE_EXTENDED  option  is  set  so  that  white  space  is
+       ignored):
+
+         \( ( (?>[^()]+) | (?R) )* \)
+
+       First  it matches an opening parenthesis. Then it matches any number of
+       substrings which can either be a  sequence  of  non-parentheses,  or  a
+       recursive  match  of  the pattern itself (that is a correctly parenthe-
+       sized substring).  Finally there is a closing parenthesis.
+
+       If this were part of a larger pattern, you would not  want  to  recurse
+       the entire pattern, so instead you could use this:
+
+         ( \( ( (?>[^()]+) | (?1) )* \) )
+
+       We  have  put the pattern into parentheses, and caused the recursion to
+       refer to them instead of the whole pattern. In a larger pattern,  keep-
+       ing  track  of parenthesis numbers can be tricky. It may be more conve-
+       nient to use named parentheses instead. For this, PCRE uses  (?P>name),
+       which  is  an  extension  to the Python syntax that PCRE uses for named
+       parentheses (Perl does not provide named parentheses). We could rewrite
+       the above example as follows:
+
+         (?P<pn> \( ( (?>[^()]+) | (?P>pn) )* \) )
+
+       This  particular example pattern contains nested unlimited repeats, and
+       so the use of atomic grouping for matching strings  of  non-parentheses
+       is  important  when  applying the pattern to strings that do not match.
+       For example, when this pattern is applied to
+
+         (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+
+       it yields "no match" quickly. However, if atomic grouping is not  used,
+       the  match  runs  for a very long time indeed because there are so many
+       different ways the + and * repeats can carve up the  subject,  and  all
+       have to be tested before failure can be reported.
+
+       At the end of a match, the values set for any capturing subpatterns are
+       those from the outermost level of the recursion at which the subpattern
+       value  is  set.   If  you want to obtain intermediate values, a callout
+       function can be used (see below and the pcrecallout documentation).  If
+       the pattern above is matched against
+
+         (ab(cd)ef)
+
+       the  value  for  the  capturing  parentheses is "ef", which is the last
+       value taken on at the top level. If additional parentheses  are  added,
+       giving
+
+         \( ( ( (?>[^()]+) | (?R) )* ) \)
+            ^                        ^
+            ^                        ^
+
+       the  string  they  capture is "ab(cd)ef", the contents of the top level
+       parentheses. If there are more than 15 capturing parentheses in a  pat-
+       tern, PCRE has to obtain extra memory to store data during a recursion,
+       which it does by using pcre_malloc, freeing  it  via  pcre_free  after-
+       wards.  If  no  memory  can  be  obtained,  the  match  fails  with the
+       PCRE_ERROR_NOMEMORY error.
+
+       Do not confuse the (?R) item with the condition (R),  which  tests  for
+       recursion.   Consider  this pattern, which matches text in angle brack-
+       ets, allowing for arbitrary nesting. Only digits are allowed in  nested
+       brackets  (that is, when recursing), whereas any characters are permit-
+       ted at the outer level.
+
+         < (?: (?(R) \d++  | [^<>]*+) | (?R)) * >
+
+       In this pattern, (?(R) is the start of a conditional  subpattern,  with
+       two  different  alternatives for the recursive and non-recursive cases.
+       The (?R) item is the actual recursive call.
+
+
+SUBPATTERNS AS SUBROUTINES
+
+       If the syntax for a recursive subpattern reference (either by number or
+       by  name)  is used outside the parentheses to which it refers, it oper-
+       ates like a subroutine in a programming language.  An  earlier  example
+       pointed out that the pattern
+
+         (sens|respons)e and \1ibility
+
+       matches  "sense and sensibility" and "response and responsibility", but
+       not "sense and responsibility". If instead the pattern
+
+         (sens|respons)e and (?1)ibility
+
+       is used, it does match "sense and responsibility" as well as the  other
+       two  strings.  Such  references must, however, follow the subpattern to
+       which they refer.
+
+
+CALLOUTS
+
+       Perl has a feature whereby using the sequence (?{...}) causes arbitrary
+       Perl  code to be obeyed in the middle of matching a regular expression.
+       This makes it possible, amongst other things, to extract different sub-
+       strings that match the same pair of parentheses when there is a repeti-
+       tion.
+
+       PCRE provides a similar feature, but of course it cannot obey arbitrary
+       Perl code. The feature is called "callout". The caller of PCRE provides
+       an external function by putting its entry point in the global  variable
+       pcre_callout.   By default, this variable contains NULL, which disables
+       all calling out.
+
+       Within a regular expression, (?C) indicates the  points  at  which  the
+       external  function  is  to be called. If you want to identify different
+       callout points, you can put a number less than 256 after the letter  C.
+       The  default  value is zero.  For example, this pattern has two callout
+       points:
+
+         (?C1)abc(?C2)def
+
+       During matching, when PCRE reaches a callout point (and pcre_callout is
+       set),  the  external function is called. It is provided with the number
+       of the callout, and, optionally, one item of data  originally  supplied
+       by  the  caller of pcre_exec(). The callout function may cause matching
+       to backtrack, or to fail altogether.  A  complete  description  of  the
+       interface  to the callout function is given in the pcrecallout documen-
+       tation.
+
+
+DIFFERENCES FROM PERL
+       This section escribes the differences in the ways that PCRE and Perl
+       handle regular expressions. The differences  described  here  are  with
+       respect to Perl 5.8.
+
+       1.  PCRE does not have full UTF-8 support. Details of what it does have
+       are given in the section on UTF-8 support in the main pcre page.
+
+       2. PCRE does not allow repeat quantifiers on lookahead assertions. Perl
+       permits  them,  but they do not mean what you might think. For example,
+       (?!a){3} does not assert that the next three characters are not "a". It
+       just asserts that the next character is not "a" three times.
+
+       3.  Capturing  subpatterns  that occur inside negative lookahead asser-
+       tions are counted, but their entries in the offsets  vector  are  never
+       set.  Perl sets its numerical variables from any such patterns that are
+       matched before the assertion fails to match something (thereby succeed-
+       ing),  but  only  if the negative lookahead assertion contains just one
+       branch.
+
+       4. Though binary zero characters are supported in the  subject  string,
+       they are not allowed in a pattern string because it is passed as a nor-
+       mal C string, terminated by zero. The escape sequence "\0" can be  used
+       in the pattern to represent a binary zero.
+
+       5.  The  following Perl escape sequences are not supported: \l, \u, \L,
+       \U, \P, \p, \N, and \X. In fact these are implemented by Perl's general
+       string-handling and are not part of its pattern matching engine. If any
+       of these are encountered by PCRE, an error is generated.
+
+       6. PCRE does support the \Q...\E escape for quoting substrings. Charac-
+       ters  in  between  are  treated as literals. This is slightly different
+       from Perl in that $ and @ are  also  handled  as  literals  inside  the
+       quotes.  In Perl, they cause variable interpolation (but of course PCRE
+       does not have variables). Note the following examples:
+
+           Pattern            PCRE matches      Perl matches
+
+           \Qabc$xyz\E        abc$xyz           abc followed by the
+                                                  contents of $xyz
+           \Qabc\$xyz\E       abc\$xyz          abc\$xyz
+           \Qabc\E\$\Qxyz\E   abc$xyz           abc$xyz
+
+       The \Q...\E sequence is recognized both inside  and  outside  character
+       classes.
+
+       7. Fairly obviously, PCRE does not support the (?{code}) and (?p{code})
+       constructions. However, there is some experimental support  for  recur-
+       sive  patterns  using the non-Perl items (?R), (?number) and (?P>name).
+       Also, the PCRE "callout" feature allows  an  external  function  to  be
+       called during pattern matching.
+
+       8.  There  are some differences that are concerned with the settings of
+       captured strings when part of  a  pattern  is  repeated.  For  example,
+       matching  "aba"  against  the  pattern  /^(a(b)?)+$/  in Perl leaves $2
+       unset, but in PCRE it is set to "b".
+
+       9. PCRE  provides  some  extensions  to  the  Perl  regular  expression
+       facilities:
+
+       (a)  Although  lookbehind  assertions  must match fixed length strings,
+       each alternative branch of a lookbehind assertion can match a different
+       length of string. Perl requires them all to have the same length.
+
+       (b)  If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $
+       meta-character matches only at the very end of the string.
+
+       (c) If PCRE_EXTRA is set, a backslash followed by a letter with no spe-
+       cial meaning is faulted.
+
+       (d)  If  PCRE_UNGREEDY is set, the greediness of the repetition quanti-
+       fiers is inverted, that is, by default they are not greedy, but if fol-
+       lowed by a question mark they are.
+
+       (e)  PCRE_ANCHORED  can  be used to force a pattern to be tried only at
+       the first matching position in the subject string.
+
+       (f) The PCRE_NOTBOL, PCRE_NOTEOL, PCRE_NOTEMPTY, and  PCRE_NO_AUTO_CAP-
+       TURE options for pcre_exec() have no Perl equivalents.
+
+       (g)  The (?R), (?number), and (?P>name) constructs allows for recursive
+       pattern matching (Perl can do  this  using  the  (?p{code})  construct,
+       which PCRE cannot support.)
+
+       (h)  PCRE supports named capturing substrings, using the Python syntax.
+
+       (i) PCRE supports the possessive quantifier  "++"  syntax,  taken  from
+       Sun's Java package.
+
+       (j) The (R) condition, for testing recursion, is a PCRE extension.
+
+       (k) The callout facility is PCRE-specific.
+
+
+
+NOTES
+        The \< and \> metacharacters from Henry Spencers package
+        are not available in PCRE, but can be emulate with \b,
+        as required, also in conjunction with \W or \w.
+
+        In LDMud, backtracks are limited by the EVAL_COST runtime
+        limit, to avoid freezing the driver with a match
+        like regexp(({"=XX==================="}), "X(.+)+X").
+
+        LDMud doesn't support PCRE callouts.
+
+
+LIMITATIONS
+        There are some size limitations in PCRE but it is hoped that
+        they will never in practice be relevant.  The maximum length
+        of a compiled pattern is 65539 (sic) bytes.  All  values  in
+        repeating  quantifiers  must be less than 65536.  There max-
+        imum number of capturing subpatterns is 65535.  There is  no
+        limit  to  the  number of non-capturing subpatterns, but the
+        maximum depth of nesting of all kinds of parenthesized  sub-
+        pattern,  including  capturing  subpatterns, assertions, and
+        other types of subpattern, is 200.
+
+        The maximum length of a subject string is the largest  posi-
+        tive number that an integer variable can hold. However, PCRE
+        uses recursion to handle subpatterns and indefinite  repeti-
+        tion.  This  means  that the available stack space may limit
+        the size of a subject string that can be processed  by  cer-
+        tain patterns.
+
+
+AUTHOR
+        Philip Hazel <ph10@cam.ac.uk>
+        University Computing Service,
+        New Museums Site,
+        Cambridge CB2 3QG, England.
+        Phone: +44 1223 334714
+
+SEE ALSO
+        regexp(C), hsregexp(C)
diff --git a/doc/concepts/pgsql b/doc/concepts/pgsql
new file mode 100644
index 0000000..12f2cc4
--- /dev/null
+++ b/doc/concepts/pgsql
@@ -0,0 +1,88 @@
+CONCEPT
+        pgsql - PostgreSQL support
+
+DESCRIPTION
+        On hosts with the PostgreSQL package installed, the driver can be
+        configured to interface with the PostgreSQL database. If that is done,
+        the driver defines the macro __PGSQL__ for LPC programs and
+        activates a number of related efuns.
+
+        -- Usage --
+
+        The interface to the PostgreSQL database is implemented
+        through the concept of a controlling object: when opening a
+        database connection, the LPC code has to provide a callback
+        function. The object this function is bound to is the
+        controlling object: all queries to the database will be issued
+        by this object, and the responses will be sent to the callback
+        function.
+
+        The interface is also asynchronous: the pg_query() efun just
+        queues the query with the database connection, and returns
+        immediately. When the database has finished working the query,
+        the callback function is called with the results.
+
+        The callback function can be defined by name or by closure,
+        and can be defined with extra parameters:
+
+
+          #include <pgsql.h>
+
+          void <callback>(int type, mixed ret, int id [, mixed extra...])
+
+            <type> is the type of the call, <id> identifies the query
+            for which this call is executed:
+
+              PGRES_TUPLES_OK: <ret> is the result from a query.
+                               It is either a mapping (field name as
+                               key, indexing <n> values for n returned
+                               tuples), or an array of arrays (one per
+                               row).
+
+              PGRES_COMMAND_OK: <ret> is a string which contains the
+                                server response (e.g. on INSERT or DELETE) 
+
+              PGRES_BAD_RESPONSE,
+              PGRES_NONFATAL_ERROR,
+              PGRES_FATAL_ERROR: ret is the error-string
+
+
+          void <callback>(int type, mixed ret [, mixed extra...])
+
+            <type> is the type of the call, which is not related a
+            specific query:
+
+              PGCONN_SUCCESS: The database-connection was established,
+                              <ret> is a dummy string.
+              PGCONN_FAILED:  The database-connection failed, <ret> is
+                              the error message.
+                The first message to the callback after a call to
+                pg_connect() is always one of these two.
+
+              PGRES_NOTICE: <ret> is a informational text.
+
+              PGCONN_ABORTED: If the connection to the backend fails
+                              we try to re-establish (reset) it. If the
+                              reset fails, the connection is closed and
+                              this value is returned. Consider the
+                              connection gone and don't try to close or 
+                              otherwise operate further on it.
+                              <ret> is a dummy string.
+
+        -- Security --
+
+        All SQL efuns (unless execute by the master or the simul-efun object)
+        trigger a privilege_violation ("pgsql", "<efun_name>"). If a more
+        finegrained control is desired, overload the individual efuns with a
+        nomask simul-efun.
+
+AUTHOR
+        Florian Heinz and others.
+
+HISTORY
+        Added as package in LDMud 3.3.445.
+        LDMud 3.3.640 added a privilege_violation() call for each efun.
+
+SEE ALSO
+        mysql(C), pg_connect(E), pg_conv_string(E), pg_query(E), pg_pending(E),
+        pg_close(E), privilege_violation(M)
diff --git a/doc/concepts/properties b/doc/concepts/properties
new file mode 100644
index 0000000..1ab418a
--- /dev/null
+++ b/doc/concepts/properties
@@ -0,0 +1,109 @@
+Properties
+ BESCHREIBUNG:
+     Im Gegensatz zu Variablen innerhalb eines Objektes, kann man Properties
+     von aussen veraendern, ohne eine besondere Funktion geschrieben zu haben.
+
+     1. Das zugrundeliegende Prinzip
+     ===============================
+      Das grundlegende Konzept der MUDlib ist, dass wichtige, objektbezogene
+      Informationen in den sogenannnten Properties gespeichert werden (engl.
+      property -- Eigenschaft, Eigentum).
+
+      Diese Informationen koennen einfache Werte, wie z.B. Zahlen, Zeichen oder
+      Objekte, aber auch kompliziertere Strukturen sein.
+      Jedes Objekt kann beliebig viele solcher Properties besitzen und deren
+      Namensgebung ist nicht nur auf die von der MUDlib bereitgestellten
+      Standardproperties begrenzt. Das heisst, das fuer eigene Anwendungen die
+      Menge der Properties fuer ein Objekt beliebig erweitert werden kann.
+      Damit sind auch schon die beiden Hauptmerkmale einer Property ange-
+      sprochen:
+
+	a) ein Name oder Kennung und
+	b) ein Wert, der durch den Namen repraesentiert wird.
+
+      Das reine Verwalten einer Property mit Namen und Wert ist aber nicht sehr
+      sinnvoll und so gehoeren zu jeder Property noch zwei weitere wichtige
+      Dinge. Zu jeder Property wurden jeweils zwei Operationen eingefuehrt,
+      welche den uebergebenen Wert vor der Speicherung oder Abfrage bearbeiten.
+
+      Zusammenfassend laesst sich das Konzept der Property in folgendem Schema
+      darstellen:
+
+               +-------------------------------------------+
+               | Property                                  |
+               +-------------------------------------------+
+               | privater Datenbereich (Property Werte)    |
+               +-------------------------------------------+
+               | Direktzugriff auf den Datenbereich        |
+               +-------------------------------------+     |
+               |     ^       Methoden       v        | ^ v |
+               |   Setzen       |        Abfragen    |     |
+               +-------------------------------------+-----+
+                     ^                      |
+	             |                      V
+                  SetProp()             QueryProp()
+
+      Aus dem Schema laesst sich Folgendes erkennen:
+      - beim Setzen und Abfragen wird der Wert einer Methode uebergeben, die
+	den Wert zurueckgibt oder ggf. die Aenderungen vornimmt
+      - ein direkter Zugriff auf den Wert der ist ebenfalls moeglich, sollte
+	aber nicht der Normalfall sein, da die Methoden Nebeneffekte erzeugen
+        - in bestimmten Faellen kann man den aeusserlich aendernden Zugriff
+	  vollkommen unterbinden (NOSETMETHOD, PROTECT)
+	  (VORSICHT bei mappings/arrays, diese werden bei QueryProp()
+	   als Referenz zurueckgegeben, sind also so aenderbar)
+
+     2. Implementation
+     =================
+
+      Die Klasse /std/thing/properties.c stellt folgende Funktionen fuer die
+      Behandlung von Properties bereit:
+
+      Normaler Zugriff:	mixed SetProp(<name>, <wert>)
+			- setzt den Wert von <name> auf <wert>
+			mixed QueryProp(<name>)
+			- gibt den Wert von <name> zurueck
+ 
+      Direkter Zugriff:	mixed Set(<name>, <wert>, <interpretation>)
+			- setzt fuer <name> einen <wert>:
+			  - den normalen Wert
+			    <interpretation>: F_VALUE (==0)
+			  - eine Methode
+			    <wert>: closure
+			    <interpretation>: F_SET_METHOD, F_QUERY_METHOD
+			  - ein Flag
+			    <wert>: SAVE, SECURED, PROTECTED, NOSETMETHOD
+			    <interpretation>: F_MODE, F_MODE_AS, F_MODE_AD
+			mixed Query(<name>, <interpretation>)
+			- fragt fuer <name> einen <wert> ab
+			  - F_SET_METHOD, F_QUERY_METHOD: die Closure/0
+			  - F_MODE: das (veroderte!) Flag
+      Global:		void SetProperties(<mapping>)
+			- setzt das Mapping komplett, beachtet >= PROTECTED
+			mapping QueryProperties()
+			- fragte das komplette Mapping als Kopie ab
+
+     3. Besonderheiten/Eingebaute Properties:
+
+      Existiert zu einer Property eine Funktion mit dem selben Namen und einem
+      "_set_" bzw "_query_" davor, so wird nicht auf die das Property-Mapping
+      zugegriffen, sondern es werden die Argumente an diese Funktion uebergeben
+      und der Rueckgabewert dieser Funktion zurueckgegeben.
+      Vorteil:
+      - so kann man Daten, die schnell verfuegbar sein muessen,	(bei denen
+        also Effizienz gegen SetProp/QueryProp spricht) trotzdem nach aussen
+	einheitlich zugreifbar machen
+      Nachteil:
+      - nicht wirklich sauber
+      - Speichern muss man selbst vornehmen
+      - Set/Query gehen wie auch bei Methoden an _set_*/_query_* vorbei
+      - dieses Verhalten sollte der Mudlib vorbehalten bleiben, fuer eigene
+        Prueffunktionen (wird etwas gesetzt/abgefragt) bzw. Aenderungen
+	sollte man Methoden (F_SET_METHOD/F_QUERY_METHOD) benutzen
+
+ SIEHE AUCH:
+     SetProp(L), QueryProp(L), Set(L), Query(L), SetProperties(L),
+     QueryProperties(L)
+     objekte, effizienz, closures
+
+ 21. Maerz 2004 Gloinson
diff --git a/doc/concepts/regexp b/doc/concepts/regexp
new file mode 100644
index 0000000..9a9d70e
--- /dev/null
+++ b/doc/concepts/regexp
@@ -0,0 +1,121 @@
+SYNOPSIS
+        Regular Expressions
+
+
+DESCRIPTION
+        LDMud supports both the traditional regular expressions as
+        implemented by Henry Spencer ("HS" or "traditional"), and the
+        Perl-compatible regular expressions by Philip Hazel ("PCRE").
+        Both packages can be used concurrently, with the selection
+        being made through extra option flags argument to the efuns.
+        One of the two packages can be selected at compile time, by
+        commandline argument, and by driver hook to be the default
+        package.
+
+        The packages differ in the expressivity of their expressions
+        (PCRE offering more options that Henry Spencer's package),
+        though they both implement the common subset outlined below.
+
+        All regular expression efuns take an additional options
+        parameter, which is a an number composed of bitflags, and is
+        used to modify the exact behaviour of the expression
+        evaluation. In addition, certain efuns may accept additional
+        specific options.
+
+        For details, refer to the detailed manpages: hsregexp(C) for
+        the Henry Spencer package, pcre(C) for the PCRE package.
+
+
+REGULAR EXPRESSION DETAILS
+        A regular expression is a pattern that is matched against  a
+        subject string from left to right. Most characters stand for
+        themselves in a pattern, and match the corresponding charac-
+        ters in the subject. As a trivial example, the pattern
+
+          The quick brown fox
+
+        matches a portion of a subject string that is  identical  to
+        itself.  The  power  of  regular  expressions comes from the
+        ability to include alternatives and repetitions in the  pat-
+        tern.  These  are encoded in the pattern by the use of meta-
+        characters, which do not stand for  themselves  but  instead
+        are interpreted in some special way.
+
+        The following metacharacters are 'universal' in that both regexp
+        packages understand them in the same way:
+
+          .       Match any character.
+
+          ^       Match begin of line.
+
+          $       Match end of line.
+
+          x|y     Match regexp x or regexp y.
+
+          ()      Match enclosed regexp like a 'simple' one.
+
+          x*      Match any number (0 or more) of regexp x.
+
+          x+      Match any number (1 or more) of regexp x.
+
+          [..]    Match one of the characters enclosed.
+
+          [^ ..]  Match none of the characters enclosed. The .. are to
+                  replaced by single characters or character ranges:
+
+          [abc]   matches a, b or c.
+
+          [ab0-9] matches a, b or any digit.
+
+          [^a-z]  does not match any lowercase character.
+
+          \B      not a word boundary
+
+          \c      match character c even if it's one of the special
+                  characters.
+
+        The following metacharacters or metacharacter combinations implement
+        similar functions in the two regexp packages;
+
+          \b      PCRE: word boundary, also used inconjunction with
+                        \w (any "word" character) and \W (any "non-word"
+                        character).
+
+          \<      HS: Match begin of word.
+          \>      HS: Match end of word.
+
+
+OPTIONS
+        The package is selected with these option flags:
+
+          RE_PCRE
+          RE_TRADITIONAL
+
+        These flags are also used for the H_REGEXP_PACKAGE driver
+        hook.
+
+
+        Traditional regular expressions understand one option:
+
+          RE_EXCOMPATIBLE
+
+
+        PCRE understands these options:
+
+          RE_ANCHORED
+          RE_CASELESS
+          RE_DOLLAR_ENDONLY
+          RE_DOTALL
+          RE_EXTENDED
+          RE_MULTILINE
+          RE_UNGREEDY
+          RE_NOTBOL
+          RE_NOTEOL
+          RE_NOTEMPTY
+
+HISTORY
+        LDMud 3.3.596 implemented the concurrent use of both packages.
+
+SEE ALSO
+        hsregexp(C), pcre(C), regexp_package(H), regexp(E), regexplode(E),
+        regmatch(E), regreplace(E), regexp_package(E), invocation(D)
diff --git a/doc/concepts/rtfm b/doc/concepts/rtfm
new file mode 100644
index 0000000..0c566fe
--- /dev/null
+++ b/doc/concepts/rtfm
@@ -0,0 +1,33 @@
+CONCEPT
+        rtfm - read the fucking manual
+
+UPDATE
+        Mateese, 15-Jun-93, 03:15 MET
+
+SYNOPSIS
+        rtfm
+
+        OPTIONS None, you have to read the manual for an answer.
+
+DESCRIPTION
+        Used when lazy people ask stupid  questions.  Normaly  cried
+        out in vain.
+
+FILES
+        /dev/null
+
+ENVIRONMENT
+        Any.
+
+CREDITS
+        Bert Nase, who else?
+
+SEE ALSO
+        man(H)
+
+DIAGNOSTICS
+        Is an diagnostic. Since you are reading this you are getting
+        the idea.
+
+BUGS
+        Ha!
diff --git a/doc/concepts/secure b/doc/concepts/secure
new file mode 100644
index 0000000..a294a5e
--- /dev/null
+++ b/doc/concepts/secure
@@ -0,0 +1,52 @@
+THEMA:
+	secure-Verzeichnisse
+
+FUNKTION:
+	Magier haben die Moeglichkeit in ihren Gilden oder Regions-
+	verzeichnissen /secure Verzeichnisse anzulegen, in denen Daten dann
+	vor Lesezugriffen anderer Magier geschuetzt sind. Leserechte in diesen
+	Verzeichnissen haben grundsaetzlich nur diejenigen, die dort auch
+	Schreibrechte haben. Diese Verzeichnisse sind fuer (Quest-)Raetsel oder
+	schwierige NPCs mit vielen Stufenpunkten gedacht. Diese Verzeichnisse
+	sind ausdruecklich _nicht_ dazu gedacht, dort ganze Gebiete oder Quests
+	abzulegen, da bei Problemen andere Magier nur noch sehr schwer helfen
+	koennen. Aus diesem Grund sind die Regionsmagier gehalten darauf zu
+	achten, dass diese Verzeichnisse nur mit Bedacht verwendet werden.
+	Sollte das ganze ausarten und uebertrieben werden, so wird der Schutz
+	der secure Verzeichnisse in den betroffenen Gebieten/Regionen wieder
+	aufgehoben!
+
+HINWEIS:
+	Es ist _nicht_ moeglich ganze Verzeichnisbaeume in ein secure/
+	Verzeichnis abzulegen. Anders formuliert:
+  Unterverzeichnisse von secure/ geniessen _keinen_ besonderen Schutz.
+
+BEISPIEL:
+
+	o richtiger Einsatz in einem fiktiven standard include file...
+
+	  #define HOME(x)    "/d/region/magiername/meingebiet/"+x
+	  #define NPC(x)     HOME("npc/"+x)
+     -> /d/region/magiername/meingebiet/npc/
+	  #define OBJ(x)     HOME("obj/"+x)
+     -> /d/region/magiername/meingebiet/obj/
+	  #define ROOM(x)    HOME("room/"+x)
+     -> /d/region/magiername/meingebiet/room/
+	  #define SECURE(x)  HOME("secure/"+x)
+     -> /d/region/magiername/meingebiet/secure/
+
+
+	o falscher (wirkungsloser) Einsatz mit einem Verzeichnisbaum:
+
+	  #define HOME(x)    "/d/region/magiername/meingebiet/secure/"+x
+	  #define NPC(x)     HOME("npc/"+x)
+     -> /d/region/magiername/meingebiet/secure/npc/
+	  #define OBJ(x)     HOME("obj/"+x)
+     -> /d/region/magiername/meingebiet/secure/obj/
+	  #define ROOM(x)    HOME("room/"+x)
+     -> /d/region/magiername/meingebiet/secure/room/
+
+
+LETZTE AeNDERUNG:
+  04.09.2011 Zesstra
+
diff --git a/doc/concepts/simul_efun b/doc/concepts/simul_efun
new file mode 100644
index 0000000..8c4a2a0
--- /dev/null
+++ b/doc/concepts/simul_efun
@@ -0,0 +1,14 @@
+CONCEPT
+        simul_efun
+
+DESCRIPTION
+        The simul_efun object is automagically sort-of inherited by
+        every object. That functions that are defined in it can be
+        accessed just like efuns or inherited functions by every
+        object (except the master object). To get access to efuns that
+        are overloaded by the simul_efun object, you can use the
+        efun::function() to bypass the simul_efun (unless the
+        simul_efun object has defined the function as ``nomask'').
+
+SEE ALSO
+        get_simul_efun(M), inheritance(LPC), operators(LPC)
diff --git a/doc/concepts/terminals b/doc/concepts/terminals
new file mode 100644
index 0000000..3dd3171
--- /dev/null
+++ b/doc/concepts/terminals
@@ -0,0 +1,18 @@
+terminals
+ BESCHREIBUNG:
+     Ein Spieler kann sein Terminal mit "stty" in verschiedene Modi
+     schalten. Mit ANSI-Escape-Sequenzen kann man dementsprechend dann
+     diesem Spieler farbige, unterstrichene, blinkende Texte auf den
+     Bildschirm zaubern, wenn dieser es unterstuetzt.
+
+     Die derzeit unterstuetzten Terminals sind:
+	dumb:   bitte keine Escapesequenzen nutzen ...
+	vt100:  versteht reverse, bold, blinking
+	ansi:   versteht vt100 und Farben
+
+     Die nutzbaren Farbcodes sind unter /sys/ansi.h definiert.
+
+ SIEHE AUCH:
+     P_TTY, stty
+
+ 21. Maerz 2004 Gloinson
diff --git a/doc/concepts/ticks b/doc/concepts/ticks
new file mode 100644
index 0000000..a30f18f
--- /dev/null
+++ b/doc/concepts/ticks
@@ -0,0 +1,66 @@
+* Was sind Ticks?
+Ein Tick ist eine Masseinheit, die man frueher eingefuehrt hat, um zu
+verhindern, dass ein Objekt/Magier den Driver beliebig lang beschaeftigen
+kann und niemand anders mehr zum Zuge kommt.
+
+* Sind es also Zeiteinheiten? Oder Rechenoperationen?
+Am ehesten entspricht ein Tick der Rechenoperation. Besser gesagt: jeder
+LPC-Operator, jedes LPC-Schluesselwort und jede efun, die man ruft, verringert
+die zur Verfuegung stehenden Ticks um mindestens 1: Sowas wie +, -, if(),
+else, switch(), etc.
+Hierbei stehen die Ticks, die ein Stueck Code braucht und die Zeit, die dessen
+Ausfuehrung braucht, in keinem konstanten Verhaeltnis. Ein Stueck Code
+braucht immer die gleiche definierte Menge an Ticks, aber kann dafuer
+unterschiedliche Zeiten benoetigen (z.b. wenn man erst was einswappen muss).
+Ebenso brauchen 2 Stueck Code, die die gleiche Menge Ticks brauchen, oft
+unterschiedlich lang.
+
+* Wie messe ich Ticks?
+Die Funktion get_eval_cost() liefert einem zurueck, wieviele Ticks man in
+diesem Ausfuehrungsthread man noch verbraten darf, bis die Ausfuehrung
+abgebrochen wird. Will man wissen, wieviel etwas kostet, ruft man vorher
+get_eval_cost(), merkt sich das und vergleicht mit dem Ergebnis von
+get_eval_cost() danach.
+
+* Wieviel ticks verbraucht diese und diese Operation/Funktion?
+Jede elementare Operation verbraucht erstmal einen Tick. Aber: es gibt Efuns
+und Operatoren, die sehr grosse Datenmengen manipulieren (koennen). Damit man
+mit diesen nicht megabyteweise Daten fuer einen Tick manipulieren kann, gibt
+es in LDMud die sog. dynamischen Evalcosts, bei denen je nach Umfang der
+manipulierten Daten Ticks abgezogen werden. Bsp: str1 + str2 kostet umso mehr,
+je groesser str1 und str2 sind.
+Wenn man es genau wissen will, sollte man per get_eval_cost() messen, dies ist
+natuerlich fuer die dynamischen Evalcosts schwieriger. Ggf. fragt den EM fuer
+Driver/Mudlib, ob er das weiss.
+
+* Wieviel stehen dem Driver pro Heartbeat zur Verfuegung? 
+Das ist so global nicht zu beantworten. Aber: pro Ausfuehrungsthread stehen
+uns momentan 1500000 Ticks zur Verfuegung. So ein Ausfuehrungsthread startet
+z.B., wenn der Driver in einem Objekt heart_beat() ruft, auch reset(),
+clean_up() oder wenn der Driver ein Spielerkommando auswertet. Callouts sind
+ein Spezialfall, hierbei teilen sich die "gleichzeitig" (im gleichen
+Backend-Zyklus des Drivers) und unter der gleichen UID ausgefuehrten Callouts
+letztendlich die Ticks.
+
+* Was passiert, wenn es doch mal nicht reicht?
+In dem Fall gibt es den beruehmt-beruechigten 'too long evaluation'-Fehler
+(TLE) und die Ausfuehrung wird an der Stelle abgebrochen, wo die Anzahl an
+verfuegbaren Ticks auf 0 faellt.
+
+* Wie finde ich heraus, wieviel Laufzeit eine bestimmte Operation benoetigt?
+Hierbei helfen einem die verbrauchten Ticks nicht weiter. Um die Laufzeit
+eines Stuecks Code zu bestimmen, misst man vorher die aktuelle Zeit mit
+genuegend grosser Genauigkeit, fuehrt seinen Code, misst erneut die Zeit und
+bildet die Differenz. Die genaueste Moeglichkeit der Zeitmessung im Mud stellt
+die efun utime() dar, welche die Zeit in Mikrosekunden ermitteln kann.
+Beispiel:
+  int *zeit1 = utime();
+  // code ausfuehren
+  int *zeit2 = utime();
+  int usec = (zeit2[0] - zeit1[0]) * 1000000 - zeit1[1] + zeit2[1];
+
+SIEHE AUCH:
+  effizienz, memory, goodstyle
+
+04.09.2008, Zesstra
+
diff --git a/doc/concepts/tls b/doc/concepts/tls
new file mode 100644
index 0000000..25946a2
--- /dev/null
+++ b/doc/concepts/tls
@@ -0,0 +1,73 @@
+PRELIMINARY
+CONCEPT
+        tls (transport layer security)
+
+DESCRIPTION
+	TLS stands for Transport Layer Security which is the successor
+	of the well known SSL (Secure Socket Layer). Both techniques 
+	provide a way to authenticate and encrypt the data send through
+	a network connection.
+	By enabling TLS during compilation of the driver you can provide
+	a secure channel into the mud to your players.
+	In difference to other solutions as "sslwrap" or "stunnel" the
+	driver integrated approach has the advantage that the mud sees 
+	the real IP of the player, not the IP of the local mud host.
+
+USAGE
+	To use TLS configure your driver with --enable-tls option.
+	After starting your driver you have five new efuns
+	(tls_init_connection(), tls_deinit_connection(), tls_error(),
+	 tls_query_connection_info(), tls_query_connection_state()).
+
+	You can switch on TLS by calling tls_init_connection().
+	This can happen in three ways:
+
+	1) in telnet_neg()
+
+            Advantage of this method is that you can offer TLS on a normal 
+            mud port. If you have a limited number of ports this can 
+            become important. The TLS connection will be started by 
+            the client with help of telnet option STARTTLS. Currently
+            there are no mudclients that support this method.
+            
+            You will have to implement the telnet option STARTTLS (46) for
+            this method. The draft for this can be found here:
+            http://www.ietf.org/proceedings/99mar/I-D/draft-ietf-tn3270e-telnet-tls-01.txt
+            Call tls_init_connection() to initiate the TLS handshake.
+
+
+	2) in master_ob->connect()
+
+            Advantage of this method is that your users can connect with
+            any program that supports TLS/SSL. Examples are telnet-ssl,
+            sslwrap or stunnel. Disadvantage is that you have to spend
+            a dedicated port for this.
+            
+            You have to call tls_init_connection() as first command
+            after the player connected (normally in master_ob->connect())
+
+        3) in an interactive object using a callback.
+
+            This method is similar to method (1), but not limited to
+            telnet: it is useful for implementing protocols thta use
+            STARTTLS like SMTP or IMAP. tls_init_connection() can be
+            called at any time by the interactive object.
+
+            You must not write to the connection after calling this
+            efun until the callback is executed (the prompt will
+            be supressed automatically during this time).
+
+        To test your code, you can use the openssl binary.
+        `openssl s_client -connect host:port' should display your certificate
+        and anything you write after the callback is executed. If you
+        encounter the error message `SSL3_GET_RECORD: wrong version number'
+        you're probably writing to the connection while you should not.
+
+BUG
+        This manpage might be not quite up to date with the implementation.
+
+HISTORY
+        Introduced in LDMud 3.3.474 and following, backported to 3.2.11.
+
+SEE ALSO
+        tls_* efuns
diff --git a/doc/concepts/uids b/doc/concepts/uids
new file mode 100644
index 0000000..724a7af
--- /dev/null
+++ b/doc/concepts/uids
@@ -0,0 +1,96 @@
+CONCEPT
+        uids (userids)
+
+DESCRIPTION
+        Every object in the mud is attributed with a user-id 'uid': a string
+        which associates the object with a certain 'user' (aka 'wizard' or
+        'creator', though it is not limited to that). The uid can be 0, which
+        internally is the default-uid.
+
+        The uid serves a dual purpose: on the on hand it is used to gather
+        statistics about the various groups of objects (in the famous
+        'wizlist'), on the other hand the uid can come in handy in the
+        implementation of security systems.
+
+        The uid of an object is assigned at its creation through the
+        driver hooks H_LOAD_UIDS for loaded objects, and H_CLONE_UIDS
+        for cloned objects, and can't be changed afterwards.
+
+        The uid of an object can be queried with the efun getuid() (resp.
+        creator() in compat-mode).
+
+
+        Every object also has a second string attribute, the 'effective
+        userid' or 'euid', which also may be 0. This value was intended to
+        implement a security system based on difference between theoretical
+        and effective permissions. Since the effectiveness of this system is
+        doubtful, the driver enforces such a use only as an option.
+
+        As uids, euids are assigned at an objects creation through
+        the two aformentioned driverhooks. They can be queried with
+        the efun geteuid() and changed with the efun seteuid(). Calls
+        to the latter are verified by the master lfun valid_seteuid().
+
+        Additionally objects can impose their uid onto an other objects
+        euid with the efun export_uid().
+
+
+        If the driver is run in 'strict euids' mode, euids are taken
+        more seriously than being just another attribute:
+          - all objects must have a non-0 uid.
+          - objects with a 0 euid can't load or clone other objects.
+          - the backbone uid as returned by master::get_bb_uid() must
+            not be 0.
+
+
+        Userids are assigned at the time of the creation of an object
+        by calling the driverhooks H_LOAD_UIDS and H_CLONE_UIDS:
+
+            mixed <load_uids closure> (string objectname)
+            mixed <clone_uids closure>(object blueprint, string objectname)
+
+        When an object is newly loaded, the H_LOAD_UIDS hook is
+        called with the object name as argument.
+        When an object is cloned, the H_CLONE_UIDS hook is called
+        with the blueprint object as first and the clone's designated
+        name as second argument.
+        In both cases the new object already exists, but has 0 uids.
+
+        For the result, the following possibilities exist (<num> is
+        a non-zero number, <no-string> is anything but a string):
+
+             "<uid>"                    -> uid = "<uid>", euid = "<uid>"
+             ({ "<uid>", "<euid>" })    -> uid = "<uid>", euid = "<euid>"
+             ({ "<uid>", <no-string> }) -> uid = "<uid>", euid = 0
+
+        If strict-euids is not active, the following results are
+        possible, too:
+
+             <num>                      -> uid = 'default', euid = 0
+             ({ <num>, "<euid>" })      -> uid = 'default', euid = "<euid>"
+             ({ <num>, <no-string> })   -> uid = 'default', euid = 0
+
+
+
+        Slightly different rules apply to the (e)uid of the master.
+        The masters (e)uid is determined by a call to
+        master->get_master_uid():
+
+             "<uid"> -> uid = "<uid>", euid = "<uid>"
+
+        In non-strict-euids mode, more results are possible:
+
+             0       -> uid = 0, euid = 0
+             <num>   -> uid = 'default', euid = 0
+
+        If your uids are in general based on filenames, it is wise to return a
+        value here which can not be legally generated from any filename.  OSB
+        for example uses 'ze/us'.
+
+        The masters uid is determined only on startup this way, at runtime the
+        uids of a reloaded master determined as for every object by a call to
+        the appropriate driver hooks.
+
+SEE ALSO
+        native(C), get_root_uid(M), valid_seteuid(M),
+        objects(C), clone_object(E), geteuid(E), getuid(E), seteuid(E)
diff --git a/doc/driver/codestyle b/doc/driver/codestyle
new file mode 100644
index 0000000..78a05b6
--- /dev/null
+++ b/doc/driver/codestyle
@@ -0,0 +1,247 @@
+    The LPMud gamedriver is by nature the result of the cooperative work
+    of multiple programmers, often separated by large oceans and years
+    of time. In order to keep the appearance of the driver source consistent
+    (and with that maintainable), the following guidelines should be followed
+    for all code contributions.
+
+    For a quick start in how good driver source should look like, take
+    a look at comm.{c,h}, object.{c,h} and mapping.{c.h}.
+
+    The guidelines have a strong emphasis on code layout and commenting,
+    stemming from the fact that proper layout and comments gave the
+    incentive for LDMud in the first place. Right now, 50% of all lines
+    are comments, and that has been proven to be a Good Thing.
+
+    Any reader of the "real programmers don't write comments"-school
+    of thought is asked to take his or her incompetence elsewhere.
+
+
+Language
+--------
+    The language is ISO Standard C (also known as 'C89' or 'ANSI C').
+    Common compiler extensions or features from the new C99 standard are
+    permitted if their addition is transparent for other C89 compilers.
+    For example: the 'inline' keyword permitted through the use of the
+    INLINE macro; so are the Metrowerks-pragmas and GNU-attributes. Not
+    permitted are GNU's local functions.
+
+    System/Platform specifics are to be detected by the configure script
+    and provided with transparent implementations in port.{c,h} (or for
+    module-specific dependencies in the respective modules).
+
+    Adherence to the Standard has the following implications:
+
+     - All functions must be fully prototyped.
+     - Standard types like size_t, ssize_t or ptrdiff_t are to be used
+       whereever possible.
+     - Unixisms like
+         {
+           a = malloc(20);
+           b = malloc(20);
+           c = b-a;
+         }
+       are not legal and shouldn't be used.
+     - Don't make assumptions about the size of the base types (e.g.
+       a char might have more than 8 bits). If such an assumption
+       is unavoidable, comment it clearly and if possible add a test
+       to raise a compile or runtime error if the assumption is not met.
+
+
+Style
+-----
+    All modules (.c-files) have to have their interface in an accompaning
+    .h-file. The header file must be guarded against repeated inclusion
+    with the normal
+        #ifndef HEADERNAME_H
+        #define HEADERNAME_H 1
+          ...
+        #endif /* HEADERNAME_H */
+    construct. To use a module, its headerfile must be included - no random
+    'extern' declarations.
+
+    Every module must include "driver.h" which in turn includes the
+    portability headers and provides common defines.
+
+    Use the driver-provided types and macros like Bool or p_int.
+
+    Code should be written defensively and readable. This is not the IOCCC.
+
+    No magic numbers - use #defines to give them names.
+
+    Add sanity checks where useful. If the checks are costly, enclose
+    them in a #ifdef DEBUG...#endif bracket.
+
+    Comment questionable code or opportunities for possible extensions with a
+    'TODO: ...' comment. For multiline comments, use 'TODO::' on the second
+    and following lines (this makes reading a grep easier).
+
+    Comment temporary debug code with a 'DEBUG:' comment. Similar, debug
+    output should always begin with 'DEBUG:'.
+
+    Variable identifiers should start with a lowercase letter, function
+    identifiers may start with upper or lowercase, constant identifiers
+    should start with an uppercase letter. Macro identifiers should be
+    all UPPERCASE, other identifiers may be under_scored or SkudlyCaps.
+    Hungarian notation is accepted only in a very light form: pFoo for
+    pointers, ppFoo for pointer to pointers, iFoo for integer types,
+    sFoo for string pointers, aFoo for complex types - you get the
+    idea. But no alpzsFoo and friends.
+
+    f_xxx() function names are reserved for efun implementations.
+    typedef'd typenames should end in _t (e.g. 'mapping_t'), struct
+    names should end in _s (e.g. 'struct instrs_s').
+
+    Indentation is 4 spaces per level. No tab characters anywhere!
+
+    The indentation style is a variant of the 'Allman style':
+
+        if (foo)
+        {
+            ...body...
+        } /* if (foo) */
+
+    Note the comment at the closing brace!
+
+    One line bodies may be written as
+
+        if (foo) body;
+
+    or
+
+        if (foo)
+            body;
+
+    _if_ it improves the readability.
+
+    Similar, the typical layout of a function is:
+
+        static int
+        function_name ( arg1 , arg2)
+
+        /* Twiddle <arg1> with <arg2> and return the result.
+         */
+
+        {
+            ....
+        } /* function_name() */
+
+    If an expression (argument list, ...) extends over several, the first
+    literal element on a line should be an operator or syntactical marker:
+
+        if (condition1
+         && (   condition2
+             || condition3)
+           )
+
+        printf( "..."
+              , arg1, arg2, arg3
+              );
+
+    Be generous with whitespace - both horizontal and vertical.
+
+    [ The reasoning behind this style is to use the language elements
+      to create strong visual structures for the eyes to follow. By doing so,
+      the structure of the program becomes obvious without much
+      conscious thought.
+    ]
+
+
+Commenting
+----------
+    The comments also follow the idea of giving strong visual clues of
+    how the program is structured.
+
+    Horizontal lines should be created as
+
+        /*------...-------*/
+        /*======...=======*/
+        /* - - -... - - - */
+
+    The '---' line is the normal separator between the components of a
+    source file (includes, variable declarations, macro declarations,
+    the separate functions). The '===' line can be used to separate
+    larger sections of a source file (e.g. the lowlevel routines from
+    the efun implementations). '- -' lines, which usally span less than
+    the whole line, can be used to subdivide large functions (though then
+    it's often better to split the function into several small ones).
+
+    A '***' line is reserved for the end of every source file.
+
+    A '/* --- Subsection --- */' is also good to separate subsections.
+
+    Vertical lines are to be constructed as
+
+      /*
+       *
+       */
+
+    No box comments.
+
+    Every function must have a head comment explaining the meaning
+    of the arguments, what the function does, and the possible results.
+    For efun implementations, this comment should be identical to the
+    man page.
+
+    Within a function, every variable should be commented as
+
+       int foo;  /* short comment */
+       int bar;
+         /* long comment which doesn't fit on one line.
+          */
+
+    The major steps in a function should be preceeded by a comment
+    explaining them. Also, wherever a critical design decision has
+    been made, a comment should line out the whats and whys:
+
+        /* Duplicate the stored arguments for the function call.
+         * (It's tempting to use the stored arguments directly
+         *  in the last pass; however it's not guaranteed that
+         *  the last pass actually comes this far.)
+         */
+
+
+    A typical file layout, commentwise, looks like this:
+
+        /*------------------------------------------------------
+         * Gamedriver Bouncing module.
+         *
+         * <reserved for future copyright notice>
+         *------------------------------------------------------
+         * 'Big picture' description of the module and its
+         * relation to the other gamedriver parts.
+         *
+         * Tricky design discussions also belong in here.
+         *------------------------------------------------------
+         */
+
+        #include "driver.h"
+        #include "typedefs.h"
+
+        #include <stdlib.h>
+
+        #include "bounce.h"
+        #include "backend.h"
+
+        /*--------------------------------------------------------*/
+
+        /* --- User information --- */
+        interactive_t *all_bouncers[MAX_PLAYERS];
+
+        /* ---  Statistics --- */
+
+        p_int number_of_calls;
+
+        /*--------------------------------------------------------*/
+        void
+        add_bouncer (interactive_t *bouncer)
+
+        /* This function adds <bouncer> to the all_bouncers[].
+         */
+        {
+            int i;  /* search index */
+
+            ....
+        } /* add_bouncer() */
+
+        /**********************************************************/
+
diff --git a/doc/driver/commandline b/doc/driver/commandline
new file mode 100644
index 0000000..6e197e9
--- /dev/null
+++ b/doc/driver/commandline
@@ -0,0 +1,60 @@
+NAME
+	commandline
+
+DESCRIPTION
+	The driver understands several command line options and
+	arguments.
+
+	-f<string>: When the master object is loaded and fully
+		    operational after startup, the function flag()
+		    with argument string is applied to the master
+		    object for each occurence of -f in the command line.
+
+	-o	  : run in compat mode (thus sometimes also called
+		    -o mode), instead of native mode. Note: the flag
+		    is obsolete by now, the driver must be compiled
+		    with the appropriate definitions in the config.h
+		    instead.
+
+	-c	  : trace compilations.
+
+	-Dsymbol  : Globally pre-#define symbol for preprocessor.
+
+	-D	  : without symbol, this logs specific trace messages
+		    to /log/D_TRACE (if the driver was compiled for it)
+
+	-e	  : The number of occurences of the -e flag is
+		    passed as argument to the epilog() function
+		    in the master at startup time.
+
+	-N	  : Don't start the erq demon.
+
+	-M<master>: provide a different name for the master object.
+
+	-m<dir>	  : provide a different mudlib directory.
+
+	-ru<size> : set the size of the reserved user memory.
+	-rm<size> : set the size of the reserved master memory.
+	-rs<size> : set the size of the reserved system memory.
+
+	-E<cost>  : set the maximum allowed evaluation cost.
+
+	--max_malloced : set maximum size of mallocable memory chunks.
+	--max_small_malloced : set max. size of mallocable memory chunks.
+
+	-u<port> : set the UDP port number for IMP communication.
+
+	-t	 : disable heart_beat and reset.
+
+	-d	 : run with debug.
+
+	-s<time> : Set the time between swapout attempts. -1 means
+		   don't swap.
+
+	-y	 : If the driver has been compiled with YYDEBUG,
+		   this will enable debug output for the LPC compiler.
+
+	<number> : the TCP port number to use for user connections.
+
+SEE ALSO
+	flag(M), epilog(M), native(C), imp(C)
diff --git a/doc/driver/copyright-issue b/doc/driver/copyright-issue
new file mode 100644
index 0000000..9f086a5
--- /dev/null
+++ b/doc/driver/copyright-issue
@@ -0,0 +1,252 @@
+The question of the Copyright and Terms of Use for the driver is an old
+one. Here is what I could salvage from the amylaar-users mailing list.
+Important is Jacob's mail I received in 1999 which essentially casts
+the current copyright terms in stone.
+
+  -- Lars (not /Lars)
+
+-------------------------------------------------------------------------------
+Date: Sat, 13 Nov 1993 03:11:29 +0100 (MET)
+From: amylaar@meolyon.hanse.de (Joern Rennecke)
+Subject: LPmud Copyright
+To: busey@ux1.cso.uiuc.edu (busey andrew), lars@cd.chalmers.se,
+        croes@swi.psy.uva.nl, gusar@uniwa.uwa.OZ.AU, duening@ibr.cs.tu-bs.de,
+        jacob@cd.chalmers.se, r_behren@informatik.uni-kl.de,
+        mud@alijku05.edvz.uni-linz.ac.at, alcaman@cs.tu-berlin.de
+
+Motivation of this letter:
+There seems to be a potential for muds that run on dedicated machines
+that charge fees from player to make the mud economically feasible.
+The Copyright file says that LPmud can freely used iff it is not for
+monetary gain. Now the debate what constitutes monetary gain and if
+an individual license is an license to break the copyright,
+is an interpretation of the license in Copyright or gives rights
+independent the restrictions in Copyright has become a normal flame
+war in the rec.games.mud.* groups. That is to say, one of the worst
+thinkable.
+
+To allow muds to charge fees to cover costs, without going through
+such debates every time, I suggest to amend the Copyright file
+with terms under witch such a mud is considered to comply to the
+'no monetary gain clause' .
+
+Explanation of the recipient list and some individual messages:
+
+Busey Andrew: wants to set up a mud that charges fees to cover costs.
+  If the below rules won't make it into the Copyright, you can regard this
+  as a license - of course only for the code written by me.
+Lars Pensj|: original author.
+  Please forward this letter to other authors that have contributed to 3.1.2
+  who have a say in the copyright.
+Felix A. Croes: wrote the non-corrupting indentation code for ed.
+Sean A Reith: wrote Mud-sprintf() .
+Lars Duening: wrote the Amiga port.
+Reimer Behrends: wrote mergesort based sort_array() .
+Herp: wrote get_object_actions() .
+Jacob Hallen: is one of the people involved with the CD driver; the email
+ address was in the news recently...
+  Please forward this letter to the person holding the copyright for the
+  UDP connectivity(unless it's yourself :-) .
+Alexander Weidt:
+  Please try to forward this letter to my brother...
+
+I hope to finally get terms which all autors can agree on that can be included
+into the Copyright file. I suggest group replies, so that we can get some
+kind of discussion going (unless there is immediate approval from all
+authors :-) . When you have objections, please try to point out what is
+wrong with these terms. Even better would it be if you had a solution
+to the problem.
+
+        Joern Rennecke (Amylaar)
+
+Proposed Terms:
+1. A LPmud may charge fees from players to cover running and machine costs.
+2. Running costs in these terms are the cost for the network connection,
+   electric power to operate the host machine, wear of backup media,
+   repair costs for the host machine, and cost for a bank account.
+   For the costs of a bank account to be considered runnung costs,
+   they must not habe been considered according to 8. , and the
+   institute has to be choosen with at least usual consideration on
+   terms and costs of the account and that there must be no affiliaton
+   with the institute.
+3. Money to cover running costs for a maximum of 18 month may be accumulated
+   in advance from fees to smoothe fluctation and to ensure stability of
+   the mud. The spare money has to be kept separate from personal money
+   and should be invested in trustee investment if liquidity allows.
+   If the mud is permanently put down, this money has to be refounded to the
+   playeres.
+4. Machine costs are costs for buying, installation and upgrade of the host
+   machine. The costs have to appear on a bona fide purchase / service
+   contract with a person/institution that is not affiliated with the
+   person who sets up the mud.
+   When the host machine is put out of use, or parts of it are removed for
+   other than technical reasons, are parts are nor re-inserted after the
+   technical resons for removal and not re-inserting have become void,
+   the current value of the machine that has put out of use/the removed
+   parts is to be subtracted from the machine costs.
+   If thus more money has been paid for machine costs than there are
+   currently, the surplus amount has to be refounded to the mud players.
+5. The machine cost share in the fee may not be more than 1/2400th
+   of the machine costs per month. If the mud has less than 100 players,
+   it may be up to machine costs / 24 / number of players, but not more than
+   1/120th of the machine costs per month.
+6. When money has to be payed back to the mud players, only those that
+   have payed at least once a fee within the last 24 month are to be
+   considered. For these players, the money is distributed in the ratio
+   of the all fee shares ever payed to cover machine costs.
+7. All players pay equal fees.
+8. Banking costs that have to be paid by the mud administration and are
+   immediately connected to incoming money transactions can be subtracted
+   from the transferred amount before counting it as payment of fees,
+   provided that the institute was choosen with at least usual
+   consideration on terms and costs of the account, and that there is
+   no affiliaton with the institute.
+9. The amount of voluntary donations is unlimited. A donation is not
+   considered voluntary if it is connected with special features or
+   favours in the mud other than an hounarary mentioning of the donor,
+   or if the donor is made to believe that such a connection exists.
+   Reasonable measures have to be taken that there is no
+   misunderstanding on this point.
+
+Comments:
+3. You may not use the money of the mud to bridge personal inliquidity.
+   Don't gamble with other persons money, e.g. investing it in junk bonds.
+5. Fees should not be arbitrarily raised so that players can be driven
+   out. I considered a fixed minimal distributen of the costs to be
+   the best means to codify this.
+   Absolute figures are bound to become void by inflation.
+6. The 24 month period is introduced to allow to erease records of
+   clients after two years, and to keep overhead affordable.
+7. We don't want favourites to get a free lift, and others grudgingly
+   paying extra. If you think somebody needs free access, find someone
+   who pays for it, or make a found payed from voluntary donations.
+
+-------------------------------------------------------------------------------
+Date: Fri, 19 Nov 1993 17:10:44 +0100 (MET)
+From: Lars Pensj| <lars@cd.chalmers.se>
+Subject: Re: LPmud Copyright
+To: amylaar@meolyon.hanse.de (Joern Rennecke)
+Cc: busey@ux1.cso.uiuc.edu, lars@cd.chalmers.se, croes@swi.psy.uva.nl,
+        gusar@uniwa.uwa.OZ.AU, duening@ibr.cs.tu-bs.de, jacob@cd.chalmers.se,
+        r_behren@informatik.uni-kl.de, mud@alijku05.edvz.uni-linz.ac.at,
+        alcaman@cs.tu-berlin.de
+
+I agree that fix of the copyright is needed. I would prefer to use the
+Gnu Copyleft, as I don't care any longer if anyone makes money from it. The
+important thing is that it is free, which means noone will be able to make
+much money anyway.
+
+Any thoughts about it ?
+
+/Lars
+
+-------------------------------------------------------------------------------
+Date: Fri, 19 Nov 1993 20:14:10 +0100 (MET)
+From: Jacob Hallen <jacob@cd.chalmers.se>
+Subject: Re: LPmud Copyright
+To: amylaar@meolyon.hanse.de (Joern Rennecke)
+Cc: busey@ux1.cso.uiuc.edu, lars@cd.chalmers.se, croes@swi.psy.uva.nl,
+        gusar@uniwa.uwa.OZ.AU, duening@ibr.cs.tu-bs.de, jacob@cd.chalmers.se,
+        r_behren@informatik.uni-kl.de, mud@alijku05.edvz.uni-linz.ac.at,
+        alcaman@cs.tu-berlin.de
+
+> Jacob Hallen: is one of the people involved with the CD driver; the email
+>  address was in the news recently...
+>   Please forward this letter to the person holding the copyright for the
+>   UDP connectivity(unless it's yourself :-) .
+
+I represent everyone involved in the CD driver. The UDP stuff is to be
+considered public domain. All other parts are covered by the non-profit clause.
+Code origination from me, Johan Andersson (Commander), Ronny Wikh (Mrpr),
+Lennart Augustsson (Marvin) is covered by it. We have no intention of
+allowing people to charge money for the usage of our driver, or borrowed
+pieces thereof.
+We consider the acceptance of volontary donations as fair practice, and we
+can accept the charging for the use of extra equipment needed to allow
+people to access the mud, as long as there is a reasonable way to access the
+mud without being charged. (Providing modem access at a cost while allowing
+free access over the internet is an example of such a setup.)
+
+My personal view is that an elaborate setup of terms like the one in the
+original letter is unreasonable. It is designed for a very specific set of
+circumstances. It is impossible to check and it is very bureaucratic.
+It does not have my support.
+
+Jacob Hallen
+
+-------------------------------------------------------------------------------
+Date: Sat, 20 Nov 1993 23:35:12 +0100 (MET)
+From: Multi User Dungeon <mud@alijku05.edvz.uni-linz.ac.at>
+Subject: Re: LPmud Copyright
+To: lars@cd.chalmers.se (Lars Pensj|)
+Cc: busey@ux1.cso.uiuc.edu, croes@swi.psy.uva.nl, gusar@uniwa.uwa.OZ.AU,
+        duening@ibr.cs.tu-bs.de, jacob@cd.chalmers.se,
+        r_behren@informatik.uni-kl.de, alcaman@cs.tu-berlin.de
+
+Lars> important thing is that it is free, which means noone will be able to make
+Lars> much money anyway.
+
+You are speaking about the GD,correct ? Normally, many a site uses an unmodified
+GD based upon which is a more or less heavily or not heavily Mudlib. Based upon
+this Mudlib is the work of the `wizards' ... Sorry for repeating known stuff.
+
+This makes most Muds differ from each other. So, the fact that the GD itself
+is free, doesn't imply that you won't make money.
+
+Another point to argue: maintainig a Mud takes time .. a LOT of time. Usually,
+doing so is not fun at all. I experienced that the more players you have, the
+less fun it is fore the adminstrators. You spend a lot of time coding,
+searching and fixing bugs ... and I think, this can be regarded as a
+service for players (... and players really can be a pain sometimes ...)
+Would it be legal to charge money for that ?
+
+Another thought: Internet Muds. They run on internet, usually on computers
+owned by a school or university, some with, some without the knowledge of
+the site adminstrators. Would it be legal to charge money when you run
+a Mud on equipment not owned by yourself ? And, even if you own the computer,
+do you pay for the internet link ? If not, I fear you must not charge money
+for a Mud without speaking with the network adminstrator since you are using
+the network components (router/bridges, even cables :-> ...) for free.
+
+How difficult is charging money in European Muds ? Not that I plan
+to do so for HM (it's closed for players currently anyway), but isn't there a
+big difference according to the "accounting mechanism" (ugh, bad english :-)
+that is used in the States ? I heard that it is much more easy to make
+financial transactions within the States. So, I suspect the "Mud money charging"
+discussion arrives from the US :-)
+
+Greetings, Herp (mud@mud.uni-linz.ac.at)
+
+------------------------------------------------------------------------------
+From jacob@cd.chalmers.se Sun Oct 24 17:02:53 1999
+Newsgroups: rec.games.mud.admin
+Subject: Re: Newsgroups
+From: jacob@cd.chalmers.se (Jacob Hallen)
+Date: 24 Oct 1999 16:02:53 GMT
+
+In article <380f817d.35916528@news.earthlink.net>,
+Lars Duening <lars@bearnip.com> wrote:
+>On Thu, 21 Oct 1999 12:11:36 -0700, Ilya
+><ilya@spam.free.gamecommandos.com> wrote:
+>
+>>Hey Lars, what hope is there, if any, of getting
+>>something going in the LP world, using LDmud or
+>>whatever,  that can be used commercially?
+>
+>Unfortunately only slim hope: the parts written by the Genesis folks
+>are definitely non-commercial; but rewriting is difficult because
+>nobody remembers _which_ parts are concerned (and mailed requests
+>haven't been answered). And I haven't asked the other contributors
+>yet, either.
+
+I have a pretty good idea of who wrote what parts of the early version 3
+gamedrivers. All in all there have been about 30 people involved. Unless
+you recode the entire gamedriver from scratch, or build from assembled pieces
+with known copyright restrictions, there is no way you can come up with
+something that does not infringe on the rights of someone who will not
+allow commecial use.
+
+Jacob Hallén
+
+------------------------------------------------------------------------------
+
diff --git a/doc/driver/debugmalloc b/doc/driver/debugmalloc
new file mode 100644
index 0000000..8f78bae
--- /dev/null
+++ b/doc/driver/debugmalloc
@@ -0,0 +1,17 @@
+NAME
+        debugmalloc
+
+DESCRIPTION
+        This command is hardcoded into the driver.
+
+        Toggles the debug mode for the memory managment.
+        If the O_IS_WIZARD flag is used in the mudlib (i.e. if
+        set_is_wizard() was called), this command is allowed only for
+        users that have this flag set.
+
+HISTORY
+        Deactivated in 3.2.7 by default, it was effectless before anyway.
+
+SEE ALSO
+        malloc(D), status(D), memory(C), objects(C), debug_info(E),
+        set_is_wizard(E)
diff --git a/doc/driver/driver b/doc/driver/driver
new file mode 100644
index 0000000..40430e8
--- /dev/null
+++ b/doc/driver/driver
@@ -0,0 +1,15 @@
+NAME
+        driver
+
+DESCRIPTION
+        This directory contains descriptions of miscellaneous
+        internals of Amylaar's version of the LPC parser/interpreter,
+        that might be useful to know.
+
+        One thing described here are the special hardcoded commands
+        of the interpreter for querying the status of the memory
+        management.
+
+SEE ALSO
+        efun(E), applied(A), concepts(C), master(M), lpc(LPC),
+        malloc(D), status(D)
diff --git a/doc/driver/dumpallobj b/doc/driver/dumpallobj
new file mode 100644
index 0000000..24b884a
--- /dev/null
+++ b/doc/driver/dumpallobj
@@ -0,0 +1,49 @@
+NAME
+        dumpallobj
+
+DESCRIPTION
+        Write a list of all loaded or cloned objects into the file
+        OBJ_DUMP, and a list of all destructed objects into the
+        file DEST_OBJ_DUMP. Both files are located in the root directory of
+        the mudlib.
+
+        Warning: these files can be very large, and if the driver is low
+        on memory there is a certain crash probability.
+
+        If the O_IS_WIZARD flag is used in the mudlib (i.e. if
+        set_is_wizard() was called), this command is allowed only for
+        users that have this flag set.
+
+        For every live object, a line is written into the file with the
+        following information in the given order:
+          - object name
+          - size in memory, shared data counted only once
+          - size in memory if data wouldn't be shared
+          - number of references
+          - 'HB' if the object has a heartbeat, nothing if not.
+          - the name of the environment, or '--' if the object has no
+            environment
+          - in parentheses the number of execution ticks spent in this
+            object
+          - the swap status:
+             nothing if not swapped,
+             'PROG SWAPPED' if only the program is swapped
+             'VAR SWAPPED' if only the variabes are swapped
+             'SWAPPED' if both program and variables are swapped
+          - the time the object was created
+
+        For every destructed object, a line is written into the file with the
+        following information in the given order:
+          - object name
+          - number of references
+          - 'NEW' if the object was destructed in this executiong
+            thread, nothing if it is older already.
+
+
+HISTORY
+        LDMud 3.2.9 added the DEST_OBJ_DUMP.
+        LDMud 3.2.10 added the object creation time to OBJ_DUMP.
+
+SEE ALSO
+        malloc(D), status(D), memory(C), objects(C), debug_info(E),
+        set_is_wizard(E)
diff --git a/doc/driver/invocation b/doc/driver/invocation
new file mode 100644
index 0000000..5760b46
--- /dev/null
+++ b/doc/driver/invocation
@@ -0,0 +1,335 @@
+NAME
+    driver/invocation
+
+PURPOSE
+    Description of the invocation of the gamedriver, especially of the command
+    arguments. This document describes the commandline version of the driver
+    only; non-commandline versions are platform specific and described in
+    the related documentation.
+
+DESCRIPTION
+    The driver is invoked from the commandline as other normal programs.
+    Neither the current directory nor the directory the executable is in need
+    to be in any special relation the directory of the mudlib. Once the driver
+    is running, it emits two streams of outputs:
+
+      - driver-related messages on stderr; this unfortunately includes
+        LPC compiler diagnostics
+      - LPC runtime-related messages in the logfile <mudlib>/<host>.parse.log
+        (the name can be changed).
+
+    It is possible to start the driver without any commandline arguments as
+    suitable defaults are specified at compile time. The invocation syntax
+    is:
+
+        driver [options] [<portnumber>]...
+
+    <portnumber> the number of the port the driver shall use to accept
+    connections. The maximum number of ports is determined by MAXNUMPORTS
+    in the source file config.h.
+
+    The options modify the behaviour of the gamedriver. Some of them are only
+    available if a certain compile-time option was enabled (typically in
+    the source file config.h). The following options are recognized:
+
+      -P|--inherit <fd-number>
+        Inherit filedescriptor <fd-number> from the parent process
+        as socket to listen for connections.
+        Only available if compiled with MAXNUMPORTS.
+
+      -u|--udp <portnumber>
+        Specify the <portnumber> for the UDP port, overriding the compiled-in
+        default.
+        Only available if compiled with CATCH_UDP_PORT.
+
+      -D|--define <macro>[=<text>]
+        Add <macro> (optionally to be expanded to <text>) to the list of
+        predefined macros known by the LPC compiler.
+
+      -E|--eval-cost <ticks>
+        Set the number of <ticks> available for one evaluation thread.
+        If 0, execution is unlimited.
+
+      -M|--master <filename>
+        Use <filename> for the master object.
+
+      -m|--mudlib <pathname>
+        Use <pathname> as the top directory of the mudlib.
+
+      --debug-file <filename>
+        Log all debug output in <filename> instead of
+        <mudlib>/<host>.debug.log .
+
+      --hostname <name>
+        Use <name> as hostname instead of what the system says.
+
+      --hostaddr <addr>
+        Use <addr> as address of this machine, instead of what the
+        system says.  In particular this address will be used to open
+        the driver ports.
+
+      --no-compat
+      --compat
+        Select the mode (plain or compat) of the driver.
+        This choice does not affect the default name of the master object.
+
+      -d|--debug
+        Generate debug output; repeat the argument for even more output:
+          >= 1: log resets, clean ups, swaps, reception of urgend data,
+                   telnet negotiation states.
+                check_a_lot_of_refcounts() on startup when swapping of
+                   variables is disabled.
+          >= 2: log all add_message()s, name lookup failures, new players.
+          >= 3: progress of garbage collection
+          >= 4: even more junk from garbage collection
+
+      -c|--list-compiles
+        List the name of every compiled file on stderr.
+
+      -e|--no-preload
+        Pass a non-zero argument (the number of occurences of this option)
+        to master->preload(), which usually inhibits all preloads of castles
+        and other objects.
+
+      --erq <filename>
+      --erq "<filename> <erq args>"
+        Use <filename> instead of 'erq' as the basename of the ERQ executable.
+        If the name starts with a '/', it is take to be an absolute pathname,
+        otherwise it is interpreted relative to <bindir>. If not specified,
+        'erq' is used as the executable name.
+
+        By enclosing the argument value in quotes, it is possible to pass
+        arguments (e.g. --execdir) to the erq. These arguments however must
+        not contain embedded spaces.
+
+      -N|--no-erq
+        Don't start the erq demon (if it would be started at all).
+
+      --alarm-time <seconds>
+        Set the granularity of call_out() and heartbeat timing. Minimum
+        value is 1.
+
+      --heart-interval <seconds>
+        Set the interval between two heartbeats. Minimum value is 1.
+
+      --sync-heart
+        All heartbeats occur at the same time (modulo granularity).
+      
+      --async-heart
+        Heartbeats occur when they are due (modulo granularity).
+
+      -t|--no-heart
+        Disable heartbeats and call_outs.
+
+      -f|--funcall <word>
+        The lfun master->flag() is called with <word> as argument before the
+        gamedriver accepts netword connections.
+
+      --regexp pcre | traditional
+        Select the default regexp package.
+
+      --max-array <size>
+        The maximum number of elements an array can hold.
+        Set to 0, arrays of any size are allowed.
+
+      --max-mapping <size>
+        The maximum number of elements a mapping can hold.
+        Set to 0, mappings of any size are allowed.
+
+      --max-mapping-keys <size>
+        The maximum number of entries a mapping can hold.
+        Set to 0, mappings of any size are allowed.
+
+      --max-callouts <size>
+        The maximum number of callouts at one time.
+        Set to 0, any number is allowed.
+
+      --max-bytes <size>
+        The maximum number of bytes one read_bytes()/write_bytes() call
+        can handle.
+        Set to 0, reads and writes of any size are allowed.
+
+      --max-file <size>
+        The maximum number of bytes one read_file()/write_file() call
+        can handle.
+        Set to 0, reads and writes of any size are allowed.
+
+      --max-thread-pending <size>\n"
+        The maximum number of bytes to be kept pending by the socket write
+        thread.
+        Set to 0, an unlimited amount of data can be kept pending.
+
+        This option is ignored if pthreads are not used.
+
+      --cleanup-time <time>
+        The idle time in seconds for an object before the driver tries to
+        clean it up. It should be substantially longer than the reset time.
+        A time <= 0 disables the cleanup mechanism.
+
+      --reset-time <time>
+        The time in seconds before an object is reset. A time <= 0 disables
+        the reset mechanism.
+
+      -s <time>  | --swap-time <time>
+      -s v<time> | --swap-variables <time>
+        Time in seconds before an object (or its variables) are swapped out.
+        A time less or equal 0 disables swapping.
+
+      -s f<name> | --swap-file <name>
+        Swap into file <name> instead of <mudlib>/LP_SWAP.<host> .
+
+      -s c       | --swap-compact
+        Reuse free space in the swap file immediately.
+        Giving this option results in smaller, but also more fragmented
+        swapfiles, and the swap performance may degrade.
+
+      --max-malloc <size>
+        Restrict total memory allocations to <size> bytes.
+        A <size> of 0 or 'unlimited' removes any restriction.\n"
+
+      --min-malloc <size>
+      --min-small-malloc <size>
+        Determine the sizes for the explicite initial large resp. small chunk
+        allocation. A size of 0 disables the explicite initial allocations.
+
+      -r u<size> | --reserve-user <size>
+      -r m<size> | --reserve-master <size>
+      -r s<size> | --reserve-system <size>
+        Reserve <size> amount of memory for user/master/system allocations to
+        be held until main memory runs out.
+
+      --filename-spaces
+      --no-filename-spaces
+        Allow/disallow the use of spaces in filenames.
+
+      --strict-euids
+      --no-strict-euids
+        Enable/disable the enforced use of euids.
+
+      --share-variables
+      --init-variables
+        Select how clones initialize their variables:
+          - by sharing the current values of their blueprint
+          - by initializing them afresh (using __INIT()).
+
+      --pidfile <filename>\n"
+        Write the pid of the driver process into <filename>.\n"
+
+      --tls-key <pathname>
+          Use <pathname> as the x509 keyfile, default is 'key.pem'.
+          If relative, <pathname> is interpreted relative to <mudlib>.
+
+      --tls-cert <pathname>
+         Use <pathname> as the x509 certfile, default is 'cert.pem'.
+         If relative, <pathname> is interpreted relative to <mudlib>.
+
+      --tls-trustfile <pathname>
+        Use <pathname> as the filename holding your trusted PEM certificates.
+        If relative, <pathname> is interpreted relative to <mudlib>.
+
+      --tls-trustdirectory <pathname>
+        Use <pathname> as the directory where your trusted
+        PEM certificates reside, default is '/etc/ssl/certs'.
+        If relative, <pathname> is interpreted relative to <mudlib>.
+
+      --wizlist-file <filename>
+      --no-wizlist-file
+        Read and save the wizlist in the named file (always interpreted
+        relative the mudlib); resp. don't read or save the wizlist.
+
+      --gcollect-outfd <filename>|<num>
+        Garbage collector output (like a log of all reclaimed memory blocks)
+        is sent to <filename> (or inherited fd <num>) instead of stderr.
+        Only available if compiled with MALLOC_smalloc.
+
+      --y|--yydebug
+        Enable debugging of the LPC compiler.
+        Only available if compiled with YYDEBUG.
+
+      --random-seed <num>
+        Seed value for the random number generator. If not given, the
+        driver chooses a seed value on its own.
+        This option is for debugging.
+
+      --check-state <lvl>
+        Perform a regular simplistic check of the virtual machine according
+        to <lvl>:
+          = 0: no check
+          = 1: once per backend loop
+          = 2: at various points in the backend loop
+        Only available if compiled with DEBUG.
+
+      --check-refcounts
+        Every backend cycle, all refcounts in the system are checked.
+        SLOW! Only available if compiled with DEBUG.
+
+      --gobble-descriptors <num>
+        <num> (more) filedescriptors are used up. You'll know when you need it.
+        Only available if compiled with DEBUG.
+
+      --check-strings
+        Every backend cycle, all shared strings in the system are checked.
+        SLOW! Only available if compiled with DEBUG and CHECK_STRINGS.
+
+      -V|--version
+        Print the version of the driver and exit.
+
+      --options
+        Print the version and compilation options of the driver and exit.
+
+      -h|-?|--help
+        Display a command help and exit.
+
+      --longhelp
+        Display a long command help and exit.
+
+      --args <filename>
+        The driver reads and parses the given file and treats its contents
+        as if given on the commandline right where the --args option
+        occured. The file itself can again contain --args options.
+
+
+DESCRIPTION -- Argument Parser
+    The parser analyses the commandline arguments given with the driver
+    invocation and distinguishes 'options', which start with a '-', from
+    proper arguments. Options are further distinguished by their name and
+    may take an additional value. In general, options and arguments can be
+    givein in any order.
+
+    Options are recognized in two forms. In the short form the option must
+    be given as a single '-' followed by a single letter. In the long form,
+    options start with '--' followed by a string of arbitrary length. The
+    short options are case sensitive, the long options aren't.
+    Most options can be specified in both the short and long form, but that
+    is not mandatory. Examples: '-r' and '--recursive'.
+
+    If an option takes a value, it must follow the option immediately after
+    a separating space or '='. Additionally, the value for a short option
+    may follow the option without separator. Examples are: '-fMakefile',
+    '-f Makefile', '--file=Makefile' and '--file Makefile'.
+
+    Short options may be collated into one argument, e.g. '-rtl', but
+    of these only the last may take a value.
+
+    The option '--' marks the end of options. All following command arguments
+    are considered proper arguments even if they start with a '-' or '--'.
+
+    The arguments are usually taken from the commandline; but the parser
+    is also able to read them from a textfiles, which can be nested. The
+    content of the textfiles is broken down into words delimited by whitespace,
+    which are then treated as given on the commandline at the place where
+    the instruction to read the textfile stood.
+
+    The file parser recognizes simple double-quoted strings, which must be
+    contained on a single line. Additionally, the '#' character given by
+    itself is a comment marker - everthing after the '#' until the end
+    of the current line is ignored.
+
+HISTORY
+    LDMud 3.2.9 added the --max-thread-pending, --hostname,
+      --hostaddr, --args and --random-seed options.
+    LDMud 3.2.10 added the --filename-spaces options.
+    LDMud 3.3.378 added --share-variables, --init-variables.
+    LDMud 3.3.475/3.2.11 added --tls-key, --tls-cert.
+    LDMud 3.3.672/3.2.11 added --tls-trustfile, --tls-trustdirectory.
+    LDMud 3.3.677 added --max-mapping-keys.
diff --git a/doc/driver/malloc b/doc/driver/malloc
new file mode 100644
index 0000000..7fb2722
--- /dev/null
+++ b/doc/driver/malloc
@@ -0,0 +1,12 @@
+NAME
+        malloc
+
+DESCRIPTION
+        This command is hardcoded into the driver's input parser.
+        It shows the statistics of the memory management module.
+
+HISTORY
+        Since 3.2.7, 'status malloc' has the same effect.
+
+SEE ALSO
+        status(D), memory(C), debug_info(E)
diff --git a/doc/driver/opcdump b/doc/driver/opcdump
new file mode 100644
index 0000000..b75ea68
--- /dev/null
+++ b/doc/driver/opcdump
@@ -0,0 +1,13 @@
+NAME
+        opcdump
+
+DESCRIPTION
+        If the driver was compiled to do opcode profiling, this command
+        will save the collected profiling information into the file /OPC_DUMP.
+        If the O_IS_WIZARD flag is used in the mudlib (i.e. if
+        set_is_wizard() was called), this command is allowed only for
+        users that have this flag set.
+
+SEE ALSO
+        malloc(D), status(D), memory(C), objects(C), debug_info(E),
+        set_is_wizard(E)
diff --git a/doc/driver/predefined b/doc/driver/predefined
new file mode 100644
index 0000000..17a7eb0
--- /dev/null
+++ b/doc/driver/predefined
@@ -0,0 +1,130 @@
+NAME
+    predefined - predefined #defines by the parser
+
+DESCRIPTION
+    Several preprocessor macros are pre#defined by the parser,
+    to provide information about parser version, compile time
+    options and parser invocation options:
+
+      LPC3            : always defined.
+      __LDMUD__       : always defined.
+      __EUIDS__       : always (for compatibility).
+      COMPAT_FLAG     : defined if the driver runs in compat mode.
+      __COMPAT_MODE__ : ditto
+      __STRICT_EUIDS__: defined if strict euid usage is enforced.
+      __FILENAME_SPACES__: defined if filenames may contain spaces.
+
+      __MASTER_OBJECT__ : the name of the master object (in compat mode
+                          without leading '/').
+      __FILE__          : the name of the compiled file (in compat mode
+                          without leading '/').
+      __LINE__          : the current line number.
+      __FUNCTION__      : the current function name.
+      __DIR__           : the directory path of the compiled file (in
+                          compat mode without leading '/').
+      __PATH__(n)       : the directory path of the compiled file without
+                          the <n> trailing elements (in compat mode without
+                          leading '/').
+      __VERSION__       : the version string of the driver.
+      __VERSION_MAJOR__ : the major version number of the driver.
+      __VERSION_MINOR__ : the minor version number of the driver.
+      __VERSION_MICRO__ : the micro version number of the driver.
+      __VERSION_PATCH__ : the patchlevel of the driver; a 0 here means
+                          'no patchlevel'.
+      __VERSION_COMMITID__ : the commit ID of the source of the driver 
+                             (attention: it might be <unknown>, if the driver
+                              was not compiled from a git repository)
+      __VERSION_LOCAL__ : the (optional) LOCAL_LEVEL, the user has defined.
+
+
+      __DOMAIN_NAME__    : the domain the host is part of.
+      __HOST_IP_NUMBER__ : the hosts IP number (as a string).
+      __HOST_NAME__      : the full hostname.
+      __MAX_RECURSION__  : the max count of nested function calls
+                           (this is config.h:MAX_USER_TRACE).
+      __MAX_EVAL_COST__  : the max evaluation cost.
+      __RESET_TIME__     : default interval time between object resets.
+      __CLEANUP_TIME__   : default interval time between object cleanups.
+      __ALARM_TIME__     : the configured timing granularity.
+      __HEART_BEAT_INTERVAL__: the configured heartbeat time.
+      __SYNCHRONOUS_HEART_BEAT__: defined if synchronous heartbeats are
+                           enabled.
+      __MAX_COMMAND_LENGTH__: the maximum length a command can have.
+      __EFUN_DEFINED__(name) : if the efun 'name' exists, this
+                               macro evaluates to " 1 ", else to " 0 ".
+      __DRIVER_LOG__     : the name of the default debug.log file (within
+                           the mudlib); undefined if a different name
+                           has been specified on the commandline.
+      __WIZLIST__        : the name of the (mudlib) file from where the
+                           driver read the initial WIZLIST information.
+                           It is undefined if the driver was configured
+                           to not read the information.
+      __MAX_MALLOC__     : the internal upper limit for total memory
+                           usage.
+      __INT_MAX__        : the largest integer number
+      __INT_MIN__        : the smallest integer number
+      __FLOAT_MAX__      : the largest (positive) float number
+      __FLOAT_MIN__      : the smallest (positive) float number
+
+      __LPC_NOSAVE__     : always defined
+      __LPC_STRUCTS__    : defined when struct support is enabled.
+                           Once structs are fully supported, this macro
+                           will always be defined.
+      __LPC_INLINE_CLOSURES__: defined when the 'real' inline closures
+                           are enabled.
+      __LPC_ARRAY_CALLS__: call_other()s on arrays of objects enabled.
+      __BOOT_TIME__      : the time() the driver was started.
+
+    If the ERQ is supported, the following macros are defined:
+
+      __ERQ_MAX_SEND__  : the max size of the send buffer
+      __ERQ_MAX_REPLY__ : the max size of the reply buffer
+
+    The following macros are defined if their associated package
+    has been compiled into the driver:
+
+      __IDNA__ :      support for IDNA
+      __IPV6__ :      support for IP v.6
+      __MYSQL__ :     support for mySQL
+      __PGSQL__ :     support for PostgreSQL
+      __SQLITE__ :    support for SQLite 3.
+      __XML_DOM__ :   support for XML parsing.
+      __JSON__ :      support for JSON parsing/serializing.
+      __MCCP__:       support for MCCP http://www.randomly.org/projects/MCCP
+      __ALISTS__:     support for alists
+      __PCRE__:       support for PCRE
+      __TLS__:        support for TLS (internal)
+      __GNUTLS__:     if __TLS__: TLS support provided by GnuTLS.
+      __OPENSSL__:    if __TLS__: TLS support provided by OpenSSL.
+      __GCRYPT__:     cryptographic routines provided by libgcrypt.
+      __DEPRECATED__: support for obsolete and deprecated efuns.
+
+
+HISTORY
+    3.2.1 added __DOMAIN_NAME__, __HOST_IP_NUMBER__, __HOST_NAME__,
+        __MAX_RECURSION__, __EFUN_DEFINED__().
+    3.2.5 added __COMPAT_MODE__, __NATIVE_MODE__, __EUIDS__,
+        __ERQ_MAX_SEND__ and __ERQ_MAX_REPLY__.
+    3.2.6 added __MAX_EVAL_COST__.
+    3.2.7 added __STRICT_EUIDS__ and made __EUIDS__ standard.
+    3.2.8 added __IPV6__, __LPC_NOSAVE__, __DIR__, __PATH__().
+    3.2.9 added __LDMUD__, __MYSQL__, __DEPRECATED__, __VERSION_MAJOR__,
+         __VERSION_MINOR__, __VERSION_MICRO__, __VERSION_PATCH__,
+         __INT_MAX__, __INT_MIN__, __FLOAT_MIN__, __FLOAT_MAX__,
+        __CATCH_EVAL_COST__, __MASTER_EVAL_COST__, __RESET_TIME__,
+        __CLEANUP_TIME__, __DRIVER_LOG__, and __WIZLIST__.
+    3.2.10 added __MAX_MALLOC__, __MSDOS_FS__, __LPC_ARRAY_CALLS__
+        and __FILENAME_SPACES__.
+    3.3 made __LPC_NOSAVE__ always defined and added __ALISTS__,
+        __MCCP__, __LPC_STRUCTS__, __LPC_INLINE_CLOSURES__, __PGSQL__,
+        __PTHREADS__, __TLS__, __BOOT_TIME__, __ALARM_TIME__,
+        __HEART_BEAT_INTERVAL__, __SYNCHRONOUS_HEART_BEAT__, and __PCRE__.
+    3.3.713 added __IDNA__, __SQLITE__.
+    3.3.714 added __OPENSSL__, __GNUTLS__.
+    3.3.718 added __XML_DOM__.
+    3.3.719 removed __PTHREADS__, AMIGA, MSDOS_FS, __BEOS__  
+		    and added __GCRYPT__.
+    3.3.721 added __FUNCTION__.
+
+SEE ALSO
+    pragma(LPC), preprocessor(LPC)
diff --git a/doc/driver/showsmallnewmalloced b/doc/driver/showsmallnewmalloced
new file mode 100644
index 0000000..17e2252
--- /dev/null
+++ b/doc/driver/showsmallnewmalloced
@@ -0,0 +1,17 @@
+NAME
+        showsmallnewmalloced
+
+DESCRIPTION
+        This command is hardcoded into the driver.
+
+        Shows a list of recently allocated small memory blocks.
+        If the O_IS_WIZARD flag is used in the mudlib (i.e. if
+        set_is_wizard() was called), this command is allowed only for
+        users that have this flag set.
+
+HISTORY
+        Deactivated in 3.2.7 by default.
+
+SEE ALSO
+        malloc(D), status(D), memory(C), objects(C), debug_info(E),
+        set_is_wizard(E)
diff --git a/doc/driver/status b/doc/driver/status
new file mode 100644
index 0000000..79759dd
--- /dev/null
+++ b/doc/driver/status
@@ -0,0 +1,18 @@
+NAME
+        status
+        status tables
+        status swap
+        status malloc
+
+DESCRIPTION
+        This command is hardcoded into the drivers input routine.
+        It displays information about the run status of the system.
+        If the O_IS_WIZARD flag is used in the mudlib (i.e. if
+        set_is_wizard() was called), this command is allowed only for
+        users that have this flag set.
+
+HISTORY
+        3.2.7 added the 'status malloc' variant.
+
+SEE ALSO
+        malloc(D), memory(C), objects(C), debug_info(E), set_is_wizard(E)
diff --git a/doc/efun/.default b/doc/efun/.default
new file mode 100644
index 0000000..2560e19
--- /dev/null
+++ b/doc/efun/.default
@@ -0,0 +1,14 @@
+FUNKTION:
+
+ARGUMENTE:
+
+BESCHREIBUNG:
+
+RUECKGABEWERT:
+
+BEMERKUNGEN:
+
+BEISPIELE:
+
+SIEHE AUCH:
+
diff --git a/doc/efun/.synonym b/doc/efun/.synonym
new file mode 100644
index 0000000..f024a1b
--- /dev/null
+++ b/doc/efun/.synonym
@@ -0,0 +1,3 @@
+round ceil
+trunc ceil
+efun::m_delete efun__m_delete
diff --git "a/doc/efun/\133\135" "b/doc/efun/\133\135"
new file mode 100644
index 0000000..a59696a
--- /dev/null
+++ "b/doc/efun/\133\135"
@@ -0,0 +1,66 @@
+SYNOPSIS
+        mixed  arr[index];
+        int    str[index];
+
+        *mixed arr[from .. to];
+        string str[from .. to];
+
+BESCHREIBUNG
+        Liefert ein Element aus einem Array oder String (erste Form), oder
+        eine Teilmenge (zweite Form).
+
+        Die Indizes <index>, <from> und <to> sind durchnummeriert von 0 bis
+        strlen(<str>)-1 bzw. sizeof(<arr>)-1. Wenn ein <index> als '<wert'
+        geschrieben wird, wird der Wert vom Ende des Stings / Arrays her
+        gezaehlt. Dabei wird nummeriert von 1 bis strlen(<str>) bzw.
+        sizeof(<arr>). Wird <from> weggelassen, beginnt die Teilmenge mit
+        dem ersten Element. Wird <to> weggelassen, endet die Teilmenge mit
+        dem letzten Element.
+
+        In der ersten Form muss <index> innerhalb der Grenzen des Strings /
+        Arrays sein, sonst wird ein Laufzeitfehler (RTE) verursacht. In der
+        zweiten Form werden die Indizes an die Groesse des Strings / Arrays
+        angepasst. Wenn <from> groesser ist als <to> oder beide ausserhalb
+        der Groesse des Strings / Arrays liegen, wird ein leerer String ""
+        bzw. ein leeres Array ({}) zurueck geliefert.
+
+        Die Notation als Closure ist entsprechend:
+
+            [index]      -> ({'#[,      arr, index })
+            [<index]     -> ({'#[<,     arr, index })
+            [from..to]   -> ({'#[..],   arr, from, to })
+            [<from..to]  -> ({'#[<..],  arr, from, to })
+            [from..<to]  -> ({'#[..<],  arr, from, to })
+            [<from..<to] -> ({'#[<..<], arr, from, to })
+
+BEISPIELE
+        foo = ({ 1, 2, 3, 4 });         str = "test";
+
+        foo[1]     -> 1                 str[1] -> 'e' == 101
+        foo[1..2]  -> ({ 2, 3 })        str[1..2]  -> "es"
+        foo[2..1]  -> ({ })             str[2..1]  -> ""
+        foo[0..<2] -> ({ 1, 2 })        str[0..<2]  -> "tes"
+
+        foo[..<2]  -> ({ 1, 2 })        str[..<2]  -> "tes"
+        foo[<3..]  -> ({ 2, 3, 4 })     str[<3..]  -> "est"
+
+        foo[1] = 5                      -> foo == ({ 1, 5, 3, 4 })
+        foo[1..2] = ({ 5, 6, 7 })       -> foo == ({ 1, 5, 6, 7, 4 })
+        foo[1..2] = ({ })               -> foo == ({ 1, 4 })
+
+        str[1] = 'a'                    -> str == "tast"
+        str[1..2] = "bar"               -> str == "tbart"
+        str[1..2] = ""                  -> str == "tt"
+
+AENDERUNGEN
+        slice_array() ist die alte Form der []-Operatoren fuer Arrays,
+        extract() ist die alte Form der []-Operatoren fuer Strings.
+        BEIDE VARIANTEN SIND VERALTET, WERDEN NICHT MEHR UNTERSTUETZT UND
+        SOLLTEN DESHALB NICHT MEHR VERWENDET WERDEN.
+
+        Die Syntax fuer 'rueckwaerts zaehlen vom letzten Element' hat sich von
+        Version 3.1.J zu 3.1.K geaendert von '-1' zu '<1'. Auch ist seit dann
+        foo[0..-1] ein leeres Array bzw. ein leerer String.
+
+SIEHE AUCH
+        member(E), sizeof(E), slice_array(E)
diff --git a/doc/efun/abs b/doc/efun/abs
new file mode 100644
index 0000000..586beea
--- /dev/null
+++ b/doc/efun/abs
@@ -0,0 +1,20 @@
+SYNOPSIS
+        int   abs (int arg)
+        float abs (float arg)
+
+BESCHREIBUNG
+        Liefert den Betrag des Argumentes <arg>.
+
+BEISPIELE
+        Funktion      Rueckgabewert
+        -------------------------------------------------------------------
+        abs(-18    )  18
+        abs( 11    )  11
+        abs( -1.974)   1.974
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6.
+
+SIEHE AUCH
+        sin(E), asin(E), cos(E), acos(E), tan(E), atan(E), log(E), exp(E),
+        sqrt(E), floor(E), ceil(E), pow(E), sgn(E)
diff --git a/doc/efun/acos b/doc/efun/acos
new file mode 100644
index 0000000..2487958
--- /dev/null
+++ b/doc/efun/acos
@@ -0,0 +1,8 @@
+SYNOPSIS
+        float acos(float)
+
+BESCHREIBUNG
+        Liefert der Arkuskosinus des Argumentes.
+
+SIEHE AUCH
+        sin(E), asin(E), cos(E), tan(E), atan(E), atan2(E)
diff --git a/doc/efun/add_action b/doc/efun/add_action
new file mode 100644
index 0000000..8b0f778
--- /dev/null
+++ b/doc/efun/add_action
@@ -0,0 +1,149 @@
+add_action(E)
+FUNKTION:
+     void add_action(string fun, string cmd)
+     void add_action(string fun, string cmd, int flag)
+
+ARGUMENTE:
+     fun
+	gerufene Methode
+     cmd
+	ausloesendes Verb
+     flag
+	Flag fuer unscharfe Interpretation
+
+BESCHREIBUNG:
+     Generell: Das Verhalten dieser efun wird durch AddCmd aus
+               /std/thing/commands.c komfortabler widergespiegelt.
+               Darauf sollte man zurueckgreifen.
+
+     Legt fuer "cmd" (ein Kommandoverb) eine im entsprechenden Objekt
+     zu rufende Methode fest.
+
+     Diese Methode bekommt die Argumente als String uebergeben und
+     muss 0 (fuer einen Fehler) oder 1 (fuer Erfolg) zurueckgeben.
+
+     Der Parser durchsucht bei einer Spielereingabe die Liste der
+     eingetragenen Kommandos nach passenden Kommandos und ruft die
+     zugehoerigen Methoden in den Objekten bis eine der Methoden
+     1 zurueckgibt oder die Liste durchlaufen wurde. In dem Fall
+     kommt die Fehlermeldung (notify_fail()) zum Einsatz.
+
+     Mit Werten != 0 fuer "flag" legt man eine unscharfe Auswertung
+     fest, im Beispiel: Die Methode "action_fun" bei einem
+      add_action("action_fun", "hops", 1);
+     wird sowohl beim Kommando "hops" als auch bei Kommandos wie
+     "hopse", "hopseblub", ... gerufen werden.
+     Dieses Flag sollte vorsichtig verwendet werden.
+
+     Es gibt drei moegliche Verhaltensweise, die per "flag" eingeschaltet
+     werden koennen:
+     Wenn das Argument <flag> AA_SHORT (d.h. 1) ist, koennen Argumente von
+     cmd ohne einen Leerschlag an cmd angehaengt sein. An die Funktion fun
+     werden alle Zeichen nach dem ersten Leerschlag als Argument
+     uebergeben.
+
+     Wenn <flag> AA_NOSPACE (d.h. 2) ist, koennen die Argumente wiederum
+     ohne Leerschlag ans Verb angehaengt sein. Im Unterschied zu AA_SHORT
+     werden alle Zeichen nach dem Verb als Argument an die Funktion
+     uebergeben. Die Zeichen, welche nicht durch einen Leerschlag vom
+     Verb getrennt sind, werden ZUSAETZLICH von query_verb() zurueck
+     gegeben.
+
+     Wenn <flag> AA_IMM_ARGS (3) ist, werden alle Zeichen nach dem Verb
+     als Argument uebergeben, nicht aber von query_verb() beruecksichtigt.
+
+
+BEMERKUNGEN:
+     (1) add_action() sollte immer innerhalb von init() benutzt werden
+     (2) das definierende Objekt muss im inventory des Spielers oder
+         environment() des kommandogebenden Lebewesens sein
+     (3) im init() spaeter eingetragene Kommandos oder spaeter hinzu-
+         kommende Objekte werden bei der Kommandoauswertung VOR den
+         alten beruecksichtigt
+         (Daher bewegt sich das Xtool der Magier regelmaessing neu in
+          das Inventory, um immer "erstes" Objekt zu sein.)
+
+BEISPIELE:
+     // ein Kommando in einem Schirm
+     void init() {
+      ::init();
+      add_action("action_oeffne", "oeffne");
+     }
+
+     int action_oeffne(string str) {
+      if(stringp(str) && id(str))	// Argument da und bin ich gemeint?
+       write("Du oeffnest den Schirm.\n");
+       say(break_string(this_player()->Name(WER)+" oeffnet einen Schirm.",78));
+       return 1;
+      }
+      notify_fail("Was willst Du oeffnen?\n");
+      return 0;
+     }
+
+     // frueher beliebt um Spieler lahmzulegen, da es _alle_ Kommandos 
+     // triggert -> siehe heute jedoch dafuer eher P_DISABLE_COMMANDS
+     // Achtung: siehe Implikation von (3)
+     add_action("action_nothing", "",1 );
+     ...
+     int action_nothing(string str) {
+      write("Dir sind die Haende gebunden.\n");
+      return 1;
+     }
+
+     Beispiele fuer die Verwendung des Argumentes "flag":
+      add_action("disfunc", "disconnect", AA_NOSPACE);
+
+        Die Funktion disfunc() wird aufgerufen, wenn der Spieler "disconnect"
+        oder eine Abkuerzung davon (zum Beispiel "di" oder "discon") eingibt.
+        Laengere Worte (zum Beispiel "disconnecting") werden NICHT erkannt.
+        Um rauszufinden, was der Spieler tatsaechlich eingegeben hat, muss
+        query_verb() aufgerufen werden.
+
+      add_action("fun", "cmd");
+      add_action("fun", "scmd", AA_SHORT);
+      add_action("fun", "ncmd", AA_NOSPACE);
+      add_action("fun", "icmd", AA_IMM_ARGS);
+
+        Die folgende Tabelle zeigt, was die oben aufgefuehrten Kommandos bzw.
+        <flag> fuer Werte an query_verb() und als Argumente an die Funktion
+        fun uebergeben:
+        |-------------------|--------------|----------------------------|
+        | Eingabe           | query_verb() | Argument der Funktion fun  |
+        |-------------------|--------------|----------------------------|
+        | "cmd"             | "cmd"        | 0                          |
+        | "cmd bla fasel"   | "cmd"        | "bla fasel"                |
+        |-------------------|--------------|----------------------------|
+        | "scmd"            | "scmd"       | 0                          |
+        | "scmd bla"        | "scmd"       | "bla"                      |
+        | "scmdbla"         | "scmdbla"    | 0                          |
+        | "scmd bla fasel"  | "scmd"       | "bla fasel"                |
+        | "scmdbla fasel"   | "scmdbla"    | "fasel"                    |
+        |-------------------|--------------|----------------------------|
+        | "ncmd"            | "ncmd"       | 0                          |
+        | "ncmd bla"        | "ncmd"       | " bla"                     |
+        | "ncmdbla"         | "ncmdbla"    | "bla"                      |
+        | "ncmd bla fasel"  | "ncmd"       | " bla fasel"               |
+        | "ncmdbla fasel"   | "ncmdbla"    | "bla fasel"                |
+        |-------------------|--------------|----------------------------|
+        | "icmd"            | "icmd"       | 0                          |
+        | "icmd bla"        | "icmd"       | " bla"                     |
+        | "icmdbla"         | "icmd"       | "bla"                      |
+        | "icmd bla fasel"  | "icmd"       | " bla fasel"               |
+        | "icmdbla fasel"   | "icmd"       | "bla fasel"                |
+        |-------------------|--------------|----------------------------|
+
+
+GESCHICHTE
+        Das Argument <flag> < 0 wird seit 3.2@127 unterstuetzt, aber erst ab
+        LDMud 3.2.8 richtig implementiert. LDMud 3.2.9 fuehrte das AA_IMM_ARGS
+        Flag ein. Ab LDMud 3.5 kann man Closures als Funktionen uebergeben.
+
+SIEHE AUCH:
+			remove_action(E), init(E), enable_commands(E)
+     Fehlermeldung:	notify_fail(E), _notify_fail(E)
+     Argumentstring:	query_verb(E), _unparsed_args(L)
+     obsolet:		add_verb(E), add_xverb(E)
+     alternativ:	AddAction(L), AddCmd(L)
+                        P_DISABLE_COMMANDS
+
+24. Maerz 2004 Gloinson@MG
diff --git a/doc/efun/all_environment b/doc/efun/all_environment
new file mode 100644
index 0000000..993f493
--- /dev/null
+++ b/doc/efun/all_environment
@@ -0,0 +1,33 @@
+SYNOPSIS
+        object *all_environment();
+        object *all_environment(object ob);
+
+ARGUMENTE:
+        ob - das Objekt, dessen environment()s gewuenscht werden
+
+BESCHREIBUNG
+        Gibt ein Array mit allen Umgebungen des Objekts <ob> zurueck.
+        Wenn <ob> nicht angegeben wird, wird standardmaessig this_object()
+        verwendet.
+
+        Wenn <o> keine Umgebung hat oder zerstoert wurde, wird 0 zurueck
+        gegeben.
+
+BEMERKUNGEN:
+        Das zurueckgegebene Array ist so angelegt, dass die innerste Umgebung
+        am Anfang des Arrays steht, und die aeusserste Umgebung am Ende.
+
+BEISPIEL
+        (Die gesuchte Fackel befindet sich in einem Behaelter, den Wargon bei
+        sich traegt. Wargon steht in seinem Workroom.)
+
+        ob = all_environment(find_object("/obj/fackel#32"));
+        => ob = ({[+wueste/durian/behaelter#31],[/magier:wargon],[~/workroom]})
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6. Ein Vorschlag von TubMud.
+
+SIEHE AUCH
+        environment(E), all_inventory(E)
+
+7.Feb 2007 Gloinson
\ No newline at end of file
diff --git a/doc/efun/all_inventory b/doc/efun/all_inventory
new file mode 100644
index 0000000..ad6eea1
--- /dev/null
+++ b/doc/efun/all_inventory
@@ -0,0 +1,17 @@
+all_inventory
+FUNKTION:
+     object *all_inventory()
+     object *all_inventory(object ob)
+
+BESCHREIBUNG:
+     Liefert ein Feld (Array) mit allen Objekten, die sich im Objekt ob
+     befinden (bzw. in this_object(), sofern kein Argument angegeben
+     wurde).
+     Gerade bei sehr vollen Objekten bietet sich eher first_inventory(),
+     next_inventory() an.
+
+SIEHE AUCH:
+     first_inventory(E), next_inventory(E), deep_inventory(E),
+     all_environment(E), environment(E)
+
+22. Maerz 2004 Gloinson
diff --git a/doc/efun/allocate b/doc/efun/allocate
new file mode 100644
index 0000000..c591c5e
--- /dev/null
+++ b/doc/efun/allocate
@@ -0,0 +1,38 @@
+SYNOPSIS
+        *mixed allocate(int size);
+        *mixed allocate(int size, mixed init_value);
+
+        *mixed allocate(*int sizes);
+        *mixed allocate(*int sizes, mixed init_value);
+
+BESCHREIBUNG
+        Alloziert ein Array von <size> Elementen. Die Anzahl Elemente muss
+        groesser sein als 0, darf aber das Systemmaximum (normalerweise 1000)
+        nicht uebersteigen. Wird <init_value> angegeben, wird allen Elementen
+        dieser als Anfangswert zugewiesen. Wenn <init_value> ein Mapping oder
+        ein Array ist, wird fuer jedes Element eine einfache Kopie erstellt.
+        Wird <init_value> nicht angegeben, sind alle Elemente 0.
+
+        In der zweiten Form (mit einem Feld von <sizes> anstelle nur einer
+        <size>) erzeugt allocate() ein mehrdimensionales Array, ein Array aus
+        Arrays.
+
+        Heute wird allocate() kaum mehr benoetigt, weil Arrays mit dem
+        +-Operator addiert werden koennen und mit dem ({})-Operator
+        initialisiert. Der einzige Nutzen der Funktion ist, grosse leere
+        oder initialisierte Arrays zu erzeugen.
+
+BEISPIEL
+        string *buffer;
+        buffer = allocate(50);
+        buffer = allocate(50, "");
+
+        buffer = allocate( ({ 2, 3 }) )
+          --> ({ ({ 0, 0, 0 }), ({ 0, 0, 0 }) })
+
+AENDERUNGEN
+        LDMud 3.2.9 fuehrte den Anfangswert <init_value> und die
+            Initialisierung von mehrdimensionalen Arrays ein.
+
+SIEHE AUCH
+        sizeof(E)
diff --git a/doc/efun/and_bits b/doc/efun/and_bits
new file mode 100644
index 0000000..f066d61
--- /dev/null
+++ b/doc/efun/and_bits
@@ -0,0 +1,23 @@
+SYNOPSIS
+        string and_bits(string str1, string str2);
+
+BESCHREIBUNG
+        <str1> und <str2> seien beides Bitstrings. Das Resultat von and_bits()
+        ist ein Bitstring mit dem binaeren Und von <str1> und <str2>, das
+        heisst ein String, in dem ein Bit nur gesetzt ist, wenn das
+        entsprechende Bit in beiden Strings <str1> und <str2> gesetzt ist.
+
+BEISPIEL
+        string s1, s2, s3;
+
+        s1 = set_bit("", 3); s1 = set_bit(s1, 15);  -> s1 is "( ("
+        s2 = set_bit("", 3); s2 = set_bit(s2, 4);   -> s2 is "8"
+
+        s3 = and_bits(s1, s2);
+
+        --> s3 ist jetzt "8", d.h. ein Bitstring, in dem nur das 3. Bit
+            gesetzt ist.
+
+SIEHE AUCH
+        clear_bit(E), set_bit(E), test_bit(E), next_bit(E), last_bit(E),
+        count_bits(E), or_bits(E), xor_bits(E), invert_bits(E), copy_bits(E)
diff --git a/doc/efun/apply b/doc/efun/apply
new file mode 100644
index 0000000..aaa30a5
--- /dev/null
+++ b/doc/efun/apply
@@ -0,0 +1,35 @@
+SYNOPSIS
+        mixed apply(closure cl, mixed arg, ...);
+
+BESCHREIBUNG
+        Wertet die Closure <cl> aus. Wenn <cl> keine Closure ist, wird <cl>
+        unveraendert zurueck geliefert und alle Argumente <arg> werden
+        ignoriert.
+
+        Es gibt einen kleinen Unterschied zu funcall(), das ja im Wesentlichen
+        das gleiche tut (naemlich, eine Closure auswerten): wenn das letzte
+        Argument von apply() ein Array ist, wird jedes Element dieses Arrays
+        zu einem separaten zusaetzlichen Parameter der Closure umgewandelt.
+
+        Eine moegliche Anwendung waere:
+            mixed eval(object ob,string func,mixed *args)
+            {
+                return apply(#'call_other,ob,func,args);
+            }
+
+        Das fuehrt zu folgenden Aufrufen:
+            ob->func(args[0],args[1],...,args[sizeof(args)-1])
+
+        Waere stattdessen funcall() aufgerufen worden, so haette das ergeben:
+            ob->func(args)
+
+        Eine wichtige Anwendung von apply() ist das Auswerten des
+        Array-Arguments in "varargs" Funktionen.
+
+AENDERUNGEN
+        Eingefuehrt in 3.2@70.
+        LDMud 3.2.8 fuehrte ein, dass das erste Argument zurueck gegeben wird,
+            wenn es sich nicht um eine Closure handelt.
+
+SIEHE AUCH
+        funcall(E), closures(LPC), varargs(LPC)
diff --git a/doc/efun/asin b/doc/efun/asin
new file mode 100644
index 0000000..44c6d4d
--- /dev/null
+++ b/doc/efun/asin
@@ -0,0 +1,8 @@
+SYNOPSIS
+        float asin(float)
+
+BESCHREIBUNG
+        Liefert der Arkussinus des Argumentes.
+
+SIEHE AUCH
+        sin(E), cos(E), acos(E), tan(E), atan(E), atan2(E)
diff --git a/doc/efun/atan b/doc/efun/atan
new file mode 100644
index 0000000..105b748
--- /dev/null
+++ b/doc/efun/atan
@@ -0,0 +1,11 @@
+SYNOPSIS
+        float atan(int|float)
+
+BESCHREIBUNG
+        Liefert den Arkustangens des Argumentes.
+
+AENDERUNGEN
+        LDMud 3.2.9: Ganzzahlen (Integers) als Argument hinzugefuegt.
+
+SIEHE AUCH
+        atan2(E), sin(E), cos(E), tan(E), asin(E), acos(E)
diff --git a/doc/efun/atan2 b/doc/efun/atan2
new file mode 100644
index 0000000..e4cd78a
--- /dev/null
+++ b/doc/efun/atan2
@@ -0,0 +1,16 @@
+SYNOPSIS
+        float atan2 (int|float y, int|float x)
+
+BESCHREIBUNG
+        Liefert den Winkel der Polarkoordinaten des Punktes (x, y) im
+        Bereich (-Pi, Pi].
+
+        Man beachte die Vertauschung der Koordinaten x und y in der
+        Parameter-Liste, die die Abfolge in der Steigungs-Winkel-Umrechnung
+        atan(y / x) widerspiegelt.
+
+AENDERUNGEN
+        LDMud 3.2.9: Ganzzahlen (Integers) als Argumente hinzugefuegt.
+
+SIEHE AUCH
+        sin(E), cos(E), tan(E), asin(E), acos(E), atan(E)
diff --git a/doc/efun/attach_erq_demon b/doc/efun/attach_erq_demon
new file mode 100644
index 0000000..032b13b
--- /dev/null
+++ b/doc/efun/attach_erq_demon
@@ -0,0 +1,37 @@
+SYNOPSIS
+        int attach_erq_demon(object ob, int do_close)
+        int attach_erq_demon(string obname, int do_close)
+
+DESCRIPTION
+        This privileged efun is to set/change the connection of the
+        driver to the external erq demon, thus in effect changing the
+        demons.
+
+        The connection of the given interactive 'ob'ject is taken away(!)
+        from it and stored as the erq-connection. The object itself is
+        then no longer needed, but may stay alive - it is just another
+        non-interactive object then.
+
+        In the second form, the string will be combined as suffix to
+        the filename ERQFILE<obname>, which is then the binary to be
+        forked off as new erq demon. The communication with this erq
+        will take place over unix domain sockets. ERQFILE defaults to
+    BINDIR/erq, where BINDIR is the configuration value for the
+    executable directory.
+
+        If there is alreay an erq demon connected to the driver, the
+        function will fail unless 'do_close' (default 0) is specified
+        as 1 (or any other odd integer): then the old connection will
+        be closed before attaching the new.
+        The efun returns 1 on success, else 0.
+
+EXAMPLE
+        To restart the (default) erq, write in
+        master.c::stale_erq(closure c):
+          attach_erq_demon("", 0);
+
+HISTORY
+        Introduced in 3.2.1@61.
+
+SEE ALSO
+        send_erq(E), erq(C)
diff --git a/doc/efun/baseof b/doc/efun/baseof
new file mode 100644
index 0000000..d64cc20
--- /dev/null
+++ b/doc/efun/baseof
@@ -0,0 +1,16 @@
+SYNOPSIS
+        int baseof (struct b, struct s)
+
+DESCRIPTION
+        Test if the type of struct <b> is a base of struct <s> (the
+        values of <b> and <s> are irrelevant). Results are:
+          0: <b> is not a base of <s>, nor is <b> of equal type as <s>
+               (though <s> might be a base of <b>).
+          1: <b> is a true base of <s>
+          2: <b> and <s> are the same struct type
+
+HISTORY
+        Introducted in LDMud 3.3.344.
+
+SEE ALSO
+        structp(E), structs(LPC)
diff --git a/doc/efun/binary_message b/doc/efun/binary_message
new file mode 100644
index 0000000..08bc321
--- /dev/null
+++ b/doc/efun/binary_message
@@ -0,0 +1,36 @@
+GESCHUETZT
+SYNOPSIS
+        int binary_message(int *|string messages, int flags);
+
+BESCHREIBUNG
+        Liest den Output aus und sendet diesen direkt mit write() OHNE IAC
+        QUOTING. Die Nachricht kann Nullen enthalten, wenn sie als
+        int * angegeben sind. Die Nachricht wird an this_object() ausgegeben,
+        aber nur, wenn dieses interaktiv ist.
+
+        Der Rueckgabewert ist die Anzahl tatsaechlich gedruckter Zeichen. Eine
+        allfaellige "allowed charset" Einstellung wird uebergangen.
+
+        <flags> werden bitweise interpretiert und koennen ueber das binaere
+        Oder verbunden werden.
+
+        Bit 0 (Wert 1): wenn gesetzt, wird add_message() anstelle von
+            write() verwendet. So muss der Output nicht zuerst ausgelesen
+            werden, allerdings erfolgt die Ausgabe nicht sofort. Auch kann
+            dann die Anzahl effektiv uebertragener Zeichen nicht bestimmt
+            werden - der Rueckgabewert ist nicht definiert.
+
+        Bit 1 (Wert 2): Der Puffer wird ausgelesen, _nachdem_ die Nachricht
+            angefuegt wurde. Ist nur in Verbindung mit Bit 0 sinnvoll.
+
+        Die Idee hinter den Flags ist, dass das Senden von Kommandocodes
+        zum Beispiel fuer Farben an den vorhandenen Filtern fuer erlaubte
+        Zeichen vorbeigeschleust werden muss, jedoch nicht wichtig genug
+        ist, um die Verschwendung von Bandbreite mittels einer
+        synchronen Uebertragung zu rechtfertigen.
+
+AENDERUNGEN
+        Eingefuehrt in 3.2.1@40.
+
+SIEHE AUCH
+        set_connection_charset(E)
diff --git a/doc/efun/bind_lambda b/doc/efun/bind_lambda
new file mode 100644
index 0000000..6075a33
--- /dev/null
+++ b/doc/efun/bind_lambda
@@ -0,0 +1,16 @@
+SYNOPSIS
+        closure bind_lambda(closure, object ob)
+
+DESCRIPTION
+        Binds an unbound lambda closure to an object and return it.
+        The efun can also be used to rebind an efun-, simul-efun
+        or operator closure to a different object.
+
+        If the optional argument ob is not this_object(), the privilege
+        violation ("bind_lambda", this_object(), ob) occurs.
+
+HISTORY
+        Introduced in 3.2@82.
+
+SEE ALSO
+        lambda(E), unbound_lambda(E), apply(E), funcall(E), closures(LPC)
diff --git a/doc/efun/blueprint b/doc/efun/blueprint
new file mode 100644
index 0000000..1c77497
--- /dev/null
+++ b/doc/efun/blueprint
@@ -0,0 +1,23 @@
+VORLAEUFIG
+SYNOPSIS
+        object blueprint()
+        object blueprint(string|object ob);
+
+BESCHREIBUNG
+        Die Efun liefert den Blueprint fuer das angegeben Objekt <ob> oder
+        fuer this_object(), wenn nicht angegeben.
+
+        Wenn der Blueprint zerstoert wurde, liefert die Funktion 0. Fuer
+        Objekte mit replace_program() liefert die Funktion den Blueprint des
+        ersetzenden Programs.
+
+BEISPIEL
+        blueprint("/obj/ding");                 -> liefert /obj/ding
+        blueprint(find_object("/obj/ding"));    -> liefert /obj/ding
+        blueprint(clone_object("/obj/ding"));   -> liefert /obj/ding
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        clones(E), clone_object(E)
diff --git a/doc/efun/break_point b/doc/efun/break_point
new file mode 100644
index 0000000..584453e
--- /dev/null
+++ b/doc/efun/break_point
@@ -0,0 +1,11 @@
+OPTIONAL
+SYNOPSIS
+        void break_point()
+
+DESCRIPTION
+        This function is for system internal use and should never be called by
+        user objects. It is supposed to check the stack integrity and aborts
+        the driver when it detects corruption.
+
+SEE ALSO
+        shutdown(E), swap(E)
diff --git a/doc/efun/call_direct b/doc/efun/call_direct
new file mode 100644
index 0000000..94ab028
--- /dev/null
+++ b/doc/efun/call_direct
@@ -0,0 +1,75 @@
+SYNOPSIS
+        unknown call_direct (object ob, string fun, mixed arg, ...)
+        unknown call_direct (object *ob, string fun, mixed arg, ...)
+
+DESCRIPTION
+        Call a member function <fun> in another object <ob> with an
+        the argument(s) <arg...>. Result is the value returned from
+        the called function (or 0 for non-existing or void functions).
+
+        This efun is a twin to call_other(), with the difference
+        being that call_direct() never calls a default method.
+
+        Optionally the driver can be configured to accept an array of
+        objects as <ob>: the function is called with the same
+        arguments in all the given objects.  The single results are
+        collected in an array and yield the final result.  Array
+        elements can be objects or the names of existing objects;
+        destructed objects and 0s will yield a '0' as result, but
+        don't cause an error.
+
+        If the array-calling mode is available, the macro
+        __LPC_ARRAY_CALLS__ is defined.
+
+        The object(s) can be given directly or via a string (i.e. its
+        object_name). If it is given by a string and the object does not
+        exist yet, it will be loaded.
+
+        ob->fun(args) and "ob_name"->fun(args) is equivalent to
+        call_other(ob, "fun", args). Nowadays the ob_name string can
+        also be a variable.
+
+        ob->fun(args) and ob->"fun"(args) are equivalent to
+        call_other(ob, "fun", args). ob->(fun)(args) are equivalent
+        to call_other(ob, fun, args) where fun is a runtime expression
+        returning the function name.
+
+        If ob::fun does not define a publicly accessible function, the
+        call_other() will return 0, which is indistinguishable from
+        a function returning 0.
+
+        "publicly accessible" means "public" when calling other objects,
+        and "public" or "static" when calling this_object(). "private"
+        and "protected" function can never be called with call_other().
+
+        The return type of call_other() is 'any' be default. However,
+        if your LPC code uses #pragma strict_types, the return type is
+        'unknown', and the result of call_other() must be casted to
+        the appropriate type before you can use it for anything.
+
+EXAMPLES
+        // All the following statements call the lfun QueryProp()
+        // in the current player with the argument P_SHORT.
+        string str, fun;
+
+        str = (string)call_direct(this_player(), "QueryProp", P_SHORT);
+        fun = "QueryProp";
+        str = (string)call_direct(this_player(), fun, P_SHORT);
+
+        You have to do explicit type casting because of the unknown
+        return type, if you have set #pragma strict_types.
+
+        // This statement calls the lfun short() in all interactive users
+        // and stores the collected results in a variable.
+        string * s;
+
+        s = (string *)call_direct(users(), "short");
+
+
+HISTORY
+        Introduced in LDMud 3.3.113 with the H_DEFAULT_METHOD hook.
+        LDMud 3.2.10 made the call on arrays of objects configurable.
+
+SEE ALSO
+        call_other(E), call_direct_resolved(E), create(A), pragma(LPC),
+        extern_call(E), function_exists(E), functions(LPC)
diff --git a/doc/efun/call_direct_resolved b/doc/efun/call_direct_resolved
new file mode 100644
index 0000000..e227934
--- /dev/null
+++ b/doc/efun/call_direct_resolved
@@ -0,0 +1,25 @@
+SYNOPSIS
+        int call_direct_resolved(mixed result, object ob, string func, ...)
+
+DESCRIPTION
+        Similar to call_direct(). If ob->func() is defined and publicly
+        accessible, any of the optional extra arguments are passed to
+        ob->func(...). The result of that function call is stored in
+        result, which must be passed by reference.
+
+        This efun is a twin to call_resolved(), with the difference
+        being that call_direct_resolved() never calls a default method.
+
+        The efun returns 1 if the function could be called.
+        If ob::fun does not define a publicly accessible function, the
+        efun will return 0.
+
+        ob can also be an object_name. If a string is passed for ob, and
+        no object with that name does exist, an error occurs.
+
+HISTORY
+        Introduced in LDMud 3.3.113 with the H_DEFAULT_METHOD hook.
+
+SEE ALSO
+        call_direct(E), call_resolved(E), function_exists(E),
+        find_object(E)
diff --git a/doc/efun/call_other b/doc/efun/call_other
new file mode 100644
index 0000000..b487f4d
--- /dev/null
+++ b/doc/efun/call_other
@@ -0,0 +1,94 @@
+SYNOPSIS
+        unknown call_other(object ob, string fun, mixed arg, ...);
+        unknown call_other(object *ob, string fun, mixed arg, ...);
+
+        ob->fun(mixed arg, ...);
+        ob->"fun"(mixed arg, ...);
+        ob->(fun)(mixed arg, ...);
+
+BESCHREIBUNG
+        Ruft die in einem anderen Objekt <ob> die Funktion <fun> mit den
+        Argumenten <arg...> auf und gibt den Wert zurueck, der von der
+        Funktion <fun> geliefert wird (oder 0 fuer nicht existierende oder
+        als void deklarierte  Funktionen).
+
+        Optional kann der Driver so konfigueriert werden, dass auch ein Array
+        von Objekten *<ob> akzeptiert wird. Die Funktion <fun> wird dann fuer
+        jedes Objekt <ob> im Array mit den Argumenten <arg...> aufgerufen.
+        Die einzelnen Resultate werden in einem Array zusammen gefasst und
+        dieses Array dann als Endresultat von call_other() zurueck gegeben.
+        Die Elemente von *<ob> koennen Objekte oder Namen von Objekten sein.
+        Zerstoerte Objekte und 0 als Element geben eine 0 zurueck, fuehren
+        aber nicht zu einem Fehler.
+        call_other() auf Arrays von Objekten ist im MG aktiviert, welches
+        durch das Define __LPC_ARRAY_CALLS__ angezeigt wird.
+
+        Das Objekt (bzw. die Objekte) kann direkt oder ueber einen String
+        (d.h. den Objektnamen) angegeben werden. Wenn ein String angegeben
+        wird und das Objekt noch nicht existiert, wird es geladen.
+
+        ob->fun(args) und "ob_name"->fun(args) sind aequivalent zu
+        call_other(ob, "fun", args). Heutzutage kann "ob_name" auch eine
+        Variable sein. ob->(fun)(args) ist aequivalent zu
+        call_other(ob, fun, args), wobei <fun> ein Runtime Ausdruck ist,
+        der den Funktionsnamen liefert.
+
+        Wenn das Objekt <ob> keine oeffentliche Funktion mit dem Namen <fun>
+        enthaelt, gibt call_other() den Wert 0 zurueck. Dies ist nicht
+        unterscheidbar von einer Funktion <fun>, die 0 zurueck liefert.
+        Oeffentlich bedeutet "public", wenn andere Objekte aufgerufen
+        werden und "public" oder "static", wenn der Aufruf an this_object()
+        ergeht. Funktionen, die "private" oder "protected" definiert sind,
+        koennen niemals von call_other() aufgerufen werden.
+
+        Der Rueckgabewert von call_other() ist standardmaessig 'any'. Falls
+        aber #pragma strict_types gesetzt ist, ist der Rueckgabewert
+        'unknown', und das Resultat des call_other() muss zuerst auf einen
+        zutreffenden Variablentyp gecastet werden, bevor man es fuer etwas
+        verwenden kann.
+
+BEISPIELE
+        Die nachfolgenden Beispiele rufen alle die Funktion "QueryProp" auf
+        mit dem Argument P_SHORT.
+
+            string str, fun;
+            str = (string)call_other(this_player(), "QueryProp", P_SHORT);
+            fun = "QueryProp";
+            str = (string)call_other(this_player(), fun, P_SHORT);
+
+            str = (string)this_player()->QueryProp(P_SHORT);
+            str = (string)this_player()->"QueryProp"(P_SHORT);
+            fun = "QueryProp";
+            str = (string)this_player()->(fun)(P_SHORT);
+
+        Solange #pragma strict_types gesetzt ist, muss man das Resultat von
+        call_other() explizit auf einen passenden Typ casten, weil
+        call_other() unknown liefert.
+
+        Das folgende Statement ruft die lfun short() in allen aktiven
+        Benutzern auf und speichert das gesammelte Resultat in einer
+        Variablen:
+
+            string * s;
+            s = (string *)users()->short();
+
+        Objekte laden (obsolet):
+            Compat: call_other("/users/luser/thing", "???", 0);
+
+        Das sieht etwas merkwuerdig aus, wurde aber oft verwendet, um einfach
+        ein Objekt zu laden. Dazu wurde die (nicht existierende) Funktion
+        "???" im Objekt aufgerufen. Gluecklicherweise gibt es heute zu
+        diesem Zweck die Efun load_object(), also bitte nicht mehr verwenden.
+
+AENDERUNGEN
+        In LDMud 3.2.8 wurden die folgenden Verbesserungen eingefuehrt:
+          - die Formen x->"y"() und x->(y)() werden erkannt;
+          - die Form x->y() kollidiert nicht mehr mit einer lokalen Variablen,
+            die auch "y" heisst.
+          - eine simul_efun call_other() erwischt auch Aufrufe der Form ->().
+          - call_other kann auch auf Arrays von Objekten angewandt werden.
+        LDMud 3.2.10 machte den Aufruf von Objektarrays konfigurierbar.
+
+SIEHE AUCH
+        function_exists(E), call_resolved(E), create(A), pragma(LPC),
+        extern_call(E), functions(LPC)
diff --git a/doc/efun/call_out b/doc/efun/call_out
new file mode 100644
index 0000000..dba28b3
--- /dev/null
+++ b/doc/efun/call_out
@@ -0,0 +1,54 @@
+SYNOPSIS
+        void call_out(string fun, int delay, mixed arg, ...)
+        void call_out(closure cl, int delay, mixed arg, ...)
+
+DESCRIPTION
+        Set up a call to function fun in the current object, or to
+        closure cl. The call will take place in delay seconds, with the
+        remaining argument list provided. delay can be 0, but be careful!
+
+        call_out() saves and restores the current user. It is now
+        possible to use say() or write() which rely on a current
+        user to be something useful.
+
+        call_out() can only call functions which are publicly accessible,
+        i.e. "public" and "static" functions. "private" and "protected"
+        functions can't be called.
+
+        The execution of the call_out()s implies a simple (not
+        exhaustive) measure against rabbits: the evaluation costs of
+        those call_outs() executing at the same time are summed up on
+        a per-UID base. If the summed-up costs exceed the given maximum,
+        a 'too long evaluation' error will occur and any remaining
+        call_outs() of this user scheduled for the same time are
+        discarded.
+
+        Callouts are executed every 2s, therefore your delay may be bigger
+        than the you specified. In fact, a Callout with delay==0 is
+        executed within 2s from the function call to call_out(). 
+
+WARNING
+        Please never use call_out(...,0) in recursive Callouts and be at least
+        very careful in other cases. That Callout would be executed directly
+        after your current function and you really get 0 delay.
+
+EXAMPLE
+        call_out("RefreshMe", 10);
+
+        This will call the function RefreshMe() in 10 seconds without
+        any arguments. The function RefreshMe() can then call out
+        itself again which will result in a loop (not in a recursion)
+        which can be used to check or set up things in the object in
+        intervals. Be aware that callouts are stored in a linear
+        list, and so are somewhat expensive for the driver.
+
+        And YES: self-replicating call_out()s, where each call_out()
+        creates two or more other call_out()s in a loop (so called
+        'rabbits') slow the mud down very fast, and are even able
+        to crash it. No need to try it yourself.
+
+SEE ALSO
+        remove_call_out(E), call_out_info(E), find_call_out(E),
+        this_player(E), reset(A), heart_beat(A)
+
+05.11.06 Zesstra
diff --git a/doc/efun/call_out_info b/doc/efun/call_out_info
new file mode 100644
index 0000000..61d5ff5
--- /dev/null
+++ b/doc/efun/call_out_info
@@ -0,0 +1,19 @@
+SYNOPSIS
+        mixed *call_out_info();
+
+BESCHREIBUNG
+        Liefert Informationen ueber alle anhaengigen call_out()s. Das Resultat
+        ist ein Array, bei dem jedes Element wiederum aus einem Array besteht,
+        das einen call_out() beschreibt. Jedes dieser Unter-Arrays enthaelt 3
+        oder mehr Elemente:
+
+        1. Das Objekt, in dem die Funktion oder die Closure aufgerufen wird.
+        2. Die Funktion oder Closure.
+        3. Der verbleibende Delay bis zum Aufruf.
+        4ff. Die (optionalen) Argumente.
+
+        call_out()s fuer zerstoerte Objekte werden nicht in der Liste
+        aufgefuehrt.
+
+SIEHE AUCH
+        call_out(E), remove_call_out(E), find_call_out(E)
diff --git a/doc/efun/call_resolved b/doc/efun/call_resolved
new file mode 100644
index 0000000..0103766
--- /dev/null
+++ b/doc/efun/call_resolved
@@ -0,0 +1,18 @@
+SYNOPSIS
+        int call_resolved(mixed result, object ob, string func, mixed arg,...);
+
+BESCHREIBUNG
+        Die Funktion ist aehnlich zu call_other(). Wenn obj->func() definiert
+        und oeffentlich ist, werden alle Argumente <arg> an obj->func()
+        uebergeben. Das Resultat dieses Funktionsaufrufes wird in <result>
+        gespeichert und muss deshalb als Referenz uebergeben werden.
+
+        Wenn <ob> zerstoert wurde oder keine oeffentlich zugaengliche Funktion
+        <func> definiert, liefert call_resolved() 0 fuer Fehler, 1 bei Erfolg.
+
+        <ob> kann auch ein object_name() sein. Wenn <ob> ein String ist und
+        das Objekt mit diesem Namen nicht gefunden oder geladen werden kann,
+        tritt ein Fehler auf.
+
+SIEHE AUCH
+        call_other(E), function_exists(E), find_object(E)
diff --git a/doc/efun/caller_stack b/doc/efun/caller_stack
new file mode 100644
index 0000000..d1b5777
--- /dev/null
+++ b/doc/efun/caller_stack
@@ -0,0 +1,33 @@
+SYNOPSIS
+        *object caller_stack();
+        *object caller_stack(int add_interactive);
+
+BESCHREIBUNG
+        Liefert ein Array der previous_object(), die einen call_other() auf
+        this_object() verursacht haben. Dabei entspricht previous_object(i)
+        caller_stack()[i].
+
+        Wenn die Funktion mit <add_interactive> (als wahr) aufgerufen wird,
+        wird this_interactive() dem Array hinzugefuegt, oder 0, wenn kein
+        this_interactive() existiert.
+
+BEISPIEL
+        Das interaktive Objekt A gibt ein Kommando ein, das im Objekt B eine
+        Funktion aufruft, die auf das Objekt C verweist, welches wiederum
+        eine Funktion im Objekt D aufruft.
+
+        Wenn D nun caller_stack() aufruft, ergibt dies: ({C,B}).
+        Fuer caller_stack(1) ergibt die Funktion: ({C,B,A}).
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6, vorgeschlagen von TubMud.
+
+ANMERKUNG
+        Aufrufe von "alien lfun closures" (vergleiche symbol_function())
+        erzeugen zwei Eintraege im Stack, wenn das gebundene Objekt sich vom
+        Objekt der Closure unterscheidet: der erste Eintrag steht fuer das
+        gebundene Objekt, der zweite fuer das Closure-Objekt.
+
+SIEHE AUCH
+        caller_stack_depth(E), previous_object(E), this_interactive(E),
+        call_other(E)
diff --git a/doc/efun/caller_stack_depth b/doc/efun/caller_stack_depth
new file mode 100644
index 0000000..230827e
--- /dev/null
+++ b/doc/efun/caller_stack_depth
@@ -0,0 +1,9 @@
+SYNOPSIS
+        int caller_stack_depth(void)
+
+DESCRIPTION
+        Returns the number of previous objects on the stack. This
+        can be used for security checks.
+
+SEE ALSO
+        caller_stack(E), previous_object(E), call_other(E), call_resolved(E)
diff --git a/doc/efun/capitalize b/doc/efun/capitalize
new file mode 100644
index 0000000..bbb82b7
--- /dev/null
+++ b/doc/efun/capitalize
@@ -0,0 +1,12 @@
+SYNOPSIS
+        string capitalize(string str)
+
+DESCRIPTION
+        Convert the first character in str to upper case, and return
+        the new string.
+
+EXAMPLES
+        capitalize("heya!") -> "Heya!"
+
+SEE ALSO
+        lower_case(E), upper_case(E)
diff --git a/doc/efun/cat b/doc/efun/cat
new file mode 100644
index 0000000..665fe4d
--- /dev/null
+++ b/doc/efun/cat
@@ -0,0 +1,29 @@
+SYNOPSIS
+        int cat(string path, int start, int num)
+
+DESCRIPTION
+        List the file found at path.
+
+        In most installations it is not legal to have '..' or spaces
+        in the path. This commands is normally connected to the "cat"
+        command that wizards have. It is also used by the "help"
+        command. The optional arguments start and num are start line
+        number and number of lines. If they are not given the whole
+        file is printed from the beginning.
+
+        The total number of lines will not exceed a system limit, which
+        normally is 50 lines.
+
+        cat() returns the number of lines read and printed if success,
+        0 if no such file or no lines to read (if start or len is < 0,
+        or if the file has less than start lines).
+
+EXAMPLE
+        cat("/doc/efun/cat", 5, 9);
+
+        This will print out the file "/doc/efun/cat" begining at line
+        5 and ending with line 13.
+
+SEE ALSO
+        get_dir(E), file_size(E), read_file(E), read_bytes(E),
+        valid_read(M)
diff --git a/doc/efun/catch b/doc/efun/catch
new file mode 100644
index 0000000..c436b7d
--- /dev/null
+++ b/doc/efun/catch
@@ -0,0 +1,64 @@
+SYNOPSIS
+        mixed catch(expr, expr, ...);
+        mixed catch(expr, expr, ...; modifiers);
+
+BESCHREIBUNG
+        Wertet die Ausdruecke <expr> aus. Wenn kein Fehler auftritt, wird 0
+        zurueck geliefert. Wenn ein Fehler auftritt, wird die Ausfuehrung an
+        diesem Punkt abgebrochen und ein String mit der Fehlermeldung wird
+        zurueck gegeben.
+
+        Systemeigene Fehlermeldungen beginnen mit einem "*", benutzerdefinierte
+        Fehlermeldungen aus throw() und raise_error() (sofern von 0
+        verschieden), werden unveraendert zurueck geliefert.
+
+        Wenn zum Zeitpunkt, zu dem catch() aufgerufen wird, weniger als
+        __CATCH_EVAL_COST__ Rechenticks uebrig sind, wird ein Laufzeitfehler
+        RTE innerhalb von catch() erzeugt (und somit wie jeder andere
+        Fehler abgefangen) und es werden keine Ausdruecke <expr> aus catch()
+        ausgewertet. Der Modifikator 'reserve' kann verwendet werden,
+        einen anderen Wert fuer die Reserve anzugeben.
+
+        Das Verhalten von catch() kann durch <modifiers> veraendert werden:
+
+            'nolog':    Normalerweise wird der Fehler im Fehlerlog
+                        gespeichert, um die Fehlersuche zu erleichtern. Wird
+                        'nolog' gesetzt, wird dieser Log-Eintrag unterdrueckt.
+            'publish':  Normalerweise wird master::runtime_error() fuer einen
+                        Fehler innerhalb eines catch() nicht aufgerufen. Mit
+                        diesem <modifier> wird runtime_error() trotzdem
+                        aufgerufen.
+            'reserve <expr>': <expr> muss eine ganzen Zahl groesser 0
+                        ergeben, welche dann als Rechenreserve anstelle
+                        von __CATCH_EVAL_COST__ verwendet wird. Das Minimum
+                        ist 2 * __MASTER_EVAL_COST__ .
+
+        catch() an sich ist nicht besonders laufzeit-intensiv: es braucht
+        nur etwas mehr Zeit als ein Intra-Objekt Funktionsaufruf.
+        
+        throw() ist ebenfalls nicht sehr teuer, da lediglich einige
+        interne Strukturen aufgeraeumt werden muessen.
+
+        Echte Laufzeitfehlers (ob nun mit oder ohne catch()) auf
+        der anderen Seite ist sehr zeitintensiv.
+
+        catch ist nicht im eigentlichen Sinne eine Efun, sondern eine Compiler
+        Anweisung.
+
+BEISPIEL
+        object obj;
+        string err;
+        if(err = catch(obj = clone_object("/foo/bar/baz")))
+            write("Kann das Objekt nicht clonen. Grund: "+err+"\n");
+
+AENDERUNGEN
+        LDMud 3.2.9 fuehrte den 'nolog' catch() als experimentelles Feature
+            ein.
+        LDMud 3.2.10 implementierte 'nolog' als offizielle Form und fuehrte
+            zudem 'publish' ein.
+        LDMud 3.3.559 verlegte den Test auf verbleibende Rechenticks in die
+            vom catch() umschlossenen Ausfuehrung.
+        LDMud 3.3.560 fuegte den Modifikator 'reserve' ein.
+
+SIEHE AUCH
+        throw(E), raise_error(E), predefined(D), runtime_error(M)
diff --git a/doc/efun/ceil b/doc/efun/ceil
new file mode 100644
index 0000000..dc44244
--- /dev/null
+++ b/doc/efun/ceil
@@ -0,0 +1,19 @@
+SYNOPSIS
+        float ceil(int|float arg);
+
+BESCHREIBUNG
+        Rundet <arg> zur naechsten ganzen Zahl auf und liefert das Resultat
+        zurueck. Wenn <arg> ein Integer ist, wird das Resultat in float
+        konvertiert.
+
+BEISPIEL
+        ceil(4.5);      ergibt:  5.0
+        ceil(-4.5);     ergibt: -4.0
+        ceil(5);        ergibt:  5.0
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7.
+        LDMud 3.2.9 fuehrte neu Integer als moegliche Argumente ein.
+
+SIEHE AUCH
+        abs(E), floor(E)
diff --git a/doc/efun/clear_bit b/doc/efun/clear_bit
new file mode 100644
index 0000000..93f15ec
--- /dev/null
+++ b/doc/efun/clear_bit
@@ -0,0 +1,35 @@
+SYNOPSIS
+        string clear_bit(string str, int n);
+
+BESCHREIBUNG
+        Gibt einen neuen String zurueck, in dem das n-te Bit im String <str>
+        nicht gesetzt ist. Dabei wird <str> selbst nicht veraendert.
+
+        Jedes Zeichen enthaelt sechs Bits. So kann in jedem Zeichen eine Zahl
+        zwischen 0 und 63 (2^6=64) gespeichert werden. Das erste Zeichen ist
+        der Leerschlag " " mit Wert 0. Das erste Zeichen im String ist jenes
+        mit den niedrigsten Bits (0 bis 5).
+
+BEISPIELE
+        string s;
+        s = clear_bit("_", 5);
+
+        Weil "_" den hoechsten moeglichen Wert enthaelt (63), enthaelt die
+        Variable s nun das Zeichen "?", das dem Wert 31 entspricht (63-2^5=31).
+
+        string s;
+        s = clear_bit("?<",3);
+        s = clear_bit(s, 8);
+
+        s enthaelt nun den String "78". "?" entspricht dem Wert 31 und "<" dem
+        Wert 28. "?<" entspricht also dem Wert 31+28<<6=31+1792=1823, was in
+        Binaerschreibweise (hoechstes Bit rechts) 11111000111 ergibt. Werden
+        aus dieser Zahl die Bits 3 und 8 (die Nummerierung beginnt mit dem
+        0. Bit) ergibt dann: 11101000011. Die ersten 6 Bits 010111 sind in
+        Dezimalschreibweise 23. Die zweiten 6 Bits (0)11000 ergeben 24 in
+        Dezimalschreibweise. Nun entspricht der Wert 23 dem Zeichen "7" und
+        der Wert 24 dem Zeichen "8". Der String s enthaelt also "78".
+
+SIEHE AUCH
+        set_bit(E), next_bit(E), last_bit(E), test_bit(E), count_bits(E),
+        and_bits(E), or_bits(E), xor_bits(E), invert_bits(E), copy_bits(E)
diff --git a/doc/efun/clone_object b/doc/efun/clone_object
new file mode 100644
index 0000000..f622bef
--- /dev/null
+++ b/doc/efun/clone_object
@@ -0,0 +1,23 @@
+SYNOPSIS:
+        object clone_object(string name)
+
+DESCRIPTION:
+        Clone a new object from definition name, and give it a new unique
+	name. Return the new object.
+        
+        The original, called blue print, used for cloning, should not be
+	used in the game, only be used for cloning. The cloned objects
+	contain only the data but the blue print also the function code.
+	The blue print is the one without a unique number at the end of
+	the object's object_name(). The clone_object() function never
+	returns a blue print.
+        
+        Note that the pathname must be complete, which means there are no
+        relative paths allowed.
+
+EXAMPLE:
+        object torch;
+        torch = clone_object("/obj/torch");
+
+SEE ALSO:
+        destruct(E), move_object(E), uids(C)
diff --git a/doc/efun/clonep b/doc/efun/clonep
new file mode 100644
index 0000000..afff71a
--- /dev/null
+++ b/doc/efun/clonep
@@ -0,0 +1,28 @@
+SYNOPSIS
+        int clonep ()
+        int clonep (object obj)
+        int clonep (string obj)
+        int clonep (mixed  arg)
+
+BESCHREIBUNG
+        Liefert 1, wenn das angegebene Objekt ein Klon ist, ansonsten 0.
+        Das Objekt kann dabei auch durch seinen Objekt-Namen angegeben werden.
+        Wird kein Argument uebergeben, so wird this_object() getestet.
+        Liefert 0, wenn das Argument von einem anderen Typ.
+        Ein Objekt, dessen Programm mittels replace_program() ersetzt wurde,
+        zaehlt nicht als Klon.
+
+BEISPIEL
+        object o;
+        o = clone_object("/obj/ding");
+        write(clonep(o));                          --> schreibt "1"
+        write(clonep("/obj/ding"))                 --> schreibt "0"
+
+        (Im COMPAT_MODE "obj/ding" als Dateinahmen benutzen)
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6, geaendert in 3.2.7, so dass Objekte mit
+        ersetzten Programmen nicht mehr als Klone zaehlen.
+
+SIEHE AUCH
+        load_name(E), clone_object(E), clones(E)
diff --git a/doc/efun/clones b/doc/efun/clones
new file mode 100644
index 0000000..23e20d2
--- /dev/null
+++ b/doc/efun/clones
@@ -0,0 +1,38 @@
+SYNOPSIS
+        *object clones();
+        *object clones(int what);
+        *object clones(string|object obj [, int what]);
+
+BESCHREIBUNG
+        Diese Efun liefert ein Array mit allen Clones eines bestimmten
+        Blueprints. Dabei unterliegt das Array den normalen Systemlimiten.
+
+        Wenn <obj> angegeben ist, werden alle Clones des Blueprints von <obj>
+        (oder von <obj> selbst, falls <obj> ein Blueprint ist) ausgegeben,
+        sonst die Clone des aktuellen Objekts bzw. die Clone des Blueprints
+        des aktuellen Objekts. Wenn <obj> als String angegeben ist, muss es
+        der Name eines existierenden Objekts sein.
+
+        <what> waehlt aus, wie Clone von aelteren Versionen des Blueprints
+        zu behandeln sind:
+            == 0: liefert nur die Clone des aktuellen Blueprints (Standard)
+            == 1: liefert nur die Clone der alten Blueprint-Version
+            == 2: liefert alle Clones aller Blueprint-Versionen
+
+        Wenn der Treiber mit DYNAMIC_COSTS kompiliert wurde, sind die Kosten
+        fuer diese Funktion proportional zur Anzahl Objekte im Spiel.
+
+BEISPIEL
+        object o, p;
+        o = clone_object("/std/thing"); /* oder "std/thing" im COMPAT_MODE */
+        destruct(find_object("/std/thing"));
+        p = clone_object("/std/thing");
+
+        clones("/std/thing")    --> ergibt ({ p })
+        clones("/std/thing", 0) --> ergibt ({ p })
+        clones("/std/thing", 1) --> ergibt ({ o })
+        clones("/std/thing", 2) --> ergibt ({ o, p })
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.8.
+        LDMud 3.2.9 fuehrte die dynamischen Kosten ein.
diff --git a/doc/efun/closurep b/doc/efun/closurep
new file mode 100644
index 0000000..25a2829
--- /dev/null
+++ b/doc/efun/closurep
@@ -0,0 +1,11 @@
+SYNOPSIS
+        int closurep(mixed arg)
+
+BESCHREIBUNG
+        Liefert 1, wenn das Argument eine Closure ist, ansonsten 0.
+
+AENDERUNGEN
+        Eingefuehrt in 3.2@70.
+
+SIEHE AUCH
+        intp(E), referencep(E), symbolp(E)
diff --git a/doc/efun/command b/doc/efun/command
new file mode 100644
index 0000000..09d6c0b
--- /dev/null
+++ b/doc/efun/command
@@ -0,0 +1,50 @@
+command()
+FUNKTION:
+     int command(string str)
+     int command(string str, object ob)
+
+BESCHREIBUNG:
+     Fuehrt str wie ein Kommando welches direkt vom Nutzer abgegeben wurde
+     aus. Alle Effekte des Kommandos wirken sich auf this_object() oder,
+     falls angegeben, auf das Objekt <obj> aus.
+
+     Der Rueckgabewert ist >=1 fuer Erfolg und 0 fuer Misserfolg.
+     Rueckgabewert ist im Erfolgsfall die Hoehe der EvalCost in Ticks.
+
+     Wenn command() auf ein anderes Objekt angewendet wird, koennen auf
+     diesem Wege keine "static" deklarierten Funktionen aufgerufen werden,
+     um etwas Schutz vor unerlaubten Aufrufen zu geben.
+
+     Kommandi werden gestapelt, das heisst, nach der Ausfuehrung von <str>
+     werden die alten Werte fuer this_player(), query_verb() etc. wieder
+     hergestellt (ein Kommando kann dazu fuehren, dass ein Kommando
+     ausgefuehrt wird).
+
+BEMERKUNGEN:
+     Die meisten in Lebewesen definierten Kommandofunktionen sind vor
+     aeusserem Aufrufen durch "static" oAe geschuetzt. Zum Ausfuehren dieser
+     Kommandos muss command_me(L) eingesetzt werden, um diesen Schutz zu
+     umgehen.
+
+BEISPIELE:
+     Siehe command_me(L) fuer einen Vergleich.
+	 
+     // #1 Ein NPC nimmt und zuendet eine herumliegende /std/lightsource an
+     object f = present("\nlichtquelle", environment());
+     if(f && command("nimm lichtquelle"))
+       if(command("zuende lichtquelle an"))
+         tell_room(environment(), Name(WER)+" freut sich.\n");
+       else
+         tell_room(environment(), Name(WER)+" schaut bedroeppelt.\n");
+     
+     // #2 Ein NPC traegt seine Sachen
+     clone_object("/ruestung/sommerkleid")->move(this_object(), 2);
+     command("trage kleid")
+     // aequivalent und besser ist hier:
+     AddItem("/ruestung/sommerkleid", REFRESH_REMOVE|CLONE_WEAR);
+
+SIEHE AUCH
+     command_stack(E), notify_fail(E), enable_commands(E), get_eval_cost(E)
+     command_me(L)
+
+6 Sep 2012 Gloinson
diff --git a/doc/efun/command_stack b/doc/efun/command_stack
new file mode 100644
index 0000000..d3a4e46
--- /dev/null
+++ b/doc/efun/command_stack
@@ -0,0 +1,34 @@
+GESCHUETZT
+SYNOPSIS
+        #include <sys/commands.h>
+
+        *mixed command_stack();
+
+BESCHREIBUNG
+        Liefert ein Array, das den Kommando Stack beschreibt. Das Array
+        umfasst command_stack_depth() Eintraege, der erste davon beschreibt
+        das Top-Level Kommando, der letze Eintrag das aktuelle Kommando.
+
+        Jeder Eintrag ist wiederum ein Array mit folgenden Eintraegen:
+
+            string [CMD_VERB]:      das Verb dieses Kommandos
+            string [CMD_TEXT]:      der volle Text des Kommandos
+            object [CMD_ORIGIN]:    der urspruengliche Kommandogeber
+            object [CMD_PLAYER]:    der momentane Kommandogeber
+            mixed  [CMD_FAIL]:      der Inhalt von notify_fail() (oder 0)
+            mixed  [CMD_FAILOBJ]:   das Objekt, welches notify_fail() gesetzt
+                                    hat
+
+        CMD_ORIGIN und CMD_PLAYER sind fuer gewohenlich das gleiche Objekt.
+        Es gibt nur einen Unterschied, wenn der modify_command Hook den
+        Kommandogeber mit set_this_player() aendert.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7.
+        LDMud 3.2.8 fuegte den CMD_FAILOBJ Eintrag hinzu.
+
+ANMERKUNG
+        Jeder der Eintraege im Array kann 0 sein.
+
+SIEHE AUCH
+        command(E), command_stack_depth(E), notify_fail(E)
diff --git a/doc/efun/command_stack_depth b/doc/efun/command_stack_depth
new file mode 100644
index 0000000..37205b5
--- /dev/null
+++ b/doc/efun/command_stack_depth
@@ -0,0 +1,13 @@
+GESCHUETZT
+SYNOPSIS
+        int command_stack_depth();
+
+BESCHREIBUNG
+        Liefert die Anzahl der verschachtelten Kommandi, also die Tiefe des
+        Command Stacks.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7.
+
+SIEHE AUCH
+        command(E), command_stack(E)
diff --git a/doc/efun/configure_driver b/doc/efun/configure_driver
new file mode 100644
index 0000000..fa2407b
--- /dev/null
+++ b/doc/efun/configure_driver
@@ -0,0 +1,133 @@
+SYNOPSIS
+        #include <configuration.h>
+
+        void configure_driver(int what, mixed data)
+
+DESCRIPTION
+        This efun configures runtime adjustable bahviour of the driver.
+
+        Sets the option <what> to the value <data>.
+
+        This function always causes the privilege_violation
+        ("configure_driver", this_object(), what, data).
+
+        <what> == DC_MEMORY_LIMIT
+           Set new soft and hard memory limits for the driver.
+           <data> is expected to be an array with two elements, which have to
+           be integers giving the amount of memory in bytes.
+           ({<soft memory limit>, <hard memory limit>})
+
+        <what> == DC_ENABLE_HEART_BEATS
+           Globally enable the calling of Heartbeats, if <data> is 1,
+           globally disable them if <data> is 0.
+           If called during heartbeat processing, the change comes into effect
+           at the next backend cycle.
+
+        <what> == DC_LONG_EXEC_TIME
+           Set the time considered as (too) long for top-level executions. If
+           an execution exceeds this time, a stack trace will be written to
+           the debug log. The execution will continue at that point.
+           <data> is an integer and measured in microseconds.
+           A time of 0 disables the detection of long executions.
+
+        <what> == DC_DATA_CLEAN_TIME
+           Sets the average time between clean-ups of an objects data
+           structures. This is not to be confused with the standard cleanup
+           time which determines when H_CLEAN_UP is called. A long time for
+           data cleanup may lead to larger memory consumption and prevents
+           destructed objects being cleaned up. A too short time may lead to
+           high loads and lag on the machine. The actual time delay will be a
+           time between 0.9*DC_DATA_CLEAN_TIME and 1.1*DC_DATA_CLEAN_TIME.
+           Default at driver startup are 3600s.
+           <data> is an integer and measured in seconds.
+
+        <what> == DC_TLS_CERTIFICATE
+           Sets the current certificate used for new TLS sessions.
+           It can be one of the certificates in the key directory
+           (command line option --tls-keydirectory) or the main
+           certificate (given with --tls-certfile).
+           Default is the main certificate or else the first
+           certificate found in the directory. The chosen certificate at the
+           time of the tls_init_connection() call is used for that connection.
+           <data> is a string containing the SHA1 fingerprint
+           of the certificate with hexadecimal numbers,
+           it may contain colons or whitespaces (for example
+           "5A:FE:CA:57:1E:50:5E:1E:C7:ED:BA:11:AD:50:10:75:0F:7A:1E:50").
+           When loading certificates their fingerprints are printed
+           on stdout and into the logfile.
+
+        <what> == DC_TLS_DHE_PARAMETER
+           Sets new parameters for the Diffie-Hellman keyexchange for new TLS
+           sessions. The paramters must be given as a PEM encoded string
+           (e.g. the output of 'openssl dhparam -5 2048').
+           If <data> is 0, the built-in defaults will be restored.
+           If importing the new parameters fails (e.g. due to an incorrect
+           format), the driver tries to keep the old parameters 
+
+        <what> == DC_TLS_CIPHERLIST
+           Sets a new list of ciphers (OpenSSL) or priorities (GnuTLS) to use.
+           For the correct format, please refer to the help of 'openssl
+           ciphers' or documentation of priority strings in GnuTLS.
+           With GnuTLS a syntax error in the list causes an error.
+           With OpenSSL an error is only raised of none of the given ciphers
+           could be selected.
+           By default, the preferred ciphers of the driver take precedence
+           This can be changed in the priority strings for GnuTLS, but
+           currently not for OpenSSL.
+
+        <what> == DC_EXTRA_WIZINFO_SIZE
+           Indicate that the wizlist should contain an array of the given size
+           with extra info for each wizard. A negative value indicates
+           a non-array value.
+
+           The value is only used to allocate a proper empty 'extra' value
+           for newly created wizlist entries.
+
+        <what> == DC_DEFAULT_RUNTIME_LIMITS
+           Sets the default runtime limits, that will be used for each thread.
+           They will be in effect as the initial limits with the next thread.
+           The limits must be given as an array with the following entries:
+
+             int[LIMIT_EVAL]:         the max number of eval costs
+             int[LIMIT_ARRAY]:        the max number of array entries
+             int[LIMIT_MAPPING_SIZE]: the max number of mapping values
+             int[LIMIT_MAPPING_KEYS]: the max number of mapping entries
+             int[LIMIT_BYTE]:         the max number of bytes handled with
+                                      one read_bytes()/write_bytes() call.
+             int[LIMIT_FILE]:         the max number of bytes handled with
+                                      one read_file()/write_file() call.
+             int[LIMIT_CALLOUTS]:     the number of callouts at one time.
+             int[LIMIT_COST]:         how to account the current cost.
+             int[LIMIT_MEMROY]:       the max. number of bytes which can be 
+                                        _additionally_ allocated/used
+                                        _per top-level execution thread_.
+
+          The limit settings recognize three special values:
+
+            LIMIT_UNLIMITED:  the limit is deactivated
+            LIMIT_KEEP:       the former setting is kept
+            LIMIT_DEFAULT:    the 'global' default setting is used.
+
+          For LIMIT_COST, the special values have these meaning:
+            LIMIT_UNLIMITED:  at maximum 1 tick is accounted
+            LIMIT_KEEP:        LIMIT_COST is set to 0
+            LIMIT_DEFAULT:     LIMIT_COST is set to -100
+
+        <what> == DC_SWAP_COMPACT_MODE
+           Sets free swap space shall be reused immediately to keep
+           the swap file as small as possible.
+           (Same as the --swap-compact command line switch.)
+
+HISTORY
+        Introduced in LDMud 3.3.719.
+        DC_ENABLE_HEART_BEATS was added in 3.5.0.
+        DC_LONG_EXEC_TIME was added in 3.5.0.
+        DC_DATA_CLEAN_TIME was added in 3.5.0.
+        DC_EXTRA_WIZINFO_SIZE was added in 3.5.0.
+        DC_TLS_CERTIFICATE was added in 3.5.0.
+        DC_TLS_DHE_PARAMETER was added in 3.5.0.
+        DC_TLS_CIPHERLIST was added in 3.5.0.
+        DC_SWAP_COMPACT_MODE was added in 3.5.0.
+
+SEE ALSO
+        configure_interactive(E)
diff --git a/doc/efun/configure_interactive b/doc/efun/configure_interactive
new file mode 100644
index 0000000..b7d145d
--- /dev/null
+++ b/doc/efun/configure_interactive
@@ -0,0 +1,139 @@
+SYNOPSIS
+        #include <configuration.h>
+
+        void configure_interactive(object ob, int what, mixed data)
+
+DESCRIPTION
+        Sets the option <what> to the value <data> on the interactive <ob>
+        or the default for all interactives if <ob> is 0.
+
+        If the first argument <ob> is not this_object(), the privilege
+        violation ("configure_interactive", this_object(), ob, what, data)
+        occurs.
+
+        As <what>, the following arguments are accepted:
+
+        <what> == IC_MAX_WRITE_BUFFER_SIZE
+          Sets the maximum amount of data to be held pending for writing
+          per player to <data> bytes. A value of -1 means unlimited,
+          0 deactivates the write buffer.
+
+        <what> == IC_SOCKET_BUFFER_SIZE
+          Changes the socket buffer size to the given size in bytes.
+          Not every operating system might provide this option to
+          change the buffer size.
+
+          The buffer size is used for sending, when the remote side isn't
+          getting the data fast enough. When the socket buffer is full,
+          the driver will buffer in its internal write buffer (see
+          IC_MAX_WRITE_BUFFER_SIZE). When that gets full, too, then
+          messages are discarded.
+
+        <what> == IC_COMBINE_CHARSET_AS_STRING
+          Set the set of characters which can be combined into a single
+          string when already received en-bloc in charmode from the
+          interactive user <ob>. Non-combinable characters and single
+          received characters are returned as separate strings as usual.
+
+          The newline '\n' and the NUL character '\0' are always
+          non-combinable.
+
+          The given string should contain all combinable characters.
+          If given as the number 0, the default combine charset is
+          re-established.
+
+        <what> == IC_COMBINE_CHARSET_AS_ARRAY
+          Set the set of characters which can be combined into a single
+          string, just like IC_COMBINE_CHARSET_AS_STRING.
+
+          The given array shall contain an array of up to 32 integers
+          that are interpreted as 8-bit-values. Each character is encoded
+          as one bit (ASCII characters 0-7 in the first integer, and so on).
+          So a character <n> is treated as combinable if
+
+              array[n/8] & (1 << n%8)
+
+          If the array contains less elements, the missing elements will
+          be regarded as 0 (non-combinable characters).
+
+        <what> == IC_CONNECTION_CHARSET_AS_STRING
+          Set the set of characters which can be output to the interactive
+          user <ob>. All other characters are discarded. (This does not
+          apply to binary_message()).
+
+          The given string should contain all allowed characters.
+          If given as the number 0, the default charset is re-established.
+
+        <what> == IC_CONNECTION_CHARSET_AS_ARRAY
+          Set the set of characters which can be output to the interactive
+          user <ob>, just like IC_CONNECTION_CHARSET_AS_STRING.
+
+          The given array shall contain an array of up to 32 integers
+          that are interpreted as 8-bit-values. Each character is encoded
+          as one bit (ASCII characters 0-7 in the first integer, and so on).
+          So a character <n> is allowed to be output if
+
+              array[n/8] & (1 << n%8)
+
+          If the array contains less elements, the missing elements will
+          be regarded as 0 (not allowed, ie. to be discarded).
+
+        <what> == IC_QUOTE_IAC
+          Sets whether the character 255 (telnet IAC) shall be quoted
+          by prepending another IAC character, so it will not be interpreted
+          by the telnet protocol. Enable with 1, disable with 0. By default
+          it is enabled and does only apply if character 255 is allowed to
+          be output (ie. it is part of the connection charset).
+
+        <what> == IC_TELNET_ENABLED
+          Enables (1) or disables (0) the telnet machine for the interactive
+          user <ob>. When deactivated the driver won't handle telnet
+          negotiations (eg. H_TELNET_NEG won't be called), they will be
+          part of the user input. Also INPUT_NOECHO won't be effective
+          as the driver won't send any telnet negotiations itself.
+
+        <what> == IC_MCCP
+          Starts oder ends MCCP compression of the driver -> client traffic.
+          <data> must be the MCCP version (either TELOPT_COMPRESS or
+          TELOPT_COMPRESS2 from <telnet.h>). When the telnet machine
+          is disabled, any value other then zero will do, and the compression
+          starts without a telnet preamble.
+
+          Available only if the driver is compiled with MCCP enabled;
+          __MCCP__ is defined in that case.
+
+        <what> == IC_PROMPT
+          Sets the prompt for the interactive user <ob> to <data>. The
+          prompt can either be a string or a closure that will be called
+          each time the prompt is shown.
+
+        <what> == IC_MAX_COMMANDS
+          Sets the max number of commands the interactive user <ob> is
+          allowed to execute per second to <data>. A negative value means
+          'unlimited' and is the setting for newly created connections.
+
+          A 'command' in this context means every received data packet
+          which causes a LPC call - actions and calls to input_to()
+          alike.
+
+        <what> == IC_MODIFY_COMMAND
+          Sets an object that will act as a modifier for each command.
+          All commands for the interactive user <ob> will be passed to
+          data->modify_command() before actually being executed.
+          <data> must be given as an object.
+
+          When an object is set, the H_MODIFY_COMMAND hook wont be
+          called anymore. 0 as argument will stop the command modification
+          and reinstall the use of that driver hook.
+
+          This mechanism is intended to expand aliases on quicktypers
+          or the like. The name of the lfun called can be changed
+          from modify_command() to something else using the
+          H_MODIFY_COMMAND_FNAME hook.
+
+
+HISTORY
+        Introduced in LDMud 3.3.719.
+
+SEE ALSO
+        configure_driver(E)
diff --git a/doc/efun/configure_object b/doc/efun/configure_object
new file mode 100644
index 0000000..9a54789
--- /dev/null
+++ b/doc/efun/configure_object
@@ -0,0 +1,41 @@
+SYNOPSIS
+        #include <configuration.h>
+
+        void configure_object(object ob, int what, mixed data)
+
+DESCRIPTION
+        Sets the option <what> to the value <data> on the object <ob>
+        or the default for all interactives if <ob> is 0.
+
+        If the first argument <ob> is not this_object(), the privilege
+        violation ("configure_object", this_object(), ob, what, data)
+        occurs.
+
+        As <what>, the following arguments are accepted:
+
+        <what> == OC_COMMANDS_ENABLED
+          Sets whether <ob> can use commands normally accessible to
+          users (1) or not (0). This also marks the object as "living".
+
+        <what> == OC_HEART_BEAT
+          Enables (1) or disables (0) the heart beat for <ob>. The
+          driver will apply the lfun heart_beat() to the <ob> every
+          __HEARTBEAT_INTERVAL__ seconds, if it is enabled.
+          A shadow over the heart_beat() lfun will be ignored.
+
+          If the heart beat is not needed for the moment, then do disable
+          it. This will reduce system overhead.
+
+          Note that heart_beat()s are called only if there are enabled
+          via configuer_driver(DC_ENABLE_HEART_BEATS), which is the
+          default.
+
+
+        The current values for these options can be queried using
+        object_info().
+
+HISTORY
+        Introduced in LDMud 3.5.0.
+
+SEE ALSO
+        object_info(E), configure_interactive(E), configure_driver(E)
diff --git a/doc/efun/convert_charset b/doc/efun/convert_charset
new file mode 100644
index 0000000..567ce65
--- /dev/null
+++ b/doc/efun/convert_charset
@@ -0,0 +1,94 @@
+SYNOPSIS
+        string convert_charset(string str, string from_cs, string to_cs)
+
+BESCHREIBUNG
+        Der String <str> wird von Zeichensatz <from_cs> in Zeichensatz
+        <to_cs> umgewandelt und das Ergebnis zurueckgegeben.
+
+        Die Zeichensaetze werden bei Namen angegeben (sowohl Klein-
+        als auch Grossschrift ist zulaessig).
+
+        Die Funktion ist nur verfuegbar auf Systemen mit installierter
+        libiconv.
+
+        Erlaubte Zeichensaetze sind:
+
+           Der derzeitige Systemzeichensatz:
+               "" (der Leerstring)
+
+           European 
+               ASCII, ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16}, KOI8-R, KOI8-U,
+               KOI8-RU, CP{1250,1251,1252,1253,1254,1257}, CP{850,866},
+               Mac{Roman,CentralEurope,Iceland,Croatian,Romania},
+               Mac{Cyrillic,Ukraine,Greek,Turkish}, Macintosh
+
+           Semitic 
+               ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic}
+
+           Japanese
+               EUC-JP,   SHIFT_JIS,    CP932,    ISO-2022-JP,    ISO-2022-JP-2,
+               ISO-2022-JP-1
+
+           Chinese
+               EUC-CN,  HZ,  GBK,  GB18030,  EUC-TW,  BIG5,  CP950, BIG5-HKSCS,
+               ISO-2022-CN, ISO-2022-CN-EXT
+
+           Korean
+               EUC-KR, CP949, ISO-2022-KR, JOHAB
+
+           Armenian
+               ARMSCII-8
+
+           Georgian
+               Georgian-Academy, Georgian-PS
+
+           Tajik
+               KOI8-T
+
+           Thai
+               TIS-620, CP874, MacThai
+
+           Laotian
+               MuleLao-1, CP1133
+
+           Vietnamese
+              VISCII, TCVN, CP1258
+
+           Platform specifics
+              HP-ROMAN8, NEXTSTEP
+
+           Full Unicode
+              UTF-8
+              UCS-2, UCS-2BE, UCS-2LE
+              UCS-4, UCS-4BE, UCS-4LE
+              UTF-16, UTF-16BE, UTF-16LE
+              UTF-32, UTF-32BE, UTF-32LE
+              UTF-7
+              C99, JAVA
+
+        Auf einigen System sind auch die folgenden Zeichensaetze verfuegbar:
+
+            European 
+                CP{437,737,775,852,853,855,857,858,860,861,863,865,869,1125}
+
+            Semitic 
+                CP864
+
+            Japanese
+                EUC-JISX0213, Shift_JISX0213, ISO-2022-JP-3
+
+            Turkmen
+                TDS565
+
+            Platform specifics
+                RISCOS-LATIN1
+
+
+BEISPIEL
+        convert_charset("Hi!", "ascii", "utf-8")
+
+GESCHICHTE
+        Introduced in LDMud 3.3.531 .
+
+SEE ALSO
+
diff --git a/doc/efun/copy b/doc/efun/copy
new file mode 100644
index 0000000..39f3752
--- /dev/null
+++ b/doc/efun/copy
@@ -0,0 +1,23 @@
+SYNOPSIS
+     mixed copy(mixed arg);
+
+BESCHREIBUNG
+     Erzeugt eine flache Kopie von <arg> und liefert diese zurueck. Fuer
+     Arrays und Mappings heisst das, dass neue Arrays bzw. Mappings erzeugt
+     werden, die Kopien der Elemente des Originals enthalten. Eingebettete
+     Arrays und Mappings werden jedoch als Referenz uebergeben!
+
+     Fuer andere Werte von <arg> bewirkt diese Funktion nichts.
+
+BEISPIEL
+     mixed *a, *b;
+     a = ({ 1, ({ 21, 22 }) });
+     b = copy(a);
+     a[0] = -1; a[1][0] = -21;
+         --> a ist nun ({ -1, ({ -21, 22 }) })
+             b ist nun ({  1, ({ -21, 22 }) })
+
+SIEHE AUCH
+     deep_copy(E)
+
+10.Apr.2007 Gloinson
\ No newline at end of file
diff --git a/doc/efun/copy_bits b/doc/efun/copy_bits
new file mode 100644
index 0000000..ec68d51
--- /dev/null
+++ b/doc/efun/copy_bits
@@ -0,0 +1,41 @@
+SYNOPSIS
+        string copy_bits(string src, string dest [, int srcstart
+            [, int deststart [, int copylen]]]);
+
+BESCHREIBUNG
+        Kopiert den Bitbereich [<srcstart> .. <srcstart> + <copylen>] aus dem
+        Bitstring <src> in den Bitstring <dest> beginnend an der Position
+        <deststart>. Die alten Werte von <dest> werden dabei ueberschrieben.
+
+        Der resultierende String wird zurueck geliefert, die beiden
+        Originalstrings bleiben unbeeinflusst.
+
+        Wird <srcstart> nicht angegeben, wird <src> von Anfang an kopiert.
+        Ist <srcstart> negativ, wird vom letzten Bit her gezaehlt (d.h. -1
+        bezeichnet das letzte Bit).
+
+        Wird <deststart> nicht angegeben, wird <dest> von Anfang an kopiert.
+        Ist <deststart> negativ, wird vom letzten Bit her gezaehlt (d.h. -1
+        bezeichnet das letzte Bit).
+
+        Wird <copylen> nicht angegeben wird, so wird der gesamte Bitstring
+        <src> kopiert. Das Resultat besteht dann aus dem Bitstring <dest>
+        bis zur Position <deststart>, gefolgt von <src> ab der Position
+        <srcstart>.
+
+        Wenn <copylen> negativ ist, werden abs(<copylen>) _vor_ <srcstart> in
+        das Resultat kopiert.
+
+BEISPIELE
+        copy_bits(src, dest, 10)       === src[10..]
+        copy_bits(src, dest, 10, 5)    === dest[0..4] + src[10..]
+        copy_bits(src, dest, 10, 5, 3) === dest[0..4] + src[10..12] + dest[8..]
+
+        (Die Notation src[] / dest[] dient nur der Illustration!)
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9
+
+SIEHE AUCH
+        clear_bit(E), set_bit(E), test_bit(E), next_bit(E), last_bit(E),
+        count_bits(E), or_bits(E), xor_bits(E), invert_bits(E), and_bits(E)
diff --git a/doc/efun/copy_file b/doc/efun/copy_file
new file mode 100644
index 0000000..6e091ed
--- /dev/null
+++ b/doc/efun/copy_file
@@ -0,0 +1,19 @@
+SYNOPSIS
+        int copy_file(string from, string to)
+
+DESCRIPTION
+        The efun copy_file() will copy the file <from> to the new name <to>.
+        If <to> exists and is a directory, then <from> will be placed in that
+        directory and keep its original name.
+        
+        You must have read permission for <from> and write permission for
+        the target file to copy the file.
+        
+        On successful completion copy_file() will return 0. If any
+        occurs, 1 is returned, or a runtime is generated.
+
+EXAMPLE
+        copy_file("/players/wizard/obj.c", "/players/wizard/newobj.c");
+
+SEE ALSO
+        mkdir(E), rmdir(E), rm(E), rename(E)
diff --git a/doc/efun/cos b/doc/efun/cos
new file mode 100644
index 0000000..85f3e92
--- /dev/null
+++ b/doc/efun/cos
@@ -0,0 +1,11 @@
+SYNOPSIS
+        float cos(int|float)
+
+BESCHREIBUNG
+        Liefert den Kosinus des Argumentes.
+
+AENDERUNGEN
+        LDMud 3.2.9: Ganzzahlen (Integers) als Argument hinzugefuegt.
+
+SIEHE AUCH
+        sin(E), asin(E), acos(E), tan(E), atan(E), atan2(E)
diff --git a/doc/efun/count_bits b/doc/efun/count_bits
new file mode 100644
index 0000000..1b725d0
--- /dev/null
+++ b/doc/efun/count_bits
@@ -0,0 +1,20 @@
+SYNOPSIS
+     int count_bits(string str);
+
+BESCHREIBUNG
+     Diese Funktion zaehlt die Anzahl gesetzer Bits im Bitstring <str> und
+     liefert die Anzahl als Resultat zurueck.
+
+BEMERKUNGEN
+     Arbeitet eigentlich nur sinnvoll auf Bitstrings :)
+
+BEISPIEL
+     string s;
+     s = set_bit("", 3); s = set_bit(s, 15);
+     count_bits(s) --> liefert 2
+
+SIEHE AUCH
+     clear_bit(E), set_bit(E), test_bit(E), next_bit(E), last_bit(E),
+     or_bits(E), xor_bits(E), invert_bits(E), copy_bits(E), bitstrings (C)
+
+10.Apr.2007 Gloinson
diff --git a/doc/efun/crypt b/doc/efun/crypt
new file mode 100644
index 0000000..932089d
--- /dev/null
+++ b/doc/efun/crypt
@@ -0,0 +1,16 @@
+SYNOPSIS
+     string crypt(string str, int seed);
+     string crypt(string str, string seed);
+
+BESCHREIBUNG
+     Verschluesselt den String <str> mit dem Schluessel <seed>. <seed> kann
+     entweder ein Integer sein oder zwei Zeichen aus dem String <seed>.
+     Wenn <seed> 0 ist, wird ein zufaelliger Schluessel erzeugt.
+
+     Das Resultat enthaelt den Schluessel als die ersten beiden Zeichen.
+
+     Fuer Passwortabfragen, die ohne Echo eingegeben werden koennen sollen,
+     bietet input_to() ein spezielles Flag.
+
+SIEHE AUCH
+     md5_crypt(E), md5(E), sha1(E), hash(E), hmac(E)
\ No newline at end of file
diff --git a/doc/efun/ctime b/doc/efun/ctime
new file mode 100644
index 0000000..8db61f8
--- /dev/null
+++ b/doc/efun/ctime
@@ -0,0 +1,22 @@
+SYNOPSIS
+     string ctime(int clock);
+     string ctime(int* uclock);
+
+BESCHREIBUNG
+     Interpretiert das Argument <clock> als Anzahl Sekunden seit dem
+     01.JAN.1970, 00:00 Uhr und konvertiert dieses in einen ansehnlichen
+     String, der Datum und Zeit enthaelt. Wenn <clock> nicht angegeben
+     wird, wird time() verwendet.
+
+     Die zweite Form entspricht der ersten, ausser dass das Argument ein
+     Array mit zwei Integer Elementen ist. Das erste Element int[0] gibt
+     die Anzahl Sekunden seit dem 01.JAN.1970 an, das zweite Element
+     int[1] die Anzahl Millisekunden innerhalb dieser Sekunde.
+
+BEISPIEL
+     write(ctime()+"\n");
+
+     Dies gibt etwas aus wie "Sun Oct 26 19:28:30 2003".
+
+SIEHE AUCH
+     dtime(E), gmtime(E), localtime(E), strftime(E), time(E), utime(E)
diff --git a/doc/efun/db_affected_rows b/doc/efun/db_affected_rows
new file mode 100644
index 0000000..1ea2783
--- /dev/null
+++ b/doc/efun/db_affected_rows
@@ -0,0 +1,24 @@
+OPTIONAL
+SYNOPSIS
+        int db_affected_rows(int handle)
+
+BESCHREIBUNG
+        Resultat ist die Anzaehl der Zeilen die vom letzten SQL-Befehl
+        beeinflusst wurden, welches zum SQL-server via <handle> gesendet
+        wurde. Diese Funktion ist nuetzlich lediglich fuer DELETE-
+        und UPDATE-Befehle.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_affected_rows").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_conv_string(E), db_close(E), db_coldefs(E), db_connect(E),
+        db_exec(E), db_error(E), db_fetch(E), db_insert_id(E), db_handles(E),
+        mysql(C), privilege_violation(M)
diff --git a/doc/efun/db_close b/doc/efun/db_close
new file mode 100644
index 0000000..208176c
--- /dev/null
+++ b/doc/efun/db_close
@@ -0,0 +1,22 @@
+OPTIONAL
+SYNOPSIS
+        int db_close(int handle)
+
+BESCHREIBUNG
+        Schliesse die Verbindung <handle> zum SQL-Server. Resultat ist
+        <handle> bei Erfolg.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_close").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_affected_rows(E), db_conv_string(E), db_coldefs(E), db_connect(E),
+        db_exec(E), db_error(E), db_fetch(E), db_handles(E), db_insert_id(E),
+        mysql(C, privilege_violation(M))
diff --git a/doc/efun/db_coldefs b/doc/efun/db_coldefs
new file mode 100644
index 0000000..c135a11
--- /dev/null
+++ b/doc/efun/db_coldefs
@@ -0,0 +1,23 @@
+OPTIONAL
+SYNOPSIS
+        string * db_coldefs (int handle)
+
+BESCHREIBUNG
+        Resultat ist ein Array mit den Spaltennamen der Tabelle des
+        letzten QUERY-Befehls. Gab die Datenbank keine Tabelle zurueck, dann
+        gibt die Efun 0 als Ergebnis.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_coldefs").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_affected_rows(E), db_conv_string(E), db_close(E), db_connect(E),
+        db_exec(E), db_error(E), db_fetch(E), db_handles(E), db_insert_id(E),
+        mysql(C), privilege_violation(M)
diff --git a/doc/efun/db_connect b/doc/efun/db_connect
new file mode 100644
index 0000000..abe20c9
--- /dev/null
+++ b/doc/efun/db_connect
@@ -0,0 +1,32 @@
+OPTIONAL
+SYNOPSIS
+        int db_connect(string database)
+        int db_connect(string database, string user)
+        int db_connect(string database, string user, string password)
+
+BESCHREIBUNG
+        Stelle eine Verbindung zur SQL-Datenbank <database> des
+        lokalen SQL-Servers her. Das Ergebnis ist die Handle-Nummer fuer diese
+        Verbindung und muss fuer alle Anfragen zu dieser Datenbank verwendet
+        werden.
+
+        Existiert die Datenbank nicht, oder kann der lokale SQL-Server nicht
+        gefunden werden, wird ein Laufzeitfehler erzeugt.
+
+        Wenn angegeben, wird die Verbindung fuer <user> mit <password>
+        erzeugt.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_connect").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_affected_rows(E), db_conv_string(E), db_close(E), db_coldefs(E),
+        db_exec(E), db_error(E), db_fetch(E), db_handles(E),
+        db_insert_id(E), mysql(C), privilege_violation(M)
diff --git a/doc/efun/db_conv_string b/doc/efun/db_conv_string
new file mode 100644
index 0000000..b630d6f
--- /dev/null
+++ b/doc/efun/db_conv_string
@@ -0,0 +1,20 @@
+OPTIONAL
+SYNOPSIS
+        string db_conv_string(string str)
+
+BESCHREIBUNG
+        Wandele den String <str> in einen String um, der von der Datenbank
+        korrekt interpretiert werden kann; z.B. werden all Apostrophe
+        durch \' ersetzt.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        db_affected_rows(E), db_close(E), db_coldefs(E), db_connect(E),
+        db_exec(E), db_error(E), db_fetch(E), db_handles(E), db_insert_id(E),
+        mysql(C)
diff --git a/doc/efun/db_error b/doc/efun/db_error
new file mode 100644
index 0000000..cb6d291
--- /dev/null
+++ b/doc/efun/db_error
@@ -0,0 +1,23 @@
+OPTIONAL
+SYNOPSIS
+        string db_error(int handle)
+
+BESCHREIBUNG
+        Result ist ein String, der den Fehler der letzten
+        Datenbanktransaktion beschreibt.  War die letzte Transaktion
+        erfolgreich, ist das Ergebnis 0.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_error").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_affected_rows(E), db_conv_string(E), db_close(E), db_coldefs(E),
+        db_connect(E), db_exec(E), db_fetch(E), db_handles(E), db_insert_id(E),
+        mysql(C), privilege_violation(M)
diff --git a/doc/efun/db_exec b/doc/efun/db_exec
new file mode 100644
index 0000000..274c983
--- /dev/null
+++ b/doc/efun/db_exec
@@ -0,0 +1,22 @@
+OPTIONAL
+SYNOPSIS
+        int db_exec(int handle, string statement)
+
+BESCHREIBUNG
+        Fuehre den SQL-Befehl <statement> fuer die Verbindung <handle> aus.
+        Resultat ist das Handle bei Erfolg, oder 0 bei einem Fehler.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_exec").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_affected_rows(E), db_conv_string(E), db_close(E), db_coldefs(E),
+        db_connect(E), db_error(E), db_fetch(E), db_handles(E),
+        db_insert_id(E), mysql(C), privilege_violation(M)
diff --git a/doc/efun/db_fetch b/doc/efun/db_fetch
new file mode 100644
index 0000000..b143e8a
--- /dev/null
+++ b/doc/efun/db_fetch
@@ -0,0 +1,23 @@
+OPTIONAL
+SYNOPSIS
+        mixed db_fetch(int handle)
+
+BESCHREIBUNG
+        Hole _eine_ Resultatzeile der letzten SQL-Aktion fuer Verbindung
+        <handle>. Sind keine weiteren Zeilen verfuegbar, wird 0
+        zurueckgegeben.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_fetch").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_affected_rows(E), db_conv_string(E), db_close(E), db_coldefs(E),
+        db_connect(E), db_error(E), db_exec(E), db_handles(E), db_insert_id(E),
+        mysql(C), privilege_violation(M)
diff --git a/doc/efun/db_handles b/doc/efun/db_handles
new file mode 100644
index 0000000..1a304b5
--- /dev/null
+++ b/doc/efun/db_handles
@@ -0,0 +1,24 @@
+OPTIONAL
+SYNOPSIS
+        int *db_handles()
+
+BESCHREIBUNG
+        Result ist ein Array mit allen aktiven Verbindungshandles zum
+        SQL-Server. Das Array ist nach der Zeit der letzten Aktion sortiert:
+        das zuletzt genutzte Handle kommt an erster Stelle. Sind keine
+        Verbindungen aktiv, ist das Array leer.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_handles").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_affected_rows(E), db_conv_string(E), db_close(E), db_coldefs(E),
+        db_connect(E), db_error(E), db_exec(E), db_fetch(E), db_insert_id(E),
+        mysql(C), privilege_violation(M)
diff --git a/doc/efun/db_insert_id b/doc/efun/db_insert_id
new file mode 100644
index 0000000..25e2a17
--- /dev/null
+++ b/doc/efun/db_insert_id
@@ -0,0 +1,23 @@
+OPTIONAL
+SYNOPSIS
+        int db_insert_id (int handle)
+
+BESCHREIBUNG
+        Nach dem Einfuegen einer Zeile in eine Tabelle mit einem
+        AUTO_INCREMENT-Feld, diese Efun kann dazu benutzt werden den neuen
+        Wert dieses Feldes zurueckzugeben.
+
+        Die Funktion ist nur verfuegbar wenn der Driver mit
+        mySQL-Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __MYSQL__ definiert.
+
+        Die Efun ist privilegiert als ("mysql", "db_insert_id").
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.9.
+        LDMud 3.2.11 machte die Efun privilegiert.
+
+SIEHE AUCH
+        db_affected_rows(E), db_conv_string(E), db_close(E), db_coldefs(E),
+        db_connect(E), db_error(E), db_exec(E), db_fetch(E), db_handles(E),
+        mysql(C), privilege_violation(M)
diff --git a/doc/efun/debug_message b/doc/efun/debug_message
new file mode 100644
index 0000000..07e75e6
--- /dev/null
+++ b/doc/efun/debug_message
@@ -0,0 +1,36 @@
+SYNOPSIS
+        #include <sys/debug_message.h>
+
+        void debug_message(string text);
+        void debug_message(string text, int flags);
+
+BESCHREIBUNG
+        Gibt <text> an die Ausgaenge stdout und stderr sowie an die Datei
+        <host>.debug.log, oder an eine beliebige Kombination dieser drei.
+
+        Das Argument <flag> bezeichnet durch eine Kombination von Bitflags das
+        Ziel und die Art, in der das Resultat geschrieben wird.
+
+        Die Ziel-Flags sind: DMSG_STDOUT, DMSG_STDERR und DMS_LOGFILE. Wird
+        zusaetzlich das Flag DMSG_STAMP gesetzt, erhaelt jeder Eintrag einen
+        Zeitstempel (Timestamp) im Format 'YYYY.MM.DD HH:MM:SS '.
+
+        Wenn <flags> 0 ist, weggelassen wird oder kein Ziel-Flag enthaelt,
+        wird <text> standardmaessig an stdout und ins Logfile ausgegeben.
+
+BEISPIEL
+        debug_message("Dieser Text geht an stdout und ins Logfile.\n");
+        debug_message("Dies geht an stderr.\n", DMSG_STDERR);
+        debug_message("Dies geht an stdout und stderr.\n", DMSG_STDOUT
+            | DMSG_STDERR);
+        debug_message("Dies geht an stdout und ins Logfile, mit Timestamp.\n",
+            DMSG_STAMP);
+        debug_message("Die geht an stdout, mit vorangestelltem Timestamp.\n",
+            DMSG_STDOUT | DMSG_STAMP);
+
+AENDERUNGEN
+        Eingefuehrt in 3.2.1@34.
+        LDMud 3.2.9 fuehrte das Argument <flags> ein.
+
+SIEHE AUCH
+        last_instructions(E)
diff --git a/doc/efun/deep_copy b/doc/efun/deep_copy
new file mode 100644
index 0000000..1cef9a8
--- /dev/null
+++ b/doc/efun/deep_copy
@@ -0,0 +1,27 @@
+SYNOPSIS
+        mixed deep_copy(mixed arg);
+
+BESCHREIBUNG
+        Erzeugt eine echte Kopie von <arg> und liefert diese zurueck. Fuer
+        Arrays und Mappings bedeutet dies, dass ein neues Array oder Mapping
+        erzeugt wird, das exakte Kopien der Eintraege des Originals enthaelt.
+        Eingebettete Arrays und Mappings werden ebenso echt kopiert.
+
+        Fuer andere Typen als Mappings und Arrays bewirkt diese Funktion
+        nichts.
+
+        Wenn im Driver DYNAMIC_COST definiert ist, zaehlt jedes eingebettete
+        Mapping oder Array zu den Evaluationskosten sowohl in der Groesse als
+        auch in der Einbettungstiefe.
+
+BEISPIEL
+        mixed *a, *b;
+        a = ({ 1, ({ 21, 22 }) });
+        b = deep_copy(a);
+        a[0] = -1; a[1][0] = -21;
+         --> a ist jetzt   ({ -1, ({ -21, 22 }) })
+             b bleibt      ({  1, ({  21, 22 }) })
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6.
+        LDMud 3.2.9 fuegte die dynamischen Kosten zur Efun hinzu.
diff --git a/doc/efun/deep_inventory b/doc/efun/deep_inventory
new file mode 100644
index 0000000..51f4c66
--- /dev/null
+++ b/doc/efun/deep_inventory
@@ -0,0 +1,36 @@
+SYNOPSIS
+        *object deep_inventory();
+        *object deep_inventory(object ob);
+        object *deep_inventory(object ob, int depth)
+
+BESCHREIBUNG
+        Gibt ein Array der Objekte zurueck, die in <obj> enthalten sind.
+        Wenn <obj> nicht angegeben wird, wird standardmaessig this_object()
+        verwendet. Ebenso werden alle Objekte angegeben, die sich im Inventory
+        der in <obj> enthaltenen Objekte befinden. Die Suche verlaeuft
+        rekursiv absteigend.
+
+        Ist <depth> angegeben und ungleich 0, ist das Resultat wie folgt
+        gefiltert:
+          <depth> > 0: Nur die Objekte in den ersten <depth> Ebenen
+                       werden zurueckgegeben.
+          <depth> < 0: Nur die Objekte in der -<depth>ten Ebene werden
+                       zurueckgegeben.
+
+BEISPIEL
+        ob
+        +- ob1
+        +- ob2
+        |   +- ob21
+        |  ob3
+        |   +- ob31
+        +- ob4
+
+
+        deep_inventory(ob) => ({ob1, ob2, ob3, ob4, ob21, ob31})
+        deep_inventory(ob, 1) => ({ob1, ob2, ob3, ob4})
+        deep_inventory(ob, 2) => ({ob1, ob2, ob3, ob4, ob21, ob31})
+        deep_inventory(ob, -2) => ({ob21, ob31})
+
+SIEHE AUCH
+        first_inventory(E), next_inventory(E), all_inventory(E)
diff --git a/doc/efun/destruct b/doc/efun/destruct
new file mode 100644
index 0000000..f64de56
--- /dev/null
+++ b/doc/efun/destruct
@@ -0,0 +1,43 @@
+SYNOPSIS
+        void destruct(object ob)
+
+BESCHREIBUNG
+        Zerstoert und entfernt das Objekt ob. Ist ob == 0 (ob wurde schon
+        zerstoert), so passiert nichts. Nach dem Aufruf von destruct()
+        existieren keine globalen Variablen mehr, sondern nur noch lokale
+        Variablen und Argumente.
+
+        Wenn sich ein Objekt selbst zerstoert, wird die Ausfuehrung nicht
+        sofort abgebrochen. Wird die Efun this_object() aufgerufen, so
+        liefert diese 0 zurueck.
+
+        Die meisten Mudlibs moegen es nicht, wenn andere Objekte mittels
+        destruct() ins Daten-Nirwana geschickt werden. Stattdessen erwarten
+        sie den Aufruf einer speziellen Lfun im zu zerstoerenden Objekt,
+        welche normalerweise remove() heisst. Damit kann das zu
+        zerstoerende Objekt noch abschliessende Arbeiten im Zusammenhang
+        mit seinem Ableben erledigen, wie z. B. die Anpassung des Gewichtes
+        seiner Umgebung etc. pp.
+
+        Der Interpreter zerstoert das Objekt nicht sofort, sondern er
+        markiert es als zerstoert, entfernt es von der Liste, die alle
+        Objekte enthaelt, und fuegt es zu der Liste zu zerstoerenden
+        Objekte hinzu. Die tatsaechliche Zerstoerung geschieht erst dann,
+        wenn keine Referenzen mehr auf das Objekt existieren. Deshalb ist
+        es moeglich, dass ein Objekt noch lange nach seiner Zerstoerung
+        Speicher belegt, obwohl es von ausserhalb nicht mehr gefunden wird.
+
+BEISPIEL
+        ob->remove();
+        if(ob)        // es existiert noch, vielleicht ist die Lfun
+                      // remove() nicht definiert?
+            destruct(ob);
+
+        Dies ist die Standard-Methode, ein Objekt zu zerstoeren, ihm aber
+        vorher noch die Chance zu geben, es selber zu tun.
+
+AENDERUNGEN
+        LDMud 3.2.7: 0 (zerstoerte Objekt) als Argument annehmen.
+
+SIEHE AUCH
+        clone_object(E), remove(A)
diff --git a/doc/efun/disable_commands b/doc/efun/disable_commands
new file mode 100644
index 0000000..0b6757e
--- /dev/null
+++ b/doc/efun/disable_commands
@@ -0,0 +1,10 @@
+SYNOPSIS
+        void disable_commands();
+
+BESCHREIBUNG
+        Verbietet dem Objekt, Kommandi zu verwenden, die normalerweise Usern
+        zugaenglich sind. Diese Funktion ist das Gegenteil von
+        enable_commands().
+
+SIEHE AUCH
+        enable_commands(E)
diff --git a/doc/efun/driver_info b/doc/efun/driver_info
new file mode 100644
index 0000000..f1eaa66
--- /dev/null
+++ b/doc/efun/driver_info
@@ -0,0 +1,685 @@
+SYNOPSIS
+        #include <driver_info.h>
+
+        mixed driver_info(int what)
+
+DESCRIPTION
+        Returns some internal information about the driver.
+        The argument <what> determines which information is returned.
+
+        It can be either a configuration option as given to
+        configure_driver() or one of the following options:
+
+
+
+        Driver Environment:
+
+        <what> == DI_BOOT_TIME:
+          The time() when the driver was started.
+
+
+
+        LPC Runtime status:
+
+        <what> == DI_CURRENT_RUNTIME_LIMITS:
+          Return an array with the current runtime limits.
+          The entries in the returned array are:
+
+            int[LIMIT_EVAL]:         the max number of eval costs
+            int[LIMIT_ARRAY]:        the max number of array entries
+            int[LIMIT_MAPPING_SIZE]: the max number of mapping values
+            int[LIMIT_MAPPING_KEYS]: the max number of mapping entries
+               (LIMIT_MAPPING is an alias for LIMIT_MAPPING_KEYS)
+            int[LIMIT_BYTE]:         the max number of bytes handled with
+                                     one read_bytes()/write_bytes() call.
+            int[LIMIT_FILE]:         the max number of bytes handled with
+                                     one read_file()/write_file() call.
+            int[LIMIT_CALLOUTS]:     the number of callouts at one time.
+            int[LIMIT_COST]:         how to account the current cost.
+            int[LIMIT_MEMROY]:       the max. number of bytes which can be 
+                                     _additionally_ allocated/used 
+                                     _per top-level execution thread_
+
+          For all limits except LIMIT_COST a limit of '0' aka LIMIT_UNLIMITED
+          means 'no limit'.
+
+          The value for LIMIT_COST has these meanings:
+
+            value > 0: the execution will cost minimum(<value>, actual cost) .
+            value = 0: if the current LIMIT_EVAL is larger than the calling
+                       LIMIT_EVAL, the evaluation will cost only 10; otherwise
+                       the full cost will be accounted.
+            value < 0: (-value)% of the current evaluation cost will be
+                       accounted; -100 obviously means 'full cost'.
+
+        <what> == DI_EVAL_NUMBER:
+          Return the current evaluation number.
+          The number is incremented for each top-level call. Top-level
+          calls are initiated by the driver, usually in reaction to an
+          external event:
+              - commands (added by add_action)
+              - heart_beat, reset, clean_up
+              - calls from call_out or input_to
+              - master applies triggered by external events
+              - calls of driver hooks in reaction to external events
+              - send_erq callbacks
+              - logon in interactives
+
+          The number can be used to detect cases where the same code is
+          executed twice in the same top level evaluation (say, heart_beat),
+          and also for time stamps for ordering some events.
+
+          Please note that the counter may overflow, especially on 32 bit
+          systems. As a result, it can also be negative.
+
+
+
+        Network configuration:
+
+        <what> == DI_MUD_PORTS:
+          Returns an array with all open ports, which the driver
+          listens for player connections on.
+
+        <what> == DI_UDP_PORT:
+          Returns the port number of the UDP socket.
+
+
+
+        Memory management:
+
+        <what> == DI_MEMORY_RESERVE_USER:
+          Current size of the user memory reserve.
+          The user memory reserve is allocated at startup and is used
+          when the driver runs out of memory.
+
+        <what> == DI_MEMORY_RESERVE_MASTER:
+          Current size of the master memory reserve.
+          The master memory reserve is allocated at startup and is used
+          when the driver runs out of memory while executing master
+          code.
+
+        <what> == DI_MEMORY_RESERVE_SYSTEM:
+          Current size of the system memory reserve.
+          The system memory reserve is allocated at startup and is used
+          when the driver runs out of memory while executing internal
+          operations.
+
+
+
+        Traces:
+
+        <what> == DI_TRACE_CURRENT:
+          Returns the current stack trace in array form.
+
+          If the array has more than one entries, the first entry is 0 or
+          the name of the object with the heartbeat which started the
+          current thread; all following entries describe the call stack
+          starting with the topmost function called.
+
+          All call entries are arrays themselves with the following elements:
+
+               int[TRACE_TYPE]: The type of the call frame:
+                   TRACE_TYPE_SYMBOL (0): a function symbol (shouldn't happen).
+                   TRACE_TYPE_SEFUN  (1): a simul-efun.
+                   TRACE_TYPE_EFUN   (2): an efun closure.
+                   TRACE_TYPE_LAMBDA (3): a lambda closure.
+                   TRACE_TYPE_LFUN   (4): a normal lfun.
+
+               mixed[TRACE_NAME]: The 'name' of the called frame:
+                   _TYPE_EFUN:   either the name of the efun, or the code of
+                                 the instruction for operator closures
+                   _TYPE_LAMBDA: the numeric lambda identifier.
+                   _TYPE_LFUN:   the name of the lfun.
+
+               string[TRACE_PROGRAM]: The (file)name of the program holding
+                                      the code.
+
+               string[TRACE_OBJECT]:  The name of the object for which the code
+                                      was executed.
+               int[TRACE_LOC]:
+                   _TYPE_LAMBDA: current program offset from the start of the
+                                 closure code.
+                   _TYPE_LFUN:   the line number.
+
+        <what> == DI_TRACE_CURRENT_DEPTH:
+          Return the current number of frames on the control stack
+          (recursion depth).
+
+        <what> == DI_TRACE_CURRENT_AS_STRING:
+          Returns the current stack trace as a string.
+
+        <what> == DI_TRACE_LAST_ERROR:
+          Returns the stack trace of the last error in array form
+          (same format as DI_TRACE_CURRENT). Stack traces of errors
+          before the last GC might not be available anymore.
+
+        <what> == DI_TRACE_LAST_ERROR_AS_STRING:
+          Returns the stack trace of the last error as a string.
+
+        <what> == DI_TRACE_LAST_UNCAUGHT_ERROR:
+          Returns the stack trace of the last uncaught error in array form
+          (same format as DI_TRACE_CURRENT). Stack traces of errors
+          before the last GC might not be available anymore.
+
+        <what> == DI_TRACE_LAST_UNCAUGHT_ERROR_AS_STRING:
+          Returns the stack trace of the last uncaught error as a string.
+
+
+
+        LPC Runtime statistics:
+
+        <what> == DI_NUM_FUNCTION_NAME_CALLS:
+          Number of function calls by name (like call_other).
+
+        <what> == DI_NUM_FUNCTION_NAME_CALL_HITS:
+          Function calls by name are cached (to accelerate
+          lookup of the corresponding program code).
+          This returns the number of cache hits.
+
+        <what> == DI_NUM_FUNCTION_NAME_CALL_MISSES:
+          The number of function call cache misses.
+
+        <what> == DI_NUM_OBJECTS_LAST_PROCESSED:
+          Number of listed objects processed in the last backend cycle.
+
+        <what> == DI_NUM_HEARTBEAT_TOTAL_CYCLES:
+          Total number of heart_beats cycles so far.
+
+        <what> == DI_NUM_HEARTBEAT_ACTIVE_CYCLES:
+          Number of active heart_beat cycles executed so far
+          (ie. cycles in which at least one heart_beat() function
+          was called).
+
+        <what> == DI_NUM_HEARTBEATS_LAST_PROCESSED:
+          Number of heart_beats calls in the last backend cycle
+
+        <what> == DI_NUM_STRING_TABLE_STRINGS_ADDED:
+          Number of distinct strings added to the string table so far.
+
+        <what> == DI_NUM_STRING_TABLE_STRINGS_REMOVED:
+          Number of distinct strings removed from the string table so far.
+
+        <what> == DI_NUM_STRING_TABLE_LOOKUPS_BY_VALUE:
+          Number of string searches by value.
+
+        <what> == DI_NUM_STRING_TABLE_LOOKUPS_BY_INDEX:
+          Number of string searches by address.
+
+        <what> == DI_NUM_STRING_TABLE_LOOKUP_STEPS_BY_VALUE:
+          Number of lookup steps needed for string searches by value.
+
+        <what> == DI_NUM_STRING_TABLE_LOOKUP_STEPS_BY_INDEX:
+          Number of lookup steps needed for string searches by address.
+
+        <what> == DI_NUM_STRING_TABLE_HITS_BY_VALUE:
+          Number of successful lookups of strings by value.
+
+        <what> == DI_NUM_STRING_TABLE_HITS_BY_INDEX:
+          Number of successful lookups of strings by address.
+
+        <what> == DI_NUM_STRING_TABLE_COLLISIONS:
+          Number of distinct strings added to an existing hash chain so far.
+
+        <what> == DI_NUM_REGEX_LOOKUPS:
+          Number of requests for new regexps.
+
+        <what> == DI_NUM_REGEX_LOOKUP_HITS:
+          Number of requested regexps found in the table.
+
+        <what> == DI_NUM_REGEX_LOOKUP_MISSES:
+          Number of requested regexps not found in the table.
+
+        <what> == DI_NUM_REGEX_LOOKUP_COLLISIONS:
+          Number of requested new regexps which collided with a cached one.
+
+
+
+        Network statistics:
+
+        <what> == DI_NUM_MESSAGES_OUT:
+          Number of messages sent to a player.
+
+        <what> == DI_NUM_PACKETS_OUT:
+          Number of packets sent to a player.
+
+        <what> == DI_NUM_PACKETS_IN:
+          Number of packets received from a player.
+
+        <what> == DI_SIZE_PACKETS_OUT:
+          Number of bytes sent to a player.
+
+        <what> == DI_SIZE_PACKETS_IN:
+          Number of bytes received from a player.
+
+
+
+        Load:
+
+        <what> == DI_LOAD_AVERAGE_COMMANDS:
+          A float value that shows the number of executed player commands
+          per second.
+
+        <what> == DI_LOAD_AVERAGE_LINES:
+          A float value that shows the number of compiled code lines
+          per second.
+
+        <what> == DI_LOAD_AVERAGE_PROCESSED_OBJECTS:
+          A float value that shows the average number of objects processed
+          each backend cycle.
+
+        <what> == DI_LOAD_AVERAGE_PROCESSED_OBJECTS_RELATIVE:
+          Average number of objects processed each cycle, expressed
+          as percentage (0..1.0) of the number of present objects.
+
+        <what> == DI_LOAD_AVERAGE_PROCESSED_HEARTBEATS_RELATIVE:
+          Average number of heart_beats called each cycle, expressed
+          as fraction (0..1.0) of the number of active heartbeats.
+
+
+
+        Memory use statistics:
+
+        <what> == DI_NUM_ACTIONS:
+          Number of allocated actions.
+
+        <what> == DI_NUM_CALLOUTS:
+          Number of pending call_outs.
+
+        <what> == DI_NUM_HEARTBEATS:
+          Number of objects with a heartbeat.
+
+        <what> == DI_NUM_SHADOWS:
+          Number of allocated shadows.
+
+        <what> == DI_NUM_OBJECTS:
+          Number of objects.
+
+        <what> == DI_NUM_OBJECTS_SWAPPED:
+          Number of objects that are swapped-out.
+
+        <what> == DI_NUM_OBJECTS_IN_LIST:
+          Number of objects in the object list
+          (i.e. not destructed objects).
+
+        <what> == DI_NUM_OBJECTS_IN_TABLE:
+          Number of objects in the object table.
+
+        <what> == DI_NUM_OBJECTS_DESTRUCTED:
+          Number of destructed, but still referenced objects.
+          (Not counting DI_NUM_OBJECTS_NEWLY_DESTRUCTED).
+
+        <what> == DI_NUM_OBJECTS_NEWLY_DESTRUCTED:
+          Number of newly destructed objects (ie. objects destructed
+          in this execution thread, that will really be destroyed in
+          the next backend cycle).
+
+        <what> == DI_NUM_OBJECT_TABLE_SLOTS:
+          Number of hash slots provided by the object table.
+
+        <what> == DI_NUM_PROGS:
+          Size occupied by the object table.
+
+        <what> == DI_NUM_PROGS_SWAPPED:
+          Number of swapped-out program blocks
+
+        <what> == DI_NUM_PROGS_UNSWAPPED:
+          Number of programs that were swapped-out, are now swapped-in,
+          but still have allocated space in the swap file.
+
+        <what> == DI_NUM_ARRAYS:
+          Number of currently existing arrays.
+
+        <what> == DI_NUM_MAPPINGS:
+          Number of currently existing mappings.
+
+        <what> == DI_NUM_MAPPINGS_CLEAN:
+          Number of clean mappings (mappings without a hash part).
+
+        <what> == DI_NUM_MAPPINGS_HASH:
+          Number of hash mappings.
+
+        <what> == DI_NUM_MAPPINGS_HYBRID:
+          Number of hybrid mappings (mappings that have a
+          condensed and hash part).
+
+        <what> == DI_NUM_STRUCTS:
+          Number of currently existing structs.
+
+        <what> == DI_NUM_STRUCT_TYPES:
+          Number of currently existing struct types.
+
+        <what> == DI_NUM_VIRTUAL_STRINGS:
+          Number of currently existing virtual strings
+          (identical strings are counted separately).
+
+        <what> == DI_NUM_STRINGS:
+          Number of real strings (identical strings
+          are counted once).
+
+        <what> == DI_NUM_STRINGS_TABLED:
+          Number of directly tabled strings.
+
+        <what> == DI_NUM_STRINGS_UNTABLED:
+          Number of untabled strings.
+
+        <what> == DI_NUM_STRING_TABLE_SLOTS:
+          Number of hash slots in the string table.
+
+        <what> == DI_NUM_STRING_TABLE_SLOTS_USED:
+          Number of hash chains in the string table.
+
+        <what> == DI_NUM_REGEX:
+          Number of cached regular expressions.
+
+        <what> == DI_NUM_REGEX_TABLE_SLOTS:
+          Number of slots in the regexp cache table.
+
+        <what> == DI_SIZE_ACTIONS:
+          Total size of allocated actions.
+
+        <what> == DI_SIZE_CALLOUTS:
+          Total size of pending call_outs.
+
+        <what> == DI_SIZE_HEARTBEATS:
+          Total size of the heart_beat list.
+
+        <what> == DI_SIZE_SHADOWS:
+          Total size of allocated shadows.
+
+        <what> == DI_SIZE_OBJECTS:
+          Total size of objects (not counting the size of the values
+          of their variables).
+
+        <what> == DI_SIZE_OBJECTS_SWAPPED:
+          Total size of swapped-out variable blocks.
+
+        <what> == DI_SIZE_OBJECT_TABLE:
+          Size occupied by the object table.
+
+        <what> == DI_SIZE_PROGS:
+          Total size of all programs.
+
+        <what> == DI_SIZE_PROGS_SWAPPED:
+          Total size of swapped-out program blocks
+
+        <what> == DI_SIZE_PROGS_UNSWAPPED:
+          Total size of unswapped program blocks
+
+        <what> == DI_SIZE_ARRAYS:
+          Total size of all arrays (not counting additional sizes
+          of array element values).
+
+        <what> == DI_SIZE_MAPPINGS:
+          Total size of all mapping (not counting additional sizes
+          of contained values).
+
+        <what> == DI_SIZE_STRUCTS:
+          Total size of all structs (not counting additional sizes
+          of contained values).
+
+        <what> == DI_SIZE_STRUCT_TYPES:
+          Total size of all struct type definitions.
+
+        <what> == DI_SIZE_STRINGS:
+          Total size of all strings.
+
+        <what> == DI_SIZE_STRINGS_TABLED:
+          Total size of all tabled strings.
+
+        <what> == DI_SIZE_STRINGS_UNTABLED:
+          Total size of all untabled strings.
+
+        <what> == DI_SIZE_STRING_TABLE:
+          Size of the string table structure itself.
+
+        <what> == DI_SIZE_STRING_OVERHEAD:
+          Size of the overhead per string (compared to a raw string).
+
+        <what> == DI_SIZE_REGEX:
+          Total size of all cached regular expressions.
+
+        <what> == DI_SIZE_BUFFER_FILE:
+          The size of the memory buffer for file operations.
+
+        <what> == DI_SIZE_BUFFER_SWAP:
+          The size of the memory buffer for the swap file.
+
+
+
+        Memory swapper statistics:
+
+        <what> == DI_NUM_SWAP_BLOCKS:
+          Number of blocks in the swap file.
+
+        <what> == DI_NUM_SWAP_BLOCKS_FREE:
+          Number of free blocks in the swap file.
+
+        <what> == DI_NUM_SWAP_BLOCKS_REUSE_LOOKUPS:
+          Number of searches for blocks to reuse in the swap file.
+
+        <what> == DI_NUM_SWAP_BLOCKS_REUSE_LOOKUP_STEPS:
+          Total number of lookup steps in searches for blocks
+          to reuse in the swap file.
+
+        <what> == DI_NUM_SWAP_BLOCKS_FREE_LOOKUPS:
+          Number of searches for blocks to free in the swap file.
+
+        <what> == DI_NUM_SWAP_BLOCKS_FREE_LOOKUP_STEPS:
+          Total number of lookup steps in searches for blocks
+          to free in the swap file.
+
+        <what> == DI_SIZE_SWAP_BLOCKS:
+          Size of the swap file.
+
+        <what> == DI_SIZE_SWAP_BLOCKS_FREE:
+          Size of free blocks in the swap file.
+
+        <what> == DI_SIZE_SWAP_BLOCKS_REUSED:
+          Total reused space in the swap file.
+
+        <what> == DI_SWAP_RECYCLE_PHASE:
+          True if the swapper is currently recycling free block.
+
+
+
+        Memory allocator statistics:
+
+        <what> == DI_MEMORY_ALLOCATOR_NAME:
+          The name of the allocator: "sysmalloc", "smalloc", "slaballoc
+
+        <what> == DI_NUM_SYS_ALLOCATED_BLOCKS:
+          Number of memory blocks requested from the operating system.
+
+        <what> == DI_NUM_LARGE_BLOCKS_ALLOCATED:
+          Number of large allocated blocks.
+          (With smalloc: The large allocated blocks include
+          the small chunk blocks.)
+
+        <what> == DI_NUM_LARGE_BLOCKS_FREE:
+          Number of large free blocks.
+
+        <what> == DI_NUM_LARGE_BLOCKS_WASTE:
+          Number of unusable large memory fragments.
+
+        <what> == DI_NUM_SMALL_BLOCKS_ALLOCATED:
+          Number of small allocated blocks.
+
+        <what> == DI_NUM_SMALL_BLOCKS_FREE:
+          Number of small free blocks.
+
+        <what> == DI_NUM_SMALL_BLOCKS_WASTE:
+          Number of unusably small memory fragments.
+
+        <what> == DI_NUM_SMALL_BLOCK_CHUNKS:
+          Number of small chunk/slab blocks.
+          (That are large blocks that are used as a
+          base for small blocks.)
+
+        <what> == DI_NUM_UNMANAGED_BLOCKS:
+          Number of unmanaged (non-GC-able) allocations.
+
+        <what> == DI_NUM_FREE_BLOCKS_AVL_NODES:
+          Number of AVL nodes used to manage the large free
+          blocks. This value might go away again.
+
+        <what> == DI_SIZE_SYS_ALLOCATED_BLOCKS:
+          Total size of memory requested from the operating system.
+
+        <what> == DI_SIZE_LARGE_BLOCKS_ALLOCATED:
+          Total size of large allocated blocks.
+
+        <what> == DI_SIZE_LARGE_BLOCKS_FREE:
+          Total size of large free blocks.
+
+        <what> == DI_SIZE_LARGE_BLOCKS_WASTE:
+          Total size of unusable large memory fragments.
+
+        <what> == DI_SIZE_LARGE_BLOCK_OVERHEAD:
+          The overhead of every large block allocation.
+
+        <what> == DI_SIZE_SMALL_BLOCKS_ALLOCATED:
+          Total size of small allocated blocks.
+
+        <what> == DI_SIZE_SMALL_BLOCKS_FREE:
+          Total size of small free blocks.
+
+        <what> == DI_SIZE_SMALL_BLOCKS_WASTE:
+          Total size of unusably small memory fragments.
+
+        <what> == DI_SIZE_SMALL_BLOCK_OVERHEAD:
+          The overhead of every small block allocation.
+
+        <what> == DI_SIZE_SMALL_BLOCK_CHUNKS:
+          Total size of small chunk/slab blocks.
+
+        <what> == DI_SIZE_UNMANAGED_BLOCKS:
+          Total size of unmanaged (non-GC-able) allocations.
+
+        <what> == DI_SIZE_MEMORY_USED:
+          The amount of memory currently allocated from the allocator.
+
+        <what> == DI_SIZE_MEMORY_UNUSED:
+          The amount of memory allocated from the system, but
+          not used by the driver.
+
+        <what> == DI_SIZE_MEMORY_OVERHEAD:
+          Amount of memory used for the management of the memory.
+
+        <what> == DI_NUM_INCREMENT_SIZE_CALLS:
+          Number of requests to increase the size of a memory block.
+
+        <what> == DI_NUM_INCREMENT_SIZE_CALL_SUCCESSES:
+          Number of successful requests to increase the
+          size of a memory block.
+
+        <what> == DI_SIZE_INCREMENT_SIZE_CALL_DIFFS:
+          Total size of additionally allocated memory by
+          increasing already allocated memory blocks.
+
+        <what> == DI_NUM_REPLACEMENT_MALLOC_CALLS:
+          Number of allocations done through the
+          clib functions (if supported by the allocator).
+
+        <what> == DI_SIZE_REPLACEMENT_MALLOC_CALLS:
+          Total size of allocations done through the
+          clib functions (if supported by the allocator).
+
+        <what> == DI_NUM_MEMORY_DEFRAGMENTATION_CALLS_FULL:
+          Total number of requests to defragment all small memory chunks.
+
+        <what> == DI_NUM_MEMORY_DEFRAGMENTATION_CALLS_TARGETED:
+          Total number of requests to defragment small memory chunks
+          for a desired size.
+
+        <what> == DI_NUM_MEMORY_DEFRAGMENTATION_CALL_TARGET_HITS:
+          Total number of successful requests to defragment small
+          memory chunks for a desired size.
+
+        <what> == DI_NUM_MEMORY_DEFRAGMENTATION_BLOCKS_INSPECTED:
+          Number of blocks inspected during defragmentations.
+
+        <what> == DI_NUM_MEMORY_DEFRAGMENTATION_BLOCKS_MERGED:
+          Number of blocks merged during defragmentations.
+
+        <what> == DI_NUM_MEMORY_DEFRAGMENTATION_BLOCKS_RESULTING:
+          Number of defragmented blocks (ie. merge results).
+
+        <what> == DI_MEMORY_EXTENDED_STATISTICS:
+          If the driver was compiled with extended memory statistics,
+          they are returned in this entry; if the driver was compiled
+          without the statistics, 0 is returned.
+
+          The array contains NUM+2 entries, where NUM is the number
+          of distinct small block sizes. Entry [NUM] describes the
+          statistics of oversized small blocks (smalloc) resp. for
+          all slabs (slaballoc), entry [NUM+1] summarizes all large
+          blocks. Each entry is an array of these fields:
+
+               int DIM_ES_MAX_ALLOC:
+                       Max number of allocated blocks of this size.
+
+               int DIM_ES_CUR_ALLOC:
+                       Current number of allocated blocks of this size.
+
+               int DIM_ES_MAX_FREE:
+                       Max number of allocated blocks of this size.
+
+               int DIM_ES_CUR_FREE:
+                       Current number of allocated blocks of this size.
+
+               float DIM_ES_AVG_XALLOC:
+                       Number of explicit allocation requests per
+                       second.
+
+               float DIM_ES_AVG_XFREE:
+                       Number of explicit deallocation requests per
+                       second.
+
+               int DIM_ES_FULL_SLABS:
+                       Number of fully used slabs (slaballoc only).
+
+               int DIM_ES_FREE_SLABS:
+                       Number of fully free slabs (slaballoc only).
+
+               int DIM_ES_TOTAL_SLABS:
+                       Total number of slabs: partially used, fully used
+                       and fully free (slaballoc only).
+
+           The allocation/deallocation-per-second statistics do
+           not cover internal shuffling of the freelists.
+
+           The slab statistics (entry [NUM], slaballoc only) shows
+           in the AVG statistics the frequence with which slabs were
+           allocated from resp. returned to the large memory pool.
+
+
+
+        Status texts:
+
+        <what> == DI_STATUS_TEXT_MEMORY:
+          A printable string containing information about
+          the memory usage.
+
+        <what> == DI_STATUS_TEXT_TABLES:
+          A printable string containing information about
+          the LPC runtime.
+
+        <what> == DI_STATUS_TEXT_SWAP:
+          A printable string containing information about
+          the swap system.
+
+        <what> == DI_STATUS_TEXT_MALLOC:
+          A printable string containing information about
+          memory allocations.
+
+        <what> == DI_STATUS_TEXT_MALLOC_EXTENDED:
+          A printable strings with extended memory statistics
+          (if the driver was compiled with them).
+
+
+HISTORY
+        Introduced in LDMud 3.5.0.
+
+SEE ALSO
+        configure_driver(E), object_info(E), interactive_info(E),
+        dump_driver_info(E)
diff --git a/doc/efun/dump_driver_info b/doc/efun/dump_driver_info
new file mode 100644
index 0000000..111f8ad
--- /dev/null
+++ b/doc/efun/dump_driver_info
@@ -0,0 +1,75 @@
+SYNOPSIS
+        #include <driver_info.h>
+
+        int dump_driver_info(int what)
+        int dump_driver_info(int what, string filename)
+
+DESCRIPTION
+        Dumps information specificied by <what> into a file
+        specified by <filename>. If <filename> is omitted,
+        a default file name is used. The function calls
+        master->valid_write() to check that it can write
+        the files. The file in question is always written anew
+
+        On success the efun returns 1, or 0 if an error occured.
+
+        <what> == DDI_OBJECTS:
+          Dumps information about all live objects.
+          Default filename is '/OBJ_DUMP',
+          valid_write() will read 'objdump' for the function.
+
+          For every object, a line is written into the file with the
+          following information in the given order:
+            - object name
+            - size in memory, shared data counted only once
+            - size in memory if data wouldn't be shared
+            - number of references
+            - 'HB' if the object has a heartbeat, nothing if not.
+            - the name of the environment, or '--' if the object
+              has no environment
+            - in parentheses the number of execution ticks spent
+              in this object
+            - the swap status:
+               nothing if not swapped,
+               'PROG SWAPPED' if only the program is swapped
+               'VAR SWAPPED' if only the variabes are swapped
+               'SWAPPED' if both program and variables are swapped
+            - the time the object was created
+
+        <what> == DDI_OBJECTS_DESTRUCTED:
+          Dumps information about all destructed objects. 
+          Default filename is '/DEST_OBJ_DUMP',
+          valid_write() will read 'objdump' for the function.
+
+          For every object, a line is written into the file with the
+          following information in the given order:
+            - object name
+            - number of references
+            - 'NEW' if the object was destructed in this execution
+              thread, nothing if it is older already.
+
+        <what> == DDI_OPCODES:
+          Dumps usage information about the opcodes.
+          Default filename is '/OPC_DUMP',
+          valid_write() will read 'opcdump' for the function.
+
+        <what> == DDI_MEMORY:
+          Dumps a list of all allocated memory blocks (if the allocator
+          supports this).
+          Default filename is '/MEMORY_DUMP',
+          valid_write() will read 'memdump' for the function,
+          and the new data will be appended to the end of the file.
+
+          If the allocator doesn't support memory dumps, this call will
+          always return 0, and nothing will be written.
+
+          This works best if the allocator is compiled with
+          MALLOC_TRACE and/or MALLOC_LPC_TRACE.
+
+          NOTE: Make sure that this option can't be abused!
+
+HISTORY
+        Introduced in LDMud 3.5.0.
+
+SEE ALSO
+        driver_info(E), object_info(E), interactive_info(E)
diff --git a/doc/efun/ed b/doc/efun/ed
new file mode 100644
index 0000000..8a8dc33
--- /dev/null
+++ b/doc/efun/ed
@@ -0,0 +1,19 @@
+SYNOPSIS
+        void ed()
+        void ed(string file)
+        void ed(string file, string func)
+
+DESCRIPTION
+        Calling without arguments will start the editor ed with the
+        name of the error file, that was returned by
+        master->valid_read(0, geteuid(this_player()), "ed_start",
+        this_player()), usually something like ~/.err. If that file is
+        empty, ed will immediatly exit again.
+        Calling ed() with argument file will start the editor on the
+        file. If the optional argument func is given, this function
+        will be called after exiting the editor.
+
+        The editor ed is almost ed(1) compatible.
+
+SEE ALSO
+        enable_commands(E), query_editing(E), ed0(LPC)
diff --git a/doc/efun/efun b/doc/efun/efun
new file mode 100644
index 0000000..88cd3f5
--- /dev/null
+++ b/doc/efun/efun
@@ -0,0 +1,45 @@
+NAME
+        efun
+
+BESCHREIBUNG
+        Dieses Directory enthaelt die Beschreibungen fuer die Efuns in
+        LDMud 3.3 .
+
+        Diese Funktionen werden vom Driver zur Verfuegung gestellt und koennen
+        von jedem LPC-Objekt verwendet werden.
+
+        Spezielle Arten dieser Efuns sind:
+
+         - 'Optional'
+
+           Es steht dem Mud-Betreiber frei, diese Efuns zu deaktivieren.
+
+             assoc()
+             break_point()
+             db_*()
+             insert_alist()
+             intersect_alist()
+             parse_command()
+             process_string()
+             rusage()
+             set_is_wizard()
+             set_light()
+             transfer()
+
+         - 'Vorlaeufig'
+
+           Das Verhalten dieser Efuns kann sich in spaeteren Driverversionene
+           aendern.
+
+
+         - 'Obsolet' or 'Veraltet'
+
+             make_shared_string()
+
+           Diese Efuns sollten nicht weiter verwendet werden. Sie stehen
+           lediglich aus Kompatibilitaetsgruenden zur Verfuegung, und
+           werden in einer spaeteren Drivervariante entfernt werden.
+
+
+SIEHE AUCH
+        efuns(LPC), applied(A), master(M), lpc(LPC), concepts(C), driver(D)
diff --git a/doc/efun/efun__m_delete b/doc/efun/efun__m_delete
new file mode 100644
index 0000000..32b9e02
--- /dev/null
+++ b/doc/efun/efun__m_delete
@@ -0,0 +1,24 @@
+SYNOPSIS:
+	mapping m_delete(mapping map, mixed key)
+
+DESCRIPTION:
+	Remove the entry with index 'key' from mapping 'map', and
+	return the changed mapping. If the mapping does not have an
+	entry with index 'key', the first argument is returned.
+
+        If you don't want to modify the mapping map, checkout the
+        simul_efun m_delete().
+
+EXAMPLE: 
+
+        mapping m1, m2;
+
+        m1 = ([ "a":1, "b":2, "c":3 ]);
+
+        m2 = efun::m_delete(m1, "b");
+           => m1 = ([ "a":1, "c":3 ])
+	      m2 = ([ "a":1, "c":3 ])
+
+SEE ALSO:
+	mappingp(E), mkmapping(E), m_indices(E), m_values(E),
+	sizeof(E)
diff --git a/doc/efun/environment b/doc/efun/environment
new file mode 100644
index 0000000..ea10b3d
--- /dev/null
+++ b/doc/efun/environment
@@ -0,0 +1,69 @@
+SYNOPSIS
+        object environment();
+        object environment(object obj);
+        object environment(string obj);
+
+ARGUMENTE:
+     obj
+          Objekt oder Pfad-String eines Objektes dessen Umgebungsobjekt
+          gesucht ist
+
+BESCHREIBUNG:
+     Es wird das Objekt bestimmt, in dem sich obj aufhaelt.
+     Wird obj nicht angegeben, so wird this_object() als Objekt angenommen.
+
+     Zerstoerte Objekte haben kein Environment.
+
+BEMERKUNGEN:
+     - Blueprints, wie zum Beispiel Raeume haben oft kein environment(). Man
+       sollte daher ueberpruefen, ob ein environment() existiert, wenn man
+       darin oder darauf eine Funktion aufrufen will.
+
+BEISPIELE:
+     // In der Variable "raum" steht der Raum, in dem sich der Spieler derzeit
+     // aufhaelt - das kann auch 0 sein!
+     raum = environment(this_player());
+
+     // Dieses Objekt hat noch kein environment, da es eben erst geclont
+     // wurde. Ergo steht in env eine 0.
+     obj = clone_object("/std/thing");
+     env = environment(obj);
+
+     // alle Methoden die auf Environment arbeiten, sollten das vorher
+     // pruefen - insbesondere tell_room()
+     if(this_player() && environment(this_player()) &&
+        objectp(o=present("schild",environment(this_player()))) {
+
+      write("Du klebst Deine Plakette auf "+o->name(WEN)+".\n");
+      tell_room(environment(this_player()), break_string(
+		this_player()->Name(WER)+" pappt einen Aufkleber auf "+
+		o->name(WEN)+".",78),
+		({this_player()}));
+     }
+
+     // wenn Dinge sehr offensichtlich in Leuten kaputtgehen wird es
+     // komplexer (man kann das natuerlich noch weiter schachteln oder
+     // ueber all_environment() versuchen zu loesen
+     if(environment()) {
+      object ee;
+      ee=environment(environment());
+      if(living(environment())) {
+       tell_object(environment(),Name(WER)+" zerfaellt.\n");
+       if(ee)
+        tell_room(ee,
+	 environment()->Name(WESSEN)+" "+name(RAW)+" zerfaellt.\n",
+	 ({environment()}));
+      } else if(ee && living(ee))
+       if(environment()->QueryProp(P_TRANSPARENT))
+        tell_object(ee, Name(WER)+" zerfaellt in Deine"+
+	 (environment()->QueryProp(P_PLURAL)?"n":
+	  (environment()->QueryProp(P_GENDER)==FEMALE?"r":"m"))+
+	 environment()->name(RAW)+".\n");
+      } else tell_room(environment(),Name(WER)+" zerfaellt.\n");
+     }
+
+SIEHE AUCH:
+        first_inventory(E), next_inventory(E), all_inventory(E)
+        all_environment(E)
+
+20. Sep. 2002 Gloinson@MG
\ No newline at end of file
diff --git a/doc/efun/exec b/doc/efun/exec
new file mode 100644
index 0000000..c86d3e0
--- /dev/null
+++ b/doc/efun/exec
@@ -0,0 +1,39 @@
+SYNOPSIS
+        int exec(object new, object old)
+
+DESCRIPTION
+        exec() switches the connection from the interactive object old
+        to the object new. If the new object is also interactive, it's
+        connection will be transferred to the old object, thus
+        exchaning the two connections between the object. If the new
+        object is not interactive, the old will not be interactive
+        anymore after the exec call succeeded.
+
+        The result is 1 on success, and 0 on failure.
+
+        exec() is used to load different "user objects" or to reconnect
+        link dead users.
+
+        To provide security mechanisms, the interpreter calls
+        master->valid_exec(current_program, new, old), which must
+        return anything other than 0 to allow this exec() invocation.
+
+        After the exec(), if arg 2 was this_player(), this_player()
+        becomes arg 1, else vice versa. Ditto for this_interactive().
+
+        Take care when writing a simul-efun around exec(): the
+        'current_program' passed to the valid_exec() function will be
+        that of the simul-efun object. To get around this, use
+        bind_lambda() to bind #'exec to the real object and funcall()
+        the resulting closure.
+
+EXAMPLE
+        ob = clone_object("std/player");
+        exec(ob, this_object());
+        destruct(this_object());
+
+HISTORY
+        LDMud 3.2.9 added the switchover of this_interactive().
+
+SEE ALSO
+        connect(M), disconnect(M), logon(A), interactive(E)
diff --git a/doc/efun/execute_command b/doc/efun/execute_command
new file mode 100644
index 0000000..0784c7e
--- /dev/null
+++ b/doc/efun/execute_command
@@ -0,0 +1,21 @@
+VORLAEUFIG, GESCHUETZT
+SYNOPSIS
+        int execute_command(string command, object origin, object player);
+
+BESCHREIBUNG
+        Diese Funktion bietet Low-Level Zugriff auf den Kommandoparser:
+        <command> wird in Verb und Rest aufgespaltet und es werden die
+        entsprechenden add_actions in <origin> aufgerufen. Fuer die
+        Ausfuehrung der Funktion(en) wird this_player() auf <player> gesetzt.
+        execute_command() setzt auch passende Werte fuer query_command()
+        und query_verb(), die dem angegebenen <command> entsprechen.
+
+        execute_command() beruecksichtigt weder den H_MODIFY_COMMAND noch den
+        H_NOTIFY_FAIL Hook. Zwar kann notify_fail() verwendet werden, die
+        Verarbeitung muss jedoch durch das aufrufende Objekt erfolgen.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7
+
+SIEHE AUCH
+        hooks(C), command(E), notify_fail(E), command_stack(E)
diff --git a/doc/efun/exp b/doc/efun/exp
new file mode 100644
index 0000000..c5746dc
--- /dev/null
+++ b/doc/efun/exp
@@ -0,0 +1,8 @@
+SYNOPSIS
+        float exp(int|float zahl);
+
+BESCHREIBUNG
+        Die Exponentialfunktion. Liefert e^zahl.
+
+SIEHE AUCH
+        log(E), pow(E)
diff --git a/doc/efun/expand_define b/doc/efun/expand_define
new file mode 100644
index 0000000..c6ff189
--- /dev/null
+++ b/doc/efun/expand_define
@@ -0,0 +1,24 @@
+SYNOPSIS
+        string expand_define (string name)
+        string expand_define (string name, string arg, ...)
+
+DESCRIPTION
+        Expands the macro <name> with the argument(s) <arg>... (default is
+        one empty string "").
+        Result is the expanded macro, or 0 if there is no macro with
+        that name.
+
+        This efun is applicable only while an object is compiled,
+        therefore its usage is restricted to a few functions like the
+        H_INCLUDE_DIRS driver hook, or the masters runtime_error()
+        function.
+
+EXAMPLE
+        While compiling 'foo.c':
+          expand_define("__FILE__") --> "foo.c"
+
+HISTORY
+        Introduced in 3.2.1@93.
+
+SEE ALSO
+        hooks(C), runtime_error(M)
diff --git a/doc/efun/explode b/doc/efun/explode
new file mode 100644
index 0000000..096eaa1
--- /dev/null
+++ b/doc/efun/explode
@@ -0,0 +1,28 @@
+SYNOPSIS
+        string *explode(string str, string del)
+
+BESCHREIBUNG
+        Liefert ein Feld (Array) mit Zeichenketten (Strings), indem alle
+        Vorkommen von del (delimiter = Trenner) aus str herausgeschnitten
+        werden und so str in mehrere Zeichenketten zerlegt wird.
+
+        implode(explode(str, del), del) == str ist immer wahr.
+
+BEISPIELE
+        Funktion                    Rueckgabewert
+        -------------------------------------------------------------------
+        explode(" ab cd ef ", " ")  ({ "", "ab", "cd", "ef", "" })
+        explode("abc", "abc")       ({ "", "" })
+        explode("", "")             ({})
+        explode("abc", "xyz")       ({ "abc" })
+        explode("abc", "")          ({ "a", "b", "c" })
+
+AENDERUNGEN
+        Zeitpunkt der Aenderung unbekannt.
+        explode(" ab cd ef ", " ") lieferte frueher ({ "ab", "cd", "ef" })
+        anstatt ({ "", "ab", "cd", "ef", "" }), d. h., leere Zeichenketten
+        wurden ignoriert. Das neue Verhalten ist schoener, da nun
+        implode(explode(str, del), del) == str immer wahr ist.
+
+SIEHE AUCH
+        sscanf(E), implode(E), regexplode(E)
diff --git a/doc/efun/export_uid b/doc/efun/export_uid
new file mode 100644
index 0000000..5b1f6a3
--- /dev/null
+++ b/doc/efun/export_uid
@@ -0,0 +1,15 @@
+SYNOPSIS
+        void export_uid(object ob)
+
+DESCRIPTION
+        Set the uid of object ob to the current object's effective uid.
+        It is only possible when object ob has an effective uid of 0.
+
+        This efun is not available in Morgengrauen.
+
+HISTORY
+        Since 3.2.1@47, this efun is availabe only when using euids.
+        Since 3.2.7, this efun is always available.
+
+SEE ALSO
+        seteuid(E), getuid(E), geteuid(E), uids(C), native(C)
diff --git a/doc/efun/extern_call b/doc/efun/extern_call
new file mode 100644
index 0000000..03dca5f
--- /dev/null
+++ b/doc/efun/extern_call
@@ -0,0 +1,12 @@
+SYNOPSIS
+        int extern_call();
+
+BESCHREIBUNG
+        Liefert 0, wenn die momentane ausgefuehrte Funktion durch eine lokale
+        Funktion aufgerufen wurde, einen Wert ungleich 0 fuer Aufrufe durch
+        call_other(), den Treiber, Closures etc. Im Moment liefert die
+        Funktion in all diesen Faellen 1 zurueck, in Zukunft koennte
+        allerdings eine Unterscheidung der Aufrufe moeglich werden.
+
+SIEHE AUCH
+        call_other(E), previous_object(E)
\ No newline at end of file
diff --git a/doc/efun/file_size b/doc/efun/file_size
new file mode 100644
index 0000000..d49dd53
--- /dev/null
+++ b/doc/efun/file_size
@@ -0,0 +1,35 @@
+FUNKTION:
+        int file_size(string file)
+
+BESCHREIBUNG:
+        Liefert die Groesse des Files in Bytes.
+
+RUECKGABEWERT:
+        Liefert die Dateigroesse in Bytes.
+
+        Davon abweichend kann auch folgendes als Rueckgabewert vor-
+        kommen:
+
+        FSIZE_NOFILE    Das File ist entweder nicht vorhanden oder das
+         (-1)           abfragende Objekt besitzt keine Leserechte dafuer.
+        FSIZE_DIR       Es handelt sich nicht um ein File sondern um
+         (-2)           ein Verzeichnis.
+
+BEISPIELE:
+        Ein Spieler soll seinen Plan abfragen koennen:
+
+        #include <sys/files.h>
+        if(file_size("/p/service/loco/plans/"+
+                     getuid(this_player())+".plan") <= FSIZE_NOFILE)
+        {
+          write("Du hast keinen eigenen Plan festgelegt.\n");
+          return 1;
+        }
+ 
+        this_player()->More(read_file("/p/service/loco/plans/"+
+                            getuid(this_player())+".plan");
+         
+SIEHE AUCH:
+        file_time(S), write_file(E), cat(E), get_dir(E), ls()
+
+03.08.2007, Zesstra
diff --git a/doc/efun/filter b/doc/efun/filter
new file mode 100644
index 0000000..61bc1e8
--- /dev/null
+++ b/doc/efun/filter
@@ -0,0 +1,189 @@
+filter(E)
+
+FUNKTION:
+     mixed * filter (mixed *arg, string fun, string|object ob
+                                              , mixed extra...)
+     mixed * filter (mixed *arg, closure cl, mixed extra...)
+     mixed * filter (mixed *arg, mapping map, mixed extra...)
+
+     string  filter (string arg, string fun, string|object ob
+                                        , mixed extra...)
+     string  filter (string arg, closure cl, mixed extra...)
+     string  filter (string arg, mapping map, mixed extra...)
+
+     mapping filter (mapping arg, string func, string|object ob
+                                             , mixed extra...)
+     mapping filter (mapping arg, closure cl, mixed extra...)
+
+PARAMETER:
+     arr     - zu filterndes Array/Mapping/String
+     fun/cl  - zu rufende Methode/Closure
+     map     - filterndes Mapping
+     ob      - Objekt/Dateiname, an dem Methode gerufen werden soll
+     extra   - weitere Parameter fuer Methode/Closure
+
+BESCHREIBUNG:        
+     Ruft fuer jedes Element des Arrays oder Mappings <arg> die Funktion
+     <ob>-><func>() bzw. die Closure <cl> auf und liefert jene Elemente,
+     fuer die die Funktion / Closure TRUE ergeben hat. Die <extra>
+     Argumente werden als zusaetzliche Parameter an die Funktion
+     uebergeben und duerfen keine Referenzen von Array- oder Mapping-
+     Elementen sein (wie &(i[1]) ).
+
+     Wird <ob> nicht angegeben oder ist es weder ein String noch ein
+     Objekt, wird standardmaessig this_object() verwendet.
+
+     Ist <arg> ein Array, wird <fun> mit jedem Element des Arrays als
+     ersten Parameter aufgerufen, gefolgt von den <extra> Argumenten.
+     Wenn das Resultat der Funktion TRUE ergibt, wird das Element in das
+     Ergebnis der filter() Operation mit einbezogen.
+
+     Wird filter() mit einem Mapping <map> anstelle der Funktion <func>
+     aufgerufen, wird jedes Element im Array <arg>, das ein Key von <map>
+     ist, ins Ergebnis mit einbezogen.
+
+     Wenn <arg> ein Mapping ist, wird die Funktion <func> mit jedem Key
+     als erstem und (falls vorhanden) den Werten dieses Keys als restliche
+     Parameter, gefolgt von den <extra> Argumenten, aufgerufen. Wenn die
+     Funktion TRUE ergibt, wird das betreffende Element des Mappings ins
+     Ergebnis aufgenommen.
+
+     Abhaengig von der Groesse des Mappings <arg> erfolgt der Aufruf der
+     Funktion auf drei unterschiedliche Arten:
+
+     widthof(arg) == 0:  ob->func(key, 0, extra,...);
+     widthof(arg) == 1:  ob->func(key, arg[key], extra, ...);
+     widthof(arg) >1:    ob->fund(key, ({arg[key,0]...arg[key, n-1]}),
+                                  extra, ...);
+
+     Der Vorteil dieser Vorgehensweise ist, dass beide Typen von
+     multidimensionalen Mappings (Mappings mit mehreren Werte pro Key und
+     Mappings aus Arrays) gleich verarbeitet werden koennen.
+
+     Ist <arg> ein String, werden der Filterfunktion die einzelnen Zeichen des
+     Strings uebergeben und nur jene Zeichen im zurueckgegebenen String
+     aufgenommen, fuer die die Filterfunkton != 0 zurueckgibt.
+
+AENDERUNGEN
+     Eingefuehrt in LDMud 3.2.6. Die Funktion loest filter_array() ab.
+
+RUeCKGABEWERT:
+     Gefiltertes Array mit allen die Filterbedingung erfuellenden Elementen.
+
+BEMERKUNGEN:
+     (1) Achtung, die Elemente in 'arr' werden nicht tief kopiert, sind sie
+     also selbst Arrays oder Mappings, so fuehrt eine spaetere Aenderung im
+     Rueckgabe-Arrays zur Aenderung im Ursprungsarray:
+
+     int *i, *j;
+     i=({({1,2,3}),({4,5,6})});
+     j=filter(i, #'sizeof);     // filtert leere Arrays heraus
+     j[0][0]=8;
+
+     fuehrt zu: i==j==({({8,2,3}),({4,5,6})});
+
+     (2) Das Kopieren in das Rueckgabemapping erfolgt fuer jedes Element nach
+     Ausfuehrung der Filtermethode. Aenderungen der Werte im Array in dieser
+     Methode (globale Variable/Uebergabe als Referenz an filter)
+     schlagen sich also im Rueckgabearray nieder.
+
+     (3) Fuer Arrays wirkt filter() wie filter_array(), fuer Mappings stellt
+     filter() eine Verallgemeinerung von filter_indices() dar.
+
+BEISPIEL:
+     ### Filtere alle Lebewesen in einem Raum in ein Array ###
+     filter(all_inventory(this_object()),#'living);
+
+
+     ### Filtere alle tauben Spieler im Raum in ein Array ###
+     static int filter_isdeaf(object who) {
+       return (interactive(who) && who->QueryProp(P_DEAF));
+     }
+     
+     filter(all_inventory(this_object()), #'filter_isdeaf);
+
+
+     ### Filtern von Idlern (>=1 Sekunde idle) ###
+     // Folgend identische Resultate, aber andere Ansaetze:
+
+     #1: nutzt die Efun query_idle() als Lfun-Closure (ideal hier)
+         idle_usr = filter(users(), #'query_idle );
+
+     #2: mit Filtermethode
+         int check_if_idle(object user) {
+           return query_idle(user);
+         }
+         
+         #2a: filtert mittels der Lfun im selben Objekt die Idler in das
+              Rueckgabearray
+              idle_usr = filter(users(), "check_if_idle");
+              idle_usr = filter(users(), "check_if_idle", this_object());
+
+         #2b: ruft die Lfun check_if_idle() als Lfun-Closure (Funktions-
+              pointer)
+              idle_usr = filter(users(), #'check_if_idle );
+
+     #3: nutzt eine Lambda-Closure (langsamer, nicht fuer alle leserlich)
+         idle_usr = filter(users(), lambda(({'u}), ({#'query_idle, 'u})));
+
+     #4: erreicht dasselbe wie #3 mit besser lesbarer Inline-Closure
+         idle_usr = filter(users(), function int (object user) {
+                      return query_idle(user);
+                    } );
+
+     ### Filtern von Idlern (>=20 Sekunden idle) mit Extraparameter ###
+     // Folgend identische Resultate, aber andere Ansaetze:
+
+     #1: die Efun koennen wir nicht mehr direkt nutzen, weil sie
+         diesen Parameter nicht unterstuetzt
+        // idle_usr = filter(users(), #'query_idle );
+
+     #2: mit separater Filtermethode ... mit neuem Parameter
+         int check_if_idle(object user, int length) {
+           return query_idle(user)>length;
+         }
+      
+         #2a: filtert mittels der Lfun im selben Objekt die Idler in das
+              Rueckgabearray ... mit drittem Parameter!
+              idle_usr = filter(users(), "check_if_idle", this_object(), 20);
+
+         #2b: ruft die Lfun check_if_idle() als Lfun-Closure (Funktions-
+              pointer)
+              idle_usr = filter(users(), #'check_if_idle, 20);
+
+     #3: nutzt eine Lambda-Closure (langsamer, nicht fuer alle leserlich)
+         idle_usr = filter(users(), 
+                      lambda(({'u, 'l}), ({#'>,({#'query_idle, 'u}),'l})), 
+                      20);
+
+     #4: erreicht dasselbe wie #3 mit einer deutlich besser lesbaren
+         Inline-Closure (gegenueber Lambdas zu empfehlende Variante):
+         idle_usr = filter(users(), function int (object user, int length) {
+                      return (query_idle(user) > length); 
+                      }, 20);
+
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i;
+     mixed *ret; mixed *input;
+
+     ret=allocate(0);
+     i=sizeof(input);
+     while(i--)
+       if(ob->fun(input[i] [, extra1, extra2, ...]))
+       // if(funcall(cl, input[i] [, extra1, extra2, ...]))
+       // if(member(map, input[i]))
+         ret+=({input[i]});
+
+SIEHE AUCH:
+     Arrays:        map(E)
+     Objektarrays:  filter_objects(E), map_objects(E)
+     Mappings:      filter_indices(E), map_indices(E)
+                    walk_mapping(E), member(E)
+
+     Sonstiges:     sort_array(E), unique_array()
+                    transpose_array(E)
+
+----------------------------------------------------------------------------
+09.04.2008, Zesstra
+
diff --git a/doc/efun/filter.eng b/doc/efun/filter.eng
new file mode 100644
index 0000000..5d0be29
--- /dev/null
+++ b/doc/efun/filter.eng
@@ -0,0 +1,49 @@
+filter(E)
+SYNOPSIS
+     mixed *filter(mixed *arr, string fun, string|object ob
+                         [, mixed extra, ...])
+     mixed *filter(mixed *arr, closure cl [, mixed extra, ...])
+     mixed *filter(mixed *arr, mapping map [, mixed extra, ...])
+
+DESCRIPTION
+        Returns an array holding the items of arr filtered through
+        ob->fun(element, extra, ...), the closure cl, or the mapping map.
+        The function 'fun' in 'ob' resp. the closure 'cl' is called
+        for each element in arr with that element as parameter. The
+        extra and following parameters are in each call if given.
+        The mapping 'map' is likewise indexed by each element.
+        If ob->fun(arr[index], extra) returns != 0 resp.
+        map[arr[index]] exists, the element is included in the
+        returned array.
+
+        If arr is not an array, an error occurs.
+
+        The extra argument(s) are optional and must not be protected
+        references like &(i[0]).
+        If <ob> is omitted, or neither a string nor an object, it
+        defaults to this_object().
+
+        Since 3.2.1@36, the second arg can also be a mapping. Then
+        only the elements of the array which belong to the map (as
+        keys) will be returned (i.e. map[arr[index]] != 0).
+
+EXAMPLE
+        int check_if_idle(object user) { return query_idle(user); }
+
+        ...
+
+        object *idle_users;
+
+        idle_users = filter(users(), "check_if_idle");
+        /* equivalent but smaller and faster */
+        idle_users = filter(users(), #'query_idle );
+
+        Now idle_users contains all users that have been idle for more
+        than 1 second.
+
+SEE ALSO:
+        Similar filter:	filter(E), filter_object(E), filter_indices(E)
+        Mapping:	map(E), map_objects(E), map_indices(E)
+        Related:	sort_aray(E), unique_array(E)
+
+29.10.2006 Zesstra
diff --git a/doc/efun/filter_indices b/doc/efun/filter_indices
new file mode 100644
index 0000000..54fdadf
--- /dev/null
+++ b/doc/efun/filter_indices
@@ -0,0 +1,115 @@
+filter_indices(E)
+
+FUNKTION:
+     mapping filter_indices(mapping map, string fun, string|object ob
+                            [, mixed extra, ...])
+     mapping filter_indices(mapping map, closure cl [, mixed extra, ...])
+
+PARAMETER:
+     map	- zu filterndes Mapping
+     fun/cl	- zu rufende Methode/Closure
+     ob		- Objekt/Dateiname, an dem Methode gerufen werden soll
+     extra	- weitere Parameter fuer Methode/Closure
+
+BESCHREIBUNG:
+     Filtert die Elemente (jeweils Schluessel) aus 'map' durch die
+     Methode 'fun' oder die Closure 'cl' in ein neues Mapping.
+     Fuer jedes Element aus 'map' wird 'fun' oder 'cl' mit dem Schluessel als
+     erstem Parameter [und folgend den optionalen Extra-Parametern] gerufen.
+
+     Wenn der Aufruf
+      	ob->fun(element [, extra1, extra2, ...]) bzw.
+       	funcall(cl, element [, extra1, extra2, ...])
+     als Rueckgabewert !=0 zurueckgibt dann wird der Schluessel+Werte in das
+     neue Array aufgenommen, sonst nicht.
+
+     Wenn auf die Werte zugegriffen werden muss, kann das Mapping 'map'
+     zusaetzlich als 'extra'-Parameter uebergeben werden. Alternativ kann man
+     walk_mapping() benutzen und das Rueckgabemapping selbst erstellen.
+
+
+     Verwendung von Methoden:
+	Wenn bei der Angabe von 'fun' kein Objekt 'ob' in Form eines Strings
+	oder Objekts angegeben wird, wird this_object() angenommen.
+
+     Verwendung von Closures:
+	Es koennen sowohl Lfun-Closures als auch Lambda-Closures verwendet
+	werden. Lfun-Closures koennen, wenn im selben Objekt vorhanden auch
+	'private' oder/und 'static' deklariert sein, muessen aber zu dem
+	Zeitpunkt der Verwendung bekannt sein (Funktionsprototypen benutzen).
+
+RUeCKGABEWERT:
+     Gefiltertes Mapping mit Filterbedingung erfuellenden Elementen.
+
+BEMERKUNGEN:
+     (1) Achtung, die Elemente in 'map' werden nicht tief kopiert, sind sie
+     also selbst Arrays oder Mappings, so fuehrt eine spaetere Aenderung im
+     Rueckgabe-Mapping zur Aenderung im Ursprungsmapping:
+
+     mapping m,n;
+     m=([1:({1,2}),0:({2,3,4})]);
+     n=filter_indicdes(m, #'!);		// filtert alle Keys !=0 heraus
+     n[0][0]=8;
+
+     fuehrt zu: n=([0:({8,3,4})])
+  		m=([0:({8,3,4}),1:({1,2})])
+
+     (2) Das Kopieren in das Rueckgabemapping erfolgt fuer jedes Element nach
+     Ausfuehrung der Filtermethode. Aenderungen der Werte im Mapping in dieser
+     Methode (globale Variable/Uebergabe als Referenz an filter_indices)
+     schlagen sich also im Rueckgabemapping nieder.
+
+BEISPIELE:
+     ### erfundene Liste mit Spielern saeubern ... ###
+     mapping x=([ [/human:liafar]:  20,
+		  [/dwarf:mesirii]: 50,
+		  [/elf:zarniya]:   40,
+		  [/feline:turbo]:  30]);
+
+     int is_badguy(object who) {
+      if(who->InFight()) return 1;
+      return 0;
+     }
+
+     mapping result=filter_indices(x, #'is_badguy);
+     // 'result' enthaelt nur noch kaempfende Spieler
+
+     ### erfundene Liste ueber ihre Werte saeubern ###
+     int is_badguy(object who, mapping m) {
+      if(m[x]<30) return 1;
+      return 0;
+     }
+
+     mapping result=filter_indices(x, #'is_badguy, &x); // Referenz
+     // 'result' enthaelt nur Spieler mit Werten >= 30
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i, width;
+     mapping ret; mapping input;
+     mixed *index;
+
+     width=get_type_info(input)[1];
+     ret=m_allocate(0, width);
+     index=m_indices(input);
+     i=sizeof(index);
+     while(i--)
+       if(ob->fun(index[i] [, extra1, extra2, ...]))
+       // if(funcall(cl, index[i] [, extra1, extra2, ...]))
+       {
+         int j;
+         j=width;
+
+         while(j--)
+           ret[index[i],j]=input[index[i],j];
+       }
+
+SIEHE AUCH:
+     Arrays:		filter(E), map(E)
+     Objektarrays:	filter_objects(E), map_objects(E)
+     Mappings:		map_indices(E)
+
+     Sonstiges:		walk_mapping(E), m_contains(E)
+			member()
+			m_indices(E), m_values(E)
+
+29.10.2006 Zesstra
diff --git a/doc/efun/filter_objects b/doc/efun/filter_objects
new file mode 100644
index 0000000..9fb6922
--- /dev/null
+++ b/doc/efun/filter_objects
@@ -0,0 +1,59 @@
+filter_objects(E)
+
+FUNKTION:
+     object *filter_objects(mixed *arr, string fun, [, mixed extra, ...])
+
+PARAMETER:
+     arr	- zu filterndes Array von Objekten/Objektpfaden
+     fun	- an Objekten zu rufende Methode
+     extra	- weitere Parameter fuer Methode
+
+BESCHREIBUNG:
+     Filtert die Elemente aus 'arr' durch den Aufruf der Methode 'fun' an
+     jedem der Elemente von 'arr'. 0-Eintraege werden ignoriert.
+
+     Wenn der Aufruf
+	arr[n]->fun([extra1, extra2, ...])
+     als Rueckgabewert !=0 zurueckgibt dann wird das Element in das neue
+     Array aufgenommen, sonst nicht.
+
+RUeCKGABEWERT:
+     Gefiltertes Array mit Filterbedingung erfuellenden Objekten.
+
+BEMERKUNGEN:
+     Werden Pfade angegeben, so wird versucht ein Objekt zu laden, falls
+     dieses nicht existiert.
+
+BEISPIEL:
+     // gibt alle tauben Personen wieder
+     deaf=filter_objects(users(), "QueryProp", P_DEAF);
+
+     // gibt alle blinden Personen wieder
+     blind=filter_objects(users(), "QueryProp", P_BLIND);
+
+     // filtert alle Objekte auf eine bestimmte ID (-> present)
+     idmatch=filter_objects(arr, "id", "irgendwasID");
+
+     // gibt alle Autoloader wieder
+     al=filter_objects(all_inventory(this_player()),
+                      "QueryProp", P_AUTOLOADOBJ);
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i;
+     object *ret; mixed *input;
+
+     ret=allocate(0);
+     i=sizeof(input);
+     while(i--)
+       if(input[i]->fun([extra1, extra2, ...]))
+         ret+=({input[i]});
+
+SIEHE AUCH:
+     Arrays:		filter(E), map(E)
+     Objektarrays:	map_objects(E)
+     Mappings:		filter_indices(E), map_indices(E)
+
+     Sonstiges:		sort_array(E), unique_array()
+			alist, transpose_array(E)
+
+20.Jan 2005 Gloinson
diff --git a/doc/efun/find_call_out b/doc/efun/find_call_out
new file mode 100644
index 0000000..0e94337
--- /dev/null
+++ b/doc/efun/find_call_out
@@ -0,0 +1,41 @@
+FUNKTION:
+        int find_call_out(string func)
+        int find_call_out(closure cl)
+
+BESCHREIBUNG:
+        Findet den ersten call_out() auf die Funktion 'func' im aktuellen Objekt
+        (bzw. auf die Closure 'cl') der ausgefuehrt werden soll.
+        Zurueck gegeben wird die verbleibende Zeit bis zum Aufruf in Sekunden.
+        Wenn kein call_out() gefunden wird, wird -1 zurueck gegeben.
+
+BEISPIELE:
+        // Findet sich kein call_out auf die Funktion 'func', so kann er
+        // gestartet werden. (Wichtig falls der call_out nicht mehrfach
+        // aufgerufen werden soll).
+ 
+        if(find_call_out("func")==-1)
+          call_out("func",5);
+
+        // Alle call_out auf Funktion 'func' werden gefunden und gestoppt.
+        // (Beispielsweise weil ein Spieler den Raum verlaesst oder sich
+        // disconnectet).
+
+        while(find_call_out("func") > -1)
+          remove_call_out("func");
+
+        // Die Suche nach call_out()s auf Closures funktioniert nur, wenn der
+        // genaue Wert der Closure gesucht wird.
+
+        // Das funktioniert:
+            closure cl = symbol_function("main", obj);
+            call_out(cl, 2);
+            find_call_out(cl);
+
+        // Das funktioniert nicht:
+            call_out(symbol_function("main", obj), 2);
+            find_call_out(symbol_function("main", obj));
+
+SIEHE AUCH:
+        call_out(E), remove_call_out(E), call_out_info(E)
+
+4.Aug 2007 Gloinson
diff --git a/doc/efun/find_input_to b/doc/efun/find_input_to
new file mode 100644
index 0000000..cb299c0
--- /dev/null
+++ b/doc/efun/find_input_to
@@ -0,0 +1,26 @@
+SYNOPSIS
+        int find_input_to (object player, string fun);
+        int find_input_to (object player, closure fun);
+        int find_input_to (object player, object fun);
+        int find_input_to (object player, object ob, string fun);
+
+BESCHREIBUNG
+        Findet den zuletzt fuer <player> gestarteten input_to(), abhaengig vom
+        Argument <fun>:
+          - <fun> ist ein String: der Funktionsname des input_to() muss passen
+          - <fun> ist ein Objekt: das Objekt, an welches die Funktion des
+            input_to() gebunden ist, muss passen
+          - <fun> ist eine Closure: die input_to() Closure muss passen
+          - <ob> und <fun> sind angegeben: sowohl Objekt als auch
+            Funktionsname muessen passen.
+
+        Die Funktion liefert -1, wenn kein input_to() gefunden wurde, sonst
+        die Position im input_to() Stack (wobei 0 den als letztes
+        hinzugefuegten input_to() bezeichnet).
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9
+
+SIEHE AUCH
+        input_to(E), input_to_info(E), remove_input_to(E),
+        query_input_pending(E)
diff --git a/doc/efun/find_object b/doc/efun/find_object
new file mode 100644
index 0000000..2a4f0d0
--- /dev/null
+++ b/doc/efun/find_object
@@ -0,0 +1,23 @@
+SYNOPSIS:
+        object find_object(string str)
+
+DESCRIPTION:
+        Find an object with the object_name str. If the object isn't loaded,
+	it will not be found.
+
+EXAMPLE:
+        object obj;
+        obj = find_object("std/thing");
+        obj = find_object("std/thing.c");
+        obj = find_object("/std/thing");
+        obj = find_object("/std/thing.c");
+        
+        All four statements are equal.
+
+	obj = find_object("/std/thing#42");
+
+	returns the clone whose object_name is "std/thing#42", if
+	it exists.
+
+SEE ALSO:
+        find_living(E), find_player(E), object_name(E)
diff --git a/doc/efun/first_inventory b/doc/efun/first_inventory
new file mode 100644
index 0000000..99be7fd
--- /dev/null
+++ b/doc/efun/first_inventory
@@ -0,0 +1,34 @@
+SYNOPSIS
+        object first_inventory();
+        object first_inventory(string ob);
+        object first_inventory(object ob);
+
+BESCHREIBUNG
+        Liefert das erste Objekt im Inventory von <obj>, wobei <obj> entweder
+        ein Objekt oder der Name eines Objekts ist. Wenn <obj> nicht angegeben
+        wird, wird standardmaessig this_object() verwendet.
+
+BEISPIELE
+        Diese Efun verwendet man am haeufigsten im folgenden Kontext:
+
+            for(obj=first_inventory(container);obj;obj=next_inventory(obj))
+            {
+                <irgendwelcher Code>
+            }
+
+        ACHTUNG: Wenn das Objekt <obj> innerhalb von <irgendwelcher Code>
+        bewegt wird, liefert next_inventory() ein Objekt aus dem neuen
+        Inventory von <obj>. Auch sollte next_inventory() nicht fuer
+        zerstoerte Objekte <obj> aufgerufen werden. Fuer den Fall, dass
+        <obj> bewegt und/oder zerstoert wird, ist folgende Loesung
+        vorzuziehen:
+
+            for(obj=first_inventory(container);obj;)
+            {
+                next=next_inventory(obj);
+                <irgendwelcher Code mit Moves oder Removes>
+                obj=next;
+            }
+
+SIEHE AUCH
+        next_inventory(E), all_inventory(E), environment(E), deep_inventory(E)
diff --git a/doc/efun/floatp b/doc/efun/floatp
new file mode 100644
index 0000000..109cace
--- /dev/null
+++ b/doc/efun/floatp
@@ -0,0 +1,10 @@
+SYNOPSIS
+        int floatp(mixed arg)
+
+BESCHREIBUNG
+        Liefert 1, wenn das Argument eine Fliesskommazahl (float) ist,
+        ansonsten 0.
+
+SIEHE AUCH
+        intp(E), mappingp(E), stringp(E), closurep(E), objectp(E),
+        referencep(E), pointerp(E), symbolp(E), clonep(E)
diff --git a/doc/efun/floor b/doc/efun/floor
new file mode 100644
index 0000000..e7b85e6
--- /dev/null
+++ b/doc/efun/floor
@@ -0,0 +1,19 @@
+SYNOPSIS
+        float floor(float arg);
+
+BESCHREIBUNG
+        Rundet das Argument <arg> ab auf die naechste ganze Zahl und gibt
+        diesen Wert zurueck. Wenn <arg> ein Integer ist, wird das Resultat
+        trotzdem als Float zurueckgegeben.
+
+BEISPIELE
+        floor(4.5)  --> liefert 4.0
+        floor(-4.5) --> liefert -5.0
+        floor(5)    --> liefert 5.0
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7.
+        LDMud 3.2.9 erlaubt auch Integer als Argumente.
+
+SIEHE AUCH
+        abs(E), ceil(E)
diff --git a/doc/efun/funcall b/doc/efun/funcall
new file mode 100644
index 0000000..6bb9833
--- /dev/null
+++ b/doc/efun/funcall
@@ -0,0 +1,10 @@
+SYNOPSIS
+        mixed funcall(closure cl, mixed arg, ...);
+
+BESCHREIBUNG
+        Wertet die Closure 'cl' aus. Die Argumente 'args' werden als Argumente
+        an die Closure uebergeben. Wenn 'cl' keine Closure ist, wird 'cl'
+        zurueck gegeben.
+
+SIEHE AUCH
+        apply(E), quote(E)
diff --git a/doc/efun/function_exists b/doc/efun/function_exists
new file mode 100644
index 0000000..43f2da2
--- /dev/null
+++ b/doc/efun/function_exists
@@ -0,0 +1,14 @@
+SYNOPSIS
+        string function_exists(string str, object ob)
+
+DESCRIPTION
+        Return the file name of the object that defines the function
+        str in object ob. The returned value can be other than
+        object_name(ob) if the function is defined in an inherited
+        object. In !compat mode, the returned name always begins with a
+        '/' (absolute path). 0 is returned if the function was not
+        defined, or was defined as static (protected function on the
+        other hand are found).
+
+SEE ALSO
+        call_other(E), call_resolved(E), functionlist(E)
diff --git a/doc/efun/functionlist b/doc/efun/functionlist
new file mode 100644
index 0000000..46f2cba
--- /dev/null
+++ b/doc/efun/functionlist
@@ -0,0 +1,55 @@
+GESCHUETZT
+SYNOPSIS
+        #include <sys/functionlist.h>
+        #include <sys/lpctypes.h>
+
+        mixed *functionlist(object ob, int flags = RETURN_FUNCTION_NAME)
+
+BESCHREIBUNG
+        Liefert ein Array mit Informationen zu den Lfuns von <ob>. Fuer jede
+        Funktion werden 1 bis 4 Werte (abhaengig von <flags>) in das Ergebnis
+        eingetragen, und zwar in folgender Reihenfolge:
+          - der Name der Funktion
+          - die Flags der Funktion (vergleiche weiter unten)
+          - den Rueckgabetyp (aufgelistet in mudlib/sys/lpctypes.h)
+          - die Anzahl Argumente, die die Funktion akzeptiert.
+
+        <ob> kann als echtes Objekt oder als Objektname uebergeben werden. Im
+        zweiten Fall versucht die Efun nicht, das Objekt vorher zu laden.
+
+        <flags> bestimmt sowohl, welche Informationen im Ergebnis gesammelt
+        werden, als auch, fuer welche Funktionen die Pruefung durchgefuehrt
+        wird. Der Wert von <flags> wird durch binaere Veroderung folgender
+        Konstanten aus mudlib/sys/functionlist.h festgelegt:
+
+        Festlegen der gesammelten Information:
+            RETURN_FUNCTION_NAME        liefert den Funktionsnamen
+            RETURN_FUNCTION_FLAGS       liefert die Flas der Funktion
+            RETURN_FUNCTION_TYPE        liefert den Rueckgabetyp der Funktion
+            RETURN_FUNCTION_NUMARG      liefert die Anzahl moeglicher
+                                        Argumente.
+
+            RETURN_FUNCTION_ARGTYPE     ist definiert, aber nicht
+                                        implementiert.
+
+        Festlegen der geprueften Funktionen:
+            NAME_INHERITED      geerbte Funktionen nicht beachten
+            TYPE_MOD_STATIC     static deklarierte Funktion nicht beachten
+            TYPE_MOD_PRIVATE    private deklarierte Funktionen nicht beachten
+            TYPE_MOD_PROTECTED  protected deklarierte Funktionen nicht
+                                beachten
+            NAME_HIDDEN         nur beachten, wenn sichtbar durch Vererbung
+
+        <flags> besteht aus der binaeren Veroderung der oben genannten Flags,
+        zusammen mit den folgenden:
+            TYPE_MOD_VARARGS    die Funktion ist varargs deklariert
+            NAME_UNDEFINED      die Funktion ist noch nicht definiert, aber
+                                referenziert
+            NAME_CROSS_DEFINED  die Funktion ist definiert, um in einem
+                                anderen Programm verwendet zu werden
+            TYPE_MOD_NOMASK     die Funktion ist nomask deklariert
+            TYPE_MOD_PUBLIC     die Funktion ist public deklariert
+
+SIEHE AUCH
+        inherit_list(E), function_exists(E), variable_list(E),
+        call_resolved(E)
diff --git a/doc/efun/garbage_collection b/doc/efun/garbage_collection
new file mode 100644
index 0000000..5c6a738
--- /dev/null
+++ b/doc/efun/garbage_collection
@@ -0,0 +1,22 @@
+GESCHUETZT
+SYNOPSIS
+        void garbage_collection();
+        void garbage_collection(string filename);
+
+BESCHREIBUNG
+        Befiehlt dem Treiber, nach Ende der aktuellen Ausfuehrung eine
+        Garbage Collection zu beginnen. Je nachdem, welcher Memory Allocator
+        verwendet wird, ist die Garbage Collection mehr oder weniger
+        gruendlich.
+
+        Wird der smalloc Memory Allocator verwendet, erzeugt GC einen Output
+        in einem Logfile. Der Standardname fuer das Logfile wird beim
+        Programmstart festgelegt, kann aber zur Laufzeit veraendert werden,
+        wenn das Argument <filename> angegeben ist. Der Log-Output wird in
+        diesem Fall an das bezeichnete Logfile angefuegt.
+
+        Fuer andere Memory Allocators erzeugt garbage_collection() keinen
+        Output. Ein allfaelliges Argument <filename> wird ignoriert.
+
+SIEHE AUCH
+        rusage(E), valid_write(M)
diff --git a/doc/efun/get_dir b/doc/efun/get_dir
new file mode 100644
index 0000000..b14288a
--- /dev/null
+++ b/doc/efun/get_dir
@@ -0,0 +1,113 @@
+SYNOPSIS
+        #include <files.h>
+
+        mixed *get_dir(string str)
+        mixed *get_dir(string str, int mask)
+
+BESCHREIBUNG
+        Benoetigt einen Pfad als erstes Argument und liefert ein Feld
+        (Array) mit Dateinamen bzw. Eigenschaften der gefundenen Dateien im
+        angegebenen Verzeichnis.
+
+        Liefert 0 zurueck, wenn es das Verzeichnis, in dem gesucht werden
+        soll, nicht gibt.
+
+        Der Dateinamen-Teil des Pfades darf "*" und "?" als Platzhalter
+        enthalten: jeder "*" steht fuer eine beliebige Anzahl Zeichen (oder
+        sich selber), "?" fuer ein beliebiges Zeichen. Entsprechend liefert
+        get_dir("/pfad/*") ein alphabetisch sortiertes Feld aller Dateien
+        im Verzeichnis "/pfad" oder ({ "/pfad/*" }), wenn es diese Datei
+        geben sollte.
+
+        Gibt man den Pfad eines Verzeichnisses mit abschliessendem "/" oder
+        "/." an (z. B. get_dir("/pfad/.")), so erhaelt man den Inhalt des
+        Verzeichnisses. Um Informationen ueber das Verzeichnis selber zu
+        erhalten, muss man den Pfad des Verzeichnisses angeben.
+
+        Das optionale zweite Argument ist eine Bitmaske, mit der man
+        angeben kann, welche Informationen man ueber die angegebenen
+        Dateien erhalten moechte.
+
+        GETDIR_EMPTY    (0x00)  get_dir() liefert ein leeres Feld (nicht
+                                wirklich sinnvoll)
+        GETDIR_NAMES    (0x01)  liefert die alphabetisch sortierten
+                                Dateinamen.
+        GETDIR_SIZES    (0x02)  liefert die unsortierten Dateigroessen
+                                (file_size()), Verzeichnisse haben die
+                                Dateigroesse FSIZE_DIR (-2).
+        GETDIR_DATES    (0x04)  liefert die unsortierten Zeiten der jeweils
+                                letzten Aenderung in Sekunden seit dem
+                                01.01.1970.
+        GETDIR_ACCESS   (0x40)  liefert die unsortierten Zeiten des jeweils
+                                letzten Zugriffes in Sekunden seit dem
+                                01.01.1970.
+        GETDIR_MODES    (0x80)  liefert die Filemode-Maske
+
+        GETDIR_ALL      (0xDF)  Liefert all Werte zurueck.
+
+        GETDIR_PATH     (0x10)  Dateinamen werden als volle Pfade geliefert.
+                                (ein ev. fehlendes GETDIR_NAMES wird als
+                                vorhanden angenommen).
+        GETDIR_UNSORTED (0x20)  Das Ergebnis wird nicht sortiert.
+
+        Wichtig: Man muss GETDIR_NAMES|GETDIR_UNSORTED verwenden, wenn man
+        die Eintraege in der selben Reihenfolge wie bei GETDIR_SIZES und
+        GETDIR_DATES haben moechte.
+
+        Die Eintraege in der Bitmaske koennen miteinander kombiniert
+        werden.
+
+BEISPIELE
+        Funktion                         Rueckgabewert
+        -------------------------------------------------------------------
+        get_dir("/obj/.")                Alle Dateien, die im Verzeichnis
+                                         /obj enthalten sind.
+        get_dir("/obj/")                 Wie get_dir("/obj/").
+
+        get_dir("/obj/fackel.c")        ({ "fackel.c" }), sofern
+                                         /obj/fackel.c existiert (als
+                                         Datei oder Verzeichnis), ansonsten
+                                         ({}), sofern /obj ein Verzeichnis
+                                         ist, ansonsten 0.
+
+        get_dir("/obj/*")                ({ "*" }), sofern * existiert.
+                                         Ansonsten und normalerweise ein
+                                         alphabetisch sortiertes Feld mit
+                                         den Namen aller Dateien und
+                                         Verzeichnisse in /obj, sofern /obj
+                                         ein Verzeichnis ist, ansonsten 0.
+
+        get_dir("/obj/fackel.c", GETDIR_SIZES)
+                                         ({ <Groesse von /obj/fackel.c> }),
+                                         sofern /obj/fackel.c existiert.
+        get_dir("/obj/.", GETDIR_NAMES)  Wie get_dir("/obj/.").
+        get_dir("/obj/.", GETDIR_SIZES)  Ein unsortiertes Feld mit den
+                                         Groessen der Dateien in /obj.
+        get_dir("/obj/.", GETDIR_NAMES|GETDIR_SIZES|GETDIR_DATES)
+            oder kuerzer
+        get_dir("/obj/.", GETDIR_ALL)    Ein eindimensionales und nach
+                                         Namen sortiertes Feld, das fuer
+                                         jede Datei in /obj den Namen, die
+                                         Groesse und den Zeitpunkt der
+                                         letzten Aenderung enthaelt, z.B.
+                                         ({
+                                             "axt.c"    ,  927, 994539583,
+                                             "fackel.c", 1283, 998153903,
+                                             }).
+
+        get_dir("/obj/fackel.c", GETDIR_NAMES|GETDIR_PATH)
+                                         ({ "/obj/fackel.c" }), sofern
+                                         vorhanden.
+        get_dir("/obj/fackel.c", GETDIR_PATH)  Kurzform dafuer.
+
+        transpose_array(({ get_dir(str, GETDIR_NAMES|GETDIR_UNSORTED)
+                         , get_dir(str, GETDIR_SIZES)
+                         , get_dir(str, GETDIR_DATES) }));
+        Liefert ein unsortiertes Feld mit Feldern, von denen ein jedes
+        Name, Groesse und Zeit einer Datei enthaelt, z. B.
+        ({
+            ({ "fackel.c", 1283, 998153903 }),
+            ({ "axt.c"    ,  927, 994539583 }),
+            }).
+SIEHE AUCH
+        cat(E), mkdir(E), rmdir(E), file_size(E)
diff --git a/doc/efun/get_error_file b/doc/efun/get_error_file
new file mode 100644
index 0000000..797e523
--- /dev/null
+++ b/doc/efun/get_error_file
@@ -0,0 +1,21 @@
+SYNOPSIS
+        mixed * get_error_file(string name, int set_forget_flag)
+
+DESCRIPTION
+        Return information about the last error which occured for
+        <name> (where <name> is a valid name from the wiz list).
+
+        Result is an array of four elements: the filename of the
+        program where the error occured, the linenumber in the
+        program, the error message (runtime error messages usually
+        start with a '*'), and a numerical flag (the 'forget flag') if
+        the error information has been queried already.
+
+        If there is no error stored for the given <name>, 0 is
+        returned.
+
+        If <set_forget_flag> is non-zero, the 'forget' flag is set
+        for the error message after it has been returned.
+
+SEE ALSO
+        ed(E), valid_read(M)
diff --git a/doc/efun/get_eval_cost b/doc/efun/get_eval_cost
new file mode 100644
index 0000000..50bc012
--- /dev/null
+++ b/doc/efun/get_eval_cost
@@ -0,0 +1,33 @@
+FUNKTION:
+        int get_eval_cost(void)
+
+BESCHREIBUNG:
+        Liefert die noch verbleibenden Eval Kosten, die das momentane
+        Kommando noch verbrauchen darf.
+        Der Maximalwert betraegt zur Zeit 1.500.000 Ticks (Stand: 2007). 
+
+        Sollten die Kosten bei der Ausfuehrung irgendwo groesser werden,
+        wird ein Fehler der Art "too long eval" erzeugt. Diese Funktion
+        dient dazu, solche Fehler genau zu lokalisieren bzw. 
+        herauszufinden, an welchen Stellen im Code wieviel Rechenzeit 
+        verbraucht wird.
+        
+BEISPIELE
+        void foo()
+        {
+          int prev, used, i;
+          
+          prev=get_eval_cost(); // Merken, was bis hierhin verbraucht wurde 
+          for (i=0;i<=1000;i++) // Dann kommt der zu testende Code, zB eine
+          {                     // Schleife
+            ...
+          }
+          used=prev-get_eval_cost(); // Berechnung der Differenz
+          printf("Die Schleife verbrauchte %d Ticks.\n", used);
+        }
+
+SIEHE AUCH:
+        caller_stack_depth(E), rusage(E), command(E), query_limits(E)
+        Konstante: __MAX_EVAL_COST__
+
+4.Aug 2007 Gloinson
diff --git a/doc/efun/get_extra_wizinfo b/doc/efun/get_extra_wizinfo
new file mode 100644
index 0000000..c356fba
--- /dev/null
+++ b/doc/efun/get_extra_wizinfo
@@ -0,0 +1,19 @@
+SYNOPSIS
+        mixed get_extra_wizinfo (object wiz)
+        mixed get_extra_wizinfo (string wiz)
+        mixed get_extra_wizinfo (int    wiz)
+
+DESCRIPTION
+        Returns the 'extra' information that was set for the given
+        wizard <wiz> in the wizlist.
+
+        If <wiz> is an object, the entry of its creator (uid) is used.
+        If <wiz> is a string (a creator aka uid), it names the entry
+        to use.
+        If <wiz> is the number 0, the data is get from the default wizlist
+        entry.
+
+        The function causes a privilege violation.
+
+SEE ALSO
+        wizlist_info(E), set_extra_wizinfo(E)
diff --git a/doc/efun/get_type_info b/doc/efun/get_type_info
new file mode 100644
index 0000000..81b1f8b
--- /dev/null
+++ b/doc/efun/get_type_info
@@ -0,0 +1,57 @@
+SYNOPSIS
+        mixed get_type_info(mixed arg, int flag);
+
+BESCHREIBUNG
+        Liefert Informationen uber den Typ von <arg>, wie von <flag>
+        angegeben.
+
+        Wenn <flag> keine Zahl ist, liefert get_type_info() ein Array, dessen
+        erstes Element ein Integer ist, der den Datentyp bezeichnet, wie in
+        <lpctypes.h> definiert. Der zweite Eintrag kann zusaetzliche
+        Informationen zu <arg> enthalten.
+
+        Ist <flag> 0, wird nur das erste Element (d.h. der Datentyp) geliefert.
+        Ist <flag> 1, wird nur das zweite Element geliefert.
+
+        Wenn <arg> eine Closure enthaelt, so kann get_type_info() das Objekt
+        der Closure liefern, wenn fuer <flag> 2 gesetzt ist. (Fuer 'alien
+        lfun closures' ist das das Objekt, in dem die Closure definiert ist,
+        nicht das Objekt, an das die Closure gebunden ist.)
+
+        Wenn <arg> eine LFun/Context-Closure enthaelt, so kann get_type_info()
+        den Namen des definierenden Programmes liefern, wenn fuer <flag> 3
+        gesetzt ist. Fur andere Closures wird 0 zurueckgegeben.
+
+        Wenn <arg> eine LFun/Context-Closure enthaelt, so kann get_type_info()
+        den Namen der Funktion liefern, wenn fuer <flag> 4
+        gesetzt ist. Fur andere Closures wird 0 zurueckgegeben.
+
+        Fuer jeden anderen Wert fuer <flag> liefert die Funktion -1.
+
+        Die zusaetzlichen Informationen (also der zweite Eintrag des Arrays)
+        beinhalten:
+          - fuer Mappings deren Breite, also die Anzahl Datenwerte pro Key.
+          - fuer Symbole und gequotete Arrays die Anzahl Quotes.
+          - fuer Closures den (internen) Typ der Closure.
+          - fuer gemeinsam verwendete Strings 0, ungleich 0 fuer andere Strings
+          - fuer structs der eindeutige Identifizierungsstring
+          - -1 fuer alle anderen Datentypen
+
+BUGS
+        Diese Funktion unterliegt haeufigen Veraenderungen im Zug der
+        Treiberentwicklung.
+
+AENDERUNGEN
+        Eingefuehrt in 3.2@127
+        Flagwert 2 eingefuehrt in 3.2.1@84
+        Zusatzinformationen zu Strings eingefuehrt in 3.2.7
+        Bis und mit 3.2.7 lieferte get_type_info(closure, 2) keine Objekte
+            von Lamda Closures und gebundenen Lambda Closures.
+        Bis und mit 3.2.7 lieferte get_type_info(closure, 2) keine Objekte von
+            Efun-, Simul-Efun- oder Operator-Closures.
+        LDMud 3.3.276 fuegte die zusaetzliche Information fuer structs hinzu.
+        LDMud 3.3.548 fuegte Flagwert '3' hinzu.
+        LDMud 3.3.708 fuegte Flagwert '4' hinzu.
+
+SIEHE AUCH
+        debug_info(E), typeof(E), to_object(E)
diff --git a/doc/efun/geteuid b/doc/efun/geteuid
new file mode 100644
index 0000000..75cc3d1
--- /dev/null
+++ b/doc/efun/geteuid
@@ -0,0 +1,12 @@
+SYNOPSIS
+        string geteuid(object ob);
+
+BESCHREIBUNG
+        Liefert die effektive User-ID des Objekts <obj> (normalerweise ein
+        Magier oder eine Domain). Objekte, die durch <obj> geclonet werden,
+        erhalten diese User-ID. Die effektive User-ID wird auch fuer
+        Zugriffschecks verwendet. Wenn <obj> nicht angegeben wird, wird
+        standardmaessig this_object() verwendet.
+
+SIEHE AUCH
+        seteuid(E), getuid(E), getuuid(E), export_uid(E)
\ No newline at end of file
diff --git a/doc/efun/getuid b/doc/efun/getuid
new file mode 100644
index 0000000..bf38fe8
--- /dev/null
+++ b/doc/efun/getuid
@@ -0,0 +1,17 @@
+SYNOPSIS
+        string getuid(object ob);
+
+BESCHREIBUNG
+        User-IDs werden im Compat Modus nicht verwendet.
+
+        Die Funktion liefert die UID des Objekts, also den Namen des Magiers
+        oder der Domain oder Gruppe, die fuer das Objekt verantwortlich ist.
+        Der Name entspricht dem Namen, der in der Wizlist verwendet wird.
+        Wird <ob> nicht angegeben, wird standardmaessig this_object()
+        genommen.
+
+AENDERUNGEN
+        Seit 3.2.1@47 ist diese Efun ein Alias fuer creator()
+
+SIEHE AUCH
+        seteuid(E), geteuid(E), export_uid(E), creator(E), getuuid(E)
diff --git a/doc/efun/gmtime b/doc/efun/gmtime
new file mode 100644
index 0000000..ab12eff
--- /dev/null
+++ b/doc/efun/gmtime
@@ -0,0 +1,38 @@
+SYNOPSIS
+        #include <sys/time.h>
+
+        int *gmtime(int clock);
+        int *gmtime(int *uclock);
+
+BESCHREIBUNG
+        Interpretiert <clock> als Anzahl Sekunden seit dem 01. Januar 1970,
+        00:00:00 Uhr und gibt die Zeit in UTC in einer schoenen Struktur
+        aus. Wird <clock> nicht angegeben, wird stattdessen time() verwendet.
+
+        Alternativ kann auch ein Array mit zwei Elementen angegeben werden,
+        wie es von uclock() geliefert wird: das erste Element wird
+        interpretiert wie <clock>, das zweite Element bezeichnet die
+        Mikrosekunden in der aktuellen Sekunde. Dieses zweite Element wird
+        ignoriert.
+
+        Das Resultat von gmtime() ist ein Array, das folgende Werte beinhaltet:
+            int TM_SEC   (0) : Sekunden (0..59)
+            int TM_MIN   (1) : Minuten (0..59)
+            int TM_HOUR  (2) : Stunden (0..23)
+            int TM_MDAY  (3) : Tag im Monat (1..31)
+            int TM_MON   (4) : Monat im Jahr (0..11)
+            int TM_YEAR  (5) : Jahr (z.B.  2001)
+            int TM_WDAY  (6) : Wochentag (Sunday = 0)
+            int TM_YDAY  (7) : Tag im Jahr (0..365)
+            int TM_ISDST (8) : TRUE: Daylight saving time
+
+BEISPIEL
+        printf("Heute ist %s\n", ({ "Sonntag", "Montag", "Dienstag",
+            "Mittwoch",        "Donnerstag", "Freitag", "Samstag"})
+            [gmtime()[TM_WDAY]]);
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+    ctime(E), localtime(E), time(E), utime(E)
diff --git a/doc/efun/hash b/doc/efun/hash
new file mode 100644
index 0000000..e3457c1
--- /dev/null
+++ b/doc/efun/hash
@@ -0,0 +1,36 @@
+SYNOPSIS
+        #include <sys/tls.h>
+
+        string hash(int method, string arg [, int iterations ] )
+        string hash(int method, int *  arg [, int iterations ] )
+
+BESCHREIBUNG
+        Berechne den Hash <method> vom Argument <arg>. Der Hash wird
+        mit <iterations> Wiederholungen berechnet, wird der Wert weggelassen,
+        wird eine Wiederholung verwendet.
+
+        <method> ist eine der TLS_HASH_-Konstanten in tls.h; nicht jede
+        beschriebene Methode ist in einem gegebenen Driver vorhanden:
+
+          TLS_HASH_SHA1      (1)
+          TLS_HASH_SHA224    (2)
+          TLS_HASH_SHA256    (3)
+          TLS_HASH_SHA384    (4)
+          TLS_HASH_SHA512    (5)
+          TLS_HASH_MD5       (6)
+          TLS_HASH_RIPEMD160 (7)
+
+        Diese Funktion ist nur verfuegbar wenn der Driver mit OpenSSL
+        compiliert wurde.
+
+BEISPIELE
+        string s;
+
+        s = hash(TLS_HASH_SHA1, "Hello", 2);
+        s = hash(TLS_HASH_SHA1, ({ 'H', 'e', 'l', 'l', 'o' }) )
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.714
+
+SIEHE AUCH
+        crypt(E), md5(E), md5_crypt(E), sha1(E), hmac(E)
diff --git a/doc/efun/heart_beat_info b/doc/efun/heart_beat_info
new file mode 100644
index 0000000..dee8d52
--- /dev/null
+++ b/doc/efun/heart_beat_info
@@ -0,0 +1,9 @@
+SYNOPSIS
+        object *heart_beat_info()
+
+BESCHREIBUNG
+        Resultat ist ein Array mit allen Objekten, die einen aktiven
+        heart_beat() haben.
+
+SIEHE AUCH
+        set_heart_beat(E), heart_beat(A), call_out_info(E)
diff --git a/doc/efun/hmac b/doc/efun/hmac
new file mode 100644
index 0000000..d41d6d5
--- /dev/null
+++ b/doc/efun/hmac
@@ -0,0 +1,35 @@
+SYNOPSIS
+        #include <sys/tls.h>
+
+        string hmac(int method, string key, string arg )
+        string hmac(int method, string key, int *  arg )
+
+BESCHREIBUNG
+        Berechnet den Hashed Message Authenication Code fuer <arg>
+        nach Methode <method> und fuer das Password <key>.
+
+        <method> ist eine der TLS_HASH_-Konstanten in tls.h; nicht jede
+        beschriebene Methode ist in einem gegebenen Driver vorhanden:
+
+          TLS_HASH_SHA1      (1)
+          TLS_HASH_SHA224    (2)
+          TLS_HASH_SHA256    (3)
+          TLS_HASH_SHA384    (4)
+          TLS_HASH_SHA512    (5)
+          TLS_HASH_MD5       (6)
+          TLS_HASH_RIPEMD160 (7)
+
+        Diese Funktion ist nur verfuegbar wenn der Driver mit OpenSSL
+        compiliert wurde.
+
+BEISPIELE
+        string s;
+
+        s = hmac(TLS_HASH_SHA1, "secret", "Hello");
+        s = hmac(TLS_HASH_SHA1, "secret", ({ 'H', 'e', 'l', 'l', 'o' }) )
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.714
+
+SIEHE AUCH
+        crypt(E), md5(E), md5_crypt(E), sha1(E), hmac(E)
diff --git a/doc/efun/idna_stringprep b/doc/efun/idna_stringprep
new file mode 100644
index 0000000..7001140
--- /dev/null
+++ b/doc/efun/idna_stringprep
@@ -0,0 +1,22 @@
+OPTIONAL
+SYNOPSIS
+        #include <sys/idn.h>
+
+        string idna_stringprep (string str, int profile, int flags = 0)
+
+BESCHREIBUNG
+        Prepariere den UTF-8 String <str> passend zum Profil <profile>
+        (siehe auch libidn stringprep(3)).
+
+        <profile> und <flags> sind definiert in idn.h .
+
+        Sollte ein Fehler auftreten, wird eine Exception geworfen.
+
+        Diese Efun is nur verfuegbar auf Systemen mit libidn
+        installiert - in diesem Fall ist das Makro __IDNA__ definiert.
+
+GESCHICHTE
+        Introduced in LDMud 3.3.713.
+
+SIEHE AUCH
+        convert_charset(E), idna_to_ascii(E), idna_to_unicode(E)
diff --git a/doc/efun/idna_to_ascii b/doc/efun/idna_to_ascii
new file mode 100644
index 0000000..63c66b9
--- /dev/null
+++ b/doc/efun/idna_to_ascii
@@ -0,0 +1,20 @@
+OPTIONAL
+SYNOPSIS
+        #include <sys/idn.h>
+
+        string idna_to_ascii (string name)
+
+BESCHREIBUNG
+        Wandle den String <name> von UTF-8 to IDNA Darstellung (8z
+        punycode).
+
+        Sollte ein Fehler auftreten, wird eine Exception geworfen.
+
+        Diese Efun is nur verfuegbar auf Systemen mit libidn
+        installiert - in diesem Fall ist das Makro __IDNA__ definiert.
+
+GESCHICHTE
+        Introduced in LDMud 3.3.713.
+
+SIEHE AUCH
+        convert_charset(E), idna_to_unicode(E), idna_stringprep(E)
diff --git a/doc/efun/idna_to_unicode b/doc/efun/idna_to_unicode
new file mode 100644
index 0000000..183dce8
--- /dev/null
+++ b/doc/efun/idna_to_unicode
@@ -0,0 +1,20 @@
+OPTIONAL
+SYNOPSIS
+        #include <sys/idn.h>
+
+        string idna_to_unicode (string name)
+
+BESCHREIBUNG
+        Wandle den String <name> von IDNA Darstellung (8z punycode)
+        nach UTF-8.
+
+        Sollte ein Fehler auftreten, wird eine Exception geworfen.
+
+        Diese Efun is nur verfuegbar auf Systemen mit libidn
+        installiert - in diesem Fall ist das Makro __IDNA__ definiert.
+
+GESCHICHTE
+        Introduced in LDMud 3.3.713.
+
+SIEHE AUCH
+        convert_charset(E), idna_to_ascii(E), idna_stringprep(E)
diff --git a/doc/efun/implode b/doc/efun/implode
new file mode 100644
index 0000000..85a723b
--- /dev/null
+++ b/doc/efun/implode
@@ -0,0 +1,25 @@
+SYNOPSIS
+        string implode(mixed *arr, string del)
+
+BESCHREIBUNG
+	Setzt alle Zeichenketten (Strings) aus dem Feld (Array) arr zu
+        einer Zeichenkette zusammen und fuegt dabei die Zeichenkette del
+        zwischen je zwei Elementen ein. Elemente aus dem Feld arr, welche
+        keine Zeichenketten sind, werden ignoriert.
+
+BEISPIELE
+	Funktion                                        Rueckgabewert
+        -------------------------------------------------------------------
+	implode(({ "foo", "bar", "" }), "*")            "foo*bar*"
+	implode(({ "a", 2, this_object(), "c" }), "b")  "abc"
+
+	Kann zusammen mit explode() als Funktion zum Ersetzen von
+        Zeichenketten verwendet werden:
+        implode(explode("a short text", " "), "_")      "a_short_text"
+
+	Heutzutage kann man stattdessen auch
+	regreplace("a short text", " ", "_", 1)
+	verwenden.
+
+SIEHE AUCH
+        explode(E)
diff --git a/doc/efun/include_list b/doc/efun/include_list
new file mode 100644
index 0000000..cc44fa9
--- /dev/null
+++ b/doc/efun/include_list
@@ -0,0 +1,80 @@
+SYNOPSIS
+        #include <sys/include_list.h>
+
+        string *include_list();
+        string *include_list(object ob);
+        string *include_list(object ob, int flags);
+
+BESCHREIBUNG
+        Diese Funktion liefert Informationen ueber alle Dateien, die bei der
+        Kompilierung von <ob> in dieses Objekt eingebunden wurden, inklusive
+        den Programmnamen von <ob>. Wird <ob> nicht angegeben, wird
+        standardmaessig das aktuelle Objekt verwendet.
+
+        Im resultierenden Array besteht die Information zu einem Includefile
+        aus drei Elementen:
+          - string [i+0]: der Name des Includefiles, wie er im Programm
+                          auftaucht, inklusive den Trennzeichen wie " " oder
+                          < >.
+          - string [i+1]: der absolute Dateipfad des Includefiles.
+          - int    [i+2]: die Tiefe der Inklusion (gewoehnlich 1, fuer
+                          verschachtelte Includes auch groesser als 1)
+
+        Der erste Eintrag im Resultat ist der Name des Programmes selbst in
+        [i+0], die anderen beiden Elemente [i+1] und [i+2] sind 0.
+
+        <flag> bezeichnet die Struktur des Ergebnisses:
+          - <flag> = INCLIST_FLAT (0, Standard):
+            Das Resultat ist ein flaches Array. Der erste Eintrag bezeichnet
+            <ob> selbst, die restlichen Eintraege bezeichnen alle Includefiles
+            in der Reihenfolge, in der sie auftreten.
+          - <flag> = INCLIST_TREE (1):
+            Das Resultat ist ein Array, dessen erster Eintrag das Objekt <ob>
+            selbst bezeichnet. Alle folgenden Eintraege bezeichnen die
+            Includefiles von <ob>. Wenn ein Includefile von <ob> selbst keine
+            Includefiles hat, wird seine Information direkt im Array
+            gespeichert. Fuer verschachtelte Includefiles wird ein Untervektor
+            erzeugt und dann in diesem Untervektor abgespeichert (wiederum
+            in [i+0], [i+1] und [i+2] sind 0). Diese Untervektoren haben
+            die gleiche Struktur wie das Resultatarray.
+
+        Wenn ein Objekt, inklusive <ob>, einem replace_programm() unterworfen
+        war, spiegeln die gelieferten Dateinamen das effektiv aktive Programm
+        wider.
+
+        Die Includepfade, die geliefert werden, beginnen immer mit '/'
+        (absolute Pfade), auch wenn der Treiber im COMPAT Modus laeuft.
+        Trotzdem beginnt der tatsaechliche Dateiname nicht mit einem '/',
+        wenn der Treiber im COMPAT Modus laeuft.
+
+BEISPIEL
+        Dieser Code erzeugt (mit /sys als Includeverzeichnis des Systems):
+
+            a.c:  #include "b.h"
+                  #include <c.h>
+            b.h:  #include "d.h"
+            c.h:  #define BAR
+            d.h:  #define FOO
+
+        Die Efun liefert drei Resultate:
+
+            include_list(a, INCLIST_FLAT)
+            -> ({ "a.c", 0, 0
+                , "\"b.h\"", "/.../b.h", 1
+                , "\"d.h\"", "/.../d.h", 2
+                , "<c.h>",   "/sys/c.h", 1
+               })
+
+             include_list(a, INCLIST_TREE)
+             -> ({ "a.c", 0, 0
+                 , ({ "\"b.h\"", "/.../b.h", 1
+                    , "\"d.h\"", "/.../d.h", 2
+                   }), 0, 0
+                 , "<c.h>",   "/sys/c.h", 1
+                 })
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9, 3.3.128
+
+SIEHE AUCH
+        debug_info(E), inherit_list(E)
diff --git a/doc/efun/inherit_list b/doc/efun/inherit_list
new file mode 100644
index 0000000..97c738e
--- /dev/null
+++ b/doc/efun/inherit_list
@@ -0,0 +1,60 @@
+SYNOPSIS
+        #include <sys/inherit_list.h>
+
+        string *inherit_list();
+        string *inherit_list(object ob);
+        string *inherit_list(object ob, int flags);
+
+BESCHREIBUNG
+        Liefert die Namen von allen Dateien, die von <ob> geerbt werden,
+        inklusive <ob>s eigener Dateiname. Wird <ob> nicht angegeben, wird
+        standarndmaessig das aktuelle Objekt verwendet.
+
+        Der Wert von <flags> bestimmt die Struktur des Rueckgabewertes:
+          - <flag> = INHLIST_FLAT (0, default):
+            inherit_list() liefert ein Array von Dateinamen, beginnend mit dem
+            Namen von <ob> selbst, gefolgt von den Namen aller geerbten
+            Objekten.
+          - <flag> = INHLIST_TREE (1):
+            inherit_list() liefert ein Array von Dateinamen, beginnend mit dem
+            Namen von <ob> selbst. Wenn ein geerbte File selbst keine Files
+            erbt, wird sein Name direkt in das Ergebnis eingetragen. Wenn ein
+            geerbtes File selbst Files erbt, wird ein Untervektor erzeugt, in
+            dem die Inherits eingetragen werden. Der Untervektor hat die
+            gleiche Struktur wie der Haupvektor.
+          - <flag> = INHLIST_TAG_VIRTUAL (2):
+            Alle Namen im Ergebnisvektor haben ein leeres Tag "  " (zwei
+            Leerschlaege) fuer normale Inherits und "v " fuer virtuelle
+            Inherits als Praefix vorangestellt.
+
+        Alle Flags koennen mit einem binaeren Oder | verbunden werden, wobei
+        INHLIST_FLAT und INHLIST_TREE sich gegenseitig ausschliessen.
+
+        Wenn ein Objekt, inklusive <ob>, einem replace_programm() unterworfen
+        war, spiegeln die gelieferten Dateinamen das effektiv aktive Programm
+        wider.
+
+        Die Inheritpfade, die geliefert werden, beginnen immer mit '/'
+        (absolute Pfade), auch wenn der Treiber im COMPAT Modus laeuft.
+
+BEISPIEL
+        Gegeben folgende Vererbungsstruktur:
+
+            / c - d
+          a
+            \ b
+
+        Wobei d virtuell geerbt wird, ergeben sich folgende Resultate:
+
+            inherit_list(a) -> ({ "a", "c", "b", "d" })
+            inherit_list(c) -> ({ "c", "d" })
+            inherit_list(a, 1) -> ({ "a", ({ "c", "d" }), "b" })
+            inherit_list(a, 3) -> ({ "  a", ({ " c", "v d" }), "  b" })
+
+AENDERUNGEN
+        Vor 3.2.8, begannen die gelieferten Namen niemals mit einem '/'.
+        LDMud 3.2.9 fuehrte die Baumstruktur (_TREE) und Tags fuer virtuelle
+            Inherits ("v ") ein.
+
+SIEHE AUCH
+        debug_info(E), include_list(E)
diff --git a/doc/efun/input_to b/doc/efun/input_to
new file mode 100644
index 0000000..11cbd97
--- /dev/null
+++ b/doc/efun/input_to
@@ -0,0 +1,146 @@
+SYNOPSIS
+        #include <sys/input_to.h>
+
+        void input_to(string|closure fun);
+        void input_to(string|closure fun, int flag, ...);
+        void input_to(string|closure fun, int flag, string|closure prompt, ...);
+
+BESCHREIBUNG
+        Die naechste Zeile, die der Spieler eintippt, wird als Argument an die
+        Funktion <fun> uebergeben. Ausnahme: wenn die naechste Zeile mit einem
+        '!' beginnt, wird sie als Kommando ausgewertet bzw. an das letzte
+        input_to() uebergeben, das das INPUT_IGNORE_BANG Flag gesetzt hat.
+        Die Funktion <fun> kann "static" deklariert sein, nicht aber "private"
+        (sonst wird sie nicht gefunden).
+
+        Der Aufruf von <fun> erfolgt nicht sofort, sondern erst, wenn der
+        Spieler die Entertaste drueckt.
+
+        Wenn input_to() mehr als einmal pro Funktion aufgerufen wird,
+        wird normalerweise nur das erste input_to() beruecksichtigt.
+        Diese Verhalten kann durch die Angabe von INPUT_APPEND
+        modifiziert werden: in diesem Fall wird das input_to() an die
+        Liste der bereits anhaengigen input_tos angehaengt (siehe
+        BEISPIELE).
+
+        Wird andererseits waehrend einem laufenden input_to() (mittels "!" am
+        Zeilenanfang) eine neue Funktion aufgerufen, die wiederum ein
+        input_to() enthaelt, wird das urspruengliche input_to() so lange
+        unterbrochen, bis das neue input_to() abgearbeitet wurde,
+        anschliessend wird es wieder aktiv.
+
+        Das optionale <flag> kann ein binaeres Oder (|) der folgenden
+        Werte sein:
+
+        INPUT_NOECHO (1):
+            Die vom Spieler eingegebene Zeile erzeugt kein Echo und wird auch
+            nicht erkannt, wenn der Spieler beobachtet wird.
+
+            Dieser Modus kann nur geaendert werden, wenn telnet enabled ist.
+
+        INPUT_CHARMODE (2):
+            Die Verbindung zum User wechselt von Zeilen- auf Zeichenmodus. So
+            wird nur ein einzelnes Zeichen (!) vom Spieler empfangen.
+
+            Ist telnet disabled, wird lediglich die Interpretation der
+            einkommenden Daten durch den Driver umgeschaltet - das
+            Clientprogramm des Spieler verbleibt im gerade aktiven Modus.
+
+            Nachdem die Funktion <fun> ausgefuehrt wurde, wechselt die
+            Verbindung zurueck in Zeilenmodus, ausser ein nachfolgendes
+            input_to( , 2) wurde gestartet.
+
+            Zeilenumbrueche werden je nach Client unterschiedlich empfangen,
+            entweder als "", als "\r" gefolgt von "" oder als "\r" (letzteres
+            kommt vor allem bei Windows Clients vor).
+
+            Das Frontend des Spielers kann dauernd im Zeilenmodus bleiben.
+            Auch wenn input_to() nur ein einzelnes Zeichen fordert, muss der
+            Spieler unter Umstaenden das Zeichen und einen Zeilenumbruch
+            druecken (und senden). Normalerweise erhaelt <fun> dann den
+            gesamten Input auf einmal.
+
+            Will man laenger im Zeichenmodus bleiben, kann der Overhead
+            reduziert werden, indem set_combine_charset() verwendet wird. So
+            koennen Zeichensequenzen als ein String anstelle von
+            Zeichen-fuer-Zeichen empfangen werden. In einem screenorientierten
+            Editor gilt dies fuer die meisten druckbaren Zeichen.
+
+        INPUT_PROMPT (4):
+            Das Argument nach dem <flag> wird als Prompt fuer die Eingabe
+            verwendet. Wenn dieses Argument nicht angegeben (und damit kein
+            Propmt definiert) ist, wird kein Prompt ausgegeben.
+
+        INPUT_NO_TELNET (8):
+            Modifiziert das INPUT_CHARMODE Argument: der Driver aendert
+            seine Behandlung von eingehenden Daten entsprechend dem _CHARMODE
+            Argument, sendet aber keine Telnetkommandos zur Anpassung
+            des Verhaltens des Clientprogrammes.
+
+        INPUT_APPEND (16):
+            Das input_to() wird an die Liste der bereits anhaengigen
+            input_tos angehaengt.
+
+        INPUT_IGNORE_BANG (128):
+            Eingaben, die mit ! beginnen, werden NICHT als Kommandi geparset,
+            sondern auch als Argument an die Funkion <fun> uebergeben. Die
+            Verwendung dieses Flags ist eingeschraenkt.
+
+        Alle nachfolgenden Argumente werden als zweites bzw. drittes usw.
+        Argument an <fun> uebergeben.
+
+BEISPIEL
+        void func()
+        {
+            ...
+            input_to("enter_name", INPUT_PROMPT, "Wie lautet dein Name?:");
+            /* Frueher erledigte man dies mit:
+             *   write("Wie lautet dein Name?:");
+             *   input_to("enter_name");
+             */
+             ...
+         }
+
+         enter_name(string str)
+         {
+            write("Heisst du wirklich '"+str+"'?? *kicher*\n");
+            ...
+        }
+
+        Bei der input_to() Anweisung fuehrt der Driver die Funktion
+        func() aus, erwartet aber gleichzeitig Input vom Spieler. Wenn
+        dieser etwas eingegeben UND DIE ENTERTASTE GEDRUECKT HAT, arbeitet
+        der Driver die Funktion enter_name() mit dem eingegebenen String
+        als Argument ab.
+
+
+        void func() {
+          ..
+          input_to("enter_firstname");
+          input_to("enter_lastname, INPUT_APPEND);
+          ...
+        }
+
+        Diese Sequenze erzeugt zwei input_tos: Eingaben gehen zuerst
+        an enter_firstname(); und wenn diese Funktion fertig ist
+        (einschliesslich etwaiger eigener non-INPUT_APPEND input_tos), geht
+        die naechste Eingabe an enter_lastname().
+
+AENDERUNGEN
+        Die Bedeutung von <flag> wurde in 3.2.1@93 erweitert.
+        Die Limitierung fuer das "stapeln" von input_to()s aus !-Kommandi
+            wurde in LDMud 3.2.8 implementiert.
+        Seit LDMud 3.2.8 kann <fun> in Form einer Closure angegeben werden.
+        LDMud 3.2.9 fuehrte das Flag INPUT_PROMPT samt zugehoerigem Argument
+            ein.
+        LDMud 3.2.11/3.3.593 fuehrte das INPUT_NO_TELNET Flag ein.
+        LDMud 3.2.11/3.3.637 fuehrte das INPUT_APPEND Flag ein.
+
+BUGS
+        Im Zeichenmodus sollten Zeilenumbrueche eigentlich als "\n" zurueck
+        gegeben werden. Dies allerdings kann existierenden Code zerstoeren.
+
+SIEHE AUCH
+        call_other(E), sscanf(E), privilege_violation(M),
+        set_combine_charset(E), query_input_pending(E), find_input_to(E),
+        input_to_info(E), remove_input_to(E), enable_telnet(E)
diff --git a/doc/efun/input_to_info b/doc/efun/input_to_info
new file mode 100644
index 0000000..8dac3d3
--- /dev/null
+++ b/doc/efun/input_to_info
@@ -0,0 +1,21 @@
+SYNOPSIS
+        *mixed input_to_info(object player);
+
+BESCHREIBUNG
+        Liefert ein Array aller fuer <player> haengigen input_to()s. Der
+        erste Eintrag im Array ist der aelteste haengige input_to()
+        (derjenige, welcher als erstes gestartet wurde), der letzte
+        Eintrag ist der neuste input_to().
+
+        Jeder Eintrag im Array ist wiederum ein Array von 2 oder mehr
+        Eintraegen, das folgende Elemente enthaelt:
+            0:   Das Objekt (nur, wenn die Funktion ein string ist)
+            1:   Die Funktion (String oder Closure)
+            2ff: Die Argumente
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        input_to(E), find_input_to(E), remove_input_to(E),
+        query_input_pending(E)
diff --git a/doc/efun/insert_alist b/doc/efun/insert_alist
new file mode 100644
index 0000000..01aca4e
--- /dev/null
+++ b/doc/efun/insert_alist
@@ -0,0 +1,28 @@
+OPTIONAL, VERALTET
+SYNOPSIS
+        mixed *insert_alist(mixed key, mixed data, ... , mixed *alist);
+        int    insert_alist(mixed key, mixed *keys);
+
+BESCHREIBUNG
+     1. Form: Einfuegen in eine Alist.
+        Der <key> und alle foglenden <data> Argumente werden in die Alist
+        eingefuegt. Wenn bereits ein Eintrag fuer <key> existiert, werden
+        nur die <data> Eintraege ersetzt. Natuerlich muss die Anzahl <data>
+        Argumente der Anzahl der Datenarrays in der Alist entsprechen.
+        Das Resultat dieser Operation ist die neue Alist.
+
+     2. Form: Einfuegen eines Keys
+        Der <key> wird in ein (geordnetes) Array von <keys> eingeordnet,
+        sodass nachfolgendes assoc()s schnell suchen koennen. Das Resultat
+        ist der Index, unter dem <key> eingefuegt oder bereits gefunden
+        wurde.
+
+ANMERKUNG
+        Wird mit String-Keys gearbeitet, kann der Index nach dem naechsten
+        Aufruf von insert_alist() nicht mehr gueltig sein.
+
+        Komplexitaet: O(lg(n) + a*n) fuer n gleich der Anzahl der Keys und
+        eine sehr kleine Konstante s (fuer Blockverschiebungen).
+
+SIEHE AUCH
+        alists(LPC), assoc(E), order_alist(E)
diff --git a/doc/efun/interactive b/doc/efun/interactive
new file mode 100644
index 0000000..c326f8a
--- /dev/null
+++ b/doc/efun/interactive
@@ -0,0 +1,10 @@
+SYNOPSIS
+        int interactive(object obj);
+
+BESCHREIBUNG
+        Liefert 1 zurueck, wenn <obj> ein interaktiver User (ein Spieler)
+        ist. Wird <obj> weggelassen, dann wird this_object() verwendet.
+
+SIEHE AUCH
+        query_once_interactive(E), query_ip_number(E), query_ip_name(E),
+        query_idle(E)
diff --git a/doc/efun/interactive_info b/doc/efun/interactive_info
new file mode 100644
index 0000000..f7c2877
--- /dev/null
+++ b/doc/efun/interactive_info
@@ -0,0 +1,106 @@
+SYNOPSIS
+        #include <interactive_info.h>
+
+        mixed interactive_info(object ob, int what)
+
+DESCRIPTION
+        Returns some internal information about the interactive user <ob>.
+        The argument <what> determines which information is returned.
+
+        It can be either a configuration option as given to
+        configure_interactive() or one of the following options:
+
+
+
+        Connection Information:
+
+        <what> == II_IP_NAME:
+          The hostname of <ob>. The hostname will asynchronously
+          looked up by the ERQ daemon and might therefore not be
+          available at the time of the first connection.
+          If no name is available the address will be returned.
+
+        <what> == II_IP_NUMBER:
+          The IP address of <ob> given as a string.
+
+        <what> == II_IP_PORT:
+          The client port number of <ob>.
+
+        <what> == II_IP_ADDRESS:
+          The full socket address structure given as an array of bytes.
+
+          For IPv4 (sockaddr_in):
+              array[0.. 1]: sin_family
+              array[2.. 3]: sin_port
+              array[4.. 7]: sin_addr
+              array[8..15]: undefined.
+
+          For IPv6 (sockaddr_in6):
+              array[ 0.. 1]: sin6_family
+              array[ 2.. 3]: sin6_port
+              array[ 4.. 7]: sin6_flowinfo
+              array[ 8..23]: sin6_addr
+              array[24..27]: sin6_scope_id
+
+        <what> == II_MUD_PORT:
+          The server port number that <ob> connected to.
+
+
+
+        Telnet Related Information:
+
+        <what> == II_MCCP_STATS:
+          Statistics about the current compression of <ob> given
+          as an array ({ uncompressed bytes, compressed bytes }).
+
+          If the connection is not compressed, 0 is returned.
+
+          Available only if the driver is compiled with MCCP enabled;
+          __MCCP__ is defined in that case.
+
+
+
+        Input Handling:
+
+        <what> == II_INPUT_PENDING:
+          If <ob> has an input_to() pending, the object that has called
+          the input_to() is returned, else 0.
+
+        <what> == II_EDITING:
+          If <ob> is currently editing with ed() and ed() was called with
+          an exit function, then the object that has called ed()
+          will be returned, 0 otherwise.
+
+        <what> == II_IDLE:
+          The number of seconds that the interactive object <ob> has been
+          idle.
+
+
+
+        Output Handling:
+
+        <what> == II_SNOOP_NEXT:
+          Returns the user who is currently snooping <ob>.
+          The calling object must be privileged by the master object
+          via valid_query_snoop().
+
+        <what> == II_SNOOP_PREV:
+          Returns the victim who is currently snooped by <ob>.
+          The calling object must be privileged by the master object
+          via valid_query_snoop().
+
+        <what> == II_SNOOP_ALL:
+          Returns all objects who are currently snooping <ob>.
+          Only one object can snoop <ob> directly, but that user might
+          be snooped, too, and so building a chain that is returned
+          as an array.
+
+          The calling object must be privileged by the master object
+          via valid_query_snoop().
+
+
+HISTORY
+        Introduced in LDMud 3.5.0.
+
+SEE ALSO
+        configure_interactive(E), object_info(E), driver_info(E)
diff --git a/doc/efun/intp b/doc/efun/intp
new file mode 100644
index 0000000..6a6a0f2
--- /dev/null
+++ b/doc/efun/intp
@@ -0,0 +1,10 @@
+SYNOPSIS
+        int intp(mixed arg)
+
+BESCHREIBUNG
+        Liefert 1, wenn das Argument eine Ganzzahl (Integer) ist, ansonsten
+        0.
+
+SIEHE AUCH
+        closurep(E), floatp(E), mappingp(E), objectp(E), pointerp(E),
+        referencep(E), stringp(E), symbolp(E), clonep(E)
diff --git a/doc/efun/invert_bits b/doc/efun/invert_bits
new file mode 100644
index 0000000..27bbe6d
--- /dev/null
+++ b/doc/efun/invert_bits
@@ -0,0 +1,17 @@
+SYNOPSIS
+        string invert_bits(string str);
+
+BESCHREIBUNG
+        Invertiert den Status aller Bits im Bitstring <str> und liefert den
+        neuen String zurueck. Dabei bleibt die Laenge von <str>, also die
+        gesamte Anzahl Bits, die gleiche.
+
+BEISPIEL
+        string s;
+        s = set_bit("", 3); s = set_bit(s, 4); s = set_bit(s, 15);
+        --> s ist nun  "8 ("
+        invert_bits(s) --> liefert "G_W"
+
+SIEHE AUCH
+        set_bit(E), clear_bit(E), test_bit(E), last_bit(E), and_bits(E),
+        or_bits(E), xor_bits(E), count_bits(E), copy_bits(E)
diff --git a/doc/efun/json_parse b/doc/efun/json_parse
new file mode 100644
index 0000000..a9f4c31
--- /dev/null
+++ b/doc/efun/json_parse
@@ -0,0 +1,45 @@
+OPTIONAL
+EXPERIMENTAL
+SYNOPSIS
+
+        mixed json_parse(string jsonstring)
+
+DESCRIPTION
+        This efun parses the JSON object encoded as string in <jsonstr> into a
+        suitable LPC type.
+        
+        Handles the following JSON types:
+        <null>        -> int (0)
+        <boolean>     -> int (0 or 1)
+        <int | int64> -> int
+        <double>      -> float
+        <string>      -> string
+        <object>      -> mapping
+        <array>       -> arrays
+        All other JSON types cause a runtime error.
+
+        The JSON object can nest other JSON objects.
+        
+        The function is available only if the driver is compiled with Iksemel
+        support. In that case, __JSON__ is defined. 
+ 
+LIMITATIONS
+        64 bit wide integers can only be parsed losslessly on hosts with
+        a 64 bit wide LPC int and json-c library newer than 0.90.
+
+BUGS
+        __FLOAT_MIN__ is not serialized/parsed losslessly.
+
+EXAMPLES
+        json_parse("42")              -> 42
+        json_parse("42.0")            -> 42.0
+        json_parse("\"hello world\\n\"")   -> "hello world\n"
+        json_parse("[ 1, 2, 3, 4, 5, 6 ]") -> ({1,2,3,4,5,6})
+        json_parse("{ \"test 2\": 42.000000, \"test 1\": 42 }")
+                                      -> ([ "test 1": 42, "test 2": 42.0 ])
+        
+HISTORY
+        Added in LDMud 3.5.0
+
+SEE ALSO
+        json_serialize(E)
diff --git a/doc/efun/json_serialize b/doc/efun/json_serialize
new file mode 100644
index 0000000..fd68deb
--- /dev/null
+++ b/doc/efun/json_serialize
@@ -0,0 +1,45 @@
+OPTIONAL
+EXPERIMENTAL
+SYNOPSIS
+
+        string json_serialize(mixed <data>)
+
+DESCRIPTION
+        This efun creates a JSON object from the given LPC variable and
+        returns the object encoded as a LPC string. For container types like 
+        arrays, mappings and structs, this will be done recursively.
+        
+        Only the following LPC types are serialized. All other LPC types cause
+        a  runtime error.
+        <int>        -> JSON int
+        <float>      -> JSON double
+        <string>     -> JSON string
+        <mapping>    -> JSON objects
+        <array>      -> JSON arrays
+        <struct>     -> JSON objects
+        
+        The function is available only if the driver is compiled with Iksemel
+        support. In that case, __JSON__ is defined. 
+
+LIMITATIONS 
+        Only mappings with a width of 1 value per key and only string keys
+        can be serialized.
+        64 bit wide integers can only be serialized losslessly on hosts with
+        a 64 bit wide LPC int and json-c library newer than 0.90.
+
+BUGS
+        __FLOAT_MIN__ is not serialized/parsed losslessly.
+
+EXAMPLES
+        json_serialize(42)              -> "42"
+        json_serialize(42.0)            -> "42.0"
+        json_serialize("hello world\n") -> "\"hello world\\n\""
+        json_serialize(({1,2,3,4,5,6})) -> "[ 1, 2, 3, 4, 5, 6 ]"
+        json_serialize(([ "test 1": 42, "test 2": 42.0 ]))
+                                -> "{ \"test 2\": 42.000000, \"test 1\": 42 }"
+        
+HISTORY
+        Added in LDMud 3.5.0
+
+SEE ALSO
+        json_parse(E)
diff --git a/doc/efun/lambda b/doc/efun/lambda
new file mode 100644
index 0000000..b156798
--- /dev/null
+++ b/doc/efun/lambda
@@ -0,0 +1,28 @@
+SYNOPSIS
+        closure lambda(mixed *arr, mixed);
+
+BESCHREIBUNG
+        Erzeugt eine Lambda Closure, entsprechend den Lamda Closures in LISP.
+        Die Closure ist an das Objekt gebunden, das sie erzeugt hat, und kann
+        deshalb Verweise auf globale Variablen enthalten.
+
+        Das erste Argument ist ein Array, das die Argumente (Symbole)
+        beschreibt, die der Closure bei ihrer Auswertung durch funcall()
+        oder apply() uebergeben werden.
+
+        Von der Verwendung wird aus Lesbarkeits- und Wartungsgruenden dringend
+        abgeraten.
+
+BEISPIEL
+        // Lambdas werden gern eingesetzt, um komplexere Filter zu schreiben
+        // Allerdings kann jede Lambda dabei auch durch eine Inline-Closure
+        // oder eine LFun-Closure ersetzt werden.
+        filter(users(), 
+          lambda(({'x}),
+                 ({#'==,
+                   ({#'call_other,'x,"QueryProp",P_SECOND}),"gloinson"
+                })));
+
+SIEHE AUCH
+        Verwandt: unbound_lambda(E), apply(E), funcall(E), bind_lambda(E)
+        Generell: closures-abstract(LPC), closures(LPC)
diff --git a/doc/efun/last_bit b/doc/efun/last_bit
new file mode 100644
index 0000000..d0d2471
--- /dev/null
+++ b/doc/efun/last_bit
@@ -0,0 +1,19 @@
+SYNOPSIS
+        int last_bit(string str);
+
+BESCHREIBUNG
+        Liefert die Nummer des letzten gesetzten Bits im Bitstring <str>.
+
+        Jedes Zeichen enthaelt 6 Bits. Also kann in jedem Zeichen ein Wert von
+        0 bis 63 gespeichert werden (2^6=64). Das erste Zeichen ist der
+        Leerschlag " " mit dem Wert 0. Das erste Zeichen im String ist jenes
+        mit den niedrigsten Bits (0-5).
+
+BEISPIEL
+        string s;
+        s = set_bit("", 4); s = set_bit(s, 2);
+        last_bit(s) --> liefert 4
+
+SIEHE AUCH
+        set_bit(E), clear_bit(E), next_bit(E), test_bit(E), count_bits(E),
+        and_bits(E), or_bits(E), xor_bits(E), invert_bits(E), copy_bits(E)
diff --git a/doc/efun/last_instructions b/doc/efun/last_instructions
new file mode 100644
index 0000000..ca447d9
--- /dev/null
+++ b/doc/efun/last_instructions
@@ -0,0 +1,28 @@
+GESCHUETZT
+SYNOPSIS
+        string *last_instructions(int lenght, int verbose);
+
+BESCHREIBUNG
+        Liefert ein Array mit der "Laenge" der zuletzt ausgefuehrten
+        Anweisungen. Wenn <verbose> ungleich 0 ist (standardmaessig so),
+        werden auch Infos zur Zeilennummer angezeigt. Jeder String hat
+        folgende Form:
+
+            Opcode-Adresse: Opcode Operand Mnemonic (Stapeltiefe) Zeilennummer
+
+        Die Information zur Stapeltiefe besteht aus zwei Zahlen <rel>:<abs>,
+        wobei <rel> der relative Stapelverbrauch der Funktion ist, <abs> der
+        absolute Stapelverbrauch.
+
+        Die Information zur Zeilennummer wird angefuegt, wenn das Flag gesetzt
+        ist und eine neue Zeile im Quellcode erreicht wird. Ebenso erzeugen
+        Aufrufe zwischen Objekten einen Eintrag im Resultatarray (allerdings
+        nur, wenn das verbose-Flag gesetzt ist). Dieser Eintrag hat die Form:
+
+            Objektname Programmname Zeilennummer.
+
+        Es gibt ein vorkonfiguriertes oberes Limit, wie viele Instruktionen
+        zurueckverfolgt werden koennen.
+
+SIEHE AUCH
+        debug_message(E)
diff --git a/doc/efun/limited b/doc/efun/limited
new file mode 100644
index 0000000..c967812
--- /dev/null
+++ b/doc/efun/limited
@@ -0,0 +1,64 @@
+VORLAEUFIG, GESCHUETZT
+SYNOPSIS
+        #include <sys/rtlimits.h>
+
+        mixed limited(closure fun);
+        mixed limited(closure fun, int tag, int value, ...);
+        mixed limited(closure fun, int *limits [, mixed *args]);
+
+BESCHREIBUNG
+        limited() ruft die Funktion <fun> mit den bezeichneten Argumenten
+        <args> auf und fuehrt sie mit den gegebenen Laufzeitlimiten aus.
+
+        Beim Ende der Funktion <fun> werden die momentan aktiven
+        Laufzeitlimiten wiederhergestellt. limited() liefert den
+        Rueckgabewert der Closure <fun> zurueck.
+
+        Die Laufzeitlimiten koennen in zwei Formen angegeben werden: als
+        Array (wie es von query_limits() geliefert wird) oder als Liste von
+        Werten mit Tags. Wird limited() ohne Angabe von Limits aufgerufen,
+        gelten die Laufzeitlimiten als 'unlimitiert'.
+
+        Die Limiteneinstellung kennt drei spezielle Werte aus <rtlimits.h>:
+            LIMIT_UNLIMITED:    es gibt kein Limit
+            LIMIT_KEEP:         das zuletzt gesetzte Limit wird beibehalten
+            LIMIT_DEFAULT:      die 'globalen' Limiten werden verwendet
+
+        Fuer LIMIT_COST, die Spezialwerte haben diese Bedeutung:
+            LIMIT_UNLIMITED: die Ausfuehrung kosten lediglich einen Tick
+            LIMIT_KEEP:      LIMIT_COST wird auf 0 gesetzt
+            LIMIT_DEFAULT:   LIMIT_COST wird auf -100 gesetzt
+
+        limited() erzeugt eine Schutzverletzung ("limited", current_object,
+        fun, limits-array).
+
+BEMERKUNGEN:
+        Diese Funktion kann bei uns mudlibweit genutzt werden. Allerdings wird
+        nur die _Reduktion_ von LIMIT_EVAL zugelassen, alle anderen Limits
+        duerfen _nicht_ veraendert werden. Hierbei ist zu beachten, dass das
+        Limit fuer LIMIT_EVAL um min. 1000 Ticks unter den noch verfuegbaren
+        Ticks liegen muss (get_eval_cost()).
+        Fuer LIMIT_COST sind nur 0 und -100 zugelassen.
+
+BEISPIELE
+        limited(#'function)
+        --> fuehrt die Funktion ohne Limiten aus.
+
+        limited(#'function, ({ 200000 }), "foo")
+        --> fuehrt die Funktion mit einem Eval-Kosten Limit von 200000 Ticks
+            aus. Die Funktion wird als 'function("foo")' aufgerufen.
+
+        limited(lambda(0, ({#'function, "foo"})), LIMIT_EVAL, 200000)
+        --> fuehrt die Funktion mit einem Eval-Kosten Limit von 200000 Ticks
+            aus. Die Funktion wird als 'function("foo")' aufgerufen.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7.
+        LDMud 3.3.563 fuehrte LIMIT_COST ein.
+
+SIEHE AUCH
+        query_limits(E), set_limits(E)
+        get_eval_cost(E)
+
+16.05.2007, Zesstra
+
diff --git a/doc/efun/living b/doc/efun/living
new file mode 100644
index 0000000..6f0a886
--- /dev/null
+++ b/doc/efun/living
@@ -0,0 +1,13 @@
+SYNOPSIS
+        int living(object ob);
+
+BESCHREIBUNG
+        Liefert 1 zurueck, wenn <ob> ein lebendiges Objekt (living) ist.
+        <ob> ist living, wenn enable_commands() aus <obj> aufgerufen wurde.
+        <ob> kann auch 0 sein.
+
+BEISPIEL
+        living(this_player());  -> Dies liefert (hoffentlich) 1 zuerueck.
+
+SIEHE AUCH
+        enable_commands(E)
diff --git a/doc/efun/load_name b/doc/efun/load_name
new file mode 100644
index 0000000..f26c1ea
--- /dev/null
+++ b/doc/efun/load_name
@@ -0,0 +1,47 @@
+SYNOPSIS
+        string load_name()
+        string load_name(object|string obj)
+
+BESCHREIBUNG
+        Die Funktion liefert den Namen, mit dem <obj> geladen wurde. <obj>
+        kann direkt als Objekt oder als String mit seinem Namen angegeben
+        werden.
+
+        Wenn <obj> ein Clon ist, liefert die Funktion den Namen des Blueprints.
+        Wenn <obj> ein Blueprint ist, liefert die Funktion den Namen des Files,
+        aus dem der Blueprint kompiliert wurde.
+
+        Wenn <obj> ueber seinen Namen angegeben wurde, aber nicht / nicht mehr
+        existiert, generiert die Funktion den Namen, wie er sein muesste und
+        gibt diesen zurueck. Wenn der angegebene Name ungueltig ist, liefert
+        die Funktion 0.
+
+        Als Spezialfall liefert die Funktion 0, wenn <ob> 0 ist.
+
+        Fuer virtuelle Objekte liefert load_name() den originalen Ladenamen
+        des Objekts, welches der virtuelle Compiler erzeugte.
+
+        Wird <obj> nicht angegeben, wird der Name fuer das momentan gueltige
+        Objekt angegeben.
+
+        Im Gegensatz zum object_name() kann der load_name() nicht durch
+        rename_object() oder einen VC veraendert werden. Ist ein <obj> jedoch
+        einem replace_program() unterworfen, spiegelt der load_name() nicht
+        mehr das effektive Verhalten des Objekts wider.
+
+BEISPIELE
+        object o;
+        o = clone_object("/std/thing");
+        write(load_name(o));  --> liefert "/std/thing" in !Compat Modus
+                                  und "std/thing"  im Compat Modus
+        write(load_name("/std/thing"));  --> gleich wie oben
+        write(load_name("/std/thing#4n5")); --> liefert 0
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.6.
+        Strings als Argumente sind moeglich seit 3.2.8.
+        0 ist zulaessig seit 3.2.9.
+
+SIEHE AUCH
+        clone_object(E), clonep(E), object_name(E), load_object(E),
+        replace_program(E), program_name(E), present_clone(E)
diff --git a/doc/efun/load_object b/doc/efun/load_object
new file mode 100644
index 0000000..847d0b8
--- /dev/null
+++ b/doc/efun/load_object
@@ -0,0 +1,23 @@
+SYNOPSIS
+        object load_object(string name)
+
+DESCRIPTION
+        Load the object from the file <name> and return it. If the
+        object already exists, just return it.
+
+        This efun can be used only to load blueprints - for clones, use
+        the efun clone_object().
+
+        If strict euids are enforced, the cloning object must have
+        a non-zero euid.
+
+EXAMPLE
+        // Update and reload the standard player object
+        destruct(find_object("/std/player"));
+        load_object("/std/player");
+
+HISTORY
+        Introduced in LDMud 3.2.6.
+
+SEE ALSO
+        clone_object(E)
diff --git a/doc/efun/localtime b/doc/efun/localtime
new file mode 100644
index 0000000..a522dc4
--- /dev/null
+++ b/doc/efun/localtime
@@ -0,0 +1,39 @@
+SYNOPSIS
+        #include <sys/time.h>
+
+        int *localtime(int clock);
+        int *localtime(int *uclock);
+
+BESCHREIBUNG
+        Interpretiert das Argument <clock> als Anzahl Sekunden seit dem
+        01. Januar 1970, 00:00:00, und gibt die Zeit in Lokalzeit in einer
+        sauberen Struktur zurueck. Wird <clock> nicht angegeben, wird
+        standardmaessig time() verwendet.
+
+        Alternativ kann auch ein Array von zwei Zahlen als Argument angegeben
+        werden. Das erste Element wird interpretiert wie <clock>, das zweite
+        Argument enthaelt die vergangenen Mikrosekunden in dieser Sekunde und
+        wird ignoriert.
+
+        Das Resultat ist ein Array mit folgenden Elementen:
+
+            int TM_SEC    (0):  Sekunde in der Minute (0..59)
+            int TM_MIN    (1):  Minute in der Stunde (0..59)
+            int TM_HOUR   (2):  Stunde des Tages (0..23)
+            int TM_MDAY   (3):  Tag im Monat (1..31)
+            int TM_MON    (4):  Monat des Jahres (0..11)
+            int TM_YEAR   (5):  Jahr (z.B. 2001)
+            int TM_WDAY   (6):  Wochentag (0..6, Sonntag = 0)
+            int TM_YDAY   (7):  Tag im Jahr (0..365)
+            inz TM_ISDST  (8):  TRUE: Daylight Saving Time
+
+BEISPIEL
+        printf("Today is %s\n", ({ "Sonntag", "Montag", "Dienstag",
+            "Mittwoch", "Donnerstag", "Freitag", "Samstag"})
+            [localtime()[TM_WDAY]]);
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9
+
+SIEHE AUCH
+    ctime(E), gmtime(E), time(E), utime(E)
diff --git a/doc/efun/log b/doc/efun/log
new file mode 100644
index 0000000..1b2abff
--- /dev/null
+++ b/doc/efun/log
@@ -0,0 +1,8 @@
+SYNOPSIS
+        float log(int|float arg);
+
+BESCHREIBUNG
+        Liefert den natuerlichen Logarithmus von <arg>.
+
+SIEHE AUCH
+        exp(E), pow(E)
diff --git a/doc/efun/lower_case b/doc/efun/lower_case
new file mode 100644
index 0000000..9701e20
--- /dev/null
+++ b/doc/efun/lower_case
@@ -0,0 +1,12 @@
+SYNOPSIS
+        string lower_case(string str);
+
+BESCHREIBUNG
+        Konvertiert alle Zeichen in <str> in Kleinbuchstaben und liefert den
+        neuen String.
+
+BEISPIEL
+        lower_case("Hallo WeLT!") -> "hallo welt!"
+
+SIEHE AUCH
+        capitalize(E), upper_case(E)
diff --git a/doc/efun/m_add b/doc/efun/m_add
new file mode 100644
index 0000000..624f4b9
--- /dev/null
+++ b/doc/efun/m_add
@@ -0,0 +1,29 @@
+SYNOPSIS
+        mapping m_add(mapping map, mixed key, [mixed data, ...]);
+
+BESCHREIBUNG
+        Fuegt einen neuen Eintrag mit Index <key> zum Mapping <map> hinzu
+        oder ersetzt diesen. Das veraenderte Mapping wird als Ergebnis
+        zurueck geliefert. Werte, die nicht zugeordnet werden koennen, werden
+        als 0 interpretiert, irrelevante Argumente werden ignoriert.
+
+BEISPIELE
+        mapping m;
+        m = ([ "foo" ]);
+        m_add(m, "bar", 1) --> ([ "foo", "bar" ])
+
+        m = ([ "foo":1 ]);
+        m_add(m, "bar", 1) --> ([ "foo":1, "bar":1 ])
+
+        m = ([ "foo":1;2 ]);
+        m_add(m, "bar", 1) --> ([ "foo":1;2, "bar":1;0 ])
+
+        apply(#'m_add, m, "baz", ({ 4, 5 }))
+        --> ([ "foo":1;2, "bar":1;0, "baz":4;5 ])
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        mappingp(E), mkmapping(E), m_delete(E), m_entry(E), m_indices(E),
+        m_values(E), sizeof(E), widthof(E)
diff --git a/doc/efun/m_allocate b/doc/efun/m_allocate
new file mode 100644
index 0000000..255f3b9
--- /dev/null
+++ b/doc/efun/m_allocate
@@ -0,0 +1,46 @@
+SYNOPSIS
+        mapping m_allocate(int size)
+        mapping m_allocate(int size, int width)
+
+BESCHREIBUNG
+        Die Funktion reserviert Speicher fuer ein Mapping. <size> ist die
+        Anzahl Eintraege (d.h. die Anzahl Keys), <width> ist die Anzahl
+        Dateneintraege pro Key. Wird <width> nicht angegeben, werden Keys
+        mit einem Datenelement erzeugt.
+
+        Die Funktion ist nur sinnvoll, wenn man ein Mapping erzeugt, dessen
+        ungefaehre Groesse von vornherein bekannt ist, um so den Overhead
+        von wiederholten Speicherallokation zu minimieren. Wenn nicht alle
+        allozierten Datenelemente mit Daten bestueckt werden, werden die
+        Ueberbleibsel einige Zeit spaeter bei Gelegenheit wieder freigegeben
+        (s. Bemerkungen).
+        m_allocate() ist auch nuetzlich, wenn ein Mapping bestimmter Breite
+        erzeugt werden soll, ohne bereits die Daten zu den Keys bereit zu
+        stellen.
+
+        Wenn bloss ein leeres Mapping bestimmter Breite erzeugt werden soll,
+        so kann folgende Notation verwendet werden:
+
+        ([ ]) : erzeugt ein leeres Mapping mit Breite 1.
+        ([:<width>]) : erzeugt ein leeres Mapping der Breite <width>,
+            wobei <width> eine beliebige Anweisung sein kann, die eine
+            Integerzahl zurueck liefert. Tatsaechlich wird diese Notation
+            als 'm_allocate(0, <width>)' kompiliert.
+
+BEISPIELE
+        m_allocate(3,7) -> erzeugt ein Mapping mit 7 Werten pro Key und Platz
+           fuer 3 Eintraege.
+       ([:2*3]) -> entspricht m_allocate(0,6).
+
+BEMERKUNGEN
+        Ungenutzer Speicher des allozierten Mappins wird waehrend des sog.
+        Kompaktierens des Mappings freigegeben. Dies passiert waehrend eines
+        "data cleanups" oder einer "garbage collection". Die Zeit zwischen
+        "data cleanups" ist mit configure_driver() konfigurierbar.
+
+GESCHICHTE
+        Umbenannt von allocate_mapping() in LDMud 3.2.6.
+        Die ([:<width>]) Notation wurde in 3.2.9 eingefuehrt.
+
+SIEHE AUCH
+        mappings(LPC), walk_mapping(E), get_type_info(E), m_reallocate(E)
diff --git a/doc/efun/m_contains b/doc/efun/m_contains
new file mode 100644
index 0000000..e941ff3
--- /dev/null
+++ b/doc/efun/m_contains
@@ -0,0 +1,18 @@
+SYNOPSIS
+        int m_contains(mixed &data1, ... , &dataN, mapping map, mixed key);
+
+BESCHREIBUNG
+        Wenn <map> den Key <key> enthaelt, werden die entsprechenden Werte
+        den Datenargumenten von <key> zugeordnet, welche per Referenz
+        uebergeben werden muessen. m_contains liefert in diesem Fall 1 zurueck.
+        Wenn <key> nicht in <map> enthalten ist, liefert die Funktion 0
+        zurueck und die Datenargumente bleiben unveraendert.
+
+        Man kann diese Funktion auch fuer 0-Wert Mappings verwenden, wobei
+        sie den gleichen Effekt wie member(E) hat.
+
+AENDERUNGEN
+        Umbenannt von 'mapping_contains' in LDMud 3.2.6.
+
+SIEHE AUCH
+        m_entry(E), mappings(LPC), member(E)
diff --git a/doc/efun/m_delete b/doc/efun/m_delete
new file mode 100644
index 0000000..bb9d453
--- /dev/null
+++ b/doc/efun/m_delete
@@ -0,0 +1,11 @@
+SYNOPSIS
+        mapping m_delete(mapping map, mixed key)
+
+BESCHREIBUNG
+        Loescht den Eintrag mit dem Index <key> aus dem Mapping <map> und
+        liefert das veraenderte Mapping zurueck. Wenn <map> keinen Eintag
+        mit dem Index <key> enthaelt, wird nichts veraendert.
+
+SIEHE AUCH
+        mappingp(E), mkmapping(E), m_add(E), m_indices(E), m_values(E),
+        sizeof(E), widthof(E)
diff --git a/doc/efun/m_entry b/doc/efun/m_entry
new file mode 100644
index 0000000..20ea2af
--- /dev/null
+++ b/doc/efun/m_entry
@@ -0,0 +1,24 @@
+SYNOPSIS
+        *mixed m_entry(mapping map, mixed key);
+
+BESCHREIBUNG
+        Durchsucht das Mapping <map> nach dem Eintrag mit Index <key> und
+        liefert alle Werte von <key> in einem Array zurueck.
+
+        Wenn <map> keinen Eintrag mit Index <key> enthaelt, liefert
+        m_entry() 0.
+
+BEISPIEL
+        mapping m = ([1:"bla":-1, 2:"fasel":-2 ])
+        m_entry(m, 0) -> 0
+        m_entry(m, 1) -> ({"bla", -1})
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.10.
+
+ANMEKRUNG
+        Mit der Efun m_add() koennen alle Werte eines Eintrages auf einmal
+        addiert werden.
+
+SIEHE AUCH
+        m_add(E), m_contains(E), mappings(LPC), member(E)
diff --git a/doc/efun/m_indices b/doc/efun/m_indices
new file mode 100644
index 0000000..4d84c4e
--- /dev/null
+++ b/doc/efun/m_indices
@@ -0,0 +1,9 @@
+SYNOPSIS:
+	mixed *m_indices(mapping map)
+
+DESCRIPTION:
+	Return an array containing the indices of mapping 'map'.
+
+SEE ALSO:
+	mappingp(E), mkmapping(E), m_values(E), m_delete(E),
+	sizeof(E), widthof(E)
diff --git a/doc/efun/m_reallocate b/doc/efun/m_reallocate
new file mode 100644
index 0000000..627bc97
--- /dev/null
+++ b/doc/efun/m_reallocate
@@ -0,0 +1,23 @@
+SYNOPSIS
+        mapping m_reallocate(mapping m, int width);
+
+BESCHREIBUNG
+        Erzeugt ein neues Mapping mit <width> Werten pro Key und fuellt das
+        Mapping mit den Werten aus <m>. Wenn <m> weniger als <width> Werte
+        pro Key hat, werden im neuen Mapping die restlichen Werte auf 0
+        gesetzt. Wenn <m> mehr als <width> Werte pro Key hat, werden die
+        ueberzaehligen Werte ignoriert.
+
+        Das urspruengliche Mapping <m> wird nicht veraendert.
+
+BEISPIEL
+        mapping m = ([ "foo":1;2;3, "bar":4;5;6 ])
+
+        m_reallocate(m, 1) --> liefert ([ "foo":1,       "bar:4 ])
+        m_reallocate(m, 4) --> liefert ([ "foo":1;2;3;0, "bar:4;5;6;0 ])
+
+AENDERUNGEN
+    Eingefuehrt in LDMud 3.2.6, auf Vorschlag von TubMud.
+
+SIEHE AUCH
+        m_allocate(E), m_values(E), widthof(E)
diff --git a/doc/efun/m_values b/doc/efun/m_values
new file mode 100644
index 0000000..4b94154
--- /dev/null
+++ b/doc/efun/m_values
@@ -0,0 +1,14 @@
+SYNOPSIS:
+        mixed *m_values(mapping map)
+        mixed *m_values(mapping map, int index)
+
+DESCRIPTION:
+       If index is 0 or not given, return an array with the first values of 
+       mapping 'map'.
+       For values of index >0, return an array with the corresponding higher
+       values of mapping 'map', i.e. m_values(map,2) returns the third 
+       values.
+
+SEE ALSO:
+       mappingp(E), mkmapping(E), m_indices(E), m_delete(E),
+       sizeof(E), widthof(E), mappings(LPC)
diff --git a/doc/efun/make_shared_string b/doc/efun/make_shared_string
new file mode 100644
index 0000000..3bb6732
--- /dev/null
+++ b/doc/efun/make_shared_string
@@ -0,0 +1,24 @@
+VERALTET
+SYNOPSIS
+        string make_shared_string (string str);
+
+BESCHREIBUNG
+        Fuegt <str> in die Tabelle der gemeinsam verwendeten String des Spiels
+        ein.
+
+        Wenn ein String von mehreren Variablen / Objekten verwendet wird,
+        spart dies Speicher. Keys von Alists und Mappings sind immer gemeinsam
+        verwendete Strings.
+
+        In LDMud 3.3 ist diese Funktion nicht laenger nuetzlich: Strings
+        werden sowieso so weit wie moeglich gemeinsam verwendet, und der
+        Driver wandelt untablierte Strings nach einiger Zeit automatisch in
+        tablierte Strings um um
+
+BUGS
+        Ein besseres Stringhandling im Driver sollte diese Efun ueberfluessig
+        machen.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6, auf Vorschlag von TubMud.
+        Veraltet seit LDMud 3.3 .
diff --git a/doc/efun/map b/doc/efun/map
new file mode 100644
index 0000000..808f065
--- /dev/null
+++ b/doc/efun/map
@@ -0,0 +1,93 @@
+SYNOPSIS
+        mixed * map(mixed *arg, string func, string|object ob, mixed extra...)
+        mixed * map(mixed *arg, closure cl, mixed extra...)
+        mixed * map(mixed *arg, mapping m [, int idx])
+
+        mixed * map(struct arg, string func, string|object ob, mixed extra...)
+        mixed * map(struct arg, closure cl, mixed extra...)
+        mixed * map(struct arg, mapping m [, int idx])
+
+        mapping map(mapping arg, string func, string|object ob, mixed extra...)
+        mapping map(mapping arg, closure cl, mixed extra...)
+
+        string map(string arg, string func, string|object ob, mixed extra...)
+        string map(string arg, closure cl, mixed extra...)
+        string map(string arg, mapping m [, int idx])
+
+BESCHREIBUNG
+        Ruft die Funktion <ob>-><func>() bzw. die Closure <cl> fuer jedes
+        Element des Strings, Arrays, Mappings oder der Struktur <arg> auf
+        und liefert ein Resultat, das aus den verschiedenen Rueckgabewerten
+        erstellt wurde.
+
+        Wurde <ob> nicht angegeben, oder ist es weder ein String noch ein
+        Objekt, wird stattdessen this_object() verwendet.
+
+        Ist <arg> ein Array, ein String oder eine Struktur, wird die Funktion
+        mit jedem Element des Arrays als erstem Parameter aufgerufen, gefolgt
+        von den <extra> Argumenten. Das Resultat der Efun ist ein Array, das
+        die Rueckgabewerte der Funktionsaufrufe enthaelt. Man koennte die
+        Operation map() deshalb umschreiben als:
+
+            foreach(index) result[index] = ob->func(arg[index], extra...)
+
+        Ist <arg> ein Array, ein String oder eine Struktur, und wurde statt
+        einer Funktion ein Mapping angegeben, so liefert map() ein Array mit
+        den Werten, die im Mapping an Stelle der urspruenglichen Werte stehen,
+        bzw. mit den Originalwerten, wenn fuer sie kein Mappingeintrag
+        existiert. Ist <idx> angegeben, so wird die entsprechende Spalte des
+        Mappings verwendet. Mit anderen Worten:
+
+            foreach(index)
+                if (arg[index] ist ein Key in <arg>)
+                    result[index] = map[arg[index]] oder map[arg[index]]
+                else
+                    result[index] = arg[index]
+
+        Ist <arg> ein Mapping, wird die Funktion fuer jeden Key des Mappings
+        als erstem Parameter und den Datenwerten (sofern vorhanden) als
+        zusaetzliche Argumente aufgerufen, gefolgt von den <extra> Argumenten.
+        Die <extra> Argumente duerfen keine geschuetzten Referenzen enthalten
+        (wie z.B. &(i[0])). Das Ergebnis der Efun ist ein Mapping, das die
+        Resultate der Funktionsaufrufe als Zuordnung zum jeweiligen Key
+        enthaelt.
+
+        Abhaengig von der Breite des Mappings <arg>, kann die Operation
+        umschrieben werden als:
+
+            foreach (key in arg)
+                switch (widthof(arg))
+                case 0:
+                    result[key] = ob->func(key, 0, extra...)
+                case 1:
+                    result[key] = ob->func(key, arg[key], extra...)
+                else  :
+                    result[key] = ob->func( key
+                                        , ({ arg[key,0] ...arg[key,width-1] })
+                                        , extra...)
+
+        Der Vorteil dieses Ansatzes ist, dass beide Arten von mehrdimensionalen
+        Mappings (Mappings mit mehreren Werten pro Key und Mappings von Arrays)
+        gleich behandelt werden koennen.
+
+BEISPIELE
+        arr = ({ 1, 2, 3, 4 });
+        m = ([ 1:-1, 3:-3 ]);
+
+        map(arr, #'%, 2)  --> liefert ({ 1, 0, 1, 0 })
+        map(arr, m)       --> liefert ([ -1, 2, -3, 4 })
+
+ANMERKUNGEN
+        map() auf Arrays angewandt verhaelt sich wie map_array(), auf Mappings
+        angewandt hingegen verhaelt es sich wie eine Verallgemeinerung von
+        map_indices().
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.2.6, loest map_array() ab.
+        LDMud 3.2.8 fuehrt neu die Moeglichkeit ein, ein Array durch ein
+        Mapping zu mappen.
+        LDMud 3.3.439 fuehrt map() fuer Strings ein.
+        LDMud 3.3.719 fuehrt den <idx>-Parameter fuer mappen mit Mappings ein.
+
+SIEHE AUCH
+        filter(E), filter_indices(E), map_indices(E), map_objects(E)
diff --git a/doc/efun/map_indices b/doc/efun/map_indices
new file mode 100644
index 0000000..de3b15f
--- /dev/null
+++ b/doc/efun/map_indices
@@ -0,0 +1,75 @@
+map_indices(E)
+
+FUNKTION:
+     mapping map_indices(mapping m, string fun, object ob [, mixed extra])
+     mapping map_indices(mapping m, closure cl [, mixed extra])
+
+PARAMETER:
+     arr	- zu mappendes Array
+     fun/cl	- zu rufende Methode/Closure
+     ob		- Objekt/Dateiname, an dem Methode gerufen werden soll
+     extra	- weitere Parameter fuer Methode/Closure
+
+BESCHREIBUNG:
+     Mapped die Elemente (jeweils Schluessel) aus 'map' durch die Methode
+     'fun' oder die Closure 'cl' in ein neues Mapping.
+     Fuer jedes Element aus 'm' wird 'fun' oder 'cl' mit dem Schluessel als
+     erstem Parameter [und folgend den optionalen Extra-Parametern] gerufen.
+
+     Der Rueckgabewert der Methode/Closure wird in fuer den Schluessel als
+     Datenwert in das neue Mapping eingetragen.
+
+     ACHTUNG: Alle anderen Daten bei Mapping mit Breite>1 verfallen!
+
+     Verwendung von Methoden:
+	Wenn bei der Angabe von 'fun' kein Objekt 'ob' in Form eines Strings
+	oder Objekts angegeben wird, wird this_object() angenommen.
+
+     Verwendung von Closures:
+	Es koennen sowohl Lfun-Closures als auch Lambda-Closures verwendet
+	werden. Lfun-Closures koennen, wenn im selben Objekt vorhanden auch
+	'private' oder/und 'static' deklariert sein, muessen aber zu dem
+	Zeitpunkt der Verwendung bekannt sein (Funktionsprototypen benutzen).
+
+RUeCKGABEWERT:
+     Mapping mit Schluessel:Rueckgabewerten der Methode/Closure.
+
+BEISPIELE:
+     // ersetze in einem Mapping die Datenwerte durch das Doppelte,
+     // nutze dabei die Datenwerte des Altmappings durch Uebergabe als
+     // extra-Parameter
+
+     // Anmerkung: Das geht mit walk_mapping() eleganter!
+
+     int do_double(string key, mapping m, int mult) {
+      return m[key]*mult;
+     }
+
+     mapping x, y;
+     x=(["a":2, "b":3]);
+     y=map_indices((["a":2, "b":3]), #'do_double, &x, 3);
+
+     y == (["a":6,"b":9])
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i;
+     mapping ret; mapping input;
+     mixed *index;
+
+     ret=m_allocate(0, 1);
+     index=m_indices(input);
+     i=sizeof(index);
+     while(i--)
+       ret[index[i]]=ob->fun(index[i] [, extra1, extra2, ...]))
+       // ret[index[i]]=funcall(cl, index[i] [, extra1, extra2, ...]);
+
+SIEHE AUCH:
+     Arrays:		filter(E), map(E)
+     Objektarrays:	filter_objects(E), map_objects(E)
+     Mappings:		filter_indices(E)
+
+     Sonstiges:		walk_mapping(E), m_contains(E)
+			member()
+			m_indices(E), m_values(E)
+
+29.10.2006 Zesstra
diff --git a/doc/efun/map_objects b/doc/efun/map_objects
new file mode 100644
index 0000000..4543a2e
--- /dev/null
+++ b/doc/efun/map_objects
@@ -0,0 +1,51 @@
+map_objects(E)
+
+FUNKTION:
+     object *map_objects(object *arr, string fun [, mixed extra])
+
+PARAMETER:
+     arr	- zu mappendes Array von Objekten/Objektpfaden
+     fun	- an Objekten zu rufende Methode
+     extra	- weitere Parameter fuer Methode
+
+BESCHREIBUNG:
+     Mapped die Elemente aus 'arr' durch den Aufruf der Methode 'fun' an
+     jedem der Elemente von 'arr' in ein neues Array.
+     0-Eintraege werden ignoriert.
+
+     Der Rueckgabewert von
+	arr[n]->fun([extra1, extra2, ...])
+     wird an der Indexposition des Elementes in das neue Array eingetragen.
+
+RUeCKGABEWERT:
+     Array mit Resultaten der Funktionsaufrufe am jeweiligen Objekt.
+
+BEMERKUNGEN:
+     Werden Pfade angegeben, so wird versucht ein Objekt zu laden, falls
+     dieses nicht existiert.
+
+BEISPIEL:
+     // ersetze alle Objekte durch ihre Namen
+     arr=map_objects(inputarr, "name");
+
+     // ersetze alle Objekte durch ihre Namen im Genitiv
+     arr=map_objects(inputarr, "name", WESSEN);
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i;
+     object *ret; mixed *input;
+
+     i=sizeof(input);
+     ret=allocate(i);
+     while(i--)
+       ret[i]=input[i]->fun([extra1, extra2, ...]);
+
+SIEHE AUCH:
+     Arrays:		filter(E), map(E)
+     Objektarrays:	filter_objects(E)
+     Mappings:		filter_indices(E), map_indices(E)
+
+     Sonstiges:		sort_array(E), unique_array()
+			alist, transpose_array(E)
+
+20.Jan 2005 Gloinson
diff --git a/doc/efun/mappingp b/doc/efun/mappingp
new file mode 100644
index 0000000..fef2ac7
--- /dev/null
+++ b/doc/efun/mappingp
@@ -0,0 +1,9 @@
+SYNOPSIS:
+	int mappingp(mixed arg)
+
+DESCRIPTION:
+	Return 1 if the argument is a mapping, or 0 if it is not. 
+
+SEE ALSO:
+	intp(E), stringp(E), objectp(E), pointerp(E), mkmapping(E),
+	m_indices(E), m_values(E), m_delete(E), sizeof(E)
diff --git a/doc/efun/master b/doc/efun/master
new file mode 100644
index 0000000..cdf55b6
--- /dev/null
+++ b/doc/efun/master
@@ -0,0 +1,17 @@
+SYNOPSIS
+        object master();
+        object master(int dont_load);
+
+BESCHREIBUNG
+        Die Funktion liefert das Masterobjekt.
+
+        Wenn <dont_load> nicht wahr ist, stellt master() zuerst sicher, dass
+        das Masterobjekt auf existiert. Wenn <dont_load> wahr ist, liefert
+        master() nur das Masterobjekt oder 0, falls das aktuelle Masterobjekt
+        zerstoert wurde.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.10
+
+SIEHE AUCH
+        master(M)
diff --git a/doc/efun/match_command b/doc/efun/match_command
new file mode 100644
index 0000000..cd495d7
--- /dev/null
+++ b/doc/efun/match_command
@@ -0,0 +1,27 @@
+SYNOPSIS
+        #include <sys/commands.h>
+
+        mixed * match_command (string command, object origin)
+
+DESCRIPTION
+        Take the command <command>, parse it, and return an array of all
+        matching actions added to <origin> (read: <origin> is the object
+        'issuing' the command).
+
+        Each entry in the result array is itself an array of:
+
+          string [CMDM_VERB]:   The matched verb.
+          string [CMDM_ARG]:    The argument string remaining, or 0 if none.
+          object [CMDM_OBJECT]: The object defining the action.
+          string [CMDM_FUN]:    The name of the function to call in
+                                CMDM_OBJECT, which may be static.
+
+        The efun is useful for both debugging, and for implementing your
+        own H_COMMAND handling.
+
+HISTORY
+        Introduced in LDMud 3.3.259.
+
+SEE ALSO
+        hooks(C), execute_command(E), command(E), notify_fail(E),
+        command_stack(E)
diff --git a/doc/efun/max b/doc/efun/max
new file mode 100644
index 0000000..189f4a5
--- /dev/null
+++ b/doc/efun/max
@@ -0,0 +1,23 @@
+SYNOPSIS
+        string max(string arg, ...);
+        string max(string *arg);
+
+        int|float max(int|float arg, ...);
+        int|float max(int|float *arg);
+
+BESCHREIBUNG
+        Die Funktion liefert den groessten Wert aller <arg> und liefert ihn
+        zurueck. Wird max() nur mit einem Array aufgerufen wird (das nicht
+        leer sein darf), liefert die Funktion das groesste Element aus <arg>.
+
+BEISPIEL
+        max(1)                     - liefert 1
+        max(1, 1.1)                - liefert 1.1
+        max("foo", "bar")          - liefert "foo"
+        max( ({ "foo", "bar" }) )  - liefert "foo"
+
+AENDERUNGEN
+        Eingefuehrt in LDMued 3.2.9.
+
+SIEHE AUCH
+        min(E)
diff --git a/doc/efun/md5_crypt b/doc/efun/md5_crypt
new file mode 100644
index 0000000..d91ba18
--- /dev/null
+++ b/doc/efun/md5_crypt
@@ -0,0 +1,20 @@
+SYNOPSIS
+        string md5_crypt(string str, int seed)
+        string md5_crypt(string str, string seed)
+
+BESCHREIBUNG
+        Verschluesselt den String <str> mit dem Schluessel <seed>.
+        <seed> kann entweder ein Integer sein oder zwei Zeichen aus
+        dem String <seed>.  Wenn <seed> 0 ist, wird ein zufaelliger
+        Schluessel erzeugt.
+
+        Das Resultat enthaelt den Schluessel als die ersten beiden Zeichen.
+
+        Die Efun verwendet den MD5-Algorithmus, und das Resultat ist
+        kompatible mit der Passwordverschluesselung des Apache Webservers.
+
+        Fuer Passwortabfragen, die ohne Echo eingegeben werden koennen sollen,
+        bietet input_to() ein spezielles Flag.
+
+SIEHE AUCH
+        crypt(E), md5(E), sha1(E), input_to(E)
diff --git a/doc/efun/member b/doc/efun/member
new file mode 100644
index 0000000..9f0e66a
--- /dev/null
+++ b/doc/efun/member
@@ -0,0 +1,24 @@
+SYNOPSIS
+        int member(mixed *array, mixed elem [, int start]);
+        int member(string s, int elem [, int start]);
+        int member(mapping map, mixed key);
+
+BESCHREIBUNG
+        Fuer Arrays und String liefert member() den Index des ersten
+        Auftretens von <elem> in <arg>. Ist <elem> nicht in <arg> enthalten,
+        wird -1 zurueck gegeben.
+
+        Ist <start> als Zahl >= 0 gegeben, beginnt die Suche ab der
+        angegebenen Position. Eine Startposition groesser als die
+        Laenge des Strings/Arrays liefert stets das Resultat -1.
+
+        Fuer Mapping prueft member(), ob <key> in <map> enthalten ist und
+        liefert 1 zurueck falls ja, 0 sonst.
+
+BEISPIELE
+        member( ({ "abc", "defg" }), "defg" ) = 1
+        member( ({ "abc", "defg" }), "x" ) = -1
+        member( "abcdefg", 100 ) = member( "abcdefg", 'd' ) = 3
+
+SIEHE AUCH
+        rmember(E), mappings(LPC)
\ No newline at end of file
diff --git a/doc/efun/min b/doc/efun/min
new file mode 100644
index 0000000..c11f9b5
--- /dev/null
+++ b/doc/efun/min
@@ -0,0 +1,22 @@
+SYNOPSIS
+        string min(string arg, ... );
+        string min(string *arg_array);
+        int|float min(int|float arg, ...);
+        int|flaot min(int|float *arg_array);
+
+BESCHREIBUNG
+        Liefert das kleinste der Argumente <arg>. Wenn min() fuer ein
+        einzelnes (nicht leeres) Array aufgerufen wird, liefert min() das
+        kleinste Element im Array.
+
+BEISPIEL
+        min(1)                      -> liefert 1
+        min(1, -1.1)                -> liefert -1.1
+        min("bla", "fasel")         -> liefert "bla"
+        min( ({ "bla", "fasel" }) ) -> liefert "bla"
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        max(E)
diff --git a/doc/efun/mkdir b/doc/efun/mkdir
new file mode 100644
index 0000000..8c7a683
--- /dev/null
+++ b/doc/efun/mkdir
@@ -0,0 +1,9 @@
+SYNOPSIS
+        int mkdir(string path);
+
+BESCHREIBUNG
+        Erstellt ein Verzeichnis <path> und liefert 1, wenn das Verzeichnis
+        erstellt werden konnte, sonst 0.
+
+SIEHE AUCH
+        rmdir(E), rm(E), get_dir(E), file_size(E)
diff --git a/doc/efun/mkmapping b/doc/efun/mkmapping
new file mode 100644
index 0000000..75cf827
--- /dev/null
+++ b/doc/efun/mkmapping
@@ -0,0 +1,37 @@
+SYNOPSIS
+        mapping mkmapping(mixed *arr1, mixed *arr2, mixed *arr3, ...);
+        mapping mkmapping(struct st);
+
+BESCHREIBUNG
+        Liefert ein Mapping mit Keys aus <arr1> und Datenelementen aus
+        <arr2>, <arr3>.... Dem Key <arr1[0]> werden die Datenelemente
+        <arr2[0]>, <arr3[0]>... zugeordnet. Wenn die Datenarrays
+        ungleich gross sind, enthaelt das Mapping nur so viele Eintraege,
+        wie im kleinsten Datenarray enthalten sind.
+
+        Die zweite Form konvertiert die angegebene struct <st> in ein Mapping.
+        Hierbei werden die Namen des jeweiligen Elementes in der struct als
+        als Schluessel.
+
+        Gewoehnlich werden Mappings erweitert, indem einfach neue Elemente
+        eingefuegt werden. Diese Funktion ist nuetzlich, wenn der
+        ungefaehr benoetigte Speicherplatz bereits vorher bekannt ist,
+        um so den Overhead bei der Speicherallokation zu minimieren.
+        Allenfalls zu viel allozierter Speicher wird freigegeben, sobald
+        die Funktion, die die mkmapping() Anweisung enthaelt, beendet ist.
+
+BESIPIEL
+        mkmapping( ({ 1, 2 }), ({ 10, 11 }), ({ 20, 21, 22}));
+          liefert ([ 1:10;20, 2:11;21 ])
+
+        struct s { int a, b, c; };
+        mkmapping( (<s> 1, ({ 2, 3 }), 3 )
+          liefert ([ "a":1, "b":({2,3}), "c":3 ])
+
+AeNDERUNGEN
+        LDMud 3.3.433 ermoeglichte die Konversion von structs.
+
+VERGLEICHE
+        mappings(LPC), mappingp(E), m_indices(E), m_values(E),
+        m_add(E), m_delete(E), sizeof(E), widthof(E), unmkmapping(E),
+        to_struct(E)
diff --git a/doc/efun/mktime b/doc/efun/mktime
new file mode 100644
index 0000000..b71227b
--- /dev/null
+++ b/doc/efun/mktime
@@ -0,0 +1,38 @@
+SYNOPSIS
+        #include <sys/time.h>
+
+        int mktime(int *ts);
+
+BESCHREIBUNG
+        Ist das Argument <ts> ein Array mit 9 Elementen (int), entsprechend
+        des Rueckgabewertes von local_time()/gm_time(), liefert die Funktion
+        die Anzahl Sekunden seit dem 01. Januar 1970, 00:00:00 zurueck.
+        Dies ist von Nutzen, wenn man ein Datum/Uhrzeit hat, diese aber als
+        Ganzzahl-Wert speichern will oder eine Zeitdifferenz zwischen zwei
+        Daten ausrechnen will.
+
+        Das Array muss dabei so aufgebaut sein:
+            int TM_SEC    (0):  Sekunde in der Minute (0..59)
+            int TM_MIN    (1):  Minute in der Stunde (0..59)
+            int TM_HOUR   (2):  Stunde des Tages (0..23)
+            int TM_MDAY   (3):  Tag im Monat (1..31)
+            int TM_MON    (4):  Monat des Jahres (0..11)
+            int TM_YEAR   (5):  Jahr (z.B. 2001)
+            int TM_WDAY   (6):  Wochentag (0..6, Sonntag = 0)
+            int TM_YDAY   (7):  Tag im Jahr (0..365)
+            inz TM_ISDST  (8):  TRUE: Daylight Saving Time
+
+      TM_YDAY und TM_WDAY werden ignoriert und koennen beliebige Zahlen
+      enthalten.
+
+BEISPIEL
+      Man hat ein Datum/Uhrzeit (z.B. Benutzereingabe), welches als
+      Unix-Zeitstmepel gespeichert werden soll:
+      // "Mit, 24. Okt 2007, 10:48:00" entspricht folgendem Zeitstempel:
+      int unixzeit = mktime( ({0, 48, 09, 24, 09, 2007, 0, 01, 0}) );
+      
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.3.71x
+
+SIEHE AUCH
+    ctime(E), gmtime(E), local_time(E), time(E), utime(E)
diff --git a/doc/efun/modify_command b/doc/efun/modify_command
new file mode 100644
index 0000000..eea6070
--- /dev/null
+++ b/doc/efun/modify_command
@@ -0,0 +1,21 @@
+SYNOPSIS
+	int|string modify_command(string cmd)
+
+DESCRIPTION
+	After set_modify_command(mob) was called for an interactive
+	object iob, all commands for that user will be passed to
+	mob->modify_command(), and the return will then be checked for
+	actions.
+
+	If the result is a string, it is the new command to execute
+	instead of the given one. Note that it is not possible to
+	make several commands from one this way!
+	If the result is a non-zero number, the given command is to
+	be ignored. In case of the closure/lfun setting this may
+	mean that the closure/lfun already executed it.
+	If the result is 0, the originally given command is to be
+	used.
+
+
+SEE ALSO
+	set_modify_command(E), hooks(C)
diff --git a/doc/efun/move_object b/doc/efun/move_object
new file mode 100644
index 0000000..48b23e9
--- /dev/null
+++ b/doc/efun/move_object
@@ -0,0 +1,18 @@
+SYNOPSIS:
+        void move_object(mixed item, mixed dest)
+
+        item->move(object dest, string methods)
+
+DESCRIPTION:
+	The item, which can be a object_name or an object, is moved into
+	it's new environment dest, which can also be object_name or an
+	object.  In native mode, the only object that can be moved
+	with move_object() is the calling object itself. This function
+	is only used to implement the lfun move().
+        
+        Use the lfun move() instead by inheriting standard objects.
+	move() must be called in the object to be moved. This gives
+	the moved object full control over its movement.
+
+SEE ALSO:
+        move(L), remove(L), init(L), transfer(E), native(C)
diff --git a/doc/efun/negate b/doc/efun/negate
new file mode 100644
index 0000000..b1f0bdf
--- /dev/null
+++ b/doc/efun/negate
@@ -0,0 +1,6 @@
+SYNOPSIS
+        int negate(int arg);
+        float negate(float arg);
+
+BESCHREIBUNG
+        Liefert den negativen Wert von <arg>.
diff --git a/doc/efun/net_connect b/doc/efun/net_connect
new file mode 100644
index 0000000..f3aae2f
--- /dev/null
+++ b/doc/efun/net_connect
@@ -0,0 +1,30 @@
+SYNOPSIS
+        int net_connect(string host, int port)
+
+BESCHREIBUNG
+        Oeffne eine nicht-blockierende TCP Netzverbindung zu
+        <host>:<port> .  Bei Erfolg wird die Verbindung zum
+        aufrufenden Objekt gebunden und die lfun logon() wird in dem
+        Objekt aufgerufen.
+
+        Resultat ist 0 bei Erfolg, und eine Unix ERRNO bei Misserfolg.
+
+        Ist der Driver fuer IPv6 konfiguriert, wird <host> erst als
+        IPv6-Name interpretiert, und wenn das fehlschlaegt, als
+        IPv4-Name.
+
+        Wenn die Verbindung nicht sofort erzeugt werden kann, gibt die
+        Funktion 'Erfolg' zurueck, und der Driver vollendet die
+        Funktion im Hintergrund. Sollte die Verbindungsaufbau im
+        Hintergrund fehlschlagen, wird logon(-1) im aktuellen Objekt
+        aufgerufen.
+
+        Die Funktion erzeugt eine privilege violation ("net_connect",
+        host, port).
+
+        WARNUNG: Ist <host> ein Name und keine IP, fuehrt die Funktion
+        einen DNS-Aufruf durch, der den Driver fuer einige Zeit
+        blockieren kann.
+
+SIEHE AUCH
+        logon(A)
diff --git a/doc/efun/next_bit b/doc/efun/next_bit
new file mode 100644
index 0000000..31fb90a
--- /dev/null
+++ b/doc/efun/next_bit
@@ -0,0 +1,32 @@
+SYNOPSIS
+        int next_bit(string str, int start);
+        int next_bit(string str, int start, int find_cleared);
+
+BESCHREIBUNG
+        Liefert den Zahlenwert des naechsten Bits im Bitstring <bit> nach
+        der Position <start>. Gewoehnlich ist dies das naechste gesetzte
+        Bit, aber wenn <find_cleared> angegeben und nicht 0 ist, wird
+        die Postion des naechsten geloeschten Bits zurueck gegeben.
+
+        Dabei ist das Finden von geloeschten Bits nach dem letzten gesetzten
+        Bit auf die tatsaechliche Laenge von <str> beschraenkt.
+
+        Jedes Zeichen enthaelt 6 Bits. In jedem Zeichen kann deshalb eine
+        Zahl von 0 bis 63 gespeichert werde (2^6=64). Das erste Zeichen
+        ist der Leerschlag " " mit dem Wert 0. Das erste Zeichen im String
+        ist jenes mit den niedrigsten Bits (0-5).
+
+BEISPIEL
+        string s;
+        int p;
+
+        s = set_bit("", 4); s = set_bit(s, 2);
+
+        for (p = -1; -1 != (p = next_bit(s, p); )
+            write(p+"\n");
+
+        --> das gibt 2 und 4 aus.
+
+SIEHE AUCH
+        set_bit(E), clear_bit(E), test_bit(E), last_bit(E), count_bits(E),
+        and_bits(E), or_bits(E), xor_bits(E), invert_bits(E), copy_bits(E)
diff --git a/doc/efun/next_inventory b/doc/efun/next_inventory
new file mode 100644
index 0000000..61370a0
--- /dev/null
+++ b/doc/efun/next_inventory
@@ -0,0 +1,17 @@
+SYNOPSIS
+        object next_inventory();
+        object next_inventory(object ob);
+
+BESCHREIBUNG
+        Liefert das naechste Objekt aus dem Inventar von <ob>. Wird <ob>
+        nicht angegeben, wird this_object() verwendet.
+
+        Diese Efun wird meistens zusammen mit first_inventory() verwendet
+        um ueber Raum- und Containerinhalte zu iterieren.
+        Fuer ein Beispiel siehe dort.
+
+SIEHE AUCH
+        first_inventory(E), all_inventory(E), environment(E),
+        deep_inventory(E)
+
+7.Aug 2007 Gloinson
\ No newline at end of file
diff --git a/doc/efun/object_info b/doc/efun/object_info
new file mode 100644
index 0000000..4a773fc
--- /dev/null
+++ b/doc/efun/object_info
@@ -0,0 +1,202 @@
+SYNOPSIS
+        #include <object_info.h>
+
+        mixed object_info(object ob, int what)
+
+DESCRIPTION
+        Returns some internal information about object <ob>. The
+        Argument <what> determines which information is returned.
+
+        It can be either a configuration option as given to
+        configure_object() or one of the following options:
+
+
+
+        Object Flags:
+
+        <what> == OI_ONCE_INTERACTIVE:
+           1 if <ob> was once (or still is) interactive, 0 else.
+
+        <what> == OI_RESET_STATE:
+           1 if <ob> is (still) reset, 0 else.
+
+        <what> == OI_WILL_CLEAN_UP:
+           1 if <ob>'s clean_up() will be called, 0 else.
+
+        <what> == OI_LAMBDA_REFERENCED:
+           1 if <ob> has lambdas (and there replace_program()
+           is not allowed anymore), 0 else.
+
+        <what> == OI_REPLACED:
+           1 if the program for <ob> was replaced, 0 else.
+
+
+
+        Program Flags:
+
+        <what> == OI_NO_INHERIT:
+           1 if the program can't be inherited.
+
+        <what> == OI_NO_CLONE:
+           1 if the program/blueprint can't be cloned.
+
+        <what> == OI_NO_SHADOW:
+           1 if the program's functions can't be shadowed.
+
+        <what> == OI_SHARE_VARIABLES:
+           1 if clones of this program share their initial
+           variable values with the blueprint.
+
+
+
+        Swapping Information:
+
+        <what> == OI_SWAPPED:
+           1 if <ob> is swapped, 0 else.
+
+        <what> == OI_PROG_SWAPPED:
+           1 if <ob>'s program is swapped, 0 else.
+
+        <what> == OI_VAR_SWAPPED:
+           1 if <ob>'s variables are swapped, 0 else.
+
+        <what> == OI_SWAP_NUM:
+           The swap number for <ob>s program, or -1 if not swapped.
+
+
+
+        Time Information:
+
+        <what> == OI_NEXT_RESET_TIME:
+            Time of the next reset.
+
+        <what> == OI_NEXT_CLEANUP_TIME:
+            Time of the next data cleanup.
+
+        <what> == OI_LAST_REF_TIME:
+            Time of the last call to <ob>.
+
+
+
+        Object List:
+
+        <what> == OI_OBJECT_NEXT:
+           The next object in the global object list.
+
+        <what> == OI_OBJECT_PREV:
+           The previous object in the global object list.
+
+        <what> == OI_OBJECT_POS:
+           The position of <ob> in the global object list,
+           counting from 0 up. This can be expensive to compute.
+
+
+
+        Shadows:
+
+        <what> == OI_SHADOW_NEXT:
+           The next object in the shadow list, i.e. the object
+           that is shadowing <ob>, or 0 if <ob> is not shadowed.
+
+        <what> == OI_SHADOW_PREV:
+           The previous object in the shadow list, i.e. the object
+           that <ob> is currently shadowing, or 0 if <ob> is not a shadow.
+
+        <what> == OI_SHADOW_ALL:
+           Returns an array of all objects that are currently
+           shadowing <ob>, or an empty array if <ob> is not shadowed.
+
+
+
+        Object Statistics:
+
+        <what> == OI_OBJECT_REFS:
+           The number of references to <ob>.
+
+        <what> == OI_TICKS:
+           The accumulated evaluation cost spend in <ob> modulo 1000000000.
+
+        <what> == OI_GIGATICKS:
+           The accumulated evaluation cost spend in <ob> divided by 1000000000.
+
+        <what> == OI_DATA_SIZE:
+           The total size of the values held in the object's variables,
+           scaled down according to the extend of data sharing.
+
+        <what> == OI_DATA_SIZE_TOTAL:
+           The unmodified total size of the values held in the
+           object's variables
+
+
+
+        Program Statistics:
+
+        <what> == OI_PROG_REFS:
+           The number of references to <ob>'s program.
+
+        <what> == OI_NUM_FUNCTIONS:
+           The number of functions in the program.
+
+        <what> == OI_NUM_VARIABLES:
+           The number of variables in the program.
+
+        <what> == OI_NUM_STRINGS:
+           The number of strings in the program.
+
+        <what> == OI_NUM_INHERITED:
+           The number of explicitely inherited programs.
+
+        <what> == OI_NUM_INCLUDED:
+           The number of included files in the program.
+
+        <what> == OI_SIZE_FUNCTIONS:
+           The size needed for the function structures.
+           Note that this does not include size of the function code.
+
+        <what> == OI_SIZE_VARIABLES:
+           The size needed for the variable structures.
+           Note that this does not include size of the variable data,
+           See OI_DATA_SIZE/OI_DATA_SIZE_TOTAL for that.
+
+        <what> == OI_SIZE_STRINGS:
+           The size needed for the string pointers.
+
+        <what> == OI_SIZE_STRINGS_DATA:
+           The size needed for the string values,
+           scaled down according to the extend of data sharing.
+
+        <what> == OI_SIZE_STRINGS_DATA_TOTAL:
+           The unmodified size needed for the string values.
+
+        <what> == OI_SIZE_INHERITED:
+           The size needed for the inherit structures.
+
+        <what> == OI_SIZE_INCLUDED:
+           The size needed for the include structures.
+
+        <what> == OI_PROG_SIZE:
+           The size of the program structure.
+
+        <what> == OI_PROG_SIZE_TOTAL:
+           The total size of the program.
+
+
+HISTORY
+        Introduced in LDMud 3.2.6.
+        Changes in LDMud 3.2.7:
+          - new basic result OIB_REPLACED.
+          - basic result OIB_IS_WIZARD is always 0 if set_is_wizard()
+              is not available.
+          - basic result OIB_APPROVED is gone.
+        LDMud 3.2.8 added OIM_DATA_SIZE to the result of OINFO_MEMORY.
+        LDMud 3.2.9 added the index mechanism, OIM_NUM_INCLUDES,
+          OIM_NO_INHERIT, OIM_NO_SHADOW, OIM_NO_CLONE, OIM_SIZE_STRINGS_DATA,
+          OIM_SIZE_STRINGS_TOTAL, and OIM_DATA_SIZE_TOTAL to the result
+          of OINFO_MEMORY.
+        LDMud 3.3.378 added the OIM_SHARE_VARIABLES to the result
+          of OINFO_MEMORY.
+        LDMud 3.3.654 added the OIB_NEXT_CLEANUP to the result of OINFO_BASIC.
+        LDMud 3.5.0 redesigned the whole efun.
+
+SEE ALSO
+        configure_object(E), interactive_info(E), driver_info(E)
diff --git a/doc/efun/object_name b/doc/efun/object_name
new file mode 100644
index 0000000..6ba82ed
--- /dev/null
+++ b/doc/efun/object_name
@@ -0,0 +1,26 @@
+SYNOPSIS:
+    string object_name()
+    string object_name(object ob)
+
+DESCRIPTION:
+    Get the file name of an object or if no argument is given of the current
+    object. If the object is a cloned object, then it will not have a
+    corresponding file name, but rather a new name based on the original
+    file name.
+        
+    The returned name always begins with '/' (absolute path),
+  	except when the parser runs in COMPAT (-o) mode.
+
+EXAMPLES:
+    find_object(object_name(ob)) == ob    
+    This is guaranteed to be true for all objects ob that are not
+   	destructed.
+        
+    sizeof(explode(object_name(ob), "#")) == 1  
+    This is always true if ob is a blue print.
+        
+SEE ALSO:
+        find_object(E)
+
+29.10.2006 Zesstra
+
diff --git a/doc/efun/object_time b/doc/efun/object_time
new file mode 100644
index 0000000..db4d91c
--- /dev/null
+++ b/doc/efun/object_time
@@ -0,0 +1,10 @@
+SYNOPSIS
+        int object_time();
+        int object_time(object ob);
+
+BESCHREIBUNG
+        Liefert die Zeit, zu der das Objekt <ob> erstellt wurde. Wird <obj>
+        nicht angegeben, wird standardmaessig this_object() verwendet.
+
+SIEHE AUCH
+        program_time(E), program_name(E)
diff --git a/doc/efun/objectp b/doc/efun/objectp
new file mode 100644
index 0000000..2b0758c
--- /dev/null
+++ b/doc/efun/objectp
@@ -0,0 +1,9 @@
+SYNOPSIS
+        int objectp(mixed arg);
+
+BESCHREIBUNG
+        Liefert 1, wenn <arg> ein Objekt ist.
+
+SIEHE AUCH
+        clonep(E), intp(E), stringp(E), pointerp(E), symbolp(E),
+        referencep(E), symbolp(E)
diff --git a/doc/efun/or_bits b/doc/efun/or_bits
new file mode 100644
index 0000000..25406e4
--- /dev/null
+++ b/doc/efun/or_bits
@@ -0,0 +1,27 @@
+SYNOPSIS
+        string or_bits(string str1, string str2);
+
+BESCHREIBUNG
+        <str1> und <str2> sind beides Bitstrings. Das Resultat von or_bits()
+        ist ein Bitstring, der das binaere Oder von <str1> und <str2>
+        enthaelt, d.h. ein String, in dem ein Bit gesetzt ist, wenn es
+        in <str1> oder <str2> oder in beiden gesetzt ist.
+
+        Jedes Zeichen enthaelt 6 Bits. In jedem Zeichen kann deshalb eine
+        Zahl von 0 bis 63 gespeichert werde (2^6=64). Das erste Zeichen
+        ist der Leerschlag " " mit dem Wert 0. Das erste Zeichen im String
+        ist jenes mit den niedrigsten Bits (0-5).
+
+BEISPIEL
+        string s1, s2, s3;
+
+        s1 = set_bit("", 3); s1 = set_bit(s1, 15);  -> s1 is "( ("
+        s2 = set_bit("", 3); s2 = set_bit(s2, 4);   -> s2 is "8"
+
+        s3 = or_bits(s1, s2);
+
+        -> s3 is now "8 (", ie. a bitstring with bits 3, 4 and 15 set.
+
+SIEHE AUCH
+        clear_bit(E), set_bit(E), test_bit(E), next_bit(E), last_bit(E),
+        count_bits(E), and_bits(E), xor_bits(E), invert_bits(E), copy_bits(E)
diff --git a/doc/efun/parse_command b/doc/efun/parse_command
new file mode 100644
index 0000000..83b7731
--- /dev/null
+++ b/doc/efun/parse_command
@@ -0,0 +1,132 @@
+OPTIONAL
+SYNOPSIS
+        int parse_command (string cmd, object  env, string fmt, mixed &var, ...)
+        int parse_command (string cmd, object* arr, string fmt, mixed &var, ...)
+
+DESCRIPTION
+        parse_command() is basically a spiffed up sscanf operating
+        on word basis and targeted at recognizing object descriptions from
+        command strings.
+
+        The efun takes the command string <cmd> and the object(s) <env>/<arr>
+        and tries to match it against the format string <fmt>. Successfully
+        matched elements are assigned to the variables <var>.... The result
+        from the efun is 1 if the command could be fully matched, and 0
+        otherwise.
+
+        If the objects are given as a single object <env>, the efun matches
+        against the given object and all objects contained therein. Otherwise,
+        if the objects are given as an array <arr> of objects, the efun
+        matches only against the given objects.
+
+        The format string <fmt> consists of words, syntactic markers, and
+        %-directives for the values to parse and return in the variables.
+        A typical example is " 'get' / 'take' %i " or
+        " 'spray' / 'paint' [paint] %i ". The elements in detail are:
+
+           'word': obligatory text
+           [word]: optional text
+           /     : Alternative marker
+           %o    : Single item, object
+           %s    : Any text
+           %w    : Any word
+           %p    : One of a list of prepositions.
+                   If the variable associated with %p is used to pass
+                   a list of words to the efun, the matching will take
+                   only against this list.
+           %l    : non-compat: Living objects
+                   compat: a single living object
+           %i    : Any objects
+           %d    : Number >= 0, or when given textual: 0-99.
+
+        A <word> in this context is any sequence of characters not containing
+        a space. 'living objects' are searched by calls to the (simul)efuns
+        find_player() and find_living(): both functions have to accept a name
+        as argument and return the object for this name, or 0 if there
+        is none.
+
+        The results assigned to the variables by the %-directives are:
+
+           %o : returns an object
+           %s : returns a string of words
+           %w : returns a string of one word
+           %p : if passed empty: a string
+                if passed as array of words: var[0] is the matched word
+           %i : returns an array with the following content:
+                  [0]: int: the count/number recognized in the object spec
+                            > 0: a count (e.g. 'three', '4')
+                            < 0: an ordinal (e.g. 'second', 'third')
+                            = 0: 'all' or a generic plural such as 'apples'
+                  [1..]: object: all(!) objects matching the item description.
+                                 In the <env> form this may be the whole
+                                 recursive inventory of the <env> object.
+                It is up to the caller to interpret the recognized numeral
+                and to apply it on the list of matched objects.
+           %l : non-compat: as %i, except that only living objects are
+                            returned.
+                compat: as %o, except that only a living object is returned.
+
+        %i (and non-compat-%l) match descriptions like 'three red roses',
+        'all nasty bugs' or 'second blue sword'.
+
+        Note: Patterns of type: "%s %w %i" might not work as one would expect.
+        %w will always succeed so the arg corresponding to %s will always be
+        empty.
+
+        To make the efun useful it must have a certain support from the
+        mudlib: it calls a set of functions in objects to get the
+        information it needs to parse a string.
+
+          1. string *parse_command_id_list()
+              Normal singular names of the object.
+
+          2. string *parse_command_plural_id_list() - optional
+              Plural forms of the names returned by 1.
+              If this function doesn't exist, the parser tries to pluralize
+              the names returned by 1.
+
+          3. string *parse_command_adjectiv_id_list() -  optional
+              All adjectives associated with this object.
+
+        All names and adjectives may consist of several words separated
+        by spaces.
+
+        These functions should exist in all objects and are therefore best
+        put into a mandatory inherit file (e.g. /std/object.c).
+
+        In addition the master object may offer the same functions to provide
+        reasonable defaults (like 'thing' as generic singular name):
+
+             string *parse_command_id_list()
+               - Would normally return: ({ "one", "thing" })
+
+             string *parse_command_plural_id_list()
+               - Would normally return: ({ "ones", "things", "them" })
+
+             string *parse_command_adjectiv_id_list()
+               - Would normally return ({ "iffish" })
+
+        Two additional functions in the master object provide the default
+        list of prepositions (needed for %p) and the single 'all' word:
+
+             string *parse_command_prepos_list()
+               - Would normally return: ({ "in", "on", "under", "behind",
+                 "beside" })
+
+             string parse_command_all_word()
+               - Would normally return: "all"
+
+
+        int parse_command(string, object|object*, string, destargs...)
+
+
+EXAMPLE
+        object *items;
+        parse_command( "take apple",environment(this_player())
+                     , " 'get' / 'take' %i ",items);
+
+HISTORY
+        LDMud 3.3.258 removed the compat-mode parse_command().
+
+SEE ALSO
+        sscanf(E)
diff --git a/doc/efun/people b/doc/efun/people
new file mode 100644
index 0000000..e04c3bf
--- /dev/null
+++ b/doc/efun/people
@@ -0,0 +1,8 @@
+void people()
+
+A function that will list all interactive players, and some info about them. 
+This function is normally
+
+connected to the people command, that wizards have.
+
+THIS FUNCTION IS OBSOLETE. LOOK AT users() INSTEAD.
diff --git a/doc/efun/pg_close b/doc/efun/pg_close
new file mode 100644
index 0000000..af4f8f0
--- /dev/null
+++ b/doc/efun/pg_close
@@ -0,0 +1,19 @@
+OPTIONAL
+SYNOPSIS
+        void pg_close()
+
+DESCRIPTION
+        Close the database connection for the current object, if there is one.
+
+        The function is available only if the driver is compiled with
+        PostgreSQL support. In that case, __PGSQL__ is defined.
+
+        The efun triggers a privilege violation ("pgsql", "pg_close").
+
+HISTORY
+        Added in 3.3.445.
+        LDMud 3.3.640 added the privilege violation.
+
+SEE ALSO
+        pgsql(C), pg_connect(E), pg_conv_string(E), pg_query(E), pg_pending(E),
+        privilege_violation(M)
diff --git a/doc/efun/pg_connect b/doc/efun/pg_connect
new file mode 100644
index 0000000..a9d4d58
--- /dev/null
+++ b/doc/efun/pg_connect
@@ -0,0 +1,39 @@
+OPTIONAL
+SYNOPSIS
+        int pg_connect (string conn, string fun)
+        int pg_connect (string conn, string fun, string|object obj, mixed extra, ...)
+        int pg_connect (string conn, closure cl, mixed extra, ...)
+
+DESCRIPTION
+        Open a database connection as directed by <conn>, and assign the
+        callback function <fun>/<cl> with the optional <extra> parameters
+        to it.
+
+        The object holding the callback function becomes the controlling
+        object; obiously it is an error to assign more than one connection
+        to the same controlling object.
+
+        The <conn> string is in the format accepted by Postgres'
+        PQconnectStart() API functions. Pass an empty string to use the
+        default options, or a string holding the '<key>=<value>' options
+        separated by whitespace.
+        
+        The most useful options are:
+          dbname:   The database name
+          user:     The user name to connect as.
+          password: Password to be used.
+
+        Return 0 on success, and -1 on failure.
+
+        The function is available only if the driver is compiled with
+        PostgreSQL support. In that case, __PGSQL__ is defined.
+
+        The efun triggers a privilege violation ("pgsql", "pg_connect").
+
+HISTORY
+        Added in 3.3.445.
+        LDMud 3.3.640 added the privilege violation.
+
+SEE ALSO
+        pgsql(C), pg_query(E), pg_pending(E), pg_conv_string(E), pg_close(E),
+        privilege_violation(M)
diff --git a/doc/efun/pg_conv_string b/doc/efun/pg_conv_string
new file mode 100644
index 0000000..d849d06
--- /dev/null
+++ b/doc/efun/pg_conv_string
@@ -0,0 +1,20 @@
+OPTIONAL
+SYNOPSIS
+        string pg_conv_string(string str)
+
+DESCRIPTION
+        Convert the string <str> into a string that is correctly interpretated
+        for usage as a string in pg_query(), e.g. ' is replaced with \' and so
+        on.
+
+        The function is available only if the driver is compiled with
+        PostgreSQL support. In that case, __PGSQL__ is defined.
+
+        The efun triggers a privilege violation ("pgsql", "pg_connect").
+
+HISTORY
+        Added in 3.3.708.
+
+SEE ALSO
+        pgsql(C), pg_query(E), pg_pending(E), pg_conv_string(E), pg_close(E),
+        privilege_violation(M)
diff --git a/doc/efun/pg_pending b/doc/efun/pg_pending
new file mode 100644
index 0000000..46a6dcc
--- /dev/null
+++ b/doc/efun/pg_pending
@@ -0,0 +1,22 @@
+OPTIONAL
+SYNOPSIS
+        int pg_pending ()
+        int pg_pending (object obj)
+
+DESCRIPTION
+        Return the number of pending queries for the connection on the given
+        object <obj> (default is the current object). The object has no
+        database connection, return -1.
+
+        The function is available only if the driver is compiled with
+        PostgreSQL support. In that case, __PGSQL__ is defined.
+
+        The efun triggers a privilege violation ("pgsql", "pg_pending").
+
+HISTORY
+        Added in 3.3.445.
+        LDMud 3.3.640 added the privilege violation.
+
+SEE ALSO
+        pgsql(C), pg_connect(E), pg_conv_string(E), pg_query(E), pg_close(E),
+        privilege_violation(M)
diff --git a/doc/efun/pg_query b/doc/efun/pg_query
new file mode 100644
index 0000000..d95f2cc
--- /dev/null
+++ b/doc/efun/pg_query
@@ -0,0 +1,28 @@
+OPTIONAL
+SYNOPSIS
+        #include <pgsql.h>
+
+        int pg_query (string query)
+        int pg_query (string query, int flags)
+
+DESCRIPTION
+        Queue a new query <query> to the database connection on the current
+        object. Return the unique id of the query. The query result itself
+        will be passed as argument to the callback function.
+
+        <flags> can be one of these values:
+          PG_RESULT_ARRAY: Pass the query result as array.
+          PG_RESULT_MAP:   Pass the query result as mapping.
+
+        The function is available only if the driver is compiled with
+        PostgreSQL support. In that case, __PGSQL__ is defined.
+
+        The efun triggers a privilege violation ("pgsql", "pg_query").
+
+HISTORY
+        Added in 3.3.445.
+        LDMud 3.3.640 added the privilege violation.
+
+SEE ALSO
+        pgsql(C), pg_connect(E), pg_conv_string(E), pg_pending(E), pg_close(E),
+        privilege_violation(M)
diff --git a/doc/efun/pointerp b/doc/efun/pointerp
new file mode 100644
index 0000000..a6f2c2c
--- /dev/null
+++ b/doc/efun/pointerp
@@ -0,0 +1,9 @@
+SYNOPSIS
+        int pointerp(mixed arg)
+
+BESCHREIBUNG
+        Liefert 1, wenn das Argument ein Feld (Array) ist, ansonsten 0.
+
+SIEHE AUCH
+        closurep(E), floatp(E), mappingp(E), objectp(E), intp(E),
+        referencep(E), stringp(E), symbolp(E), clonep(E)
diff --git a/doc/efun/pow b/doc/efun/pow
new file mode 100644
index 0000000..f0ff586
--- /dev/null
+++ b/doc/efun/pow
@@ -0,0 +1,16 @@
+SYNOPSIS
+        float pow(int|flaot base, int|flaot exp);
+
+BESCHREIBUNG
+        Die Potenzfunktion. Sie liefert das Resultat von "<base> hoch <exp>".
+
+BEISPIEL
+        pow(-2, 3) -> liefert -8.0
+        pow(8, 1.0/3.0) -> liefert 2.0
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7.
+        LDMud 3.2.9. erlaubte neu Integer als Argumente.
+
+SIEHE AUCH
+        exp(E), log(E)
diff --git a/doc/efun/present b/doc/efun/present
new file mode 100644
index 0000000..7b7d8d3
--- /dev/null
+++ b/doc/efun/present
@@ -0,0 +1,84 @@
+SYNOPSIS
+        object present(string str)
+        object present(string str, int n)
+        object present(string str, object env)
+        object present(string str, int n, object env)
+
+        object present(object ob)
+        object present(object ob, object env)
+
+BESCHREIBUNG
+        Wenn ein Objekt mit der Id <str> sich im Inventar oder in der Umgebung
+        von this_object() befindet, wird es zurueck geliefert.
+        
+        Ist das Argument <n> gegeben, wird das n-te Objekt mit Namen <id>
+        zurueck geliefert. Das heisst, der Driver fuehrt fuer alle Objekte
+        im Inventar und in der Umgebung von this_object() die Funktion
+        id(str) aus, bis ein Treffer erzielt wird (wenn ueberhaupt).
+
+        Ist <n> nicht gegeben, aber <str> hat die Form "<id> <n>" , wird
+        ebenfalls das n-te Objekt mit Namen <id> zurueckgeliefert.
+
+        Es ist: id(str) { return str == <name>; }
+
+        <str> kann auch ein Objekt (anstatt einem object_name()) sein, was den
+        Test schneller und einfacher macht.
+
+        Das Argument <env> ist optional. <env> gibt an, wo nach <str> gesucht
+        wird. Nur das Inventory von <env> wird durchsucht, nicht jedoch dessen
+        Umgebung. Oftmals wird fuer <env> this_player() gesetzt.
+
+
+ANMERKUNG
+        Diese efun kann u.U. _sehr_ teuer sein! Bitte schaut euch auf jeden
+        Fall auch die efun present_clone() an und schaut, ob die evtl. das
+        kann, was ihr machen wollt. present_clone() ist erheblich billiger.
+
+        Wenn die efun sowohl in this_object() als auch dessen Umgebung
+        sucht, werden, soweit es die Numerierung betrifft, die beiden
+        Umgebungen zusammenhaengend betrachtet.
+
+BEISPIELE
+        present("chest");
+          --> findet das erste 'chest' Objekt
+
+        present("chest 2");
+          --> findet das zweite 'chest' Objekt
+
+        present("chest 2", 1);
+          --> findet das erste 'chest 2' Objekt
+
+        Wenn sich eine "chest" im this_object() befindet, und zwei
+        ausserhalb:
+          present("chest", 1) -> findet die chest im Objekt
+          present("chest", 2) -> findet die erste chest ausserhalb
+          present("chest", 3) -> findet die zweite chest ausserhalb
+        
+        Wenn ein Objekt die Forum "<id> <n>" in Verbindung mit einem selbst
+        ueber add_action() gesetzten Verb unterstuetzen soll (damit z. B.
+        "oeffne Kiste 3" funktioniert), kann das folgendermassen geloest
+        werden:
+
+            void init() { add_action("oeffne_kiste", "oeffne"); }
+
+            int oeffne_kiste(string str)
+            {
+                if(present(str) != this_object() )
+                {
+                    return 0; /* nicht diese Kiste */
+                    ...
+                }
+            }
+
+HISTORY
+        LDMud 3.2.11/3.3.610 fuehrte die (str, n)-Form ein.
+        LDMud 3.3.713 aenderte die Numerierung wenn sowohl Inventory
+          als auch Umgebung durchsucht werden. In der vorherigen
+          Implementierung wurde eine Numerierung auf beiden Umgebungen
+          einzeln angewandt, was zur Folge hatte, dass niedere Objekte
+          in der aeusseren Umgebung nicht gefunden werden koennten, da
+          sie von den Objekten in Inneren verdeckt wurden.
+
+SIEHE AUCH
+        move_object(E), environment(E), this_object(E), present_clone(E),
+        id(A), init(A)
diff --git a/doc/efun/present_clone b/doc/efun/present_clone
new file mode 100644
index 0000000..cd64488
--- /dev/null
+++ b/doc/efun/present_clone
@@ -0,0 +1,41 @@
+VORLAEUFIG
+SYNOPSIS
+        object present_clone(string str [, object env] );
+        object present_clone(object obj [, object env] );
+
+BESCHREIBUNG
+        Diese Efun durchsucht das Inventar von <env> nach einem Objekt mit
+        einem bestimmten Blueprint . Wird <env> nicht angegeben, wird in
+        this_object() gesucht. Der Blueprint kann entweder mit seinem Namen
+        <str> angegeben werden, oder als Blueprint des Objekts <obj>. Gesucht
+        wird in beiden Faellen aufgrund von load_name().
+        Wird kein passendes Objekt gefunden, liefert die Efun 0 zurueck.
+
+        Fuer Driver im Plain Modus beginnt der Name in jedem Fall mit '/', im
+        Compat Modus nicht.
+
+BEISPIELE
+        Angenommen, das Objekt <env> enthalte die Objekte /items/money#8,
+        /std/weapon#9, /std/weapon#12 und /obj/key in der angegeben
+        Reihenfolge.
+
+        +--------------------------------------------------+---------------+
+        | Funktion                                         | Liefert       |
+        +--------------------------------------------------+---------------+
+        | present_clone("/items/money", env)               | /items/money#8|
+        | present_clone("/std/weapon#12", env)             | /std/weapon#9 |
+        | present_clone(find_object("/items/money#1"), env)| /items/money#8|
+        | present_clone("/obj/key#18", env)                | /obj/key      |
+        +--------------------------------------------------+---------------+
+
+        Fuer Driver im Compat Modus liefert die Funktion keine '/' am Anfang.
+
+AENDERUNGEN
+        Eingefuehrt in 3.2.7.
+
+ANMERKUNG
+        Im Unterschied zu present() sucht present_clone() niemals in der
+        Umgebung von <env>.
+
+SIEHE AUCH
+        load_name(E), present(E)
diff --git a/doc/efun/previous_object b/doc/efun/previous_object
new file mode 100644
index 0000000..6a712ad
--- /dev/null
+++ b/doc/efun/previous_object
@@ -0,0 +1,50 @@
+SYNOPSIS
+        object previous_object();
+        object previous_object(int i);
+
+BESCHREIBUNG
+        Liefert einen Pointer auf das letzte Objekt, das einen Aufruf (mittels
+        call_other(), funcall() etc.) auf das aktuelle Objekt this_object()
+        gemacht hat. Wenn dieses aufrufende Objekt inzwischen zerstoert wurde,
+        liefert previous_object() 0.
+        Bei einem Aufruf einer eigenen Funktion durch ein Objekt bleibt das
+        bisherige previous_object() unveraendert.
+
+        Wird das Argument <i> angegeben, so verfolgt previous_object() den
+        Aufruf <i> Stufen zurueck. Zum Beispiel liefert previous_object(1) das
+        aufrufende Objekt des aufrufenden Objekts. Fuer <i> muss gelten:
+        0 <= i < call_stack_depth(). Ein Wert <i> < 0 liefert das erste
+        aufrufende Object zurueck.
+
+        Es gibt einen wichtigen Spezialfall: in Funktionen, die vom Gamedriver
+        auf Grund eines externen Ereignises aufgerufen wurden (zum Beispiel
+        Kommandi, die mit add_action() definiert wurden), liefert
+        previous_object() this_object(), previous_object(0) hingegen 0.
+
+BEISPIEL
+        int sicherheitscheck()
+        {
+            object prev;
+            if(!(prev=previous_object()));
+            else if(getuid(prev)!=getuid(this_object()));
+            else if(geteuid(prev)!=geteuid(this_object()));
+            else return 1;
+            return 0;
+        }
+        void sensible_funktion()
+        {
+            if(!sicherheitscheck())
+            return;
+            ...
+        }
+
+        Diese Funktion zeigt, wie man ueberpruefen kann, ob der letzte Aufruf
+        einer Funktion im aktuellen Objekt sicher war, oder ob die
+        Verarbeitung abgebrochen werden sollte.
+
+FEHLER
+        Werte von <i> < 0 werden wie <i> == 0 behandelt - dies ist historisch.
+
+SIEHE AUCH
+        call_other(E), this_object(E), this_player(E)
+        caller_stack(E), caller_stack_depth(E), extern_call(E)
\ No newline at end of file
diff --git a/doc/efun/printf b/doc/efun/printf
new file mode 100644
index 0000000..d58233b
--- /dev/null
+++ b/doc/efun/printf
@@ -0,0 +1,9 @@
+SYNOPSIS
+        void printf(string format, ...);
+
+BESCHREIBUNG
+        Eine Mischung aus sprintf() und write(). Gibt void zurueck und den
+        String an den Benutzer aus.
+
+SIEHE AUCH
+        sprintf(E), write(E), terminal_colour(E)
diff --git a/doc/efun/program_name b/doc/efun/program_name
new file mode 100644
index 0000000..44162d5
--- /dev/null
+++ b/doc/efun/program_name
@@ -0,0 +1,38 @@
+SYNOPSIS
+        string program_name()
+        string program_name(object obj)
+
+BESCHREIBUNG
+        Liefert den Name des Programms, aus dem <obj> kompiliert wurde.
+        Wenn <obj> nicht angegeben wird, wird standardmaessig this_object()
+        verwendet.
+
+        Der Name ist fuer Clones der Name des Files, aus dem der Blueprint
+        kompliert wurde. Der Name wechselt, wenn ein Objekt sein Programm
+        durch replace_program() aendert.
+
+        Fuer den Spezialfall, dass <obj> als 0 uebergeben wird, liefert
+        program_name() 0 zurueck.
+
+        Der Name endet immer mit '.c'. Er beginnt mit einem '/', wenn der
+        Driver sich nicht im Compat Modus befindet.
+
+BEISPIEL
+        object o;
+        o = clone_object("/std/dings");
+        write(program_name(o));
+
+        liefert:
+        --> "/std/dings.c", wenn der Driver nicht im Compat Modus laeuft.
+        --> "std/dings.c", wenn der Driver im Compat Modus laeuft.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6.
+        Seit 3.2.9 ist das Argument 0 erlaubt.
+
+ANMERKUNG
+        Die Efun swapt zum Programm, wenn dieses geswapt ist.
+
+SIEHE AUCH
+        clone_object(E), clonep(E), load_name(E), load_object(E),
+        object_name(E), replace_program(E)
diff --git a/doc/efun/program_time b/doc/efun/program_time
new file mode 100644
index 0000000..62a6297
--- /dev/null
+++ b/doc/efun/program_time
@@ -0,0 +1,17 @@
+SYNOPSIS
+        int program_time()
+        int program_time(object ob)
+
+DESCRIPTION
+        Returns the creation (compilation) time of the object's
+        program. In other words, this is the object_time() of
+        the blueprint.
+
+        Default is this_object(), if no arg is given.
+
+	
+        CAVEAT: If the objects program is swapped out, this efun
+          swaps it back in.
+
+SEE ALSO
+        object_time(E), program_name(E)
diff --git a/doc/efun/query_actions b/doc/efun/query_actions
new file mode 100644
index 0000000..90acaba
--- /dev/null
+++ b/doc/efun/query_actions
@@ -0,0 +1,37 @@
+SYNOPSIS
+        #include <sys/commands.h>
+
+        mixed *query_actions(object|string ob, mixed mask_or_verb);
+
+BESCHREIBUNG
+        Das erste Argument von query_actions() ist entweder ein Objekt
+        oder der Dateiname eines Objekts. Das zweite Argument muss
+        entweder eine Bitmaske (ein Integer) oder ein String sein.
+
+        Ist das zweite Argument ein String, liefert query_actions() ein
+        Array mit Informationen ueber das Verb oder 0 zurueck, wenn
+        das lebendige Objekt <ob> das Verb nicht verwenden kann.
+
+        Wenn das zweite Argument ein Integer ist, liefert query_actions()
+        ein flaches Array mir den Informationen entsprechend der Bitmaske
+        zu allen Verben von <ob>.
+
+            QA_VERB         ( 1):   das Verb,
+            QA_TYPE         ( 2):   der Typ,
+            QA_SHORT_VERB   ( 4):   das short_verb,
+            QA_OBJECT       ( 8):   das Objekt,
+            QA_FUNCTION     (16):   die Funktion.
+
+        Der Typ ist ein Wert wie in <sent.h> (bzw. /sys/sent.h) definiert,
+        der vom Parser Quellcode geliefert wird.
+
+            SENT_PLAIN       durch add_action(fun, cmd) hinzugefuegt
+            SENT_SHORT_VERB  durch add_action(fun, cmd, 1) hinzugefuegt
+            SENT_NO_SPACE    durch add_action(fun); add_xverb(cmd);
+            SENT_NO_VERB     nur eine Funktion mit add_action(fun), ohne Verb
+            SENT_MARKER      intern, ist nicht im Array enthalten
+            negativer Wert   das Verb muss nur in den ersten -<wert> Zeichen
+                             uebereinstimmen.
+
+SIEHE AUCH
+        add_action(E), init(A)
diff --git a/doc/efun/query_command b/doc/efun/query_command
new file mode 100644
index 0000000..bbabdbd
--- /dev/null
+++ b/doc/efun/query_command
@@ -0,0 +1,34 @@
+SYNOPSIS
+        string query_command();
+
+BESCHREIBUNG
+        Liefert den Text des aktuellen Kommandos oder 0, wenn keines
+        ausgefuehrt wird.
+
+        Der Text entspricht dem, was der Parser "sieht", also nachdem
+        modify_command() ausgefuehrt und nachfolgende Leerzeichen
+        abgeschnitten wurden.
+
+        query_command() liefert 0, wenn es von einer Funktion gestartet wurde,
+        die wiederum von einem call_out() oder dem heart_beat() aufgerufen
+        wurde. Auch Kommandi, die beim Userlogin aufgerufen werden, liefern 0.
+
+BEISPIEL
+        void init()
+        {
+            ...
+            add_action("sing","sing");
+            ...
+        }
+
+        int sing(string str)
+        {
+            write("Dein Kommando war:"+query_command()+"\n");
+            return 1;
+        }
+
+        Jedesmal, wenn jemand "sing blafasel" eingibt, liefert das Programm
+        "Dein Kommando war: sing blafasel".
+
+SIEHE AUCH
+        add_action(E), query_verb(E)
diff --git a/doc/efun/query_notify_fail b/doc/efun/query_notify_fail
new file mode 100644
index 0000000..3d98423
--- /dev/null
+++ b/doc/efun/query_notify_fail
@@ -0,0 +1,21 @@
+SYNOPSIS
+        mixed query_notify_fail();
+        mixed query_notify_fail(int flag);
+
+BESCHREIBUNG
+        Wenn <flag> nicht angegeben oder 0 ist, liefert die Funktion den String
+        oder die Closure, die zuletzt als Fehlermeldung fuer ein Kommando
+        gesetzt wurde (mit notify_fail()).
+
+        Wurde keine Meldung gesetzt, wird 0 geliefert.
+
+        Ist <flag> != 0 wird das Objekt zurueckgeliefert, was das letzte
+        Notify-Fail gesetzt hat.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7.
+        LDMud 3.2.8 fuegte den Paramter <flag> hinzu.
+
+SIEHE AUCH
+        add_action(E), query_verb(E), query_command(E), notify_fail(E),
+        hooks(C)
diff --git a/doc/efun/query_verb b/doc/efun/query_verb
new file mode 100644
index 0000000..f216591
--- /dev/null
+++ b/doc/efun/query_verb
@@ -0,0 +1,53 @@
+SYNOPSIS
+        string query_verb();
+        string query_verb(int flag);
+
+BESCHREIBUNG
+        Liefert das Verb des aktuellen Kommandos oder 0, wenn kein Kommando
+        bearbeitet wird.
+
+        Wenn <flag> nicht angegeben oder 0 ist, wird das Verb wie vom User
+        eingegeben geliefert (das ist das erste Wort der Inputzeile des
+        Spielers, bis zum (aber ohne) den ersten Leerschlag / Zeilenumbruch).
+        Wenn <flag> nicht 0 ist, wird das Verb entsprechend der add_action()
+        zurueck gegeben.
+
+        Innerhalb einer add_action()-Funktion, die von mehreren Kommandos
+        aufgerufen wird kann man so zwischen diesen Kommandos unterscheiden.
+
+BEMERKUNGEN
+        Die fruehere Einschraenkung, dass bei geschachtelten Kommandos
+        query-verb() nach dem inneren Kommando 0 zurueck gibt ist jetzt
+        entfallen.
+
+BEISPIEL
+        void init()
+        {
+            ...
+            add_action("sing","singe");
+            add_action("sing","jodel", 1);
+            ...
+        }
+
+        int sing(string str)
+        {
+            write("Das Kommando war:"+query_verb()+(str ? str : "")+"\n");
+            write("Das Verb war:"+query_verb(1)+(str ? str : "")+"\n");
+        }
+
+        Das Kommando "sing blafasel" liefert:
+            Das Kommando war: sing
+            Das Verb war: sing
+
+        Das Kommando "jodel blafasel" liefert:
+            Das Kommando war: jodel
+            Das Verb war: jodel
+
+        Das Kommando "jodele blafasel" liefert:
+            Das Kommando war: jodele
+            Das Verb war: jodel
+
+SIEHE AUCH
+        query_command(E), add_action(E), AddCmd(L), AddAction(L)
+
+7.Aug 2007 Gloinson
\ No newline at end of file
diff --git a/doc/efun/quote b/doc/efun/quote
new file mode 100644
index 0000000..ce01fd7
--- /dev/null
+++ b/doc/efun/quote
@@ -0,0 +1,13 @@
+SYNOPSIS
+        mixed quote(mixed arg);
+
+BESCHREIBUNG
+        Konvertiert ein Array zu einem quoted Array und Strings zu Symbolen.
+        Symbole und quoted Arrays werden erneut gequoted.
+
+BEISPIEL
+        quote("foo") -> 'foo
+        quote(({1,2,3})) -> '({1,2,3})
+
+SIEHE AUCH
+        sympolp(E), unquote(E)
diff --git a/doc/efun/raise_error b/doc/efun/raise_error
new file mode 100644
index 0000000..40ac234
--- /dev/null
+++ b/doc/efun/raise_error
@@ -0,0 +1,23 @@
+SYNOPSIS
+        void raise_error(string arg);
+
+BESCHREIBUNG
+        Bricht die Ausfuehrung des laufenden Programms ab. Wenn das Programm
+        durch catch() aufgerufen wurde, liefert dieses catch() <arg> als
+        Fehlercode, sonst wird <arg> als Fehlermeldung ausgegeben.
+
+        raise_error() gleicht in der Funktion throw(), aber waehrend throw()
+        aus catch() heraus aufgerufen werden soll, kann raise_error() von
+        ueberall her aufgerufen werden.
+
+        Da raise_error() sich wie andere 'echte' Laufzeitfehler verhaelt,
+        einschliesslich der Erzeugung eines Stack Backtraces, ist diese
+        Funktion sehr zeitintensiv.
+
+BEMERKUNGEN
+        Der String sollte umgebrochen oder wenigstens mit einem \n terminiert
+	werden, da die Ausgabe direkt an den interaktiven Magier erfolgen
+	kann bzw. auf dem Debug-Kanal das letzte Zeichen entfernt wird.
+
+SIEHE AUCH
+        catch(E), throw(E)
diff --git a/doc/efun/random b/doc/efun/random
new file mode 100644
index 0000000..a98542b
--- /dev/null
+++ b/doc/efun/random
@@ -0,0 +1,42 @@
+FUNKTION:
+        int random(int n)
+
+ARGUMENTE:
+        n: Zahlen-Bereich aus dem gewaehlt werden soll.
+
+BESCHREIBUNG:
+        Gibt eine zufaellige Zahl im Bereich von 0..(n-1) zurueck.
+
+BEMERKUNGEN:
+        Der Nachteil der Zufaelligkeit (ueber grosse Zahlen) ist, dass wenn
+        viele Zahlen in einem kleinen Bereich in kurzer Zeit generiert
+        werden, einige Zahlen sehr viel haeufiger auftreten als andere.
+
+        Es sei nochmal darauf hingewiesen, dass der Bereich immer bei 0 
+        und NICHT bei 1 anfaengt. Ein random(10) geht also nicht von 
+        1..10 sondern von 0..9!
+
+BEISPIELE:
+        // Einfache Abfrage z.B. aus der HitFunc einer Waffe:
+
+        if(random(101) >= 70) return random(11);
+        else                  return 0;
+
+        // Spieler soll in einen zufaellig ausgewaehlten Raum gemovt
+        // werden: 
+
+        string *dest = ({ "raum1","raum2","raum3","raum4","raum5" });
+        this_player()->move(dest[random(sizeof(dest))],M_GO|M_NOCHECK);
+
+        // Es soll eine zufaellige Meldung ausgegeben werden:
+
+        tell_object(this_player(),
+         ({ "Es knackt.\n", "Dir ist kalt.\n", "Du schwitzt.\n",
+            "Du bekommst Angst.\n", "Hinter Dir knackt es im Gebuesch.\n",
+            "Ein kuehler Wind kommt auf.\n" })[random(6)]);
+
+        Wie man sieht, gibt es fuer random() viele schoene Einsatz-
+        moeglichkeiten. Wobei letzteres Beispiel ueber AddRoomMessage
+        (fuer Raeume) viel einfacher umzusetzen ist.
+
+7.Aug 2007 Gloinson
diff --git a/doc/efun/read_bytes b/doc/efun/read_bytes
new file mode 100644
index 0000000..95cabbd
--- /dev/null
+++ b/doc/efun/read_bytes
@@ -0,0 +1,19 @@
+SYNOPSIS
+        string read_bytes(string file, int start, int anzahl)
+
+BESCHREIBUNG
+        Liest eine bestimmte Anzahl Bytes aus dem File <file>. Wenn <start>
+        nicht angegeben oder 0 ist, wird das File von Beginn weg gelesen,
+        sonst vom Byte mit der Nummer <start>. Wenn <start> negativ ist,
+        werden die Bytes vom Ende des Files her gezaehlt. <anzahl> ist die
+        Anzahl Bytes, die gelesen werden sollen. Werte von 0 oder negative
+        Werte sind zwar moeglich, aber wenig sinnvoll.
+
+        Wenn <start> ausserhalb der Groesse des Files liegt, liefert
+        read_byte() anstelle eines Strings 0 zurueck.
+
+        Die max. Anzahl einzulesender Bytes pro Aufruf dieser Funktion
+        betraegt LIMIT_BYTE (s. query_limits()).
+
+SIEHE AUCH
+        read_file(E), write_bytes(E), write_file(E)
diff --git a/doc/efun/read_file b/doc/efun/read_file
new file mode 100644
index 0000000..7f1ccfc
--- /dev/null
+++ b/doc/efun/read_file
@@ -0,0 +1,19 @@
+SYNOPSIS
+        string read_file(string file, int start, int anzahl)
+
+BESCHREIBUNG
+        Liest Zeilen aus einem File <file>. Wenn <start> angegeben ist und
+        nicht 0, wird von Beginn der Zeile <start> an gelesen; ist <start> 0
+        oder nicht angegeben, wird vom Beginn des Files gelesen.
+
+        Wenn <anzahl> nicht angegeben oder 0 ist, wird das gesamte File
+        gelesen, sonst nur <anzahl> Zeilen.
+
+        Wenn <start> ausserhalb der Groesse des Files liegt, liefert
+        read_file() anstelle eines Strings 0 zurueck.
+
+        Die max. Anzahl einzulesender Bytes (nicht Zeilen!) pro Aufruf dieser
+        Funktion betraegt LIMIT_FILE (s. query_limits()).
+
+SIEHE AUCH
+        read_bytes(E), write_file(E)
diff --git a/doc/efun/referencep b/doc/efun/referencep
new file mode 100644
index 0000000..5c2c0df
--- /dev/null
+++ b/doc/efun/referencep
@@ -0,0 +1,13 @@
+SYNOPSIS
+        int referencep(mixed arg)
+
+BESCHREIBUNG
+        Liefert 1, wenn das Argument an die aktuelle Funktion per Referenz
+        uebergeben wurde, ansonsten 0.
+
+        Man beachte, dass das Argument als Referenz an referencep()
+        uebergeben werden muss, z. B. referencep(&x).
+
+SIEHE AUCH
+        closurep(E), floatp(E), mappingp(E), objectp(E), intp(E),
+        pointerp(E), stringp(E), symbolp(E), clonep(E), references(LPC)
diff --git a/doc/efun/regexp b/doc/efun/regexp
new file mode 100644
index 0000000..354e6a6
--- /dev/null
+++ b/doc/efun/regexp
@@ -0,0 +1,41 @@
+SYNOPSIS
+        #include <regexp.h>
+
+        string *regexp(string *list, string pattern)
+        string *regexp(string *list, string pattern, int opt)
+
+DESCRIPTION
+        Match the pattern <pattern> (interpreted according to <opt> if
+        given) against all strings in list, and return a new array with all
+        strings that matched.
+
+        If there is an error in the regular expression, a runtime
+        error will be raised.
+
+EXAMPLE
+        string strs;
+        string pattern;
+        
+        if (regexp_package() == RE_PCRE)
+            pattern = "\\<help\\>.*\\<me\\>";
+        else
+            pattern = "\\bhelp\\b.*\\bme\\b";
+
+        if (strs = regexp( ({"please, help me Sir John."}),
+                         , pattern
+                         ))
+        {
+           if (sizeof(strs)
+              write("It matches.\n");
+        }
+
+        The regular expression will test the given string (which is
+        packed into an array) if there is something like "help ... me"
+        inside of it.
+
+HISTORY
+        LDMud 3.3 added the optional <opt> argument.
+
+SEE ALSO
+        regexplode(E), regmatch(E), regreplace(E), regexp_package(E), sscanf(E),
+        regexp(C)
diff --git a/doc/efun/regexp_package b/doc/efun/regexp_package
new file mode 100644
index 0000000..8b8d29f
--- /dev/null
+++ b/doc/efun/regexp_package
@@ -0,0 +1,48 @@
+SYNOPSIS
+        #include <regexp.h>
+
+        int regexp_package()
+
+DESCRIPTION
+        Return which regexp package is used by default:
+
+          RE_TRADITIONAL: traditional regexps
+          RE_PCRE:        PCRE
+
+        As the package can be selected at runtime through the
+        REGEXP_PACKAGE driver hook, there is no good way to determine
+        the package at LPC compile time.
+        Match the pattern <pattern> (interpreted according to <opt> if
+        given) against all strings in list, and return a new array with all
+        strings that matched.
+
+        If there is an error in the regular expression, a runtime
+        error will be raised.
+
+EXAMPLE
+        string strs;
+        string pattern;
+        
+        if (regexp_package() == RE_PCRE)
+            pattern = "\\<help\\>.*\\<me\\>";
+        else
+            pattern = "\\bhelp\\b.*\\bme\\b";
+
+        if (strs = regexp( ({"please, help me Sir John."}),
+                         , pattern
+                         ))
+        {
+           if (sizeof(strs)
+              write("It matches.\n");
+        }
+
+        The regular expression will test the given string (which is
+        packed into an array) if there is something like "help ... me"
+        inside of it.
+
+HISTORY
+        Introduced in LDMud 3.3.634.
+
+SEE ALSO
+        regexp(E), regexplode(E), regmatch(E), regreplace(E), sscanf(E),
+        regexp(C), regexp_package(H)
diff --git a/doc/efun/regexplode b/doc/efun/regexplode
new file mode 100644
index 0000000..595e9df
--- /dev/null
+++ b/doc/efun/regexplode
@@ -0,0 +1,28 @@
+SYNOPSIS
+        #include <regexp.h>
+
+        string *regexplode (string text, string pattern)
+        string *regexplode (string text, string pattern, int opt)
+
+DESCRIPTION
+        This function is similar to explode but accepts a regular
+        expression <pattern> as delimiter (interpreted according to <opt>
+        if given).
+
+        If flag RE_OMIT_DELIM is not set in <opt>, then every second element
+        in the result vector will be the text that matched the delimiter.
+        If the flag is set, then the result vector will contain only
+        the text between the delimiters.
+
+EXAMPLES
+        regexplode("abcdef", "cde")                -> ({ "ab", "cde", "f" })
+        regexplode("abcdef", "cde", RE_OMIT_DELIM) -> ({ "ab", "f" })
+
+HISTORY
+        Introduced in 3.2@61
+        LDMud 3.3 added the optional <opt> argument and the RE_OMIT_DELIM
+          flag.
+
+SEE ALSO
+        explode(E), regexp(E), regmatch(E), regreplace(E),
+        regexp_package(E), regexp(C)
diff --git a/doc/efun/regmatch b/doc/efun/regmatch
new file mode 100644
index 0000000..dbb73f5
--- /dev/null
+++ b/doc/efun/regmatch
@@ -0,0 +1,46 @@
+SYNOPSIS
+        #include <regexp.h>
+
+        string  regmatch (string text, string pattern)
+        string  regmatch (string text, string pattern, int opt)
+        string  regmatch (string text, string pattern, int opt, int start)
+        string *regmatch (string text, string pattern, int opt)
+        string *regmatch (string text, string pattern, int opt, int start)
+
+DESCRIPTION
+        Match the string <txt> against <pattern> (interpreted according
+        to <opt> if given). If <start> is given, it is the start
+        position for the match and must be in the range [0..strlen(text)].
+
+        If there is no match, the result is 0. If there is a match, the exact
+        result is determined by the flag RE_MATCH_SUBS:
+
+        If the flag RE_MATCH_SUBS is not set, the result is the matched
+        expression.
+
+        If the flag RE_MATCH_SUBS is set, the result is an array of the
+        matched string(s) of the first match. Entry [0] is the full string
+        matching the <pattern>, following entries are the string segments
+        matching parenthesized subexpressions in <pattern>. If a particular
+        subexpression didn't have a match, the corresponding array entry will
+        be 0.
+
+        The last entry in the array will be the new start index in case you
+        want to repeat the match on the remaining parts of the string. This
+        new index is usually equal the length of the match, but at least one
+        higher than the original start index.
+
+EXAMPLE
+        regmatch("abcdefcdf", "cd")    -> "cd"
+        regmatch("abcdefcdf", "cd(e)") -> "cde"
+
+        regmatch("abcdefcdf", "cd", RE_MATCH_SUBS)    -> ({ "cd" })
+        regmatch("abcdefcdf", "cd(e)", RE_MATCH_SUBS) -> ({ "cde", "e" })
+
+HISTORY
+        Introduced in LDMud 3.3.198.
+        Modified in 3.3.214 to return 0 for non-matches, and to take and
+        return a start position.
+
+SEE ALSO
+        regexplode(E), regreplace(E), regexp(E), regexp_package(E), regexp(C)
diff --git a/doc/efun/regreplace b/doc/efun/regreplace
new file mode 100644
index 0000000..d459bb2
--- /dev/null
+++ b/doc/efun/regreplace
@@ -0,0 +1,57 @@
+SYNOPSIS
+     string regreplace(string txt, string pattern,
+                       string|closure replacepattern, int flags)
+
+BESCHREIBUNG
+     Die Funktion durchsucht den String txt nach einem Vorkommen
+     des regulaeren Ausdrucks pattern, und ersetzt ihn durch
+     den String replacepattern. (replacepattern kann auch eine Closure
+     sein. Sie bekommt als argument den passenden Substring und muss
+     den Ersatzstring zurueckliefern.)
+
+     Im replacestring kann man via '&' auf den zum Suchausdruck
+     passenden Teilstring im Original zugreifen. Mit \n (wobei n
+     eine Ganzzahl ist) kann man auf den n-ten Unterausdruck
+     des regulaeren Ausdrucks zugreifen. Um "&" oder "\\1" als
+     Ersetzung zu erreichen, muss "\\&" bzw "\\\\1" verwendet werden.
+
+     Beim Flag bestimmt ein gesetztes Bit 0, dass der Ausdruck so oft
+     wie vorhanden ersetzt wird, sonst nur das erste Auftreten.
+     Bit 1 bestimmt, ob der regulaere Ausdruck 'ed' oder 'sed' kompatibel
+     ist (Bit geloescht) oder 'ex' kompatibel (gesetzt).
+
+     Die Funktion wirkt wie s/pattern/replacepattern/flags in
+     Editoren wie vi oder sed. Sie ist besonders gut geeignet um
+     variable Strings zu ersetzen, im Gegensatz zu regexplode, wo
+     man den String nur nach einem regulaeren Ausdruck zerlegen kann.
+
+BEISPIELE
+     // ersetzt @@wer@@ durch den Namen des Objektes
+     regreplace(str,"@@wer@@",(string)obj->name(WER,2),1)
+
+     // ersetze alle doppelten Leerzeichen durch ein einzelnes
+     regreplace(str, "  *", " ", 1);
+
+     // Sucht nach 'teilt Dir mit: ' und schliesst den nachfolgenden
+     // Text mit <underline> und </underline> ein; bei jedem Auftreten.
+
+     msgin = regreplace(msgin, "teilt Dir mit: (.*)",
+                               "teilt Dir mit: <underline>\\1</underline>",
+                               1);
+
+     // Ersetzt die <underline> html-Tags durch die vt100
+     // Escape-Sequenzen fuer Unterstreichung
+     txt = regreplace(txt, "<underline>", "<ESC>[5m", 1);
+
+     // Ersetzt das Wort HOUSE in Kleinbuchstaben.
+     txt = regreplace(txt, "HOUSE", #'lower_case, 1);
+
+BUGS:
+     I have written that efun. It doesn't have BUGS. By definition.
+     Well, in fact it crashed as I first tried it on running TAPPMud.
+     *sigh*
+     Marcus@TAPPMud
+
+SIEHE AUCH
+     Verwandt: regexp(E), regexplode(E), sscanf(E)
+     Aehnlich: replace_personal(L)
diff --git a/doc/efun/remove_action b/doc/efun/remove_action
new file mode 100644
index 0000000..b939a51
--- /dev/null
+++ b/doc/efun/remove_action
@@ -0,0 +1,21 @@
+SYNOPSIS
+        int remove_action(int|string verb);
+        int remove_action(int|string verb, object obj);
+
+BESCHREIBUNG
+        Wenn <verb> ein String ist: entferne das erste im Objekt <obj> durch
+        add_action() definierte Kommando <verb>. Wenn <obj> nicht
+        angegeben wird, wird standardmaessig this_player() verwendet.
+        Gib 1 zurueck, wenn ein Kommando gefunden und entfernt wurde,
+        sonst 0.
+
+        Wenn <verb> ein Integer ist: wenn verb nicht 0 ist, entferne alle
+        durch das Objekt <obj> definierten Kommandi. Wenn <obj> nicht
+        angegeben wird, wird standardmaessig this_player() verwendet. Gibt
+        die Anzahl der entfernten Kommandi zurueck.
+
+SIEHE AUCH
+     Verwandt:      add_action(E), init(E)
+     Alternativ:	AddAction(L), AddCmd(L)
+
+7.Aug 2007 Gloinson
diff --git a/doc/efun/remove_call_out b/doc/efun/remove_call_out
new file mode 100644
index 0000000..d5a22db
--- /dev/null
+++ b/doc/efun/remove_call_out
@@ -0,0 +1,32 @@
+SYNOPSIS
+        int remove_call_out(string fun);
+        int remove_call_out(closure fun);
+
+BESCHREIBUNG:
+        Entfernt den naechsten laufenden call_out() auf die Funktion <fun>
+        im aktuellen Objekt bzw. den naechsten laufenden call_out() auf die
+        Closure <fun>. Die verbleibende Zeit wird zurueckgeliefert.
+
+        Wenn es keine laufenden call_out()s auf gibt, wird -1 zurueck
+        geliefert.
+
+BEISPIEL
+        Um alle call_out()s auf MeineFunktion() zu entfernen:
+
+        while(remove_call_out("MeineFunktion") != -1);      /* wiederhole */
+
+BUGS
+        Das Entfernen von call_out()s auf Closures funktioniert nur, wenn der
+        exakt gleiche Wert fuer die Closure verwendet wird.
+
+        Das funktioniert:
+            closure cl = symbol_function("main", obj);
+            call_out(cl, 2);
+            remove_call_out(cl);
+
+        Das funktioniert nicht:
+            call_out(symbol_function("main", obj), 2);
+            remove_call_out(symbol_function("main", obj));
+
+SIEHE AUCH
+        call_out(E), call_out_info(E), find_call_out(E)
diff --git a/doc/efun/remove_input_to b/doc/efun/remove_input_to
new file mode 100644
index 0000000..7cd9393
--- /dev/null
+++ b/doc/efun/remove_input_to
@@ -0,0 +1,38 @@
+SYNOPSIS
+        int remove_input_to (object player);
+        int remove_input_to (object player, string fun);
+        int remove_input_to (object player, closure fun);
+        int remove_input_to (object player, object fun);
+        int remove_input_to (object player, object obj, string fun);
+
+BESCHREIBUNG
+        Entfernt ein haengiges input_to() aus dem interaktiven Playerobjekt.
+        Wenn <fun> nicht angegeben ist, wird der zuletzt aufgerufen input_to()
+        entfernt.
+
+        Wurde <fun> angegeben, entfernt remove_input_to das neueste auf <fun>
+        aufgerufene input_to. Je nach der Definition von <fun> wird nach
+        unterschiedlichen Kriterien gesucht:
+          - <fun> ist ein String: gesucht wird nach dem Funktionsnamen
+          - <fun> ist ein Objekt: gesucht wird nach dem Objekt, in dem
+            input_to() aufgerufen wurde
+          - <fun> ist eine Closure: gesucht wird nach der Closure, die
+            input_to() enthaelt
+          - <obj> und <fun> wurden angegeben: es wird nach Objekt und
+            Funktionsname gesucht. Beide muessen uebereinstimmen.
+
+        remove_input_to() liefert 1 bei Erfolg, sonst 0 (es wurde kein
+        input_to() gefunden, das Objekt ist nicht interaktiv oder es gibt
+        kein haengiges input_to() auf dem Objekt).
+
+BEISPIELE
+        Entfernt alle haengigen input_to()s des aktuellen Spielers, falls
+        vorhanden:
+            while(remove_input_to(this_interactive()));
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        input_to(E), find_input_to(E), input_to_info(E),
+        query_input_pending(E)
diff --git a/doc/efun/remove_interactive b/doc/efun/remove_interactive
new file mode 100644
index 0000000..0d6d200
--- /dev/null
+++ b/doc/efun/remove_interactive
@@ -0,0 +1,13 @@
+SYNOPSIS
+        void remove_interactive(object ob)
+
+DESCRIPTION
+        Close the connection to the interactive object ob.
+
+        For the time of the LPC execution, the object is only marked
+        internally as 'about to be closed', meaning that while all
+        output will be redirected to stdout, the actual network connection
+        will continue to exist until the LPC execution ends.
+
+SEE ALSO
+        connect(M), logon(A), disconnect(M)
diff --git a/doc/efun/rename b/doc/efun/rename
new file mode 100644
index 0000000..2f74492
--- /dev/null
+++ b/doc/efun/rename
@@ -0,0 +1,25 @@
+SYNOPSIS
+        int rename(string from, string to);
+
+BESCHREIBUNG
+        Die Efun rename() verschiebt <from> nach <to>. Wenn <from> ein File
+        ist, kann <to> entweder ein andere File oder ein Verzeichnis sein.
+        Wenn <from> ein Verzeichnis ist, muss <to> auch ein Verzeichnis sein.
+        Wenn in diesem Fall <to> existiert und ein Verzeichnis ist, wird
+        <from> in <to> verschoben und behaelt seinen Namen.
+
+        <from> umzubenennen erfordert Schreibrechte auf <from>.
+
+        Unterverzeichnisse (Verzeichnisse in Verzeichnissen) koennen nur auf
+        Maschinen umbenannt werden, die unter System V laufen, d.h. es ist
+        nicht moeglich, diese in ein anderes Verzeichnis zu verschieben. Das
+        Verschieben von Verzeichnissen von einem Filesystem zum andreren ist
+        unter keinem System moeglich.
+
+        Bei Erfolg liefert rename() 0, bei Fehlschlag einen Wert ungleich 0.
+
+BEISPIEL
+        rename("/players/wizard/obj.c", "/players/wizard/newobj.c");
+
+SIEHE AUCH
+        copy_file(E), mkdir(E), rmdir(E), rm(E)
diff --git a/doc/efun/rename_object b/doc/efun/rename_object
new file mode 100644
index 0000000..2d31674
--- /dev/null
+++ b/doc/efun/rename_object
@@ -0,0 +1,10 @@
+SYNOPSIS:
+	void rename_object (object ob, string new_name);
+
+DESCRIPTION:
+	Give the current object a new object_name. Causes a privilege
+	violation. The new name must not contain a # character, except
+	at the end, to avoid confusion with clone numbers.
+
+SEE ALSO:
+	creator(E), object_name(E)
diff --git a/doc/efun/replace_program b/doc/efun/replace_program
new file mode 100644
index 0000000..4812d4e
--- /dev/null
+++ b/doc/efun/replace_program
@@ -0,0 +1,52 @@
+SYNOPSIS
+        void replace_program();
+        void replace_program(string program);
+
+BESCHREIBUNG
+        Ersetzt ein Programm mit dem geerbten Programm (inherit) <program>.
+        Das Argument <program> kann weggelassen werden, wenn nur ein Programm
+        geerbt wird. In diesem Fall waehlt der Treiber automatisch dieses eine
+        geerbte Programm.
+
+        Diese Efun ist nuetzlich, wenn es um Leistung und Speicherverbrauch
+        des Treibers geht. Ein Programm, welches keine zusaetzlichen Variablen
+        oder Funktionen braucht (ausser waehrend der Erstellung), kann
+        replace_program() aufrufen, um die Trefferquote des Treibers auf den
+        Funktionen-Caches zu erhoehen. Dies verringert die Anzahl Programme
+        im System.
+
+        Raeume sind ein gutes Beispiel fuer die Anwendung dieser Funktion, da
+        viele Raeume nur aus einem Inherit und einer Konfigurationsfunktion
+        bestehen. Jedes Objekt kann replace_program() aufrufen, verliert dabei
+        jedoch alle Variablen und Funktionen, die nicht im geerbten Programm
+        definiert sind.
+
+        Wenn replace_program() angewendet wird, werden Shadows vom Objekt
+        entfernt, in dem replace_program() stattfindet. Dies ist so seit
+        3.2@166.
+
+        Es ist nicht moeglich, replace_program() aufzurufen, wenn es an das
+        Objekt gebundene (Lambda-) Closures gibt. Hingegen ist es moeglich,
+        zuerst das Programm des Objekts zu ersetzen und dann Lambdaclosures
+        daran zu binden.
+
+        Das Ersetzen des Programms findet erst statt, wenn das Objekt
+        vollstaendig abgearbeitet wurde, nicht schon beim Aufruf der Funktion
+        replace_program(). Das kann dazu fuehren, dass Closures auf inzwischen
+        verschwundene Lfuns des Objekts referenzieren. Das stellt allerdings
+        kein Problem dar, solange diese Referenzen nicht ausgefuehrt werden.
+
+BEMERKUNGEN
+        Raeume benutzen replace_program automatisch. Es ist nicht sinnvoll
+        oder notwendig, replace_program selbst ohne Konsultaton mit einem
+        Erzmagier einzusetzen!
+
+BUGS
+        Wenn ein ersetzendes Programm virtuell geerbte Variablen enthaelt,
+        muss dieses Programm als erstes geerbt werden. Ohne diese
+        Einschraenkung ueberleben die falschen Variablen den
+        Ersetzungsprozess.
+
+AENDERUNGEN
+        LDMud 3.2.9 liess zu, dass das Argument <program> weggelassen wird,
+        wenn nur ein Inherit existiert.
diff --git a/doc/efun/restore_object b/doc/efun/restore_object
new file mode 100644
index 0000000..fa991d6
--- /dev/null
+++ b/doc/efun/restore_object
@@ -0,0 +1,45 @@
+SYNOPSIS
+        int restore_object(string name);
+        int restore_object(string str);     (VORLAEUFIG)
+
+BESCHREIBUNG
+        Laedt Werte von Variablen fuer das aktuelle Objekt aus der Datei
+        <name> oder direkt aus dem String <str>.
+
+        Um direkt aus einem String Variablen laden zu koennen, muss dieser
+        mit der typischen Zeile "#x:y" beginnen. Strings, die von der Efun
+        save_object() erzeugt wurden, beginnen so.
+
+        Wenn Variablen aus einer Datei geladen werden, kann <name> mit .c
+        enden. Diese Dateiendung wird vom Treiber entfernt. Das Masterobjekt
+        fuegt dem Dateinamen ein .o hinzu. Die Gueltigkeit des Dateinamens
+        wird mit der Funktion check_valid_path() automatisch ueberprueft.
+
+        Die Funktion gibt 1 zurueck, wenn die Variablen erfolgreich geladen
+        wurden und 0, wenn es nichts zu laden gab.
+
+        Variablen mit dem Typenvermerk nosave werden nicht geladen, zum
+        Beispiel nosave int xxx;
+
+        Closures aus Lfuns, Variablne und simul_efuns werden nur geladen,
+        wenn sie gefunden werden. Falls nicht, werden sie mit dem Wert '0'
+        geladen.
+
+        Wenn Vererbung verwendet wird, kann es vorkommen, dass mehrere
+        Variablen mit dem gleichen Namen an unterschiedlichen Orten vorkommen
+        und deshalb in der Speicherdatei mehrmals auftreten. Beim Laden der
+        Variablen werden sie in Reihenfolge ihres Auftretens im Vererbungsbaum
+        geladen. Ein geeignetes Vorgehen ist die Verwendung von Verbose und
+        einzigartigen Namen bei nicht-statischen Variablen. So wird auch das
+        manuelle Lesen oder Editieren des Savefiles einfacher.
+
+AENDERUNGEN
+        Das direkte Laden aus einem String wurde in LDMud 3.2.8 eingefuehrt,
+            wird aber moeglicherweise in Zukunft in eine separate Efun
+            ausgelagert.
+        LDMud 3.2.9 ergaenzte die Funktion um die Moeglichkeit,
+            NonLambda-Closures, Symbole und gequotete Arrays zu laden,
+            indem ein neues Format fuer das Savefile verwendet wird.
+
+SIEHE AUCH
+        save_object(E), restore_value(E), valid_read(M)
diff --git a/doc/efun/restore_value b/doc/efun/restore_value
new file mode 100644
index 0000000..fa44b18
--- /dev/null
+++ b/doc/efun/restore_value
@@ -0,0 +1,17 @@
+SYNOPSIS
+        mixed restore_value(string str);
+
+BESCHREIBUNG
+        Wandelt die String-Entsprechung <str> eines Wertes zurueck in den Wert
+        selbst und gibt diesen Wert zurueck. <str> ist ein String, wie er von
+        save_value() erzeugt wird. Die Spezifikation des Speicherformates
+        '#x:y' ist optional.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.8.
+        Mit LDMud 3.2.9 kam das Laden von Non-Lambda Closures, Symbolen und
+        gequoteten Arrays hinzu, wozu ein neues Format fuer die Speicherdatei
+        verwendet wird.
+
+SIEHE AUCH
+        save_value(E), restore_object(E), save_object(E)
diff --git a/doc/efun/reverse b/doc/efun/reverse
new file mode 100644
index 0000000..90c7890
--- /dev/null
+++ b/doc/efun/reverse
@@ -0,0 +1,31 @@
+SYNOPSIS
+        inti    reverse (int arg)
+        string  reverse (string arg)
+        mixed * reverse (mixed * arg)
+        mixed * reverse (mixed * & arg)
+
+DESCRIPTION
+        Kehrt die Reihenfolge des Inhaltes von Array oder String <arg>
+        um und liefert den neuen Wert als Resultat.
+        Ist <arg> eine Zahl, wird die Reihenfolge der Bits in <arg> umgekehrt.
+
+        Wenn in der Referenz-Variante verwendet, wird das Argumentarray selber
+        invertiert und auch zurueckgegeben.
+
+EXAMPLES
+        reverse (0x306a) - return 0x560c0000
+
+        reverse ("test") - return "tset"
+
+        mixed * a = ({ 1, 2 });
+        reverse(a)  - returns ({ 2, 1 }), a ist unveraendert.
+        reverse(&a) - returns ({ 2, 1 }), a ist nun ({ 2, 1 })
+
+BUGS
+        Referenz-Teilarrays wie reverse(&(a[1..2])) sind nicht unterstuetzt.
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.529.
+        LDMud 3.3.532 fuegte die Bitumkehr von Zahlen ein.
+
+SEE ALSO
diff --git a/doc/efun/rm b/doc/efun/rm
new file mode 100644
index 0000000..d1b59e3
--- /dev/null
+++ b/doc/efun/rm
@@ -0,0 +1,9 @@
+SYNOPSIS
+        int rm(string file);
+
+BESCHREIBUNG
+        Loescht die Datei <file>. Gibt 0 zurueck, wenn etwas nicht geklappt
+        hat, 1 bei Erfolg.
+
+SIEHE AUCH
+        mkdir(E), rmdir(E), rename(E)
diff --git a/doc/efun/rmdir b/doc/efun/rmdir
new file mode 100644
index 0000000..19af329
--- /dev/null
+++ b/doc/efun/rmdir
@@ -0,0 +1,8 @@
+SYNOPSIS
+        int rmdir(string dir);
+
+BESCHREIBUNG
+        Loescht das Verzeichnis <dir>. Liefert 1 bei Erfolg, 0 bei Misserfolg.
+
+SIEHE AUCH
+        mkdir(E), rm(E), rename(E)
diff --git a/doc/efun/rmember b/doc/efun/rmember
new file mode 100644
index 0000000..dc1962c
--- /dev/null
+++ b/doc/efun/rmember
@@ -0,0 +1,20 @@
+SYNOPSIS
+        int rmember(mixed *array, mixed elem [, int start]);
+        int rmember(string str, int elem [, int start]);
+
+BESCHREIBUNG
+        Liefert fuer Arrays und Strings den Index des letzten Auftretens des
+        Arguments <elem> im Array <*array>  bzw. im String <str>. Wenn <elem>
+        nicht gefunden wird, liefert die Funktion -1 zurueck.
+
+        Ist <start> als Zahl >= 0 gegeben, beginnt die Suche ab der
+        angegebenen Position. Eine Startposition groesser als die
+        Laenge des Strings/Arrays liefert stets das Resultat -1.
+
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.10.
+        LDMud 3.3.556 fuegte den <start>-Parameter hinzu.
+
+SIEHE AUCH
+        member(E)
diff --git a/doc/efun/rusage b/doc/efun/rusage
new file mode 100644
index 0000000..8dc2523
--- /dev/null
+++ b/doc/efun/rusage
@@ -0,0 +1,18 @@
+OPTIONAL
+SYNOPSIS
+        int *rusage();
+
+BESCHREIBUNG
+        Liefert ein Array mit Informationen ueber den momentanen
+        Systemzustand; Benutzungsstatistiken, wie sie vom Unix-Kommando
+        getrusage(2) generiert werden, namentlich:
+            utime, stime, maxrss, rus.ru_ixrss, rus.ru_idrss, rus.ru_isrss,
+            rus.ru_minflt, rus.ru_majflt, rus.ru_nswap, rus.ru_inblock,
+            rus.ru_oublock, rus.ru_msgsnd, rus.ru_msgrcv, rus.ru_nsignals,
+            rus.ru_nvcsw, rus.ru_nivcsw
+
+ANMERKUNG
+    Diese Funktion ist optional.
+
+SIEHE AUCH
+        sys/resource.h(Unix)
diff --git a/doc/efun/save_object b/doc/efun/save_object
new file mode 100644
index 0000000..681946b
--- /dev/null
+++ b/doc/efun/save_object
@@ -0,0 +1,54 @@
+SYNOPSIS
+        int save_object(string name [, int format]);
+        string save_object([int format]);
+
+BESCHREIBUNG
+        Codiert die speicherbaren (s.u.) Variablen des aktuellen Objekts in
+        einen String.
+
+        In der ersten Form wir der String in die Datei <name> geschrieben. Eine
+        Endung ".c" in <name> wird entfernt, dafuer kann eine Endung ".o"
+        durch das Masterobjekt angefuegt werden, waehrend der Ueberpruefung
+        durch valid_read(). Die Efun save_object() liefert 0, wenn die
+        Speicherdatei erfolgreich erstellt wurde, sonst eine Zahl ungleich 0,
+        wenn ein nicht schwerwiegendee Fehler aufgetreten ist (die Datei
+        konnte nicht geschrieben werden oder das aktuelle Objekt wurde
+        inzwischen zerstoert).
+
+        In der zweiten Form wird der String direkt zurueck gegeben. Wenn das
+        Objekt zerstoert wurde, wird 0 zurueck gegeben. In beiden Faellen kann
+        durch das optionale Argument <format> das Format der Speicherdatei
+        angegeben werden:
+
+            -1: das normale Format des Treibers (Standard)
+             0: das Originalformat nach Amylaar's LPMud und LDMud <=3.2.8
+             1: LDMud >= 3.2.9: Non-Lambda Closures, Symbole und gequotete
+                Arrays koennen gespeichert werden
+
+        Eine Variable wird als 'speicherbar' betrachtet, wenn sie nicht als
+        'nosave' oder 'static' deklariert ist.
+
+        Bitte beachten, dass diese efun im MG durch eine Sefun ueberschrieben
+        wird und deren Manpage auch lesen!
+
+BEMERKUNGEN:
+        Damit ein Objekt in Verzeichnisse der Region/des Magiers schreiben
+        kann, muss es entsprechende Rechte, also eine gueltige EUID
+        besitzen. Im create() sollte daher ein:
+
+        seteuid(getuid(this_object()));
+
+        stehen.
+
+AENDERUNGEN
+        Seit LDMud 3.2.8 liefert save_object() einen fixen Wert bei Erfolg.
+        Das direkte Abspeichern in einen String wurde in LDMud 3.2.8
+            eingefuehrt, wird aber in Zukunft eventuell in eine separate Efun
+            umgezogen.
+        LDMud 3.2.9 ergaenzte die Funktion um das Speichern von Non-Lambda
+            Closures, Symbolen und gequoteten Arrays. Dazu wurde ein neues
+            Format fuer die Speicherdatei eingefuehrt.
+        LDMud 3.2.10 fuehrte das Argument <format> ein.
+
+SIEHE AUCH
+        restore_object(E), save_value(E), save_object (Sefun)
diff --git a/doc/efun/save_value b/doc/efun/save_value
new file mode 100644
index 0000000..d9e1486
--- /dev/null
+++ b/doc/efun/save_value
@@ -0,0 +1,31 @@
+SYNOPSIS
+        string save_value(mixed wert [, int format]);
+
+BESCHREIBUNG
+        Schreibt <wert> in einen String, der sich mit restore_value()
+        auswerten laesst. Der String wird zurueck gegeben.
+
+        Das optionale Argument <format> bestimmt das Format des Strings:
+
+            -1: das normale Format des Treibers (Standard)
+             0: das Originalformat nach Amylaar's LPMud und LDMud <=3.2.8
+             1: LDMud >= 3.2.9: Non-Lambda Closures, Symbole und gequotete
+                Arrays koennen gespeichert werden
+
+        Der erzeugte String besteht aus zwei Zeilen, die jeweils mit einem
+        Zeilenumbruch enden. Die erste Zeile beschreibt das Format, in dem der
+        Wert gespeichert wird, in der '#x:y'-Schreibweise. Die zweite Zeile
+        stellt den eigentlichen Wert da.
+
+        Das Format zum Schreiben des Wertes in den String entspricht dem von
+        save_object() und restore_object() verwendeten Format.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.8.
+        LDMud 3.2.9. ergaenzte die Funktion um die Moeglichkeit, Non-Lambda
+            Closures, Symbole und gequotete Arrays zu speichern. Dazu wurde
+            ein neues Format fuer den String eingefuehrt.
+        LDMud 3.2.10 fuehrte das Argument <format> ein.
+
+SIEHE AUCH
+        restore_value(E), restore_object(E), save_object(E)
diff --git a/doc/efun/say b/doc/efun/say
new file mode 100644
index 0000000..6f0958f
--- /dev/null
+++ b/doc/efun/say
@@ -0,0 +1,98 @@
+SYNOPSIS
+        void say(string str);
+        void say(string str, object exclude);
+        void say(string str, object *excludes);
+
+        void say(mixed *|mapping|struct|object msg);
+        void say(mixed *|mapping|struct|object msg, object exclude);
+        void say(mixed *|mapping|struct|object msg, object *excludes);
+
+BESCHREIBUNG
+        Es bestehen zwei Hauptanwendungen fuer say():
+
+        Wenn das erste Argument ein String <str> ist, wird er an alle
+        lebendigen Objekte im aktuellen Raum gesendet, ausser zum Objekt,
+        das die Funktion aufgerufen hat.
+
+        Ist die Nachricht ein String, wird der Text an interaktive Objekte
+        direkt ausgegeben, fuer andere Objekte wird die lfun catch_tell()
+        in diesen aufgerufen.
+        Falls ein Lewebesen die Funktion catch_tell() definiert (-> shadow),
+        so wird der Text hier ausgewertet und nicht an den User ausgegeben.
+
+        Wenn das zweite Argument, die Nachricht, kein String ist, wird in
+        allen Lebewesen, die den Text erhalten, catch_msg() anstatt
+        catch_tell() aufgerufen.
+
+        Mit dem Array <*exclude> kann man verhindern, dass die Nachricht an
+        die darin enthaltenen Objekte gesendet wird. Der Sender muss nicht
+        noch einmal aufgefuehrt werden.
+        Das ist sinnvoll, wenn zB eine Spielergruppe Ausloeser einer Meldung
+        ist und diese selbst nicht erhalten soll.
+
+        Das aufrufende Objekt wird nach folgenden Regeln bestimmt:
+          - Wenn say() aus einem lebendigen Objekt aufgerufen wird, gilt
+            dieses als das aufrufende Objekt.
+          - Wenn say() aus einem nicht-lebendigen Objekt als Resultat einer
+            Handlung eines Benutzers aufgerufen wird (das heisst,
+            this_player() ist gueltig), gilt this_player() als aufrufendes
+            Objekt.
+          - In allen anderen Faellen (Aufruf aus reset zB) gilt das Objekt,
+            das say() aufgerufen hat, als aufrufendes Objekt.
+
+BEMERKUNGEN
+        - fuer laengere Meldungen sollte break_string() verwendet werden
+        - wird in einem catch_msg() der Wert von <msg> veraendert, erhalten
+          alle nachfolgenden Objekte das veraenderte <msg> (Referenz!)
+
+        - say(<str>) ist verhaltensgleich zu
+          tell_room(environment(), <str>, ({this_player()||this_object()}))
+
+BEISPIELE
+        // Folgende Aufrufe sind gleich, wenn sie durch ein Spielerkommando
+        // in einem nicht lebendigen Objekt aufgeloest werden:
+
+            say("Hi!\n");
+            say("Hi!\n", this_player());
+
+        // Das folgende Beispiel zeigt, wie say() zusammen mit catch_tell()
+        // funktioniert. Das zweite Objekt darf nicht lebendig sein, damit
+        // write() an den aktuellen Benutzer geht.
+
+        Objekt 1 (living):
+            void catch_tell(string str) {
+                write("Empfangen: "+str+"\n");
+            }
+
+        Objekt 2 (nicht living):
+            void func() {
+                ...
+                say("HiHo!\n");
+                ...
+            }
+
+        // Ein etwas komplexeres Beispiel zeigt das Zusammenspiel von say()
+        // und catch_msg(). Auch hier wird ein nicht-lebendiges Objekt
+        // verwendet, das die Nachricht ausgibt, sodass das 'wer' in
+        // catch_msg() auf den aktuellen Benutzer zeigt.
+
+        Object 1 (living):
+            void catch_msg(mixed *arr, object who) {
+                foreach(mixed element: arr)
+                    tell_object(who, sprintf("%O\n", element));
+            }
+
+        Object 2 (nicht living):
+            void func() {
+                ...
+                say( ({ "Hello", "there!" }) );
+                ...
+            }
+
+SIEHE AUCH
+        Aehnlich:   tell_room(E), write(E), shout(E), tell_object(E),
+                    printf(E)
+        Verwandt:   catch_tell(E), catch_msg(A)
+        Sonstiges:  object_name(E)
+
+7.Aug 2007 Gloinson
\ No newline at end of file
diff --git a/doc/efun/send_erq b/doc/efun/send_erq
new file mode 100644
index 0000000..d3521e1
--- /dev/null
+++ b/doc/efun/send_erq
@@ -0,0 +1,24 @@
+GESCHUETZT
+SYNOPSIS
+        int send_erq(int request, string|int *data, closure callback);
+
+BESCHREIBUNG
+        Eine Anfrage vom Typ <request> (standardmaessig 0) wird mit Inhalt
+        <data> word an den ERQ gesandt. Wenn <callback> angegeben ist,
+        wird diese Closure aufgerufen, wenn eine Antwort vom ERQ eintrifft
+        (ein Status Code), vorausgesetzt die Antwort enthaelt ausreichend
+        Daten, um damit zu arbeiten:
+
+            void <closure>(int *response_data, int len);
+
+        <data> kann entweder ein String oder ein Array von Integers sein,
+        wobei im zweiten Fall die Zahlen als Zeichen interpretiert werden.
+        Die unterschiedlichen Anfragen sind in /sys/erq.h definiert.
+
+        Die Funktion liefert 0 zurueck, wenn das Senden fehlgeschlagen ist,
+        etwas anderes sost.
+
+        Die Funktion verursacht eine Schutzverletzung "erq".
+
+SIEHE AUCH
+        attach_erq_demon(E), erq(C)
diff --git a/doc/efun/send_udp b/doc/efun/send_udp
new file mode 100644
index 0000000..8ad0c33
--- /dev/null
+++ b/doc/efun/send_udp
@@ -0,0 +1,12 @@
+SYNOPSIS:
+	int send_udp(string host, int port, string message)
+
+DESCRIPTION:
+	Sends The message in an UDP packet to the given host and port
+	number. Causes a privilege violation.
+	Returns 1 on success, 0 on failure.
+
+SEE ALSO:
+	receive_udp(M)
+
+29.10.2006 Zesstra
diff --git a/doc/efun/set_auto_include_string b/doc/efun/set_auto_include_string
new file mode 100644
index 0000000..247e50d
--- /dev/null
+++ b/doc/efun/set_auto_include_string
@@ -0,0 +1,19 @@
+DEPRECATED
+SYNOPSIS:
+	void set_auto_include_string(string arg)
+
+DESCRIPTION:
+
+	The arg will be automatically included into every compiled LPC
+	object. This is useful to enforce global definitions, e.g.
+	``#pragma combine_strings'' or ``#pragma strict_types''.  The
+	calling objectneeds to be privileged by the master object.
+
+NOTE:
+  Not available in LDMud 3.3.x
+  Please use the driver hook H_AUTO_INCLUDE in LDMud > 3.2.9
+
+SEE ALSO:
+	privilege_violation(M), pragma(LPC)
+  
+29.10.2006 Zesstra
diff --git a/doc/efun/set_bit b/doc/efun/set_bit
new file mode 100644
index 0000000..847c6b5
--- /dev/null
+++ b/doc/efun/set_bit
@@ -0,0 +1,30 @@
+SYNOPSIS
+        string set_bit(string str, int n);
+
+BESCHREIBUNG
+        Liefert einen neuen String, bei dem das Bit <n> in <str> gesetzt
+        ist. Dabei wird der urspruengliche String <str> nicht veraendert.
+
+        Jedes Zeichen enthaelt 6 Bits. In jedem Zeichen kann deshalb eine
+        Zahl von 0 bis 63 gespeichert werde (2^6=64). Das erste Zeichen
+        ist der Leerschlag " " mit dem Wert 0. Das erste Zeichen im String
+        ist jenes mit den niedrigsten Bits (0-5).
+
+        Der neue String wird automatisch verlaengert, falls noetig.
+
+BEISPIEL
+        string s;
+        s=set_bit("?",5);
+
+        Weil "?" einen Wert von 31 hat, ist das 6. Bit nicht gesetzt. Wird
+        es gesetzt, so ergibt sich "_". Der String s enthaelt nun also "_".
+
+        string s;
+        s=set_bit("78",3);
+        s=set_bit(s,8);
+
+        s enthaelt nun "?<".
+
+SIEHE AUCH
+        clear_bit(E), last_bit(E), next_bit(E), test_bit(E), count_bits(E),
+        and_bits(E), or_bits(E), xor_bits(E), invert_bits(E), copy_bits(E)
diff --git a/doc/efun/set_driver_hook b/doc/efun/set_driver_hook
new file mode 100644
index 0000000..5489120
--- /dev/null
+++ b/doc/efun/set_driver_hook
@@ -0,0 +1,98 @@
+SYNOPSIS
+        void set_driver_hook(int what, closure arg)
+        void set_driver_hook(int what, string arg)
+        void set_driver_hook(int what, string * arg)
+
+DESCRIPTION
+        This privileged efun sets the driver hook 'what' (values are
+        defined in /sys/driver_hook.h) to 'arg'.
+        The exact meanings and types of 'arg' depend of the hook set.
+        To remove a hook, set 'arg' to 0.
+
+        These hooks exist:
+
+        H_MOVE_OBJECT0
+        H_MOVE_OBJECT1
+          arg: unbound lambda
+          Mandatory hooks implementing the move_object() efun.
+
+        H_LOAD_UIDS
+        H_CLONE_UIDS
+          arg: unbound lambda or lfun closure
+          Mandatory hooks to determine the (e)uid of new objects.
+
+        H_CREATE_SUPER
+        H_CREATE_OB
+        H_CREATE_CLONE
+        H_RESET
+        H_CLEAN_UP
+          arg: lambda closure (H_CLEAN_UP also accepts a lfun
+            closure), function name.
+          Optional hooks for creation/reset/clean up-actions.
+
+        H_DEFAULT_METHOD
+          arg: lambda closure, lfun closure, function name.
+          Optional hook for default method implementation.
+
+        H_DEFAULT_PROMPT
+          arg: lambda closure, lfun closure, prompt string.
+          Optional hook for the default command prompt.
+
+        H_PRINT_PROMPT
+          arg: lambda closure, lfun closure, function name.
+          Optional hook to print the command prompt.
+
+        H_MODIFY_COMMAND
+          arg: lambda closure, lfun closure, function name, mapping
+          Optional hook for modifying player commands before the
+          parser sees them.
+
+        H_NOTIFY_FAIL
+          arg: lambda closure, lfun closure, string.
+          Mandatory hook to generate the default message if an entered
+          command couldn't be parsed and no notify_fail() command is
+          in effect.
+
+        H_SEND_NOTIFY_FAIL
+          arg: lambda closure, lfun closure, string.
+          Optional hook to deliver the notify fail message from a failed
+          command.
+
+        H_NO_IPC_SLOT
+          arg: string.
+          Optional hook specifying the 'sorry' messages if logins are
+          rejected due to fullness of the mud.
+
+        H_INCLUDE_DIRS
+          arg: lambda closure, lfun closure, string array.
+          Semi-mandatory hook specifying the directories where <>-type
+          include files are searched.
+
+        H_AUTO_INCLUDE
+          arg: lambda closure, lfun closure, string
+          Optional hook to specify a string to be included before the
+          source of every compiled LPC object.
+
+        H_TELNET_NEG
+          arg: lambda closure, lfun closure, string.
+          Optional hook to specifiy how to perform a single telnet
+          negotiation.
+
+        H_NOECHO
+          arg: lambda closure, lfun closure, string.
+          Optional hook to specifiy how to perform the telnet actions
+          to switch the echo mode (used for e.g. password input_to()s).
+
+        H_ERQ_STOP
+          arg: lambda closure, lfun closure.
+          Optional hook to notify the mudlib about the termination of
+          the erq demon.
+
+        See hooks(C) for a detailed discussion.
+
+HISTORY
+        Introduced in 3.2.1@1 as efun309(), renamed to
+        set_driver_hook() in 3.2.1@13
+
+SEE ALSO
+        hooks(C)
diff --git a/doc/efun/set_environment b/doc/efun/set_environment
new file mode 100644
index 0000000..fe3a969
--- /dev/null
+++ b/doc/efun/set_environment
@@ -0,0 +1,20 @@
+SYNOPSIS
+	void set_environment(object item, object env)
+
+DESCRIPTION
+	The item is moved into its new environment env, which may be 0.
+	This efun is to be used in the move_object() hook, as it does
+	nothing else than moving the item - no calls to init() or such.
+
+	Don't use it in your own objects!
+
+HISTORY
+  Introduced in 3.2.1@1 as 'efun308()', renamed to 'set_environment()'
+                in 3.2.6 and LP "03.02.1@150".
+
+SEE ALSO
+	remove(A), init(A), move_object(E), transfer(E), hooks(C),
+	native(C)
+
+29.10.2006 Zesstra
+
diff --git a/doc/efun/set_extra_wizinfo b/doc/efun/set_extra_wizinfo
new file mode 100644
index 0000000..f0095c9
--- /dev/null
+++ b/doc/efun/set_extra_wizinfo
@@ -0,0 +1,22 @@
+SYNOPSIS
+        void set_extra_wizinfo (object wiz, mixed extra)
+        void set_extra_wizinfo (string wiz, mixed extra)
+        void set_extra_wizinfo (int    wiz, mixed extra)
+
+DESCRIPTION
+        Set the value <extra> as the 'extra' information for the wizlist
+        entry of <wiz>.
+
+        If <wiz> is an object, the entry of its creator (uid) is used.
+        If <wiz> is a string (a creator aka uid), it names the entry
+        to use.
+        If <wiz> is the number 0, the data is set in the default wizlist
+        entry. It can be used to store data for the lifetime of this
+        driver run, like the time of the last reboot.
+
+        The <extra> argument may be any value.
+
+        The function causes a privilege violation.
+
+SEE ALSO
+        get_extra_wizinfo(E), set_extra_wizinfo_size(E), wizlist_info(E)
diff --git a/doc/efun/set_next_reset b/doc/efun/set_next_reset
new file mode 100644
index 0000000..c4cd3b7
--- /dev/null
+++ b/doc/efun/set_next_reset
@@ -0,0 +1,55 @@
+FUNKTION
+     int set_next_reset(int delay)
+
+ARGUMENTE
+     delay - minimale Zeit bis zum naechsten Reset des Objektes
+
+BESCHREIBUNG
+     Mit dieser efun ist es moeglich Einfluss auf das Resetverhalten des
+     Objektes zu nehmen:
+
+     Das Objekt bekommt einen reset()-Aufruf fruehestens in <delay> Sekunden.
+     Bei Angabe eines Wertes <0 wird der reset() für das Objekt abgeschaltet,
+     was fuer Blueprints gelegentlich sinnvoll ist.
+
+     Intern wird in gleichbleibenden Abstaenden (derzeit: in der Regel 2s,
+     kann sich aber auch verzoegern, wenn der Driver viel zu hat, z.B. auf 
+     4s) geprueft ob die Zeit zum zum naechsten reset() abgelaufen ist. 
+     Sollte dies der Fall sein, wird die Funktion reset() im Objekt 
+     aufgerufen.
+
+     Die Funktion gibt die verbleibende Zeit bis zum naechsten Reset
+     zurueck, bevor <delay> gesetzt wurde. Der Wert kann auch negativ
+     sein, wenn der Reset ueberfaellig war.
+
+     Achtung: die tatsaechliche Zeit, wann der Reset im Objekt durchgefuehrt
+     wird, haengt auch davon ab, ob das Objekt nach Ablauf von <delay>
+     verwendet wird.
+
+BEISPIELE
+     // ein Objekt mit verkuerzter reset()-Zeit
+     void create() {
+       ...
+       set_next_reset(15*60);	// ~ 15 Minuten
+       ...
+     }
+
+     void reset() {
+       set_next_reset(900);	// die muss im reset() immer wieder
+       ::reset();           // neu gesetzt werden
+     }
+
+     // ein Objekt, dessen Blueprint keinen reset() bekommen soll
+     void create() {
+       if(!clonep(this_object())) {
+         set_next_reset(-1);
+         return;
+       }
+       ::create();
+       ...
+     }
+
+SIEHE AUCH
+     call_out(E), object_info(E), reset(L), query_next_reset(E)
+
+7.Aug 2007 Gloinson
diff --git a/doc/efun/set_this_object b/doc/efun/set_this_object
new file mode 100644
index 0000000..2afda56
--- /dev/null
+++ b/doc/efun/set_this_object
@@ -0,0 +1,60 @@
+GESCHUETZT
+SYNOPSIS
+        void set_this_object(object objekt-an-stelle-von-originalobjekt);
+
+BESCHREIBUNG
+        Dies ist eine geschuetzte Funktion, die nur vom Master-Objekt und im
+        Simul-Efun-Objekt genutzt werden darf. Bei sonstiger Benutzung
+        erzeugt diese Funktion einen Fehler.
+
+        Die Funktion aendert das Resultat von this_object() in der laufenden
+        Funktion, ebenso das Resultat von previous_object() in Funktionen in
+        anderen Objekten, die einen call_other() Aufruf machen.
+
+        Der Effekt von set_this_object() bleibt bestehen, bis ein externer
+        Funktionsaufruf abgeschlossen ist oder bis zu einem erneuten
+        set_this_object(). Waehrend der Ausfuehrung von Code im Master-Objekt
+        oder im Simul-Efun-Objekt ist set_this_object() garantiert, auch wenn
+        this_object() durch set_this_object() veraendert wird. Die gilt
+        nicht fuer Funktionen, die aus anderen Programmen inheritet werden.
+
+        Diese Funktion darf nur mit hoechster Sorgfalt verwendet werden, um
+        Inkonsistenzen zu vermeiden. Nach einem Aufruf von set_this_object()
+        koennen sich gewisse LPC-Konstrukte merkwuerdig verhalten oder gar
+        das System zum Absturz bringen. Insbesondere die Verwendung von
+        globalen Variablen oder der Aufruf von lokalen Funktionen (ausser
+        durch call_other()) ist unzulaessig und wird aktiv verhindert.
+
+        Erlaubt sind call_other(), map(), der Zugriff auf lokale Variablen
+        (die auch Pointer auf globale Arrays enthalten duerfen), einfache
+        Arithmetik und der Zuweisungs-Operator.
+
+BUGS
+        Es ist momentan nicht moeglich, das originale gueltige Objekt wieder
+        herzustellen. Anstelle von:
+
+            object ich = this_object();
+            set_this_object(dings);
+            <irgendwelcher Code>
+            set_this_object(ich);
+            <mehr Code>
+
+        muss das ueber einen Umweg geloest werden:
+
+            private void tuwas(object dings)
+            {
+                set_this_object(dings);
+                <irgendwelcher code>
+            }
+
+            funcall(#'tuwas, dings);
+            <mehr Code>
+
+        Manche Leute bezeichnen das als Feature.
+
+AENDERUNGEN
+        LDMud 3.2.10 verhindert aktiv die Referenz auf globale Variablen und
+            Funktionsaufrufe nach Adresse, waehren set_this_object() gilt.
+
+SIEHE AUCH
+        this_object(E), set_this_player(E)
diff --git a/doc/efun/set_this_player b/doc/efun/set_this_player
new file mode 100644
index 0000000..085c529
--- /dev/null
+++ b/doc/efun/set_this_player
@@ -0,0 +1,31 @@
+GESCHUETZT
+SYNOPSIS
+        void set_this_player(object ob);
+
+BESCHREIBUNG
+        Aendert den momentanen Kommandogeber zu <ob>. Dabei kann <ob> auch
+        0 sein, wenn der aktuelle Kommandogeber 'deaktiviert' werden soll.
+
+        Diese Funktion ist nicht geschuetzt und sollte deshalb von einer
+        simul_efun ueberlagert werden, die die Efun entweder komplett
+        abschaltet, oder mindestens gewisse Sicherheitschecks durchfuehrt.
+        Es ist sonst einfach, die Sicherheit eines Muds mit Hilfe dieser
+        Efun zu untergraben.
+
+        Die Efun ist nur in 3.2.1 verfuegbar. Eine moegliche Simulation fuer
+        3.2 koennte etwa so aussehen:
+
+            void set_this_player(object ob)
+            {
+                /* Insert your privilege checks here */
+                if (living(ob))
+                    funcall(bind_lambda(#'enable_commands, ob));
+            }
+            (suggested by Mark Lewis (Nostradamus@Zebedee))
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.1.
+        LDMud 3.2.6 fuehrte die 0 als moeglichen Parameter ein.
+
+SIEHE AUCH
+        set_this_object(E), this_player(E)
diff --git a/doc/efun/seteuid b/doc/efun/seteuid
new file mode 100644
index 0000000..5c2793a
--- /dev/null
+++ b/doc/efun/seteuid
@@ -0,0 +1,17 @@
+SYNOPSIS
+        int seteuid(string str);
+
+BESCHREIBUNG
+        Setzt die effektive UID auf <str>. Das aufrufende Objekt muss dazu
+        vom Masterobjekt berechtigt sein. In den meisten Installationen
+        kann die effektive UID jederzeit auf die momentane UID des Objekts,
+        auf die UID des Erschaffers des Objekts oder auf 0 gesetzt werden.
+
+        Nur wenn dieser Wert 0 ist, kann die UID des Objekts durch
+        export_uid() veraendert werden.
+
+        Unter strikten eUID Regeln koennen Objekte mit UID 0 keine anderen
+        Objekte laden oder clonen.
+
+SIEHE AUCH
+        export_uid(E), getuid(E), getuuid(E), geteuid(E), native(C)
diff --git a/doc/efun/sgn b/doc/efun/sgn
new file mode 100644
index 0000000..2331c0d
--- /dev/null
+++ b/doc/efun/sgn
@@ -0,0 +1,17 @@
+SYNOPSIS
+        int sgn (int|float arg)
+
+BESCHREIBUNG
+        Liefert das Vorzeichen des Argumentes.
+
+        arg  sgn(arg)
+        --------------
+        > 0   1
+          0   0
+        < 0  -1
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        abs(E)
diff --git a/doc/efun/shutdown b/doc/efun/shutdown
new file mode 100644
index 0000000..46ef0af
--- /dev/null
+++ b/doc/efun/shutdown
@@ -0,0 +1,18 @@
+SYNOPSIS
+        void shutdown();
+        void shutdown(int exit_code);
+
+BESCHREIBUNG
+        Faehrt das Mud herunter. Diese Funktion darf nie verwendet werden!
+        Wenn das Mud heruntergefahren werden muss, so hat dies ueber den
+        Shutdownbefehl zu erfolgen.
+
+        Ist ein <exit_code> Argument gegeben, wird sein Wert als der
+        Unix-Resultatwert verwendet; andernfalls wird 0 verwendet.
+
+        Man fragt sich nun vielleicht, wozu es dann diese Funktion gibt,
+        wenn man sie nicht verwenden darf. Sorry, das darf hier nicht
+        bekannt gegeben werden. Streng geheim.
+
+SIEHE AUCH
+        break_point(E), swap(E)
diff --git a/doc/efun/sin b/doc/efun/sin
new file mode 100644
index 0000000..6eab7ec
--- /dev/null
+++ b/doc/efun/sin
@@ -0,0 +1,8 @@
+SYNOPSIS
+        float sin(int|float)
+
+BESCHREIBUNG
+        Liefert den Sinus des Argumentes.
+
+SIEHE AUCH
+        asin(E), cos(E), acos(E), tan(E), atan(E), atan2(E)
diff --git a/doc/efun/sizeof b/doc/efun/sizeof
new file mode 100644
index 0000000..b5023b4
--- /dev/null
+++ b/doc/efun/sizeof
@@ -0,0 +1,16 @@
+SYNOPSIS
+        int sizeof(mixed * val);
+        int sizeof(string  val);
+        int sizeof(mapping val);
+
+BESCHREIBUNG
+        Liefert die Anzahl Elemente in einem Array <val>, die Anzahl
+        Zeichen in einem String <val> oder die Anzahl Keys in einem Mapping
+        <val>.
+
+        Als Spezialfall kann <val> auch 0 sein. In diesem Fall liefert die
+        Funktion 0 zurueck.
+
+SIEHE AUCH
+        allocate(E), pointerp(E), mappingp(E), m_allocate(E),
+        widthof(E)
diff --git a/doc/efun/sl_close b/doc/efun/sl_close
new file mode 100644
index 0000000..753948d
--- /dev/null
+++ b/doc/efun/sl_close
@@ -0,0 +1,17 @@
+OPTIONAL
+SYNOPSIS
+        void sl_close()
+
+BESCHREIBUNG
+        Schliesst die SQLite-Datenbank, welche vom aktuellen Objekt
+        geoeffnet wurde.
+
+        Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite-
+        Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __SQLITE__ definiert.
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.713.
+
+SIEHE AUCH
+        sl_open(E), sl_exec(E), sl_insert_id(E)
diff --git a/doc/efun/sl_exec b/doc/efun/sl_exec
new file mode 100644
index 0000000..e8c4a8f
--- /dev/null
+++ b/doc/efun/sl_exec
@@ -0,0 +1,25 @@
+OPTIONAL
+SYNOPSIS
+        mixed* sl_exec(string statement, ...)
+
+BESCHREIBUNG
+        Fuehrt den SQL-Befehl <statement> in der aktuell geoeffneten
+        SQLite-Datenbank aus. Dieser SQL-Befehl kann Wildcards wie '?'
+        nd '?nnn', wobei 'nnn' eine Zahl ist, enthalten. Diese Wildcards
+        koennen als weitere Parameter an sl_exec uebergeben werden.
+        Mit '?nnn' kann direkt die Nummer eines bestimmten Parameters
+        angegeben werden, der erste Parameter hat die Nummer 1.
+
+        Falls der SQL-Befehl Daten zurueckliefert, liefert sl_exec ein
+        Array aus den einzelnen Zeilen (welche wieder Arrays der einzelnen
+        Felder sind) zurueck.
+
+        Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite-
+        Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __SQLITE__ definiert.
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.713.
+
+SIEHE AUCH
+        sl_open(E), sl_insert_id(E), sl_close(E)
diff --git a/doc/efun/sl_insert_id b/doc/efun/sl_insert_id
new file mode 100644
index 0000000..a425cef
--- /dev/null
+++ b/doc/efun/sl_insert_id
@@ -0,0 +1,18 @@
+OPTIONAL
+SYNOPSIS
+        int sl_insert_id()
+
+BESCHREIBUNG
+        Nachdem eine Zeile in eine Tabelle mit einer AUTO_INCREMENT-Spalte
+        eingefuegt wurde, kann man mit dieser Funktion den (neuen) Wert
+        dieses AUTO_INCREMENT-Feldes der eingefuegten Zeile abfragen.
+
+        Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite-
+        Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __SQLITE__ definiert.
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.713.
+
+SIEHE AUCH
+        sl_open(E), sl_exec(E), sl_close(E)
diff --git a/doc/efun/sl_open b/doc/efun/sl_open
new file mode 100644
index 0000000..b54685d
--- /dev/null
+++ b/doc/efun/sl_open
@@ -0,0 +1,20 @@
+OPTIONAL
+SYNOPSIS
+        int sl_open(string filename)
+
+BESCHREIBUNG
+        Oeffnet die Datei <filename> als SQLite-Datenbank. Falls
+        sie noch nicht existiert, wird sie erstellt. Es ist nur
+        eine geoeffnete Datenbank pro Objekt erlaubt. Im Erfolgsfalle
+        liefert diese Funktion 1 zurueck, anderenfalls wird
+        normalerweise ein Fehler ausgeloest.
+
+        Diese Funktion ist nur verfuegbar, wenn der Driver mit SQLite-
+        Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __SQLITE__ definiert.
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.713.
+
+SIEHE AUCH
+        sl_exec(E), sl_insert_id(E), sl_close(E)
diff --git a/doc/efun/snoop b/doc/efun/snoop
new file mode 100644
index 0000000..484b202
--- /dev/null
+++ b/doc/efun/snoop
@@ -0,0 +1,22 @@
+GESCHUETZT
+SYNOPSIS
+        int snoop(object snooper);
+        int snoop(object snooper, object snoopee);
+
+BESCHREIBUNG
+        Beginnt die Beobachtung des Objekts <snoopee> durch <snooper>. Wenn
+        <snoopee> nicht angegeben wird, werden alle Beobachtungen von
+        <snooper> beendet.
+
+        Die Funktion liefert 1 bei Erfolg, -1 wenn eine Schleife entstehen
+        wuerde und 0 fuer alle anderen Fehler.
+
+        Die Beobachtung wird mit dem Master-Objekt auf Gueltigkeit geprueft.
+        Es wird auch ein Fehler verursacht, wenn eine Beobachtung zu einer
+        Rekursion fuehren wuerde.
+
+ANMERKUNG
+        Diese Funktion ist geschuetzt.
+
+SIEHE AUCH
+        query_snoop(E)
diff --git a/doc/efun/sort_array b/doc/efun/sort_array
new file mode 100644
index 0000000..b4a65ca
--- /dev/null
+++ b/doc/efun/sort_array
@@ -0,0 +1,111 @@
+sort_array(E)
+
+FUNKTION:
+     mixed *sort_array(mixed *arr, mixed func [, mixed ob])
+
+PARAMETER:
+     arr  - zu sortierendes Array
+     func - zu rufende Methode; kann als String (Funktionsname) oder 
+            Closure uebergeben werden
+     ob   - Objekt, an dem Methode gerufen werden soll; kann als String
+            (Filename) oder Objektpointer uebergeben werden
+
+BESCHREIBUNG
+     Erzeugt eine (flache) Kopie des Arrays 'arr' und sortiert diese mit der
+     Sortierfunktion 'func'. Die sortierte Kopie wird dann zurueckgegeben.
+
+     Die Elemente des zu sortierenden Arrays werden paarweise an die
+     Sortierfunktion als Argumente uebergeben.
+     Die Sortierfunktion sollte eine Zahl
+     - >0 zurueckgeben, wenn die Elemente in der falschen
+       Reihenfolge sind
+     - <=0 zurueckgeben, wenn die Elemente in der richtigen
+       Reihenfolge sind.
+
+     Verwendung von Methoden:
+       Wenn bei der Angabe von 'func' kein Objekt 'ob' in Form eines Strings
+       oder Objekts angegeben wird, wird this_object() angenommen.
+
+     Verwendung von Closures:
+       Es koennen Lfun-, Lambda- und Inline-Closures verwendet werden. 
+       Lfun-Closures koennen, wenn im selben Objekt vorhanden, auch
+       'private' oder/und 'static' deklariert sein, muessen aber zu dem
+       Zeitpunkt der Verwendung bekannt sein (Funktionsprototypen benutzen).
+       Von der Verwendung von Lambda-Closures wird ausdruecklich abgeraten.
+
+BEMERKUNGEN:
+     (1) sort_array() unterstuetzt keinen extra-Parameter
+
+     (2) Achtung, die Elemente in 'arr' werden nicht tief kopiert, sind sie
+     also selbst Arrays oder Mappings, so fuehrt eine Aenderung im Rueckgabe-
+     Array zur Aenderung im Ursprungsarray:
+
+     int *i, *j;
+     i=({({1}),({2,3}),({4,5,6})});
+     j=sort_array(i,        // sortiert der Groesse nach absteigend
+         function int ( mixed x, mixed y ) {
+           return sizeof(x) < sizeof(y); }
+         );
+     
+     Zu diesem Zeitpunkt ist  i == ({ ({1}),({2,3}),({4,5,6}) })
+                              j == ({ ({4,5,6}),({2,3}),({1}) })
+     
+     Fuehrt man jetzt die Zuweisung j[0][0]=8; aus
+
+     resultieren folgende Arrays: i == ({ ({1}),({2,3}),({8,5,6}) })
+                                  j == ({ ({8,5,6}),({2,3}),({1}) })
+
+BEISPIELE:
+     ### Sortieren von Zahlen in aufsteigender Reihenfolge ###
+     
+     int *arr = ({ 3, 8, 1, 3 })
+
+     // Folgend identische Resultate, aber andere Ansaetze:
+
+     #1: nutzt die 'Efun' > als Lfun-Closure (ideal hier):
+         sort_array(arr, #'>);
+
+     #2: mit Sortierfunktion im selben Objekt:
+         int is_greater (int a, int b) {
+           return a > b;
+         }
+         
+         #2a: sortiert mittels der Lfun im selben Objekt die Elemente in das
+              Rueckgabearray
+              sort_array(arr, "is_greater", this_object())
+              sort_array(arr, "is_greater")
+
+         #2b: nutzt die Lfun is_greater() als Lfun-Closure (Funktionspointer)
+              sort_array(arr, #'is_greater)
+
+     #3: nutzt eine Lambda-Closure (langsamer, nicht fuer alle leserlich)
+         sort_array(arr, lambda(({'a, 'b}), ({#'>, 'a, 'b})))
+
+     #4: analog zu 3, mit Inline-Closure
+         sort_array(arr, function int (int a, int b) {
+           return a > b; } );
+
+     Resultat in allen Faellen: ({1,3,3,8})
+
+     ### Sortieren von geschachtelten Arrays ###
+
+     arr = ({ ({ "foo", 3 }), ({ "quux", 1 }), ... })
+
+     // Vorgehen identisch, allerdings muss die Sortierfunktion
+     // angepasst werden (siehe auch das Beispiel unter Verwendung von
+     // Inline-Closures oben unter "Bemerkungen"):
+     
+     int is_greater (mixed *a, mixed *b) {
+       return a[1] > b[1];
+     }
+
+SIEHE AUCH:
+     Arrays:        filter(E), map(E)
+     Objektarrays:  filter_objects(E), map_objects(E)
+     Mappings:      filter_indices(E), map_indices(E)
+
+     Sonstiges:     unique_array()
+                    alist, transpose_array(E)
+
+----------------------------------------------------------------------------
+Last modified: Mon Feb 18 23:09 2008 by Arathorn
diff --git a/doc/efun/sprintf b/doc/efun/sprintf
new file mode 100644
index 0000000..3cb6970
--- /dev/null
+++ b/doc/efun/sprintf
@@ -0,0 +1,147 @@
+SYNOPSIS

+        string sprintf(string fmt, ...)

+

+BESCHREIBUNG

+        Mit dieser Funktion kann man auf einfache Weise aus dem Inhalt

+        von Variablen einen String bauen; und dies effektiver als

+        mit der ueblichen "Du hast "+anzahl+" Punkt(e)"-Methode.

+

+        Die Funktion bekommt als erstes Argument einen Formatstring fmt,

+        der Informationen darueber enthaelt, wie die weiteren beliebigen

+        Argumente in den Ergebnisstring eingebaut werden sollen.

+        Die meisten Zeichen gelangen vom Formatstring unveraendert in

+        den Ausgabestring. Die Regeln zum Einbau eines Arguments werden

+        immer mit '%' eingeleitet. Moechte man ein '%' in die Ausgabe

+        bringen, so muss man im Formatstring "%%" verwenden.

+

+        Ein einfaches Beispiel ist erg=sprintf("%s %d", str, i);

+        '%' leitet einen Argumentformatstring (AFS) ein. Das 's' schliesst

+        ihn ab und besagt, dass ein String eingebaut werden soll. Das

+        folgende Leerzeichen wird unveraendert uebernommen. '%' leitet

+        wieder einen neuen Formatstring ein, wobei 'd' eine Ganzzahl

+        bezeichnet (eine Variable von Typ int).

+        Dies ist ein allerdings nur ein sehr einfaches Beispiel.

+

+        Jeder Argumentformatstring kennzeichnet also, auf welche Art

+        ein Argument in das Ergebnis eingebaut werden soll. Der erste

+        AFS ist fuer das zweite Argument der Funktion, der zweite AFS

+        fuer das dritte Argument u.s.w. (das erste Argument der Funktion

+        ist ja der Formatstring selbst).

+

+        Jeder AFS beginnt mit einem '%' und endet mit einem der

+        folgenden Zeichen (Argumenttyp-Kennzeichner):

+        Zeichen    Argumenttyp    Bemerkung

+        's'        string

+        'c'        integer        als ASCII-Zeichen

+        'd' 'i'    integer        Dezimalschreibweise

+        'o'        integer        Oktalschreibweise

+        'b' 'B'    integer        Binaerschreibweise

+        'x' 'X'    integer        Hexadezimalschreibweise

+        'e' 'E'    float          Exponentialschreibweise

+        'f' 'F'    float          Gleitkommadarstellung

+        'g' 'G'    float          Gleitkommadarstellung

+        'O'        mixed          Gibt fuer Debugging alles irgendwie

+                                  lesbar aus, auch Arrays und Mappings

+        'Q'        mixed          Wie 'O', gibt jedoch Sonderzeichen in

+                                  Strings in der LPC-Notation aus

+        

+        Zwischen dem '%' und dem Argumenttyp-Kennzeichner kann man

+        noch mehrere Modifikatoren setzen, die das Verhalten

+        beeinflussen.

+        Hier eine Uebersicht. n steht hier fuer eine Ganzzahl, also

+        zum Beispiel "12".

+        Modifikator  Bedeutung

+        n            Minimale Stringlaenge, die fuer dieses Argument

+                     verwendet werden soll. Fehlende Zeichen werden mit

+                     einem Fuellzeichen aufgefuellt. Beginnt n mit einer

+                     '0' (etwa "08") so ist das Fuellzeichen '0' sonst

+                     ist es per Default ' '. (sogenannte 'Feldbreite')

+        .n           Bei Ganzzahlen die Maxanzahl der Stellen, bei Gleit-

+                     kommazahlen die Maximalzahl der Nachkommastellen.

+                     Bei (einfachen) Strings die Maximallaenge.

+        :n           Ist dasselbe wie n.n - setzt also beide Werte auf

+                     dieselbe Zahl.

+        'X'          Als Fuellzeichen wird X genutzt. X koennen dabei

+                     auch mehrere Zeichen sein, etwa fuehrt '-=' zu

+                     Fuellungen der Art "-=-=-=-=". Um mit Hochkommas

+                     zu fuellen ist '\\'' anzugeben. Rueckwaerts-

+                     schraegstrich entsprechend mit '\\\\'.

+        <Space>      Vor positive Zahlen wird ein Leerzeichen gefuegt.

+        +            Vor positive Zahlen wird ein '+' gefuegt.

+        -            Der Wert wird linksbuendig in das fuer dieses Argument

+                     vorgesehene Feld eingefuegt (Standard ist rechts-

+                     buendig). Bei Strings wird meistens diese Ausrichtung

+                     die sinnvollste sein.

+        |            Der Wert wird zentriert in das Feld eingefuegt.

+                     (Siehe Modifikator n, Feldbreite)

+        $            Blocksatz. Benoetigt eine Feldbreite, funktioniert nur

+                     bei Strings (auch im Spaltenmodus).

+        =            Spaltenmodus (siehe unten).

+        #            Fuer Strings: Tabellenmodus (siehe unten).

+                     Fuer '%O'/'%Q': kompakte Ausgabe.

+        @            Arraymodus (siehe unten).

+        *            Ein Stern kann immer dort eingesetzt werden, wo

+                     hier weiter oben ein n fuer eine Ganzzahl steht.

+                     Der Wert der Zahl muss dann als weiterer Parameter

+                     an die Funktion uebergeben werden.

+

+BEISPIELE

+        Mit den bis jetzt erwaehnten Moeglichkeiten kann man zB machen:

+

+        sprintf("%d (dec) == %o (octal) == %x (hex)", 20, 20, 20);

+        => "20 (dec) == 24 (octal) == 14 (hex)"

+

+        sprintf("Du drehst den Knopf um %.3f Umdrehungen", 12.3456);

+        => "Du drehst den Knopf um 12.345 Umdrehungen"

+

+        sprintf("Du liest %|'*':9s", "Fiona");

+        => "Du liest **Fiona**"

+

+        sprintf("Auf dem Zettelstueck steht: %-.*s...", 7, "Hallo Du da");

+        => "Auf dem Zettelstueck steht: Hallo D...

+

+ERWEITERTE MODI

+        Mit dem Modifikatoren = # und @ stehen maechtige Werkzeuge zur

+        Verfuegung. Mit ein wenig Ueberlegung kann man sich oft viele

+        Zeilen Code ersparen.

+        Arraymodus (@):

+          sprintf("%@s", arr_of_string);

+          Der Argumentformatstring (allerdings ohne das @) wird sooft

+          hintereinandergereiht, wieviele Elemente das Array hat.

+          Jeder AFS wird dann fuer ein Element des Arrays benutzt.

+          sprintf("%@s", ({"aaa","bbb"})) ist somit dasselbe wie

+          sprintf("%s%s", "aaa", "bbb"). Allerdings passt es sich

+          immer an die Elementzahl der uebergebenden Arrays an.

+          Dies ist nuetzlich um Ergebnisse von map() oder aehnlich

+          auszugeben.

+          sprintf("%@s", map_objects(all_inventory(), "short"));

+          Der Argumenttyp-Kennzeichner muss hierbei immer dem Typen

+          eines Elementes des Arrays entsprechen.

+        Spaltenmodus (=):

+          Diese Funktion bricht Text um. Die Feldbreite muss angegeben

+          werden. Wird neben der Feldbreite auch eine maximale String-

+          laenge angegeben, so wird die letztere fuer die Breite des

+          Umbrechens verwendet, die Feldbreite wird mit Fuellzeichen

+          aufgefuellt.

+          sprintf("%=-20s", str); bricht den String str 'wordwrap'end

+          auf 20 Zeichen Laenge um. sprintf("%=-*s", len, str);

+          ist schon eine einfache break_string() Variante.

+        Tabellenmodus (#):

+          Diese Funktion gibt Strings tabellenartig aus. Die Teilstrings

+          muessen mit \n getrennt als ein String als Argument uebergeben

+          werden. Die Feldbreite muss angegeben werden und bezeichnet

+          die (maximale) Gesamtbreite der Tabelle.

+          Die Anzahl der Spalten der Tabelle wird moeglichst optimal

+          bestimmt, und ist fuer alle Spalten gleich. Wird ein

+          Wert als 'Praezision' angegeben, so ist dies die Anzahl von

+          Spalten, die verwendet werden soll.

+          sprintf("%#30.4s", str) erzeugt eine Tabelle, die maximal

+          30 Zeichen breit ist und 4 Spalten enthaelt.

+          sprintf("%#30s", str) legt die Spaltenzahl dynamisch anhand

+          der Einzelstringlaengen fest, so dass der laengste String

+          noch genau in die Tabelle passt.

+          Wenn string* worte die in die Tabelle einzubettenden Worte

+          enthaelt, so muss str=implode(worte,"\n") sein.

+

+SIEHE AUCH:

+        printf(E)

diff --git a/doc/efun/sqrt b/doc/efun/sqrt
new file mode 100644
index 0000000..44c4805
--- /dev/null
+++ b/doc/efun/sqrt
@@ -0,0 +1,9 @@
+SYNOPSIS
+        float sqrt(int value);
+        float sqrt(floag value);
+
+BESCHREIBUNG
+        Liefert die Quadratwurzel von <value>.
+
+SIEHE AUCH
+        log(E), pow(E)
\ No newline at end of file
diff --git a/doc/efun/sscanf b/doc/efun/sscanf
new file mode 100644
index 0000000..a616bf2
--- /dev/null
+++ b/doc/efun/sscanf
@@ -0,0 +1,115 @@
+FUNKTION:
+ int sscanf(string str,string fmt,mixed var1,mixed var2,...)
+
+ARGUMENTE:
+      str
+        - String, der nach einem Muster zu durchsuchen ist
+        - darf nicht NULL sein
+      fmt
+        - Format-String, nach dessen Muster untersucht wird
+      var1,var2,...
+        - Argumente die mit %d oder %s korrespondieren
+
+RUeCKGABEWERT:
+     Anzahl der gefundenen Argumente.
+
+BESCHREIBUNG:
+     Wertet einen String <str> unter Beruecksichtigung des Formats <fmt>
+     aus. <fmt> kann Strings beinhalten, die durch %d und %s getrennt
+     werden. Jedes %d und %s entspricht einer der Variablen <var1>, <var2>,
+     etc. in die gespeichert werden soll.
+
+     Die Operatoren im Format-String <fmt> haben eines der folgenden
+     Formate:
+
+         %[+][!|~][<size>[.<minmatch>]]<type>
+
+        <type> kann folgendes sein:
+            d: steht fuer eine Zahl
+            D: steht fuer eine Zahl
+            U:
+            s: steht fuer eine Zeichenkette
+            %: steht fuer das %-Zeichen
+            t: steht fuer Whitespaces (also Leerschlaege und Tabulatoren),
+               speichert diese aber nicht.
+
+     <size> ist die erwartete Feldgroesse, <minmatch> die verlangte
+     minimale Laenge fuer einen Treffer (Standardwerte sind 0 fuer
+     Strings und 1 fuer Nummern). Sowohl <size> als auch <minmatch> kann
+     entweder numerisch oder mit '*' angegeben werden - im zweiten Fall
+     wird die gueltige Variable in der Liste der Argumente benutzt.
+
+     Wird + angegeben, muessen die Zeichen nach dem Feld ebenfalls
+     matchen. Ist dies nicht der Fall, wird auch dieses Feld als
+     Misserfolg in der Rueckgabe betrachtet (auch wenn der Wert
+     bereits an die zugehoerige Variable zugewiesen wurde).
+
+     Wird ! angegeben, wird zwar die Suche durchgefuehrt, aber Treffer
+     werden weder gespeichert noch gezaehlt. Mit ~ als Argument wird
+     zwar die Suche durchgefuehrt und die Treffer gezaehlt, das Resultat
+     wird aber nicht gespeichert.
+
+     Wenn ein %s nicht am Ende von <fmt> steht, wird nur ein Treffer
+     registriert, wenn auch der nachfolgende String bzw. das
+     nachfolgende Format gefunden wird. Weiter unten gibt es dazu
+     ein Beispiel.
+     Bei einem %d allerdings muss dieses Verhalten mit einem '+'
+     erzwungen werden.
+
+     Der Unterschied zwischen %d und %D %U ist, dass letzteres ein
+     unmittelbar vorausgehendes %s so bald als moeglich abbricht,
+     waehrend ersteres zuerst versucht, einen moeglichst grossen Treffer
+     fuer %s zu erzielen. Trotzdem ueberspringt %D/%U keine Whitespaces,
+     dazu muss %.0t%D gesetzt werden.
+
+     Die Funktion sscanf() ist insofern ein Spezialfall, als dass
+     Argumente automatisch nach Referenz uebergeben werden.
+
+BEISPIELE:
+     string who, what;
+         if (sscanf("wirf frisbee zu rex",
+                    "wirf %s zu %s", what, who) != 2)
+             write("Usage: Wirf <what> zu <who>\n");
+         else
+             write("Du wirfst einen "+what+" zu "+who+".\n");
+
+     sscanf("ab", "%s%s", who, what)
+     ==> liefert 2, who = "", what = "ab"
+
+     sscanf("ab", "%s %s", who, what)
+     ==> liefert 0, who = 0, what = 0
+
+     sscanf("ab ", "%s %s", who, what)
+     ==> liefert 2, who = "ab", what = ""
+
+
+     // Achtung bei %d
+     sscanf("12 ","%d xyz", num1);
+     ==> liefert 1, num1 = 12
+
+     sscanf("12 ","%s xyz", num1);
+     ==> liefert 0, num1 = 0
+
+     // mit '+' wird das Parsen des Restformats erzwungen:
+     sscanf("12 ","%+d xyz", num1);
+     ==> liefert 0, num1 = 12
+
+
+     // Weiteres Beispiel zu %d:
+     sscanf("get 12 coins","get %d rubys",num)
+     ==> ergibt 1, weil 'rubys' ignoriert wird
+
+     // Beispiel Format-Ignore 2
+     sscanf("get 12 coins","get %+d rubys",num);
+     ==> ergibt 0, da mit dem '+' das Parsen des Restformats erzwungen wird
+     ==> ergibt 1 bei 'get 12 rubys'
+
+     // Beispiel Format-Ignore 3 [alte Variante]
+     sscanf("get 12 coins","get %d rubys%s", num, dummy)
+     ==> ergibt 1
+     ==> ergibt 2 bei "get 12 rubys"
+
+SIEHE AUCH:
+        explode(E), regexp(E)
+
+8.Aug 2007 Gloinson
diff --git a/doc/efun/strftime b/doc/efun/strftime
new file mode 100644
index 0000000..c167afb
--- /dev/null
+++ b/doc/efun/strftime
@@ -0,0 +1,112 @@
+SYNOPSIS
+     string strftime()
+     string strftime(string fmt)
+     string strftime(int clock)
+     string strftime(string fmt, int clock)
+     string strftime(string fmt, int clock, int localized)
+
+BESCHREIBUNG
+     Gibt, aehnliche wie ctime(), eine Zeit als formatierten String zurueck.
+     Hierbei kann ein String mit div. Platzhaltern vom Benutzer angegeben
+     werden (s.u.). Wird kein String angegeben, wird "%c" als Formatstring
+     benutzt.
+
+     Das Argument <clock> wird als Anzahl Sekunden seit dem 01.01.1970, 00:00
+     Uhr interpretiert. Wenn <clock> nicht angegeben wird, wird time()
+     verwendet.
+
+     Das Argument <localized> gibt an, ob die Ausgabe englisch (das sog.
+     klassische "C" locale) oder in der jeweiligen Landessprache (z.B.
+     deutsch) erfolgen soll. Hierbei haengt die Sprache allerdings von den auf
+     dem Mudrechner gesetzten Umgebungsvariablen LC_TIME oder LC_ALL ab, sie
+     kann nicht selber gewaehlt werden. Wird kein <localized> angegeben, wird
+     1 verwendet, was einer Ausgabe in Landessprache entspricht.
+     0: Ausgabe im klassischen "C" locale (english)
+     1: Ausgabe in Landessprache des Mudrechners.
+
+BEMERKUNGEN:
+     Der zurueckgebene Ergebnisstring ist max. 511 Zeichen lang.
+
+PLATZHALTER:
+     Diese Funktion versteht alle Platzhalter, die die Funktion strftime() aus
+     der C-Standardbibliothek versteht. Momentan sind dies:
+       %a     Der abgekuerzte Wochentag abhaengig von der momentanen Locale.
+       %A     Der gesamte Wochentag abhaengig von der momentanen Locale.
+       %b     Der abgekuerzte Monatsname abhaengig von der momentanen Locale.
+       %B     Der volle Monatsname abhaengig von der momentanen Locale.
+       %c     Das bevorzugte Datums- und Uhrzeit-Repraesentation laut Einstel-
+              lungen der momentanen Locale.
+       %C     Das Jahrhundert als zweistellige Zahl.
+       %d     Der Tag im Monat als Dezimalzahl (01 - 31).
+       %D     Aequivalent  zu %m/%d/%y.  (US-amerikanisches Format.  In anderen
+              Laendern ist %d/%m/%y durchaus ueblich . In internationalem Kon- 
+              text ist dieses Format daher mehrdeutig und sollte nicht verwen-
+              det werden.)
+       %e     Wie %d, der Tag im Monat als Dezimalzahl, aber eine fuehrende
+              Null ist durch ein Leerzeichen ersetzt.
+       %E     Modifikator: Alternatives Format benutzen, s.u.
+       %g     Wie  %G,  aber ohne das Jahrhundert, also mit zweistelligem Jahr
+              (00-99).
+       %G     Das Jahr laut ISO 8601 mit dem Jahrhundert als Dezimalzahl.  Das
+              vierstellige Jahr, das zu ISO-Wochennummer (siehe %V) passt.  Es
+              hat dasselbe Format und denselben Wert wie %y,  nur  dass,  wenn
+              die  ISO-Wochennummer  zum  vorhergehenden  oder  naechsten  Jahr
+              gehoert, dieses Jahr stattdessen benutzt wird.
+       %h     Aequivalent zu %b.
+       %H     Die Stunde im 24h-Format als Ganzzahl (00 - 23).
+       %I     Die Stunde im 12h-Format als Ganzzahl (01 - 12).
+       %j     Der Tag im Jahr als Ganzzahl (001 - 366).
+       %k     Die Stunde im 24h-Format als Ganzzahl (0 - 23); einzelne Ziffern
+              haben ein vorangestelltes Leerzeichen. (Siehe %H.)
+       %l     Die Stunde im 12h-Format als Ganzzahl (0 - 12); einzelne Ziffern
+              haben ein vorangestelltes Leerzeichen. (Siehe %I.)
+       %m     Der Monat als Ganzzahl (01 - 12).
+       %M     Die Minute als Ganzzahl (00 - 59).
+       %n     Ein Zeilenvorschub.
+       %p     Entweder 'AM' oder 'PM', je nach der uebergebenen  Uhrzeit,  oder
+              die  zugehoerigen Zeichenketten in der momentanen Locale.  Mittag
+              erhaelt 'PM', Mitternacht 'AM'.
+       %P     Wie %p, aber in Kleinbuchstaben.
+       %r     Zeit in AM/PM-Notation; in der POSIX-Locale ist das Aequivalent
+              zu '%I:%M:%S %p'.
+       %R     Zeit in 24h-Notation (%H:%M). (SU) Fuer eine Version mit Sekunden
+              siehe %T.
+       %s     Die Zahl der Sekunden seit  der  Epoche,  also  seit  1970-01-01
+              00:00:00 UTC.
+       %S     Die Sekunde als Ganzzahl (00 - 61).
+       %t     Ein Tabulatorzeichen.
+       %T     Zeit in 24h-Notation (%H:%M:%S).
+       %u     Der Tag der Woche als Zahl von 1 bis 7, mit Montag als 1.  Siehe
+              auch %w.
+       %U     Die Wochennummer des aktuellen Jahres als Ganzzahl  von  00  bis
+              53,  beginnend  mit dem ersten Sonntag als erster Tag der ersten
+              Woche.  Siehe auch %V und %W.
+       %V     Die Wochennummer nach ISO 8601:1988 als Dezimalzahl von  01  bis
+              53,  wobei Woche 1 die erste Woche ist, die wenigstens 4 Tage im
+              laufenden Jahr hat, mit Montag als dem  ersten  Tag  der  Woche.
+              Siehe auch %U und %W.
+       %w     Der  Tag  der  Woche  als  Zahl  von 0 bis 6, mit Sonntag als 0.
+              Siehe auch %u.
+       %W     Die Wochennummer des aktuellen Jahres als Ganzzahl  von  00  bis
+              53,  beginnend  mit  dem ersten Montag als erster Tag der ersten
+              Woche.
+       %x     Die bevorzugte Datums-Repraesentation ohne die Zeit in der momen-
+              tanen Locale.
+       %X     Die  bevorzugte  Uhrzeit-Repraesentation  ohne  das  Datum in der
+              momentanen Locale.
+       %y     Das Jahr als Ganzzahl ohne das Jahrhundert (00 - 99).
+       %Y     Das Jahr als Ganzzahl mit dem Jahrhundert.
+       %z     Die  Zeitzone  als  Stundendifferenz  zu  GMT. Benoetigt, um
+              RFC822-konforme  Datumsangaben  zu  erhalten  (mit '%a, %d %b %Y
+              %H:%M:%S %z').
+       %Z     Die Zeitzone oder der Name oder die Abkuerzung.
+       %+     Datum und Zeit im Format von date(1).
+       %%     Das Zeichen '%'.
+     
+BEISPIEL
+     write(strftime("Heute ist %A, der %d. %B %Y.\n"))
+     ergibt z.B.
+     "Heute ist Montag, der 24. September 2007.\n"
+
+SIEHE AUCH
+     ctime(E), gmtime(E), localtime(E), mktime(E), time(E), utime(E)
diff --git a/doc/efun/strftime.en b/doc/efun/strftime.en
new file mode 100644
index 0000000..ca0aa65
--- /dev/null
+++ b/doc/efun/strftime.en
@@ -0,0 +1,122 @@
+SYNOPSIS
+     string strftime()
+     string strftime(string fmt)
+     string strftime(int clock)
+     string strftime(string fmt, int clock)
+     string strftime(string fmt, int clock, int localized)
+
+BESCHREIBUNG
+     Gibt, aehnliche wie ctime(), eine Zeit als formatierten String zurueck.
+     Hierbei kann ein String mit div. Platzhaltern vom Benutzer angegeben
+     werden (s.u.). Wird kein String angegeben, wird "%c" als Formatstring
+     benutzt.
+
+     Das Argument <clock> wird als Anzahl Sekunden seit dem 01.01.1970, 00:00
+     Uhr interpretiert. Wenn <clock> nicht angegeben wird, wird time()
+     verwendet.
+
+     Das Argument <localized> gibt an, ob die Ausgabe englisch (das sog.
+     klassische "C" locale) oder in der jeweiligen Landessprache (z.B.
+     deutsch) erfolgen soll. Hierbei haengt die Sprache allerdings von den auf
+     dem Mudrechner gesetzten Umgebungsvariablen LC_TIME oder LC_ALL ab, sie
+     kann nicht selber gewaehlt werden. Wird kein <localized> angegeben, wird
+     1 verwendet, was einer Ausgabe in Landessprache entspricht.
+
+BEMERKUNGEN:
+     Der zurueckgebene Ergebnisstring ist max. 511 Zeichen lang.
+     Im MG erfolgt momentan immer eine englische Ausgabe.
+
+PLATZHALTER:
+     Diese Funktion versteht alle Platzhalter, die die Funktion strftime() aus
+     der C-Standardbibliothek versteht. Momentan sind dies:
+     
+     %a
+        is replaced by the locale's abbreviated weekday name. 
+     %A
+        is replaced by the locale's full weekday name. 
+     %b
+        is replaced by the locale's abbreviated month name. 
+     %B
+        is replaced by the locale's full month name. 
+     %c
+        is replaced by the locale's appropriate date and time representation. 
+     %C
+        is replaced by the century number (the year divided by 100 and 
+        truncated to an integer) as a decimal number [00-99]. 
+     %d
+        is replaced by the day of the month as a decimal number [01,31].
+     %D
+        same as %m/%d/%y. 
+     %e
+        is replaced by the day of the month as a decimal number [1,31]; a 
+        single digit is preceded by a space. 
+     %h
+        same as %b. 
+     %H
+        is replaced by the hour (24-hour clock) as a decimal number 
+        [00,23]. 
+     %I
+        is replaced by the hour (12-hour clock) as a decimal number 
+        [01,12]. 
+     %j
+        is replaced by the day of the year as a decimal number 
+        [001,366]. 
+     %m
+        is replaced by the month as a decimal number [01,12]. 
+     %M
+        is replaced by the minute as a decimal number [00,59]. 
+     %n
+        is replaced by a newline character. 
+     %p
+        is replaced by the locale's equivalent of either a.m. or p.m. 
+     %r
+        is replaced by the time in a.m. and p.m. notation; in the POSIX 
+        locale this is equivalent to %I:%M:%S %p. 
+     %R
+        is replaced by the time in 24 hour notation (%H:%M). 
+     %S
+        is replaced by the second as a decimal number [00,61]. 
+     %t
+        is replaced by a tab character. 
+     %T
+        is replaced by the time (%H:%M:%S). 
+     %u
+        is replaced by the weekday as a decimal number [1,7], with 1 
+        representing Monday. 
+     %U
+        is replaced by the week number of the year (Sunday as the first day 
+        of the week) as a decimal number [00,53]. 
+     %V
+        is replaced by the week number of the year (Monday as the first day 
+        of the week) as a decimal number [01,53]. If the week containing 1 
+        January has four or more days in the new year, then it is considered 
+        week 1. Otherwise, it is the last week of the previous year, and the 
+        next week is week 1. 
+     %w
+        is replaced by the weekday as a decimal number [0,6], with 0 
+        representing Sunday. 
+     %W
+        is replaced by the week number of the year (Monday as the first day 
+        of the week) as a decimal number [00,53]. All days in a new year 
+        preceding the first Monday are considered to be in week 0. 
+     %x
+        is replaced by the locale's appropriate date representation. 
+     %X
+        is replaced by the locale's appropriate time representation. 
+     %y
+        is replaced by the year without century as a decimal number [00,99]. 
+     %Y
+        is replaced by the year with century as a decimal number. 
+     %Z
+        is replaced by the timezone name or abbreviation, or by no bytes if 
+        no timezone information exists. 
+     %%
+        is replaced by %.
+
+BEISPIEL
+     write(strftime("Heute ist %A, der %d. %B %Y.\n"))
+     ergibt z.B.
+     "Heute ist Montag, der 24. September 2007.\n"
+
+SIEHE AUCH
+     gmtime(E), localtime(E), mktime(), time(E), utime(E)
diff --git a/doc/efun/stringp b/doc/efun/stringp
new file mode 100644
index 0000000..97d82b0
--- /dev/null
+++ b/doc/efun/stringp
@@ -0,0 +1,10 @@
+SYNOPSIS
+        int stringp(mixed arg)
+
+BESCHREIBUNG
+        Liefert 1, wenn das Argument eine Zeichenkette (String) ist,
+        ansonsten 0.
+
+SIEHE AUCH
+        closurep(E), floatp(E), mappingp(E), objectp(E), intp(E),
+        referencep(E), pointerp(E), symbolp(E), clonep(E)
diff --git a/doc/efun/strlen b/doc/efun/strlen
new file mode 100644
index 0000000..e081a7a
--- /dev/null
+++ b/doc/efun/strlen
@@ -0,0 +1,11 @@
+SYNOPSIS
+        int strlen(string str)
+
+BESCHREIBUNG
+        Liefert die Laenge eines Strings.
+        Diese efun ist VERALTET und ersetzt durch sizeof().
+        Bitte in neuem Code nicht mehr benutzen und in altem
+        Code sukzessive ersetzen.
+
+SIEHE AUCH
+        sizeof(E), extract(E)
diff --git a/doc/efun/strrstr b/doc/efun/strrstr
new file mode 100644
index 0000000..bc039b6
--- /dev/null
+++ b/doc/efun/strrstr
@@ -0,0 +1,25 @@
+SYNOPSIS
+        int strrstr(string str, string muster);
+        int strrstr(string str, string muster, int pos);
+
+BESCHREIBUNG:
+        Liefert den Index des ersten Auftretens von <muster> im String <str>,
+        ausgehend von der Position <pos> her rueckwaerts gesucht. Wird <pos>
+        nicht angegeben, wird als Standard -1 gesetzt, was dem Ende von <str>
+        entspricht. Mit anderen Worten: die Funktion liefert den Index des
+        letzten Auftretens von <muster> vor <pos>.
+
+        Der Index, der zurueck gegeben wird, ist relativ zum Beginn des
+        Strings <str>.
+
+        Wenn <muster> nicht in <str> gefunden wird, wird -1 zurueck gegeben.
+
+        Wenn <pos> negativ ist, bezeichnet <pos> den Index vom Ende des
+        Strings aus gezaehlt. Dabei wird die Suche aber dennoch rueckwaerts
+        im String <str> durchgefuehrt.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.10
+
+SIEHE AUCH
+        strstr(E), strlen(E), sscanf(E), sprintf(E), explode(E)
diff --git a/doc/efun/strstr b/doc/efun/strstr
new file mode 100644
index 0000000..ea5cb83
--- /dev/null
+++ b/doc/efun/strstr
@@ -0,0 +1,17 @@
+SYNOPSIS
+        int strstr(string str, string muster);
+        int strstr(string str, string muster, int pos);
+
+BESCHREIBUNG
+        Liefert den Index des ersten Auftretens von <muster> in <str>,
+        ausgehend von der Position <pos>, wobei in <str> vorwaerts gesucht
+        wird. Wird <pos> nicht angegeben, wird als Standardwert 0 gesetzt,
+        also vom Beginn von <str> her gesucht.
+
+        Wenn <muster> nicht gefunden wird, wird -1 zurueck geliefert.
+
+        Wenn <pos> negativ ist, bezeichnet <pos> die Startposition der Suche
+        relativ zum Ende von <str>, es wird aber weiterhin vorwaerts gesucht.
+
+SIEHE AUCH
+        strrstr(E), strlen(E), sscanf(E), sprintf(E), explode(E)
diff --git a/doc/efun/struct_info b/doc/efun/struct_info
new file mode 100644
index 0000000..4d4cd0b
--- /dev/null
+++ b/doc/efun/struct_info
@@ -0,0 +1,46 @@
+SYNOPSIS
+        #include <struct_info.h>
+        #include <lpctypes.h>
+
+        mixed * struct_info (struct st, int what)
+
+DESCRIPTION
+        Return information about the structure of struct <st> in an array.
+        If <st> has a base struct, <what> determines how the information
+        is returned:
+
+        <what> == SINFO_FLAT:
+            All members of <st>, including those inherited from the base
+            struct, are returned on the top level of the result.
+            The base struct is signified by just its name.
+
+        <what> == SINFO_NESTED:
+            Only the members defined in <st> itself are returned on
+            the top level of the result. The information for the base
+            struct is a array by itself, as it would be returned
+            by a call to struct_info() for a base struct instance.
+
+        The elements in the resulting array are:
+
+          string [SI_NAME]:        the name of the struct
+          string [SI_PROG_NAME]:   the name of program defining the struct
+          string [SI_PROG_ID]:     the id of the program defining the struct
+          mixed  [SI_BASE]:        0, or the base struct information
+          mixed* [SI_MEMBER+0]:    the first member information
+          mixed* [SI_MEMBER+n]:    the last member information
+
+        The member information entries are arrays themselves with
+        these elements:
+
+          string [SIM_NAME]:  name of the member
+          int    [SIM_TYPE]:  the type of the member (compile-time value)
+          string [SIM_EXTRA]: 0, or if the member is a struct, the
+                              struct name
+
+HISTORY
+        Introduced in LDMud 3.3.344.
+        LDMud 3.3.417 introduced SI_PROG_NAME and SI_PROG_ID in exchange
+          for SI_UNIQUE_NAME.
+
+SEE ALSO
+        structs(LPC)
diff --git a/doc/efun/structp b/doc/efun/structp
new file mode 100644
index 0000000..0b1668d
--- /dev/null
+++ b/doc/efun/structp
@@ -0,0 +1,13 @@
+SYNOPSIS
+        int structp(mixed arg)
+
+DESCRIPTION
+        Return 1 if arg is a struct.
+
+HISTORY
+        Introducted in LDMud 3.3.273.
+
+SEE ALSO
+        baseof(E), closurep(E), floatp(E), mappingp(E), objectp(E),
+        intp(E), referencep(E), pointerp(E), stringp(E), symbolp(E),
+        clonep(E)
diff --git a/doc/efun/swap b/doc/efun/swap
new file mode 100644
index 0000000..fd242e4
--- /dev/null
+++ b/doc/efun/swap
@@ -0,0 +1,7 @@
+GESCHUETZT
+SYNOPSIS
+        void swap(object obj);
+
+BESCHREIBUNG
+        Lagert ein Objekt aus. Diese Efun ist nur fuer systeminternes
+        Debugging und kann einen Absturz verursachen.
diff --git a/doc/efun/symbol_function b/doc/efun/symbol_function
new file mode 100644
index 0000000..dbb53d0
--- /dev/null
+++ b/doc/efun/symbol_function
@@ -0,0 +1,36 @@
+SYNOPSIS
+        closure symbol_function(symbol arg);
+        closrue symbol_function(string arg);
+        closure symbol_function(string arg, object|string obj);
+
+BESCHREIBUNG
+        Erzeugt eine Lfun-, Efun- oder Operator-Closure aus <arg>, wobei
+        <arg> entweder ein string oder ein symbol sein muss. Fuer
+        Lfun-Closures gibt <obj> an, zu welchem Objekt die Lfun gehoert,
+        entweder angegeben durch das Objekt selbst (bzw. einen pointer
+        darauf) oder durch den Objektnamen als String. Wenn ein String
+        angegeben wird, wird das Objekt beim Aufruf geladen.
+
+        Wenn die Closure fuer eine Lfun in einem anderen als dem momentanen
+        Objekt erzeugt wird, ergibt dies eine "alien lfun closure". Solche
+        Closures sind an das Objekt gebunden, das symbol_function()
+        aufgerufen hat (dieses Objekt wird von to_object() geliefert),
+        obwohl der eigentliche Code in einem anderen Objekt steht (das mit
+        get_type_info() gefunden werden kann).
+
+        Als "private" deklarierte Funktionen koennen auf diese Weise nie
+        zu einer Closure gewandelt werden, "static" und "protected"
+        deklarierte Lfuns nur dann, wenn <obj> das gueltige Objekt
+        (d.h. this_object()) ist.
+        Expord.h. tiert man die Closures, koennen sie unabhaengig vom Modifier der
+        Ursprungsfunktionen von jedem gerufen werden.
+        umgehen).
+
+BEISPIELE
+        symbol_function("efun::users");
+            --> ergibt: #'users
+        symbol_function("QueryProp", other_obj);
+            --> ergibt: other_obj->QueryProp()
+
+SIEHE AUCH
+        lambda(E), quote(E)
diff --git a/doc/efun/symbol_variable b/doc/efun/symbol_variable
new file mode 100644
index 0000000..b3a66d4
--- /dev/null
+++ b/doc/efun/symbol_variable
@@ -0,0 +1,29 @@
+SYNOPSIS
+        closure symbol_variable(string arg);
+        closure symbol_variable(symbol arg);
+        closure symbol_variable(int arg);
+
+BESCHREIBUNG
+        Erzeugt eine Identifier (Lfun) Closure aus der globalen Variablen
+        <arg> des gueltigen Objekts. Die Variable kann angegeben werden
+        als Symbol, mit ihrem Namen oder durch die ordinale Nummer in der
+        Variablentabelle des Objekts.
+
+        Wenn keine solche Variable existiert oder sie von aussen nicht
+        sichtbar ist, wird 0 zurueck geliefert.
+
+        Wenn <arg> ein Integer ist und sich auf eine geerbte Variable
+        bezieht, die im geerbten Objekt "private" deklariert ist (d.h.
+        versteckt), fuehrt dies zu einer Schutzverletzung.
+
+AENDERUNGEN
+        Eingefuehrt in 3.2.1@8
+
+BEISPIELE
+        int base;
+        int var;
+        symbol_variable("var");         ergibt: #'<this_object>->var
+        symbol_variable(0);             ergibt: #'<this_object>->base
+
+SIEHE AUCH
+        lambda(E), quote(E), symbol_function(E)
diff --git a/doc/efun/symbolp b/doc/efun/symbolp
new file mode 100644
index 0000000..92c64b7
--- /dev/null
+++ b/doc/efun/symbolp
@@ -0,0 +1,14 @@
+SYNOPSIS
+        int symbolp(mixed arg)
+
+BESCHREIBUNG
+        Liefert 1, wenn das Argument ein Symbol ist, ansonsten 0.
+
+BEISPIEL
+        symbolp('foo) liefert 1.
+
+AENDERUNGEN
+        Eingefuehrt in 3.2@70.
+
+SIEHE AUCH
+        intp(E), quote(E)
diff --git a/doc/efun/tail b/doc/efun/tail
new file mode 100644
index 0000000..8c50b35
--- /dev/null
+++ b/doc/efun/tail
@@ -0,0 +1,9 @@
+SYNOPSIS
+        void tail(string file);
+
+BESCHREIBUNG
+        Listet das Ende eines Files. Es gibt kein Zeilenlimit, es werden aber
+        maximal 1000 Bytes ausgegeben.
+
+SIEHE AUCH
+        cat(E), ed(E)
diff --git a/doc/efun/tan b/doc/efun/tan
new file mode 100644
index 0000000..f99a085
--- /dev/null
+++ b/doc/efun/tan
@@ -0,0 +1,11 @@
+SYNOPSIS
+        float tan(int|float)
+
+BESCHREIBUNG
+        Liefert den Tangens des Argumentes.
+
+AENDERUNGEN
+        LDMud 3.2.9: Ganzzahlen (Integers) als Argument hinzugefuegt.
+
+SIEHE AUCH
+        sin(E), asin(E), cos(E), acos(E), atan(E), atan2(E)
diff --git a/doc/efun/tell_object b/doc/efun/tell_object
new file mode 100644
index 0000000..e2cfd9c
--- /dev/null
+++ b/doc/efun/tell_object
@@ -0,0 +1,47 @@
+SYNOPSIS
+        void tell_object(object|string obj, string str);
+        void tell_object(object|string obj, mixed *|mapping|struct|object msg);
+
+BESCHREIBUNG
+        Sendet einen Nachricht an das Objekt <obj> (das auch durch seinen
+        Objektnamen angegeben werden kann).
+
+        Ist die Nachricht ein String, wird der Text an interaktive Objekte
+        direkt ausgegeben, fuer andere Objekte wird die lfun catch_tell()
+        in diesen aufgerufen.
+
+        Ist die Nachricht ein anderer Typ, wird die lfun catch_msg() im
+        Empfaenger aufgerufen.
+
+BEMERKUNGEN
+        - wird in einem catch_msg() der Wert von <msg> veraendert, erhalten
+          alle nachfolgenden Objekte das veraenderte <msg> (Referenz!)
+
+BEISPIELE
+        // Dies gibt ein einfaches "Hi!" an den Spieler Thomas aus:
+
+            object wer;
+            wer = find_player("thomas");
+            tell_object(wer, "Hi!\n");
+
+        // Ein Beispiel mit zwei Objekten, das zeigt, wie das Zusammenspiel
+        // von catch_tell() und tell_object() ablaueft. Objekt1 ist ein
+        // Lebewesen mit Namen "Dummymonster", Objekt2 verteilt die Meldung:
+
+        Objekt1:
+            void catch_tell(string str) {
+                write("Erhaltener Text: "+str+"\n");
+            }
+
+        Objekt2:
+            void fun() {
+                object wer;
+                wer = find_living("dummymonster");
+                tell_object(wer, "Folge mir, Sterblicher!\n");
+                ...
+            }
+
+SIEHE AUCH
+        Aehnlich:   write(E), shout(E), say(E), tell_room(E), printf(E)
+        Verwandt:   catch_tell(E), catch_msg(A)
+        Sonstiges:  object_name(E)
\ No newline at end of file
diff --git a/doc/efun/tell_room b/doc/efun/tell_room
new file mode 100644
index 0000000..77f302c
--- /dev/null
+++ b/doc/efun/tell_room
@@ -0,0 +1,79 @@
+FUNKTION:
+        void tell_room(string|object obj, string str);
+        void tell_room(string|object obj, string str, object *exclude);
+
+        void tell_room(string|object obj, mixed *|mapping|struct|object msg)
+        void tell_room(string|object obj, mixed *|mapping|struct|object  msg
+                                        , object *exclude);
+
+BESCHREIBUNG:
+        Gibt einen Text <str> an den Raum <obj> aus. <obj> kann auch der
+        Objektname des Raumes als String sein.
+        Wenn das Raumobjekt mit seinem Namen angegeben ist, sucht der Driver
+        das Objekt unter diesem Namen und laedt es, falls notwendig.
+
+        Ist die Nachricht ein String, wird der Text an interaktive Objekte
+        direkt ausgegeben, fuer andere Objekte wird die lfun catch_tell()
+        in diesen aufgerufen.
+        Falls ein Lewebesen die Funktion catch_tell() definiert (-> shadow),
+        so wird der Text hier ausgewertet und nicht an den User ausgegeben.
+
+        Wenn das zweite Argument, die Nachricht, kein String ist, wird in
+        allen Lebewesen, die den Text erhalten, catch_msg() anstatt
+        catch_tell() aufgerufen.
+
+        Mit dem Array <*exclude> kann man verhindern, dass die Nachricht an
+        die darin enthaltenen Objekte gesendet wird.
+        Das ist sinnvoll, wenn zB ein Spieler Ausloeser einer Meldung ist
+        und diese selbst nicht erhalten soll.
+
+BEMERKUNGEN:
+        - der Eintrag von mehreren Anwesenden in *exclude ist moeglich
+        - wird in einem catch_msg() der Wert von <msg> veraendert, erhalten
+          alle nachfolgenden Objekte das veraenderte <msg> (Referenz!)
+
+        - say("str") ist verhaltensgleich zu
+          tell_room(environment(), "str", ({this_player()||this_object()}))
+
+BEISPIELE:
+        // Dies ist ein einfaches Beispiel fuer eine Meldung an alle An-
+        // wesenden im Raum.
+
+        tell_room(this_object(),"Ein leichter Wind kommt auf.\n");
+
+        // Diese Meldung wird im Raum /d/ebene/ark/raum.c ausgegeben, dieser
+        // Raum muss nicht derjenige sein, in dem das tell_room() ausgefuehrt
+        // wird.
+
+        tell_room("/d/ebene/ark/raum","Ein leichter Wind kommt auf.\n");
+
+
+        // Diese Meldung wird an alle Anwesenden im Raum AUSSER this_player()
+        // (der diese Meldung ausgeloest hat) ausgegeben. Der muss eine ge-
+        // sonderte Meldung ueber sein Stolpern per write() oder
+        // tell_object() bekommen.
+        tell_room(this_object(),
+                  break_string(this_player()->Name()+" stolpert.", 78),
+                  ({ this_player() }));
+        tell_object(this_player(), "Du stolperst.\n");
+
+        // Ein Beispiel mit zwei Objekten, das zeigt, wie das Zusammenspiel
+        // von catch_tell() und tell_room() ablaueft. Objekt1 ist ein
+        // Lebewesen mit Namen "Dummymonster", Objekt2 verteilt die Meldung:
+
+        Objekt1 (ein Lebewesen, steht im Env von this_player()):
+            void catch_tell(string str) {
+                write("Empfangen: "+str+"\n");
+            }
+
+        Objekt2:
+            void fun() {
+                tell_room(environment(this_player()), "Hallo Welt!\n");
+            }
+
+SIEHE AUCH
+        Aehnlich:   tell_object(E), write(E), shout(E), say(E), printf(E)
+        Verwandt:   catch_tell(E), catch_msg(A)
+        Sonstiges:  object_name(E)
+
+7.Aug 2007 Gloinson
diff --git a/doc/efun/terminal_colour b/doc/efun/terminal_colour
new file mode 100644
index 0000000..6cd1bce
--- /dev/null
+++ b/doc/efun/terminal_colour
@@ -0,0 +1,127 @@
+SYNOPSIS
+        varargs string terminal_colour(string str,
+                                       null | mapping | closure map,
+                                       int wrap, int indent);
+BESCHREIBUNG
+        Ist <map> ein Wert ungleich 0, ersetzt diese Efun alle Farb-
+        Definitionen der Form "%^KEY%^" (siehe unten fuer Details) im
+        String <str> und ersetzt sie durch die entsprechenden Werte aus dem
+        unter <map> angegebenen Farbschluessel.
+
+        Ist <map> ein Mapping, muessen die Eintraege das Format
+        "KEY" : "wert" haben; Eintraege, die keine Strings enthalten,
+        werden ignoriert. Einzige Ausnahme dazu: enthaelt <map> einen
+        Eintrag der Form 0:wert, wird dieser fuer alle Farbdefinitionen
+        verwendet, die keinem anderen Schluessel zugeordnet werden koennen.
+        <wert> kann in diesem Fall ein String oder eine Closure sein. Handelt
+        es sich um eine Closure, erhaelt diese den <KEY> als Argument und
+        muss einen String zurueck liefern, der <KEY> ersetzt.
+
+        Ist <map> eine Closure, wird diese mit den Farbdefinitionen <KEY>
+        als Argument aufgerufen und muss einen String zurueck liefern, der
+        die <KEY>s ersetzt.
+
+        Die speziellen Schluessel "%^%^" und "%%^^" werden immer durch das
+        Literal "%^" ersetzt.
+
+        Die Parameter <wrap> und <indent> sind optional. Ist nur <wrap>
+        angegeben, wird <str> in der Spalte <wrap> umgebrochen. Ist
+        zusaetzlich <indent> angegeben, werden alle umgebrochenen Zeilen
+        um <indent> Spalten eingerueckt.
+
+        Der Zeilenumbruch ignoriert die Laenge der Farbmakros und ihrer
+        Inhalte. Er bricht <str> anhand der Laenge der uebrigen Zeichen
+        um, ist also farb-neutral.
+
+        Ist <map> als 0 angegeben, fuehrt die Efun kein Suchen und Ersetzen
+        von Farbdefinitionen durch. Die Funktionalitaet von Zeilenumbruch
+        und Einrueckung bleiben erhalten, wenn gewuenscht. Auf diese Weise
+        dupliziert terminal_colour() die Funktion von sprintf("%-=s") und
+        wirkt als einfache Zeilenumbruch Funktion.
+
+
+        ERKENNEN VON FARBDEFINITIONEN
+
+        Wie bereits erwaehnt, werden die speziellen Schluessel "%^%^" und
+        "%%^^" durch das Literal "%^" ersetzt und spielen im Weiteren
+        keine Rolle.
+
+        Fuer den Eingabestring wird das folgende Format vorausgesetzt:
+
+            text { '%^' colorkey '%^' text } [ '%^' colorkey ]
+
+        Oder in Worten: die Efun trennt den String bei jedem '%^', das
+        sie antrifft und behandelt anschliessend jeden zweiten Teilstring
+        als Farbschluessel.
+
+        Merke: dieses Verhalten unterscheidet sich von der Behandlung des
+        Eingabestrings unter MudOS. Dort lautet die Syntax:
+
+            key_oder_text { '%^' key_oder_text }
+
+        Oder in Worten: die MudOS Efun trennt den String bei jedem '%^'
+        und versucht dann jeden Teilstring als Farbschluessel zu behandeln.
+        Dieses Verhalten laesst sich auch unter LPC erreichen:
+
+          string mudos_terminal_colour(string str, mapping ext, int w, int i)
+          {
+            return terminal_colour("%^"+implode(explode(str, "%^")-({""})
+                                               ,"%^%^")
+                                  , ext, w, i);
+          }
+
+
+BEISPIELE
+        mapping trans;
+        string str;
+
+        trans = ([ "GREEN" : "ansi-green", "RED" : "", "BLUE" : 1 ]);
+
+        str = terminal_colour( "%^GREEN%^ and %^RED%^ and %^BLUE%^", trans );
+
+        Dies fuehrt zu str == "ansi-green and  and BLUE".
+
+        "%^GREEN^%" wird ersetzt durch "ansi-green", weil <trans> das so
+        definiert,
+        "%^RED%^" wird aus <str> entfernt, weil es mit "" ersetzt wird, und
+        "%^BLUE%^" wird um die "%^" verkuert, weil der Eintrag zu BLUE in
+        <trans> keinen gueltigen Wert enthaelt (d.h. kein String ist). Das
+        selbe wuerde passieren, wenn <str> "%^DEFINE%^" enthalten wuerde,
+        zu dem es keinen Eintrag in <trans> gibt.
+
+        Merke: um direkt benachbarte Schluessel zu ersetzen, soll die
+        Efun wie folgt verwendet werden:
+
+            str = terminal_colour( "%^GREEN%^%^RED%^", trans );
+
+        Eine Eingabe der Form
+
+            str = terminal_colour( "%^GREEN%^RED%^", trans );
+
+        fuehrt zum logischen, aber vielleicht unerwarteten Ergebnis
+        "ansi-greenRED".
+
+
+        Einige Worte zum Zeilenumbruch:
+
+        Ein String, der ohne Einrueckung umgebrochen wird (<indent> ist 0),
+        sieht so aus:
+
+            "dies ist die erste Zeile\nund dies ist die zweite Zeile"
+
+        Ein String, der mit <indent> 3 umgebrochen wird, sieht so aus:
+
+            "dies ist die erste Zeile\n   und dies ist die zweite Zeile"
+
+AENDERUNGEN
+        Die Idee fuer diese Efun und die erste Implementierung stammen
+        aus MudOS; die Strategie fuer das Erkennen von Schluesseln
+        (eingeschlossen die pure Zeilenumbruch Funktion) wurde in
+        LDMud 3.2.8 geglaettet.
+        LDMud 3.2.9 fuegte die Verwendung von Closures zur Definition
+        von Farbschluesseln hinzu. Es erklaerte zudem offiziell das
+        Verhalten betreffen "%%^^" aus Gruenden besserer Kompatibilitaet
+        mit MudOS.
+
+SIEHE AUCH
+        sprintf(E)
diff --git a/doc/efun/test_bit b/doc/efun/test_bit
new file mode 100644
index 0000000..af82c95
--- /dev/null
+++ b/doc/efun/test_bit
@@ -0,0 +1,21 @@
+SYNOPSIS
+        int test_bit(string str, int n);
+
+BESCHREIBUNG
+        Gibt 0 oder 1 des <n>-ten Bits im String <str> zurueck.
+
+        Jedes Zeichen besteht aus 6 Bits. Jedem Zeichen ist also ein Wert
+        zwischen 0 und 63 zugeordnet (weil 2^6=64). Das erste Zeichen ist der
+        Leerschlag " " mit dem Wert 0 (keines der Bits ist gesetzt). Das
+        erste Zeichen im String ist dasjenige mit den niedrigsten Bits (0-5).
+
+BEISPIELE
+        test_bit("_", 5);   Liefert 1, weil "_" das 63. Zeichen ist und
+                            deshalb das 5. Bit gesetzt hat.
+
+        test_bit(" ", 3);   Liefert 0, weil " " das 0. Zeichen ist und deshalb
+                            kein Bit gesetzt hat.
+
+SIEHE AUCH
+        set_bit(E), clear_bit(E), last_bit(E), next_bit(E), count_bits(E),
+        and_bits(E), or_bits(E), xor_bits(E), invert_bits(E), copy_bits(E)
diff --git a/doc/efun/this_interactive b/doc/efun/this_interactive
new file mode 100644
index 0000000..92938bb
--- /dev/null
+++ b/doc/efun/this_interactive
@@ -0,0 +1,9 @@
+SYNOPSIS
+        object this_interactive();
+
+BESCHREIBUNG
+        Die Funktion gibt das momentane interaktive Objekt zurueck, falls
+        vorhanden, also dasjenige welches "die Entertaste gedrueckt hat".
+
+SIEHE AUCH
+        this_player(E), previous_object(E), interactive(E), living(E)
diff --git a/doc/efun/this_object b/doc/efun/this_object
new file mode 100644
index 0000000..5b60276
--- /dev/null
+++ b/doc/efun/this_object
@@ -0,0 +1,10 @@
+SYNOPSIS:
+        object this_object(void)
+
+DESCRIPTION:
+        Return the object pointer for this object. This is not to be
+        confused with the internal name of an object, which is used by
+        the id() function.
+
+SEE ALSO:
+        this_player(E), previous_object(E), object_name(E), find_object(E)
diff --git a/doc/efun/this_player b/doc/efun/this_player
new file mode 100644
index 0000000..5ab6420
--- /dev/null
+++ b/doc/efun/this_player
@@ -0,0 +1,18 @@
+SYNOPSIS
+        object this_player();
+
+BESCHREIBUNG
+        Liefert den momentanen Kommandogeber. Das kann ein interaktiver
+        Benutzer oder ein lebendiges Objekt sein, zum Beispiel ein NPC.
+
+        Wenn die Funktion von innerhalb des heart_beat() eines nicht
+        lebendigen Objekts aufgerufen wird, wird 0 zurueck gegeben.
+
+BEISPIEL
+        if(this_player() != this_interactive())
+        {
+            write("Hey, jemand zwingt uns, Kommandos auszufuehren!\n");
+        }
+
+SIEHE AUCH
+        this_object(E), previous_object(E), interactive(E), living(E)
diff --git a/doc/efun/throw b/doc/efun/throw
new file mode 100644
index 0000000..2a21cde
--- /dev/null
+++ b/doc/efun/throw
@@ -0,0 +1,16 @@
+SYNOPSIS
+        void throw(mixed arg);
+
+BESCHREIBUNG
+        Bricht die Programmverarbeitung ab. Wenn die Verarbeitung mit catch()
+        gestartet wurde, gibt dieses catch() <arg> als Fehlermeldung aus.
+
+        Der Aufruf von throw() ohne vorheriges catch() ist sinnlos und
+        erzeugt einen "throw without catch" Fehler.
+
+BEISPIEL
+        catch(throw("Verarbeitung abgebrochen!"));
+        Das macht nichts als "Verarbeitung abgebrochen!" auszugeben.
+
+SIEHE AUCH
+        catch(E), raise_error(E)
diff --git a/doc/efun/time b/doc/efun/time
new file mode 100644
index 0000000..f7016a4
--- /dev/null
+++ b/doc/efun/time
@@ -0,0 +1,21 @@
+SYNOPSIS
+        int time();
+
+BESCHREIBUNG
+        Liefert die Anzahl Sekunden, die seit dem 01. Januar 1970,
+        00:00:00 GMT verstrichen sind.
+
+        Die Zeitangabe basiert auf der Systemzeit des Hosts, der Driver
+        stellt jedoch sicher, dass das Resultat von time() monoton ansteigt
+        (also immer nur zu hoeheren Werten wechselt).
+
+        Das Resultat von time() veraendert sich nicht waehrend dem Abarbeiten
+        eines Kommandos.
+
+BEISPIEL
+        Um das aktuelle Datum und die aktuelle Zeit anzuzeigen:
+
+            write(ctime(time())+"\n");
+
+SIEHE AUCH
+        ctime(E), gmtime(E), localtime(E), utime(E)
diff --git a/doc/efun/tls_available b/doc/efun/tls_available
new file mode 100644
index 0000000..804a03d
--- /dev/null
+++ b/doc/efun/tls_available
@@ -0,0 +1,19 @@
+PRELIMINARY
+SYNOPSIS
+        int tls_available()
+
+DESCRIPTION
+        If the global TLS initialisation could not been set up, 
+        tls_is_available() returns 0, otherwise 1.
+        It is not very useful calling any other tls_*-efun if this one 
+        returns 0, since there is no TLS-encryption available.
+        Most likely the global initialisation fails due to missing or 
+        unreadable key resp. certificate-file.
+
+HISTORY
+        Introduced in LDMud 3.3.474 and following, backported to 3.2.11.
+
+SEE ALSO
+        tls_init_connection(E), tls_deinit_connection(E), 
+        tls_query_connection_state(E), tls_query_connection_info(E),
+        tls_check_certificate(E), tls_refresh_certs(E)
diff --git a/doc/efun/tls_check_certificate b/doc/efun/tls_check_certificate
new file mode 100644
index 0000000..f8afc8e
--- /dev/null
+++ b/doc/efun/tls_check_certificate
@@ -0,0 +1,49 @@
+PRELIMINARY
+SYNOPSIS
+        mixed *tls_check_certificate(object obj);
+        mixed *tls_check_certificate(object obj, int extra);
+
+DESCRIPTION
+        tls_check_certificate() checks the certificate of the secured
+        connection bound to <obj> (default is the current object).  If
+        <obj> is not interactive, or if TLS is not available, an error
+        is thrown.
+
+        If <obj> doesn't have a secure connection up and running, an
+        error is thrown.
+        Otherwise, the result is an array with these values:
+
+          int [0]      : Result code of SSL_get_verify_result (see man 1 verify
+                         subsection DIAGNOSTICS for possible values)
+          array [1]    : array with 3*n entries of extra x509 data.
+                         structure is:
+                            3*i    : numerical form of object name,
+                                     e.g. "2.5.4.3"
+                            3*i + 1: long or short name if available,
+                                     e.g. "commonName"
+                            3*i + 2: value
+          array [2]    : if extra is set:
+                            array with 3*n entries of x509 extension data
+                            data structure is:
+                            3*i    : numerical form of extension name
+                            3*i + 1: long or short name of extension
+                                     name if available
+                            3*i + 2: array of strings with the data
+                                     structure of [1]
+
+        Note: a x509 certificate can have more than one object with
+        the same name
+
+BUGS
+        Not supported when using GnuTLS.
+
+HISTORY
+        Introduced in LDMud 3.3.672/3.2.11.
+        LDMud 3.3.711/3.2.12 modified the behaviour to return the
+        low-level API result value, and to throw an error if the connection
+        is not secure.
+
+SEE ALSO
+        tls_init_connection(E), tls_deinit_connection(E), tls_error(E),
+        tls_query_connection_state(E), tls_query_connection_info(E),
+        tls_available(E), tls_refresh_certs(E), mudlib/psyc-tls.c
diff --git a/doc/efun/tls_deinit_connection b/doc/efun/tls_deinit_connection
new file mode 100644
index 0000000..7883801
--- /dev/null
+++ b/doc/efun/tls_deinit_connection
@@ -0,0 +1,20 @@
+PRELIMINARY
+SYNOPSIS
+        void tls_deinit_connection(object ob)
+
+DESCRIPTION
+        tls_deinit_connection() shuts down a TLS connection to
+        the interactive object <ob> (or this_object() if <ob> is not
+        given) but the connection is not closed.
+
+        Under normal circumstances there is no need to use this efun: most
+        clients operate in either secure or unsecure mode, but don't allow
+        switching connection security on the fly.
+
+HISTORY
+        Introduced in LDMud 3.3.474 and following, backported to 3.2.11.
+
+SEE ALSO
+        tls_init_connection(E), tls_error(E), tls_query_connection_state(E),
+        tls_query_connection_info(E), tls_available(E),
+        tls_check_certificate(E), tls_refresh_certs(E)
diff --git a/doc/efun/tls_error b/doc/efun/tls_error
new file mode 100644
index 0000000..2b5c788
--- /dev/null
+++ b/doc/efun/tls_error
@@ -0,0 +1,15 @@
+PRELIMINARY
+SYNOPSIS
+        string tls_error(int errorno)
+
+DESCRIPTION
+        tls_error() returns a string describing the error behind the
+        error number errorno.
+
+HISTORY
+        Introduced in LDMud 3.3.474 and following, backported to 3.2.11.
+
+SEE ALSO
+        tls_init_connection(E), tls_deinit_connection(E), 
+        tls_query_connection_state(E), tls_query_connection_info(E),
+        tls_available(E), tls_check_certificate(E), tls_refresh_certs(E)
diff --git a/doc/efun/tls_init_connection b/doc/efun/tls_init_connection
new file mode 100644
index 0000000..e33afae
--- /dev/null
+++ b/doc/efun/tls_init_connection
@@ -0,0 +1,50 @@
+PRELIMINARY
+SYNOPSIS
+        int tls_init_connection(object ob)
+        int tls_init_connection(object ob, string fun, string|object fob, mixed extra...)
+        int tls_init_connection(object ob, closure fun, mixed extra...)
+
+DESCRIPTION
+        tls_init_connection() tries to start a TLS secured connection to 
+        the interactive object <ob> (or this_object() if <ob> is not given).
+
+        Result:
+          errorcode < 0: unsuccessful, use tls_error() to get an useful
+                         description of the error
+             number > 0: the secure connection is still being set up in the
+                          background
+            number == 0: the secure connection is active.
+        
+        OpenSSL only:
+
+            If the callback <fun>/<fun>:<fob> is specified, it will be called
+            once the fate of the secure connection has been determined. The
+            first argument will be the return code from the handshake
+            (errorcode < 0 on failure, or 0 on success), followed by the
+            interactive object <ob> and any <extra> arguments.
+
+        If the TLS setup fails, it is not necessary to call
+        tls_deinit_connection().
+
+        IMPORTANT: During the TLS handshake nothing else must be sent
+        to the client! For the most cases (TLS-capable clients logging in)
+        this means that the TLS handshake is the first and only thing the
+        client gets to see while the handshake is in progress.
+
+        The driver automatically suppresses the printing of the prompt
+        while the TLS handshake is in progress.
+
+        If tls_init_connection() is called in the master::connect() function,
+        the driver will either call the set callback in place of logon(), or
+        if not callback has been set, delay the call of logon() until the
+        state of the connection is clear.
+
+HISTORY
+        Introduced in LDMud 3.3.474 and following, backported to 3.2.11.
+        LDMud 3.2.13/3.3.713 streamlined the handling of secure connections
+        during logon.
+
+SEE ALSO
+        tls_deinit_connection(E), tls_error(E), tls_query_connection_state(E),
+        tls_query_connection_info(E), tls_available(E),
+        tls_check_certificate(E), tls_refresh_certs(E), connect(M), logon(A)
diff --git a/doc/efun/tls_query_connection_info b/doc/efun/tls_query_connection_info
new file mode 100644
index 0000000..32aeef7
--- /dev/null
+++ b/doc/efun/tls_query_connection_info
@@ -0,0 +1,37 @@
+PRELIMINARY
+SYNOPSIS
+        #include <sys/ tls.h>
+        int *tls_query_connection_info (object ob)
+
+DESCRIPTION
+        If <ob> does not have a TLS connection or if the connection
+        is still being set-up, or if <ob> is not interactive, the efun
+        returns 0.
+
+        If <ob> has a TLS connection, tls_query_connection_info()
+        returns an array that contains some parameters of <ob>'s
+        connection:
+
+          int|string [TLS_CIPHER]: the cipher used
+          int        [TLS_COMP]:   the compression used
+          int        [TLS_KX]:     the key-exchange used
+          int        [TLS_MAC]:    the digest algorithm used
+          int|string [TLS_PROT]:   the protocol used
+
+        To translate these numbers into strings, <tls.h> offers a
+        number of macros:
+
+          TLS_xxx_TABLE: a literal array of strings describing the
+            value in question.
+          TLS_xxx_NAME(x): a macro translating the numeric result
+            value into a string.
+
+          xxx: CIPHER, COMP, KX, MAC, PROT
+
+HISTORY
+        Introduced in LDMud 3.3.474 and following, backported to 3.2.11.
+
+SEE ALSO
+	tls_init_connection(E), tls_deinit_connection(E), tls_error(E),
+	tls_query_connection_state(E), tls_available(E),
+        tls_check_certificate(E), tls_refresh_certs(E)
diff --git a/doc/efun/tls_query_connection_state b/doc/efun/tls_query_connection_state
new file mode 100644
index 0000000..2624f20
--- /dev/null
+++ b/doc/efun/tls_query_connection_state
@@ -0,0 +1,16 @@
+PRELIMINARY
+SYNOPSIS
+        int tls_query_connection_state(object ob)
+
+DESCRIPTION
+        tls_query_connection_state() returns a positive number if <ob>'s
+        connection is TLS secured, 0 if it's unsecured, and a negative number
+        if the TLS connection setup is still being set-up.
+
+HISTORY
+        Introduced in LDMud 3.3.474 and following, backported to 3.2.11.
+
+SEE ALSO
+	tls_init_connection(E), tls_deinit_connection(E), tls_error(E), 
+	tls_query_connection_info(E), tls_available(E),
+        tls_check_certificate(E), tls_refresh_certs(E)
diff --git a/doc/efun/tls_refresh_certs b/doc/efun/tls_refresh_certs
new file mode 100644
index 0000000..c8364c5
--- /dev/null
+++ b/doc/efun/tls_refresh_certs
@@ -0,0 +1,17 @@
+PRELIMINARY
+SYNOPSIS
+        void tls_refresh_certs()
+
+DESCRIPTION
+        Reload the certificates and certificate revocation information.
+
+BUGS
+        Not supported when using GnuTLS.
+
+HISTORY
+        Introduced in LDMud 3.3.714/3.2.15.
+
+SEE ALSO
+        tls_init_connection(E), tls_deinit_connection(E), tls_error(E),
+        tls_query_connection_state(E), tls_query_connection_info(E),
+        tls_available(E), tls_check_certificate(E), mudlib/psyc-tls.c
diff --git a/doc/efun/to_array b/doc/efun/to_array
new file mode 100644
index 0000000..21b1a93
--- /dev/null
+++ b/doc/efun/to_array
@@ -0,0 +1,30 @@
+SYNOPSIS
+        mixed *to_array(string arg);
+        mixed *to_array(symbol arg);
+        mixed *to_array(quotedarray arr);
+        mixed *to_array(mixed *arg);
+        mixed *to_array(struct);
+
+        (int*)<value>
+
+BESCHREIBUNG
+        Strings und Symbole werden umgewandelt in ein Integer-Array, das aus
+        den Zeichen von <arg> besteht.
+
+        Gequotete Arrays werden "entquotet", und Arrays bleiben, wie sie sind.
+
+        Structs werden in normale Arrays umgewandelt.
+
+BEISPIELE:
+        to_array("12") liefert ({33,34}).
+
+BUGS
+        Die Cast-Schreibweise funktioniert nur, wenn der genaue Wert von
+        <value> zum Zeitpunkt der Kompilierung bekannt ist. Dies wird
+        nicht geaendert werden, da die Funktionsform verwendet werden kann.
+
+HISTORY
+        LDMud 3.3.250 added structs to the accepted data types.
+
+SIEHE AUCH
+        to_int(E), to_string(E), to_struct(E)
diff --git a/doc/efun/to_float b/doc/efun/to_float
new file mode 100644
index 0000000..7b989ce
--- /dev/null
+++ b/doc/efun/to_float
@@ -0,0 +1,19 @@
+SYNOPSIS
+        float to_float(int arg);
+        float to_float(string arg);
+        float to_flaot(float arg);
+
+        (float)<value>
+
+BESCHREIBUNG
+        Integers werden zu Floats erweitert, Strings werden in Floats
+        konvertiert bis zum ersten Zeichen, das nicht mehr zum Float
+        gehoert. Floats werden direkt zurueck gegeben.
+
+BUGS
+        Die Cast-Schreibweise funktioniert nur, wenn der genaue Wert von
+        <value> zum Zeitpunkt der Kompilierung bekannt ist. Dies wird nicht
+        geaendert werden, da die Funktionsform verwendet werden kann.
+
+SIEHE AUCH
+        to_string(E), to_int(E), sscanf(E)
diff --git a/doc/efun/to_int b/doc/efun/to_int
new file mode 100644
index 0000000..6c648e4
--- /dev/null
+++ b/doc/efun/to_int
@@ -0,0 +1,32 @@
+SYNOPSIS
+        int to_int(string arg);
+        int to_int(float arg);
+        int to_int(int arg);
+        int to_int(closure arg);
+
+        (int)<value>
+
+BESCHREIBUNG
+        Bei Floats werden die Nachkommastellen abgeschnitten, Strings mit
+        Ziffern am Anfang werden bis zum ersten Nicht-Ziffern-Zeichen in
+        Integers umgewandelt. Lfun-Closures werden in ihren Funktionsindex
+        konvertiert, Variablen-Closures in ihren Variablenindex. Integers
+        werden unveraendert zurueck gegeben.
+
+        Bezueglich Floats ist es wichtig, Rundungseffekte zu beachten:
+        to_int(3.1*10.0) ergibt nicht 31, sondern 30, weil intern das
+        Resultat der Multiplikation 30.999999 ergibt.
+     
+        Diese Funktion unterstuetzt die Basisprefixe '0x', '0o' und '0b'.
+
+BUGS
+        Die Cast-Schreibweise funktioniert nur, wenn der genaue Wert von
+        <value> zum Zeitpunkt der Kompilierung bekannt ist. Dies wird
+        nicht geaendert werden, da die Funktionsform verwendet werden kann.
+
+AENDERUNGEN
+        Eingefuehrt in 3.2.1@2
+        LDMud 3.2.11 fuehrte die Basisprefixe ein.
+
+SIEHE AUCH
+        to_string(E), sscanf(E)
diff --git a/doc/efun/to_object b/doc/efun/to_object
new file mode 100644
index 0000000..bb577f0
--- /dev/null
+++ b/doc/efun/to_object
@@ -0,0 +1,15 @@
+SYNOPSIS
+	object to_object(string arg)
+	object to_object(closure arg)
+	object to_object(object arg)
+
+DESCRIPTION
+	The argument is converted into an object, if possible.
+	For strings, the object with a matching object_name() is
+	returned, or 0 if there is none, as find_object() does.
+	For (bound!) closures, the object holding the closure is
+	returned.
+	Objects and the number 0 return themselves.
+
+SEE ALSO
+	find_object(E), to_array(E), to_int(E), to_string(E)
diff --git a/doc/efun/to_string b/doc/efun/to_string
new file mode 100644
index 0000000..1d23ef6
--- /dev/null
+++ b/doc/efun/to_string
@@ -0,0 +1,29 @@
+SYNOPSIS
+        string to_string(mixed arg)
+
+BESCHREIBUNG
+        <arg> wird in einen String umgewandelt. Das klappt mit Werten vom Typ
+        int, float, object, array, struct, symbol, string oder closure.
+
+        Closures werden in einen passenden Namen umgewandelt (vorwiegend fuer
+        Debugging-Zwecke geeignet).
+
+ANMERKUNGEN
+        Arrays werden als "explodete" Strings betrachtet, also Arrays von
+        Zeichencodes. Sie werden bis zur ersten 0 oder bis zum ersten
+        nicht-numerischen Eintrag "implodet", je nachdem, was zuerst eintritt.
+
+        Das bedeutet, dass to_string( ({ 49, 50 }) ); "12" liefert, und nicht
+        "({ 49, 50 })"
+
+FEHLER
+        Die Cast-Schreibweise funktioniert nur, wenn der genaue Wert von
+        <value> zum Zeitpunkt der Kompilierung bekannt ist. Dies wird nicht
+        geaendert werden, da die Funktionsform verwendet werden kann.
+
+GESCHICHTE
+        LDMud 3.2.8 laesst Lambdaclosures als gueltige Datentypen zu.
+        LDMud 3.3.250 laesst structs als gueltige Datentypen zu.
+
+SIEHE AUCH
+        to_array(E), to_int(E), to_object(E), to_struct(E), sprintf(E)
diff --git a/doc/efun/to_struct b/doc/efun/to_struct
new file mode 100644
index 0000000..e5b0bfa
--- /dev/null
+++ b/doc/efun/to_struct
@@ -0,0 +1,47 @@
+SYNOPSIS
+        mixed to_struct(mixed *|mapping data)
+        mixed to_struct(mixed *|mapping data, struct template)
+        mixed to_struct(struct data)
+        mixed to_struct(struct data, struct template)
+
+DESCRIPTION
+        The given array, mapping or struct <data> is returned as a struct.
+        If a <template> struct is given, the returned struct is of the same
+        type. Without a template, an anonymous struct is returned in case of
+        arrays and mappings and in case of structs <data> is returned
+        unchanged.
+
+        If <data> is an array, its elements are assigned in order to the
+        resulting struct. For an anonymous struct, all elements of <data>
+        are assigned, for a templated struct only as many as fit into
+        the struct.
+
+        If <data> is a mapping and no template is given, the resulting
+        anonymous struct contains all elements from <data> with a string
+        key; the key name is used as struct member name.
+
+        If <data> is a mapping and a template is given, the struct
+        member names are used as keys for lookups in <data>; the found
+        data is assigned to the struct members.
+
+        If <data> is a struct and a template is given, a struct of the type
+        of template is created and all members from <data> are copied to the
+        new struct, which exist in both structs. This conversion is only
+        allowed between a struct and one of its base structs or a base struct
+        and one of its children. Otherwise an error is raised.
+
+        Neither <data> nor <template> will be changed in this process - the
+        result is a new struct value. The actual value of <template> does not
+        matter, only its type.
+
+        Since the returned struct can't be known at compile time, the
+        efun is declared to return 'mixed'.
+
+HISTORY
+        Introduced in LDMud 3.3.250 .
+        LDMud 3.3.344 added the template argument.
+        LDMud 3.3.433 added the conversion from mappings.
+        LDMud 3.3.720 added the conversion of structs into another struct.
+
+SEE ALSO
+        to_array(E), to_string(E), mkmapping(E), structs(LPC)
diff --git a/doc/efun/trace b/doc/efun/trace
new file mode 100644
index 0000000..36edc79
--- /dev/null
+++ b/doc/efun/trace
@@ -0,0 +1,54 @@
+GESCHUETZT
+SYNOPSIS
+        #include <sys/trace.h>
+
+        int trace(int traceflags);
+
+BESCHREIBUNG
+        Setzt die Trace Flags und liefert die alten Trace Flags zurueck.
+        Wenn Tracing eingeschaltet ist, wird waehrend der Ausfuehrung eine
+        Menge Informationen ausgegeben. Zu viel Output kann die Verbindung
+        lahm legen oder sogar den ganzen Treiber zum Absturz bringen.
+
+        Tracing erfolgt auf einer Pro-Verbindung-Basis: jeder interaktive (!)
+        User kann sein eigenes Tracelevel und -praefix festlegen. Jeder
+        erhaelt nur den Traceoutput fuer den Code, der waehrend der
+        Auswertung eines vom User eingegeben Kommandos ausgefuehrt wird.
+
+        Die Trace-Bits (aus <trace.h>) sind:
+
+            TRACE_NOTHING       (  0): Beendet das Tracing
+            TRACE_CALL          (  1): Tracet alle Aufrufe von Lfuns
+            TRACE_CALL_OTHER    (  2): Tracet alle call_other() Aufrufe
+            TRACE_RETURN        (  4): Tracet Resultate von Funktionen
+            TRACE_ARGS          (  8): Gibt Argumente und Resultate von
+                                       Funktionen aus
+            TRACE_EXEC          ( 16): Tracet alle ausgefuehrten Anweisungen
+            TRACE_HEART_BEAT    ( 32): Tracet den Heartbeat Code
+            TRACE_APPLY         ( 64): Tracet Treiber-Applies
+            TRACE_OBJNAME       (128): Gibt den Namen des Objektes aus
+
+        TRACE_EXEC und TRACE_HEART_BEAT sollten nicht verwendet werden, weil
+        sie massiven Output verursachen. TRACE_OBJNAME sollte nicht verwendet
+        werden, wenn bekannt ist, welches Objekt getracet wird.
+
+        Die Master-Lfun valid_trace() wird mit ("trace", traceflags)
+        aufgerufen, um die Erlaubnis fuer die Nutzung von trace() zu erhalten.
+
+BEISPIEL
+        object obj;
+        string prefix;
+        obj=find_player("thomas");
+        prefix=objec_name(obj);
+        prefix=prefix[1..strlen(prefix)-1];  /* entfernt den Praefix "/" */
+        traceprefix(prefix);
+        /* Von hier an wird nur Code im Objekt std/player#69 getracet */
+        trace(TRACE_CALL|TRACE_CALL_OTHER|TRACE_RETURN|TRACE_ARGS);
+        ...
+        trace(TRACE_NOTHING);
+
+AENDERUNGEN
+        LDMud 3.2.9 uebergibt auch <traceflags> an valid_trace()
+
+SIEHE AUCH
+        traceprefix(E)
diff --git a/doc/efun/traceprefix b/doc/efun/traceprefix
new file mode 100644
index 0000000..0f46f45
--- /dev/null
+++ b/doc/efun/traceprefix
@@ -0,0 +1,25 @@
+SYNOPSIS:
+        string traceprefix(string prefix)
+        string traceprefix(int dummy)
+
+DESCRIPTION:
+        If called with a string, only objects matching this prefix will
+        be traced. The string must not contain a leading "/" because
+        the object names are stored internally without it. If called
+        with a number, the traceprefix will be ignored and all objects
+        will be traced. Returns the last traceprefix or 0 if there
+        wasn't any.
+
+EXAMPLE:
+        object obj;
+        string prefix;
+        obj = find_player("deepthought");
+        prefix = object_name(obj);
+        prefix = prefix[1..strlen(prefix)-1]; /* cut off the leading "/" */
+        traceprefix(prefix);
+        trace(1|2|4|8);
+        ...
+        trace(0);
+        
+SEE ALSO:
+        trace(E)
diff --git a/doc/efun/transfer b/doc/efun/transfer
new file mode 100644
index 0000000..b413f02
--- /dev/null
+++ b/doc/efun/transfer
@@ -0,0 +1,25 @@
+VERALTET
+SYNOPSIS
+        int transfer(object item, object dest)
+
+BESCHREIBUNG
+        Diese Funktion existiert lediglich aus Kompatibilitaetsgrunden, und
+        dann auch nur, wennn der Driver mit USE_DEPRECATED kompiliert wird.
+
+        Das Object <item> wird in Objekt <dest> bewegt. Verschiedene Tests
+        werden durchgefuehrt, und das Resultat beschreibt den (Miss)Erfolg:
+
+        0: Erfolg.
+        1: Zu schwer fuer <dest>
+        2: Kann nicht fallen gelassen werden.
+        3: Kann nicht aus seinem  Behaelter genommen werden.
+        4: <item> kann in keinen Behaelter gesteckt werden.
+        5: <dest> akzeptiert <item> nicht.
+        6: <item> kann nicht aufgenommen werden.
+
+        Die Funktion ruft die lfuns add_weight(), drop(), get(),
+        prevent_insert(), add_weight(), und can_put_and_get() nach Bedarf..
+
+SIEHE AUCH
+         move_object(E), drop(A), get(A), prevent_insert(A),
+         can_put_and_get(A), add_weight(A)
diff --git a/doc/efun/transpose_array b/doc/efun/transpose_array
new file mode 100644
index 0000000..68e2a78
--- /dev/null
+++ b/doc/efun/transpose_array
@@ -0,0 +1,22 @@
+SYNOPSIS:
+	mixed *transpose_array (mixed *arr);
+
+DESCRIPTION:
+	transpose_array ( ({ ({1,2,3}), ({a,b,c}) }) )
+			== ({ ({1,a}), ({2,b)}, ({3,c}) }) 
+
+	transpose_array() applied to an alist results in an array of
+	({ key, data }) pairs, useful if you want to use sort_array()
+	or filter() on the alist.
+
+EXAMPLE:
+	sort_array(transpose_array( ({ m_indices(map), m_values(map) }) ),
+		   lambda( ({ 'a, 'b }),
+			   ({ #'<, ({ #'[, 'a, 0 }),
+				   ({ #'[, 'b, 0}) }) ) )
+
+	The given mapping 'map' is returned as an array of 
+	({ key,	data })  pairs, sorted by the keys.
+
+SEE ALSO:
+	alists(LPC), sort_array(E)
diff --git a/doc/efun/trim b/doc/efun/trim
new file mode 100644
index 0000000..4525a82
--- /dev/null
+++ b/doc/efun/trim
@@ -0,0 +1,33 @@
+SYNOPSIS
+        #include <sys/strings.h>
+
+        string trim(string str);
+        string trim(string str, int where);
+        string trim(string str, int where, string char);
+
+BESCHREIBUNG
+        Entfernt alle vorausgehenden und abschliessenden Zeichen <char> in
+        einem String <str> und gibt den neuen String zurueck.
+
+        <char> kann entweder ein oder mehrere Zeichen sein. Wird <char> nicht
+        angegeben, wird standardmaessig der Leerschlag " \t" genutzt.
+
+        Mit <where> kann angegeben werden, wo Zeichen entfernt werden:
+
+            TRIM_LEFT   (1):        entfernt alle vorausgehenden
+                                    Zeichen <char>
+            TRIM_RIGHT  (2):        entfernt alle abschliessenden
+                                    Zeichen <char>
+            TRIM_BOTH   (3 oder 0): entfernt sowohl vorausgehende als auch
+                                    abschliessende Zeichen <char>
+
+BEISPIEL
+        trim("    1234    ");                       ergibt: "1234"
+        trim("    1234    ", TRIM_RIGHT);           ergibt: "    1234"
+        trim("    1234    ", TRIM_BOTH, " 1");      ergibt: "234"
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7
+
+SIEHE AUCH
+        regreplace(E)
diff --git a/doc/efun/typeof b/doc/efun/typeof
new file mode 100644
index 0000000..151bb96
--- /dev/null
+++ b/doc/efun/typeof
@@ -0,0 +1,13 @@
+SYNOPSIS
+        int typeof(mixed arg);
+
+BESCHREIBUNG
+        Gibt einen Code fuer den Typ des Arguments <arg>. Die Typen sind
+        definiert in <sys/lpctypes.h>
+
+AENDERUNGEN
+        Eingefuehrt in 3.2@63
+
+SIEHE AUCH
+        get_type_info(E), intp(E), objectp(E), floatp(E), pointerp(E),
+        closurep(E), symbolp(E), stringp(E), mappingp(E)
diff --git a/doc/efun/unbound_lambda b/doc/efun/unbound_lambda
new file mode 100644
index 0000000..804b1b5
--- /dev/null
+++ b/doc/efun/unbound_lambda
@@ -0,0 +1,27 @@
+SYNOPSIS
+        closure unbound_lambda(mixed *arg, mixed code);
+
+BESCHREIBUNG
+        Erzeugt eine Lambda-Closure, die nicht an ein Objekt gebunden ist,
+        entsprechend einer Lambda-Funktion in LISP.
+
+        Die Closure kann keine Referenz zu globalen Variablen enthalten.
+        Lfun-Closures werden unveraendert in die Closure eingebunden, da es
+        kein Ursprungsobjekt fuer diese Closure gibt.
+
+        Bevor die Closure aufgerufen werden kann, muss sie an ein Objekt
+        gebunden werden. Normale Objekte koennen Closures nur an sich selbst
+        binden, das Binden an andere Objekte erzeugt eine Schutzverletzung.
+
+        Der Punkt ist, dass previous_object() fuer Aufrufe innerhalb der
+        Closure auf das Objekt zeigt, das bind_lambda() aufgerufen hat, und
+        alle objekt- oder uid-basierten Sicherheitschecks beziehen sich
+        auf jenes Objekt.
+
+        Das erste Argument <*arg> ist ein Array, das die Argumente (Symbole)
+        enthaelt, die an die Closure uebergeben werden, wenn diese mit
+        funcall() oder apply() ausgewertet wird. Das zweite Argument <code>
+        enthaelt den Code der Closure.
+
+SIEHE AUCH
+        closures(LPC), lambda(E), apply(E), funcall(E), bind_lambda(E)
diff --git a/doc/efun/unique_array b/doc/efun/unique_array
new file mode 100644
index 0000000..390c56e
--- /dev/null
+++ b/doc/efun/unique_array
@@ -0,0 +1,47 @@
+SYNOPSIS
+        mixed unique_array(object *obj, string|closure fun)
+        mixed unique_array(object *obj, string|closure fun, mixed skip)
+        mixed unique_array(object *obj, string|closure fun, mixed extra...
+                                      , mixed skip)
+
+BESCHREIBUNG
+        Gruppiert alle Objekte aus <*obj>, fuer die die Funktion <fun>
+        den gleichen Wert liefert. Wenn <*obj> etwas anderes als Objekte
+        enthaelt, werden diese ignoriert.
+        
+        Ist die Funktion mit Namen angegeben, wird sie in jedem Objekt
+        in <*obj> einmal aufgerufen. Wurden <extra> Argumente
+        gegeben, werden diese an die Funktion bei jedem Aufruf als
+        Parameter uebergeben.
+
+        Ist die Funktion als Closure angegeben, wird sie fuer jedes Objekt
+        in <*obj> einmal aufgerufen, wobei das Objekt als erstes Argument
+        uebergeben wird, gefolgt von etwaiigen <extra> Argumenten.
+
+        Wird ein Argument <skip> angegeben (bei Verwendung von <extra>
+        Argumenten muss dies geschehen), und entspricht <skip> dem
+        Resultat von <separator> fuer ein Element aus <*obj>, so wird
+        dieses Element nicht in das Resultat von unique_array()
+        uebernommen.
+        
+        Das Resultat von unique_array() hat die Form:
+
+            ({ ({same1:1, same1:2, ... same1:n}),
+               ({same2:1, same2:2, ... same2:n}),
+               ({samem:1, samem:2, ... samem:n}) })
+
+BEISPIEL
+        Um ein Array von Arrays zu erhalten, das alle Benutzer, nach Level
+        gruppiert, enthaelt:
+
+            mixed *arr;
+            arr=unique_array(users(), "_query_level", -1);
+
+        Goetter haben einen Level von -1. Sie werden nicht in arr aufgenommen,
+        weil <skip> == -1.
+
+SIEHE AUCH
+      Arrays:       filter(E), map(E)
+      Objektarrays: filter_objects(E), map_objects(E)
+      Mappings:     filter(E), map(E), filter_indices(E), map_indices(E)
+
diff --git a/doc/efun/unmkmapping b/doc/efun/unmkmapping
new file mode 100644
index 0000000..3beeccb
--- /dev/null
+++ b/doc/efun/unmkmapping
@@ -0,0 +1,27 @@
+SYNOPSIS
+        *mixed unmkmapping(mapping map);
+
+BESCHREIBUNG
+        Wandelt das Mapping <map> in ein Array von Arrays aus, das alle Keys
+        und Werte von <map> enthaelt und gibt dieses Array zurueck.
+
+        Das Resultat von unmkmapping() hat die Form ({ keys[], data0[],
+        data1[] ... }), wobei keys[] ein Array aller Keys ist, data0[] ein
+        Array mit allen Werten aus der ersten Spalte, data1[] ein Array mit
+        allen Werten aus der zweiten Spalte etc. Das heisst, dass die
+        Werte von key[x] in data0[x], data1[x] usw. gespeichert sind.
+
+        unmkmapping() ist die Umkehrfunktion von mkmapping(), sodass gilt:
+
+            apply(#'mkmapping, unmkmapping(m)) == m
+
+BEISPIEL
+        mapping m = ([ 1:10;20, 2:11;21 ]);
+        unmkmapping(m) ergibt: ({ ({1, 2}) , ({10, 11}) , ({20, 21}) })
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6.
+
+SIEHE AUCH
+        mappings(LPC), mappingp(E), m_indices(E), m_values(E), m_delete(E),
+        sizeof(E), widthof(E).
diff --git a/doc/efun/unquote b/doc/efun/unquote
new file mode 100644
index 0000000..8000060
--- /dev/null
+++ b/doc/efun/unquote
@@ -0,0 +1,17 @@
+SYNOPSIS
+        quoted_array unquote(quoted_array arr);
+        string|symbol unquote(symbol sym);
+
+BESCHREIBUNG
+        Entfernt ein Quote von einem gequoteten Array oder Symbol. Wenn das
+        letzte Quote von einem Symbol entfernt wird, entsteht ein String.
+
+BEISPIELE:
+        unquote('foo);              ergibt: "foo"
+        unquote( '({1,2,3}) );      ergibt: ({1,2,3})
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        quote(E), symbolp(E)
diff --git a/doc/efun/unshadow b/doc/efun/unshadow
new file mode 100644
index 0000000..688d5ff
--- /dev/null
+++ b/doc/efun/unshadow
@@ -0,0 +1,21 @@
+FUNKTION
+     void unshadow()
+
+BESCHREIBUNG
+     Das aufrufende Objekt wird als Shadow von allen anderen Objekten
+     entfernt, denen es uebergeworfen war. Wenn dem aufrufenden Objekt
+     selbst ein Shadow uebergeworfen war, wird dieser entfernt.
+     Man sollte diese (s)efun rufen, bevor man den Schatten zerstoert.
+
+BEISPIELE
+     // B beschattet A
+     void b::stop_shadowing() {
+       unshadow();
+     }
+
+SIEHE AUCH
+     Generell:	     shadow(E)
+     Rechte:	     query_allow_shadow(M), query_prevent_shadow(L)
+     Informationen:  query_shadowing(E)
+
+20.08.2009, Zesstra
diff --git a/doc/efun/upper_case b/doc/efun/upper_case
new file mode 100644
index 0000000..ac1ffa5
--- /dev/null
+++ b/doc/efun/upper_case
@@ -0,0 +1,12 @@
+SYNOPSIS
+        string upper_case(string str);
+
+BESCHREIBUNG
+        Wandelt alle Zeichen in <str> in Grossbuchstaben um und gibt das
+        Resultat zurueck.
+
+BEISPIEL
+        upper_case("Heya!")     ergibt: "HEYA!"
+
+SIEHE AUCH
+        capitalize(E), lower_case(E)
diff --git a/doc/efun/users b/doc/efun/users
new file mode 100644
index 0000000..48b4ae3
--- /dev/null
+++ b/doc/efun/users
@@ -0,0 +1,5 @@
+SYNOPSIS
+        *object users();
+
+BESCHREIBUNG
+        Liefert ein Array, das alle interaktiven Benutzer enthaelt.
diff --git a/doc/efun/utime b/doc/efun/utime
new file mode 100644
index 0000000..96218af
--- /dev/null
+++ b/doc/efun/utime
@@ -0,0 +1,22 @@
+SYNOPSIS
+        *int utime()
+
+BESCHREIBUNG
+        Liefert ein Array der Zeit, die seit dem 01. Januar 1970,
+        00:00:00 GMT vergangen ist, mit Genauigkeit in Mikrosekunden
+        (0.000001 Sekunden).
+
+        Zurueck gegeben wird ein Array der Form:
+            int[0]: Anzahl Sekunden seit Beginn der Zeitrechnung
+            int[1]: Anzahl Mikrosekunden innerhalb der aktuellen Sekunde
+
+BEISPIEL
+        write(ctime(utime())+"\n");
+
+        Gibt das aktuelle Datum und Zeit zurueck.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9.
+
+SIEHE AUCH
+        ctime(E), gmtime(E), localtime(E), time(E)
diff --git a/doc/efun/variable_exists b/doc/efun/variable_exists
new file mode 100644
index 0000000..1bbd843
--- /dev/null
+++ b/doc/efun/variable_exists
@@ -0,0 +1,29 @@
+SYNOPSIS
+        #include <functionlist.h>
+
+        string variable_exists(string str [, int flags]);
+        string variable_exists(string str, object obj [, int flags]);
+
+BESCHREIBUNG
+        Sucht eine Varialbe <str> in this_object() oder (falls angegeben)
+        im Objekt <obj>.
+
+        Das Resultat ist der Name des Programms, in dem die Variable definiert
+        ist. Das kann entweder object_name(obj) sein oder der Name eines
+        geerbten Programms. Wenn sich der Treiber nicht im Compat-Modus
+        befindet, beginnt der zurueck gelieferte Name immer mit '/'.
+
+        Wird <flags> NAME_HIDDEN gesetzt, so liefert variable_exists() auch
+        Informationen ueber Variablen vom Typ "static" und "protected" in
+        anderen Objekten. Es ist nicht moeglich, Informationen ueber "private"
+        deklarierte Variablen zu erhalten.
+
+        Wird die Variable nicht gefunden (weil sie nicht existiert oder weil
+        sie fuer das aufrufende Objekt nicht sichtbar sind), wird 0 zurueck
+        geliefert.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.10.
+
+SIEHE AUCH
+        function_exists(E), variable_list(E)
diff --git a/doc/efun/variable_list b/doc/efun/variable_list
new file mode 100644
index 0000000..673b377
--- /dev/null
+++ b/doc/efun/variable_list
@@ -0,0 +1,60 @@
+GESCHUETZT
+SYNOPSIS
+        #include <sys/functionlist.h>
+        #include <sys/lpctypes.h>
+
+        *mixed variable_list(object obj, int flags = RETURN_FUNCTION_NAME);
+
+BESCHREIBUNG
+        Liefert ein Array mit Informationen ueber die Variablen von <obj>.
+        Fuer jede Variable werden 1 bis 4 Werte in diesem Array gespeichert,
+        abhaengig von <flags>. Die Resultate werden in dieser Reihenfolge
+        im Array abgespeichert:
+          - der Name der Variablen
+          - die Flags der Variablen (siehe weiter unten)
+          - der Rueckgabetyp (gemaess mudlib/sys/lpctypes.h)
+          - der Wert der Variablen
+
+        <obj> kann als Objekt oder als Dateinamen uebergeben werden. Im
+        zweiten Fall versucht variable_list() nicht, das Objekt vor der
+        Verarbeitung zu laden.
+
+        Wenn <obj> nicht das aufrufende Objekt ist und der Wert der Variablen
+        abgefragt wird, erzeugt dies eine Schutzverletzung ("variable_list",
+        <obj>).
+
+        Mit <flags> wird festgelegt, welche Informationen ueber welche
+        Variablen abgefragt werden. Folgende Flags aus <sys/functionlist.h>
+        koennen mit binaerem Oder kombiniert werden:
+
+        Auswahl der gesammelten Information:
+            RETURN_FUNCTION_NAME    liefert den Namen der Variablen
+            RETURN_FUNCTION_FLAGS   liefert die Flags der Variablen (s. unten)
+            RETURN_FUNCTION_TYPE    liefert den Rueckgabetyp
+            RETURN_VARIABLE_VALUE   liefert den Wert der Variablen
+
+        Auswahl der Variablen, die ausgewertet werden:
+            NAME_INHERITED        schliesst geerbte Variablen aus
+            TYPE_MOD_STATIC       schliesst "static" deklarierte Variablen aus
+            TYPE_MOD_NOSAVE       schliesst "nosave" deklarierte Variablen aus
+            TYPE_MOD_PRIVATE      schliesst "private" deklarierte Variablen aus
+            TYPE_MOD_PROTECTED    schliesst "protected" deklarierte Variablen
+                                  aus
+            NAME_HIDDEN           enthaelt Variablen, die geerbt wurden.
+
+        Die Flags der Variablen koennen die Auswahl-Flags enthalten und
+        zusaeztlich folgende Werte:
+            TYPE_MOD_VIRTUAL      die Variable wurde virtuell geerbt
+            TYPE_MOD_NO_MASGK     die Variable ist "nomask" deklariert
+            TYPE_MOD_PUBLIC       die Variable ist "public" deklariert
+
+        All diese Flags sind in mudlib/sys/functionlist.h definiert und
+        sollten an einen allgemein zugaenglichen Platz kopiert werden.
+        Die Rueckgabewerte sind in mudlib/sys/lpctypes.h definiert, die
+        auch in die Mudlib kopiert werden sollten.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.10
+
+SIEHE AUCH
+        inherit_list(E), functionlist(E), variable_exists(E)
diff --git a/doc/efun/walk_mapping b/doc/efun/walk_mapping
new file mode 100644
index 0000000..7396fcf
--- /dev/null
+++ b/doc/efun/walk_mapping
@@ -0,0 +1,88 @@
+walk_mapping(E)
+
+FUNKTION:
+        void walk_mapping(mapping m, string fun [, mixed extra, ...])
+        void walk_mapping(mapping m, string fun, string|object ob
+                                                , mixed extra,...)
+        void walk_mapping(mapping m, closure cl, mixed extra,...)
+
+PARAMETER:
+     m		- durchzugehendes Mapping
+     fun/cl	- zu rufende Methode/Closure
+     ob		- Objekt/Dateiname, an dem Methode gerufen werden soll
+     extra	- weitere Parameter fuer Methode/Closure
+
+BESCHREIBUNG:
+     Ruft die Methode fuer jeden Eintrag im Mapping:
+      ob->func(key, value1, ..., valueN, extra,...)
+     beziehungsweise fuehrt die Closure fuer jeden dieser Eintraege aus:
+      funcall(cl, key, value1, ..., valueN, extra,...)
+
+     Die Schluessel werden als Wert uebergeben und die dazugehoerigen Werte
+     per Referenz, diese koennen somit also in der Funktion/Closure geaendert
+     werden.
+
+
+     Verwendung von Methoden:
+	Wenn bei der Angabe von 'fun' kein Objekt 'ob' in Form eines Strings
+	oder Objekts angegeben wird, wird this_object() angenommen.
+
+     Verwendung von Closures:
+	Es koennen sowohl Lfun-Closures als auch Lambda-Closures verwendet
+	werden. Lfun-Closures koennen, wenn im selben Objekt vorhanden auch
+	'private' oder/und 'static' deklariert sein, muessen aber zu dem
+	Zeitpunkt der Verwendung bekannt sein (Funktionsprototypen benutzen).
+
+BEISPIELE:
+     // Liste mit Spielern durchgehen ...
+     mapping x=([ [/human:liafar]:  20,
+		  [/dwarf:mesirii]: 50,
+		  [/elf:zarniya]:   40,
+		  [/feline:turbo]:  30]);
+
+     // ... und Werte aendern:
+     void add_val(object key, int val, int add) {
+       if(key->InFight())
+         val+=add;
+       else
+         val-=add;
+     }
+
+     // verschiedene Aufrufarten, identisches Resultat:
+     walk_mapping(x, "add_val", 0, 10);
+     walk_mapping(x, "add_val", this_object(), 10
+     walk_mapping(x, "add_val", "/players/jof/addierobjektmitmethode", 10);
+
+     walk_mapping(x, #'add_val, 10);
+
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     // so richtig aequivalent wird es nur mit einer Closure hier
+     int i, width;
+     mapping input;
+     mixed *index, *param;
+
+     width=get_type_info(input)[1];
+     param=allocate(width);
+     index=m_indices(input);
+     i=sizeof(index);
+     while(i--) {
+       j=width;
+       while(j-- > 1)
+         param[j]=input[index[i],j];
+       j[0]=index[i];
+
+       apply(cl, param);
+       // fun(index[i], input[index[i],0], input[index[i],1], ...);
+      }
+
+SIEHE AUCH:
+     Arrays:		filter(E), map(E)
+     Objektarrays:	filter_objects(E), map_objects(E)
+     Mappings:		filter_indices(E), map_indices(E)
+
+     Sonstiges:		m_contains(E)
+			member()
+			m_indices(E), m_values(E)
+
+20.Jan 2005 Gloinson
diff --git a/doc/efun/widthof b/doc/efun/widthof
new file mode 100644
index 0000000..e3ac599
--- /dev/null
+++ b/doc/efun/widthof
@@ -0,0 +1,16 @@
+SYNOPSIS
+        int widthof(mapping map);
+
+BESCHREIBUNG
+        Liefert die Anzahl Values pro Key im Mapping <map>. Wenn <map> 0 ist,
+        ist das Resultat 0.
+
+BEISPIEL
+        mapping map = (["foo" : 1;2]);
+        widthof(map)    ergibt 2.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.6
+
+SIEHE AUCH
+        sizeof(E), mkmapping(E), m_reallocate(E), m_values(E), unmkmapping(E)
diff --git a/doc/efun/wizlist_info b/doc/efun/wizlist_info
new file mode 100644
index 0000000..674ec9a
--- /dev/null
+++ b/doc/efun/wizlist_info
@@ -0,0 +1,38 @@
+SYNOPSIS
+        #include <wizlist.h>
+
+        mixed * wizlist_info()
+
+DESCRIPTION
+        Returns an array with the interesting entries of the wizlist.
+        Needs to be privileged by the master object.
+
+        The result is an array with one entry for every wizard (uid).
+        Every entry is an array itself:
+
+          string w[WL_NAME]        = Name of the wizard.
+          int    w[WL_COMMANDS]    = Weighted number of commands execute by
+                                     objects of this wizard.
+          int    w[WL_COST],
+          int    w[WL_GIGACOST]       = Weighted sum of eval_costs.
+          int    w[WL_TOTAL_COST],
+          int    w[WL_TOTAL_GIGACOST] = Total sum of eval_costs.
+          int    w[WL_HEART_BEATS]   = Weighted count of heart_beats.
+          int    w[WL_CALL_OUT]      = Reserved for call_out() (unused yet).
+          int    w[WL_ARRAY_TOTAL]   = Total size of arrays in elements.
+          int    w[WL_MAPPING_TOTAL] = Total size of mappings in elements.
+          int    w[WL_STRUCT_TOTAL]  = Total size of structs in elements.
+          mixed  w[WL_EXTRA]         = Extra wizlist-info if set.
+
+        The 'weighted' entries decay every hour by 10%.
+
+HISTORY
+        LDMud 3.2.10 split the old WL_EVAL_COST into WL_COST and WL_GIGACOST
+          to accomodate for longer uptimes, and introduced
+          WL_TOTAL_COST/WL_TOTAL_GIGACOST.
+        LDMud 3.3.174 added WL_MAPPING_TOTAL.
+        LDMud 3.3.? added WL_STRUCT_TOTAL.
+
+SEE ALSO
+        privilege_violation(M), set_extra_wizinfo_size(E)
+        get_extra_wizinfo(E), set_extra_wizinfo(E)
diff --git a/doc/efun/write b/doc/efun/write
new file mode 100644
index 0000000..a3041b0
--- /dev/null
+++ b/doc/efun/write
@@ -0,0 +1,37 @@
+SYNOPSIS:
+        void write(mixed msg)
+
+DESCRIPTION:
+        Write out something to the current player. What exactly will
+        be printed in the end depends of the type of msg.
+        Please mind: if there is no current player (this_player()), the
+        function will output directly to the driver debug log. Please check
+        before!
+        
+        If it is a string or a number then just prints it out.
+        
+        If it is an object then the object will be printed in the
+        form: "OBJ("+object_name((object)mix)+")"
+        
+        If it is an array just "<ARRAY>" will be printed.
+        
+        If the write() function is invoked by a command of an living
+        but not interactive object and the given argument is a string
+        then the lfun catch_tell() of the living will be invoked with
+        the message as argument.
+
+EXAMPLES:
+        write("Hello world!\n");
+        
+        Just print out a string.
+        
+        write(this_player());
+        
+        This will print out something like "OBJ(std/player#1234)".
+        
+        write( ({ "blub" }) );
+        
+        Will print out "<ARRAY>".
+        
+SEE ALSO:
+        say(E), tell_object(E), tell_room(E), shout(E), catch_tell(L)
diff --git a/doc/efun/write_bytes b/doc/efun/write_bytes
new file mode 100644
index 0000000..bb75484
--- /dev/null
+++ b/doc/efun/write_bytes
@@ -0,0 +1,11 @@
+SYNOPSIS
+        int write_bytes(string file, int start, string str);
+
+BESCHREIBUNG
+        Schreibt den String <str> ins File <file> und ueberschreibt dabei die
+        alten Bytes ab Position <start>. Wenn <start> eine negative Zahl ist,
+        werden die Zeichen vom Ende von <file> an gezaehlt. write_bytes()
+        liefert 1 bei Erfolg, 0 bei Misserfolg.
+
+SIEHE AUCH
+        save_object(E), write_file(E)
diff --git a/doc/efun/write_file b/doc/efun/write_file
new file mode 100644
index 0000000..e79fb6b
--- /dev/null
+++ b/doc/efun/write_file
@@ -0,0 +1,14 @@
+SYNOPSIS
+        int write_file(string file, string str);
+        int write_file(string file, string str, int flags);
+
+BESCHREIBUNG
+        Haengt den String <str> an die Datei <file> an. Liefert 1 bei Erfolg,
+        0 bei Misserfolg.
+
+        If <flags> = 1, dann wird die Datei vor dem eigentlichen
+        Schreiben geloescht; das 'anhaengen' wird so effektiv ein
+        'ueberschreiben'. Defaultwert fuer <flags> ist 0.
+
+SIEHE AUCH
+        file_size(E), cat(E), write_bytes(E), read_file(E), rm(E)
diff --git a/doc/efun/xml_generate b/doc/efun/xml_generate
new file mode 100644
index 0000000..86506e0
--- /dev/null
+++ b/doc/efun/xml_generate
@@ -0,0 +1,77 @@
+OPTIONAL
+EXPERIMENTAL
+SYNOPSIS
+        #include <xml.h>
+
+        string xml_generate(mixed *xml)
+
+BESCHREIBUNG
+        Wandelt das uebergebene <xml>-Array in einen XML-konformen String um,
+        sofern moeglich. Der <xml>-Parameter muss folgende Struktur haben:
+
+        Er muss Tag-Arrays mit folgenden drei Elementen enthalten:
+
+            string XML_TAG_NAME
+                Der Name des XML-Tags.
+
+            mapping XML_TAG_ATTRIBUTES
+                Alle Attribute dieses XML-Tags als ein Mapping mit dem
+                jeweiligen Attributnamen als Schluessel und den Attributwert
+                als der dazugehoerige String.
+                
+                Falls ein XML-Tag keine Attribute enthaelt, so ist dieses
+                Element 0.
+
+            mixed * XML_TAG_CONTENTS
+                Der Inhalt des XML-Tags als ein Array. Dieses Array kann
+                entweder Strings (reine Zeichendaten) oder Arrays
+                als weitere Tags enthalten, welche wiederum diese
+                drei Elemente besitzen.
+                
+                Falls das XML-Tag nichts enthaelt, so ist dieses Element 0.
+
+        Falls der uebergebe Parameter nicht diese Struktur besitzt, so wird
+        eine Fehlermeldung ausgegeben. Ansonsten ist ein gueltiger XML-String
+        das Resultat.
+
+        Diese Funktion ist nur verfuegbar, wenn der Driver mit Iksemel-
+        Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __XML_DOM__ definiert.
+
+BEISPIEL
+        xml_generate(({ "abc", 0, 0 })) -> "<abc/>"
+        xml_generate(({ "abc", ([ "xyz" : "cde" ]), 0 })) -> "<abc xyz="cde"/>"
+
+        mixed* xml = ({ "buch"
+                      , ([ "sprache" : "deutsch" ])
+                      , ({ ({ "titel"
+                            , 0
+                            , ({ "Dies ist der Titel" })
+                           })
+                         , ({ "kapitel"
+                            , 0
+                            , ({ "Dies ist ein Kapitel" })
+                           })
+                         , ({ "kapitel"
+                            , 0
+                            , ({ "Das soll "
+                               , ({ "b"
+                                  , 0 
+                                  , ({ "fettgedruckt" })
+                                 })
+                               , " sein."
+                              })
+                           })
+                        })
+                     })
+
+        xml_generate(xml)
+            -> "<buch sprache="deutsch"><titel>Dies ist der Titel</titel>"
+               "<kapitel>Dies ist ein Kapitel</kapitel><kapitel>Das soll "
+               "<b>fettgedruckt</b> sein.</kapitel></buch>"
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.718.
+
+SIEHE AUCH
+        xml_parse(E)
diff --git a/doc/efun/xml_parse b/doc/efun/xml_parse
new file mode 100644
index 0000000..4649c9a
--- /dev/null
+++ b/doc/efun/xml_parse
@@ -0,0 +1,78 @@
+OPTIONAL
+EXPERIMENTAL
+SYNOPSIS
+        #include <xml.h>
+
+        mixed* xml_parse(string xml)
+
+BESCHREIBUNG
+        Parst den angegebenen String <xml> als XML. Der String darf nur ein
+        einziges Root-Tag enthalten, weitere Root-Tags werden ignoriert.
+
+        Falls der String XML-konform war, so wird ein Array mit drei Elementen
+        zurueckgegeben, dessen Elemente folgendermassen definiert sind:
+
+            string XML_TAG_NAME
+                Der Name des XML-Tags.
+
+            mapping XML_TAG_ATTRIBUTES
+                Alle Attribute dieses XML-Tags als ein Mapping mit dem
+                jeweiligen Attributnamen als Schluessel und den Attributwert
+                als der dazugehoerige String.
+                
+                Falls ein XML-Tag keine Attribute enthaelt, so ist dieses
+                Element 0.
+
+            mixed * XML_TAG_CONTENTS
+                Der Inhalt des XML-Tags als ein Array. Dieses Array kann
+                entweder Strings (reine Zeichendaten) oder Arrays
+                als weitere Tags enthalten, welche wiederum diese
+                drei Elemente besitzen.
+                
+                Falls das XML-Tag nichts enthaelt, so ist dieses Element 0.
+
+        Falls der XML-String nicht wohlgeformt ist oder falls nicht genug Speicher
+        zur Verfuegung steht, wird eine Fehlermeldung ausgegeben.
+
+        Diese Funktion ist nur verfuegbar, wenn der Driver mit Iksemel-
+        Unterstuetzung compiliert wurde. In diesem Fall ist das Makro
+        __XML_DOM__ definiert.
+
+BEISPIEL
+        xml_parse("<abc/>")           -> ({ "abc", 0, 0 })
+        xml_parse("<abc xyz="cde"/>") -> ({ "abc", ([ "xyz" : "cde" ]), 0 })
+
+        xml_parse("<buch sprache="deutsch">" + 
+                  "    <titel>Dies ist der Titel</titel>" + 
+                  "    <kapitel>Dies ist ein Kapitel</kapitel>" + 
+                  "    <kapitel>Das soll <b>fettgedruckt</b> sein.</kapitel>" +
+                  "</buch>")
+
+            -> ({ "buch"
+                , ([ "sprache" : "deutsch" ])
+                , ({ ({ "titel"
+                      , 0
+                      , ({ "Dies ist der Titel" })
+                     })
+                   , ({ "kapitel"
+                      , 0
+                      , ({ "Dies ist ein Kapitel" })
+                     })
+                   , ({ "kapitel"
+                      , 0
+                      , ({ "Dies soll "
+                         , ({ "b"
+                            , 0 
+                            , ({ "fettgedruckt" })
+                           })
+                         , "sein."
+                        })
+                     })
+                  })
+               })
+
+GESCHICHTE
+        Eingefuehrt in LDMud 3.3.718.
+
+SIEHE AUCH
+        xml_generate(E)
diff --git a/doc/efun/xor_bits b/doc/efun/xor_bits
new file mode 100644
index 0000000..6f9eab9
--- /dev/null
+++ b/doc/efun/xor_bits
@@ -0,0 +1,19 @@
+SYNOPSIS
+        string xor_bits(string str1, string str2);
+
+BESCHREIBUNG
+        <str1> und <str2> sind beiden Bitstrings. Das Resultat von xor_bits()
+        ist ein Bitstring mit dem binaeren XOR von <str1> und <str2>, also
+        ein String, in dem ein Bit nur gesetzt ist, wenn es entweder in <str1>
+        oder in <str2> vorkommt, nicht aber in beiden.
+
+BEISPIELE
+        string s1, s2, s3;
+        s1 = set_bit("", 3); s1 = set_bit(s1, 15);  -> s1 ist "( ("
+        s2 = set_bit("", 3); s2 = set_bit(s2, 4);   -> s2 ist "8"
+        s3 = xor_bits(s1, s2);
+        -> s3 ist "0 (", es sind also das 4. und das 15. Bit gesetzt.
+
+SIEHE AUCH
+        clear_bit(E), set_bit(E), test_bit(E), next_bit(E), last_bit(E)
+        count_bits(E), and_bits(E), or_bits(E), invert_bits(E), copy_bits(E)
diff --git a/doc/events/EVT_GUILD_ADVANCE b/doc/events/EVT_GUILD_ADVANCE
new file mode 100644
index 0000000..f421f43
--- /dev/null
+++ b/doc/events/EVT_GUILD_ADVANCE
@@ -0,0 +1,36 @@
+EVENT: 
+   EVT_GUILD_ADVANCE
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/gilden_ob.c
+
+BESCHREIBUNG:
+   Dieser Event wird immer ausgeloest, wenn sich der Gildenlevel eines
+   Spielers erhoeht oder auch, wenn nur der Gildenlevel eines Spielers von
+   einer Gilde geaendert wird (weil sie keine Gildenlevel kennt).
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBJECT:         (object) Spielerobjekt
+      E_PLNAME:         (string) UID/Spielername
+      E_ENVIRONMENT:    (object) Environment des Spielers
+      E_GUILDNAME:      (string) Gildenname
+      P_GUILD_LEVEL     (string) s. Property, neuer Gildenlevel
+      P_GUILD_TITLE:    (string) s. Property, neuer Gildentitel
+      P_SUBGUILD_TITLE: (string) s. Property, neuer Subguild-Title
+    ])
+
+BEMERKUNGEN:
+   Wenn Gilden keine Gildenlevel kenne, sondern andere Formen des Gildenstatus
+   vergeben und der Gildentitel allein nicht ausreicht,  muss hier ueber eine
+   Ergaenzung der Daten nachgedacht werden.
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+16.08.2007, Zesstra
+
diff --git a/doc/events/EVT_GUILD_CHANGE b/doc/events/EVT_GUILD_CHANGE
new file mode 100644
index 0000000..4acb906
--- /dev/null
+++ b/doc/events/EVT_GUILD_CHANGE
@@ -0,0 +1,31 @@
+EVENT: 
+   EVT_GUILD_CHANGE
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /secure/gildenmaster.c
+
+BESCHREIBUNG:
+   Dieser Event wird immer ausgeloest, wenn ein Spieler eine Gilde wechselt.
+   Da Spieler bei einem Gildenaustritt in ihrer Standardgilde landen, ist
+   jeder Aus- und Eintritt letztendlich ein Wechsel.
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBJECT:         (object) Spielerobjekt, was die Gilde wechselte,
+      E_PLNAME:         (string) UID/Playername des Spielers,
+      E_ENVIRONMENT:    (object) Environment des Spielers,
+      E_GUILDNAME:      (string) neue Gilde,
+      E_LAST_GUILDNAME: (string) alte Gilde,
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+16.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_ADVANCE b/doc/events/EVT_LIB_ADVANCE
new file mode 100644
index 0000000..9dd8fd1
--- /dev/null
+++ b/doc/events/EVT_LIB_ADVANCE
@@ -0,0 +1,30 @@
+EVENT: 
+   EVT_LIB_ADVANCE
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/gilde.c
+
+BESCHREIBUNG:
+   Dieses Event wird ausgeloest, wenn sich der Spielerlevel eines Spielers
+   aendert. (Momentan erhoeht er sich nur.)
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBJECT:         (object) Spielerobjekt
+      E_PLNAME:         (string) UID/Spielername
+      E_ENVIRONMENT:    (object) Environment des Spielers
+      E_GUILDNAME:      (string) Name der Gilde des Spielers
+      P_LEVEL:          (int) s. Prop, neuer Spielerlevel
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+16.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_CLOCK b/doc/events/EVT_LIB_CLOCK
new file mode 100644
index 0000000..22ff451
--- /dev/null
+++ b/doc/events/EVT_LIB_CLOCK
@@ -0,0 +1,32 @@
+EVENT: 
+   EVT_LIB_CLOCK
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /obj/uhr.c
+
+BESCHREIBUNG:
+   Alle Viertelstunde wird dieser Event gerufen. Wenn man Ereignisse jeweils
+   zur vollen Stunde, xx:15, xx:30 und xx:45 durchfuehren will, bietet es sich
+   an, diesem Event zu lauschen.
+
+EVENT-DATEN:
+   Die Daten sind ein Mapping mit den Arrayindizes von localtime() als Keys
+   und den dazu gehoerigen Daten als Values.
+
+BEMERKUNGEN:
+   Will man ermitteln, in welcher Viertelstunde man sich gerade befindet,
+   bietet sich ((minuten/15) % 4) an. Das ergibt immer eine Zahl zwischen 0
+   und 3. 0-> volle Stunde, 1-> viertel nach, 2-> halb, 3-> viertel vor voll.
+   Hierbei wird nach Benachrichtigen der Objekt um ueblicherweise 0-2s
+   verzoegert, wenn es als wirklich exakt sein muss, laesst sich dieser Event
+   dann doch nicht verwenden.
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+28.11.2012, Zesstra
+
diff --git a/doc/events/EVT_LIB_DATECHANGE b/doc/events/EVT_LIB_DATECHANGE
new file mode 100644
index 0000000..3638b49
--- /dev/null
+++ b/doc/events/EVT_LIB_DATECHANGE
@@ -0,0 +1,24 @@
+EVENT: 
+   EVT_LIB_DATECHANGE
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /obj/uhr.c
+
+BESCHREIBUNG:
+   Dieser Event tritt auf, wenn sich das Datum aendert. Also immer um 00:00.
+
+EVENT-DATEN:
+   Die Daten sind ein Mapping mit den Arrayindizes von localtime() als Keys
+   und den dazu gehoerigen Daten als Values.
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+   EVT_LIB_CLOCK
+-----------------------------------------------------------------------------
+28.11.2012, Zesstra
+
diff --git a/doc/events/EVT_LIB_LOGIN b/doc/events/EVT_LIB_LOGIN
new file mode 100644
index 0000000..22cba32
--- /dev/null
+++ b/doc/events/EVT_LIB_LOGIN
@@ -0,0 +1,32 @@
+EVENT: 
+   EVT_LIB_LOGIN
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/player/base.c
+
+BESCHREIBUNG:
+   Ein Spieler hat sich gerade eingeloggt.
+   Bitte beachten: Objekt im Inventar und im Environment eines Spieler sollten
+   weiterhin BecomesNetAlive() benutzen! Dieser Event ist nur fuer Objekte
+   gedacht, die das Einloggen mitkriegen wollen, aber nicht in der Naehe des
+   Spieler sind.
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBJECT:      (object) Objekt des eingeloggten Spielers,
+      E_PLNAME:      (string) UID/Name des eingeloggten Spielers,
+      E_ENVIRONMENT: (object) Environment nach dem Einloggen,
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+   EVT_LIB_LOGOUT
+
+-----------------------------------------------------------------------------
+16.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_LOGOUT b/doc/events/EVT_LIB_LOGOUT
new file mode 100644
index 0000000..b3b3afa
--- /dev/null
+++ b/doc/events/EVT_LIB_LOGOUT
@@ -0,0 +1,32 @@
+EVENT: 
+   EVT_LIB_LOGOUT
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/player/base.c
+
+BESCHREIBUNG:
+   Ein Spieler hat sich gerade ausgeloggt.
+   Bitte beachten: Objekt im Inventar und im Environment eines Spieler sollten
+   weiterhin BecomesNetDead() benutzen! Dieser Event ist nur fuer Objekte
+   gedacht, die das Ausloggen mitkriegen wollen, aber nicht in der Naehe des
+   Spieler sind.
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBJECT:      (object) Objekt des ausgeloggten Spielers,
+      E_PLNAME:      (string) UID/Name des ausgeloggten Spielers,
+      E_ENVIRONMENT: (object) letztes Environment vor dem Ausloggen,
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+   EVT_LIB_LOGIN
+
+-----------------------------------------------------------------------------
+16.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_MINIQUEST_SOLVED b/doc/events/EVT_LIB_MINIQUEST_SOLVED
new file mode 100644
index 0000000..932f02d
--- /dev/null
+++ b/doc/events/EVT_LIB_MINIQUEST_SOLVED
@@ -0,0 +1,29 @@
+EVENT: 
+   EVT_LIB_MINIQUEST_SOLVED
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /secure/questmaster.c
+
+BESCHREIBUNG:
+   Dieser Event wird vom Questmaster ausgeloest, wenn ein Spieler eine
+   Miniquest geloest hat.
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBJECT:        (object) Questgeber-Objekt,
+      E_OBNAME:        (string) Objektname des Questgebers
+      E_PLNAME:        (string) Spielername,
+      E_MINIQUESTNAME: (string) Titel der Miniquest
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+2014-Feb-03, Arathorn
+
diff --git a/doc/events/EVT_LIB_NEW_ERROR b/doc/events/EVT_LIB_NEW_ERROR
new file mode 100644
index 0000000..9c04648
--- /dev/null
+++ b/doc/events/EVT_LIB_NEW_ERROR
@@ -0,0 +1,31 @@
+EVENT: 
+   EVT_LIB_NEW_ERROR
+
+DEFINIERT IN:
+   /sys/events.h
+   /secure/errord.h (Konstanten fuer Eventdaten sind dort definiert)
+
+GETRIGGERT VON:
+   /secure/errord.c
+
+BESCHREIBUNG:
+   Ein neuer Fehlereintrag wurde im ErrorD eingetragen. Hierbei muss es kein
+   echter Fehler sein, sondern kann auch eine Warnung oder eine Idee eines
+   Spielers sein (alle Fehlertypen T_* aus /secure/errord.h sind moeglich).
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ F_TYPE:     (int) Typ des Fehlereintrags
+      F_HASHKEY:  (string) ID des Fehlereintrages
+      F_UID:      (string) UID des Objektes, in welchen der Fehler auftrat
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd,
+   fehlerteufel
+
+-----------------------------------------------------------------------------
+07.09.2011, Zesstra
+
diff --git a/doc/events/EVT_LIB_NPC_DEATH b/doc/events/EVT_LIB_NPC_DEATH
new file mode 100644
index 0000000..6b1fb00
--- /dev/null
+++ b/doc/events/EVT_LIB_NPC_DEATH
@@ -0,0 +1,69 @@
+EVENT: 
+   EVT_LIB_NPC_DEATH(x)
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/living/life.c
+
+BESCHREIBUNG:
+   Dieser Event wird immer dann von einem NPC ausgeloest, wenn dieser gerade
+   getoetet wurde (um genau zu sein: im die()).
+   Dieser Event macht vermutlich die meisten Die-Hooks einfach unnoetig, da es
+   bei vielen nur darum geht, zu erfahren, ob der NPC tot ist, wer ihn
+   getoetet hat und ob derjenige genug Schaden gemacht hat. Dies laesst sich
+   aus den Daten dieses Event ebenfalls ermitteln, ohne den Aufwand eines
+   Hooks zu betreiben.
+
+   Bitte beachtet, dass in diesem Fall das ebenfalls gelieferte triggernde
+   Objekt (der NPC) bereits zerstoert ist, wenn ihr den Event empfangt,
+   'trigob' also 0 ist! Ihr muesst also den Eintrag E_OBNAME im Datenmapping 
+   des Events nutzen, um herauszufinden, welcher NPC getoetet wurde.
+
+PARAMETER:
+   Der an das Event-Define zu uebergebende Parameter "x" muss ein String 
+   sein.
+   Uebergibt man den Leerstring "", registriert man sich fuer das globale
+   Event EVT_LIB_NPC_DEATH(""), ueber das der Tod saemtlicher NPCs 
+   weitergemeldet wird.
+   Uebergibt man den load_name() des Zielobjekts als Parameter, so werden
+   nur die Tode von NPCs gemeldet, die sich von der Blueprint des
+   Zielobjekts ableiten, also auch aller Clones.
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBNAME:        (string)   Objektname des getoeteten NPCs,
+      E_ENVIRONMENT:   (object)   Environment des Opfer beim Tod,
+      E_TIME:          (int)      Zeitstempel des Todes,
+      P_NAME:          (string,string*)  P_NAME,
+      P_KILLER:        (object)   der Killer, s. Property,
+      P_ENEMY_DAMAGE:  (mapping)  s. Manpage P_ENEMY_DAMAGE,
+      P_LAST_DAMAGE:   (int)      s. Property,
+      P_LAST_DAMTYPES: (string *) s. Property,
+      E_EXTERNAL_DEATH:(int)      Flag, ob die() von aussen gerufen,
+      E_POISON_DEATH:  (int)      Flag, ob der Tod durch Gift ausgeloest,
+      E_CORPSE:        (object)   Leiche, sofern es eine gibt
+      P_XP:            (int)      P_XP,
+      P_ATTRIBUTES:    (int*)     P_ATTRIBUTES,
+      P_MAX_HP:        (int)      P_MAX_HP,
+      P_HANDS:         (mixed)    P_HANDS,
+      P_ALIGN:         (int)      P_ALIGN)
+      P_RACE:          (string)   P_RACE,
+      P_CLASS:         (string*)  P_CLASS,
+    ])
+
+BEMERKUNGEN:
+   Bei der Registrierung fuer die Todes-Events von einzelnen NPCs kann es 
+   im Fall von VC-generierten NPCs zu unerwarteten Effekten kommen, da hier
+   load_name() fuer jedes Objekt den Namen des VC-Standardobjekts 
+   zurueckliefert.
+   Die Registrierung fuer das Todes-Event eines einzelnen Clones ist nicht
+   moeglich.
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+21.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_PLAYER_ATTR_CHANGE b/doc/events/EVT_LIB_PLAYER_ATTR_CHANGE
new file mode 100644
index 0000000..8ad2fd4
--- /dev/null
+++ b/doc/events/EVT_LIB_PLAYER_ATTR_CHANGE
@@ -0,0 +1,24 @@
+EVENT: 
+   EVT_LIB_PLAYER_ATTR_CHANGE
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/living/life.c
+
+BESCHREIBUNG:
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ 
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+16.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_PLAYER_CREATION b/doc/events/EVT_LIB_PLAYER_CREATION
new file mode 100644
index 0000000..abff825
--- /dev/null
+++ b/doc/events/EVT_LIB_PLAYER_CREATION
@@ -0,0 +1,31 @@
+EVENT: 
+   EVT_LIB_PLAYER_CREATION
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/player/base.c
+
+BESCHREIBUNG:
+   Dieser Event wird vom Spielerobjekt ausgeloest, wenn sich ein Spieler
+   erstmalig ins MorgenGrauen eingeloggt hat.
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_PLNAME:       (string) UID/Name des erstellten Spielers,
+      E_OBJECT:       (object) Objekt des Spielers,
+    ])
+
+BEMERKUNGEN:
+   Da zu diesem Zeitpunkt das Spielerobjekt noch nicht vollstaendig
+   konfiguriert ist, werden nur Objekt und Spielername in den Daten 
+   uebermittelt.
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+   EVT_LIB_PLAYER_DELETION
+
+-----------------------------------------------------------------------------
+16.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_PLAYER_DEATH b/doc/events/EVT_LIB_PLAYER_DEATH
new file mode 100644
index 0000000..45e5598
--- /dev/null
+++ b/doc/events/EVT_LIB_PLAYER_DEATH
@@ -0,0 +1,36 @@
+EVENT: 
+   EVT_LIB_PLAYER_DEATH
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/living/life.c
+
+BESCHREIBUNG:
+   Dieser Event wird immer dann von einem Spielerobjekt ausgeloest, wenn 
+   der Spieler  gerade getoetet wurde (um genau zu sein: im die()).
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBJECT:        (object) Objekt des getoeteten Spielers,
+      E_PLNAME:        (string) UID/Playername des getoeteten Spielers, 
+      E_ENVIRONMENT:   (object) Environment des Opfer beim Tod,
+      E_TIME:          (int) Zeitstempel des Todes,
+      P_LAST_KILLER:   (object) Der Killer, s. Property
+      P_LAST_DAMAGE:   (int) s. Property,
+      P_LAST_DAMTYPES: (string *) s. Property,
+      P_LAST_DEATH_PROPS: (mixed) s. Property
+      E_EXTERNAL_DEATH:(int) Flag, ob die() von aussen gerufen,
+      E_POISON_DEATH:  (int) Flag, ob der Tod durch Gift ausgeloest,
+      E_CORPSE:        (object) Leiche, sofern es eine gibt
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+21.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_PLAYER_DELETION b/doc/events/EVT_LIB_PLAYER_DELETION
new file mode 100644
index 0000000..7d63856
--- /dev/null
+++ b/doc/events/EVT_LIB_PLAYER_DELETION
@@ -0,0 +1,32 @@
+EVENT: 
+   EVT_LIB_PLAYER_DELETION
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/player/base.c
+
+BESCHREIBUNG:
+   Dieser Event wird vom Spielerobjekt ausgeloest, wenn sich ein Spieler
+   mittels "selbstloeschung" loescht. Der Event wird umittelbar vor der
+   Zerstoerung des Spielerobjekts ausgeloest.
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_PLNAME:       (string) UID/Name des geloeschten Spielers,
+      E_ENVIRONMENT:  (object) letztes Environment des Spielers,
+      E_GUILDNAME:    (string) Name der letzten Gilde des Spielers,,
+    ])
+
+BEMERKUNGEN:
+   Wenn Spieler vom Loeschscript erfasst oder vom Sheriff oder einem EM
+   geloescht werden, wird dieser Event natuerlich nicht ausgeloest.
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+   EVT_LIB_PLAYER_CREATION
+
+-----------------------------------------------------------------------------
+16.08.2007, Zesstra
+
diff --git a/doc/events/EVT_LIB_QUEST_SOLVED b/doc/events/EVT_LIB_QUEST_SOLVED
new file mode 100644
index 0000000..6abbfc9
--- /dev/null
+++ b/doc/events/EVT_LIB_QUEST_SOLVED
@@ -0,0 +1,30 @@
+EVENT: 
+   EVT_LIB_QUEST_SOLVED
+
+DEFINIERT IN:
+   /sys/events.h
+
+GETRIGGERT VON:
+   /std/player/quests.c
+
+BESCHREIBUNG:
+   Dieser Event wird vom Spielerobjekt ausgeloest, wenn der Spieler eine Quest
+   geloest hat.
+
+EVENT-DATEN:
+   Die Daten werden als Mapping uebergeben:
+   ([ E_OBJECT:         (object) Spielerobjekt,
+      E_PLNAME:         (string) Spielername,
+      E_ENVIRONMENT:    (object) Environment des Spielers,
+      E_QUESTNAME:      (string) Name der Quest,
+      E_QP_GRANTED:     (int)    vergebene Abenteuerpunkte,
+    ])
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+   events, RegisterEvent(), UnregisterEvent(), TriggerEvent(), eventd
+
+-----------------------------------------------------------------------------
+2014-Feb-03, Arathorn
+
diff --git a/doc/events/eventd b/doc/events/eventd
new file mode 100644
index 0000000..790e35f
--- /dev/null
+++ b/doc/events/eventd
@@ -0,0 +1,29 @@
+Event-Dispatcher: /p/daemon/eventd.c
+
+BENUTZUNG:
+   #include <events.h>
+   EVENTD->fun(bla);
+
+BESCHREIBUNG:
+   Der Event-Dispatcher merkt sich Event und Daten, die ihr ueber
+   TriggerEvent() an ihn meldet und informiert mit kurzer Zeitverzoegerung
+   alle fuer den jeweiligen Event-Typ angemeldeten Objekte.
+
+FUNKTIONEN:
+   - RegisterEvent(): anmelden fuer einen Event
+   - UnregisterEvent(): von einem Event abmelden
+   - TriggerEvent(): einen Event melden
+   - CheckEventID(): wieviele Lauscher gibt es fuer den Event?
+
+BEMERKUNGEN:
+   Wenn Bedarf fuer einen spezialisierten Event-Dispatcher besteht, der
+   Sonderfunktionen hat oder auch nicht-oeffentliche Events anbietet, besteht
+   die Moeglichkeit, den normalen eventd zu erben. Bitte sprecht in dem Fall
+   aber bitte vorher Zesstra an.
+
+SIEHE AUCH:
+   events, 
+   RegisterEvent(), UnregisterEvent(), TriggerEvent(), CheckEventID()
+
+18.08.2007, Zesstra
+
diff --git a/doc/events/events b/doc/events/events
new file mode 100644
index 0000000..fa0dfa8
--- /dev/null
+++ b/doc/events/events
@@ -0,0 +1,120 @@
+Was sind Events?
+================
+Events im MorgenGrauen sind Ereignisse, die von beliebigen Objekten ausgeloest
+werden koennen. Es gibt eine Reihe von vordefinierten Ereignissen, die die
+Basis-Lib bereitstellt (s.u.). Zusaetzlich zu diesen koennen Magier beliebige
+weitere Events erstellen bzw. benutzen.
+
+Wenn ein Objekt dem zentralen Event-Dispatcher einen bestimmten Event meldet,
+merkt dieser sich dies und die Daten, die ihm vom ausloesenden Objekt
+uebergeben wurde. Mit kurzer Verzoegerung (0-2s) informiert der
+Event-Dispatcher dann alle Objekte, die sich fuer diesen Event interessieren,
+d.h. dafuer angemeldet sind. Hierzu ruft er eine bestimmte Funktion in den
+angemeldeten Objekten auf.
+Hierbei ist zu beachten, dass die informierten Objekte das Ereignis in keinem
+Fall mehr beeinflussen koennen, da es bereits abgeschlossen wurde. Es ist
+lediglich eine Information ueber das Ereignis. Wenn ein Objekt Einfluss nehmen
+will (z.B. auf einen Tod), ist dafuer ein Hook zu verwenden.
+
+
+Welche Events definiert die Mudlib?
+==================================
+Diese Events haben in /sys/events.h vordefinierte Event-IDs und werden von der
+Basis-Mudlib mit den entsprechenden Daten ausgeloest (s. jew. Event):
+- EVT_LIB_LOGIN: Login eines Spielers
+- EVT_LIB_LOGOUT: Logout eines Spielers
+- EVT_LIB_PLAYER_DEATH: Ein Spieler ist gestorben
+- EVT_LIB_PLAYER_DELETION: Ein Spieler hat sich geloescht
+- EVT_LIB_PLAYER_CREATION: Ein Spieler wurde neu angelegt.
+- EVT_LIB_NPC_DEATH(): Ein NPC ist gestorben (Parameter s. Event-Manpage)
+- EVT_LIB_ADVANCE: Ein Spieler hat seine Spielerstufe erhoeht
+- EVT_LIB_PLAYER_ATTR_CHANGE: Die Attribute eines Spielers wurden geaendert
+- EVT_LIB_CLOCK: Die volle Stunde ist erreicht
+- EVT_LIB_DATECHANGE: Ein neuer Tag ist angebrochen. ;-)
+- EVT_LIB_QUEST_SOLVED: Ein Spieler hat eine Quest geloest
+- EVT_LIB_MINIQUEST_SOLVED: Ein Spieler hat eine Miniquest geloest
+
+Gilden muessen definieren (ggf. via /std/gilden_ob.c):
+- EVT_GUILD_CHANGE: Spieler hat seine Gilde gewechselt.
+- EVT_GUILD_ADVANCE: Ein Spieler hat seine Gildenstufe erhoeht
+
+
+Namenskonvention fuer Event-IDs:
+===============================
+- Die IDs aller Standardevents beginnen mit "evt_lib_". 
+  Dementsprechend sind alle Strings, die damit anfangen, fuer ALLE ausser 
+  der Mudlib TABU! D.h.
+  - diese Events werden NIEMALS von Objekten ausserhalb der Basislib
+    ausgeloest!
+  - es duerfen keine Events registriert werden, die mit dieser Zeichenfolge
+    anfangen, ausser mit den symbolischen Namen in /sys/events.h
+- Gilden-Events beginnen mit "evt_guild_", sofern es ein Event ist, den jede
+  Gilde definiert (s. /sys/events.h).
+  Die Events einzelner Gilden sollten mit "evt_gildenname_" beginnen.
+- Die IDs einzelner Magier sollten am besten zwecks Eindeutigkeit mit
+  "magiername_" beginnen.
+
+
+Was ist als lauschendes Objekt zu beachten?
+==========================================
+Das lauschende Objekt muss zunaechst /sys/events.h inkludieren und sich
+mittels Aufrufs von RegisterEvent() als Lauscher registrieren.
+Weiterhin muss es eine Funktion oeffentlich definieren (Name beliebig), die
+der EVENTD aufrufen kann. Diese Funktion bekommt 3 Argumente uebergeben:
+Event-ID, event-ausloesendes Objekt und die Event-Daten:
+   public void listen_event(string eid, object trigob, mixed data);
+'data' ist ein Datentyp, der vom Eventtyp abhaengt. Oft handelt es sich
+um ein Mapping. Fuer eine genaue Beschreibung schaut bitte die in die Manpage
+des konkreten Events.
+
+Bitte beachten: Die Daten in 'data' im Falle eines Arrays/Mappings niemals
+aendern. Aus Effizienzgruenden wird 'data' nicht kopiert, bevor es an die
+einzelnen Objekte uebergeben wird. Wenn ihr also Muell reinschreibt, werden
+nach euch informierte Lauscher euren Schrott empfangen. Sollte hier
+'Missbrauch' auffallen, wird das entsprechend geahndet!
+
+Und zum Schluss: Bitte missbraucht die Events nicht und meldet euch (speziell 
+fuer haeufige Events) nur an, wenn ihr mit den Informationen was sinnvolles 
+macht (also z.B. nicht nur, um ein Log der getoeteten NPCs im Spiel zu 
+erstellen. ;-)).
+
+
+Was ist als ausloesendes Objekt zu beachten?
+===========================================
+Eigentlich gar nicht viel. Ihr muesst lediglich /sys/events.h inkludieren und
+bei Auftreten des Events die Funktion TriggerEvent() im EVENTD aufrufen und
+ihr die Event-ID und die Event-Daten uebergeben.
+Bitte uebergebt als Event-Daten ggf. Kopien von Mappings/Arrays, da lauschende
+Objekte diese Daten veraendern koennen.
+
+
+Beispiele:
+========
+1. Ein Objekt moechte ueber Spielertode informiert werden:
+     EVENTD->RegisterEvent(EVT_LIB_PLAYER_DEATH, "spieler_ist_tot", 
+                           this_object());
+   Ab jetzt wird im Objekt jedes Mal, wenn ein Spieler stirbt, die Funktion
+   "spieler_ist_tot" aufgerufen.
+
+2. Ein Objekt moechte nicht mehr ueber Spielertode informiert werden:
+     EVENTD->UnregisterEvent(EVT_LIB_PLAYER_DEATH, this_object());
+
+3. Ein Objekt will informiert werden, wenn der Event
+   "boing_zwergenkoenig_angriff" ausgeloest wird:
+     EVENTD->RegisterEvent("boing_zwergenkoenig_angriff","alarm",
+                           this_object());
+
+4. Der Zwergenkoenig (oder einer seiner Waechter) wird angegriffen:
+   EVENTD->TriggerEvent("boing_zwergenkoenig_angriff", daten);
+   Anschliessend wird jedes Objekt, das es wissen will (s. 3.) vom EVENTD
+   informiert und kriegt dabei 'daten' uebergeben. Dies kann ein beliebiger
+   Datentyp sein (z.b. ein Mapping). In diesem Fall enthaelt 'daten'
+   zweckmaessigerweise den Angreifer.
+
+
+Siehe auch:
+==========
+  eventd, TriggerEvent(), RegisterEvent(), UnregisterEvent()
+
+18.08.2007, Zesstra
+
diff --git a/doc/help/.readme b/doc/help/.readme
new file mode 100644
index 0000000..0b2a57f
--- /dev/null
+++ b/doc/help/.readme
@@ -0,0 +1,3 @@
+Hier befinden sich Hilfen zu allgemeinen Themen, die sowohl fuer Spieler
+als auch fuer Magier von Interesse sind.
+
diff --git a/doc/help/.synonym b/doc/help/.synonym
new file mode 100644
index 0000000..893c568
--- /dev/null
+++ b/doc/help/.synonym
@@ -0,0 +1,138 @@
+4gewinnt spiele
+abalone spiele
+abenteuerpunkte abenteuer
+abkuerzung abk
+abkuerzungen abk
+akuefi abk
+alkohol essen_trinken
+anbetung gott
+anfaenger einfuehrung
+armageddon reboot
+attribut attribute
+ausdauer attribute
+bezugsobjekt bezugspunkt
+boing gott
+buch buecher
+ciceronen cicerones
+clients client
+cpu mudrechner
+dart spiele
+doppelkopf spiele
+eks erstkillstufenpunkte
+erstkills erstkillstufenpunkte
+erstie zweitspieler
+erstspieler zweitspieler
+essen essen_trinken
+facebook sozialmedien
+feier parties
+fete parties
+fluch gift
+flueche gift
+ftp mudrechner
+fussball spiele
+geschick attribute
+geschicklichkeit attribute
+gesundheit lebenspunkte
+getraenke essen_trinken
+getraenk essen_trinken
+gifte gift
+gilde gilden
+gladiopolis spiele
+gmcp GMCP
+goetter gott
+google sozialmedien
+go spiele
+heilen heilung
+herzschlag leben
+hp leben
+intelligenz attribute
+jof gott
+kaempfen kampf
+kneipe heilung
+kneipen heilung
+konzentrationspunkte zauberei
+konzentration zauberei
+kraft attribute
+krankheiten gift
+krankheit gift
+lars tod
+lebenspunkte leben
+loeschen loeschskript
+loeschung loeschskript
+lp leben
+maexchen spiele
+magiepunkte zauberei
+magie zauberei
+metzeln kampf
+minesweeper spiele
+miniquests stufenpunkte
+miniquest stufenpunkte
+mpa zeitung
+nahrung essen_trinken
+netlag lag
+netzlag lag
+netz mudrechner
+orakel zaubertraenke
+party parties
+portale sehertore
+portal sehertore
+qp abenteuer
+quest abenteuer
+questen abenteuer
+questliste abenteuerliste
+questpunkte abenteuer
+quests abenteuer
+rage spiele
+rechner mudrechner
+regel regeln
+region regionen
+regionsmagier regionen
+rodeln spiele
+rumata gott
+saufen essen_trinken
+schach spiele
+scripte regeln
+script regeln
+scripts regeln
+seherportale sehertore
+seherportal sehertore
+sehertor sehertore
+skat spiele
+skripte regeln
+skript regeln
+skripts regeln
+speicher mudrechner
+speise essen_trinken
+speisen essen_trinken
+spielerloeschen loeschskript
+spielerloeschung loeschskript
+spielertestie spielertesties
+staerke attribute
+tablut spiele
+tanke heilung
+tanken heilung
+team teamkampf
+testie spielertesties
+testies spielertesties
+testspieler spielertesties
+tf client
+todesfolgen tod
+todesmalus tod
+tot tod
+trinken essen_trinken
+ts3 teamspeak
+ts teamspeak
+twitter sozialmedien
+umlaute syntax
+verbindung client
+vergiftung gift
+waffenskills waffenfertigkeiten
+waffenskill waffenfertigkeiten
+waffen waffenfertigkeiten
+waffe waffenfertigkeiten
+zaubertrank zaubertraenke
+zauber zauberei
+zook gott
+zt zaubertraenke
+zweities zweitspieler
+zweitie zweitspieler
diff --git a/doc/help/GMCP b/doc/help/GMCP
new file mode 100644
index 0000000..600ad88
--- /dev/null
+++ b/doc/help/GMCP
@@ -0,0 +1,356 @@
+General Mud Communication Protocol im MorgenGrauen
+==================================================
+
+0. Einleitung
+   GMCP wird benutzt, um Daten zwischen MUD und Client "out of band" zu
+   uebertragen. "Out of band" bedeutet hier, dass der Datenaustausch hinter
+   den Kulissen passiert statt in der normalen textuellen Spielausgabe,
+   welcher vom Client mittels mehr oder weniger komplizierter Trigger
+   ausgewertet werden muss.
+
+   Vorteile:
+   * keine komplexen Trigger (Regexps) mehr.
+   * Daten werden in einem definierten Format uebertragen, welches der Client
+     fuer euch interpretiert.
+   * keine Gagtrigger mehr noetig, um empfangenen Text auszublenden
+   * keine stoerenden Ausgaben, falls man diese Gagtrigger nicht hat.
+   * Daten koennen auch uebertragen werden in Situationen, in denen eine
+     normale Textausgabe nicht so gut geht, z.B. in Editoren.
+   * Daten, die die Clientscripte nicht verarbeiten, stoeren nicht den
+     Textfluss.
+   * Der Client kann konfigurieren, welche Informationen er bekommen will.
+   * Im MG ist neben Dingen wie LP und KP die Uebertragung div. anderer Dinge
+     geplant, vor allem andere Informationen  ueber den Char oder den Raum
+     (z.B. eindeutige Raum-IDs (in den meisten Faellen)).
+
+
+1. Unterstuetzte Module
+
+1.1. Core (aus IRE (Iron Realms Entertainment) MUDs)
+  Das Core Modul ist immer aktiv. Es verwaltet die grundsaetzlichen
+  Einstellungen von GMCP. Die MG-Variante ist fast identisch zur IRE-Variante,
+  hat allerdings zusaetzliche das "Debug"-Kommando.
+
+  Vom Client gesendet:
+    - Core.Hello
+        Muss die erste Nachricht sein, welche der Client nach Aktivierung von
+        GMCP sendet.
+        Die Daten sind ein Objekt mit den Schluesseln "client" und "version",
+        welche entsprechend den Clientnamen und seine Versionskennung
+        enthalten.
+      Core.Hello { "client": "Nexus", "version": "3.1.90" }
+    - Core.Supports.Set
+        Informiert das MUD ueber die Pakete/Module, die der Client
+        unterstuetzt, d.h. die der Client empfangen kann. Es ist immer noch
+        Entscheidung des Muds, welche dieser Module ihre Daten senden (z.B.
+        wird MG einem "MG.char" den Vorzug geben vor einem generischen "Char",
+        falls vom Client beide unterstuetzt werden.
+        Wenn bereits vorher ein Core.Supports.* Kommando empfangen wurde, wird
+        die Liste der unterstuetzten Module durch die neue ersetzt.
+        Daten sind ein Array von Strings, welche jeweils den Modulnamen und
+        die Versionsnummer angeben (mit einem Leerzeichen getrennt).
+        Die Versionsnummer muss eine positive Ganzzahl sein.
+        Die meisten Clients werden Set nur einmal am Anfang senden und
+        brauchen kein Add/Remove.
+      Core.Supports.Set [ "MG.char 1", "MG.room 1" ]
+    - Core.Supports.Add
+        aehnlich zu Set, aber es fuegt die angegeben Module an die in der
+        Vergangenheit uebermittelten an.
+        Wenn noch keine Liste gesendet wurde, ist das Ergebnis wie bei Set.
+        Wenn die Liste Module enthaelt, die bereits aktiv sind, wird die neue
+        Versionsnummer Prioritaet vor der alten haben, selbst wenn die kleiner
+        ist.
+        Die Daten sind identisch zu Set.
+    - Core.Supports.Remove
+        Entfernt die angebenen Module aus der Liste der unterstuetzen Module.
+        Die Daten sind identisch zu Set. Die Modulversionen sind NICHT
+        optional (anders als bei IRE). Allerdings werden auch Module anderer
+        Version abgeschaltet. (Insofern koennte man - zur Zeit - einfach immer 1
+        als Versionsnummer senden.)
+    - Core.KeepAlive
+        Vom MG ignoriert, weil Verbindungen nicht automatisch getrennt werden.
+    - Core.Ping
+        Veranlasst das MG mit einem Core.Ping zu antworten.
+        Die Daten ist eine Ganzzahl, welche die durchschnittliche Pingzeit
+        aus verherigen Pings enthaelt, falls verfuegbar.
+        (Anmerkung: IRE macht keine Angabe ueber die Einheit dieser Zahl. MG
+         geht von Millisekunden aus.)
+      Core.Ping 120
+    - Core.Debug
+        Kann gesendet werden, um die Ausgabe von menschenlesbaren
+        Debugmeldungen vom GMCP zu aktivieren.
+        Die Daten sind eine Ganzzahl. Je groesser, desto mehr Debugmeldungen
+        werden ausgegeben.
+        0 schaltet die Debugmeldungen aus.
+        1 schaltet nur die Ausgabe von GMCP-Fehlern an.
+        100 schaltet alles an.
+      Core.Debug 1
+  Vom Server gesendet:
+    - Core.Ping
+        Als Antwort eines vom Client empfangenen Core.Ping gesendet.
+        Keine Daten.
+    - Core.Goodbye [NOT IMPLEMENTED YET!]
+        Gesendet vom MUD unmittelbar vor Verbindungstrennung.
+        Die Daten sind eine Nachricht (string), welche dem User angezeigt
+        werden kann und koennen den Grund fuer den Disconnect erklaeren.
+      Core.Goodbye "Goodbye, adventurer"
+
+1.2. MG.char 1 (angelehnt an Aardwolf, aber modifiziert)
+  Die Uebertragung der Kommandos in diesem Modul wird aktiviert, wenn
+  "MG.char" aktiv ist. Es gibt keine Submodule, die getrennt aktiviert werden
+  muessten. Die jeweiligen Kommandos werden gesendet, wenn sich eins der
+  gesendeten Daten aendert.
+  Alle Kommandos werden einmal bei Modulaktivierung gesendet (auch wenn ein
+  Modul durch ein Core.Supports.Set (erneut) aktiviert wird).
+  Ist dieses Modul vom Client unterstuetzt, werden keine Daten aus den
+  Modulen "Char" und "char" gesendet.
+  (Spieler aelter als 12.05.2013 muessen einmalig den textuellen Report mit
+   "report ein" und "report vorsicht" einschalten, damit die Uebertragung
+   via GMCP freigeschaltet wird. Der Report kann danach wieder
+   ausgeschaltet werden.)
+
+1.2.2. MG.char.base
+  Vom Server gesendet:
+    - MG.char.base
+      Einige grundlegende Eigenschaften des Chars, die sich selten aendern.
+      Ein "wizlevel" von 1 zeigt an, dass der Char ein Seher ist.
+      Der "title" kann am Anfang ein Backspace "\b" gefolgt von "," oder "'"
+      enthalten.
+      MG.char.base { "name": "Jof", "guild": "Abenteurer",
+                     "race": "Elf", "presay": "Mudgott",
+                     "title": "idlet.", "wizlevel": 101 }
+
+1.2.3. MG.char.vitals
+  Vom Server gesendet:
+    - MG.char.vitals
+      Aktuelle Lebenspunkte, Konzentrationspunkte und Vergiftungzustand.
+      Im Falle von Gift: je groesser, desto staerker die Vergiftung.
+      MG.char.vitals { "hp": 210, "sp": 90, "poison": 3 }
+    - MG.char.maxvitals
+      Aktuelle Maximalwerte fuer LP, KP und Vergiftungszustand. Werden in
+      einer separaten Gruppe uebertragen, weil sie sich viel seltener aendern.
+      MG.char.maxvitals { "max_hp": 210, "max_sp": 226, "max_poison": 10 }
+
+1.2.4. MG.char.attributes
+  Vom Server gesendet:
+    - MG.char.attributes
+      Aktuelle Attribute des Chars.
+      Die Daten sind ein Objekt Name-Wert-Paaren von Attributen.
+      MG.char.attributes { "int": 12, "con": 10, "str": 8, "dex": 12 }
+
+1.2.5. MG.char.infoVars
+  Vom Server gesendet:
+    - MG.char.infoVars
+      Diese Nachricht gibt den "technischen" Namen aus MG.char.info einen
+      Namen, der dem Spieler stattdessen angezeigt werden sollte.
+      Diese Nachricht wird nur bei Modulaktivierung gesendet.
+      Die Daten sind ein Objekt von Name-Beschreibung-Paaren.
+      MG.char.infoVars { "level": "Stufe", "guildlevel": "Gildenstufe" }
+
+1.2.6. MG.char.info
+  Vom Server gesendet:
+    - MG.char.info
+      Uebertraegt (ausgewaehlte) Daten aus dem Kommando <info>.
+      Die Daten sind ein Objekt von Name-Wert-Paaren.
+      (Moegliche weitere Angaben in der Zukunft: Questpunkte, Stufenpunkte
+       (Genauigkeit 20% einer Stufe), ...)
+      MG.char.info { "level": 210, "guildlevel": 9 }
+
+1.2.7. MG.char.wimpy
+  Vom Server gesendet:
+    - MG.char.wimpy
+      Aktuelle Vorsicht und ggf. Fluchtrichtung des Char.
+      Die Daten sind ein Objekt Name-Wert-Paare von Vorsicht+Fluchtrichtung.
+      Ist keine Fluchtrichtung gesetzt, wird 0 uebertragen.
+      Fuer die Uebermittlung der Vorsicht muss der Char die Quest "Der Schrat
+      kann nicht einschlafen" geloest haben und fuer die Fluchtrichtung
+      Seher sein.
+      MG.char.wimpy { "wimpy": 50, "wimpy_dir": "norden" }
+
+
+1.3. char 1 (Aardwolf)
+  Dieses Modul ist so aehnlich zum "char" Modul von Aardwolf wie es geht, d.h.
+  es benutzt die gleichen Schluesselnamen. Es ist aber reduziert im Umfang der
+  Daten, d.h. es uebertraegt weniger Daten als Aardwolf es tut.
+  Wann immer moeglich, wird empfohlen, das Modul MG.char stattdessen zu
+  verwenden.
+  Wenn MG.char aktiv ist, werden von diesem Modul keine Daten uebertragen.
+  ES WIRD DAVON ABGERATEN, DIESES MODUL ZU VERWENDEN.
+  Wann immer moeglich, solltet ihr es in euren Clients abschalten!
+
+1.3.1. char.base
+  Vom Server gesendet:
+    - char.base
+      Einige grundlegende Eigenschaften des Chars, die sich selten aendern.
+      char.base { "name": "Jof", "race": "Elf",}
+
+1.3.2. char.vitals
+  Vom Server gesendet:
+    - char.vitals
+      Aktuelle Lebens- und Konzentrationspunkte.
+      char.vitals { "hp": 210, "mana": 90}
+
+1.3.3. char.stats
+  Vom Server gesendet:
+    - char.stats
+      Aktuelle Attribute des Spielers.
+      Die Daten sind ein Objekt Name-Wert-Paaren von Attributen.
+      char.stats { "int": 12, "con": 10, "str": 8, "dex": 12 }
+
+1.3.4. char.status
+  Vom Server gesendet:
+    - char.status
+      Aktueller Level des Chars. (Dies ist die einzige Angabe aus dem Aardwolf
+      char.status, welche das MG machen kann.)
+      Die Daten sind ein Objekt Name-Wert-Paaren von Attributen.
+      char.status { "level": 210 }
+
+
+1.4. Char 1 (IRE)
+  Dieses Modul ist so aehnlich zum "Char" Modul von IRE wie es geht, d.h.
+  es benutzt die gleichen Schluesselnamen. Es ist aber reduziert im Umfang der
+  Daten, d.h. es uebertraegt weniger Daten als IRE es tut.
+  Wann immer moeglich, wird empfohlen, das Modul MG.char stattdessen zu
+  verwenden.
+  Wenn MG.char aktiv ist, werden von diesem Modul keine Daten uebertragen.
+  ES WIRD DAVON ABGERATEN, DIESES MODUL ZU VERWENDEN.
+  Wann immer moeglich, solltet ihr es in euren Clients abschalten!
+
+1.4.1. Char.Vitals
+  Vom Server gesendet:
+    - Char.Vitals
+      Aktuelle und maximale Lebens- und Konzentrationspunkte.
+      Char.Vitals { "hp": 210, "mp": 90, "maxhp": 210, "maxmp": 226 }
+
+1.4.2. Char.Status
+  Vom Server gesendet:
+    - Char.Status
+      Aktueller Level und Gilde des Chars. 
+      Die Daten sind ein Objekt Name-Wert-Paaren von Attributen.
+      Char.Status { "level": 210, "guild": "Zauberer" }
+
+1.4.3. Char.StatusVars
+  Vom Server gesendet:
+    - Char.StatusVars
+      Diese Nachricht gibt den "technischen" Namen aus Char.Status einen
+      Namen, der dem Spieler stattdessen angezeigt werden sollte.
+      Dieses Kommando wird nur bei Modulaktivierung gesendet.
+      Die Daten sind ein Objekt von Name-Beschreibung-Paaren.
+      Char.StatusVars { "level": "Spielerstufe", "guild": "Gilde" }
+
+
+1.5. comm.channel 1 (Aardwolf)
+  Dieses Modul ist genauso wie es Aardwolf definiert. Allerdings werden
+  natuerlich aus dem MG andere Ebenen uebertragen. ;-)
+  Vom Server gesendet:
+    - comm.channel
+      Diese Nachricht wird immer dann gesendet, wenn jemand was auf einer
+      eingeschalteten Ebene sagt. (Nicht bei Abruf der History!)
+      Zur Zeit ist es nicht moeglich, Ebenen per GMCP ein- oder auszuschalten.
+      Wenn dieses GMCP-Modul eingeschaltet ist, wird die Ausgabe der
+      Ebenenmeldung in der normalen Spielausgabe des MG unterdrueckt.
+      Achtung: Zur Zeit erfolgt (noch) keine Beruecksichtung eurer
+      "ignoriere"-Einstellungen bei den via GMCP uebertragenen
+      Ebenenmeldungen.
+      comm.channel { "chan": "allgemein",
+          "msg": "[Allgemein:Maharet] Guten Morgen, Grauen!", 
+          "player": "Maharet" }
+
+
+1.5. MG.team 1 (eigene Variante, inspiriert von Aardwolf)
+     Kommt spaeter. ;-)
+
+
+1.6. MG.room 1 (eigene Variante, inspiriert von Aardwolf)
+  MG.room beinhaltet Informationen ueber den aktuellen Raum des Spielers
+
+  Vom Server gesendet:
+  - MG.room.info
+    Diese Nachrichtig wird immer nach Betreten eines neuen Raumes gesendet
+    und enthaelt folgende Informationen:
+    * id: Eine eindeutige ID des Raumes (technisch: ein MD5-Hash)
+        Diese Angabe fehlt in Labyrinthraeumen (nicht gewollt) und in einigen
+        speziellen Raeumen (technische Gruende, z.B. manche 'virtual
+        compiler'). In diesem Fall ist die ID "" (leerer String).
+    * short: Die Kurzbeschreibung des Raumes
+    * domain: Die Region, in der der Raum liegt
+        Manche Raeume liegen nicht in den Regionen. In dem Fall fehlt diese
+        Angabe.
+    * exits: eine Liste von sichtbaren Ausgaengen (d.h. unsichtbare Ausgaenge
+        werden nicht angezeigt).
+    Hinweis: es ist moeglich, dass der Spieler in einen Raum bewegt wird,
+    der zwar technisch ein anderer Raum ist, aber kein anderer Ort. In
+    diesem Fall unterbleibt diese Nachricht.
+    room.info { "id": "d41d8cd98f00b204e9800998ecf8427e",
+                "short": "Die beruehmte Abenteurergilde",
+                "domain": "Ebene",
+                exits: [ "norden", "oben" ] }
+
+
+2. Vergleich mit GMCP in Aardwolf und IRE Muds
+   Im Morgengrauen wird GMCP letztendlich nur als Spezifikation des Transport
+   Layers betrachtet, da bei den Modulen jedes Mud seine eigene Definition der
+   uebertragenen Daten und ihrer Bedeutung vornimmt.
+
+   Das Modul "Char" ist aus den IRE-Muds, welches nur existiert, weil einige
+   Clients es standardmaessig schonmal einschalten. Es sendet aber nur einen
+   Minimalsatz an Daten.
+   Das Modul "char" ist aus Aardwolf, welches nur existiert, weil einige
+   Clients es standardmaessig schonmal einschalten. Es sendet aber nur einen
+   Minimalsatz an Daten.
+
+   Dem Modul MG.char sollte immer der Vorzug vor "Char" oder "char" gegeben
+   werden, da dort deutlich mehr Daten uebertragen werden.
+
+   Das Modul "Room" aus IRE wird nicht unterstuetzt, weil seine Daten vom MG
+   groesstenteils nicht in der geforderten Form bereitgestellt werden koennen
+   (zumindest nicht ohne ungerechtfertigten Aufwand).
+
+3. Transport Specification
+   Einstweilen am besten auf http://www.gammon.com.au/gmcp nachlesen.
+
+   Kommt hier vielleicht spaeter noch, einstweilen am besten im Netz
+   nachgucken.
+
+4. Implementationsdetails
+  Im MG ist Gross-/Kleinschreibung des Modulnamens wichtig, im Gegensatz zum
+  IRE. Meines Wissens (bitte korrigiert mich ggf.), machte die
+  Transportspezifikation keine Aussage in diesem Punkt, sondern IRE hat dies
+  entschieden.
+  Jetzt ist es so, dass Aardwolf teils Module mit dem gleichen Namen, aber
+  anderer Funktion wie IRE gebaut hat. Alle Doku von Aardwolf schreibt aber
+  immer von kleingeschriebenen Modulnamen. Insofern ist das jetzt ein Versuch,
+  die Module von IRE/Aardwolf doch irgndendwie auseinander zu halten.
+
+
+5. Client-Kram
+5.1. Tips und Hinweiss
+  Manche Clients zeigen die empfangenen GMCP-Daten standardmaessig auf dem
+  Bildschirm an.
+  Normalerweise sortieren sie die Daten  aber in von Scripten nutzbare
+  Tabellen ein, so dass es entfaellt, irgendeinen Text zu parsen.
+  In der Regel ist es dann auch so, dass der Client Moeglichkeiten anbietet,
+  auf den Empfang von GMCP-Daten reagieren zu koennen (z.B. nen Script
+  aufrufen zu lassen).
+
+5.2. Clients mit GMCP-MG-Support
+
+5.3. Clients mit GMCP-Support (Transport Spec)
+  * Mudlet (http://forums.mudlet.org/viewtopic.php?f=7&t=1547)
+    Im Netz sind div. weitere Quellen und Tutorial zu finden.
+  * Tintin++ (http://tintin.sourceforge.net/board/viewtopic.php?p=4651)
+  * TF 5 (http://mikeride.chaosnet.org/abelinc/scripts/telopt.html)
+  * CMUD (http://forums.zuggsoft.com/forums/viewtopic.php?p=158455#158455)
+  * Mushclient (http://www.aardwolf.com/wiki/index.php/Clients/MushclientGMCP)
+
+
+6. Angedachte Module fuer die Zukunft
+Ob und wann etwas aus diesem Bereich kommt, ist voellig offen. Haengt auch vom
+Interesse der Spielerschaft ab.
+
+6.3. Char.Items (IRE)
+  Eigentlich eher weniger geplant...
+
+LETZTE AeNDERUNG:
+09.01.2016, Zesstra
+
diff --git a/doc/help/abenteuer b/doc/help/abenteuer
new file mode 100644
index 0000000..3029db4
--- /dev/null
+++ b/doc/help/abenteuer
@@ -0,0 +1,41 @@
+
+Abenteuer
+=========
+
+    Um im MorgenGrauen zu etwas zu kommen, muss man Abenteuer (in
+    englischsprachigen MUDs als 'Quests' bekannt) loesen. Fuer bestandene
+    Abenteuer bekommt man Abenteuerpunkte. Nur wer genug Abenteuerpunkte
+    bekommen hat, kann Magier oder Seher werden. Je komplizierter ein
+    Abenteuer zu loesen ist, desto mehr Abenteuerpunkte bekommt man beim
+    Bestehen.
+
+    Einige Abenteuer sind nicht nur schwer, sondern auch gefaehrlich. Diese
+    sollten nur von Spielern auf einer hohen Stufe in Angriff genommen werden.
+
+    Eine Liste aller vorhandenen Abenteuer kann man in den Gilden mit dem
+    Befehl 'liste' bekommen. Dort werden auch die Punkte fuer das Abenteuer
+    angezeigt. Die Abenteuer sind in der Liste in etwa nach der
+    Gefaehrlichkeit sortiert. Die Stufe, die dort angegeben ist, bezieht sich
+    nicht allein auf die Spielerstufe, sondern kann auch als Hinweis auf die
+    durchschnittlichen Attribute verstanden werden, die man zum Loesen des
+    Abenteuers aufweisen sollte.
+
+    In der Hochebene ist ein alter Wanderer zu finden, der einem sagen kann,
+    worin die Aufgabe bei den Abenteuern besteht. Er sagt (wird einmal sagen),
+    ob das Abenteuer nicht zu gefaehrlich fuer den Spieler ist.
+
+ TECHNISCHER HINWEIS:
+    Wenn man ein Abenteuer durchspielt, sollte man nicht einschlafen (seine
+    Verbindung zum MorgenGrauen kappen), da nicht garantiert werden kann, dass
+    das Abenteuer auch nach dem Wiedererwachen noch weitergespielt werden
+    kann.
+
+    Manchmal ist ein Gegenstand/Quest-NPC gerade nicht da, zB weil ein
+    Mitspieler die Quest geloest oder den NPC getoetet hat. Dann musst du
+    bis zum naechsten Reset warten.
+
+ SIEHE AUCH:
+    abenteuerliste, stufen, stufenpunkte, schlafe, kampf, reset
+
+1.11.2012, Zesstra
+
diff --git a/doc/help/abenteuerliste b/doc/help/abenteuerliste
new file mode 100644
index 0000000..7ac2ffe
--- /dev/null
+++ b/doc/help/abenteuerliste
@@ -0,0 +1,34 @@
+Abenteuerliste
+==============
+
+ Die Liste der spielbaren Abenteuer haengt in jeder Gilde im MorgenGrauen aus.
+ Sie ist mit dem Kommando "liste" abrufbar.
+
+ Die in der Liste verwendeten Abkuerzungen werden im Folgenden erlaeutert:
+ 
+ AP       = Fuer die Quest vergebene Abenteuerpunkte
+ Klasse   = Subjektive Einstufung innerhalb der Gruppe bzgl. Arbeitsaufwand,
+            Dauer oder Gefahren
+ Attribut = Keines    -> Keine besonderen Charakteristika
+            Fleissig  -> Vornehmlich Sammeln, Auffinden von Items oder von
+                         Informationen
+            Heroisch  -> Heldentat, die Mut, Kampfbereitschaft und eine
+                         gewisse Bereitschaft zum Forschen braucht
+            Episch    -> Grosse Anforderungen an Ausdauer und Mut, grosser
+                         Aufwand fuer das Erforschen der Loesung, Kaempfe
+                         mittlerer Haerte
+            Legendaer -> Barden preisen die Einsatzbereitschaft der Helden,
+                         recht grosse Gefahr fuer Leib und Leben, mitunter
+                         lange Questzeit
+ Stufe    = Vor dem / steht die empfohlene Stufe fuer die Quest. Diese ist 
+            keine Voraussetzung, ausser bei Seherquests, die teilweise den
+            Status voraussetzen.
+            Nach dem / stehen die Durchschnittsstufen der loesenden Spieler.
+ Autor    = Magier, der die Quest geschrieben hat
+
+
+ SIEHE AUCH:
+    abenteuer, stufen, stufenpunkte, schlafe, kampf, reset
+
+26.05.2016, Zesstra
+
diff --git a/doc/help/abenteurer b/doc/help/abenteurer
new file mode 100644
index 0000000..e223861
--- /dev/null
+++ b/doc/help/abenteurer
@@ -0,0 +1,35 @@
+
+Die Abenteurergilde
+-------------------
+
+    Die meisten neuen Spieler sind automatisch Mitglied der Abenteurergilde.
+    Die Gilde beherbergt alle Spieler, die keiner anderen Gilde angehoeren,
+    sei es durch Geburt oder freiwilligen Wechsel.
+
+    Das Gildenhaus befindet sich in der Stadt Port Vain. Dort ist eigentlich
+    immer etwas los.
+
+    Die Abenteurergilde stellt ein paar Zaubersprueche zur Verfuegung, ist
+    aber nicht unbedingt die staerkste Gilde. Sie ist eher dafuer gedacht,
+    dass man sich als Abenteurer in die Welt des MorgenGrauen einspielen kann
+    und sich einen Ueberblick verschafft, bevor man sich fuer eine Karriere in
+    einer der anderen Gilden entschliesst.
+
+    Es gibt jedoch auch verwegene Spieler, die es als Abenteurer zu grossem
+    Ruhm gebracht haben.
+
+ SIEHE AUCH:
+    gilden,
+    steinschlag (5P/S1), identifiziere (10P/S3), licht (5P/S6),
+    schaetz (3P/S8), pfeil (10P/S10), ausweichen (10P/S13), 
+    kampfschrei (30P/S16), feuerball (20P/S18), schnell (100P/S21), 
+    saeurestrahl (25P/S28).
+
+    Fuer die Werte in Klammern gilt: P=Magiekosten; S=Stufe zum Erlernen.
+
+    *Ist man Mitglied einer anderen Gilde, so muss man fuer die Hilfen zu den
+    Spruechen `hilfe gilde abenteurer <name>' benutzen!*
+
+ LETZTE AeNDERUNG:
+    03.11.2012, Zesstra
+
diff --git a/doc/help/abentoira b/doc/help/abentoira
new file mode 100644
index 0000000..dbbac86
--- /dev/null
+++ b/doc/help/abentoira
@@ -0,0 +1,35 @@
+Die Abentoiragilde
+-------------------
+
+    Als kleiner, frisch erschaffener Goblin ist man automatisch Mitglied der
+    Abentoiragilde. Diese ist die Goblin-Zweigstelle der bekannten
+    Abenteurergilde.
+
+    Das Haupt-Gildenhaus befindet sich in der Stadt Port Vain. Nur dort sind
+    Gildenein- und -austritt moeglich, auch kann man nur dort neue
+    Zaubersprueche lernen. Seine Stufe kann man in jedem Gildenhaus erhoehen,
+    jedoch werden einem Goblin nur in der Zweigstelle im Goblindorf beim
+    Aufstieg seine besonderen Abentoira-Titel verliehen!
+
+    Die Abenteurergilde stellt ein paar Zaubersprueche zur Verfuegung, ist
+    aber nicht unbedingt die staerkste Gilde. Sie ist eher dafuer gedacht,
+    dass man sich als Abenteurer in die Welt des MorgenGrauen einspielen kann
+    und sich einen Ueberblick verschafft, bevor man sich fuer eine Karriere
+    in einer der anderen Gilden entschliesst.
+
+    Es gibt jedoch auch verwegene Spieler, die es als Abenteurer zu grossem
+    Ruhm gebracht haben.
+
+ SIEHE AUCH:
+    gilden,
+    licht (5P/S4), identifiziere (10P/S8), schaetz (3P/S10), pfeil (10P/S11),
+    ausweichen (10P/S12), kampfschrei (30P/S13), feuerball (20P/S15),
+    schnell (100P/S17), saeurestrahl (25P/S30).
+
+    Fuer die Werte in Klammern gilt: P=Magiekosten; S=Stufe zum Erlernen.
+
+    *Ist man Mitglied einer anderen Gilde, so muss man fuer die Hilfen zu den
+    Spruechen `hilfe gilde abenteurer <name>' benutzen!*
+
+ LETZTE AeNDERUNG:
+    1.Jan 2008 Kessa
diff --git a/doc/help/abk b/doc/help/abk
new file mode 100644
index 0000000..ea9c938
--- /dev/null
+++ b/doc/help/abk
@@ -0,0 +1,72 @@
+Haeufig benutzte Abkuerzungen
+-----------------------------
+
+     11       Elf
+     112      Feuerwehr
+     AdT      Auge des Teufels (Quest)
+     AFR      Anti-Feuer-Ring
+     AP       Abenteuerpunkte
+     AFAIK    As far as i know (soweit ich weiss)
+     AKUEFI   Abkuerzungsfimmel
+     Aur      Aurora
+     AU       Ausdauer
+     BSS      Blutsauger-Schwert
+     C4       Zephyr
+     CK       Chaoskneipe
+     D11      Dunkelelf
+     DD       Daemonendimension
+     DE(LF)   Dunkelelf
+     DG       Drachengott
+     EE       Elementarebenen
+     EK       Erstkill
+     EKSP     Erstkill-Stufenpunkte
+     EP       Erfahrungspunkt(e)
+     Famu     Feuer-Amulett
+     FE       Feuerebene
+     Flapa    Flammenpanzer
+     F&E      Forschungs- und Entwicklungsabteilung
+     FI       Feuerinsel
+     FidKG    Frauen in die Klerikergilde (c) Lug
+     FiRZG    Fehler im Raum-Zeit-Gefuege
+     FK       Friedhofskneipe
+     FL       Fluchtrichtung
+     FLW      Famous last words
+     FP       Forscherpunkte
+     FR       Fluchtrichtung
+     GE       Geschicklichkeit
+     GL       Gildenlevel
+     GQ       Gildenquest
+     HE       Hochebene
+     IN       Intelligenz
+     IMHO     In my humble opinion (meiner bescheidenen Meinung nach)
+     IIRC     If I remember correctly (wenn ich mich recht erinnere)
+     KL       Komplettloesung
+     KP       Konzentrationspunkte
+     KR       Kraft
+     LP       Lebenspunkte
+     LOL      Laughing out Loud (laut lachen)
+     MG       MorgenGrauen :-)
+     MQ       MiniQuest
+     NNADW    Nichts Neues auf der Welt
+     nFE      Neue Feuerebene
+     PA*      Boese Magier: Paracelsus, Padreic, [Patryn]
+     PK       Playerkill
+     PV       Port Vain
+     PARA     Parallelwelt
+     PW       Parallelwelt
+     RL       Real Life
+     ROTFL    Rolling on the Floor, laughing (sich kringeln vor Lachen)
+     SL       Spielerlevel
+     SMS      Schwertmeisterschwert (manchmal auch SpeerMeisterSpeer)
+     SP       Stufenpunkte
+     SPMSP    Speermeisterspeer
+     SSP      Schreckensspitze
+     Stupse   Stufenpunkte
+     tab      team angriffsbefehl
+     TI       Toeter's Insel (Akhar Nth'tar)
+     UvSdER   Ungeheuer vom See des ewigen Regens
+     VL       Virtual Life oder Verlorenes Land
+     VS       Vollstrecker oder Vorsicht
+     WUW      Wasserunwesen
+     WWI      Werwolfinsel
+     WWW      Wald der Wonnewichte
\ No newline at end of file
diff --git a/doc/help/altgilden b/doc/help/altgilden
new file mode 100644
index 0000000..677ac92
--- /dev/null
+++ b/doc/help/altgilden
@@ -0,0 +1,29 @@
+
+Ehemals geplante Gilden
+=======================
+
+   Folgende Gilden waren einmal angedacht, mit einer Fertigstellung durch die
+   damaligen Magier ist aber nicht mehr zu rechnen.
+
+   Diese Liste mag als Inspiration dienen, wenn jemand eine Gilde bauen 
+   moechte, aber nicht weiss, welche. Ob es noch Teile davon gibt, ist 
+   von Gilde zu Gilde voellig verschieden.
+
+     * Hexen (Twingi)
+     * Eiskrieger (Tilly)
+     * Piraten (Astar)
+     * Druiden (Bernard)
+     * Assassinen (Catweazle)
+     * Schwerttaenzer (Dancer)
+     * Ninja (Morgoth)
+     * Elementare (Morgoth)
+     * Harlekine (Puma)
+     * Todesanbeter (Vrai)
+     * Thaumaturgen (Yoru, Paracelsus)
+     * Idioten (Muadib, Boing)
+     * Paladine (Nonne)
+
+ SIEHE AUCH:
+
+ LETZTE AeNDERUNG: 
+    Fre, 1.11.2013, von Humni 
diff --git a/doc/help/attribute b/doc/help/attribute
new file mode 100644
index 0000000..7c83ec1
--- /dev/null
+++ b/doc/help/attribute
@@ -0,0 +1,35 @@
+
+Die Attribute
+=============
+
+    In MorgenGrauen gibt es fuer Spieler 4 Attribute: *Intelligenz*, *Kraft*,
+    *Geschicklichkeit* und *Ausdauer*. Je hoeher der Wert dieser Attribute
+    ist, desto besser ist es natuerlich fuer den Spieler. Die Attribute wirken
+    sich z.B. auf folgende Bereiche aus:
+
+     Intelligenz
+        Konzentration, Lernfaehigkeiten
+     Kraft
+        Kampfkraft, Tragen von Gegenstaenden
+     Geschicklichkeit
+        Benutzen von Waffen, Schutz vor Schaden im Kampf
+     Ausdauer
+        Gesundheit (Lebenspunkte)
+
+    Erhoeht werden die Attribute durch Zaubertraenke, die ueberall im Spiel
+    versteckt sind. Die Zaubertraenke sind teilweise recht leicht zu finden,
+    teilweise aber auch sehr schwer. Das Orakel von Tingan gibt allerdings zu
+    jedem Zaubertrank einen Hinweis.
+
+    Die einzelnen Rassen haben einen rassenspezifischen Bonus bei den
+    Attributen, der immer bestehenbleibt.
+
+    Wenn man nach einem Tod wieder ins Leben zurueckkehrt, sind die Attribute
+    um ein gewisses Mass herabgesetzt. Sie regenerieren sich aber im Laufe der
+    Zeit von selbst wieder.
+
+ SIEHE AUCH:
+    info, zaubertraenke, lebenspunkte
+
+ LETZTE AeNDERUNG: 17.01.2009, Zesstra
+
diff --git a/doc/help/balance b/doc/help/balance
new file mode 100644
index 0000000..9832dc8
--- /dev/null
+++ b/doc/help/balance
@@ -0,0 +1,58 @@
+Balance im MorgenGrauen
+=======================
+
+Ein Thema ueber das immer wieder gerne gestritten wird, ist die Balance
+im MorgenGrauen. Auf der einen Seite steht der (auf den ersten Blick 
+verstaendliche) Wunsch der Spieler, moeglichst maechtig zu sein, auf
+der anderen Seite steht der Wunsch der Magierseite, den Spielern noch
+Herausforderungen stellen zu koennen. Wenn Spieler nur noch zappend
+durch die Gegend rennen, dann wird das auch schnell langweilig ...
+
+
+Es gibt vier 'Institutionen' der Balance:
+
+1) Gilden-Balance
+
+Hierfuer zustaendig ist ein Erzmagier (momentan Humni), 
+der versucht, die Gilden in einem einigermassen vernuenftigen Rahmen
+zu halten. Hierbei beruecksichtigt werden neben den Faehigkeiten auch
+der Aufwand und das allgemeine Gilden-Feeling.
+
+2) Objekt-Balance
+
+Fuer die Objekt-Balance ist eine Gruppe von Spielern und Magiern zustaendig
+(das sogenannte Balance-Team). Behandelt werden praktisch alle Dinge, die
+den Kampf irgendwie beeinflussen (Waffen, Ruestungen, magische Objekte, etc.)
+Momentan setzt sich das Balance-Team aus folgenden Personen zusammen:
+
+  McDee, Tassram, Talanis, Croft, Xutelius, Soynada, Zook 
+  und Humni (als verantwortlicher Erzmagier).
+
+** out of order: 3) NPC-Balance
+**
+** Die NPC-Balance soll ein Ansprechpartner fuer Spieler sein, die der Ansicht
+** sind, dass irgendein Monster (NPC - non player character) zu stark, unfair
+** oder sonst irgendwie daneben ist. 
+**
+** Eine Institution "NPC-Balance" gibt es bis auf weiteres nicht mehr.
+** Zustaendig fuer die Eintragung von Erstkill-Stupsen ist Arathorn. Fuer
+** Beschwerden ueber Monster, die zu stark oder zu unfair sind, stehen
+** die Regionsmagier oder Zook zur Verfuegung.
+
+4) Heilungs-Balance
+
+Die Heilungs-Balance deckt alles ab, was irgendwie mit Heilung zu tun
+hat. Konkret sind das Kneipen, Heiler (auch Gift, Krankheit, etc.), feste
+Heilstellen, tragbare Heilung und Sachen die Saettigung oder Alkohol
+runtersetzen. Momentan zustaendig fuer dieses Gebiet ist Humni.
+
+
+Alle Institutionen arbeiten besser, wenn sie sowohl von Spielern als
+auch Magiern unterstuetzt werden. Speziell die NPC-Balance kommt in der
+Regel NUR zum Einsatz, wenn ein Spieler einen Misstand anspricht. Also
+sprecht die entsprechenden Leute an, wenn ihr irgendwo ein Problem seht!
+
+------------------------------------------------------------------------------
+ LETZTE AENDERUNG:
+    13-01-2011, Zesstra
+    
diff --git a/doc/help/bewegung b/doc/help/bewegung
new file mode 100644
index 0000000..43e68a6
--- /dev/null
+++ b/doc/help/bewegung
@@ -0,0 +1,24 @@
+
+Bewegen im MorgenGrauen
+=======================
+
+ KOMMANDOS:
+    s(ueden), w(esten), n(orden), o(sten), ob(en), u(nten), n(ord)w(esten),
+    ...
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Mit diesen Kommandos kann man den Raum in eine bestimmte Richtung
+    verlassen. Jede der Himmelsrichtungen kann durch einen (oder zwei)
+    Buchstaben abgekuerzt werden.
+
+    ABER: Manchmal muss man einen Weg finden, der nicht in eine bestimmte
+    Himmelsrichtung fuehrt.
+
+ SIEHE AUCH:
+untersuche, kurz, ausgaenge, klettere, reise
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/help/bezugspunkt b/doc/help/bezugspunkt
new file mode 100644
index 0000000..01ed421
--- /dev/null
+++ b/doc/help/bezugspunkt
@@ -0,0 +1,54 @@
+
+Der Bezugspunkt
+-------------------
+
+    Der Bezugspunkt oder das Bezugsobjekt ist bei den Befehlen "schau",
+    "untersuche", "lies", "taste", "lausche" und "rieche" wichtig.
+
+    Diese Kommandos merken sich den jeweils zuletzt erfolgreich untersuchten
+    Gegenstand (bzw. den Gegenstand, an dem das zuletzt erfolgreich
+    untersuchte Detail klebt) als Bezugspunkt fuer das naechste Kommando.
+    Hierbei benutzen alle genannten Befehle den gleichen Bezugspunkt.
+
+ BEISPIELE:
+    Beispiel 1:
+    > "unt schrank"
+    -> gibt es einen Schrank, wird der beschrieben _und_ er wird der neue
+       Bezugspunkt.
+    > "unt tuer"
+    -> Jetzt wird "tuer" am Bezugsobjekt "schrank" gesucht. Existiert das
+       Detail, bleibt der Schrank auch weiterhin der Bezugspunkt. Existiert
+       es nicht, wird ein Detail "tuer" oder ein Objekt "tuer" im Raum und
+       dann in euch gesucht. Gibt es da sowas, wird es beschrieben und das
+       neue Bezugsobjekt. Wenn alles fehlschlaegt, gibt es eine
+       Fehlermeldung und der Bezugspunkt geloescht. Beim naechsten "unt" wird
+        zuerst im Raum und dann in euch gesucht.
+    (Es wuerde auch gehen: "unt tuer an schrank".)
+
+    Beispiel 2:
+    > "unt paket"
+    -> Das Paket wird beschrieben und der neue Bezugspunkt.
+    > "unt seil"
+    -> Das Seil im paket wird beschrieben (sofern sie existiert) und der
+       neue Bezugspunkt.
+    > "unt wolle"
+    -> Das Detail "wolle" am Seil wird beschrieben. Das Seil bleibt der
+       Bezugspunkt.
+    (In diesem Beispiel koennte man die Wolle auch direkter untersuchen,
+     indem man "unt wolle an seil in paket in mir" benutzt.)
+
+    Beispiel 3:
+    > "unt rucksack"
+    -> Der Rucksack wird untersucht und der neue Bezugspunkt.
+    > "lies schild"
+    -> Hat der Rucksack ein lesbares Detail "schild", wird es ausgegeben. Der
+       Rucksack bleibt der Bezugspunkt. Wenn nicht, wird ein lesbares Detail
+       oder ein lesbarer Gegenstand "schild" im Raum und in euch gesucht.
+    (Es wuerde auch gehen: "lies schild an rucksack")
+ 
+SIEHE AUCH:
+    schau, untersuche, lies, taste, lausche, rieche
+
+ LETZTE AeNDERUNG:
+    18.01.2013, Zesstra
+
diff --git a/doc/help/bierschuettler b/doc/help/bierschuettler
new file mode 100644
index 0000000..4e6ba58
--- /dev/null
+++ b/doc/help/bierschuettler
@@ -0,0 +1,48 @@
+
+Die Bierschuettlergilde
+-----------------------
+
+    Vor einiger Zeit gruendeten die Shakies auf Shaky Island die Gilde der
+    Bierschuettler, damit diese Kunst des Bierschuettelns nicht ausstirbt.
+    Bruno wurde von allen Shakies zum Gildenshaky gewaehlt, weil er sich mit
+    diesem Thema bestens auskennt. Nun koennen alle Spieler bei ihm
+    einundzwanzig Zaubersprueche lernen. Da gibt es zum Beispiel das Erdbeben
+    oder den Hitzeschlag, die im Kampf eingesetzt werden koennen. Natuerlich
+    kann ein echter Bierschuettler seinen Feind auch alkoholisieren und sich
+    selbst auch nuechterner machen.
+
+    Da Shakies sehr behaart sind, ist Bruno in der Lage dem Gildenmitglied den
+    Trick mit der Haarruestung zu zeigen, die nicht nur schuetzt, sondern noch
+    ein kleines Special hat. Die Shakies sind eine frohe Rasse, die natuerlich
+    auch ueber die Zaubersprueche Party und Freibier verfuegen. Fuer jeden
+    Gildenlevelaufstieg ist Bruno bereit, dem Mitglied einen neuen Spruch
+    beizubringen. Die Gildenlevel sind wie in der Abenteurergilde an die
+    Spielerlevel gekoppelt, so dass auch Anfaenger schnell aufsteigen koennen.
+
+    Trotzdem ist die Gilde der Bierschuettler fuer Seher nicht uninteressant.
+    Die Gildenlevel reichen vom 'nuechternen Anfaenger' bis hin zum
+    'Bierschuettelmeister'. Uebrigens gibt es keinerlei Auflagen wenn man den
+    Bierschuettlern beitreten moechte.
+
+    Bruno gibt Bierschuettlern ab Level zwei noch ein kleines Geschenk mit auf
+    den Weg. Es handelt sich dabei um eine Bierschuerze, die dem Mitglied
+    einige Vorteile bietet. Man bekommt dann zum Beispiel in einigen Kneipen
+    einen Rabatt von bis zu 25% eingeraeumt.
+
+    Weitere Informationen, zum Beispiel ueber die einzelnen Sprueche, kann man
+    direkt bei Bruno einholen. Ausserdem steht es jedem Spieler frei, auf dem
+    Kanal [Bierschuettler:] zu lauschen, den man mit dem Befehl
+    -Bierschuettler+ einschalten kann. Hier gibt Bruno auch bekannt, wenn die
+    Bierschuettler neue Mitglieder begruessen duerfen.
+
+ SIEHE AUCH:
+    gilden, attribute, ebenen
+
+ FUeR GILDENMITGLIEDER:
+    zaubersprueche, bierschuerze, abstufungen
+
+    *Ist man Mitglied einer anderen Gilde, so muss man fuer die Hilfen zu den
+    Spruechen `hilfe gilde bierschuettler <name>' benutzen!*
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/help/buecher b/doc/help/buecher
new file mode 100644
index 0000000..d4d4218
--- /dev/null
+++ b/doc/help/buecher
@@ -0,0 +1,26 @@
+
+Buecher
+=======
+
+    Im MorgenGrauen gibt es viele Buecher, die man mit 'lies buch' lesen kann.
+    Bei standardisierten Buechern kann man die folgenden Kommandos benutzen:
+
+     oeffne buch
+        Zum Oeffnen des Buches; die meisten Buecher sind anfaenglich
+        geschlossen.
+
+     schliesse buch
+        Zum Schliessen des Buches; wenn man das Buch ausgelesen hat, schliesst
+        man es automatisch.
+
+     lies buch
+        Wenn das Buch geschlossen ist, zeigt dieses Kommando die Titelseite;
+        ist es offen, zeigt es die Seite, auf der es aufgeschlagen ist, und
+        blaettert um. Wird das Ende des Buches erreicht, wird es geschlossen.
+
+     blaettere zu seite <n>
+        Mit diesem Kommando kann man im Buch vorwaerts- und rueckwaerts
+        blaettern, natuerlich nur, wenn das Buch geoeffnet ist.
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/help/chaos b/doc/help/chaos
new file mode 100644
index 0000000..35aae8d
--- /dev/null
+++ b/doc/help/chaos
@@ -0,0 +1,46 @@
+
+Die Gilde der Krieger des Chaos
+-------------------------------
+
+    Man kann in die Gilde der Krieger des Chaos bei Kruuolq, dem obersten
+    Meister des Chaos, eintreten. Um aufgenommen zu werden muss man mindestens
+    Spielerlevel 9 (Kundschafter/Kundschafterin) sein.
+
+    Insgesamt gibt es 11 Gildenstufen, vom kleinen Chaoten bis zum Meister des
+    Chaos. Fuer jede Stufenerhoehung muss man einen Kampf auf Leben und Tod in
+    der gildeneigenen Arena austragen, man muss Sprueche und Daemonen, der
+    jeweiligen Stufe entsprechend gut, beherrschen und ab Gildenlevel 9 kommen
+    noch besondere Anforderungen hinzu.
+
+    Je nach Stufe kann man unterschiedliche Faehigkeiten erlernen. Diese
+    teilen sich grob in zwei Kategorien:
+    1) Zaubersprueche
+    2) Beschwoeren von Daemonen.
+    Mit Hilfe der Zaubersprueche kann man z.B. Raeume verdunkeln oder einen
+    Chaosball werfen, mit Hilfe der Daemonen kann man Sachen identifizieren
+    oder, mit steigender Stufe, Daemonen beschwoeren die den Spieler im Kampf
+    unterstuetzen. Da es nicht ganz so einfach ist Daemonen zu beschwoeren
+    kann es dabei passieren, dass der falsche Daemon erscheint. Um dies zu
+    verhindern sollte man sich im Gildenladen 'Nuetzliche Zutaten fuer boese
+    Zaubersprueche' mit allerlei Utensilien ausstatten, die einen bei den
+    Beschwoerungen unterstuetzen. Genaueres ueber die Zaubersprueche und
+    Daemonen erfaehrst Du bei Kruuolq.
+
+    Ueben kann man Sprueche und Beschwoerungen in dem nur fuer
+    Gildenmitglieder zugaenglichen Ritualraum bei Wuqour. Er hilft Anfaengern
+    sich besser in der Welt des Chaos zurecht zu finden.
+
+    Es gibt zwei Voraussetzungen um seine chaotischen Faehigkeiten voll zu
+    entfalten. Man muss ausreichend 'boese' sein um die Sprueche anzuwenden
+    und man muss einen Daemonen beschwoeren, der in die eigene Haut eindringt,
+    sie verstaerkt und die Attribute des Chaoten gegebenenfalls mit seinen
+    eigenen auf- oder abwertet. Dieser Daemon ermoeglicht erst die Anwendung
+    aller Sprueche.
+
+    Natuerlich haben die Chaoten auch eine eigene Ebene [Chaos:].
+
+ SIEHE AUCH:
+    attribute, ebenen, gilden
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/help/cicerones b/doc/help/cicerones
new file mode 100644
index 0000000..ba488cb
--- /dev/null
+++ b/doc/help/cicerones
@@ -0,0 +1,95 @@
+CICERONES 
+---------
+
+<bildung>
+
+Der Begriff stammt aus dem italienischen und ist eine Bezeichnung fuer einen
+Fremdenfuehrer oder Aehnliches.
+
+</bildung>
+
+Cicerones sind Spieler, die sich bereiterklaert haben, fuer unsere kleinen
+Spieler da zu sein. Sie sind die Ansprechpartner fuer die Neulinge im MUD.
+
+Jeder Spieler sollte bereit sein, Neulingen unter die Arme zu greifen. Die
+Cicerones haben aber abgesehen davon, dass sie den Titel ,,Cicerone'' fuehren
+duerfen, keine besonderen Vorrechte.
+
+Um Cicerone zu werden kann man den Befehl ,,cicerone'' verwenden. Naehres 
+dazu siehe auf der dazugehoerigen Hilfeseite.
+
+AUFGABEN DER CICERONES
+----------------------
+
+Die Cicerones sollen kleinen Spielern auf Anfrage beistehen. Sie sollen ihnen
+Fragen beantworten (natuerlich keine Quest-KLs vorkauen) und ihnen die ersten
+Schritte und Befehle im MG erklaeren. Auch Konzepte ("Gilden" oder 
+"Zaubertraenke") sollen erlaeutert werden.
+
+Cicerones sollen aber definitiv nicht dem kleinen Spieler das Spielen 
+abnehmen. Klar darf man bei der Anfaengerquest danebenstehen und bei 
+offensichtlichen Problemen Tips geben. Aber immer mit dem Hintergrund, dass
+der Spieler etwas dabei lernt.
+
+Beispiel: (diese Quest ist fiktiv)
+
+Humni sagt: Wie geht das hier jetzt?
+Muadib sagt: Ist doch ganz klar. Du musst den Stein nehmen, dann gibst Du ein
+Muadib sagt: ,wirf stein auf berg'. Dann kommt ein Schatten runter, dem gibst
+Muadib sagt: Du das Amulett und sagst dann das Zauberwort ,,Bloerderkrampf.''
+Humni sagt: Oh toll! Danke!
+
+_FALSCH_.
+
+Humni sagt: Wie geht das hier jetzt?
+Muadib sagt: Na, schau Dich mal genau um. Du kannst auch gewisse Dinge 
+Muadib sagt: untersuchen, die es quasi ueberall gibt. Es gibt quasi ueberall
+Muadib sagt: einen Boden.
+Humni sagt: Aha.
+Humni sagt: Boah, da liegt ja ein Stein?
+Muadib sagt: Ja, richtig. Was kannst Du damit machen?
+Humni gruebelt.
+Humni sagt: Aufessen?
+Muadib sagt: Nein. Das ist ein Stein.
+Humni sagt: Ach so.
+Humni sagt: Ich kann ihn ja mal aufheben.
+Muadib sagt: Genau.
+Humni nimmt den Stein.
+Muadib sagt: So, dann schau Dich mal weiter um. Was ist hier noch?
+Humni sagt: Ein Berg.
+Muadib sagt: Hast Du Dir den mal genauer angeguckt?
+Humni sagt: Da steht, ich kann den mit Steinen bewerfen, der mag das.
+.
+.
+
+_RICHTIG_
+
+Ja, der zweite Fall ist nerviger, er kostet mehr Zeit und der Spieler hat 
+weniger Erfolgserlebnisse als im ersten Fall.
+
+Halt.
+
+Stimmt nicht.
+
+Klar, im ersten Fall hat der Spieler nach 2 Minuten seine erste Quest 
+geloest - toll, oder? Nur was ist mit der naechsten? Wenn bei der naechsten
+Quest kein Cicerone danebensteht hat der Spieler verloren. Er hat naemlich
+nichts selbst rausgekriegt und nichts gelernt.
+
+Im zweiten Fall hat der Spieler ganz viel gelernt: Er hat gelernt, dass man
+eigentlich ueberall den Boden angucken kann, dass man sich die Dinge angucken
+muss und dass man mit den Gegenstaenden logische Sachen machen kann und dass
+sehr, sehr oft in den Details die Anwendungsmoeglichkeiten versteckt sind.
+
+DAS ist die Aufgabe eines Ciceronen, und die kostet Zeit.
+
+Darum sollte man sich gut ueberlegen, ob man diese Zeit gerade jetzt im 
+Moment aufbringen kann und will. Wenn nicht, sollte man es besser sein 
+lassen.
+
+SIEHE AUCH
+----------
+
+einfuehrung, cicerone
+
+Letzte Aenderung: 2005-01-04, von Humni
diff --git a/doc/help/client b/doc/help/client
new file mode 100644
index 0000000..2c136a4
--- /dev/null
+++ b/doc/help/client
@@ -0,0 +1,19 @@
+Clients
+=======
+
+    Man kann in Morgengrauen ueber ein einfaches 'telnet'-Programm spielen,
+    aber diese trennen meist Ein- und Ausgabe nicht und machen damit den
+    Lesefluss meist unangenehm.
+    
+    Es gibt verschiedene Programme, ueber die das Unterscheiden der Ein- und
+    Ausgabe, ein Einfaerben/Auslassen von Texten (wie zB den Kanaelen oder
+    Kampfmeldungen) und noch vieles mehr moeglich ist.
+    
+    Verlinkt findet ihr auf unserer Webseite: http://mg.mud.de einige der
+    fuer am besten befundenen: http://mg.mud.de/newweb/download/index.shtml
+
+ SIEHE AUCH:
+    www
+
+ LETZTE AeNDERUNG:
+    20. Juli 2007 Gloinson
diff --git a/doc/help/crash b/doc/help/crash
new file mode 100644
index 0000000..cbc2563
--- /dev/null
+++ b/doc/help/crash
@@ -0,0 +1,20 @@
+Crashs und ihre Folgen
+-----------------------
+
+    Vorsichtig ausgedrueckt ist ein 'Crash' ein unbeabsichtigter Neustart 
+    des Spieles (siehe: hilfe reboot), jedoch kann es hierbei zu 
+    unvorhersehbaren Nebenwirkungen kommen. Solltest Du also der Meinung
+    sein, dass nach einem 'Crash' irgendetwas mit Dir nicht stimmen
+    kann, wende Dich an einen Magier Deines Vertrauens.
+    Die Nebenwirkungen eines 'Crashs' sind jedoch relativ selten.
+
+    Die Gruende fuer einen 'Crash' sind vielfaeltig. Doch wenn man es
+    auf den Punkt bringen moechte, wird ein 'Crash' schlicht und 
+    einfach durch schwere Programmierfehler ausgeloest, an denen sich das 
+    MorgenGrauen verschluckt. 
+    
+ SIEHE AUCH:
+    reboot, magier
+
+ LETZTE AeNDERUNG:
+    Sat, 14.10.2000, 10:16:25 von Bierchen.
diff --git a/doc/help/dunkelelfen b/doc/help/dunkelelfen
new file mode 100644
index 0000000..ad78184
--- /dev/null
+++ b/doc/help/dunkelelfen
@@ -0,0 +1,51 @@
+
+Die Dunkelelfengilde
+-----------------------
+
+      Das Volk der Dunkelelfen lebt in einer grossen Hoehlenstadt gut
+      versteckt hinter einem Wasserfall. Ueber kaum ein anderes Volk gibt es
+      soviele Vorurteile wie ueber die Dunkelelfen und so werden sie von
+      allen misstrauisch beaeugt oder sogar bekaempft. In diesem Kampf,
+      insbesondere gegen die Elfen, sind sie voellig auf sich allein gestellt
+      und so hat sich eine mehr oder minder autarke Gesellschaft entwickelt.
+      Die Dunkelelfen haben eine eigene Kultur und eine eigene Goettin der
+      sie huldigen. Wie auch die Elfen verfuegen sie ueber ausserordenlich
+      grosse magische Faehigkeiten, auch wenn sie sich mehr auf die schwarze
+      Seite der Magie spezialisiert haben.
+
+      Die Gilde besteht aus vier Teilen, einem allgemeinen Teil mit Skills
+      wie identifiziere, schaetz, feuerlanze usw. die jeder in der Gilde
+      erlernen muss. Darueber hinaus gibt es drei verschiedene Zweige der
+      Gilde, von denen jeder Dunkelelf in zwei Zweige eintreten und sich am
+      Ende dann in einem dieser zwei Zweige spezialisieren kann. Diese drei
+      Zweige sind Kampf, Magie und Klerus. Insgesamt gibt es also 6 moegliche
+      Zweigkombinationen, zwischen denen die Dunkelelfen frei waehlen koennen.
+
+      Der Kampfzweig widmet sich in erster Linie dem Umgang mit dem
+      Runenschwert. Es gibt einen Schwertskill, einen Skill zum Schmieden von
+      Runenschwertern, Verzauberungen des Schwerts, sowie einige allgemeine
+      Kampffaehigkeiten wie Finte, Parade, Ausweichen, Ausfall.
+
+      Der Klerikale Zweig widmet sich der Huldigung von Seyt-Hamakha und der
+      dunklen Seite der Macht. Die Faehigkeiten der Kleriker sind z.B.
+      verfluchen, vergiften, das Beschwoeren von Zombies, jedoch keine
+      Heilzauber oder soetwas.
+
+      Im Magiezweig geht es dann um Zaubersprueche im engeren Sinne.
+      Feuerlanzen, Schmerzen, Schutzzauber und aehnliches.
+
+      Jeder der drei Zweige hat einen eigenen Vorsitzenden. Nyela die
+      Waffenschmiedin steht dem Kampfzweig vor. Teo'na'katl der Hohepriester,
+      dem Klerikalen Zweig und Nenais'u die Zauberin dem Magiezweig.
+      Ausserdem ist Nenais'u als Vorsitzende des Magiezweigs traditionell
+      auch das Gildenoberhaupt. Zusaetzlich zu den drei Vorsitzenden gibt es
+      drei weitere wichtige NPCs. Der Ruestungsschmied Baiy'Sagar, der Wirt
+      und eine Kraeuterkundige im Labor der Delfengilde.
+
+
+ SIEHE AUCH:
+    gilden, attribute, ebenen, gildenstufen, abstufungen
+
+
+ LETZTE AeNDERUNG:
+    Mon, 28. Jul 2003, 23:27:04 von Padreic
diff --git a/doc/help/editor b/doc/help/editor
new file mode 100644
index 0000000..1ebcfb4
--- /dev/null
+++ b/doc/help/editor
@@ -0,0 +1,129 @@
+
+Der Editor
+==========
+
+    Der Editor wird von der Zeitung, der Post und in den Seherhaeusern
+    verwendet. Es besteht keine Trennung zwischen Eingabe- und Kommandomodus;
+    Befehle werden mit einer Tilde (~) als erstem Zeichen in der Zeile
+    eingeleitet (Ausnahmen: ., ** und !<cmd>).
+
+    Der Editor versteht folgende Befehle:
+
+     Allgemeine Kommandos
+
+         . oder **
+            Der eingegebene Text wird uebernommen, der Editor beendet.
+
+         !<cmd>
+            Das Kommando <cmd> wird ausgefuehrt, als wenn Du gerade nicht
+            schreiben wuerdest.
+
+         ~q
+            Abbruch. Schon eingegebener Text ist verloren; in der Post/MPA
+            wird kein Artikel erzeugt.
+
+         ~h
+            Eine Hilfeseite wird angezeigt (quasi eine Kurzform dieser Seite)
+
+         ~!
+            Der Editor wird voruebergehend verlassen.
+            Man kann mit dem Befehl ~r weiterschreiben (das ~r ist als
+            normales Kommando ausserhalb des Editors einzugeben!)
+
+         ~r
+            Der gesamte bisher geschriebene Text wird angezeigt.
+         ~R
+            Wie ~r, es werden jedoch noch Zeilennummern mit ausgegeben.
+
+         ~z
+            Der Textausschnitt um den Cursor herum wird angezeigt.
+         ~Z
+            wie ~z, es werden jedoch noch Zeilennummern mit ausgegeben.
+
+         ~s
+            Es werden Statusinformationen angezeigt.
+
+         ~b
+            Es wird zwischen Flattersatz (default) und Blocksatz umgeschaltet
+
+        Nur fuer Magier:
+
+         ~i <filename>
+            Die Datei <filename> wird an der momentanen Cursorposition in den
+            Text eingefuegt.
+            Aus Kompatibilitaetsgruenden kann man auch ~r <filename> nehmen.
+
+     Zeilenorientierte Kommandos
+
+         ~d
+            Die letzte Zeile wird geloescht (Text-, nicht Eingabezeile).
+
+         ~v
+            Es wird zwischen dem Einfuegemodus (default) und dem
+            Ueberschreibmodus umgeschaltet.
+
+         ~s !s1!s2!
+            Ersetzt das erste Vorkommnis des Strings s1 durch den String s2 in
+            der aktuellen Zeile.
+            Statt durch ! koennen die Strings auch durch beliebige andere
+            Zeichen getrennt werden, die weder in s1 noch in s2 vorkommen.
+            Mit der Form ~s !s1!s2!p wird die geaenderte Zeile direkt
+            angezeigt.
+
+         ~f
+            Formatiert die aktuelle Zeile neu.
+
+     Cursorkommandos
+
+         ~cu
+            Der Cursor wird um eine Zeile nach oben bewegt.
+         ~cd
+            Der Cursor wird um eine Zeile nach unten bewegt.
+
+         ~ct
+            Der Cursor wird an den Anfang des Textes bewegt.
+         ~cb
+            Der Cursor wird an das Ende des Textes bewegt.
+
+         ~cs
+            Der Cursor wird an den Anfang des markierten Blocks bewegt.
+         ~ce
+            Der Cursor wird an das Ende des markierten Blocks bewegt.
+
+         ~c<nr>
+            Der Cursor wird in die Zeile <nr> bewegt.
+         ~c+<nr>
+            Der Cursor wird um <nr> Zeilen nach oben bewegt.
+         ~c-<nr>
+            Der Cursor wird um <nr> Zeilen nach unten bewegt.
+
+     Blockorientierte Kommandos
+
+         ~bs
+            Der Blockanfang wird auf die aktuelle Zeile gesetzt.
+         ~bs<nr>
+            Der Blockanfang wird auf die Zeile <nr> gesetzt.
+
+         ~be
+            Das Blockende wird auf die aktuelle Zeile gesetzt.
+         ~be<nr>
+            Das Blockende wird auf die Zeile <nr> gesetzt.
+
+         ~F
+            Der markierte Block wird neu formatiert.
+
+         ~D
+            Der markierte Block wird geloescht.
+
+         ~m
+            Der markierte Block wird an die aktuelle Cursorposition
+            verschoben.
+
+    Alles andere gilt als Text. Ueberlange Zeilen werden auf eine maximale
+    Laenge von 78 Zeichen umgebrochen.
+
+    Nach ~!, oder wenn man beim Schreiben netztot wird, kann man mit ~r wieder
+    in den Editor einsteigen.
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/help/einfuehrung b/doc/help/einfuehrung
new file mode 100644
index 0000000..bc8e8dc
--- /dev/null
+++ b/doc/help/einfuehrung
@@ -0,0 +1,58 @@
+Eine kurze Einfuehrung
+======================
+
+Hallo und willkommen im MorgenGrauen!
+
+Du befindest Dich jetzt in einer virtuellen Welt, in der Du Deinen Charakter
+(so bezeichnet man Deine Spielfigur) mittels verbaler Befehle dazu bringen
+kannst, die verschiedensten Bewegungen und Aktionen auszufuehren. Du kannst
+umhergehen, Dich umsehen, kaempfen, Dinge aufheben und benutzen und vieles
+mehr! Dazu solltest Du Dich mit den grundlegenden Befehlen vertraut machen,
+die dazu notwendig sind. Folgende Hilfeseiten seien Dir an's Herz gelegt:
+
+- "hilfe bewegung"
+- "hilfe syntax"
+
+Du kannst Dich mit den anderen Spielern auf verschiedene Weise
+verstaendigen. Wichtig ist zum einen das direkte Mitteilen, das funktioniert
+so: 
+
+"teile <spielername> mit <nachricht>"
+
+also zum Beispiel
+
+"teile zook mit hallo mudgott!"
+
+Das andere sind die sogenannten "Ebenen", auf denen Du allen Spielern (die
+dort grade mithoeren) etwas mitteilen kannst. Am Anfang befindest Du Dich
+auf den Ebene "anfaenger" und "abenteuer". Wenn Du zum Beispiel die anderen
+Spieler etwas fragen moechtest, tipp zum Beispiel
+
+-anfaenger Hallo ihr da draussen! Wie komme ich zur Abenteurergilde?
+
+und alle, die auf der Anfaengerebene mithoeren, werden diese Nachricht
+bekommen. Fuer weitere Informationen zu den Ebenen lies einfach mal
+die Hilfeseite dazu ("hilfe ebenen").
+
+Eines der Hauptziele dieses Spieles ist, seine Spielfigur weiterzuentwickeln,
+also die Werte zu verbessern. Informationen dazu findest Du auf den
+Hilfeseiten "stufenpunkte", "abenteuer" und "attribute".
+
+Es sei noch darauf hingewiesen, dass es natuerlich auch gewisse Regeln
+gibt, an die sich die Spieler halten muessen ("hilfe regeln").
+Lies Dir diese auf jeden Fall in Ruhe vollstaendig durch!
+
+Es gibt auch gewisse Spieler, die sich extra bereiterklaert haben, Dir als
+Anfaenger zur Seite zu stehen, die Ciceronen. Wenn Du wissen willst, wer 
+davon online ist, kannst Du den Befehl
+
+"kwer cicerone"
+
+verwenden. Die sollten dann anwesend sein und auch Zeit fuer Dich und Deine
+Fragen haben.
+
+ SIEHE AUCH:
+     abenteuer, bewegung, forscherpunkte, regeln, stufen, syntax, ciceronen
+ 
+ LETZTE AeNDERUNG:
+    Sun, 24.06.2001, 22:30:00 von Nachtwind
diff --git a/doc/help/erstkillstufenpunkte b/doc/help/erstkillstufenpunkte
new file mode 100644
index 0000000..0176881
--- /dev/null
+++ b/doc/help/erstkillstufenpunkte
@@ -0,0 +1,43 @@
+Erstkill-Stufenpunkte (EK-Stupse)
+=================================
+
+    Zusaetzlich zu der allgemeinen Erlaeuterung, was EK-Stufenpunkte sind
+    und wofuer diese gutgeschrieben werden, die in der Hilfeseite zu den
+    Stufenpunkten nachzulesen ist, sei hier ein technisches Detail zu 
+    Erstkill-Stufenpunkten in Zusammenhang mit Kerbholz und Duesterwald-
+    Plakette (beides Questbelohnungen) naeher erlaeutert:
+      
+    Wenn ein Monster, fuer das EK-Stupse gutgeschrieben werden, zum
+    allerersten Mal ueberhaupt getoetet wird, d.h. in der Regel nach
+    dem Neuanschluss eines Gebietes, ist dieser Kill noch nicht sofort
+    auf der Plakette erkennbar, und auch noch nicht in die Gesamt-
+    Stufenpunkte des Spielers eingerechnet. Das Kerbholz wird jedoch
+    anzeigen, dass der Spieler den Kill schon hat.
+    
+    Aus technischen Gruenden ist es unumgaenglich, solche "frischen" EKs
+    zunaechst nur temporaer zu registrieren und von einem Erzmagier auf
+    Gueltigkeit pruefen zu lassen. So lange der zustaendige EM (wer das 
+    jeweils  ist, laesst sich auf der Hilfeseite "erzmagier" nachlesen)
+    den EK nicht bestaetigt hat, gibt es voruebergehend also eine
+    Diskrepanz zwischen Kerbholz, Stufe und Plakette. Sobald der
+    EK jedoch bestaetigt wurde, verschwindet diese.
+
+    Weiterhin ist zu beachten, dass eventuell vergebene Sonder-
+    Stufenpunkte fuer besonders harte Monster (z.B. Drachengott)
+    erst *nach* einer Bestaetigung des EKs durch den zustaendigen
+    EM eingetragen werden koennen, so dass es nachtraeglich noch zu
+    einer Erhoehung der Stufenpunkte des betreffenden Spielers kommen kann.
+
+    WICHTIG:
+    Diese Hinweise gelten nur fuer solche Spieler, die Monster getoetet 
+    haben, welche noch nie zuvor umgehauen wurden. Fuer alle, die den Kill 
+    erst spaeter erreichen, aendert sich nichts: Die Punkte werden sofort in 
+    voller Hoehe gutgeschrieben, und die Plakette zaehlt den EK auch sofort 
+    mit.
+
+  SIEHE AUCH:
+    stufen, stufenpunkte, erzmagier
+
+  LETZTE AeNDERUNG:
+    16. August 2013, von Arathorn
+
diff --git a/doc/help/erzmagier b/doc/help/erzmagier
new file mode 100644
index 0000000..8963000
--- /dev/null
+++ b/doc/help/erzmagier
@@ -0,0 +1,66 @@
+Erzmagier
+=========
+
+ERZMAGIER:
+  Der Einflussbereich der Erzmagier beschraenkt sich nicht nur auf Bereiche
+  innerhalb des Spiels, sondern auch auf Bereiche ausserhalb. Sie koennen
+  Aenderungen an der Basis-MudLib vornehmen und damit die Rahmenbedingungen
+  des Spiels aendern oder ergaenzen. Ausserdem sind sie die richtigen
+  Ansprechpartner, wenn man sein Passwort vergessen hat, oder wenn durch
+  einen Absturz des Rechners das Savefile eines Spielers kaputt gegangen
+  ist.
+
+  Die MudGoetter Jof, Rumata und Zook sind dabei die hoechsten Instanzen;
+  Jof macht sich allerdings in letzter Zeit etwas rar.
+
+Die Aufgabenbereiche der einzelnen Erzmagier sind wie folgt festgelegt:
+
+      Amaryllis
+        Amaryllis ist fuer die Administration und das Hosting unseres
+        Servers zustaendig und hat ausserdem das Amt des Sheriffs inne.
+      Arathorn
+        Arathorn kuemmert sich um die Vergabe der Erstkill-Stupse (dazu
+        begutachtet er die NPCs). Darueberhinaus kuemmert er sich 
+        um die Weiterentwicklung der Mudlib.
+      Ark
+        Ark testet neue Abenteuer sowie sogenannte MiniQuests bevor sie
+        auf Spieler losgelassen werden und traegt diese mit 
+        angemessener Punktzahl ein.
+        Er kuemmert sich um die Pflege der bestehenden Rassen sowie die
+        Ausarbeitung weiterer Rassen. Dazu gehoeren sowohl die Rassenshells
+        als auch die Seele.
+      Humni
+        Humni ist fuer die Gilden-Balance zustaendig und leitet das
+        Balance-Team. Des Weiteren ist er fuer die Heilungs-Balance
+        zustaendig.
+      Jof
+        Jof ist als MudGott fuer mehr oder weniger alles zustaendig.
+      Rumata
+        Rumata ist MudGoettin und damit auch Maedchen fuer alles.
+        Und delegiert dann ;-)
+      Miril
+        Miril verwaltet die Forscherpunkte und Zaubertraenke.
+      N.N. 
+        Er/Sie ist weiterhin fuer die Pflege des Stufensystems verantwortlich 
+        und kuemmert sich um die Pflege der Mudlib.
+      Zesstra
+        Zesstra kuemmert sich um unseren Driver und die Mudlib.
+      Zook
+        Zook ist einer der MudGoetter und damit Maedchen fuer 
+        alles. Er ernennt Regionsmagier und beruft diese gegebenenfalls
+        ab. Jungmagier koennen sich mit ihren Gesellenstuecken gerne bei
+        ihm melden.
+
+Noch im Kreis der Erzmagier, aber schon ihrer Aufgaben entbunden 
+sind: 
+
+      Hate
+        Hate war fuer die Administration unseres Mud-Rechners zustaendig.
+
+SIEHE AUCH:
+        ebenen, regionen, goetter
+        (nur Magier): balance
+
+LETZTE AeNDERUNG:
+        2011-09-25 von Zook.
+
diff --git a/doc/help/essen_trinken b/doc/help/essen_trinken
new file mode 100644
index 0000000..887c4ed
--- /dev/null
+++ b/doc/help/essen_trinken
@@ -0,0 +1,30 @@
+
+Essen und Trinken
+=================
+
+     Eines voraus: Essen und Trinken sind in Morgengrauen nicht lebens-
+     notwendig. Niemand wird an Hunger oder Durst sterben und auch der
+     Gang auf die Toilette ist hoechst optional.
+
+     Hauptsaechlich in Kneipen kann man hier essen, trinken oder sich
+     besaufen. Es gibt auch tragbare Getraenke und Speisen.
+     Dabei haengen die Grenzen des Fassungsvermoegens fuer Nahrung,
+     Fluessigkeit und Alkohol vor allem von der Rasse ab, aber auch manche
+     Gilden koennen durch Magie oder Uebung fuer mehr Kapazitaet sorgen.
+     
+     Mit der Zeit entleert man sich dann wieder von alleine. Man kann diesem
+     Vorgang auch etwas auf die Spruenge helfen, jedoch nicht unbegrenzt
+     oft in kurzer Zeit. Hierbei sollte bedacht werden, dass nur auf Klo
+     gehen kann, wer auch vorher eine bestimmte Menge an Nahrung zu sich
+     genommen hat.
+
+     Speisen und Getraenke heilen in bestimmtem Mass. Dabei koennen sie
+     Lebens- oder Konzentrationspunkte auch unabhaengig voneinander
+     staerken. Ein jeder suche sich die Kneipe seiner Wahl.
+
+ SIEHE AUCH:
+     heilung, leben
+
+ LETZTE AeNDERUNG:
+     14.Maerz 2004 Gloinson
+
diff --git a/doc/help/faq b/doc/help/faq
new file mode 100644
index 0000000..e9c89f6
--- /dev/null
+++ b/doc/help/faq
@@ -0,0 +1,28 @@
+
+Die FAQ
+=======
+
+    Du hast Interesse an den FAQ? Gut so, eine kluge Entscheidung.
+
+    Zur Zeit findest Du die neueste Ausgabe der FAQ auf dem FTP Server des
+    Muds im Verzeichnis `/open/Texte/FAQ/'. Dieses Verzeichnis ist auch fuer
+    Spieler zugaenglich. Im einzelnen solltest Du folgendermassen vorgehen:
+
+    > ftp mg.mud.de
+    [Als Login-Namen 'anonymous' und als Passwort Deine EMail-Adresse angeben]
+    [Magier koennen auch Namen und Passwort ihres Charakters nehmen]
+    > cd /open/Texte/FAQ
+    > get mg-faq.v202
+
+    Eine andere Moeglichkeit ist, eine E-Mail an mud@mg.mud.de zu
+    schicken und als Subject `FAQ' anzugeben.
+
+    Hast Du das geschafft, bist Du im Besitz eines umfangreichen Werkes ueber
+    sehr viele Fragen, die im Zusammenhang mit dem Spiel auftauchen koennen.
+    Sollte Deiner Meinung nach etwas in den FAQ fehlen, so schreib einfach
+    eine Mail an Pilgrim oder Viper. Pilgrim ist als Autor des Werkes fuer
+    Anregungen sehr dankbar.
+
+LETZTE AeNDERUNG:
+    Sam, 29. Sep 2001, 11:35:01 von Zook.
+
diff --git a/doc/help/forscherpunkte b/doc/help/forscherpunkte
new file mode 100644
index 0000000..d12ddd9
--- /dev/null
+++ b/doc/help/forscherpunkte
@@ -0,0 +1,54 @@
+
+Forscherpunkte
+==============
+
+    Die Forscherpunkte geben Deinen aktuellen Grad der Kenntnis des
+    MorgenGrauens wieder. Sie werden allerdings nicht als nackte Zahl
+    praesentiert, sondern in Form einer Einschaetzung gemessen an der Kenntnis
+    Deiner Mitspieler sowie am gesamten MorgenGrauen.
+
+    Die Kenntnis waechst im Laufe der Zeit, wenn Du Dich einigermassen
+    sorgfaeltig umsiehst und mit NPCs unterhaeltst. Wer einfach nur stumpf das
+    absolut Noetigste eingibt, um ein Abenteuer zu loesen, darf sich also
+    nicht wundern, wenn er sich im MorgenGrauen trotzdem so gut wie gar nicht
+    auskennt.
+
+    Die Forscherpunkte machen einen grossen Teil der Stufenpunkte aus.
+
+    Wenn man die erste Huerde (`Du kennst Dich im MorgenGrauen so gut wie gar
+    nicht aus.') ueberwunden hat, sind folgende relativen und absoluten
+    Einstufungen moeglich:
+
+    Verglichen mit Deinen Mitspielern, kennst Du Dich im MorgenGrauen
+
+     * kaum aus.
+     * aeusserst schlecht aus.
+     * sehr schlecht aus.
+     * schlecht aus.
+     * unterdurchschnittlich aus.
+     * durchschnittlich gut aus.
+     * besser als der Durchschnitt aus.
+     * recht gut aus.
+     * ziemlich gut aus.
+     * gut aus.
+     * sehr gut aus.
+     * ausserordentlich gut aus.
+     * unheimlich gut aus.
+     * einfach hervorragend aus.
+
+    Absolut gesehen
+
+     * kennst Du nur wenig vom MorgenGrauen.
+     * solltest Du Dich vielleicht noch genauer umsehen.
+     * bist Du durchaus schon herumgekommen.
+     * hast Du schon einiges gesehen.
+     * bist Du schon weit herumgekommen.
+     * koenntest Du eigentlich einen Reisefuehrer herausbringen.
+     * hast Du schon sehr viel gesehen.
+     * besitzt Du eine hervorragende Ortskenntnis.
+
+ SIEHE AUCH:
+    stufenpunkte, info
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/help/gesellenstueck b/doc/help/gesellenstueck
new file mode 100644
index 0000000..ae980bb
--- /dev/null
+++ b/doc/help/gesellenstueck
@@ -0,0 +1,76 @@
+
+GESELLENSTUECK
+==============
+
+      Im MorgenGrauen musst Du als Jungmagier erst ein Gesellenstueck
+      abliefern, bevor Du von den zustaendigen Erzmagiern zum Vollmagier
+      befoerdert wirst. Bis dahin bist Du noch Lehrling und hast nur ein-
+      geschraenkte Leserechte.
+
+      Diese Einschraenkung der Leserechte soll Dich keinesfalls bei Deiner
+      Arbeit behindern - wenn Du Fragen zur Programmierung hast, die durch
+      die Beispiele im Verzeichnis '/doc' nicht beantwortet werden, so
+      kannst Du Dich jederzeit an Deinen Sponsor wenden, um weitere
+      Beispiel-Dateien zu bekommen.
+
+      Bei der Gestaltung Deines Gesellenstueckes kannst Du Deiner Phantasie
+      vollkommen freien Lauf lassen, Es gibt fuer das Gesellenstueck im MG 
+      keine festen Regeln wie "mindestens 20 Raeume und fuenf NPCs". Dein 
+      Gesellenstueck sollte jedoch etwas neues sein und keine Ueberarbeitung
+      von bestehendem Code, weil es LPC-Anfaengern erfahrungsgemaess
+      schwerer faellt, sich in fremden Code einzulesen. Ausserdem soll
+      ja klar erkennbar sein, dass das Neue tatsaechlich komplett von Dir
+      selbst stammt.
+
+      Ein kleiner Punkt sei als Denkanstoss erwaehnt: Wie waere es, wenn 
+      Du etwas fuer Anfaenger schreibst und nicht das x-te Super-Duper 
+      Seher-Team Metzelgebiet? Versuche ein Gebiet zu schreiben, an dem 
+      viele Spieler ihre Freude haben koennen und nicht nur die sehr hohen 
+      Seher. 
+
+      Genauso gut kannst Du eine neue Quest programmieren oder (gerade auch
+      in Teamarbeit) eine neue Gilde. Letzteres ist allerdings nicht fuer
+      LPC-Anfaenger zu empfehlen. Es muss nichtmal unbedingt ein "Standard-
+      Gesellenstueck" sein. 
+
+      Die Erzmagier sind auch anderen hier nicht aufgefuehrten Ideen immer 
+      aufgeschlossen gegenueber - sprich sie einfach einmal an und erzaehle,
+      was Du so an Vorstellungen davon hast, was Du im MorgenGrauen 
+      programmieren moechtest.        
+ 
+      Bevor Du Dich an das Programmieren begibst, solltest Du das Konzept
+      fuer Dein Gesellenstueck mit einem der zustaendigen Erzmagier
+      abklaeren, um sicherzugehen, dass es als Gesellenstueck ausreicht.
+      
+      Um Dein Gesellenstueck bewerten zu lassen, wendest Du Dich bitte an
+      einen der in der Hilfe als zustaendig angegebenen Erzmagier.
+      Du kannst auch gerne danach fragen, was von den anderen Jungmagiern 
+      bisher so an Gesellenstuecken abgegeben wurde, um Dir einen kleinen 
+      Ueberblick zu verschaffen, was ungefaehr von Dir erwartet wird.
+
+      Feste Grenzwerte vorzugeben, ab wann ein Gesellenstueck ausreichend 
+      ist, kann nicht im Sinne dieser Regelung sein. Daher gibt es an dieser
+      Stelle auch nur einige wenige grobe Richtlinien:
+
+      - ein Gesellenstueck sollte eine Bereicherung fuer das MorgenGrauen
+        sein - also kein lieblos hingeklatschtes Gebiet, bei dem man sofort
+        merkt, dass es nur zur Befoerderung zum Vollmagier taugen sollte.
+
+      - man sollte dem Gesellenstueck ansehen koennen, dass einiges an
+        Arbeit dahinter steckt, und dass es nicht "mal eben" an einem
+        Wochenende zusammengestrickt wurde.
+
+      - mittlerweile gibt es im MorgenGrauen gewisse Qualitaets-Standards,
+        was neue Gebiete angeht. Dazu gehoert u.a., dass die Raeume nicht
+        alle gleich aussehen (Copy&Paste laesst gruessen), gewisse
+        Standard-Details ueberall beschrieben sind etc. Dieser Standard gilt
+        selbstverstaendlich auch fuer Gesellenstuecke.
+
+      Bei weitergehenden Fragen wende Dich einfach an einen der in der Hilfe 
+      als Ansprechpartner angegebenen Erzmagier.
+
+ SIEHE AUCH:
+    erzmagier, regionsmagier, magier
+
+ LETZTE AeNDERUNG:
+    Mon, 28. AUG 2000, 22:30:00 von Wim.
diff --git a/doc/help/gift b/doc/help/gift
new file mode 100644
index 0000000..3699eae
--- /dev/null
+++ b/doc/help/gift
@@ -0,0 +1,28 @@
+Gift/Krankheit/Flueche
+======================
+
+    Es gibt im Morgengrauen verschiedene Gifte, Krankheiten und Flueche,
+    die einem das Leben schwerer machen.
+
+    Krankheiten und Gifte beeinflussen fast immer "nur" Lebens- und
+    Konzentrationspunkte. Flueche haben ganz andere oder weitergehende
+    Wirkungen.
+
+    Dabei nimmt man Gifte meist selbst (und oft freiwillig) auf,
+    Krankheiten und Flueche jedoch verpasst einem irgendwer oder
+    irgendwas ohne einen zu fragen.
+
+    Die generelle Vergiftung wird einem durch Meldungen und die Anzeige
+    von "info" bekannt gemacht. Die Wirkung ist, das man nicht mehr
+    ohne Tanken heilt bis hin zum Lebenspunktverlust. Einige Heiler und
+    Gilden koennen die Vergiftung lindern und aufheben.
+
+    Der einfache Fluch wirkt auf Waffen und Ruestungen. Diese sind dann
+    nicht mehr wegsteckbar bzw. ausziehbar. Auch hier koennen Heiler und
+    Gilden helfen.
+
+ SIEHE AUCH:
+    sterben
+
+ LETZTE AeNDERUNG:
+    18. Maerz 2004 Gloinson
diff --git a/doc/help/gilden b/doc/help/gilden
new file mode 100644
index 0000000..947f7a3
--- /dev/null
+++ b/doc/help/gilden
@@ -0,0 +1,55 @@
+Die Gilden
+==========
+
+    Es gibt im Morgengrauen mehrere Gilden, in denen man einige besondere
+    Faehigkeiten erwerben kann. Man kann jedoch nur in einer Gilde
+    gleichzeitig sein und hat auch immer nur die Faehigkeiten der Gilde, in
+    der man momentan ist. Wer mit seiner Gilde nicht zufrieden ist, kann
+    natuerlich auch jederzeit wieder austreten, hat dann, falls er erneut
+    eintritt, jedoch nur noch einen Teil der frueher erworbenen Faehigkeiten.
+
+    Jeder ist beim Start schon in einer Gilde: Menschen, Hobbits und
+    Zwerge in der Abenteurergilde, Felinen bei den Katzenkriegern, Elfen in 
+    der Gilde der Wipfellaeufer, Orks in der Gilde der Urukhai und 
+    Dunkelelfen in der Dunkelelfengilde. 
+
+    Die Faehigkeiten seiner Anfangsgilde verliert man nicht, wenn man in 
+    einer anderen Gilde war und dort ausgetreten ist.
+
+    Dunkelelfen sind bei der Auswahl stark eingeschraenkt, da sie in den
+    meisten Gilden nicht akzeptiert werden und auch nur ihre Gilde ihnen
+    den lebensnotwendigen Schutz bietet, jedoch koennen sie sich auf
+    mehrere Zweige spezialisieren.
+
+    Momentan gibt es folgende Gilden:
+
+     * Abenteurergilde, in Port Vain, von Boing
+     * Wipfellaeufer, im Elfendorf, von Humni
+     * Gilde der Karatekaempfer, in der Stadt Xian im Fernen Westen, von
+       Rochus
+     * Krieger des Chaos, in der Eiswueste, von Zardoz
+     * Akademie der geistigen Kraft zu Taramis, von Silvana
+     * Der Heilige Orden, in Djelibeby, von Wargon
+     * Bierschuettlergilde, auf Shaky Island, von Shakedbeer
+     * Kaempfergilde, auf Akhar Nth'tar, von Zardoz, Toeter und Bendeigid
+     * Die Katzenkrieger, in der Dschungelstadt Katzmandu, von Paracelsus
+     * Die Tanjian, im Eistannenwald, von Paracelsus
+     * Dunkelelfen, in der Hoehlenstadt Zzerenzzen, von Padreic
+     * Urukhai, von Morgoth und Bugfix
+     * Werwoelfe, von Humni
+
+    Folgende Gilden sind derzeit noch in Entwicklung, der Zeitpunkt ihrer
+    Fertigstellung ist aber noch ungewiss:
+
+     * Magusgilde, von Ark
+ 
+ SIEHE AUCH:
+    abenteurer, bierschuettler, chaos, kaempfer, karate, katzenkrieger,
+    klerus, zauberer, tanjian, dunkelelfen, waffenfertigkeiten,
+    gildenmagier, wipfellaeufer, altgilden
+ 
+ LETZTE AENDERUNG: 
+    2011-11-13 von Humni
+
+
+----------------------------------------------------------------------
diff --git a/doc/help/gildenmagier b/doc/help/gildenmagier
new file mode 100644
index 0000000..cad3f7a
--- /dev/null
+++ b/doc/help/gildenmagier
@@ -0,0 +1,37 @@
+
+Die Gildenmagier des MorgenGrauens
+==================================
+
+Jede Gilde wird von ein oder mehreren Magiern betreut, die die Gilde warten
+und erweitern. Sie sind die Ansprechpartner, wenn es Probleme innerhalb
+einer dieser Gilden gibt.
+
+Hier also alle Gilden des Morgengrauens mit ihren Gildenmagiern:
+(MA - Mitarbeiter)
+
+(Einige der Gildenmagier sind derzeit ein wenig inaktiver als sonst.
+Diese sind mit einem ,,i'' gekennzeichnet. In diesem Fall gibt es derzeit
+niemanden, der die Gilde weiterentwickelt. Fuer dringende Fragen kannst Du
+Dich dann an den Erzmagier fuer Gilden, derzeit Humni, wenden.)
+
+  Abenteurergilde               - Boing
+  Gilde der Karatekaempfer      - Humni
+  Krieger des Chaos             - Ennox (i), Mupfel (i), Bugfix
+  Akademie der geistigen Kraft  - Chagall
+  Der Heilige Orden             - Wargon (i), Gloinson
+  Bierschuettlergilde           - Bielefeld (i), Shakedbeer(i), Raschaua (i)
+  Kaempfergilde                 - Gabylon
+  Die Katzenkrieger             - Bambi
+  Die Tanjian                   - Chagall, Nibel (i)
+  Dunkelelfen                   - Amaryllis(*), Padreic (i)
+  Uruk-Hai                      - Bugfix, Rhovan, Morgoth (i)
+  Wipfellaeufer                 - Humni
+  Werwoelfe                     - Humni
+
+(*) Amaryllis hat fuer die Gilde derzeit wenig Zeit.
+(i) Dieser Magier ist zur Zeit inaktiv.
+
+SIEHE AUCH:
+     Gilden, Magier, Regionen, Regionsmagier, Erzmagier
+
+Fre, 05. Juni 2015, 22:52:00 von Boing
diff --git a/doc/help/gott b/doc/help/gott
new file mode 100644
index 0000000..25c88d5
--- /dev/null
+++ b/doc/help/gott
@@ -0,0 +1,26 @@
+
+Goetter im Morgengrauen
+=======================
+
+ BESCHREIBUNG:
+     Es gibt einige, wenige Goetter im Morgengrauen. Wie bei allen Goettern
+     gilt es in der Anbetung des Jof, Rumata und Zook erstens jeweils den
+     richtigen Ansprechpartner und zweitens die richtige Balance zwischen
+     Schleimerei und Gottesbelaestigung zu finden. Kleine Opfergaben wie
+     Bierreichungen auf Parties sind natuerlich gern gesehen.
+
+     Unsere Goetter zogen ein schweres Los - wo die Erzmagier Arbeit
+     erledigen, tragen die Goetter die schwere Last der Verantwortung. Sie
+     muessen dafuer sorgen, dass das rechte Mass an Neid, Missgunst, Gier und
+     Verstimmung zwischen Spielern, Sehern, Magiern, Erzmagiern und sonstigen
+     Spielteilnehmern immer gewahrt bleibt.
+
+ BEMERKUNGEN:
+     Es gibt einen zurueckgetretenen Gott, Boing. Dieser wird immer noch
+     von einigen Unglaeubigen in blutigen Ritualen in der SSP verehrt.
+
+ SIEHE AUCH:
+        erzmagier, willkuer, parties
+
+ LETZTE AeNDERUNG:
+    22. November 2004 Muadib
diff --git a/doc/help/hardcore b/doc/help/hardcore
new file mode 100644
index 0000000..0ac2b98
--- /dev/null
+++ b/doc/help/hardcore
@@ -0,0 +1,29 @@
+Der Hardcoremodus
+======================
+
+    Entscheidet sich der Spieler fuer nur ein einziges Leben, so 
+    spielt er im Hardcoremodus.
+
+    Dies bedeutet, dass der Spieler nach seinem ersten Tod nicht mehr
+    aktiv am Spiel teilnehmen kann. Lediglich kommunikative Mittel wie
+    das Rufen oder die Ebenen stehen ihm noch zur Verfuegung.
+
+    Dieser Modus sollte nur von erfahrenen Spielern gewaehlt werden.
+
+    Die Hardcorespieler unterliegen den Regeln wie ganz normale 
+    Spieler.
+
+    Wenn ein Spieler wuenscht, im Hardcoremodus zu spielen, kann er/sie vor
+    Erreichen der zweiten Stufe (d.h. bevor man das erste Mal erhoehen kann)
+    und vor dem ersten Tod einen Erzmagier ansprechen, welcher den HC-Modus
+    aktiviert. Dies ist endgueltig und wird nicht rueckgaengig gemacht.
+
+    Eine Warnung: Ein gestorbener Spieler wird unter gar keinen Umstaenden
+    wieder in das Leben zurueckgeholt.
+
+ SIEHE AUCH:
+    rufe, ebenen, tod, regeln 
+
+ LETZTE AeNDERUNG:
+    22.8.2011, Zesstra
+
diff --git a/doc/help/heilung b/doc/help/heilung
new file mode 100644
index 0000000..f29f8eb
--- /dev/null
+++ b/doc/help/heilung
@@ -0,0 +1,40 @@
+
+Die Heilung
+===========
+
+     Im Kampf oder durch Gift verliert man mehr Lebenspunkte als einem
+     lieb sein kann. Zauberei verbraucht zusaetzlich Konzentration.
+
+     Es gibt mehrere Wege um sich zu heilen:
+
+      Mit Geduld: Im Herzschlag heilt ein Spieler - so er nicht vergiftet
+                  ist - langsam sich selbst. Das ist immer auch von der
+                  Umgebung und der Rasse des Spielers abhaengig.
+
+      In Kneipen: Man kann sich durch Verzehr von Speisen oder Getraenken
+                  rascher selbst heilen. Dabei wird einem diese Heilung
+                  innerhalb des Herzschlages langsam zuteil.
+                  Wichtig ist hierbei vor allem, dass man nur soviel
+                  Heilungspotential mit einem Mal essen oder trinken kann,
+                  wie man maximale Lebenspunkte/Konzentrationspunkte hat.
+                  Besitzt man also maximal 90 Lebenspunkte, so kann man in
+                  einem Moment nur fuer 90 Lebenspunkte essen oder trinken,
+                  alle darueberhinausgehende Heilung der Speise geht
+                  verloren.
+                  Bei aktuellen 20 LP waere es also sinnvoll, zwei Getraenke
+                  a 35 Lebenspunkte zu sich zu nehmen. Vor einem Kampf kann
+                  man sich dadurch uebrigens einen zusaetzlichen Puffer
+                  verschaffen, indem man 2 Getraenke a 35 und 1 Getraenk a
+                  20 Lebenspunkte zu sich nimmt. Die 20 LP werden einem dann
+                  bei eventuellem LP-Verlust im Kampf wieder zugefuehrt.
+
+      Mit Magie:  Viele Orte oder auch Gildenangehoerige bestimmter Gilden
+                  besitzen spezielle Magie, die einem ebenfalls zu Heilung
+                  verhelfen kann. Diese Heilung ist entweder sofortig oder
+                  unterliegt den gleichen Regeln wie die Heilung in Kneipen.
+
+ SIEHE AUCH:
+     tod, leben, essen, kampf, report
+
+ LETZTE AeNDERUNG:
+     14. Maerz 2004 Gloinson
diff --git a/doc/help/irc b/doc/help/irc
new file mode 100644
index 0000000..61e8a71
--- /dev/null
+++ b/doc/help/irc
@@ -0,0 +1,23 @@
+IRC

+===

+

+     Der IRC-Kanal des Morgengrauens (-#mg) ist von aussen wie folgt

+     zu erreichen:

+     

+     Server:	irc.freenet.de

+		irc.fu-berlin.de

+		- siehe auch http://irc.fu-berlin.de/ircmap.html

+     Kanal:	mg.de

+

+     Befehle:   Um aus dem IRC zu sehen, welche Spieler den IRC-

+                Kanal des MG nutzen:

+                /msg [MG] who #mg.de

+

+                Um vom MG heraus die Liste der ICR-User zu sehen:

+                -#MG @who

+							

+ SIEHE AUCH:

+     kanaele, www

+

+ LETZTE AeNDERUNG:

+    30. Maerz 2006 Gloinson

diff --git a/doc/help/kaempfer b/doc/help/kaempfer
new file mode 100644
index 0000000..1e3a2f0
--- /dev/null
+++ b/doc/help/kaempfer
@@ -0,0 +1,79 @@
+
+Die Kaempfergilde
+-----------------
+
+    Die Kaempfergilde im MorgenGrauen ist dem Bund der Trves angeschlossen.
+    Sie hat ihren Hauptsitz im Koru-Tschakar-Struv, welches im Nordosten
+    der Insel "Akhar Nth'Tar" gelegen ist.
+
+    Man erlernt dort den Umgang mit den verschiedenen Waffentypen, wobei die
+    maximale Faehigkeit abhaengig von der Rasse ist. Es gibt:
+
+     * Messer und Dolche,
+     * Schwerter,
+     * Kampfstaebe,
+     * Aexte und Beile,
+     * stumpfe Hiebwaffen und
+     * Speere bzw. Stangenwaffen.
+
+    Weiterhin gibt es noch den allgemeinen Umgang mit Zweihandwaffen.
+
+    Es gibt verschiedene Kampftaktiken bzw. Techniken, die man im Kampf je
+    nach Gegner waehlen kann:
+
+     * Allgemeine Taktik (Verhaeltnis von Offensive zu Defensive),
+     * die Raserei und
+     * die Technik der Schildkroete, Drache oder Schlange
+
+    Besondere Aktionen im Kampf sind z.B.:
+
+     * das Schnelle Kaempfen,
+     * das Unterlaufen der Waffe des Gegners,
+     * die Finte und
+     * der Kampfwille.
+
+    Es gibt eine Reihe von zusaetzlichen Angriffen, die man machen kann,
+    wie z.B.:
+
+     * Kampftritt,
+     * Kniestoss und
+     * Todesstoss.
+
+    Ausserdem kann man einen Waffenbruch und einen KO-Schlag anbringen.
+
+    Es gibt natuerlich auch defensive Kampfmittel:
+    Die Parade und die Schildparade. Recht anspruchsvoll ist das Ausweichen
+    von Zauberspruechen.
+
+    Techniken, die im Gruppenkampf nuetzlich sind:
+
+     * Rueckendeckung,
+     * das Blockieren der Waffe des Gegners und
+     * das Beschimpfen des Gegners.
+
+    Zusaetzlich gibt es noch:
+
+     * das Waffenschaerfen,
+     * das Einschaetzen von Monstern, Waffen und Ruestungen,
+     * das Identifizieren von Dingen,
+     * den Kampfsprung,
+     * das Saufen und
+     * das Tragen von schweren Lasten.
+
+ Insgesamt gibt es 41 verschiedene Faehigkeiten zu erlernen.
+ Darueberhinaus gilt es, auf seinem Weg durch die verschiedenen Gildenlevel
+ (zur Zeit bis GL 24), immer einige der 38 Aufgaben, die das Struv fuer
+ einen bereithaelt, zu erledigen.
+
+ Wer sich noch mehr Informationen verschaffen moechte, schaut einfach mal
+ auf http://www.trves.de vorbei.
+
+
+ SIEHE AUCH:
+    attribute, ebenen, gilden
+
+    *Ist man Mitglied einer anderen Gilde, so muss man fuer die Hilfen zu den
+    Spruechen `hilfe gilde kaempfer <name>' benutzen!*
+
+ LETZTE AeNDERUNG:
+    Thu, 17.01.2008, 14:00:00 von Gabylon
diff --git a/doc/help/kampf b/doc/help/kampf
new file mode 100644
index 0000000..991e545
--- /dev/null
+++ b/doc/help/kampf
@@ -0,0 +1,32 @@
+
+Kaempfen
+========
+
+     Kaempfen, auch allgemein als Metzeln bekannt ist eine der Lieblings-
+     sportarten diverser Gilden und aktiver Spieler. Dabei sucht man sich
+     einen moeglichst interessant ausgestatteten NPC, bringt ihn um und
+     benutzt dessen ehemaliges Hab und Gut um einen weiteren NPC zu toeten.
+     Das ist beliebig iterierbar.
+
+     Ein Kampf ist in Kampfrunden aufgeteilt, die durch den Herzschlag
+     bestimmt sind. Benutzt man eine Waffe oder hat Haende frei, so greift
+     man mit diesen einen Gegner an, dessen Haut und Ruestung schuetzt
+     davor. Dann greifen der oder die Gegner an.
+
+     In jeder Kampfrunde kann man zusaetzlich mit Zauberei oder Objekten
+     Schaden verursachen oder den Kampf beeinflussen. Wie oft das moeglich
+     ist, haengt von Seherstatus, (Seher)level und eigener Geschwindigkeit
+     ab.
+
+     Gerade schwierigere Monster koennen nur im Team besiegt werden. In
+     der Parallelwelt, die nur fuer Seher erreichbar ist, sind die Monster
+     manchmal auch noch etwas staerker oder hinterhaeltiger.
+
+ SIEHE AUCH:
+     Verwandt: toete, stop, report, team
+     Anderes:  heilung, leben, tod 
+               zauberei, waffenfertigkeiten
+               balance, abenteuer
+
+ LETZTE AeNDERUNG:
+    14. Maerz 2004 Gloinson
diff --git a/doc/help/karate b/doc/help/karate
new file mode 100644
index 0000000..5b1216b
--- /dev/null
+++ b/doc/help/karate
@@ -0,0 +1,72 @@
+
+Die Gilde der Karatekaempfer
+----------------------------
+
+    Man kann in der Gilde der Karatekaempfer bei Sensei Funakoshi Karate
+    lernen. Wenn man in der Gilde eingetreten ist, sollte man ihn nach den
+    Anforderungen fragen - er sagt einem dann, welche Karatetechniken man
+    lernen und ueben muss, um jeweils den naechsten Grad zu erreichen.
+
+    Es wird jedoch einige Zeit dauern, bis man die verschiedenen Techniken gut
+    genug kann. Man kann in der Gilde jede Technik einzeln ueben, bei den
+    Abwehrtechniken ist es jedoch ratsam, diese mit `uebe abwehr' gegen den
+    Sensei zu ueben - dabei muss man auf jeden Angriff mit einer Abwehrtechnik
+    reagieren. Natuerlich muss es die richtige Abwehr sein - einen Age-Zuki
+    (Fauststoss nach oben, im Kopfbereich) kann man nun einmal nicht mit einem
+    Gedan-Barai (Abwehr nach unten, gegen Schlaege unterhalb der Guertellinie)
+    abwehren. Anfangs wird man auch noch nicht jeden Angriff abwehren koennen.
+    Beim Training sollte man uebrigens nicht zuviel Krempel mit sich
+    herumschleppen - immerhin muss man sich bei Karate viel bewegen.
+
+    Im Kampf wendet man die erlernten Techniken uebrigens automatisch an. Auch
+    dadurch lernt man einiges hinzu. Schwere Ruestungen schraenken allerdings
+    die Beweglichkeit stark ein - man sollte sich also auf Gi und Guertel
+    beschraenken.
+
+    Es werden beim Kampf uebrigens nur die Ruestungen im getroffenen
+    Koerperbereich beim Gegner beruecksichtigt - wenn jemand in einem Bereich
+    schlecht geschuetzt ist, sollte man sich mit `angriff mit xxx, yyy und
+    zzz' auf die Angriffstechniken im richtigen Zielbereich beschraenken. Wer
+    einen hohen Grad hat, waehlt uebrigens die richtige Technik automatisch
+    etwas geschickter...
+
+    Es ist auch wichtig, wie gross der Gegner ist - ein Elf sollte nicht
+    versuchen, einen Zwerg mit einem Age-Zuki anzugreifen, weil er dann
+    Loecher in die Luft ueber ihm schlaegt.
+
+    Von den Angriffstechniken sind Tritte am effektivsten, danach kommen
+    Handkantenschlaege, dann Ellbogenschlaege und Knietritte, dann
+    Faustschlaege und zuletzt Fauststoesse.
+
+    Man kann mit zwei Haenden im Prinzip besser verteidigen als mit einer -
+    jedoch ist eine darauf folgende Handtechnik immer etwas schlechter. Auch
+    zwei Fusstechniken kurz hintereinander sind nicht empfehlenswert.
+
+    Die Erfolgswahrscheinlichkeit einer Technik haengt nicht nur vom Koennen
+    ab, sondern auch von der geistigen Konzentration, also den Magiepunkten.
+    Wenn diese nachlassen, sinkt die Wahrscheinlichkeit, bei schwierigen
+    Techniken frueher und bei leichten spaeter. Je hoeher jedoch der Grad ist,
+    desto langsamer sinkt die Wahrscheinlichkeit dann.
+
+    Die maximale Wirkung eines misslungenen Schlages ist schlechter als die
+    maximale Wirkung eines gelungenen Schlages - bei einfachen Schlaegen halb
+    so gut, bei schwierigen noch weniger. Je hoeher der Grad ist, desto hoeher
+    ist die garantierte Mindestwirkung eines gelungenen Schlages. Bei hohen
+    Graden kann es auch geschehen, dass ein Schlag besonders gut gelingt - bei
+    voller Konzentration wird die Wirkung dadurch fast verdoppelt. Handschuhe
+    bzw. Schuhe daempfen natuerlich einen Schlag bzw. Tritt.
+
+    Die Verteidigung ist auch noch von der Art des Angriffs abhaengig - ein
+    Karateka kann Angriffe mit stumpfen und spitzen Waffen gut abwehren,
+    Schwerter und aehnliche Waffen auch noch recht gut, aber etwas schlechter.
+    Gegen Magie, Feuer und Aehnliches sieht ein Karateka anfangs recht alt
+    aus, weil er dies nicht abwehren kann - wenn er einen hohen Grad hat
+    gelingt, es ihm aber oefter, einem solchen Angriff auszuweichen, jedoch
+    nur, wenn er nicht zuviel Gewicht dafuer bewegen muss.
+
+ SIEHE AUCH:
+    abwehr, angriff, konzentration, nemoku-owaru,
+    attribute, ebenen, gilden, daempfung
+
+    *Ist man Mitglied einer anderen Gilde, so muss man fuer die Hilfen zu den
+    Kommandos `hilfe gilde karate <name>' benutzen!*
diff --git a/doc/help/katzenkrieger b/doc/help/katzenkrieger
new file mode 100644
index 0000000..a70d42b
--- /dev/null
+++ b/doc/help/katzenkrieger
@@ -0,0 +1,13 @@
+KATZENKRIEGER:
+
+        Als die Dschungelstadt  Katzmandu ihre Tore fuer  die Welt oeffnete,
+        lernte die Welt nicht nur die Felinen kennen, sondern auch die Gilde
+        der  Katzenkrieger.  Die Mitglieder  dieser  Gilde  verfuegen  ueber
+        verschiedene Zauber und  Faehigkeiten,  deren Ursprung im taeglichen
+        Kampf um das Ueberleben im Dschungel zu suchen ist.
+
+        Naehere  Informationen  zu  dieser  Gilde findest  Du in der grossen
+        Bibliothek von Katzmandu.
+
+SIEHE AUCH:
+	attribute, gilden, kanaele
diff --git a/doc/help/klerus b/doc/help/klerus
new file mode 100644
index 0000000..0fb8693
--- /dev/null
+++ b/doc/help/klerus
@@ -0,0 +1,72 @@
+
+Die Klerikergilde
+-----------------
+
+    Obwohl der Stammtempel des Heiligen Ordens sich auf der Insel am Ende der
+    Welt befindet, spielt sich der fuer die Spieler relevante Teil im Tempel
+    in der Stadt Djelibeby ab. Die Begruendung kann man im 'Buch der
+    Grundsaetze' nachlesen.
+
+    Praktisch bedeutet dies, dass so gut wie alle Aktionen, wie der Ein- oder
+    Austritt, das Erlernen von Spruechen (bei den Klerikern Anrufungen
+    genannt) und das Erhoehen der Stufe nur im Tempel in Djelibeby verfuegbar
+    sind. Nur fuer die Priesterweihe und den Aufstieg zum/zur Erleuchteten
+    muss man den Stammtempel aufsuchen. Der Besuch des Stammtempels lohnt sich
+    jedoch auch, wenn man sich genauer ueber die Ordensgeschichte informieren
+    will, da dort die wichtigsten Schriftstuecke zu finden sind.
+
+ INFORMATIONEN:
+    Um sich ueber den Orden zu informieren, sollte man im Tempel folgende
+    Buecher lesen:
+
+     Das Buch der Anrufungen
+        hier stehen Informationen zu den einzelnen Anrufungen
+
+     Das Buch der Grundsaetze
+     Das Buch des zweiten Exodus
+        ein paar historische Informationen
+
+     Das Buch der Hierarchie
+        die einzelnen Ordensstufen mit Anforderungen und Faehigkeiten
+
+ ZUM EINTRITT:
+    Fuer den allerersten Eintritt in den Orden benoetigt man einen
+    Fuersprecher. Dieser muss selbst Mitglied des Heiligen Ordens und in der
+    Ordenshierarchie schon zum Wanderprediger aufgestiegen sein. Wenn man (aus
+    welchen Gruenden auch immer) aus dem Heiligen Orden austritt und dann doch
+    wieder eintreten will, ist ein Fuersprecher nicht mehr noetig.
+
+    Weitere Eintrittsbedingung ist, dass man einen heiligen Charakter
+    aufweist.
+
+ ZU DEN ANRUFUNGSKOSTEN:
+    Bei den Kosten, die auf den Hilfeseiten angegeben sind, handelt es sich
+    nur um Grundwerte. Diese Werte variieren abhaengig vom Charakter und der
+    Glaubensstaerke. Ein frecher, boeser oder gar satanischer Charakter zieht
+    hoehere Kosten nach sich, waehrend es bei nettem, gutem oder heiligem
+    Charakter zu einer Kostensenkung kommt.
+
+    Ausserdem werden bei der Weihe zum Priester die Kosten der Anrufungen der
+    Gottheit, der man sich geweiht hat, generell um 20% reduziert, waehrend
+    die Kosten fuer die Anrufungen der anderen Goetter um 20% steigen.
+
+    Die genauen Kosten zu gegebenem Charakter und Glaubensstaerke kann man
+    immer im Buch der Anrufungen nachschlagen.
+
+ SONSTIGES:
+    In den Tempeln steht den Ordensmitgliedern der Befehl `tempeltransport'
+    zur Verfuegung, der den schnellen Wechsel zwischen beiden Tempeln erlaubt.
+
+ SIEHE AUCH:
+    gilden,
+    bete, entfrosche, identifiziere, lebenskraft, sonnenschutz, donner,
+    entfluche, kuriere, laeutere, blitz, heile, schaetz, segne,
+    elementarsphaere, entgifte, leuchten, traue, weihe, elementarschild,
+    heiligenschein, messerkreis, regeneriere, spaltung, beistand, heiltrank,
+    schutzhand, wunder
+
+    *Nicht-Kleriker muessen fuer die Hilfen zu den Anrufungen `hilfe gilde
+    klerus <name>' benutzen!*
+
+ LETZTE AeNDERUNG:
+    Fri, 05.09.1997, 08:47:08 von Wargon
diff --git a/doc/help/konzept b/doc/help/konzept
new file mode 100644
index 0000000..5b84130
--- /dev/null
+++ b/doc/help/konzept
@@ -0,0 +1,58 @@
+
+Die Idee hinter diesem Spiel
+============================
+
+    Dies sind die (etwas technisch gehaltenen) Grundkonzepte des
+    MorgenGrauens, bzw. von LPMuds an sich:
+
+     1. Ein Magier kann das Spiel erweitern.
+
+     2. Spielerweiterungen koennen am laufenden Spiel vorgenommen werden.
+
+     3. Alles im Spiel besteht aus Objekten. Raeume, Spieler, Monster und
+        Schaetze sind alles Objekte.
+
+     4. Alle Objekte werden in einem C-Dialekt (LPC) geschrieben. Die
+        Objekte werden bei Bedarf geladen und halbinterpretiert.
+
+     5. Es gibt keinen Parser. Alle Kommandos werden von den Objekten
+        definiert. Ein Messer definiert zum Beispiel das Kommando `schneide'
+        und eine Lederjacke das Kommando `trage'.
+
+        Ein Objekt definiert ein Kommando, indem es sie mit einer im Objekt
+        implementierten Funktion verknuepft. Wenn der Spieler das Kommando
+        eingibt, so wird die zugehoerige Funktion im Objekt aufgerufen. Wenn
+        der Spieler `trage jacke' eingibt, so wird `jacke' als Argument an
+        diese Funktion uebergeben. Wenn der Spieler `trage schild' eingibt, so
+        erkennt die Funktion, dass `jacke' != `schild' ist, und gibt den Wert
+        fuer Misserfolg (0) zurueck. Dann wird ein anderes `trage'-Kommando
+        ausprobiert, bis ein Passendes gefunden wird.
+
+        Bewegt der Spieler die Jacke aus seinem Inventory oder seinem
+        Environment - sprich seinem Einflussbereich so werden alle Kommandos,
+        die zur Jacke gehoeren geloescht.
+
+     6. Raeume sind Objekte, die Kommandos wie `osten' oder `kletter' und
+        aehnliches definieren. Wenn der Spieler `osten' eingibt, so wird die
+        zugehoerige Funktion etwas mit dem Spieler tun.
+
+     7. Ein Objekt kann eine Funktion namens heart_beat() definieren. Diese
+        Funktion wird alle zwei Sekunden aufgerufen. Diese Funktion kann fuer
+        selbststaendig agierende Monster, verloeschende Fackeln oder
+        verzoegerte Fallen eingesetzt werden.
+
+        Der Phantasie der Magier sind keine Grenzen gesetzt.
+        (Der Effizienz dieser Funktion schon!)
+
+     8. Das komplizierteste Objekt ist das Spielerobjekt. Es definiert
+        Kommandos wie `nimm', `laechel', `schau' oder `toete'.
+
+     9. Wenn ein Spieler Magier wird, so wird er einer Region zugeteilt.
+        Innerhalb dieser Region darf er dann das Spiel erweitern. Er kann
+        Schloesser bauen, oder eine Hoehle ...
+
+    10. Fuer Magier, die Objekte schreiben, stehen ein ed-kompatibler Editor
+        und ein UNIX-aehnliches Filesystem zur Verfuegung.
+
+ LETZTE AeNDERUNG:
+    14. Maerz 2004 Gloinson
diff --git a/doc/help/lag b/doc/help/lag
new file mode 100644
index 0000000..227a5a1
--- /dev/null
+++ b/doc/help/lag
@@ -0,0 +1,41 @@
+Das LAG
+=======
+
+    Das LAG ist das groesste und fieseste Monster des Morgengrauen. Selbst
+    Magier und Goetter sind machtlos. Es tritt auf den Plan, wenn ein Magier
+    mal wieder Unsinn fabriziert, ein Seher das eigene Haus bis zum
+    Dachspanten vollgemuellt oder ein sehr beliebter Mitspieler ein
+    "mail freunde" abgesetzt hat.
+
+    Ganz technisch betrachtet ist der Rechner ueberlastet und kann den
+    Mud-Prozess nicht mit gewohnter Geschwindigkeit ausfuehren. Dadurch
+    haengt dann natuerlich alles - der Vorteil jedoch ist, dass man im
+    Normalfall an Lag nicht stirbt, da auch alle Monster unter Zeitmangel
+    leiden.
+    Dahingegen ist das kleine Monster Netzlag hinterhaeltiger. Meist reicht
+    es aber, den Nachbarn vom Netzkabel herunterzuschubsen um es zu
+    vertreiben.
+
+
+    Es gibt einige Spielzeuge, mit denen man sich das Lag in Zahlen
+    anzeigen lassen kann. Am beliebtesten ist jedoch der Kanal <MasteR>:
+
+    [<MasteR>:Gloinson] l
+    [<MasteR>:<MasteR>] 7.80 cmds/s, 127.97 comp lines/s
+    [<MasteR>:<MasteR>] Lag: 0.5%/60, 0.8%/15, 1.2/5, 0.0%/1
+
+    Dabei bedeuten die Zahlen, um wieviel Prozent im Vergleich zur normalen
+    Zeit das MUD in den letzten 60/15/5/1 Minuten im Durchschnitt langsamer
+    war.
+    
+    Hierbei ist zu beachten, dass selbst der 1-Minutenwert nur alle 10s
+    berechnet wird. Tritt also gerade jetzt ein Lag auf und ihr fragt sofort
+    das Lag ab, ist es wahrscheinlich, dass es noch nicht im 1-Minutenwert
+    enthalten ist. Die anderen Werte werden entsprechend seltener neu
+    bestimmt.
+
+ SIEHE AUCH:
+    mudrechner, sterben, ebenen
+
+ LETZTE AeNDERUNG:
+    04.09.2010, Gloinson
diff --git a/doc/help/leben b/doc/help/leben
new file mode 100644
index 0000000..883b399
--- /dev/null
+++ b/doc/help/leben
@@ -0,0 +1,23 @@
+
+Leben und Lebenspunkte
+======================
+
+     Ein jeder geniesst sein (virtuelles) Leben so gut er kann, oft wird
+     gemetzelt, manchmal gequestet und noch haeufiger geidelt.
+
+     Das Leben wird bestimmt durch Lebenspunkte und Konzentrationspunkte,
+     wobei erstere ueber den Tod entscheiden und zweitere einen Einfluss
+     auf die Zauberei haben. Sinken die Lebenspunkte durch Kampf oder Gift
+     auf unter 0, stirbt man (fast immer). Die Anzahl der Lebenspunkte
+     haengt vom Attribut Ausdauer ab, kann aber auch durch besondere
+     Zaubereien oder Ausruestung erhoeht werden.
+
+     Jeder Spieler hat einen Herzschlag. Diesen spuert er im Kampf oder
+     nach dem Kampf, denn dieser bestimmt Kampfrunden (und die darin
+     moeglichen Aktionen) und die Heilung.
+
+ SIEHE AUCH:
+     tod, heilung, kampf, report
+
+ LETZTE AeNDERUNG:
+     4. Nov 2011 Gloinson
diff --git a/doc/help/leitfaden b/doc/help/leitfaden
new file mode 100644
index 0000000..e0eb5d2
--- /dev/null
+++ b/doc/help/leitfaden
@@ -0,0 +1,228 @@
+Ein kleiner Leitfaden zum Spiel im MorgenGrauen
+===================================================
+
+  Das MorgenGrauen ist ein Spiel. Wie bei jedem Spiel muessen, um den
+  Spielspass moeglichst fuer alle zu erhalten, ein paar wenige Regeln
+  beachtet werden. Diese Regeln gelten sowohl fuer Spieler als auch
+  fuer Magier.
+
+                                *
+
+    Die wichtigste Regel betrifft das Angreifen und Toeten anderer
+    Spieler.
+
+    ES IST STRIKT UNTERSAGT ANDERE SPIELER ANZUGREIFEN ODER ZU TOETEN.
+
+    Auch das absichtliche indirekte Toeten von Spielern durch
+    Gildenfaehigkeiten, spezielle Objekte oder aehnliches faellt unter
+    diese Regel.
+
+    Sollte man einen Spieler umgebracht haben, treten sofort
+    Beschraenkungen in Kraft, die nur durch einen Erzmagier wieder
+    aufgehoben werden koennen.
+
+    Will man sich dennoch mit anderen Spielern messen, so existieren
+    extra dafuer eingerichtete Gebiete, wie zum Beispiel die Arena in
+    der Wueste, in denen man sich gegenseitig bekaempfen kann.
+
+                                *
+
+    Hat man mit seinem Charakter eine Zeit lang gespielt, so entsteht
+    oft der Wunsch, einmal eine andere Rasse, Gilde oder einfach einen
+    anderen Rollenspielcharakter zu spielen.
+    Seinen bisherigen Charakter kann oder moechte man dazu allerdings
+    nicht benutzen.
+    Daher kann jeder Spieler weitere Charaktere anlegen.
+
+    Diese muessen dann jedoch als sogenannter Zweitspieler des ersten
+    Charakters markiert werden.
+    Diese Markierung kann man zum Beispiel beim Schmied in der
+    Zwergenstadt oder beim Dorfschreiber im Elfendorf erhalten.
+    Diese Markierung kann man auch vor anderen Spielern verbergen.
+
+    Man kann beliebig viele seiner Charaktere gleichzeitig einloggen,
+    doch ist hierbei darauf zu achten, dass nur zwei dieser Charaktere
+    aktiv am Spielgeschehen, das ist alles was ueber reine
+    Kommunikation hinausgeht, teilnehmen.
+    Die anderen Charaktere muessen sich auf die Kommunikation
+    beschraenken.
+
+    Weitere Einschraenkungen existieren fuer Magier.
+
+    Ein Magier darf nicht gleichzeitig mit seinen Spielercharakteren
+    eingeloggt sein, diese manipulieren oder fuer seine Zweitspieler
+    fremden Code analysieren.
+
+    Der Magier-Zweitspieler sollte darauf achten, anderen Spielern
+    nicht durch seinen eventuellen Wissensvorteil bei Questen zu
+    helfen.
+
+    Ein Magier-Zweitspieler sollte weiterhin darauf achten, andere
+    Spieler nicht in ihrem Spiel zu behindern. Dies koennte zum
+    Beispiel durch Blockieren von Quests oder bestimmter limitierter
+    Gildenraenge geschehen.
+    Den Programmierern von Quests oder Gilden steht es natuerlich frei,
+    hier eine eigene Vorsorge zu treffen.
+
+                                *
+
+    Wer im MorgenGrauen spielt, der ist des oefteren auf die Hilfe
+    Anderer angewiesen. Eine Form der Hilfe ist es, einen Charakter
+    auszuleihen oder ausgeliehen zu bekommen.
+    Um sprachlich begruendete Missverstaendnisse im weiteren zu
+    vermeiden, hier kurz folgende Nomenklatur:
+
+      Ein Spieler, der einem anderen Spieler einen Charakter zur
+      Verfuegung stellt, wird als Verleiher bezeichnet.
+
+      Ein Spieler, der einen Charakter eines anderen Spielers nutzt,
+      wird als Nutzer bezeichnet.
+
+    Das Ausleihen von Charakteren ist mit gewissen Randbedingungen
+    erlaubt.
+
+    Ein ausgeliehener Charakter wird als aktiver Zweitspieler des
+    Nutzers betrachtet und ist somit den Regelungen fuer Zweitspieler
+    unterworfen.
+
+    Besonders zu beachten ist, dass der ausgeliehene Charakter nicht
+    mit dem Nutzer, oder einem Zweitspieler des Nutzers, in ein Team
+    darf.
+
+    Sowohl der Nutzer des ausgeliehenen Spielers als auch Verleiher,
+    koennen fuer die Handlungen des ausgeliehen Charakters
+    verantwortlich gemacht werden.
+
+                                *
+
+    Wer mit einem Charakter Aufgaben geloest hat oder zu bestimmten
+    Vermutungen ueber Forscherpunkte gelangt ist, der notiert dies oft,
+    um bei spaeteren Charakteren auf diese Informationen zugreifen zu
+    koennen.
+
+    Solche Forscherpunktlisten oder Komplettloesungen sind zum
+    Eigengebrauch, das heisst fuer die eigenen Zweitspieler erlaubt.
+
+    Die Weitergabe dieser Informationen oder das Nutzen von nicht
+    selbst erstellten Komplettloesungen oder Forscherpunktlisten sind
+    anderen Spielern gegenueber im hoechsten Masse unfair und daher
+    untersagt.
+
+                                *
+
+    Um das Spielen von Muds zu vereinfachen und komfortabler zu
+    gestalten, gibt es eine Reihe sogenannter Mud-Clients.
+
+    Diese Clienten bieten oftmals die Moeglichkeit, mehrere Kommandos
+    im Mud auf eine einzige Aktion hin auszufuehren oder auf Ausgaben
+    mit solchen Kommandoketten zu reagieren.
+
+    Man spricht hier von Scripten oder Triggern.
+
+    Zusammen mit einer internen Programmiersprache der Clienten lassen
+    sich vielfach bestimmte Aktionen im Mud automatisieren.
+
+    Die Verwendung solcher Scripte ist mit einigen Auflagen jedem
+    Spieler freigestellt.
+
+    Sogenannte Untersuchescripte, die selbstaendig eine oder mehrere
+    Detailtiefen von Raeumen, Monstern oder anderen Gegenstaenden
+    abfragen, sind nicht erlaubt.
+
+    Jeder Charakter sollte individuell gesteuert werden, daher sind
+    Scripte, die mehrere Charaktere auf einmal steuern untersagt.
+
+    Scripte, welche einen Charakter im Sinne einer Komplettloesung
+    durch eine Quest fuehren oder eine Forscherpunktliste abarbeiten
+    sind nicht erlaubt.
+
+    Grundsaetzlich duerfen andere Spieler durch Scripte nicht in ihrem
+    Spiel behindert oder belaestigt werden.
+
+    Alle anderen Scripte sind erlaubt, soweit der Spieler innerhalb
+    einer Minute im Rahmen seiner Moeglichkeiten ansprechbar bleibt.
+
+    Als unerlaubtes Skript zaehlt auch der Kampf mit einem Monster,
+    wenn der Spieler dabei laengere Zeit keine Tastatureingaben
+    vornimmt und dabei nicht ansprechbar ist(totidlen). Dies gilt vor
+    allem wenn der Tod des Monsters nicht absehbar ist.
+
+                                *
+
+    Das MorgenGrauen baut auf die Arbeit vieler freiwilliger
+    Programmierer auf. Wie bei jedem Programm kann es dabei zu Fehlern,
+    auch Bugs genannt, kommen.
+
+    Jeder Spieler sollte ein Interesse daran haben, dass diese Fehler
+    beseitigt werden.
+
+    Dies kann man durch eine Meldung des Fehlers an den jeweiligen
+    Magier oder falls dieser nicht erreichbar ist, durch eine Meldung
+    an den entsprechenden Regionsmagier erreichen. Auch der Befehl
+    "fehler" kann hier nuetzliche Dienste leisten.
+
+    Wer diese Magier sind, kann jedem Spieler bei Bedarf durch einen
+    anwesenden Magier oder oft auch anderen Spieler mitgeteilt werden.
+
+    Dieses Vorgehen sollte auch fuer Fehler gelten, die dem Spieler,
+    der diese Fehler entdeckt, zum Vorteil gereichen.
+
+    Sollte sich ein Spieler nicht sicher sein, ob es sich bei einem
+    bestimmten Verhalten von Gegenstaenden, Monstern oder Raeumen um
+    einen Fehler handelt oder um Absicht des Programmieres, so kann er
+    den zustaendigen Magier problemlos danach fragen und somit bei der
+    Beseitigung von Fehlern aktiv helfen.
+
+    Das Verschweigen und Ausnutzen von Fehlern ist anderen Spielern
+    gegenueber unfair und ist daher zu unterlassen.
+
+                                *
+
+    Grundsaetzlich sollte der Spielspass fuer moeglichst alle Spieler
+    erhalten bleiben. Dazu gehoert auch ein gewisses Mass an Fairness
+    der Spieler untereinander.
+
+    Es ist nicht der Sinn der Regeln, das Spielen im MorgenGrauen durch
+    Ueberreglement zu behindern oder reizlos zu gestalten.
+
+    Daher ist es jedoch auch moeglich, dass im Spiel Situationen
+    auftreten, die den Spielspass anderer Spieler und die allgemeine
+    Fairness beeintraechtigen, ohne dass diese Situation durch diesen
+    Leitfaden abgedeckt ist.
+
+    Hier ist jeder Spieler und auch Magier gefragt, seinen gesunden
+    Menschenverstand zu befragen und zu ueberlegen, wie er eine solche
+    Situation vermeiden oder entspannen kann, auch wenn man damit auch
+    einmal auf einen Vorteil verzichten muss.
+
+    Es ist also durchaus nicht alles erlaubt, was nicht explizit
+    verboten ist.
+
+                                *
+
+    Fuer Magier gelten natuerlich zusaetzlich die Regeln des
+    Magiervertrages.
+
+                                *
+
+    Sollte ein Spieler oder Magier gegen Regeln verstossen haben, so
+    kann dies vom Sheriff, seinen Deputies oder den Erzmagiern geahndet
+    werden.
+    Strafen koennen sich von einer einfachen Verwarnung bis hin zur
+    Loeschung von Charakteren erstrecken.
+
+    Die Strafen werden in einem gesunden Verhaeltnis zum Fehlverhalten
+    des Spielers stehen.
+
+                                *
+
+    Wer die Funktion des Sheriffs oder eines Deputies wahrnimmt, kann
+    man mit dem Kommando 'hilfe sheriff' erfragen.
+
+
+ SIEHE AUCH:
+    zweitiemarkierung, fehler, sheriff
+
+ LETZTE AeNDERUNG:
+    Wed, 30.08.2000, 11:35:00 von Muadib
+    
diff --git a/doc/help/loeschskript b/doc/help/loeschskript
new file mode 100644
index 0000000..c54b4be
--- /dev/null
+++ b/doc/help/loeschskript
@@ -0,0 +1,18 @@
+Kriterieren fuer das Loeschskript

+=================================

+

+    Das Script zum Loeschen alter Charaktere laeuft jeweils am 20. eines

+    Monats.

+    Charaktere werden geloescht, wenn sie ALLE folgenden Bedingungen

+    erfuellen:

+

+    * 90 Tage nicht eingeloggt

+    * weniger als 30 Abenteuerpunkte

+    * weniger als 30000 Erfahrungspunkte

+    * Stufe kleiner 10

+

+ SIEHE AUCH:

+    selbstloeschung, spielpause

+

+ LETZTE AeNDERUNG:

+    09.03.2013 Zesstra

diff --git a/doc/help/magier b/doc/help/magier
new file mode 100644
index 0000000..e439dc8
--- /dev/null
+++ b/doc/help/magier
@@ -0,0 +1,130 @@
+
+MAGIER
+======
+
+    In MorgenGrauen erweitern Magier das MUD. Ausserdem haben sie viele
+    Moeglichkeiten, die Spieler nicht haben.
+
+     Wer kann Magier werden?
+        Magier kann jeder werden, der die Anforderungen zur Seher-Werdung
+        erfuellt; siehe dazu die Hilfeseite 'seher'.
+        Soll ein Charakter Magier werden, der selber kein Seher ist, aber der
+        Erstspieler dieses Spielers ist Seher, ist dies mit Genehmigung der
+        EMs moeglich. Hierzu muss den EMs (in Absprache mit dem zukuenftigen
+        Sponsor) ein GS-Konzept vorgestellt werden (in diesem Fall bitte 
+        auch Abschnitt 'Magierwerdung mit einem nicht-Seher' unten beachten).
+
+     Muss ich Magier werden?
+        Wer keine Lust hat, Magier zu werden und lieber noch spielen moechte,
+        kann mit diesen Voraussetzungen Seher werden. Als Seher hat man auch
+        ein paar zusaetzliche Faehigkeiten.
+
+     Wie werde ich Magier?
+        Wenn Du die Voraussetzungen erfuellst, um Magier zu werden, musst Du
+        einen Magier finden, der Dich unterstuetzt. Dieser Magier soll den
+        neuen Magier in seine Moeglichkeiten einweisen und fuer Fragen offen
+        sein. D.h. es sollte am besten ein Magier sein, den Du schon kennst
+        und von dem Du Hilfe erwarten kannst.
+
+        Wenn Du so einen Magier gefunden hast, fragst Du ihn, ob er Dich zu
+        einem neuen Magier ausbildet. Von dem Magier bekommst Du dann einen
+        Vertrag, den Du sorgfaeltig lesen solltest. Wenn Du dann immer noch
+        Magier werden willst, unterschreibst Du den Vertrag. Danach gehst Du
+        mit dem Vertrag zu Merlin (erstmal suchen) und der Magier, von dem
+        Du den Vertrag hast, bittet Merlin, Dich zum Magier zu machen.
+
+        Danach solltest Du von dem Magier eine Einfuehrung erhalten,
+        desweiteren wird Dir Merlin ein Mail mit nuetzlichen Informationen
+        schicken.
+
+     Und was dann?
+        Du beginnst Dein Magierdasein als Lehrling (Lv 15). Du hast noch kein
+        eigenes Verzeichnis, in dem Du programmieren kannst, und Du kannst
+        auch nicht in allen Verzeichnissen lesen. Du kannst Dich allerdings
+        schon einmal mit den Einschraenkungen des Magierlebens (siehe Vertrag)
+        sowie mit der MudLib vertraut machen. Dazu hast Du Leserechte in den
+        Verzeichnissen `/doc', `/std', `/secure' und `/sys'.
+
+        Wenn Du zu diesem Zeitpunkt erkennst, dass der Magierstatus wohl doch
+        nichts fuer Dich ist, kannst Du Dich immer noch an einen Erzmagier
+        wenden, damit er Dich wieder zum Spieler macht. Hiermit solltest Du
+        jedoch nicht zulangen warten, da hierzu eine aeltere Kopie Deines
+        ehemaligen Spielers noetig ist.
+
+        Wenn Du allerdings merkst, dass Du gerne etwas programmieren moech-
+        test, dann melde Dich (mit mail erzmagier) unter Angabe eines kurzen
+        Abrisses, wie Du Deinen weiteren Werdegang als Magier vorstellst bei
+        den Erzmagiern, damit sie Dich auf die naechste Magierstufe (Lv 20)
+        befoerdern. Die Bearbeitugnszeit dieser Mail liegt bei ein bis zwei
+        Wochen. Auf dieser Stufe bekommst Du ein eigenes Verzeichnis samt
+        Workroom, und Du kannst Deine ersten eigenen Programmierversuche
+        starten.
+
+        Wenn Du auch nach Deinen ersten mehr oder weniger erfolgreichen
+        Programmierversuchen noch immer nicht die Flinte ins Korn geworfen
+        hast, dann solltest Du Dir einmal Gedanken darueber machen, was Du
+        im MorgenGrauen genau programmieren moechtest. Der zustaendige
+        Regionsmagier wird Dich bei der Ausarbeitung Deines Konzeptes gerne
+        beraten. Bevor Du anfaengst zu programmieren, solltest Du mit
+        Deinem genauen Konzept noch einmal bei einem zustaendigen
+        Erzmagier nachfragen, ob es als Gesellenstueck ausreicht.
+
+        Sobald Dein Regionsmagier und Du der Meinung seid, dass Deine
+        Sachen fertig sind, koennt Ihr Euch damit an einen der fuer
+        die Abnahme von Gesellenstuecken zustaendigen Erzmagier (siehe
+        Hilfe Erzmagier) wenden. Dieser wird sich Deine Arbeit ansehen und
+        dann entscheiden, ob sie fuer ein Gesellenstueck im MorgenGrauen
+        ausreichend ist. Beachte bitte, dass vor einer solchen Genehmigung
+        durch die zustaendigen Erzmagier von Dir noch keine Objekte
+        unter eigenem Namen angeschlossen werden koennen/duerfen.
+
+        Sofern Du die Regeln fuer Gesellenstuecke erfuellt hast, wird Dich
+        der zustaendige Erzmagier zu einem Vollmagier machen. Erst dann
+        kannst Du auch in anderen Teilen der MudLib einen Blick in den
+        Quellcode anderer Magier werfen. Ausserdem bekommst Du ein eigenes
+        Verzeichnis in der Region, in der Du mitarbeiten moechtest. Dort
+        kannst Du Deine Sachen ausgiebig testen und spaeter dann auch von
+        Deinem Regionsmagier anschliessen lassen.
+
+
+Magierwerdung mit einem nicht-Seher
+-----------------------------------
+
+      * Die Berufung eines nicht-Seher-Charakters zum Magier ist moeglich,
+        sofern der betreffende RL-Spieler bereits einen Seher hat.
+      * Die Berufung eines solchen Charakters zum Magier ist nur in Absprache
+        mit den EMs moeglich. Bei konkreten Anfragen an EMs muss eine erste 
+        Idee angegeben werden, was man sich als GS vorstellt.
+      * Ein vernuenftiges, d.h. zustimmungsfaehiges Konzept muss _vor_
+        Magierwerdung den EMs vorgstellt werden.. An dieses werden die sonst
+        ueblichen Anforderungen bzgl. Umfang und Komplexitaet gestellt. Das
+        Konzept wird von EMs genehmigt, bevor die Berufung zum Magier
+        erfolgt.
+      * Nach Sponsorn des Charakters entfaellt die sonst uebliche Wartezeit
+        von 1-2 Wochen (weil die EMs ja vorher zugestimmt haben) und der
+        Char kann direkt auf Level 20 befoerdert werden.
+      * Das GS muss innerhalb von 6 Monaten nach Magierwerdung fertiggestellt 
+        werden.
+        Die Fertigstellung ist definiert als Einreichung an den RM zur 
+        Abnahme.
+        Dies darf natuerlich keine pro-forma Einreichung von halbfertigem 
+        Zeugs sein.
+      * Eine Verlaengerung dieser Frist kann durch einen von den EMs be-
+        nannten EM (idR EM Gesellenstuecke) genehmigt werden, sofern ihm
+        dies sinnvoll erscheint ("begruendete Faelle", fast fertig, etc.).
+        In Zweifelsfaellen wird die Verlaengerung von den EMs diskutiert.
+      * Muss das GS nach Abnahme durch den RM und/oder den EM Gesellenstuecke
+        nachgebessert werden, sollte dieses innerhalb von 2 Monaten geschehen.
+        Verlaengerungen: s.o.
+      * Bei Nicht-Einhaltung der Frist erfolgt die Loeschung des Charakters 
+        oder Dauerspielpausen auf Magierlevel 15.
+      * Der Spieler unterliegt auch nach Loeschung dem Magiervertrag insofern,
+        als dass er ueber etwaige als Magier gewonnene Interna von nicht-
+        oeffentlichem Code Stillschweigen zu wahren hat.
+
+ SIEHE AUCH:
+    stufen, magierstufen, abenteuer, konzept, gesellenstueck
+    seher, regionen, gildenmagier, erzmagier, goetter
+
+ LETZTE AeNDERUNG: 2015-05-30 von Zook
+
diff --git a/doc/help/magierstufen b/doc/help/magierstufen
new file mode 100644
index 0000000..e36c8b3
--- /dev/null
+++ b/doc/help/magierstufen
@@ -0,0 +1,68 @@
+magierstufen
+============
+
+    Es gibt verschiedene Magierstufen, die bestimmte Rechte und Pflichten mit
+    sich bringen. Ueblicherweise sind die entsprechenden Magier oft auch ein
+    paar Level hoeher (so ist ein Gott ueblicherweise Level 111), dies sind
+    die Grenzen, ab wo die Bezeichnung bzw. die Rechte im beschriebenen 
+    Umfang gueltig sind:
+
+    Level 100	---	Gott
+		Ernennt Erzmagier, klaert schwerwiegende Probleme, traegt die
+		Last der Verantwortung.
+		Volle Schreibrechte.
+
+    Level 60	---	Erzmagier
+		Sind fuer verschiedene praktische Aufgabengebiete wie
+		(Gildenbalance), Mudlib oder Gesellenstuecke verantwortlich.
+		Volle Schreibrechte.
+
+    Level 50	---	Weise
+		Bearbeiten ein spezielles Thema.
+		Volle Schreibrechte bis auf die Mudlib.
+
+    Level 40	---	Regionsmagier
+		Sind fuer eine oder mehrere Regionen zustaendig und haben
+		dort volle Schreibrechte. Ernennt Regionsmitarbeiter.
+
+    Level 30	---	Hilfsmagier
+		Kuemmern sich um Dokumentation oder andere Spezialaufgaben,
+		haben dafuer im Dokumentationsbereich volle Schreibrechte.
+
+    Level 26    ---     Regionsmitarbeiter
+                Wie Level 25, darf zusaetzlich selbst Neumagier berufen.
+		Wird vom Regionsmagier verliehen, fuer Magier, denen diese
+		Verantwortung zugetraut werden kann.
+
+    Level 25	---	Regionsmitarbeiter
+		Arbeitet in einer (oder mehreren) Regionen mit und hat dort
+		auf sein Verzeichnis volle Schreibrechte.
+
+    Level 21	---	Vollmagier
+		Meist ein Uebergangszustand, wenn das Gesellenstueck
+		akzeptiert aber in keiner Region angeschlossen ist.
+		Schreibrechte im eigenen Verzeichnis.
+		Leserechte in allen Gebieten und der Mudlib, mit gewissen
+		Ausnahmen.
+
+    Level 20	---	Lehrling
+		Schreibt sein Gesellenstueck (oder sollte es tun).
+		Schreibrechte im eigenen Verzeichnis.
+		Keine Leserechte in Regionen, Magier- oder Gilden-
+		verzeichnissen.
+
+    Level 15	---	Lehrling/Neumagier
+		Auf diesem Level kann man in der Dokumentation und in der
+		Mudlib stoebern und sich mit dem Magierdasein vertraut
+		machen. Diesen Level erhaelt man direkt nach der
+		Magierwerdung.
+		Bei Annahme des Konzeptes fuer das Gesellenstueck erfolgt
+		Befoerderung auf Level 20.
+		Keine Schreibrechte.
+
+ SIEHE AUCH:
+    magier, stufen, vertrag
+    seher, regionen, gildenmagier, erzmagier, goetter
+
+ LETZTE AeNDERUNG:
+	25.01.2006 von Humni
diff --git a/doc/help/merlin b/doc/help/merlin
new file mode 100644
index 0000000..48ebe78
--- /dev/null
+++ b/doc/help/merlin
@@ -0,0 +1,13 @@
+
+Merlin
+======
+
+Merlin ist der Uebervater aller Magier. Er ist auch zustaendig,
+falls ein Spieler Magier oder Seher werden moechte. Sprich ihn
+einfach einmal darauf an.
+
+Daneben ist er auch reichlich tuettelig und vergisst manchmal,
+wo er sich befindet....
+
+
+LETZTE AeNDERUNG: 2006-02-21 von Zook.
\ No newline at end of file
diff --git a/doc/help/mudrechner b/doc/help/mudrechner
new file mode 100644
index 0000000..7a3100e
--- /dev/null
+++ b/doc/help/mudrechner
@@ -0,0 +1,31 @@
+Der Mudrechner
+==============
+
+     Das Mud laeuft seit 21. Feb 2010 auf:
+     - Dell 2950 mit 2 Netzteilen
+     - 2 * XEON 5420 2.5GHz, 8GB RAM, 70GB (RAID1) OS, 500 GB (RAID1) Daten
+     und ist ueber
+      - 1GB Ethernet (extern 1GB)
+     an das Internet angeschlossen.
+
+     Unter der Adresse mg.mud.de sind ebenfalls:
+      stunnel:  - zur Verschluesselung der Verbindung mit dem MUD
+      FTP:      - anonym
+                  - zum Hochladen von Partybildern
+                  - zum Zugriff auf Software (inklusive aktueller Mudlib)
+                - mit Magiername/Passwort
+                  - zum Zugriff auf das eigene Verzeichnis im MUD
+      git:      - mit hinterlegtem Schluessel (fuer Magier)
+                  - zum Zugriff auf saemtliche freien/eigenen git-Repositories
+      WWW:      - die Webseiten des MG
+     zu erreichen.
+
+ SIEHE AUCH:
+   lag, irc, stunnel, teamspeak, client, www
+
+ HISTORY:
+      Rechner bis 21. Feb 2010, (Stand 08. April 2004):
+      - Xeon CPU 2.40GHz 1024MB RAM, 36 + 70 GB Plattenplatz (SCSI)
+
+ LETZTE AeNDERUNG:
+     8. Nov 2012 Gloinson
diff --git a/doc/help/parties b/doc/help/parties
new file mode 100644
index 0000000..4bd8719
--- /dev/null
+++ b/doc/help/parties
@@ -0,0 +1,28 @@
+
+Parties des Morgengrauen
+========================
+
+ KOMMANDOS:
+     anmelden
+
+ BESCHREIBUNG:
+     Mit diesen Kommando meldet man sich an einem Partybrett zu einer der
+     regelmaessig stattfindenden Parties der Morgengrauen Mudder an. Dort
+     darf man dann dem Protzen welterfahrener Spieler, den Aufschneiden
+     schon lange nicht mehr spielender Seher, den vagen Andeutungen der
+     Magier und sonstigen Prahlereien bei gepflegtem Alkoholkonsum und immer
+     unter der Aufsicht eines Erzmagiers fuer Sittlichkeit lauschen.
+     Wirklich wichtige Details koennen von dir thematisiert werden.
+
+     Ort, Zeit und Kosten der demnaechst stattfindenden Party kann man in
+     der MPA, rubrik "party" oder im Web unter
+       https://mg.mud.de/realworld/party.shtml
+     erfahren.
+
+     erfahren.
+
+ SIEHE AUCH:
+     verein, magier
+
+ LETZTE AeNDERUNG:
+     22. Maerz 2004 Gloinson
diff --git a/doc/help/post b/doc/help/post
new file mode 100644
index 0000000..df10b56
--- /dev/null
+++ b/doc/help/post
@@ -0,0 +1,182 @@
+Das Postsystem
+==============
+
+    Im Mud gibt es auch die Moeglichkeit, anderen Spielern Post zu senden.
+    Anders als bei der Bundespost sind aber weder Briefe noch Postkarten im
+    Mud freimachungspflichtig.
+
+    Man geht einfach in eine der Postfilialen und tippt `post' oder `mail', um
+    in das Postmenue zu gelangen. Das Postmenue gibt auf `h' (oder `hilfe')
+    eine kurze Hilfsseite mit einer Befehlsuebersicht.
+
+    Will man nach 'post' oder 'mail' nicht die im Folder enthaltenen Mails
+    aufgelistet bekommen, so nutze man stattdessen 'post -silent' oder
+    'mail -silent'.
+
+ Inhaltsverzeichnis dieser Hilfsseite:
+
+    1. Mail schreiben
+    2. Mail nach und von ausserhalb des Muds
+    3. Mailaliase
+    4. Mail lesen, beantworten, loeschen und weitersenden - die anderen
+       Menuepunkte im Postmenue
+    5. Ordner (folders)
+    6. Nachsendeauftraege (.forward)
+    7. Paketpost
+    8. Absender ignorieren
+
+ 1. Mail schreiben:
+    Grundsaetzlich gibt es zwei Moeglichkeiten: Entweder innerhalb des
+    Postmenues `m <name>', oder aber man ruft direkt mit `mail <name>' das
+    Schreiben auf und landet dann nach Beendigung im Menue.
+
+    Man wird zunaechst nach der Ueberschrift gefragt und gibt dann den Text
+    ein. Die Eingabe verwendet einen einfachen Editor mit einigen
+    rudimentaeren Editorfunktionen, eine eigene Hilfsseite ist mit `~h'
+    abzufragen.
+    Ueberlange Zeilen werden auf 78 Zeichen pro Zeile umgebrochen, man kann
+    also getrost auch lange Texte am Stueck schreiben.
+
+    Beendet wird die Eingabe mit `.' oder `**' (als eigene Zeile eingeben) und
+    wird dann nach CC's gefragt. CC bedeutet `carbon copy', also Durchschlag.
+    Man kann jetzt einen oder mehrere durch Komma oder Leerzeichen getrennte
+    Namen angeben, an die der Brief zusaetzlich zum eigentlichen Empfaenger
+    gesendet wird.
+
+    Mail an mehrere Personen:
+    Man kann gleich beim Aufruf mehrere Namen durch Komma oder Leerzeichen
+    getrennt angeben, oder die anderen als cc. Auch eine Kombination ist
+    erlaubt. Gibt man mehr als einen Namen als Empfaenger an, so gilt der
+    erste als Empfaenger, die restlichen bekommen cc's.
+
+    Blind Carbon Copies (BCC):
+    Setzt man vor einen Namen ein `-', so wird der Brief auch an diese Adresse
+    gesendet, aber die Adresse steht nicht im Verteiler.
+    *Achtung:* Der eigentliche Empfaenger, also die erste angegebene Adresse,
+    darf keine BCC sein.
+
+ 2. Mail nach und von ausserhalb
+    
+    a) Mail in andere Muds ((Inter-)Mudmail)
+      Es ist moeglich, Mails in eine Reihe von anderen Muds zu schicken und
+      welche von dort zu empfangen.
+      Zum Empfangen muss man nix tun.
+      Zum Versenden gibt man den Charnamen des Empfaenger gefolgt von einem @
+      und dem Mudnamen des Empfaengers an, z.B. 'bla@unitopia'.
+
+    b) Mail in den Rest des Internets
+      
+      Achtung: Politische Vorgaben und das Anwachsen von Spam haben zur
+               Abschaltung dieser Funktionen gefuehrt.
+
+ 3. Mailaliase:
+    Mailaliase koennen wie Namen verwendet werden. Es gibt eine Anzahl
+    vordefinierter Aliase, eine Liste der Aliase bekommt man im Postmenue mit
+    `a'.
+    Magier haben die Moeglichkeit, sich eine Datei `.mailrc' in ihr
+    Verzeichnis zu legen, die eigene Mailaliase enthaelt.
+
+    Es gibt einige vordefinierte Mailaliase, die fuer alle gelten:
+
+     * `me' sendet an diejenige Adresse, die man selber als Emailadresse
+       angegeben hat. Das ist nuetzlich, wenn man Post an seinen eigenen
+       account weiterschicken will.
+     * `freunde' - das sind alle Deine Freunde, wie sie auf Deinem
+       Freundschaftsband stehen (falls Du eins hast).
+     * Rundschreiben an alle Mitarbeiter einer Region: Einfach `d.xyz' als
+       Empfaenger angeben, wobei `xyz' natuerlich der Name der Region ist.
+     * einige weitere Aliase wie `erzmagier', `polizei', `goetter', ... (siehe
+       Liste mit `a') erleichtern es, den richtigen Ansprechpartner zu finden.
+     * Einige Aliase sind eigentlich Nachsendeauftraege und werden bald
+       verschwinden.
+
+ 4. Mail lesen und die anderen Menuepunkte im Postmenue
+
+     Mail lesen:
+        Einfach die Nummer des Briefes tippen, die man lesen will. Um den
+        aktuellen Brief (das ist der, auf den der Pfeil zeigt) zu lesen, `.'
+        tippen, fuer den naechsten `+' (praktisch zum Durchblaettern), `-'
+        fuer den vorhergehenden.
+
+     Mail loeschen:
+        Alle Briefe werden gespeichert, bis man sie loescht. Als Argument
+        Nummer angeben, ansonsten wird der Brief geloescht, auf den der Pfeil
+        in der Liste zeigt.
+
+        Listenargumente der Form [nr] [nr-nr] ... sind zulaessig.
+
+        Beispiel: `d 18 12-14 2' loescht die Briefe Nummer 2,12,13,14,18.
+
+     Mail beantworten, Gruppenantwort:
+        Dasselbe wie `schreiben', nur dass der Empfaenger automatisch der
+        Absender des beantworteten Briefes ist, und, ausser man gibt eine
+        andere an, die Ueberschrift `Re: <Originalueberschrift>' lautet.
+
+        Bei "Gruppenantwort" wird die Antwort ausserdem an alle Empfaenger von
+        CC's des Originalbriefes verschickt.
+
+        Ist eine `Reply-to:'-Zeile im Text enthalten, wird der Brief an die
+        hier angegebene Adresse geschickt.
+
+        *Achtung:* Auch in diesem Fall werden Mailaliase und ggf.
+        Nachsendeauftraege ausgewertet!
+
+     Mail weitersenden (forward):
+        Der erhaltene Brief wird kopiert und an den neuen Empfaenger
+        weitergeschickt. Bei `F' bzw. `Weiter' kann man ausserdem noch
+        zusaetzlich eigenen Text anhaengen.
+
+        Nur fuer `f' (also ohne zusaetzlichen Text) gilt: Wird eine Liste als
+        Argument angegeben, so werden alle Briefe zu einem langen Brief
+        zusammengehaengt und dieser weitergesendet.
+
+ 5. Zum Thema Ordner:
+    Man kann Briefe, die man noch nicht loeschen will, in verschiedene Ordner
+    (folders) sortieren. Solche Ordner muss man zunaechst anlegen, dann kann
+    man die Briefe von einem zum anderen verschieben. Angezeigt werden
+    natuerlich immer nur die Briefe des aktuellen Ordners. Um andere zu lesen,
+    muss man zunaechst den Ordner wechseln.
+
+    Beim Einstieg ins Postmenue schlaegt man zunaechst den Ordner `newmail'
+    auf, in den alle ankommenden Briefe auch abgespeichert werden.
+
+    Alle Befehle, die Ordnernamen als Argumente verlangen, akzeptieren auch
+    `-' fuer den in der Liste vorhergehenden Ordner, `+' fuer den
+    nachfolgenden und jede eindeutige Abkuerzung.
+
+ 6. Nachsendeauftraege
+    Will man seine Post lieber an einen anderen Charakter ausgeliefert
+    bekommen, so geht das auch. Hierzu muss man aber als Emailadresse den
+    anderen Char in dieser Form angeben: 'neuer_empfaenger@morgengrauen' 
+    (siehe auch Befehl 'email').
+
+    Um einen solchen Nachsendeauftrag zu stellen, geht man zu irgendeinem
+    Postamt mit Paketschalter. Genaueres erzaehlt der Postbeamte auf
+    Nachfrage.
+
+    Man sollte sich dieses aber gut ueberlegen: hat ein Charakter keine
+    gueltige eMail-Adresse eingetragen, ist das Zuruecksetzen des Passwortes
+    erheblich komplizierter oder sogar unmoeglich.
+
+    Es ist NICHT moeglich, eine eMail-Adresse ausserhalb des Morgengrauens
+    anzugeben.
+
+ 7. Paketpost
+    Im MorgenGrauen gibt es eine Paketpost. Informationen erteilt der
+    Postbeamte an jedem Paketschalter.
+
+ 8. Absender ignorieren
+    Sollte man von einem bestimmten Absender ueberhaupt keine Post empfangen
+    wollen, so kann dies durch "ignoriere name.mail" erreicht werden, wobei
+    "name" natuerlich durch den konkreten Spielernamen zu ersetzen ist.
+
+------------------------------------------------------------------------------
+
+(c) 1993-1996 Morgengrauen Postverwaltung
+Abteilung Technik, Loco (Abteilungsleiter)
+Anregungen, Fehlermeldungen und Fragen bitte direkt an Loco,
+Flames direkt nach /dev/null.
+
+LETZTE AeNDERUNG:
+   28.10.2013, Zesstra
+
diff --git a/doc/help/rassen b/doc/help/rassen
new file mode 100644
index 0000000..45e4ef5
--- /dev/null
+++ b/doc/help/rassen
@@ -0,0 +1,102 @@
+DIE RASSEN DES MORGENGRAUEN
+---------------------------
+
+Wenn Du jetzt nicht gerade ein Gast bist, kannst Du Deine Rasse ohnehin nicht
+mehr veraendern. Der folgende Ueberblick ist vielleicht trotzdem von Nutzen.
+
+Er beinhaltet genau die Hinweise, die auch bei der Charaktergenerierung
+angezeigt werden.
+
+MENSCHEN
+--------
+
+Die Staerke des Menschen ist seine Vielseitigkeit.
+Der Mensch kann zwar nichts besonders gut - dafuer aber eigentlich alles.
+
+DUNKELELFEN
+-----------
+
+Das Volk der Dunkelelfen lebt in einer grossen Hoehlenstadt gut versteckt
+hinter einem Wasserfall. Ueber kaum ein anderes Volk gibt es soviele
+Vorurteile wie ueber die Dunkelelfen, und so werden sie von allen misstrauisch
+beaeugt oder sogar bekaempft. In diesem Kampf, insbesondere gegen die Elfen,
+sind sie voellig auf sich allein gestellt, und so hat sich eine mehr oder
+minder autarke Gesellschaft entwickelt. Die Dunkelelfen haben eine eigene
+Kultur und eine eigene Goettin, der sie huldigen. Wie auch die Elfen
+verfuegen sie ueber ausserordenlich grosse magische Faehigkeiten, auch wenn
+sie sich mehr auf die schwarze Seite der Magie spezialisiert haben.
+
+ZWERGE
+------
+
+Zwerge sind kleine aber kraeftige Gebirgsbewohner, nicht sehr gespraechig,
+leicht erzuernt, aber eine schlagkraeftige Unterstuetzung fuer ihre Freunde.
+Ihr Mut und ihre Standfestigkeit ist weit und breit beruehmt, auch ihr
+Geschick im Umgang mit Zwergenwaffen verleiht ihnen zusaetzliche Kraft.
+Leider sind Zwerge nicht allzu schlau, sie verlassen sich lieber auf
+ihre Kraft als auf ihr Gehirn.
+
+GOBLINS
+-------
+Goblins sind winzige, gruenhaeutige Wesen, sogar noch kleiner als Hobbits.
+An ihren zu dick geratenen Koepfchen befinden sich lange, selten reglose,
+Ohren und eine grosse, krumme Nase. Ihre kleine Statur sollte jedoch nicht
+taeuschen, denn ihre fehlende Kraft machen sie mit Geschwindigkeit,
+Praezision und nicht zuletzt ihrer unbestrittenen Ruchlosigkeit alleweil
+wett.
+Obwohl fuer sie Pluendern, lautes Herumbruellen und die gemeinsten Streiche
+spielen zum Alltag gehoeren, wuerde sie niemand als boesartig bezeichnen.
+Denn Goblins sind vieles, aber sicherlich nicht die intelligentesten
+Kreaturen. Durch ihren zaehen Willen und die dicke, lederne Haut sind sie
+aussergewoehnlich widerstandsfaehig, und, sofern funkelnde Beute winkt, fuer
+jedes Abenteuer zu haben.
+
+ELFEN
+-----
+
+Als Elfen bezeichnet man in der Regel jene hageren Hinterwaeldler, deren
+demonstratives Naturgehabe in der Regel nur durch ihre Liebe zu kitschigen
+Gedichten und ausschweifendem Geschlechtsleben in den Schatten gestellt wird.
+Einen Elf kann man im allgemeinen nicht nur an aeusseren Missbildungen
+(spitze Ohren, spindelduerre Gestalt, blonde Haare) erkennen, sondern auch
+an seiner aufdringlichen Art, ueber jeden und alles hemmungslos ins Gruene
+loszuphilosophieren.
+
+FELINEN
+-------
+
+Felinen sind aufrecht gehende Katzenwesen.
+Ihre Heimat ist der Dschungel. Kaum jemand duerfte sich dort besser
+zurechtfinden als sie. Bedingt durch diese Umgebung haben sie im Laufe der
+Zeit eine Vorliebe fuer elegante Hoelzer und funkelnde Edelsteine entwickelt.
+Sie sind zwar nicht so 'raffgierig' wie Zwerge, aber dennoch sollte man besser
+nicht versuchen, einem Felinen einen Edelstein wegzunehmen. Sie benutzen die
+Edelsteine sehr gerne, um sich damit zu schmuecken. Felinen betreiben sogar
+einen regelrechten Koerperkult, insbesondere wenn es darum geht, das Fell oder
+die Krallen zu faerben. Edelsteine kommen da als Accessoires gerade recht.
+Auch im Kampf gegen einen Felinen sollte man sehr vorsichtig sein, da Felinen
+ihre geringe Ausdauer durch eine hohe Geschwindigkeit sowie Geschick und
+Intelligenz wettmachen. Auch die Spitzen Krallen sind da nicht zu verachten
+und so mancher Gegner musste schon als Ersatz fuer einen Kratzbaum herhalten.
+
+HOBBITS
+-------
+
+Hobbits sind kleine Wesen, die am ehesten den Menschen aehneln.
+Sie zeichnen sich trotz Ihrer Groesse durch ihren Mut und Standfestigkeit aus.
+Obwohl sie viel lieber zuhause vorm warmen Kamin sitzen, sind sie immer
+fuer ein Abenteuer zu haben.
+
+ORKS
+----
+
+Orks sind humanoide Wesen, allerdings etwas kleiner als Menschen. Von Natur
+aus sind sie ausgesprochen haesslich anzusehen mit ihrere dunklen Haut, die
+fast ins zwergenartig-dreckige geht. Aufgrund ihrer charakterlichen Neigung
+zu Gewaltbereitschaft werden sie gerne als unzivilisiert angesehen, haben
+sich jedoch als unerschrockene, risikobereite Kaempfer einen Namen gemacht.
+
+Letzte Aenderung: 20.05.2015, Amaryllis
+
+
+
diff --git a/doc/help/reboot b/doc/help/reboot
new file mode 100644
index 0000000..e6f183b
--- /dev/null
+++ b/doc/help/reboot
@@ -0,0 +1,57 @@
+Reboots und ihre Folgen
+-----------------------
+    
+    Bei einem 'Reboot' wird das MorgenGrauen heruntergefahren, d.h.
+    das aktuelle Spiel wird beendet und, wenn alles gut geht, ein neues 
+    Spiel gestartet. Dies ist manchmal noetig, wenn groessere Aenderungen 
+    am MorgenGrauen vorgenommen wurden.
+    
+    Dabei gehen in der Regel alle Objekte (Waffen, Ruestungen etc.), die 
+    im Umlauf waren, verloren. Nach einem 'Reboot' stehst Du also erstmal 
+    ziemlich nackt in der Gegend herum :)
+    
+    Eine Ausnahme bilden jedoch sogenannte 'Autoload-Objekte'. Oft sind
+    dies Objekte, die man als Belohnung fuer bestandene Abenteuer erhalten
+    hat, Gildenobjekte, Muenzen und einiges mehr. Sie ueberleben selbst
+    einen 'Reboot' und bleiben Dir erhalten. Was Du an 'Autoload-Objekten'
+    bei Dir traegst, kannst Du mit dem Befehl 'i +a' erfahren (Siehe hierzu:
+    hilfe inv).
+    
+    Fuer Objekte, die Du durch einen 'Reboot' verloren hast, bekommst
+    Du eine finanzielle Entschaedigung.
+ 
+    Ein 'Reboot' hat jedoch keine Auswirkungen auf Deine Gildenfaehigkeiten,
+    die Hoehe Deiner Erfahrungs- oder Abenteuerpunkte u.ae., er fuegt Dir
+    lediglich einen unwesentlichen materiellen Schaden zu.
+
+Armageddon
+----------
+    Wird ein Reboot noetig, ist das meist keine ploetzliche Angelegenheit,
+    sondern von langer Hand vorbereitet. Daher kann der Reboot auch einige
+    Tage zuvor angekuendigt werden, so dass Spieler sich auf ihn einstellen
+    koennen. Diese Aufgabe uebernimmt Armageddon als Herold des Weltunter-
+    gangs. Dieser ruft regelmaessig aus, wie lange es noch bis zum Reboot 
+    ist und sorgt auch sonst fuer eine passende, unheimliche, also dem Welt-
+    untergang angemessene Stimmung.
+
+    Wenn Du nicht durch Armageddons Meldungen belaestigt werden moechtest, 
+    kannst Du dies auf zweierlei Arten tun:
+    
+    Entweder durch 'ignoriere armageddon'. Du wirst ab sofort nur noch das 
+    absolute Minimum an Meldungen von Armageddon bekommen. Weltuntergangs-
+    stimmung gibt es dann aber auch nicht mehr.
+
+    Oder durch 'teile armageddon mit ruhe'. Damit bringst Du diesen einen
+    Armageddon zum schweigen. Wird dieser aber abgebrochen, oder kommt es
+    doch mal zum Reboot, ist ein neuer Armageddon redseelig wie gehabt. 
+
+    Auf diese Weise verpasst Du keinen Armageddon, wirst aber auch nicht 
+    durch staendiges gescrolle genervt. Falls Du doch wieder genervt werden
+    moechtest, reicht die Wiederholung des oben genannten tm.
+
+    
+ SIEHE AUCH:
+    inv, ignoriere, crash, erzmagier
+
+ LETZTE AeNDERUNG:
+    Mon Apr 05 21:30:00 2004 von Vanion.
diff --git a/doc/help/regeln b/doc/help/regeln
new file mode 100644
index 0000000..5a5136d
--- /dev/null
+++ b/doc/help/regeln
@@ -0,0 +1,232 @@
+Ein kleiner Leitfaden zum Spiel im MorgenGrauen
+===================================================
+
+  Das MorgenGrauen ist ein Spiel. Wie bei jedem Spiel muessen, um den
+  Spielspass moeglichst fuer alle zu erhalten, ein paar wenige Regeln
+  beachtet werden. Diese Regeln gelten sowohl fuer Spieler als auch
+  fuer Magier.
+
+                                *
+
+    Die wichtigste Regel betrifft das Angreifen und Toeten anderer
+    Spieler.
+
+    ES IST STRIKT UNTERSAGT ANDERE SPIELER ANZUGREIFEN ODER ZU TOETEN.
+
+    Auch das absichtliche indirekte Toeten von Spielern durch
+    Gildenfaehigkeiten, spezielle Objekte oder aehnliches faellt unter
+    diese Regel.
+
+    Sollte man einen Spieler umgebracht haben, treten sofort
+    Beschraenkungen in Kraft, die nur durch einen Erzmagier wieder
+    aufgehoben werden koennen.
+
+    Will man sich dennoch mit anderen Spielern messen, so existieren
+    extra dafuer eingerichtete Gebiete, wie zum Beispiel die Arena in
+    der Wueste, in denen man sich gegenseitig bekaempfen kann.
+
+                                *
+
+    Hat man mit seinem Charakter eine Zeit lang gespielt, so entsteht
+    oft der Wunsch, einmal eine andere Rasse, Gilde oder einfach einen
+    anderen Rollenspielcharakter zu spielen.
+    Seinen bisherigen Charakter kann oder moechte man dazu allerdings
+    nicht benutzen.
+    Daher kann jeder Spieler weitere Charaktere anlegen.
+
+    Diese muessen dann jedoch als sogenannter Zweitspieler des ersten
+    Charakters markiert werden.
+    Diese Markierung kann man zum Beispiel beim Schmied in der
+    Zwergenstadt oder beim Dorfschreiber im Elfendorf erhalten.
+    Diese Markierung kann man auch vor anderen Spielern verbergen.
+
+    Man kann beliebig viele seiner Charaktere gleichzeitig einloggen,
+    doch ist hierbei darauf zu achten, dass nur zwei dieser Charaktere
+    aktiv am Spielgeschehen, das ist alles was ueber reine
+    Kommunikation hinausgeht, teilnehmen.
+    Die anderen Charaktere muessen sich auf die Kommunikation
+    beschraenken.
+
+    Weitere Einschraenkungen existieren fuer Magier.
+
+    Ein Magier darf nicht gleichzeitig mit seinen Spielercharakteren
+    eingeloggt sein, diese manipulieren oder fuer seine Zweitspieler
+    fremden Code analysieren.
+
+    Dazu gibt es nur ein Ausnahme: Zum Zwecke der Zweitiemarkierung
+    darf der Magier sich gleichzeitig mit dem Spielercharakter
+    einloggen.
+
+    Der Magier-Zweitspieler sollte darauf achten, anderen Spielern
+    nicht durch seinen eventuellen Wissensvorteil bei Questen zu
+    helfen.
+
+    Ein Magier-Zweitspieler sollte weiterhin darauf achten, andere
+    Spieler nicht in ihrem Spiel zu behindern. Dies koennte zum
+    Beispiel durch Blockieren von Quests oder bestimmter limitierter
+    Gildenraenge geschehen.
+    Den Programmierern von Quests oder Gilden steht es natuerlich frei,
+    hier eine eigene Vorsorge zu treffen.
+
+                                *
+
+    Wer im MorgenGrauen spielt, der ist des oefteren auf die Hilfe
+    Anderer angewiesen. Eine Form der Hilfe ist es, einen Charakter
+    auszuleihen oder ausgeliehen zu bekommen.
+    Um sprachlich begruendete Missverstaendnisse im weiteren zu
+    vermeiden, hier kurz folgende Nomenklatur:
+
+      Ein Spieler, der einem anderen Spieler einen Charakter zur
+      Verfuegung stellt, wird als Verleiher bezeichnet.
+
+      Ein Spieler, der einen Charakter eines anderen Spielers nutzt,
+      wird als Nutzer bezeichnet.
+
+    Das Ausleihen von Charakteren ist mit gewissen Randbedingungen
+    erlaubt.
+
+    Ein ausgeliehener Charakter wird als aktiver Zweitspieler des
+    Nutzers betrachtet und ist somit den Regelungen fuer Zweitspieler
+    unterworfen.
+
+    Besonders zu beachten ist, dass der ausgeliehene Charakter nicht
+    mit dem Nutzer, oder einem Zweitspieler des Nutzers, in ein Team
+    darf.
+
+    Sowohl der Nutzer des ausgeliehenen Spielers als auch Verleiher,
+    koennen fuer die Handlungen des ausgeliehen Charakters
+    verantwortlich gemacht werden.
+
+                                *
+
+    Wer mit einem Charakter Aufgaben geloest hat oder zu bestimmten
+    Vermutungen ueber Forscherpunkte gelangt ist, der notiert dies oft,
+    um bei spaeteren Charakteren auf diese Informationen zugreifen zu
+    koennen.
+
+    Solche Forscherpunktlisten oder Komplettloesungen sind zum
+    Eigengebrauch, das heisst fuer die eigenen Zweitspieler erlaubt.
+
+    Die Weitergabe dieser Informationen oder das Nutzen von nicht
+    selbst erstellten Komplettloesungen oder Forscherpunktlisten sind
+    anderen Spielern gegenueber im hoechsten Masse unfair und daher
+    untersagt.
+
+                                *
+
+    Um das Spielen von Muds zu vereinfachen und komfortabler zu
+    gestalten, gibt es eine Reihe sogenannter Mud-Clients.
+
+    Diese Clienten bieten oftmals die Moeglichkeit, mehrere Kommandos
+    im Mud auf eine einzige Aktion hin auszufuehren oder auf Ausgaben
+    mit solchen Kommandoketten zu reagieren.
+
+    Man spricht hier von Scripten oder Triggern.
+
+    Zusammen mit einer internen Programmiersprache der Clienten lassen
+    sich vielfach bestimmte Aktionen im Mud automatisieren.
+
+    Die Verwendung solcher Scripte ist mit einigen Auflagen jedem
+    Spieler freigestellt.
+
+    Sogenannte Untersuchescripte, die selbstaendig eine oder mehrere
+    Detailtiefen von Raeumen, Monstern oder anderen Gegenstaenden
+    abfragen, sind nicht erlaubt.
+
+    Jeder Charakter sollte individuell gesteuert werden, daher sind
+    Scripte, die mehrere Charaktere auf einmal steuern untersagt.
+
+    Scripte, welche einen Charakter im Sinne einer Komplettloesung
+    durch eine Quest fuehren oder eine Forscherpunktliste abarbeiten
+    sind nicht erlaubt.
+
+    Grundsaetzlich duerfen andere Spieler durch Scripte nicht in ihrem
+    Spiel behindert oder belaestigt werden.
+
+    Alle anderen Scripte sind erlaubt, soweit der Spieler innerhalb
+    einer Minute im Rahmen seiner Moeglichkeiten ansprechbar bleibt.
+
+    Als unerlaubtes Skript zaehlt auch der Kampf mit einem Monster,
+    wenn der Spieler dabei laengere Zeit keine Tastatureingaben
+    vornimmt und dabei nicht ansprechbar ist(totidlen). Dies gilt vor
+    allem wenn der Tod des Monsters nicht absehbar ist.
+
+                                *
+
+    Das MorgenGrauen baut auf die Arbeit vieler freiwilliger
+    Programmierer auf. Wie bei jedem Programm kann es dabei zu Fehlern,
+    auch Bugs genannt, kommen.
+
+    Jeder Spieler sollte ein Interesse daran haben, dass diese Fehler
+    beseitigt werden.
+
+    Dies kann man durch eine Meldung des Fehlers an den jeweiligen
+    Magier oder falls dieser nicht erreichbar ist, durch eine Meldung
+    an den entsprechenden Regionsmagier erreichen. Auch der Befehl
+    "fehler" kann hier nuetzliche Dienste leisten.
+
+    Wer diese Magier sind, kann jedem Spieler bei Bedarf durch einen
+    anwesenden Magier oder oft auch anderen Spieler mitgeteilt werden.
+
+    Dieses Vorgehen sollte auch fuer Fehler gelten, die dem Spieler,
+    der diese Fehler entdeckt, zum Vorteil gereichen.
+
+    Sollte sich ein Spieler nicht sicher sein, ob es sich bei einem
+    bestimmten Verhalten von Gegenstaenden, Monstern oder Raeumen um
+    einen Fehler handelt oder um Absicht des Programmieres, so kann er
+    den zustaendigen Magier problemlos danach fragen und somit bei der
+    Beseitigung von Fehlern aktiv helfen.
+
+    Das Verschweigen und Ausnutzen von Fehlern ist anderen Spielern
+    gegenueber unfair und ist daher zu unterlassen.
+
+                                *
+
+    Grundsaetzlich sollte der Spielspass fuer moeglichst alle Spieler
+    erhalten bleiben. Dazu gehoert auch ein gewisses Mass an Fairness
+    der Spieler untereinander.
+
+    Es ist nicht der Sinn der Regeln, das Spielen im MorgenGrauen durch
+    Ueberreglement zu behindern oder reizlos zu gestalten.
+
+    Daher ist es jedoch auch moeglich, dass im Spiel Situationen
+    auftreten, die den Spielspass anderer Spieler und die allgemeine
+    Fairness beeintraechtigen, ohne dass diese Situation durch diesen
+    Leitfaden abgedeckt ist.
+
+    Hier ist jeder Spieler und auch Magier gefragt, seinen gesunden
+    Menschenverstand zu befragen und zu ueberlegen, wie er eine solche
+    Situation vermeiden oder entspannen kann, auch wenn man damit auch
+    einmal auf einen Vorteil verzichten muss.
+
+    Es ist also durchaus nicht alles erlaubt, was nicht explizit
+    verboten ist.
+
+                                *
+
+    Fuer Magier gelten natuerlich zusaetzlich die Regeln des
+    Magiervertrages.
+
+                                *
+
+    Sollte ein Spieler oder Magier gegen Regeln verstossen haben, so
+    kann dies vom Sheriff, seinen Deputies oder den Erzmagiern geahndet
+    werden.
+    Strafen koennen sich von einer einfachen Verwarnung bis hin zur
+    Loeschung von Charakteren erstrecken.
+
+    Die Strafen werden in einem gesunden Verhaeltnis zum Fehlverhalten
+    des Spielers stehen.
+
+                                *
+
+    Wer die Funktion des Sheriffs oder eines Deputies wahrnimmt, kann
+    man mit dem Kommando 'hilfe sheriff' erfragen.
+
+
+ SIEHE AUCH:
+    zweitiemarkierung, fehler, sheriff
+
+ LETZTE AeNDERUNG:
+    Fri, 08.06.2001, 11:35:00 von Nonne
+    
diff --git a/doc/help/regionen b/doc/help/regionen
new file mode 100644
index 0000000..a278350
--- /dev/null
+++ b/doc/help/regionen
@@ -0,0 +1,37 @@
+Die Regionen im MorgenGrauen
+============================
+
+Fuer so manchen Spieler ist es vielleicht von Interesse zu erfahren, welcher
+Magier fuer welche Region zustaendig ist. Das ist zum einen hilfreich, wenn
+man ein Seherhaus bauen will, zum anderen aber auch dann, wenn man sich mit
+der Absicht traegt selbst mal Magier zu werden und einen Ansprechpartner
+sucht.
+
+Hier also alle Regionen des Morgengrauens mit ihren Regionsmagiern:
+
+   Anfaenger     Ark
+   Dschungel     Ark
+   Ebene         Arathorn
+   Fernwest      Vanion
+   Gebirge       Bambi
+   Inseln        Miril
+   Polar         Humni, Caldra
+   Schattenwelt  Zook
+   Seher         Zook
+   Unterwelt     Zesstra (vertretungsweise in Abwesenheit eines RM)
+   VLand         Bugfix, Esme, nur noch spiritus rector: Morgoth
+   Wald          Notstrom 
+   Wueste        Notstrom, Ennox
+
+Wenn Du den Regionsmagiern einer Region eine Mail schreiben moechtest,
+so verwende am besten die Mail-Aliase "rm_<regionname>".
+
+Falls der/die RMs einer Region ueber laengere Zeit nicht erreichbar sind:
+* bitte ersatzweise einen Erzmagier ansprechen
+* bei akuten Problemen mit "mrufe" und "mail erzmagier" alle ansprechen
+
+SIEHE AUCH:
+	Gildenmagier
+
+----------------------------------------------------------------------------
+Last modified: 2015-12-18 von Zook.
diff --git a/doc/help/reset b/doc/help/reset
new file mode 100644
index 0000000..d3451a9
--- /dev/null
+++ b/doc/help/reset
@@ -0,0 +1,39 @@
+
+Reset
+=====
+
+    Resets sind ein Ereignis fuer alle Objekte (also Wesen, Raeume, Waffen
+    und Ruestungen).
+    Dabei werden diese (oft) auf einen bestimmten Zustand zurueckgesetzt
+    oder es werden Aktionen, wie zB Heilung durch Amulette durchgefuehrt.
+
+    Speziell bei Raeumen werden im Reset:
+      1. Objekte des Raumes neuerzeugt:
+         * sowohl herumliegende Objekte, welche entfernt wurden
+         * als auch getoetete NPCs, die jetzt wiederbelebt werden
+      2. Tueren geschlossen/geoeffnet (je nach Ursprungszustand).
+      3. gleiche, herumliegende Objekte im Raum aufgeraeumt.
+         (danach gibt es maximal 3 gleiche Objekte, das findet nur bei
+          Spielerabwesenheit statt)
+
+    Speziell 1. ist interessant, weil in einem Reset mit einem Mal wieder
+    dieses fiese Blockademonster auftaucht oder endlich der heissersehnte
+    Questgegenstand erlangbar ist.
+
+    Normalerweise ist die Zeit zwischen zwei Resets 30+random(30) Minuten.
+    Allerdings veraendern Magier diese Werte gern mal.
+
+ BEMERKUNGEN:
+    Beruehmt-beruechtigt ist der sogenannte Boing-Reset:
+    Aus technischen Gruenden fand frueher ein Reset in einem das erste Mal
+    seit langer Zeit betretenen (und damit geladenen) Raum sehr frueh nach
+    diesem Betreten statt.
+    Insbesondere in der SSP (also Boings Gebiet) fand man sich dadurch
+    ploetzlich erneut in der Gesellschaft eines doch gerade eben hoeflich
+    hinfortkomplimentierten Blockademonsters wieder.
+
+ SIEHE AUCH:
+    abk, reboot, abenteuer
+
+21.10.2014, Zesstra
+
diff --git a/doc/help/seher b/doc/help/seher
new file mode 100644
index 0000000..69f147c
--- /dev/null
+++ b/doc/help/seher
@@ -0,0 +1,62 @@
+
+Seher
+=====
+
+    Seher im MorgenGrauen sind Spieler, die durch das Erfuellen 
+    bestimmter Anforderungen zeigen, dass sie sich im MorgenGrauen
+    gut auskennen und schon eine Reihe von Herausforderungen 
+    gemeistert haben. Die Seher-Anforderungen muss man auch erfuellen,
+    um Magier werden zu koennen.
+
+    Mit dem Status des Sehers sind einige Vorrechte verbunden, die dem
+    'kleinen' Spieler nicht zur Verfuegung stehen:
+
+     * Seher koennen einige Aspekte ihrer Charakterbeschreibung wie z.B. den
+       Titel, das Presay oder die Bewegungsmeldungen aendern.
+     * Seher koennen sich ein Haus bauen und weitgehend frei einrichten. Das
+       Haus dient danach auch als Startpunkt nach ende oder einem Reboot.
+     * In einigen Gilden stehen die hoechsten Raenge, Zaubersprueche oder
+       Kampftechniken nur Sehern offen.
+     * Weitere Bonbons stellt die Fraternitas dono Archmagorum 
+       zur Verfuegung. 
+
+    Die Bedingungen fuer den Seherstatus sind wie folgt festgelegt:
+
+    Insgesamt benoetigt man 3800 Stufenpunkte und muss die 
+    Spielerstufe 42 erreicht haben, um Seher zu werden. Fuer die 
+    Stufenpunkte muss man in einigen Bereichen gewisse Mindestpunkt-
+    zahlen erreichen:
+
+     * Man muss mindestens 1610 Abenteuerpunkte erzielt haben.
+     * Man muss mindestens 100 Forscherpunkte gesammelt haben, dem
+       entsprechen 600 Stufenpunkten. 
+     * Man muss mindestens 40 Zaubertraenke gefunden haben, dem
+       entsprechen 200 Stufenpunkte.
+     * Man muss eine Reihe von wuerdigen Gegnern erlegt haben, so 
+       dass man aus diesen "Erstkills" 150 Stufenpunkte erzielt.
+
+    Die verbleibenden Stufenpunkte koennen auf jede beliebiege
+    Art gesammelt werden (so auch die Stufenpunkte, die fuer die 
+    Gildenfaehigkeiten, fuer MiniQuests etc. vergeben werden). 
+
+    ** WICHTIGER HINWEIS: 
+    ** Die Seheranforderungen werden jaehrlich von den Erzmagiern
+    ** evaluiert und ggf. nach oben oder unten angepasst. Der Termin
+    ** fuer solche etwaig willkuerliche Anpassungen ist jedes Jahr
+    ** der 15. September. 
+
+    Wenn man alle Anforderungen erfuellt hat, kann man sich von
+    Merlin befoerdern lassen. 
+
+    Ist man einmal Seher, und bekommt ploetzlich doch Lust, sich als Magier zu
+    betaetigen, so kann man ohne weiteres Magier werden (wenn man einen
+    Sponsor findet).
+
+SIEHE AUCH:
+    allg. Hilfe: merlin, stufen, stufenpunkte, abenteuer, forscherpunkte, 
+                 magier
+    Seherhilfe: hausbau, extralook, fehlermeldung, fluchtrichtung, presay, 
+                review, sethands, setmin, setmout, setmmin, setmmout, titel
+                (nur ab Seherstatus lesbar)
+
+LETZTE AeNDERUNG: 2016-06-05 von Arathorn
diff --git a/doc/help/sehertore b/doc/help/sehertore
new file mode 100644
index 0000000..586e505
--- /dev/null
+++ b/doc/help/sehertore
@@ -0,0 +1,30 @@
+Sehertore
+=========
+
+    Sehertore sind ueber das gesamte MorgenGrauen verteilt und nur fuer
+    Seher zu erkennen und zu nutzen.
+
+    Mithilfe dieser Portale ist es moeglich, grosse Distanzen im MG
+    durch einen Teleport von einem Tor zu einem anderen zurueckzulegen.
+    Liegt das Ziel auf einer anderen Insel als das Starttor, sind zum
+    Teleportieren Magiepunkte notwendig.
+
+    Die frueher moegliche "Fehlteleportation" ist inzwischen zum 
+    Glueck der Seher abgeschafft worden. Wobei in der Parallelwelt auch
+    diesbezueglich manchmal andere Regeln gelten.
+
+    Bevor jedoch Sehertore benutzt werden koennen, muessen sie entdeckt
+    werden. Dies geschieht oftmals durch blosses Betreten eines Raumes,
+    in dem ein Sehertor aufgestellt ist; es ist jedoch auch denkbar, 
+    dass naehere Untersuchungen oder gar Aktionen notwendig werden, be-
+    vor sich ein Sehertor zu erkennen gibt.
+
+    Einmal gefundene Sehertore bleiben bekannt.
+
+    Seit einiger Zeit erlaubt die Fraternitas Domo Archmagorum auch
+    Spielern das Erlernen von Portalen. Dies ist jedoch eingeschraenkt.
+    Dazu sollte man sich in der Fraternitas einfach einmal ein wenig 
+    umschauen.
+
+ LETZTE AeNDERUNG:
+	2013-01-27 von Humni
diff --git a/doc/help/sheriff b/doc/help/sheriff
new file mode 100644
index 0000000..dd6c16e
--- /dev/null
+++ b/doc/help/sheriff
@@ -0,0 +1,18 @@
+Der Sheriff uebernimmt die Auslegung der Regeln und Ahndung von Regel-
+verstoessen. Er stellt insofern also eine Art Schiedsrichter da. 
+
+Derzeit ist Amaryllis dafuer zustaendig.
+
+Es steht den Sheriffs frei, weitere Deputys zu ernennen die sie bei
+der Arbeit unterstuetzen, in jedem Fall ist ihren Anweisungen und
+denen ihrer Deputys Folge zu leisten.
+
+Meldet Euch bei Fragen oder Problemen bitte direkt bei ihnen oder
+schickt ihnen eine Mail, hilfreich ist hier auch das Mailalias
+"polizei".
+
+SIEHE AUCH:
+   leitfaden
+
+LETZTE AeNDERUNG:
+   04.02.2008 von Zesstra.
diff --git a/doc/help/sozialmedien b/doc/help/sozialmedien
new file mode 100644
index 0000000..5986947
--- /dev/null
+++ b/doc/help/sozialmedien
@@ -0,0 +1,14 @@
+Diverse MG-Gruppen ausserhalb des MUDs
+======================================
+
+Morgengrauen besitzt momentan:
+
+ * einen Twitter-Account: https://twitter.com/morgengrauen
+ * eine Facebook-Gruppe: https://www.facebook.com/groups/120370845579
+ * eine G+-Community:
+   https://plus.google.com/communities/101092454975782252702
+
+SIEHE AUCH:
+    teamspeak
+
+1. Jun 2016, Gloinson
diff --git a/doc/help/spiele b/doc/help/spiele
new file mode 100644
index 0000000..1cd6d3e
--- /dev/null
+++ b/doc/help/spiele
@@ -0,0 +1,34 @@
+
+Spiele
+======
+
+     Als waere das Morgengrauen nicht Spiel genug, haben sich doch einige
+     magisch wankende Gestalten daran gemacht noch ganz andere Spiele zu
+     basteln, bei denen man sich vom Metzel- und Questalltag erholen kann.
+
+     Wen es also reizt, der kann folgende Spiele zusammen mit anderen
+     Spielern suchen und versuchen:
+
+     17&4		Wald, Elfendorf, Casino
+     4 Gewinnt		Ebene, Port Vain
+     Abalone		Ebene, Port Vain, Owen Braddon
+     Dart		Vland, Orkhausen, Kneipe
+     Doppelkopf		Inseln, Shaky Island
+     Fussball		Ebene, Feuerbergstadion
+     Go			Fernwest, Xian
+     Maexchen		Ebene, Port Vain, Abenteurerkneipe/Owen Braddon
+     Minesweeper	Dschungel, Ohort, Hinterzimmer
+     Rage		Wald, Drakonien, Huette
+     Rodeln		Polar, Tundra
+     Schach		Gebirge, Hochebene
+     Skat		Gebirge, Lupinental, Kneipe
+     Tablut		Gebirge, Bergdorf, Kneipe
+     Take It Easy	Dschungel, Steppe, Huette
+     Monopoly           Feuerinsel, Vulkan d. Parawelt (GladioPolis)
+
+ SIEHE AUCH:
+     parties, sterben
+
+ LETZTE AeNDERUNG:
+     22. Maerz Gloinson
+
diff --git a/doc/help/spielertesties b/doc/help/spielertesties
new file mode 100644
index 0000000..d0204bf
--- /dev/null
+++ b/doc/help/spielertesties
@@ -0,0 +1,85 @@
+Spielertesties
+==============
+
+Nach Absprache mit einem Erzmagier ist es erlaubt, dass ein Spieler
+unangeschlossene Gebiete, Quests oder auch Gilden testet. 
+
+Fuer das Testen von Gebieten und Questen gibt es zwei Moeglichkeiten:
+  
+Der Magier leitet den Test hauptverantwortlich:
+Diese Regelung ist vor allem fuer das Testen kleinerer Quests und Gebiete gedacht.
+Hier gelten folgende Regeln:
+ Der Spieler, der den Test durchfuehrt, bekommt einen Testspieler des Magiers 
+ sowie eine angemessene Ausruestung. Bei der Auswahl eines Testspielers
+ ist es auch moeglich Testspieler anderer Magier mit deren Einverstaendnis
+ zu verwenden.
+ Der leitende Magier informiert einen Erzmagier ueber den Testspieler.
+ Der Testspieler darf waehrend der Testzeit das Testgebiet nicht verlassen und 
+ auch keine Objekte des zu testenden Gebietes an andere weiterreichen. 
+ Der Testspieler wird waehrend der ganzen Testzeit vom Magier ueberwacht. 
+ Dies geschieht sowohl zur Ueberwachung dieser Regeln, als auch,  um dem 
+ programmierenden Magier weitere Ideen zur Verfuegung zu stellen.
+ Dieser Test kann nach der Fertigstellng und Tests des Gebietes durch den 
+ verantwortlichen Magier stattfinden.
+ 
+Ein Erzmagier leitet den Test hauptverantwortlich:
+Diese Regelung ist vor allem fuer das Testen groesserer Quests und Gebiete 
+gedacht.
+Hier gelten folgende Regeln:
+ Der Spieler, der den Test durchfuehrt, bekommt durch den Erzmagier einen 
+ Testspieler sowie eine angemessene Ausruestung gestellt. Bei der Auswahl 
+ eines Testspielers ist es auch moeglich Testspieler anderer Magier mit 
+ deren Einverstaendnis zu verwenden. Dieser Testspieler darf waehrend der 
+ Testzeit das Testgebiet nicht verlassen und auch keine Objekte des zu 
+ testenden Gebietes an andere weiterreichen. 
+ Der Testspieler wird waehrend der ganzen Testzeit vom Magier und Erzmagier 
+ ueberwacht. Dies geschieht sowohl zur Ueberwachung dieser Regeln, als auch,  
+ um dem programmierenden Magier weitere Ideen zur Verfuegung zu stellen.
+ Der Erstcharakter des Spielers (auf Wunsch auch ein Zweitie) erhaelt nach
+ Abschluss des Tests die gefundenen Forscherpunkte und Erstkillstupse 
+ gutgeschrieben, aber auch die erlittenen Schaeden (insbesondere Tode) - 
+ selbstverstaendlich, soweit sie nicht durch Programmier-fehler bedingt waren.
+Dieser Test findet NACH dem Test des Gebietes durch den zustaendigen 
+Regionsmagier und (bei Questen) durch den Quest-Erzmagier, sowie NACH 
+Eintrag der Forscherpunkte statt.
+
+Beide Testvarianten ersetzen auf keinen Fall die Tests durch Magier.  
+
+Fuer das Testen von Gilden gelten andere Regeln, da sich diese zusammen mit
+anderen Spielern in gleichen Gebieten aufhalten koennen:
+
+1) Gildentesties sind immer echte, zu diesem Zweck erschaffene Testspieler.
+   P_TESTPLAYER wird dabei auf den Namen der Gilde gesetzt.
+
+2) Jeder einem Spieler zur Verfuegung gestellte Gildentestie muss 
+   mittels P_SECOND mit dem Namen des Erstspielers markiert sein, der
+   ihn fuehrt. Jeder Testspieler sollte eindeutig zuzuordnen sein.
+  
+3) Die Testies unterliegen ALLEN Regeln des Testie-Daseins. Das heisst
+   unter anderem, dass sie NICHT fuer andere Spieler Ausruestung beschaffen
+   oder Wege freimetzeln duerfen! Verstoesse hiergegen koennen unter
+   Umstaenden zur Loeschung der beguenstigten Spielercharaktere und
+   des Testcharakters fuehren.
+
+4) Die Testies werden staendig ueberwacht. Logfiles koennen unter Umstaenden
+   von den Gildenmagiern eingesehen werden.
+
+5) Jeder Testie muss vom EM Gilden (z.Z. Humni) genehmigt werden!
+
+6) 5 Testies pro Gilde sollten genuegen. Wenn ein Teil der Testies nichts
+   tut, kann man den Testie auch weitergeben lassen.
+
+SIEHE AUCH:
+        Erzmagier, Gildenmagier, Regionsmagier, Tod
+
+----------------------------------------------------------------------------
+Last modified: Fri Oct 18 16:24:00 2002 by Muadib
+
+
+Fuer Magier.
+Magier koennen natuerlich ohne Absprache Testspieler einer bestimmten Gilde
+haben, sofern diese normalen Spielern zugaenglich ist. Sofern eine Gilde das
+Anlegen von Testspielern unterstuetzt, gibt es entsprechende Hilfeseiten unter
+<gildenname>.testspieler - zum Beispiel katzenkrieger.testspieler
+
+Zusatz: Tue Jan  7 23:22:44 2003, durch Bambi.
\ No newline at end of file
diff --git a/doc/help/sterben b/doc/help/sterben
new file mode 100644
index 0000000..08ab270
--- /dev/null
+++ b/doc/help/sterben
@@ -0,0 +1,37 @@
+ Sterben ist in diesem Mud recht leicht.
+ Einige recht sichere Moeglichkeiten sind:
+ - In die Steinbeisserhoehle, s,s,o,n,n,
+ - In den Schacht der F&E (Archie), 15 mal "unten" tippen
+ - Bei den Raeubern "vorsicht 0", "toete alle"
+ - In Yantros Haus der Farben im schwarzen Raum: beschwoere Tod
+ - In der Daemonenkneipe (Zardoz' Burg): kaufe liqour manor
+ - Pandora: Beim Skispringen die Skier ausziehen
+ - Bei der Hydra solange Koepfe abschlagen und NICHT ausbrennen,
+   bis ca. 50 Stueck da sind, DANN den Koerper angreifen.
+ - Auf Tamibar: toete haiavaha (Noch sicherer: Man sage Bowan's
+   Spruch aus "Traumpark" auf...)
+ - In Orkhausens Katakomben: nur ein wenig kaempfen und idlen
+ - Im Tal der Lupinen am zerstoerten Schrein: bete
+ - Als Seher: "fluchtrichtung egalwohin", "toete weghier"
+ - In Fekesh's Laden "kaufe tamahorny", 3x "schlage tamahorny"
+ - In der Sauna "nimm handtuch", "toete masseur"
+ - Als Elf: Dunkelelfen toeten, "nimm runenschwert", "zuecke runenschwert"
+ - Als Zauberer: In der Archie-Kneipe einen Grog und eine Cola 40 trinken,
+   anschliessend "verletze architekt"
+ - Als Karateka: Steintroll angreifen
+
+ Generelle Tipps:
+ - "vorsicht 0" ist bei vereinzelten Gegnern angebracht; wenn aggressive
+   Monster in den Nebenraeumen stehen, ist hohe vorsicht sinnvoller.
+ - "toete alle" bei vielen starken Gegnern fuehrt recht sicher zum Tod
+ - ohne Ruestung stirbt man leichter
+ - Als Seher: "fluchtrichtung -B Ich will sterben!"
+ - Key fragen, der kann brauchbare Tips geben
+ - Monster von Rochus oder Patryn angreifen 
+
+ SIEHE AUCH:
+    toete, vorsicht, fluchtrichtung, kampf
+
+ LETZTE AeNDERUNG:
+    12.12.2011, Zesstra
+
diff --git a/doc/help/stufen b/doc/help/stufen
new file mode 100644
index 0000000..1c4732d
--- /dev/null
+++ b/doc/help/stufen
@@ -0,0 +1,53 @@
+
+stufen
+======
+
+    Seine (Spieler-)Stufe kann man in jeder Gilde erhoehen. Die einzige
+    Voraussetzung dabei ist es, genuegend Stufenpunkte zu haben.
+
+    Ab Stufe 9 gilt:
+    Um auf Stufe <x> aufsteigen zu koennen, benoetigt man <x-4>*100 dieser
+    Stufenpunkte.
+    Bis Stufe 9 kosten die Stufen weniger als 100 Stufenpunkte (s. Tabelle).
+
+    Die einzige Ausnahme ist der Aufstieg vom Spieler zum Seher oder Magier:
+     Um Seher zu werden gibt es zusaetzliche Bedingungen, wie bestimmte
+     Anzahlen von Abenteuerpunkten, Forscherpunkten und Erstkills. Die
+     aktuelle Liste ist unter der Hilfeseite "seher" zu finden.
+     Magier kann man nach Erreichen des Seherstands auf Anfrage bei einem
+     hoeheren Magier werden.
+
+    Bis zur Stufe 19 sehen die Stufenbezeichnungen fuer Abenteurer wie folgt
+    aus:
+
+      Stufe  St.pkte        Maennlich               Weiblich          
+       19     1500      der angehende Seher     die angehende Seherin     
+       18     1400      der Held                die Heldin                
+       17     1300      der Eroberer            die Erobererin            
+       16     1200      der Entdecker           die Entdeckerin           
+       15     1100      der Feuerbaendiger      die Feuerbaendigerin      
+       14     1000      der Schatzsucher        die Schatzsucherin        
+       13      900      der Draufgaenger        die Draufgaengerin        
+       12      800      der Weltenbummler       die Weltenbummlerin       
+       11      700      der Abenteurer          die Abenteurerin          
+       10      600      der Reisende            die Reisende              
+        9      500      der Kundschafter        die Kundschafterin        
+        8      420      der Jaeger              die Jaegerin              
+        7      340      der Wegekundige         die Wegekundige           
+        6      280      der Faehrtensucher      die Faehrtensucherin      
+        5      220      der Waldlaeufer         die Waldlaeuferin         
+        4      180      der Wandergeselle       die Wandergesellin        
+        3      140      der Streuner            die Streunerin            
+        2      120      der Landstreicher       die Landstreicherin       
+        1      100      der hoffnungsvolle      die hoffnungsvolle        
+
+    Seherstufen tragen keinen Titel, da jeder Seher seinen Titel selbst frei
+    waehlen darf.
+
+ SIEHE AUCH:
+    seher, magier, magierstufen
+    forscherpunkte, stufenpunkte
+    abenteuer
+
+ LETZTE AeNDERUNG:
+    04.05.2013, Zesstra
diff --git a/doc/help/stufenpunkte b/doc/help/stufenpunkte
new file mode 100644
index 0000000..b16f470
--- /dev/null
+++ b/doc/help/stufenpunkte
@@ -0,0 +1,56 @@
+
+Stufenpunkte
+============
+
+    Die Stufenpunkte bilden die Grundlage des neuen Stufenkonzeptes im
+    MorgenGrauen. Anstatt wie frueher nur durch Erfahrungspunkte und in
+    gewissem Masse Abenteuerpunkte wird die Moeglichkeit zum Aufstieg nun auch
+    noch von einigen anderen Faktoren bestimmt, die insgesamt eine
+    ausgewogenere Einschaetzung des Charakters ermoeglichen sollen:
+
+    Den wichtigsten Anteil bilden nun die Abenteuerpunkte. Sie gehen im
+    Verhaeltnis 1:1 in die Stufenpunkte ein.
+
+    Der zweitgroesste Anteil wird von den Forscherpunkten gestellt. Diese
+    Punkte werden einem zwar nicht direkt als Zahl bekannt gegeben; mit dem
+    Befehl `info' (auch als `score' oder `punkte' bekannt) kann man jedoch
+    eine Einschaetzung der Mud-Kenntnis abfragen.
+
+    Den naechsten Anteil liefern gefundene Zaubertraenke und ein weiteres
+    Level die Heiltraenke (die letzten vier ZTs).
+
+    Die Gilde, in der man sich befindet, liefert einen vierten Anteil. Hier
+    gehen in der Regel die Kenntnisse der einzelnen Sprueche und der
+    Faehigkeiten ein, die man in der Gilde erlernen kann (das ist aber jeder
+    Gilde selbst ueberlassen). Gilden, aus denen man ausgetreten ist, werden
+    dabei nicht beruecksichtigt! Manche Gilden vergeben sehr viele Stufen-
+    punkte schon bis Level 20. Dann verliert man beim Wechsel einige Stufen,
+    die man in der neuen Gilde aber mit der Zeit wieder erlangt.
+
+    Schliesslich gibt es noch Stufenpunkte fuer das Toeten von Monstern;
+    allerdings muss das Monster dafuer eine bestimmte minimale Menge von
+    Erfahrungspunkten geben. Diese Punkte werden nur fuer das erstmalige
+    Toeten des Monsters vergeben. Es nuetzt also nichts, den selben Ork 27 mal
+    zu toeten; wenn er ueberhaupt Stufenpunkte abwirft, dann nur beim ersten
+    Mal.
+
+    (Ein erweiterter Hinweis zum Thema Erstkill-Stufenpunkte, insbesondere
+     in Zusammenhang mit Kerbholz und  Duesterwald-Plakette, ist in der
+     Hilfeseite "erstkillstufenpunkte" (oder "eks") zu finden.)
+
+    Auch "MiniQuests" koennen Stufenpunkte vergeben. (Miniquests sind kleine
+    Aufgaben, die keine Abenteuerpunkte geben).
+
+    Und zum guten Schluss kommen auch die Erfahrungspunkte noch zu Ehren, wenn
+    auch nicht zu besonders grossen... ;-)
+    Fuer x Erfahrungspunkte erhaelt man x^0.32 Stufenpunkte, so dass im
+    unteren Erfahrungspunktebereich recht schnell Stufenpunkte erzielt
+    werden, nach oben hin jedoch immer weniger Stufenpunkte pro erzieltem
+    Erfahrungspunkt vergeben werden.
+
+ SIEHE AUCH:
+    forscherpunkte, info, stufen, erstkillstufenpunkte, erzmagier
+
+ LETZTE AeNDERUNG:
+    Wed, 09.05.01, 15:00:00 von Rikus
+ 
diff --git a/doc/help/stunnel b/doc/help/stunnel
new file mode 100644
index 0000000..88b46de
--- /dev/null
+++ b/doc/help/stunnel
@@ -0,0 +1,73 @@
+Verschluesselung der MUD-Kommunikation mit stunnel
+==================================================
+
+    Mit 'stunnel' kann man seine saemtliche Kommunikation mit dem MUD
+    verschluesseln. Dazu startet man lokal bei sich stunnel und verbindet
+    sich dann per telnet/tf/... mit diesem Client.
+    In den folgenden Beispielen wird dafuer jeweils localhost:4711 benutzt.
+
+    Stunnel gibt es fuer diverse OS unter: http://www.stunnel.org/
+    
+    Start von stunnel unter Linux uAe:
+    * bis zur Version 3.* mit dem Kommando
+      stunnel -c -d 4711 -r mg.mud.de:4712
+    * ab Version 4.* mit Konfigurationsdatei folgenden Inhalts, gefolgt
+      von Start via "stunnel <konfigurationsdatei>"
+    --
+      foreground = yes
+      client = yes
+
+      [mg]
+      connect = mg.mud.de:4712
+      accept = localhost:4711
+    --
+
+    Start von stunnel unter Windows:
+    * Installieren/Starten, dann unter Configuration die Datei stunnel.conf
+      editieren und bei 'Service definitions' folgende Zeilen hinzufuegen:
+    --
+      client = yes
+      [mg]
+      connect = mg.mud.de:4712
+      accept = 127.0.0.1:4711
+    --
+
+ BEMERKUNGEN:
+    Der Server unterstuetzt Kompression, zB durch die Konfigurationszeile:
+      compression = zlib
+    ausserhalb des Profils.
+    
+    Auszugsweise momentan moegliche Chiffren sind, nach Staerke aufsteigend:
+      DES-CBC-SHA           SSLv3 Kx=RSA    Au=RSA  Enc=DES(56)   Mac=SHA1
+      RC4-SHA               SSLv3 Kx=RSA    Au=RSA  Enc=RC4(128)  Mac=SHA1
+      RC4-MD5               SSLv3 Kx=RSA    Au=RSA  Enc=RC4(128)  Mac=MD5 
+      CAMELLIA128-SHA       SSLv3 Kx=RSA    Au=RSA  Enc=Camellia(128) Mac=SHA1
+      DHE-RSA-AES128-SHA    SSLv3 Kx=DH     Au=RSA  Enc=AES(128)  Mac=SHA1
+      DES-CBC3-SHA          SSLv3 Kx=RSA    Au=RSA  Enc=3DES(168) Mac=SHA1
+      EDH-RSA-DES-CBC3-SHA  SSLv3 Kx=DH     Au=RSA  Enc=3DES(168) Mac=SHA1
+
+      AES128-SHA            SSLv3 Kx=RSA    Au=RSA  Enc=AES(128)  Mac=SHA1
+      AES128-SHA256         TLSv1.2 Kx=RSA  Au=RSA  Enc=AES(128)  Mac=SHA256
+      AES128-GCM-SHA256     TLSv1.2 Kx=RSA  Au=RSA  Enc=AESGCM(128) Mac=AEAD
+      AES256-SHA            SSLv3 Kx=RSA    Au=RSA  Enc=AES(256)  Mac=SHA1
+      AES256-SHA256         TLSv1.2 Kx=RSA  Au=RSA  Enc=AES(256)  Mac=SHA256
+      AES256-GCM-SHA384     TLSv1.2 Kx=RSA  Au=RSA  Enc=AESGCM(256) Mac=AEAD
+
+      DHE-RSA-CAMELLIA256-SHA SSLv3 Kx=DH   Au=RSA  Enc=Camellia(256) Mac=SHA1
+      DHE-RSA-AES256-SHA    SSLv3 Kx=DH     Au=RSA  Enc=AES(256)  Mac=SHA1
+      DHE-RSA-AES256-SHA256 TLSv1.2 Kx=DH   Au=RSA  Enc=AES(256)  Mac=SHA256
+      DHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=DH Au=RSA  Enc=AESGCM(256) Mac=AEAD
+    
+    Einstellbar ist das bei speziellen Wuenschen (Vorschriften
+    zur Verschluesselungsstaerke im Ausland zB) mit:
+      ciphers = RC4-SHA
+    innerhalb des Profils. Fuer einige muss allerdings
+      fips = no
+    gesetzt werden, da sie als nicht mehr sicher genug gelten.
+ 
+ SIEHE AUCH:
+    teamspeak, mudrechner
+    Details zu Zertifikaten: http://mg.mud.de/download/stunnel.shtml
+
+ LETZTE AeNDERUNG:
+3. Aug 2015 Gloinson
diff --git a/doc/help/syntax b/doc/help/syntax
new file mode 100644
index 0000000..2315c37
--- /dev/null
+++ b/doc/help/syntax
@@ -0,0 +1,60 @@
+
+Die Syntax der Eingaben im MorgenGrauen
+=======================================
+
+    Eine Eingabe sollte im allgemeinen folgendermassen aussehen:
+
+    > <verb> [<objekt(e)>] [<adverb> [und <adverb>]]
+
+    Gross- und Kleinschreibung sowie Artikel koennen in den meisten Faellen
+    benutzt werden. Das Verb MUSS allerdings IMMER klein geschrieben werden!
+    Folgende Ausdruecke sollten also aequivalent sein:
+
+    > steck das Schwert in den Beutel
+    > steck schwert in beutel
+
+    Umlaute und andere Sonderzeichen (Zeichen mit ASCII-Codes >= 127) sind
+    verboten und werden durch `?' ersetzt.
+
+    Wenn nicht genau klar ist, welches Objekt gemeint ist, kann man das
+    gewuenschte Objekt mit einer angehaengten Nummer identifizieren:
+
+    > steck schwert 2 in beutel
+    > steck das 2. Schwert in den Beutel
+
+    Folgendes geht allerdings nicht:
+
+    > steck das zweite Schwert in den Beutel
+
+    Solltest Du irgendwo im Spiel auf eine Stelle stossen, wo keine
+    grammatikalisch richtige Eingabe erwartet wird, gib bitte einem Magier
+    Bescheid.
+
+    Wenn Du bei der Verwendung eines Adverbs in Zusammenhang mit einem Verb
+    Probleme hast, so vergewissere Dich, ob das Verb ueberhaupt die Verwendung
+    von Adverbien unterstuetzt.
+
+    Bei Verben, die die Verwendung von Adverbien unterstuetzen, kannst Du auch
+    einen Text nach Wahl benutzen und zwar folgendermassen:
+
+    > <verb> /<text_nach_wahl>
+
+    Viel Spass beim Ausprobieren.
+
+ BEISPIELE:
+
+    > nimm buch
+    > stecke buch in tasche
+    > ziehe schild an
+    > nimm schwert aus leichnam 2
+
+    > grinse
+    > grinse jamm und jofi (jamm und jofi muessen natuerlich
+                            in der "adverb"-Liste stehen.)
+    > grinse /was-neues-was-auch-nicht-in-der-"adverb"-Liste-steht
+
+ SIEHE AUCH:
+    verben, adverb, idee
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/help/tanjian b/doc/help/tanjian
new file mode 100644
index 0000000..3642bd0
--- /dev/null
+++ b/doc/help/tanjian
@@ -0,0 +1,33 @@
+
+Die Gilde der Tanjian
+---------------------
+
+          #          Die Gilde der Tanjian befindet sich im Wald der 
+          ###        Eistannen, suedoestlich eines dunklen Waldes, der
+          ##         angeblich boese Drakonier beherbergt. 
+          #    ##     
+   ################  Die Tanjian betrachten sich als Wahrer der Neutralitaet,
+    ##   ##     ##   daher wenden sie sich sowohl gegen heilige als auch
+         #      ##   gegen satanische Lebewesen.
+        ##     ##     
+       ##      ##    Der Tanjian lernt den Umgang mit verschiedensten Fern-
+      ##       ##    und Nahkampfwaffen, gleichzeitig strebt er danach, die
+    ##     #  ##     Kraefte des Universums in Form von maechtigen Spruechen
+  ###       ####     fuer sich zu nutzen.
+ #           #         
+                     Naeheres zu der Gilde erzaehlt einem gerne der
+ Lehrmeister der Gilde, Siamil, oder der Schulleiter Orthosius. 
+ 
+ Um sich der Tanjiangilde anzuschliessen sollte Deine Stufe mindestens der
+ 5. entsprechen, all Deine Attribute 5 oder mehr betragen, Dein Charakter
+ weder satanisch noch heilig sein und Du sollst ein Alter von wenigstens 
+ einem Tag aufweisen. Zusaetzlich benoetigst Du 50 Abenteuerpunkte.
+
+ Wer einmal Mitglied der Chaos- oder Klerikergilde war, kann der Tanjiangilde
+ nicht mehr beitreten!
+                         
+ SIEHE AUCH:
+    gilden
+
+ LETZTE AeNDERUNG:
+    Mon, 17. Mai 2004, 17:10:00 von Nibel
diff --git a/doc/help/teamkampf b/doc/help/teamkampf
new file mode 100644
index 0000000..1af65c3
--- /dev/null
+++ b/doc/help/teamkampf
@@ -0,0 +1,155 @@
+Teamkampf
+=========
+
+Gruenden eines Teams und Aufnahme neuer Mitglieder
+--------------------------------------------------
+team folge            Ein Spieler kann mit <team folge name> beantragen,
+                      dass <name> ihn in sein Team aufnimmt.
+
+team aufnahme         Wenn ein Spieler die Aufnahme ins Team beantragt hat,
+                      kann der Teamleiter ihn mit <team aufnahme name>
+                      aufnehmen. Wenn man noch nicht in einem Team ist,
+                      so wird hiermit eins gegruendet.
+                      Von der Aufnahme ausgeschlossen sind Gaeste und
+                      Geister sowie Zweitspieler von Teammitgliedern.
+
+team verlasse         Mit diesem Befehl verlaesst man das Team.
+
+Organisation innerhalb des Teams
+--------------------------------
+team leiter           Der Teamleiter seine Aufgabe an ein anderes Mitglied
+                      abgeben. Schlaeft der Teamleiter ein oder ist laenger
+                      als 10 Minuten inaktiv, koennen auch die anderen
+                      Mitglieder einen neuen Teamleiter ernennen.
+
+team entlasse         Der Teamleiter kann auch Mitglieder entlassen.
+
+Angriffskoordination
+--------------------
+team angriffsbefehl   Ein Teammitglied kann einen Befehl angeben, der
+                      ausgeloest wird, sobald der Teamleiter das Signal
+                      zum Angriff gibt.
+                      Beispiel: <team angriffsbefehl norden> - wenn der
+                      Teamleiter das Signal gibt geht man nach Norden
+                      zum Monster.
+
+team angriff          Der Teamleiter loest den Angriffsbefehl bei allen
+                      Teammitgliedern aus, die im gleichen Raum stehen
+                      und einen Angriffsbefehl eingestellt haben.
+
+Organisation des Teamkampfes
+----------------------------
+                      Teammitglieder haben die Moeglichkeit, ihre Position
+                      innerhalb der Kampfaufstellung zu bestimmen. So koennen
+                      die Kaempfer vorne kaempfen und den Kleriker decken
+                      der sie staendig heilt :-)
+
+team kampfreihe       Jedes Teammitglied kann seinen Positionswunsch mit
+                      <team kampfreihe nr> angeben, wobei <nr> im Bereich
+                      von 1 bis 5 sein muss. Dabei wird jedoch immer die vom
+                      Teamleiter gewuenschte Formation eingehalten.
+                      Durch die Teammitglieder in den vorderen Reihen
+                      werden die in den hinteren Reihen geschuetzt.
+                      Beispielsweise reichen drei Mitglieder in Reihe 1 aus,
+                      zwei in Reihe 2 und eines in Reihe 3 zu schuetzen.
+                      Der Anteil der Schlaege die ein Mitglied abbekommt
+                      entspricht der Anzahl der ungeschuetzen Mitglieder
+                      seiner Reihe (in der ersten Reihe plus 1).
+                      Nur die erste Reihe kann selber im Nahkampf zuschlagen.
+
+team fluchtreihe      Ein Teammitglied kann eine Reihe angeben, in die er
+                      bei der Flucht wechseln moechte statt abzuhauen.
+                      So kann man sich - ausreichende Deckung vorausgesetzt -
+                      in Ruhe von dem mitgebrachten Kleriker heilen lassen.
+                      Wird die Flucht ausgeloest, so wird die Fluchtreihe zur
+                      gewuenschten Kampfreihe. Mit
+                      <team fluchtreihe 0> wird die Fluchreihe deaktiviert.
+                      Falls die Flucht in eine hintere Reihe nicht gelingt,
+                      wird die normale Flucht ausgeloest.
+
+team formation        Der Teamleiter kann bestimmen, innerhalb welcher
+                      Grenzen die Formation eingehalten werden soll.
+                      Dies geschieht mit <team formation min1-max1
+                      min2-max2 min3-max3 min4-max4 min5-max5>. Die
+                      Beschraenkungen fuer nicht angegebene Reihen
+                      werden nicht geaendert. Wenn statt Minimum und
+                      Maximum nur eine Zahl angegeben wird, gilt diese
+                      fuer beide Werte. Die Grenzen werden automatisch so
+                      angepasst, dass sie erfuellbar sind, maxmial 6
+                      Mitglieder in jeder Reihe stehen und mindestens eines
+                      in Reihe 1.
+                      Beispiel: "team formation 3-4 2 1"
+
+team uebersicht       Zeigt die eigenen und gegnerischen Reihen an.
+
+Weitere nuetzliche Teambefehle
+------------------------------
+team autofolge        Teammitglieder, die mit <team autofolge ein> den
+                      Folgemodus aktiviert haben, fuehren automatisch
+                      jeden Befehl des Teamleiters (nach kurzer Verzoegerung)
+                      aus, der einen Ortswechsel bewirkt, vorausgesetzt sie
+                      stehen dort wo der Leiter direkt vor seinem Ortswechsel
+                      war.
+                      Der Teamleiter muss den Folgemodus auch aktiviert haben,
+                      damit die anderen ihm folgen.
+                      Wenn der Teamleiter versucht zu fliehen, wird der
+                      Folgemodus fuer ihn deaktiviert.
+
+team info             Gibt Informationen ueber die Teammitglieder.
+                      Dabei steht in den Spalten:
+                      *      - Kennzeichnung des Teamleiters
+                      Name   - der Name
+                      Gilde  - die Gilde
+                      LV     - Stufe
+                      GLV    - Gildenstufe
+                      LP/MLP - Lebenspunkte
+                      KP/MKP - Konzentrations/Magiepunkte
+                      Vors.  - Vorsicht
+                      GR     - Gewuenschte Reihe
+                      AR     - Aktuelle Reihe (bezogen aufs ganze Team)
+                      TR     - Tatsaechliche Reihe (bezogen auf Anwesende)
+                      FR     - Fluchtreihe
+                      A      - Angriffsbefehl eingestellt
+                      V      - Verfolgemodus aktiviert
+                      Der Teamleiter kann durch die Angabe "lang" eine
+                      zweizeilige Ausgabe bekommen, bei der auch
+                      Angriffsbefehl und Fluchtrichtung gezeigt werden.
+                      Wenn man "sortiert" angibt, wird die Ausgabe nach
+                      (TR,AR,GR,Name) sortiert, bei "alphabetisch" erfolgt
+                      die Sortierung nach dem Namen, wobei Spieler jedoch
+                      vor anderen Teammitgliedern eingeordnet werden.
+                      Ansonsten wird nach AR geordnet.
+
+team farben           Damit laesst sich aendern, ab wann die eigenen
+                      Lebenspunkte bzw. Konzentrationspunkte gelb oder
+                      gar rot (bzw. fett) angezeigt werden.
+
+team orte             Zeigt an, wo sich die Teammitglieder befinden.
+                      Normalerweise werden nur Spieler angezeigt, mit
+                      "alle" jedoch auch andere Teammitglieder.
+
+team rufe             Mitteilung an alle Teammitglieder.
+
+team hist             History der Teammitteilungen. Die Anzahl der
+                      anzuzeigenden Zeilen (bis 100) kann angegeben werden.
+
+team name             Man kann seinem Team auch einen Namen geben.
+
+team hilfe            Gibt eine kurze Befehlsuebersicht.
+
+team liste            Zeigt an, welche Teams es schon gibt.
+
+Punkteverteilung
+----------------
+Die Erfahrungspunkte fuers Toeten eines Monsters werden zur Haelfte
+unter den anwesenden Teammitgliedern und zur Haelfte anteilmaessig
+verteilt. Dies gilt nur fuer das Team des Killers, fuer alle anderen
+ist die Verteilung wie bisher anteilmaessig.
+
+Die Erstkillpunkte werden an ein Teammitglied vergeben, das diese noch
+nicht hat. Dabei werden Teammitglieder in der ersten Reihe bevorzugt.
+
+Abk.
+----
+Statt "team" sind auch "gruppe" und die Abkuerzung "g" moeglich.
+
diff --git a/doc/help/teamspeak b/doc/help/teamspeak
new file mode 100644
index 0000000..dfd1433
--- /dev/null
+++ b/doc/help/teamspeak
@@ -0,0 +1,64 @@
+
+Das Morgengrauen-Teamspeak
+==========================
+
+Teamspeak - was ist das ueberhaupt?
+
+    Teamspeak ist ein Voice-Chat-System, zu dem man sich mit einem geeigneten
+    Client verbinden kann, um sich mit anderen Leuten zu unterhalten. Das
+    Ganze funktioniert im Grunde aehnlich wie Skype, hat aber gegenueber
+    diesem den Vorteil, dass die Kommunikation ueber Server laeuft, die
+    nicht unter der Kontrolle von Fremdfirmen stehen, so dass auch nichts
+    mitgeloggt wird, was dort gesprochen wird.
+
+
+Wofuer braucht man das?
+    
+    Im Teamspeak kann man sich treffen, um gemeinsam Mehrspielerquests zu
+    loesen, groessere Metzelaktionen zu koordinieren oder einfach nur
+    zu quatschen.
+
+    Fuer Magier gibt es separate Channel, in denen man sich zur Diskussion
+    von Programmierthemen und -problemen treffen kann.
+
+
+Bin ich schon drin?
+
+    Wenn Du Lust bekommen hast, unser TS mal auszuprobieren, benoetigst Du
+    folgendes:
+
+    - eine Soundkarte im PC
+    - Lautsprecher und ein Mikrofon, besser jedoch ein Headset
+    - den Teamspeak3-Client von http://www.teamspeak.com
+    - die Zugangsdaten:
+
+      Servername:     mgts.mud.de (sollte ohne Portangabe funktionieren)
+      Serverpasswort: der Name unseres bekannten Urvaters aller Magier
+      Server-IP (falls benoetigt): 85.214.250.188:4711
+
+
+    Im Teamspeak-Client kannst Du diese Daten im Menue unter "Favoriten -
+    Favoriten verwalten" eintragen, indem Du einen neuen Favoriten anlegst
+    und unter "Adresse" den Servernamen eintraegst. Deinen Spielernamen
+    traegst Du noch unter "Nickname" ein, und unter "Server Passwort" 
+    jenes, das Du (hoffentlich) aus dem Hinweis oben ableiten konntest.
+
+    Wenn Du moechtest, kannst Du das MG-TS noch als Standard-Server
+    einstellen, indem Du in der Favoritenverwaltung unten links auf "Mehr"
+    klickst und dann ein Haekchen bei "Beim Start verbinden" setzt. Dann
+    wirst Du bei jedem Starten des TS3-Clients direkt mit dem MG-TS 
+    verbunden.
+
+  
+Noch einige Hinweise:
+
+    Der Server wird derzeit von Olli zur Verfuegung gestellt, um die
+    Moeglichkeit zum Ausprobieren anzubieten, benehmt Euch also, wenn Ihr
+    da drauf seid. :-)
+
+    Die Rechteverwaltung von TS3 ist ausgesprochen komplex geraten, so dass
+    wir um Geduld bitten moechten, wenn irgendetwas nicht auf Anhieb
+    funktioniert.
+
+31.10.2012  Arathorn
+
diff --git a/doc/help/tod b/doc/help/tod
new file mode 100644
index 0000000..b5e2059
--- /dev/null
+++ b/doc/help/tod
@@ -0,0 +1,37 @@
+
+Der Tod und seine Folgen
+========================
+
+    Im MorgenGrauen gibt es viele verschiedene Moeglichkeiten, zu ster-
+    ben. Der haeufigste Grund ist jedoch das Sinken der Lebenspunkte
+    auf unter Null.
+
+    Den Tod bemerkt man an einer mehr oder weniger originellen Todes-
+    sequenz, die automatisch vor einem ablaeuft; in diese kann nicht
+    eingegriffen werden. Ausserdem verliert man als Spieler 33% seiner
+    Erfahrungspunkte. Je mehr Erfahrung man gesammelt hat, desto mehr
+    Punkte verliert man ergo. Damit der Verlust nicht ins Bodenlose 
+    steigen kann, geniessen Seher den Vorteil, mit jeder neuen Stufe
+    weniger Erfahrungspunkte im Todesfall zu verlieren.
+
+    Ein weiterer Effekt des Sterbens ist natuerlich der Verlust des 
+    Koerpers. Aus der Todessequenz kommt man als Geist wieder zurueck
+    auf die Welt. (Tip: "rassle /freundlich" ;-) Um wieder in den Ge-
+    nuss von koerperlichen Freu(n)den zu kommen, muss man einen heiligen
+    Ort aufsuchen und das weltliche Kommando "bete" eingeben.
+    [Chaoten beschwoeren alternativ einen unheiligen Daemonen.]
+
+    Nach dem Tod verliert man zeitlich begrenzt Attribute und buesst
+    Gildenfaehigkeiten ein. Nichtsdestotrotz kann man mit diesem Malus
+    an anderer Stelle im MG weiterspielen. Wer das ueberpruefen moechte,
+    sollte mit "hilfe sterben" eine schnelle legale Moeglichkeit finden,
+    Lars einen Besuch abzustatten oder Rochus eine Mail schicken.
+
+    Lars ist uebrigens der Gehilfe des Todes, und Rochus die linke und
+    die rechte Hand des Todes. :-)
+   
+ SIEHE AUCH:
+    sterben, leben, kampf
+
+ LETZTE AeNDERUNG:
+    14. Maerz 2004 Gloinson
diff --git a/doc/help/topliste b/doc/help/topliste
new file mode 100644
index 0000000..1d986c1
--- /dev/null
+++ b/doc/help/topliste
@@ -0,0 +1,21 @@
+
+ TOPLISTEN:
+ ==========
+
+    In (fast) jeder Kneipe im Morgengrauen findet man eine Topliste.
+    Auf dieser Topliste stehen die 100 Spieler, die die meisten
+    Stufenpunkte haben.
+    Wer - aus welchen Gruenden auch immer - darauf verzichten moechte,
+    in dieser Topliste aufzutauchen (wenn er/sie denn gut genug dafuer
+    ist), kann sich selbst mit dem Kommando
+
+        topliste nein
+
+    fuer die Topliste sperren. Mit dem Kommando
+
+        topliste ja
+
+    wird dies wieder rueckgaengig gemacht.
+
+ LETZTE AeNDERUNG:
+    Son, 30.8.1998, 22:10:00 von Paracelsus
diff --git a/doc/help/urukhai b/doc/help/urukhai
new file mode 100644
index 0000000..1965538
--- /dev/null
+++ b/doc/help/urukhai
@@ -0,0 +1,28 @@
+
+Die Gilde der Urukhai
+---------------------
+
+In Orkhausen im Verlorenen Land gibt es die Gilde der Urukhai. Dies ist die
+Standardgilde der Orks.
+
+Allerdings koennen auch andere Spieler Urukhai werden. Nur Felinen werden
+nicht zugelassen, da die Katzenwesen einfach fehl am Platze waeren. Weitere
+Voraussetzungen, um ein Urukhai zu werden, gibt es nicht, allerdings sollte
+man die richtige Einstellung mitbringen und es gerne blutig moegen.
+
+Hragznor ist der Gildenmeister der Urukhai. Bei ihm kann man der Gilde 
+beitreten und die verschiedenen Sprueche lernen, er weiss auch vieles 
+ueber die Gilde.
+
+Orks koennen von Natur aus gut mit bestimmten Waffen kaempfen. Auch dazu
+weiss Hragznor mehr.
+
+SIEHE AUCH:
+beisse, nachtsicht, identifiziere, schaetz, ruelpse, wirbelwind,
+spucke, hammerfaust, steinhaut, riesenpranke, leichenfledder,
+furcht, trollstaerke
+
+ALS NICHT-URUKHAI MUSS MAN DAFUER FOLGENDE SYNTAX NUTZEN:
+hilfe gilde urukhai <zaubername>
+z.B. hilfe gilde urukhai nachtsicht
+
diff --git a/doc/help/verein b/doc/help/verein
new file mode 100644
index 0000000..a745d66
--- /dev/null
+++ b/doc/help/verein
@@ -0,0 +1,73 @@
+#===================================================================#

+#   DU BIST NOCH NICHT MITGLIED? DANN LIES BESONDERS SORGFAELTIG!   #

+#===================================================================#

+

+Informationen zum Foerderverein Projekt MorgenGrauen e. V.:

+- WWW-Seite: http://mg.mud.de/Verein 

+- MPA unter der Rubrik "morgengrauen.verein"

+

+Zweck des Vereins:

+Foerderung des MUDs MorgenGrauen

+- finanzielle Mittel durch Spenden

+- Betreuung des vereinseigenen Rechners, auf dem das MUD laeuft

+- Kurse und Vortraege fuer Programmierer und Spieler

+  (Natuerlich keine Questloesungen)

+Diese Ziele sind satzungsbedingt. 

+

+Satzung:

+- im Vereinsbuero im Ordner

+- auf den WWW-Seiten des Vereins (auch zum ausdrucken)

+

+Wie werde ich Mitglied?

+- Antrag

+- moeglichst auch Einzugsermaechtigung

+(Siehe WWW-Seite)

+

+Was mach ich als Mitglied?

+- zu den Versammlungen kommen

+- mithelfen, die Zwecke des Vereins zu erfuellen

+- Sponsoren fuer den MG e. V. suchen und dem Vorstand mitteilen

+  (bitte keine Alleingaenge)

+- Kursthemen vorschlagen

+- selbst einen Vortrag halten

+

+Wer ist eigentlich der Vorstand?

+Der Vorstand besteht aus folgenden vier Personen:

+

+1. Vorsitzender:   Xutelius
+                   Henning Ullrich
+                   Himmelpfortener Weg 52
+                   59823 Arnsberg
+
+2. Vorsitzender:   Gloinson
+                   Christian Becker
+                   Abt-Thomas-Strasse 40
+                   88682 Salem
+
+Kassenwart:        Vanion
+                   Christian Fiedler
+                   Athenstr. 26
+                   26384 Wilhelmshaven
+
+Schriftfuehrer:    Guard
+                   Rene Waechter
+                   Karl-Kunger-Str. 66                 offizielle
+                   12435 Berlin                        Vereinsadresse!!
+
+Unsere Kontoverbindung:
+
+IBAN DE09 2802 0050 9204 1417 00
+SWIFT-BIC OLBODEH2XXX
+Kontonummer: 9204141700
+Oldenburgische Landesbank AG
+BLZ: 280 200 50
+
+Bei Fragen ueber den Verein koennt Ihr Euch direkt an eine dieser vier

+Personen wenden. Ihr erreicht alle Vorstandsmitglieder auch per E-Mail

+unter der Adresse 

+                        vorstand@mg.mud.de.

+

+#===================================================================#

+#              WAS ZOEGERST DU NOCH, WERDE MITGLIED!                #

+#===================================================================#

+

diff --git a/doc/help/waffenfertigkeiten b/doc/help/waffenfertigkeiten
new file mode 100644
index 0000000..e6a5285
--- /dev/null
+++ b/doc/help/waffenfertigkeiten
@@ -0,0 +1,33 @@
+Allgemeine Waffenfertigkeiten:
+==============================
+
+Bestimmte Gilden erlernen Waffenfertigkeiten. Dies sind bisher die
+Mitglieder folgender Gilden:
+
+ - Abenteurer
+ - Bierschuettler
+ - Chaos
+ - Katzenkrieger
+ - Wipfellaeufer
+
+Die Spieler dieser Gilde koennen das Kaempfen mit den Waffengattungen 
+Keulen, Staebe, Aexte, Speere, Messer, Schwerter und Peitschen durch 
+Benutzung dieser Waffen erlernen. Je besser man mit den Waffen umgehen
+kann, desto mehr Schaden kann man bei seinem Gegner verursachen.
+
+Neben der Faehigkeit im Umgang mit den Waffen spielt auch die Waffe
+eine Rolle, sowie die eigene Kraft und Geschicklichkeit. Dabei sollte
+man beruecksichtigen, dass die Waffen unterschiedliche Anforderungen 
+an das Geschick stellen. So ist die Benutzung einer Peitsche sehr
+komplex, zum Kampf mit einem Messer muss man sich ebenso recht
+geschickt anstellen, dicht gefolgt vom Kampf mit Speeren. Recht 
+ausgeglichen zwischen Geschicklichkeit und Kraft ist der Kampf mit einem
+Schwert. Die Benutzung von Aexten erfordert noch einiges Geschick, waehrend
+man bei Keulen am ehesten mit purer Kraft bedient ist.
+
+Wer wissen moechte, wie gut er den Umgang mit den Waffen bereits
+beherrscht, kann dazu einen Kaempfer (mindestens im Range eines
+Unteroffiziers) befragen. Der sollte dies beurteilen koennen. 
+
+
+Letzte Aenderung: 2012-08-26 von Arathorn.
diff --git a/doc/help/werwoelfe b/doc/help/werwoelfe
new file mode 100644
index 0000000..9a04f3a
--- /dev/null
+++ b/doc/help/werwoelfe
@@ -0,0 +1,13 @@
+-----------------------
+Die Gilde der Werwoelfe
+-----------------------
+
+Man kann auf der Werwolfinsel Mitglied der Gilde der Werwoelfe werden.
+Dazu muss man Mondheuler finden und bei ihm in die Gilde eintreten.
+
+Was die Werwoelfe koennen und welche Faehigkeiten sie haben kann man 
+dann von diversen Gildenmitgliedern erfragen.
+
+Eine Einfuehrung kann man bekommen, wenn man Mondheuler nach Hilfe fragt.
+
+Letzte Aenderung: 1.11.2013, Humni
diff --git a/doc/help/willkuer b/doc/help/willkuer
new file mode 100644
index 0000000..e78e038
--- /dev/null
+++ b/doc/help/willkuer
@@ -0,0 +1,9 @@
+Willkuer
+========
+        Willkuer ist subjektiv.
+
+ SIEHE AUCH:
+        goetter, erzmagier
+
+ LETZTE AeNDERUNG:
+     morgen, Gloinson i.A. Vanion
diff --git a/doc/help/wipfellaeufer b/doc/help/wipfellaeufer
new file mode 100644
index 0000000..3d662f5
--- /dev/null
+++ b/doc/help/wipfellaeufer
@@ -0,0 +1,71 @@
+GILDE DER WIPFELLAEUFER
+-----------------------
+
+Ueber dem heiligen Hain der Elfen befindet sich die Gilde der Wipfellaeufer.
+Illdereth, der Gildenvorsteher, bringt jungen Elfen und allen, die sonst der
+Gilde beitreten moechten, alles bei, was die Wipfellaeufer wissen muessen.
+
+EINSTUFUNG DER GILDE
+--------------------
+
+Die Wipfellaeufer sind eine explizite Anfaengergilde und als Anfaengergilde
+der Elfen ausgelegt. Allerdings werden sie im Laufe der Stufen auch durchaus
+in vielen Bereichen noch besser, so dass ein paar ihrer Faehigkeiten auch 
+fuer groessere Spieler interessant sein koennen.
+
+PRINZIPIEN
+----------
+
+Wipfellaeufer sind Kreaturen des Waldes, in der Regel Elfen, fuer die diese
+Gilde auch die Anfangsgilde ist. Sie verstehen sich auf das Bogenschiessen, 
+was vor allem dann sehr gut nutzbar ist, wenn sich jemand schuetzend im Kampf
+vor sie stellt.
+
+Ferner beherrschen sie ein paar Angriffszauber und kennen natuerlich die
+elementaren Dinge, die fuer das Ueberleben im Wald noetig sind.
+
+SONSTIGES
+---------
+
+Die wichtigsten Informationen ueber die Wipfellaeufer kennt Illdereth, 
+ansonsten kann man andere Mitspieler auf der Wipfellaeufer-Ebene befragen.
+
+Die Wipfellaeufer-Ebene kann man mit -wipfel+ betreten. (Mehr dazu unter 
+"hilfe ebenen").
+
+BESCHRAENKUNGEN
+---------------
+
+Zwerge koennen keine Wipfellaeufer werden. Die zwergischen Prinzipien des
+Stollenbaus wuerden auch nicht dazu passen, und die meisten Zwerge haben auch
+gar kein Interesse daran.
+
+Ferner koennen Dunkelelfen aufgrund des alten Hasses zwischen den Voelkern
+auch keine Wipfellaeufer werden.
+
+ZAUBERSPRUECHE
+--------------
+
+gluehwuermchen
+identifiziere
+schaetz
+regenguss
+baumrinde
+hagelschlag
+pfeilschnell
+blitz
+
+Gildenmagier
+------------
+
+Die Gilde wurde von Humni geschrieben, der derzeit auch dafuer zustaendig ist.
+
+Siehe auch: 
+-----------
+gilden, (die einzelnen Zaubersprueche), bogenschiessen
+
+* WENN MAN EINER ANDEREN GILDE ANGEHOERT, MUSS MAN FUER DIE HILFE
+,,hilfe gilde wipfellaeufer <thema>'' EINGEBEN! *
+
+Letzte Aenderung: Humni, 2011-10-27
+
diff --git a/doc/help/www b/doc/help/www
new file mode 100644
index 0000000..7d9638a
--- /dev/null
+++ b/doc/help/www
@@ -0,0 +1,19 @@
+Die Webseite(n)
+===============
+
+     Auf folgenden Webseiten finden sich Informationen ueber unser
+     MUD und dazugehoerige Projekte:
+
+     Offizielle Seite: http://mg.mud.de
+     * ermoeglicht Zugriff auf MPA/Archive
+     * enthaelt einen Web-Client und Links auf Clients
+     * enthaelt Informationen zum Ausrichten und Bilder von Parties
+     * enthaelt die Vereins-Seite: http://mg.mud.de/verein
+
+     Die Wiki-Seite: http://http://wiki.morgengrauen.info/
+     * auch von Nichtmagiern editierbare Projektseiten
+
+SIEHE AUCH:
+     mudrechner, client, teamspeak, irc
+
+26. Aug 2013 Gloinson
diff --git a/doc/help/zauberei b/doc/help/zauberei
new file mode 100644
index 0000000..11cd502
--- /dev/null
+++ b/doc/help/zauberei
@@ -0,0 +1,37 @@
+
+Zauberei im MorgenGrauen
+========================
+
+    Die meisten Gilden stellen ihren Mitgliedern mehr oder weniger nuetzliche
+    Zaubersprueche zur Verfuegung. Genaueres zu den einzelnen Spruechen
+    findest Du auf den jeweiligen Hilfeseiten.
+
+    Allgemein laesst sich sagen, dass die Anwendung von Magie im wesentlichen
+    an die Intelligenz des Charakters gekoppelt ist.
+
+    So verbrauchen die Sprueche in der Regel mehr oder weniger viele
+    Magiepunkte. Deren Anzahl wiederum haengt direkt von der Intelligenz ab,
+    kann aber auch durch andere Magie erhoeht werden.
+
+    Lernt man einen Spruch neu dazu, so wird ihm ein Anfangswert fuer die
+    Erfolgswahrscheinlichkeit zugeordnet. Auch dieser Anfangswert haengt bei
+    den meisten Gilden von der Intelligenz ab (hier koennen aber auch noch
+    weitere Faktoren wirksam werden).
+
+    Die Erfolgswahrscheinlichkeit eines Spruches verbessert sich, wenn der
+    Spruch fehlschlaegt (`Du lernst aus Deinem Fehler.'). Hier muss man
+    allerdings aufpassen: Einige Sprueche haben eine Beschraenkung der maximal
+    erreichbaren Wahrscheinlichkeit. Die Schranke wandert mit zunehmender
+    Spielerstufe weiter nach oben. Hat man den fuer seine Stufe maximalen Wert
+    erreicht, so kann es bei einigen Gilden immer noch zu der Lernmeldung
+    kommen, obwohl man eigentlich nichts dazulernt!
+
+    Die Verbesserung der Wahrscheinlichkeit im Falle eines Fehlschlags haengt
+    uebrigens wiederum in den meisten Faellen von der Intelligenz ab.
+
+ SIEHE AUCH:
+    attribute, gilden, heilung
+
+ LETZTE AeNDERUNG:
+    18. Maerz 2004 Gloinson
+
diff --git a/doc/help/zauberer b/doc/help/zauberer
new file mode 100644
index 0000000..846a375
--- /dev/null
+++ b/doc/help/zauberer
@@ -0,0 +1,36 @@
+
+Die Gilde der Zauberer
+----------------------
+
+    Die Gilde der Zauberer befindet sich in Taramis und ist im Moment nur
+    ueber ein magisches Tor zu erreichen. Um der Gilde beitreten zu koennen,
+    muss man den zweiten Level erreicht haben und 50 Abenteuerpunkte
+    aufweisen. Insgesamt gibt es zehn Stufen. Davon sind die ersten vier
+    Anfaengern vorbehalten. Vor dem Erreichen der fuenften Stufe muss man die
+    Lehrlingspruefung ablegen. Nach Bestehen der Pruefung bekommt man seinen
+    Zauberstab, der eine grosse Hilfe fuer den Zauberer ist.
+
+    Danach kann man bis zur Stufe Acht aufsteigen. Vor dem Erreichen der Stufe
+    Neun muss die Magisterpruefung abgelegt werden. Im Gegensatz zur
+    Lehrlingspruefung ist die Magisterpruefung aeusserst schwer. Danach steigt
+    man zum Magister auf und kann einen Magisterposten in einem der Zweige
+    beantragen. Aus spieltechnischen und balancetechnischen Gruenden ist der
+    Rang eines Erzmagisters momentan nicht von Spielern zu erreichen.
+
+    Die Zaubersprueche, die der Zauberer lernen kann, unterteilen sich in
+    sechs Zweige: Angriff, Beherrschung, Hellsicht, Illusion, Schutz und
+    Verwandlung.
+    Zu Beginn lernt man aus jedem Zweig einen Spruch. Nach der
+    Lehrlingspruefung kann man auf jeder Stufe (5-8) je einen Spruch aus einem
+    Zweig lernen. Als Magister kann man sich fuer einen Zweig entscheiden und
+    dort zwei Magistersprueche lernen. 
+
+
+ SIEHE AUCH:
+    attribute, ebenen, gilden
+
+    Angehoerige fremder Gilden koennen sich in der Bibliothek der Zauberer
+    ueber die einzelnen Sprueche und Zweige informieren.
+
+ LETZTE AeNDERUNG:
+    Die, 03.10.2006, 20:32:00 von Chagall
diff --git a/doc/help/zaubertraenke b/doc/help/zaubertraenke
new file mode 100644
index 0000000..2c65860
--- /dev/null
+++ b/doc/help/zaubertraenke
@@ -0,0 +1,64 @@
+
+Zaubertraenke
+=============
+
+ ZAUBERTRAeNKE:
+    Im ganzen MorgenGrauen sind Zaubertraenke (ZT) versteckt, welche die
+    Attribute erhoehen. Da das Spiel aber inzwischen so gross geworden ist,
+    dass man sie ohne Hilfe praktisch nicht mehr finden kann, gibt es das
+    Orakel von Tingan. Dort bekommt man in Abhaengigkeit von den
+    Stufenpunkten konkrete Hinweise, wo man einen Zaubertrank finden kann.
+    Natuerlich bekommen Anfaenger zuerst die leichtesten Verstecke verraten,
+    der Schwierigkeitsgrad steigert sich dann im Spielverlauf. So sollte es
+    immer moeglich sein, mit den Tipps auch etwas anzufangen (siehe DETAILS).
+
+    Konkret sieht das so aus:
+
+     * 8 Tipps kann man sich direkt bei Spielbeginn umsonst holen
+     * 26 Tipps gibt es fuer jeweils 25 Stufenpunkte
+     * 26 Tipps gibt es fuer jeweils 40 Stufenpunkte
+     * 10 Tipps gibt es fuer jeweils 70 Stufenpunkte
+     * 10 Tipps gibt es fuer jeweils 100 Stufenpunkte
+
+    Natuerlich muss man keine Stufenpunkte bezahlen, man muss sie nur haben.
+
+    ACHTUNG: Man kann die Zaubertraenke erst finden, wenn man den
+    entsprechenden Hinweis vom Orakel bekommen hat.
+
+    Wo ist das Orakel?
+    Das Orakel kann man finden, wenn man sich den westlichen Teil der
+    Hochebene etwas genauer anschaut. Wie man die Hochebene findet? Das kann
+    jeder Spieler mit ein bisschen Spielerfahrung erklaeren, also fragt ruhig
+    ein bisschen herum.
+
+    Wie sehen die Hinweise aus?
+    Natuerlich orakelmaessig verschluesselt, aber nicht *zu* undurchsichtig.
+    Man sollte in der Regel schon etwas damit anfangen koennen, das heisst
+    aber nicht, dass man ueberhaupt nicht mehr suchen oder nachdenken muss.
+    Damit man sich nicht alles aufschreiben muss, merkt sich der Spieler die
+    momentan aktuellen Sprueche automatisch, man kann sie mit dem Befehl
+    `zaubertraenke' abrufen. Wenn der Zaubertrank gefunden wurde, verschwindet
+    auch der entsprechende Hinweis aus der Liste.
+    Fuer einige Zaubertraenke gibt es mehrere Sprueche, die in der Liste
+    zufaellig ausgewaehlt und angezeigt werden.
+
+ DETAILS:
+    Technisch genauer: Ein Spieler bekommt bei seinem ersten Login eine Liste
+    von ZTs zugeordnet. Diese Liste ist eine Auswahl aus allen existierenden
+    ZTs.
+    Das Orakel praesentiert einem dann jeweils die leichtesten ZTs aus dieser
+    eigenen Liste (und nicht aus allen ZTs!)
+    Das heisst also, dass euch durch andere Spieler bekannte, leichte ZTs
+    nicht unbedingt auch eure ZTs sein muessen. Und es kann bedeuten, dass
+    eure leichten ZTs etwas schwerer sind. Nicht aufgeben!
+
+    Wenn euch ZTs an nur in einer Quest erreichbaren Stellen auffallen, so
+    wendet euch bitte an den Erzmagier, der fuer die ZTs zustaendig ist
+    (siehe hilfe erzmagier).
+
+ SIEHE AUCH:
+    attribute, stufenpunkte
+
+ LETZTE AeNDERUNG:
+    25. Nov 2007 Gloinson
+
diff --git a/doc/help/zeitung b/doc/help/zeitung
new file mode 100644
index 0000000..cd1c28e
--- /dev/null
+++ b/doc/help/zeitung
@@ -0,0 +1,21 @@
+
+Zeitung im Morgengrauen
+=======================
+
+ BESCHREIBUNG:
+     In Morgengrauen gibt es eine fuer alle verfuegbare Zeitung, die
+     Morgengrauen Presse-Agentur (MPA). Besuche einen Startraum deiner
+     Wahl und nimm dir eine mit.
+
+     Die Zeitung selbst hat dann eine eigene Hilfefunktion.
+
+ BEMERKUNGEN:
+     Eine der wichtigsten Rubriken ist die Rubrik "megaschmarrn". Dort
+     werden alle (!) relevanten Themen besprochen. Regeln siehe
+     Rubrik.
+
+ SIEHE AUCH:
+     teile mit, ebenen
+
+ LETZTE AeNDERUNG:
+    5. Oktober 2004 Gloinson
diff --git a/doc/help/zookeln b/doc/help/zookeln
new file mode 100644
index 0000000..ee6329f
--- /dev/null
+++ b/doc/help/zookeln
@@ -0,0 +1,16 @@
+
+Extra fuer Mesirii gibt es nun auch zum Thema zookeln eine Hilfeseite:
+
+ZOOKELN (TM):  Versehentliches Gelaber auf der falschen Ebene. Besonders
+               spannend, wenn man gerade ueberaus wichtige und geheime
+               Dinge auf -all statt auf -goetter erzaehlt. Oftmals voellig
+               zusammenhangsloses Gelaber, mit dem nur die was anfangen 
+               koennen, die die Ebene eingeschaltet haben, auf der dieser
+               Text gesendet werden sollte.
+
+BEMERKUNGEN:   Ueberfluessig
+
+SIEHE AUCH:    zook
+---------------------------------------------------------------------------
+Letzte Aenderung: 19.10.2005  Miril
+
diff --git a/doc/help/zweitspieler b/doc/help/zweitspieler
new file mode 100644
index 0000000..bc57f74
--- /dev/null
+++ b/doc/help/zweitspieler
@@ -0,0 +1,23 @@
+
+Zweitspieler
+============
+
+ BESCHREIBUNG:
+     Zweitspieler sind Spieler, welche man zusaetzlich zu seinem Haupt-
+     charakter erschaffen hat. Hauptsaechlich nutzt man sie, um fuer den
+     Erstie Sachen zu schleppen, zu sterben, um andere Gilden zu testen oder
+     gar Magier zu werden.
+
+ BEMERKUNGEN:
+     Jeder Spieler im MUD ist verpflichtet, seine Zweities zu markieren, um
+     damit Verantwortlichkeiten besser zuordnen zu koennen.
+
+     Diese Markierung kann man zum Beispiel beim Schmied in der Zwergenstadt
+     oder beim Dorfschreiber im Elfendorf erhalten.  Diese Markierung kann
+     man auch vor anderen Spielern verbergen.
+
+ SIEHE AUCH:
+     zweitiemarkierung, regeln
+
+ LETZTE AeNDERUNG:
+     5. Mai 2004 Gloinson
diff --git a/doc/hilfe.magier b/doc/hilfe.magier
new file mode 100644
index 0000000..92e88d7
--- /dev/null
+++ b/doc/hilfe.magier
@@ -0,0 +1,36 @@
+
+  ---------------------------MAGIERHILFSSEITE------------------------------
+
+Als Magier hat man neben den Spieler- und Seherbefehlen einige weitere
+Befehle zur Verfuegung. Bei der Anzeige der Hilfeseiten wird nicht zwischen
+den Stufen der Magier unterschieden wird. Diese wird aber bei Erlaeuterung
+beruecksichtigt:
+
+Allgemeine Themen und REGELN:	    |  Kommunikation:
+    balance, forscherpunkte,	    |      echoall, echoto, echo, mecho,
+    testspieler, zweitspieler,	    |      mrufe, oropax, remote
+    effizienz, objekte		    |
+				    |
+Bewegung:			    |  Kampf:
+    goto, trans, home, verfolge,    |      zap, frieden, sethands
+    at, in, +			    |
+				    |
+Dateisystem:			    |  Objekte:
+    cd, pwd, ls, cat, head, tail,   |      clone, destruct, upd(ate), load,
+    more, grep, cp, mv, rm, mkdir,  |	   setcmsg, setdmsg
+    rmdir, set, prompt, ed	    |
+				    |  Anderes:
+Information:                        |     heile, zwinge, titel, extralook,
+    mschau, people, pwho, man,      |     traenke, invis, vis, protect, do
+    snoop, sallow, spieler, rman,   |     showpresay, ping, todo
+    localcmd			    |
+				    |  Erzmagierbefehle:
+Regionsmagierbefehle:		    |     addmaster, removemaster, mbanish,
+    regionsmagier, banish, exec     |     shutdown
+				    |
+
+In den Verzeichnissen unter /doc/ findest du weitere Dokumentation:
+- funktionierende Beispiele unter /doc/beispiele/
+- MG-spezifische Informationen unter /doc/MG/
+- einen Programmierkurs unter /doc/KURS/
+
diff --git a/doc/hilfe.seher b/doc/hilfe.seher
new file mode 100644
index 0000000..5281978
--- /dev/null
+++ b/doc/hilfe.seher
@@ -0,0 +1,22 @@
+
+  ----------------------------SEHERHILFSSEITE------------------------------
+
+Als Seher hat man einige zusaetzliche Befehle. Zu den folgenden Befehlen
+kann man mit "hilfe <thema>" eine Erlaeuterung erhalten.
+
+Kommunikation:			    |  Kampf
+    remote,			    |      fluchtrichtung, sethands, review
+    echo (nach Architektenquest)    |
+				    |
+Bewegungsmeldungen:		    |  Aussehen:
+    setmin, setmout, setmmin,	    |      titel, extralook, presay
+    setmmout, review		    |
+
+Hausbau:
+    hausbau, instanthaus, seherhaus,
+    aendere, ausgang, beschreibe, erlaube, kopiere, licht, loesche,
+    meldungen, notiz, schiebe, sperre, spion, uebersicht, verbiete, werfe
+
+Anderes:
+    fehlermeldung, review
+
diff --git a/doc/hilfe.spieler b/doc/hilfe.spieler
new file mode 100644
index 0000000..a2072f8
--- /dev/null
+++ b/doc/hilfe.spieler
@@ -0,0 +1,62 @@
+
+  ---------------------------SPIELERHILFSSEITE-----------------------------
+
+Fuer folgende allgemeine Befehle und Themen kann mit "hilfe <thema>" eine
+Erlaeuterung angezeigt werden:
+
+Einfuehrung und erste Schritte:
+    Grundlegend: 
+      syntax, bewegung, regeln, einfuehrung
+    Charakter:
+      attribute, zaubertraenke, stufen, stufenpunkte
+    Spiel:   
+      abenteuer, gilden, zauberei
+    Neuspieler:  
+      cicerones, tutorial
+
+Kommunikation:
+    Im Raum:	
+      sage, gespraech, frage, antworte
+    Privat:	
+      teile (mit), erzaehle, erwidere, fluestere,
+    MUD-weit:	
+      rufe, ebenen, post, mrufe
+    Anderes:	
+      ignoriere, kobold, weg, parties, senderwiederholung, klingelton
+      teamspeak
+
+Allgemeine Aktionen:
+    gib (an), hole (aus), nimm [aus], stecke (in), wirf (weg),
+    behalte, klettere, reise
+
+Interaktion und Information:
+    schau (an), untersuche, lausche, rieche, suche, i (=inventur),
+    ausruestung, info, kurzinfo, taste
+    inform, erwarte, wer, kwer, kkwer, muds, zeit, finger, idlezeit
+    email, url, ort, icq, wegmeldung
+
+Sonstige Verben:
+    verben (mit eigener Hilfefunktion), adverb, emote, rknuddle, rwinke
+
+Eingaben und Ersetzungen:
+    alias, unalias, ersetzungsanzeige, history
+
+Kampf:
+    toete, stop, vorsicht, zuecke, ziehe (hervor/aus), trage,
+    stecke (weg/zurueck), heilung, sterben, spruchermuedung
+    team, waffenfertigkeiten, gift/krankheiten/flueche
+
+Gildenuebersicht:
+    abenteurer, bierschuettler, chaos, dunkelelfen, kaempfer, karate,
+    klerus, tanjian, uruk-hai, werwoelfe, zauberer
+
+Andere Befehle:
+    ende, schlafe (ein), speichern, lang, kurz, ultrakurz, ausgaenge,
+    passwort, fehler, idee, typo, zeilen, selbstloeschung, spieldauer,
+    spielpause, uhrmeldung, zweitiemarkierung, telnegs, stty, grafik, 
+    telnet
+
+Sonstige Themen:
+    verein, konzept, seher, magier, regionen, editor, buecher, faq,
+    balance, mudrechner, einfuehrung, spiele
+
diff --git a/doc/hook/auto_include b/doc/hook/auto_include
new file mode 100644
index 0000000..a82adda
--- /dev/null
+++ b/doc/hook/auto_include
@@ -0,0 +1,37 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_AUTO_INCLUDE, value)
+
+        <value> being:
+
+          string <text>
+          string <closure>(string base_file, string current_file
+                          , int sys_include)
+
+DESCRIPTION
+        Optional hook specifying a string to be included before
+        the source of every compiled LPC object.
+        Hook setting can be a string or a closure.
+
+        If the setting is a string, it will be automatically included before
+        the source of every compiled LPC object.
+
+        If the setting is a closure, it is called for every file
+        opened by the compiler. <base_file> will be the filename of
+        the compiled object, <current_file> the name of a file
+        included directly or indirectly by the <base_file>. When the
+        <base_file> itself is opened, <current_file> will be 0. For an
+        included file, <sys_include> will be TRUE if it is a <>-type
+        include.
+
+        If the result from the call is a string, it will be included
+        before the actual text of the file.
+
+        In both cases, the string will be included as-is; in
+        particular no terminating '\n' will be added.
+
+HISTORY
+
+SEE ALSO
+        hooks(C), include_dirs(H)
diff --git a/doc/hook/clean_up b/doc/hook/clean_up
new file mode 100644
index 0000000..e00521a
--- /dev/null
+++ b/doc/hook/clean_up
@@ -0,0 +1,45 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_CLEAN_UP, value)
+
+        <value> being:
+
+          int <closure>(int ref, object ob)
+          void|int <name>(int ref)
+
+DESCRIPTION
+        Optional hook to clean up an object.
+        Hook setting can be any closure, or the name of the function
+        to call in the object.
+
+        This hook is called for an object if it hasn't been used
+        for at least TIME_TO_CLEAN_UP seconds, to give it the
+        opportunity to self destruct.
+
+        If the hook is a closure, it is called with the refcount of
+        the object to clean up as first argument, and with the object
+        itself as second. Lambda closures are also bound to the object
+        prior to the call.
+
+        If the hook is the name of an lfun, it is called in the
+        object with its refcount as argument.
+
+        In both calls, the refcount is constructed as:
+
+          ref = 0: the object is a clone, or a blueprint with
+                   replaced program.
+          ref = 1: the object is a swapped or unused blueprint.
+          ref > 1: the object is a used blueprint with <ref> references.
+
+        The cleanup method has the possibility to destruct the
+        object. To survive this time, but try again some time later,
+        the call has to result in a non-zero value.
+
+        If the hook specifies a non-existing lfun, or if the call
+        returns 0, no further attempt to clean up this object will be done.
+
+HISTORY
+
+SEE ALSO
+        hooks(C)
diff --git a/doc/hook/clone_uids b/doc/hook/clone_uids
new file mode 100644
index 0000000..4bf902a
--- /dev/null
+++ b/doc/hook/clone_uids
@@ -0,0 +1,36 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_CLONE_UIDS, value)
+
+        <value> being:
+
+          mixed <closure>(object blueprint, string objectname)
+
+DESCRIPTION
+        Mandatory hooks to determine the uid and euid of cloned
+        objects.  Hook settings can be any closure.
+
+        When an object is cloned, the H_CLONE_UIDS hook is called with
+        the blueprint object as first and the clone's designated name
+        as second argument. The new object already exists, but has 0
+        uids.
+
+        For the result, the following possibilities exist (<num> is
+        a non-zero number, <no-string> is anything but a string):
+
+           "<uid>"                    -> uid = "<uid>", euid = "<uid>"
+           ({ "<uid>", "<euid>" })    -> uid = "<uid>", euid = "<euid>"
+           ({ "<uid>", <no-string> }) -> uid = "<uid>", euid = 0
+
+        If strict-euids is not active, the following results are
+        possible, too:
+
+           <num>                      -> uid = 0, euid = 0
+           ({ <num>, "<euid>" })      -> uid = 0, euid = "<euid>"
+           ({ <num>, <no-string> })   -> uid = 0, euid = 0
+
+HISTORY
+
+SEE ALSO
+        hooks(C), uids(C), load_uids(H)
diff --git a/doc/hook/command b/doc/hook/command
new file mode 100644
index 0000000..de1b609
--- /dev/null
+++ b/doc/hook/command
@@ -0,0 +1,33 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_COMMAND, value)
+
+        <value> being:
+
+          int <closure>(string command, object command_giver)
+          int <name>(string command, object command_giver)
+
+DESCRIPTION
+        Optional hook to parse and execute commands. If this hook is
+        used, it bypasses the normal command parsing done by the
+        driver (including the MODIFY_COMMAND and NOTIFY_FAIL hooks).
+
+        The hook is called with two parameters: the command received
+        from the living (interactive user or NPC), and the living
+        object (the 'command giver') itself. The hook has to return
+        non-0 if the command was found and executed, and 0 otherwise.
+
+        At the time the hook is called, query_command() returns the
+        command string and this_player() returns the living object.
+        query_verb() and query_notify_fail() return 0.
+
+        If the hook is a string, it is the name of an lfun in the
+        command giver; if the hook is a lambda closure, it is bound to
+        the command giver before the call.
+
+HISTORY
+
+SEE ALSO
+        hooks(C), modify_command(H), modify_command_fname(H), notify_fail(H),
+        send_notify_fail(H)
diff --git a/doc/hook/create_clone b/doc/hook/create_clone
new file mode 100644
index 0000000..bf3100e
--- /dev/null
+++ b/doc/hook/create_clone
@@ -0,0 +1,34 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_CREATE_CLONE, value)
+
+        <value> being:
+
+          void <name> (0)
+          int <closure> ( void )
+          int <closure> (object obj_to_init)
+
+DESCRIPTION
+        Optional hooks to initialize a cloned object after creation.
+        Hook setting can be unbound lambda closures, or the name of
+        the function (static or public) to call in the object.
+
+        If the hook is a closure expecting an argument, it is bound
+        to the current object and called with the created object as
+        argument. If the hook as a closure without arguments, it is bound to
+        the object to be initalized and called.
+
+        If the result of the closure call is a non-zero number, it is used
+        as the interval to wait before the first reset(), else the default
+        interval computed from TIME_TO_RESET is used.
+
+        If the hook is defined as the name of an lfun in the object,
+        it is called in the object with 0 as argument, and any result
+        is ignored.
+
+HISTORY
+        LDMud 3.2.10 allowed static functions to be given by name.
+
+SEE ALSO
+        hooks(C), create_ob(H), create_super(H)
diff --git a/doc/hook/create_ob b/doc/hook/create_ob
new file mode 100644
index 0000000..7de7ba3
--- /dev/null
+++ b/doc/hook/create_ob
@@ -0,0 +1,35 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_CREATE_OB, value)
+
+        <value> being:
+
+          void <name> (0)
+          int <closure> ( void )
+          int <closure> (object obj_to_init)
+
+DESCRIPTION
+        Optional hooks to initialize an explictely loaded
+        object/blueprint after creation.  Hook setting can be unbound
+        lambda closures, or the name of the function (static or public) to
+        call in the object.
+
+        If the hook is a closure expecting an argument, it is bound
+        to the current object and called with the created object as
+        argument. If the hook as a closure without arguments, it is bound to
+        the object to be initalized and called.
+
+        If the result of the closure call is a non-zero number, it is used
+        as the interval to wait before the first reset(), else the default
+        interval computed from TIME_TO_RESET is used.
+
+        If the hook is defined as the name of an lfun in the object,
+        it is called in the object with 0 as argument, and any result
+        is ignored.
+
+HISTORY
+        LDMud 3.2.10 allowed static functions to be given by name.
+
+SEE ALSO
+        hooks(C), create_super(H), create_clone(H)
diff --git a/doc/hook/create_super b/doc/hook/create_super
new file mode 100644
index 0000000..a502730
--- /dev/null
+++ b/doc/hook/create_super
@@ -0,0 +1,35 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_CREATE_SUPER, value)
+
+        <value> being:
+
+          void <name> (0)
+          int <closure> ( void )
+          int <closure> (object obj_to_init)
+
+DESCRIPTION
+        Optional hooks to initialize a blueprint which is loaded by
+        inheritance after creation.
+        Hook setting can be unbound lambda closures, or the name of
+        the function (static or public) to call in the object.
+
+        If the hook is a closure expecting an argument, it is bound
+        to the current object and called with the created object as
+        argument. If the hook as a closure without arguments, it is bound to
+        the object to be initalized and called.
+
+        If the result of the closure call is a non-zero number, it is used
+        as the interval to wait before the first reset(), else the default
+        interval computed from TIME_TO_RESET is used.
+
+        If the hook is defined as the name of an lfun in the object,
+        it is called in the object with 0 as argument, and any result
+        is ignored.
+
+HISTORY
+        LDMud 3.2.10 allowed static functions to be given by name.
+
+SEE ALSO
+        hooks(C), create_ob(H), create_clone(H)
diff --git a/doc/hook/default_method b/doc/hook/default_method
new file mode 100644
index 0000000..427a131
--- /dev/null
+++ b/doc/hook/default_method
@@ -0,0 +1,44 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_DEFAULT_METHOD, value)
+
+        <value> being:
+
+          int <name>(mixed & result, string fun, varargs args)
+          int <closure>(mixed & result, object ob, string fun, varargs args)
+
+DESCRIPTION
+        Optional hook to provide default implementation for unresolved
+        calls. Hook setting can be any closure, or the name of the
+        function to call in the object.
+
+        This hook is called whenever a call_other(), call_resolved()
+        or call_out() on named function (as opposed to a closure)
+        couldn't be resolved. The hook has then the opportunity to
+        provide a default implementation.
+
+        Exempt from this behaviour are calls to the master object, to
+        simul-efuns, and calls done with call_direct() and
+        call_direct_resolved().
+
+        If the hook is the name of an lfun, it is called in the target
+        object; otherwise if it is a closure, the target object is
+        passed as parameter <ob>.
+
+        The other parameters passed are the name <fun> of the called
+        function, the arguments <args> passed to the call (if any),
+        and a reference <result> to a variable for the call result.
+
+        If the hook can resolve the call, it has to return the call
+        result in <result> and 1 as function result.
+
+        If the hook can not (or doesn't want to) resolve the call, it
+        has to return 0.
+
+
+HISTORY
+        Introduced in LDMud 3.3.113
+
+SEE ALSO
+        hooks(C)
diff --git a/doc/hook/default_prompt b/doc/hook/default_prompt
new file mode 100644
index 0000000..6231bb4
--- /dev/null
+++ b/doc/hook/default_prompt
@@ -0,0 +1,24 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_DEFAULT_PROMPT, value)
+
+        <value> being:
+
+          string <prompt>
+          string <closure>()
+
+DESCRIPTION
+        Optional hook for the command prompt. If this hook is not used,
+        the driver will use "> " as the command prompt.
+
+        The hook can be given as string or as closure. If it is a
+        closure, it is called with the commandgiver being the calling
+        object. If the result is a string, it will be printed,
+        otherwise ignored.
+
+HISTORY
+        Introduced in LDMud 3.3.163.
+
+SEE ALSO
+        hooks(C), print_prompt(H)
diff --git a/doc/hook/erq_stop b/doc/hook/erq_stop
new file mode 100644
index 0000000..a135a1c
--- /dev/null
+++ b/doc/hook/erq_stop
@@ -0,0 +1,20 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_ERQ_STOP, value)
+
+        <value> being:
+
+          void <closure>()
+
+DESCRIPTION
+        Optional hook to notify the mudlib about the termination of
+        the erq demon.  Hook setting may be any closure.
+
+        The closure is called without arguments and may do whatever it
+        likes to clean-up after the erq.
+
+HISTORY
+
+SEE ALSO
+        hooks(C)
diff --git a/doc/hook/hook b/doc/hook/hook
new file mode 100644
index 0000000..3218445
--- /dev/null
+++ b/doc/hook/hook
@@ -0,0 +1,18 @@
+CONCEPT
+        driver hooks
+
+DESCRIPTION
+        To allow a greater flexibility of the muds, the gamedrivers
+        since 3.2.1 moved several once hardcoded 'underground'
+        activities from the driver into the mudlib. This includes for
+        example the differences between compat and native mode.
+
+        The hooks are set with the privileged efun set_driver_hook().
+        Some of the hooks are mandatory, some not. Most hooks accept
+        unbound lambda closures as values, some also lfun closures or
+        even strings.
+        The hooks are identified by an ordinal number, for which
+        symbolic names are defined in /sys/driverhooks.h.
+
+SEE ALSO
+        native(C), set_driver_hook(E)
diff --git a/doc/hook/include_dirs b/doc/hook/include_dirs
new file mode 100644
index 0000000..6557359
--- /dev/null
+++ b/doc/hook/include_dirs
@@ -0,0 +1,38 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_INCLUDE_DIRS, value)
+
+        <value> being:
+
+          string *<dirs>
+          string <closure>(string include_name, string current_file)
+
+DESCRIPTION
+        Semi-mandatory hook specifying the directories where <>-type
+        include files are searched (this includes ""-includes not
+        found as specified).  Hook setting may be any closure or a
+        string array. If not set, only ""-type includes may be used in LPC
+        programs.
+
+        The hook is called only if a call to master::include_file()
+        does not return a usable filename.
+
+        If the hook setting is a string array, it has to contain the
+        path names of those directories where <>-type includes are to
+        be searched. The directories are searched in the order they
+        appear in the array. The directory name and the name of the
+        actual include file are concatenated, therefore the directory
+        names have to end in '/'. Leading slashes may be omitted.
+
+        If the setting is a closure, it is called with the name of the
+        desired include file as first, and the name of the compiled
+        LPC file as second argument.  Result has to be the complete
+        path name of the include file to use. Leading slashes may be
+        omitted.  If the closure is a lambda closure, it is bound to
+        this_object() prior to execution.
+
+HISTORY
+
+SEE ALSO
+        hooks(C), auto_include(H), include_file(M)
diff --git a/doc/hook/load_uids b/doc/hook/load_uids
new file mode 100644
index 0000000..9d1e160
--- /dev/null
+++ b/doc/hook/load_uids
@@ -0,0 +1,35 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_LOAD_UIDS, value)
+
+        <value> being:
+
+          mixed <closure> (string objectname)
+
+DESCRIPTION
+        Mandatory hooks to determine the uid and euid of loaded or
+        cloned objects.  Hook settings can be any closure.
+
+        When an object is newly loaded, the H_LOAD_UIDS hook is called
+        with the object name as argument.  The new object already
+        exists, but has 0 uids.
+
+        For the result, the following possibilities exist (<num> is
+        a non-zero number, <no-string> is anything but a string):
+
+           "<uid>"                    -> uid = "<uid>", euid = "<uid>"
+           ({ "<uid>", "<euid>" })    -> uid = "<uid>", euid = "<euid>"
+           ({ "<uid>", <no-string> }) -> uid = "<uid>", euid = 0
+
+        If strict-euids is not active, the following results are
+        possible, too:
+
+           <num>                      -> uid = 0, euid = 0
+           ({ <num>, "<euid>" })      -> uid = 0, euid = "<euid>"
+           ({ <num>, <no-string> })   -> uid = 0, euid = 0
+
+HISTORY
+
+SEE ALSO
+        hooks(C), uids(C), clone_uids(H)
diff --git a/doc/hook/modify_command b/doc/hook/modify_command
new file mode 100644
index 0000000..f478312
--- /dev/null
+++ b/doc/hook/modify_command
@@ -0,0 +1,61 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_MODIFY_COMMAND, value)
+
+        <value> being:
+
+          int|string <closure>(string cmd, object player)
+          int|string <name>(string cmd)
+          <mapping>
+
+DESCRIPTION
+        Optional hook to modify commands (both entered or given by a
+        call to command()) before the parser sees them (this includes
+        special commands like 'status').
+
+        Hook setting can be any closure, the name of the function to
+        call in the object, or a mapping.
+
+        For interactives this hook is used only if the interactive
+        object has no command modifier already set by the efun
+        set_modify_command().
+
+        If the hook is a closure, it is called with the entered
+        command as first, and the command giving player as second
+        argument. Lambda closures are bound to the command giving player,
+        unbound-lambda closures remain unbound.
+
+        If the hook is a string, it is used as the name of an lfun
+        in the command giving player, which is called with the command
+        as argument.
+
+        If the hook is a mapping, it is queried with the given command
+        as index, and the data retrieved is used as new command
+        (defaults to 0 if no data is stored for a given command). If
+        an entry is a closure instead of a string, it is called as
+
+          int|string <closure>(string cmd, object player)
+
+        and the result from the call is used as 'the' command.
+
+        The result is treated equal in all three cases:
+         - If the result is a string, it is the new command to execute
+           instead of the given one. Note that it is not possible to
+           make several commands from one this way!
+         - If the result is a non-zero number, the given command is to
+           be ignored. In case of the closure/lfun setting this may
+           mean that the closure/lfun already executed it.
+         - If the result is 0, the originally given command is to be
+           used.
+
+        It is possible for the hook to change the command giver
+        (this_player()) for the execution of the command. This means that
+        even though the commands are execute for the original commandgiver,
+        this_player() will return the changed commandgiver.
+
+HISTORY
+
+SEE ALSO
+        hooks(C), command(H), modify_command_fname(H), notify_fail(H),
+        send_notify_fail(H)
diff --git a/doc/hook/modify_command_fname b/doc/hook/modify_command_fname
new file mode 100644
index 0000000..095ef80
--- /dev/null
+++ b/doc/hook/modify_command_fname
@@ -0,0 +1,44 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_MODIFY_COMMAND_FNAME, value)
+
+        <value> being:
+
+          int|string <name>(string cmd)
+
+DESCRIPTION
+        Mandatory hook specifying the name of the 'modify_command'
+        lfun to call for newly entered commands as result of a
+        set_modify_command().
+
+        Hook setting must be a string.
+
+        If set_modify_command() is used for an interactive user, all
+        newly entered commands are first passed to the function named
+        by this hook.
+
+        The function is called with the command as argument.
+
+        If the result is a string, it is the new command to execute
+        instead of the given one. Note that it is not possible to make
+        several commands from one this way!
+
+        If the result is a non-zero number, the given command is to be
+        ignored. In case of the closure/lfun setting this may mean
+        that the closure/lfun already executed it.
+
+        If the result is 0, the originally given command is to be
+        used.
+
+        It is possible for the hook to change the command giver
+        (this_player()) for the execution of the command. This means
+        that even though the commands are execute for the original
+        commandgiver, this_player() will return the changed
+        commandgiver.
+
+HISTORY
+
+SEE ALSO
+        hooks(C), command(H), modify_command(H), notify_fail(H),
+        send_notify_fail(H)
diff --git a/doc/hook/move_object b/doc/hook/move_object
new file mode 100644
index 0000000..5b2445d
--- /dev/null
+++ b/doc/hook/move_object
@@ -0,0 +1,27 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_MOVE_OBJECT0, value)
+        set_driver_hook(H_MOVE_OBJECT1, value)
+
+        <value> being:
+
+          void <closure>(object item, object dest)
+
+DESCRIPTION
+        Mandatory hooks to implement the efun void move_object().
+        Hook setting must be an unbound lambda closure.
+
+        Upon call, the hook has to perform the move itself (by using
+        set_environment()) and all depending actions (like the calls to
+        init() to add actions).
+
+        The difference lies in the binding of the set hook prior to
+        the call: the H_MOVE_OBJECT0 closure is bound to the current
+        object, the H_MOVE_OBJECT1 to 'item'.
+        If both hooks are set, H_MOVE_OBJECT0 is ignored.
+
+HISTORY
+
+SEE ALSO
+        move_object(E), set_environment(E), hooks(C)
diff --git a/doc/hook/msg_discarded b/doc/hook/msg_discarded
new file mode 100644
index 0000000..5360dfe
--- /dev/null
+++ b/doc/hook/msg_discarded
@@ -0,0 +1,28 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_MSG_DISCARDED, value)
+
+        <value> being:
+
+          string <msg>
+          string <closure>(object user)
+
+DESCRIPTION
+        Optional hook to specify a message or take other measures
+        when a message had to be discarded, because they could not
+        be delivered to the player <user>. If the hook is not set,
+        a standard message is used.
+
+        If the hook is a string, this text will be sent as soon as
+        possible to the player informing about the lost transmission.
+
+        If the hook is a closure, it is the function to be called
+        and the result is used as the message to be sent. Lambda
+        closures are bound to the interactive <user> first.
+
+HISTORY
+        Introduced in LDMud 3.3.719
+
+SEE ALSO
+        hooks(C), configure_interactive(E)
diff --git a/doc/hook/no_echo b/doc/hook/no_echo
new file mode 100644
index 0000000..b592529
--- /dev/null
+++ b/doc/hook/no_echo
@@ -0,0 +1,41 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_TELNET_NEG, value)
+
+        <value> being:
+
+          void <name>(int flag, object user, int no_telnet)
+          void <closure>(int flag, object user, int no_telnet)
+
+DESCRIPTION
+        Optional hook to specifiy how to perform the telnet actions to
+        switch the echo mode (used for e.g. password input_to()s).
+        Hook setting may be any closure or a string.  If not set, a
+        default handling is performed.
+
+        If the setting is a string, it used as name of an lfun to call
+        in the interactive <user>, where <flag> is the echo-flag
+        passed to the input_to() statement.
+
+        If the setting is a closure, it is called with the same
+        arguments, and unbound lambda-closures being bound to
+        this_player() prior to execution.
+
+        <local> is a boolean flag: it is TRUE when input_to() was
+        called with the INPUT_NO_TELNET flag.
+
+        When set, the hook is called whenever the driver needs to
+        change the echo mode, thus you can negotiate about things that
+        are coupled with it, like LINEMODE or character-at-a-time.
+
+        IMPORTANT: If this hook is used, the control of all telnet
+        negotiation is transferred to the mudlib: all incoming negotiations
+        are passed to H_TELNET_NEG, and the sending of no-echo negotiations
+        is handled by this hook.
+
+HISTORY
+        LDMud 3.2.11/LDMud 3.3.593 added the <no_telnet> argument.
+
+SEE ALSO
+        hooks(C), telnet(C), telnet_neg(H)
diff --git a/doc/hook/no_ipc_slot b/doc/hook/no_ipc_slot
new file mode 100644
index 0000000..4d1b0fb
--- /dev/null
+++ b/doc/hook/no_ipc_slot
@@ -0,0 +1,22 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_NO_IPC_SLOT, value)
+
+        <value> being:
+
+          0
+          string <msg>
+
+DESCRIPTION
+        Optional hook specifying the message given to logins
+        rejected due to space limitations (MAX_PLAYER).
+        Hook setting has to be string.
+
+        If set to 0, the default message "Lpmud is full. Come back
+        later." is issued.
+
+HISTORY
+
+SEE ALSO
+        hooks(C)
diff --git a/doc/hook/notify_fail b/doc/hook/notify_fail
new file mode 100644
index 0000000..8a4bacf
--- /dev/null
+++ b/doc/hook/notify_fail
@@ -0,0 +1,33 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_NOTIFY_FAIL, value)
+
+        <value> being:
+
+          string <msg>
+          string <closure>(string entered_command, object cmd_giver)
+
+DESCRIPTION
+        Mandatory hook to issue the default message if an entered
+        command couldn't be parsed and no notify_fail() command is in
+        effect.  Hook setting can be a any closure, or a string.
+
+        If set to a string, it is the message returned to the
+        player.
+
+        If set to a closure, it is called with the command and the
+        command giver as arguments, and the result is used as failure
+        message. Lambda closures are bound to this_player() prior to
+        execution.
+
+        <cmd_giver> is the object which received the command in the
+        first place. It is usually identical with this_player(),
+        unless the H_MODIFY_COMMAND hook changed it.
+
+HISTORY
+        LDMud 3.2.7 added the new 'command_giver' argument.
+
+SEE ALSO
+        hooks(C), command(H), modify_command(H), modify_command_fname(H),
+        send_notify_fail(H)
diff --git a/doc/hook/print_prompt b/doc/hook/print_prompt
new file mode 100644
index 0000000..f864db7
--- /dev/null
+++ b/doc/hook/print_prompt
@@ -0,0 +1,28 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_PRINT_PROMPT, value)
+
+        <value> being:
+
+          void <name>(string prompt).
+          void <closure>(string prompt)
+
+DESCRIPTION
+        Optional hook to print the current command prompt. If this
+        hook is not set, the driver will just print the prompt to the
+        user.
+
+        The hook is called with the prompt string as single argument
+        and has to print the prompt, e.g. using write() or
+        binary_message().
+
+        If the hook is a string, it is the name of an lfun in the
+        command giver. If the hook is a closure, it is called
+        with the command giver as previous object.
+
+HISTORY
+        Introduced in LDMud 3.3.163.
+
+SEE ALSO
+        hooks(C), default_prompt(H)
diff --git a/doc/hook/regexp_package b/doc/hook/regexp_package
new file mode 100644
index 0000000..ae52e3f
--- /dev/null
+++ b/doc/hook/regexp_package
@@ -0,0 +1,23 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+        #include <sys/regexp.h>
+
+        set_driver_hook(H_REGEXP_PACKAGE, value)
+
+        <value> being an integer:
+          0
+          RE_PCRE
+          RE_TRADITIONAL
+
+DESCRIPTION
+        Optional hook to select the default regexp package to use
+        for regular expression functions.
+
+        If set to 0, the default package determined by the driver's
+        configuration/commandline options is used.
+
+HISTORY
+        Introduced in LDMud 3.3.595.
+
+SEE ALSO
+        hooks(C), default_prompt(H), invocation(D), regexp(C)
diff --git a/doc/hook/reset b/doc/hook/reset
new file mode 100644
index 0000000..23f1dea
--- /dev/null
+++ b/doc/hook/reset
@@ -0,0 +1,38 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_RESET, value)
+
+        <value> being:
+
+          void|int <closure> ( void )
+          void <name>(1)
+
+DESCRIPTION
+        Optional hook to reset an object.
+        Hook setting can be unbound lambda closures, or the name of
+        the function (static or public) to call in the object.
+
+        If the hook is a closure, it is bound to the object to be
+        reset and called with no argument.
+
+        If the result of this call is a positive number, it is used as
+        the interval to wait before the next reset().  If the result
+        is 0, the default interval computed from TIME_TO_RESET is
+        used.  If the result is a negative number, the object will not
+        be reset again, unless directed otherwise by set_next_reset().
+
+        If the hook is defined as the name of an lfun in the object,
+        it is called in the object with 1 as argument, and any result
+        is ignored.  In this call the previous_object() is the object
+        initiating the reset.  If the function does not exist, the
+        object won't be reset again.
+
+        Note that an object is only reset by call to this hook if it
+        has been used since the last reset.
+
+HISTORY
+        LDMud 3.2.10 allowed static functions to be given by name.
+
+SEE ALSO
+        hooks(C)
diff --git a/doc/hook/send_notify_fail b/doc/hook/send_notify_fail
new file mode 100644
index 0000000..7f61bb4
--- /dev/null
+++ b/doc/hook/send_notify_fail
@@ -0,0 +1,34 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_SEND_NOTIFY_FAIL, value)
+
+        <value> being:
+
+          void <name>(string msg, object msgobj, object orig_cmd_giver)
+          void <closure>(string msg, object msgobj, object orig_cmd_giver)
+
+DESCRIPTION
+        Optional hook to send the notify fail message, regardless
+        of how it was determined, to the player. If the hook is not
+        set, the message is delivered using tell_object() internally.
+        Hook setting can be a string or a closure.
+
+        If the hook is a string, it is the name of a (possibly static)
+        function to call in the current command giver. If the hook
+        is a closure, it is the function to be called. Lambda closures
+        are bound to the current command giver first.
+
+        The arguments to the call are:
+         - <msg> is the notify fail message to be delivered.
+         - <msgobj> is the object which set the message. It is 0 for
+           the default message.
+         - <orig_cmd_giver> is the object for which the original
+           command was first received. It is usually identical with
+           the current command giver this_player().
+
+HISTORY
+
+SEE ALSO
+        hooks(C), command(H), modify_command(H), modify_command_fname(H),
+        notify_fail(H)
diff --git a/doc/hook/telnet_neg b/doc/hook/telnet_neg
new file mode 100644
index 0000000..0f8b8c1
--- /dev/null
+++ b/doc/hook/telnet_neg
@@ -0,0 +1,72 @@
+SYNOPSIS
+        #include <sys/driver_hooks.h>
+
+        set_driver_hook(H_TELNET_NEG, value)
+
+        <value> being:
+
+          void|mixed <name>(int action, int option [, int * opts ] )
+          void|mixed <closure>(int action, int option [, int * opts ] )
+
+DESCRIPTION
+        Optional hook to specifiy how to perform a single telnet
+        negotiation.  Hook setting may be any closure or a string.  If
+        not set, most telnet options are rejected (read: only a very
+        minimal negotiation takes place).
+
+        The hook is called whenever the driver receives a demand for
+        option negotiation for any option the driver does not handle itself.
+        By default, the driver deals with the following options:
+            TELOPT_ECHO:      Echo option
+            TELOPT_SGA:       Suppress Go Ahead (nearly always on)
+            TELOPT_COMPRESS:  Mud client compression protocol (obsolete)
+            TELOPT_COMPRESS2: Mud client compression protocol V2
+
+        For all other telnet options negotiations, this hook is called.
+
+        The hook has then to perform the negotiation using the efun
+        binary_message().
+
+        Alternatively, if H_NOECHO is set, this hook is called for
+        _all_ telnet data received.
+
+        If the setting is a string, it used as name of an lfun to call
+        in this_player(). Closures are just called, with unbound
+        lambda-closures being bound to this_player() prior to
+        execution.
+
+        The hook is called for a 'DO/DONT/WILL/WONT <opt>' with the action
+        (DO/DONT/...) as the first, and <opt> as the second argument.
+
+        For example:, if the driver receives the sequence
+
+          IAC SB <opt> <opts>...
+
+        followed by IAC SB/SE,  the hook is called with 'SB' as first
+        argument, <opt> as second, and <opts> as an array of integers as
+        third argument.
+
+REMARKS
+        An incomplete list of telnet negotiations this hook is called
+        for includes the following:
+            SB:               Suboption negotiation
+            TELOPT_LINEMODE:  linemode
+            TELOPT_NAWS:      window size
+            TELOPT_TTYPE:     terminal type
+            TELOPT_TM:        timing mark
+            TELOPT_NEWENV:    remote environment variables
+            TELOPT_ENVIRON:   remote environment variables
+            TELOPT_XDISPLOC:  remote X display address
+            TELOPT_TSPEED:    terminal speed
+            TELOPT_BINARY:    binary data, needed for non-ASCII charsets
+            TELOPT_EOR:       TinyFugue prompt marker (together with EOR)
+
+            TELOPT_MSP:       Mud Sound Protocol
+            TELOPT_MXP:       Mud Extension Protocol
+            TELOPT_MSSP:      Mud Server Status Protocol
+            TELOPT_GMCP:      Generic Mud Communication Protocol
+
+HISTORY
+
+SEE ALSO
+        hooks(C), telnet(C), no_echo(H)
diff --git a/doc/infomails/info_ml15 b/doc/infomails/info_ml15
new file mode 100644
index 0000000..0c936bf
--- /dev/null
+++ b/doc/infomails/info_ml15
@@ -0,0 +1,74 @@
+Herzlich willkommen im Kreise der Magier!
+Hallo @WER1,
+
+ich nehme an, dass Dir Dein Sponsor bereits einige Hinweise und Tips
+und vor allen Dingen den weiteren Ablauf Deines Magierdaseins hier im MG
+erlaeutert hat. Trotzdem moechte ich Dir auch noch ein paar Hinweise
+geben, damit nichts schief geht.
+
+Zum einen findest Du zusaetzliche Informationen in den Hilfeseiten zu
+"magier" und "gesellenstueck". Lies Dir die einmal in Ruhe durch und wenn
+Du dazu noch weitere Fragen hast, kannst Du Dich gerne an Deinen Sponsor 
+wenden.
+
+Des weiteren hast Du momentan nur Leserechte in /doc, das ist das 
+Verzeichnis, in dem die gesamte Dokumentation des Morgengrauens
+abgelegt ist. Du kannst Dir die Dateien mit Hilfe des Befehls "man"
+anzeigen lassen. Eine Uebersicht ueber die Struktur der Dokumentation und
+die Themen der einzelnen Unterverzeichnisse verschafft Dir der Befehl
+"more /doc/README".
+Unter /doc/beispiele/ befinden sich ein paar Beispiele der Programmierung 
+mit LPC - auch wenn leider nicht alle auf dem aktuellsten Stand sind.
+
+Der Befehl "man <begriff>" durchsucht alle diese Verzeichnisse automatisch
+nach dem angegebenen Begriff, der z.B. eine Mudlib-Funktion sein kann.
+Wenn er eine passende Manpage gefunden hat, wird Dir diese angezeigt.
+Probier doch z.B. einfach mal "man AddExit" aus, um zu erfahren, wie Du
+in einem Raum einen Ausgang anlegst, oder schau mit "man P_KILL_MSG" nach,
+wie Du Deinem NPC beibringst, seinen Gegner auf der Ebene "Tod" angemessen
+zu verspotten. Auf diese Weise kannst Du Dir einen ersten Ueberblick ueber
+die Funktionalitaet und Arbeitsweise der Mudlib und des Drivers verschaffen.
+Wie immer gilt aber, dass Dein Sponsor, oder auch die anderen Magier Dir
+gerne weiterhelfen, wenn etwas unklar bleiben sollte. Scheue Dich bitte
+nicht, einfach jemanden zu fragen.
+
+Zum Ablauf Deines Gesellenstuecks moechte ich zunaechst nur soviel sagen,
+dass Du erst auf Magierlevel 20 ein eigenes Home-Verzeichnis bekommen wirst,
+in dem Du dann arbeiten kannst. Vorher musst Du den Erzmagiern, insbesondere
+dem fuer die Gesellenstuecke zustaendigen (wer das ist, bekommst Du mittels
+"hilfe erzmagier" heraus), Dein Konzept fuer dieses Gesellenstueck 
+erlaeutern. Sei dabei ruhig ein wenig ausfuehrlicher und schreib ein wenig
+etwas zu sammen. Falls Du ein neues Gebiet schreiben moechtest, ist eine 
+kleine ASCII-Karte als Gebietsueberblick immer gern gesehen.
+
+Ein wichtiger Hinweis zum Konzept: Sprich bitte rechtzeitig mit dem
+zustaendigen Regionsmagier der Region, die Dein GS aufnehmen soll, Deinem
+Sponsor und auch mit dem GS-EM Dein Gesellenstueck ab. Bitte teile uns auch 
+mit, wenn Du waehrend der Programmierung Aenderungen vornimmst. Je besser
+wir uns im Vorfeld absprechen, desto weniger Probleme treten bei der 
+Abnahme durch die beteiligten Instanzen auf. Es hat sich ausserdem gezeigt,
+dass man saemtliche (und damit meine ich wirklich _alle_) Absprachen 
+bezueglich des Konzepts sauber dokumentieren sollte, z.B. per Mail.
+
+Bei der Ausarbeitung eines Konzeptes ist Dir gerne Dein Sponsor oder 
+auch der Regionsmagier behilflich - jeder von denen hat selber schon
+ein GS-Konzept eingereicht und sollte etwas dazu sagen koennen. Falls
+Dir noch ein wenig die Ideen abgehen, schau doch einfach mal auf das
+Projektbrett in der Abenteurer-Gilde: dort sind haeufig Gesellenstueck-
+Projekte ausgeschrieben.
+
+Wenn Dein Konzept vorliegt und vom Umfang und Schwierigkeit her fuer 
+ausreichend befunden wurde, so wirst Du nach ca. 8 Tagen auf Magierlevel
+20 befoerdert.
+Wenn Du noch Fragen hast, Sorgen, Noete o.ae. so stehen Dir Dein Sponsor,
+jeder andere Magier und der GS-EM natuerlich auch gerne zur Verfuegung.
+
+Ich wuensche Dir im Namen der Magierschaft viel Spass beim Programmieren 
+und hoffe, dass Du schon bald eine Mail mit Deinem Konzept an die Erzmagier
+absenden wirst!
+
+Viele Gruesse, Dein Merlin.
+
+P.S.: Wenn Du magst, kannst Du auch gerne die Ebenen -magier und -lpc 
+      betreten, um dort ein wenig mitzulesen oder Deine eigenen Fragen
+      loszuwerden.
diff --git a/doc/infomails/info_ml20 b/doc/infomails/info_ml20
new file mode 100644
index 0000000..0f011a6
--- /dev/null
+++ b/doc/infomails/info_ml20
@@ -0,0 +1,83 @@
+Willkommen auf Magierlevel 20. :-)
+Hallo @WER1,
+
+Du bist gerade von mir auf Magierlevel 20 befoerdert worden. Das 
+bedeutet fuer Dich vor allem, dass Dein Konzept fuer ein Gesellenstueck
+das Wohlwollen der Erzmagier gefunden hat und angenommen wurde. Herzlichen
+Glueckwunsch erst einmal dazu! :-)
+
+Weiterhin wurde jetzt auch ein Home-Verzeichnis unter /players/@WER1
+angelegt, in dem Du die Dateien Deines Gesellenstuecks und anderes ablegen
+kannst. Unter /players/@WER1/workroom.c existiert jetzt auch Dein eigener
+Workroom, in dem Du Dich standardmaessig nach dem Einloggen materialisierst.
+
+Als kleine Hilfestellung fuer Deine Arbeit am Gesellenstueck moechten Dir
+die Erzmagier einige Tips mit auf den Weg geben, die Dir das Leben 
+hoffentlich erleichtern.
+
+1) Zur Programmierung:
+
+   Im Mud selbst kannst Du nur ueber den Zeilen-Texteditor "ed" etwas
+   programmieren. Hilfe zu diesem Werkzeug bekommst Du ueber "man ed"
+   und "man ed0..ed5". Als sinnvolle Alternative steht Dir ein FTP-
+   Zugang zur Verfuegung, ueber den Du die auf Deinem eigenen Rechner
+   geschriebenen Files ins Mud kopieren kannst. Hierbei kannst Du dann
+   Deinen eigenen Editor verwenden. Bitte achte aber darauf, dass Du
+   als Dateiformat das Unix-Format verwendest. Auch unter Windows 
+   beherrschen inzwischen die meisten Editoren dieses Dateiformat.
+
+   Um vernuenftig arbeiten zu koennen, solltest Du Dir das MGTool (zu
+   finden unter /obj/tools/MGtool) beschaffen (die Hilfe hierzu findest
+   Du dann mittels "xman"). Weiterhin sei Dir dringend die Verwendung des
+   Fehlerteufels (siehe "hilfe fehlerteufel") empfohlen, der Dir die
+   Fehlersuche stark erleichtert. Wie Du diese Objekte clonst, kann Dir
+   Dein Sponsor oder ein anderer Magier sicher zeigen.
+
+   Weiterhin solltest Du nun zusaetzlich noch die Ebenen -debug, 
+   -entwicklung und -warnungen einschalten, auf denen Du ueber auftretende
+   Bugs informiert wirst (nicht nur Deine eigenen, aber Du wirst Dich
+   damit sicher schnell zurechtfinden).
+
+   Was formale und auch inhaltliche Anforderungen an Deinen Code angeht,
+   lies Dir bitte "hilfe regionsleitfaden" durch, hier findest Du alles
+   wesentliche kompakt zusammengefasst. Wenn darueber hinaus spezielle
+   Fragen zu der Region bestehen, die Dein Gesellenstueck spaeter aufnehmen
+   soll, kannst Du gerne auch den Regionsmagier ansprechen. Du solltest 
+   aber auf jeden Fall davon ausgehen, dass dieser Dir nur sehr geringe
+   Abweichungen von den im Regionsleitfaden beschriebenen Standards zuge-
+   stehen wird, wenn ueberhaupt (insbesondere wird viel Wert auf eine 
+   sinnvolle Kommentierung Deines Codes gelegt).
+
+2) Zur Fertigstellung und Abnahme des Gesellenstuecks:
+
+   Der uebliche Ablauf ist der, dass der zustaendige Regionsmagier
+   (den Du schon von der Konzeptphase her kennen duerftest) Dein 
+   Gesellenstueck als erster abnimmt und seine Anmerkungen dazu gibt.
+   Wenn diese geklaert und umgesetzt sind, ist der GS-Erzmagier an der
+   Reihe, der Dein Werk nochmals durchsieht und evtl. weitere Kommentare
+   dazu aeussert. Wenn diese beiden Schritte erledigt sind, ist Dein
+   Gesellenstueck fast fertig fuer den Anschluss.
+
+   In der Regel ist jetzt auch der Zeitpunkt gekommen, dass Du zum
+   Vollmagier (Level 21) befoerdert werden kannst und Dein Code in
+   die Region kopiert wird, in der er angeschlossen werden wird.
+
+   Allerdings sei Dir ein Punkt jetzt schon ans Herz gelegt: Solltest
+   Du Objekte in Deinem Gesellenstueck bauen wollen, die von der Balance
+   genehmigt werden muessen (siehe hierzu zunaechst "man balance" und 
+   "man grenzwerte"), solltest Du den noetigen Antrag rechtzeitig stellen,
+   da die Erfahrung zeigt, dass solche Entscheidungen in der Regel nicht
+   von heute auf morgen getroffen werden koennen. 
+   Hilfestellung bei der Frage, was genehmigt werden muss, gibt die
+   Balance gerne auf Anfrage, ansonsten wird aber auch jeder erfahrene
+   Magier aushelfen oder zumindest einen Ansprechpartner vermittln koennen.
+
+Damit ueberlasse ich Dich nun Deiner Arbeit am GS. Wenn Du noch Fragen
+hast (was sicher der Fall sein wird), scheue Dich nicht, sie zu stellen, 
+ob auf einer der Magierebenen oder direkt Deinem Sponsor oder anderen 
+Magiern! Es wird sich sicher jemand finden, der Dir helfen kann oder der
+Dich zumindest auf die richtige Faehrte bringt.
+
+Viele Gruesse und viel Erfolg,
+Dein Merlin.
+
diff --git a/doc/infomails/info_ml21 b/doc/infomails/info_ml21
new file mode 100644
index 0000000..0013306
--- /dev/null
+++ b/doc/infomails/info_ml21
@@ -0,0 +1,32 @@
+Gratulation zur Befoerderung zum Vollmagier
+Hallo @WER1,
+
+ich bin's mal wieder, der Merlin. :-)
+
+Du bist ja jetzt auf Magierlevel 21 angekommen, das heisst, ich kann Dir
+auf diesem Wege zur erfolgreichen Abnahme Deines Gesellenstuecks 
+gratulieren! War ja auch eine Menge Arbeit, oder? ;-)
+
+Bevor Du jetzt aber freudestrahlend anschliessen kannst, moechte ich Dich
+auf einige Dinge hinweisen, die vor dem Anschluss erledigt werden muessen.
+Keine Sorge, das ist nicht allzuviel, und meist recht schnell erledigt.
+
+Als erstes wird sicherlich der Regionsmagier Deinen Code in seine Region
+kopieren (lasst bitte nichts davon in Deinem Home-Verzeichnis zurueck,
+das kann spaeter eine Menge Aerger verursachen). Der Code kann aber erst 
+angeschlossen werden, wenn die Forscherpunkte (FP), Zaubertrank-Fundorte
+(ZTs) und Erstkillstufenpunkte (EKs) beantragt und genehmigt sind
+(die hierfuer zustaendigen EMs sind in "hilfe erzmagier" aufgefuehrt).
+Du wirst hierfuer - je nach Zeitaufwand fuer die beteiligten EMs - eine
+gewisse Wartezeit vor dem Anschluss einkalkulieren muessen. In dieser 
+Zeit kannst Du ja schon einmal einen schoenen Artikel zur stilechten
+Ankuendigung in der MPA entwerfen.
+Weiterhin muessen natuerlich alle Balance-relevanten Objekte genehmigt sein.
+
+Wenn das alles erledigt ist, und damit Dein Werk anschlussfertig, wird
+Dich der Regionsmagier auf Magierlevel 25 befoerdern. Sobald das geschafft
+ist, vergiss nicht, mich zur Party einzuladen! :-)
+
+Liebe Gruesse,
+Dein Merlin
+
diff --git a/doc/infomails/info_ml25 b/doc/infomails/info_ml25
new file mode 100644
index 0000000..1b01a8b
--- /dev/null
+++ b/doc/infomails/info_ml25
@@ -0,0 +1,38 @@
+Du arbeitest jetzt an einer Region mit!
+Hallo @WER1,
+
+mit der Befoerderung auf Magierlevel 25 ist jetzt Dein Gesellenstueck
+endgueltig angeschlossen und wird sicher in Kuerze vielfachen Zuspruch
+von Spielern finden!
+
+Ich wuerde mich freuen, wenn Du auch nach dem Anschluss immer mal ein
+Auge auf Deinen Code werfen wuerdest, um (die gerade in der Anfangszeit
+recht haeufigen) Bugs zu beheben. Ich haette aber natuerlich auch
+ueberhaupt nichts dagegen, wenn Du noch mehr fuers Morgengrauen entwickeln
+wolltest. Wenn Du Ideen dafuer hast, dann sprich doch einfach mit einem
+Regionsmagier, in dessen Region Du ein Plaetzchen dafuer benoetigst! :-)
+
+An dieser Stelle sei Dir erneut der Hinweis auf sorgfaeltige
+Dokumentation Deines Konzepts und der Absprachen mit dem RM dringend ans
+Herz gelegt. Sowas hat ueberhaupt nichts mit Misstrauen Dir oder dem RM
+gegenueber zu tun, sondern einfach damit, dass man auf diese Weise 
+Missverstaendnissen vorbeugen kann - allein die Vorstellung, was ein
+"kleines" oder "groesseres" Gebiet sein soll, unterscheidet sich teils
+erheblich zwischen zwei Personen. (Uebrigens solltest Du fuer den Fall, 
+dass der fuer Deine Region zustaendige Regionsmagier einmal wechseln sollte,
+dem neuen RM Dein Konzept vorlegen, um sicherzugehen, dass dieser davon
+Kenntnis hat und ggf. seine Ansicht beruecksichtigen zu koennen.)
+
+Solltest Du Dich hingegen zu hoeherem berufen fuehlen, und gerne selbst
+eine Region als RM uebernehmen wollen, oder andere Aufgaben als Magier
+wahrnehmen, so kannst Du gerne einen Erzmagier ansprechen oder Dich direkt
+bewerben. Auch wenn man gerne anderes erzaehlt: die beissen alle nicht. ;-)
+
+Achso, eins noch: Wenn Du selbst einen Seher sponsorn moechtest, also
+diesen zum Magier machen, benoetigst Du Magierlevel 26 dafuer. Diesen
+kannst Du durch Befoerderung seitens Deines Regionsmagiers erreichen. 
+Sprich ihn doch einfach mal darauf an.
+
+Viele Gruesse,
+Dein Merlin.
+
diff --git a/doc/infomails/info_ml45 b/doc/infomails/info_ml45
new file mode 100644
index 0000000..6ffd4b8
--- /dev/null
+++ b/doc/infomails/info_ml45
@@ -0,0 +1,21 @@
+Willkommen im Kreis der Regionsmagier!
+Herzlichen Glueckwunsch @WER1!
+
+Ich freue mich, dass Du in den Kreis der Regionsmagier aufgenommen wurdest
+und das MorgenGrauen jetzt einen weiteren aktiven Magier zur Pflege der
+Regionen hat. :-)
+Um Dir die Arbeit zu erleichtern, haben Deine Kollegen haeufig gefragte
+Fragen bzw. haeufige Taetigkeiten eines RMs zusammengestellt. Ich
+empfehle Dir daher, dieses Howto zu lesen, Du findest wichtige Hinweise
+dort: 'man rm-howto'.
+Ebenfalls von Interesse ist fuer Dich sicherlich die Hilfeseite 
+"regionsmagier", welches einige weitere Informationen fuer Dich hat.
+Falls Du einmal Diskussionen fuehren willst (oder Fragen hast), die Du nur mit
+Deinen Regionsmagierkollegen (bzw. RM+) eroertern moechtest, kannst Du hierzu
+die MPA-Rubrik 'regionsmagier' benutzen.
+
+Und nun wuensche ich Dir viel Spass in Deinem neuen Amt!
+
+Liebe Gruesse,
+      Merlin
+
diff --git a/doc/lfun/.default b/doc/lfun/.default
new file mode 100644
index 0000000..d519f69
--- /dev/null
+++ b/doc/lfun/.default
@@ -0,0 +1,16 @@
+muster()
+
+FUNKTION:
+	type muster(...)
+	
+ARGUMENTE:
+	
+BESCHREIBUNG:
+
+RUECKGABEWERT:
+	
+BEMERKUNG:
+	
+BEISPIEL:
+
+SIEHE AUCH:
diff --git a/doc/lfun/.synonym b/doc/lfun/.synonym
new file mode 100644
index 0000000..77c92a5
--- /dev/null
+++ b/doc/lfun/.synonym
@@ -0,0 +1,14 @@
+A_CON QueryAttribute
+A_DEX QueryAttribute
+A_INT QueryAttribute
+A_STR QueryAttribute
+pathd SearchPath
+qpp QueryPossPronoun
+SP_NAME Defend
+SP_NO_ACTIVE_DEFENSE Defend
+SP_NO_ENEMY Defend
+SP_PHYSICAL_ATTACK Defend
+SP_RECURSIVE Defend
+SP_REDUCE_ARMOUR Defend
+SP_SHOW_DAMAGE Defend
+TestIgnoreExt TestIgnore
diff --git a/doc/lfun/AddAction b/doc/lfun/AddAction
new file mode 100644
index 0000000..23183ca
--- /dev/null
+++ b/doc/lfun/AddAction
@@ -0,0 +1,76 @@
+AddAction(L)
+FUNKTION:
+     varargs void AddAction(mixed fun, mixed cmd, int flag, int lvl);
+
+DEFINIERT IN:
+     /std/player/command.c
+
+ARGUMENTE:
+     fun	zu rufende Methode im Spieler oder eine Closure
+     cmd	ausloesendes Kommandoverb
+     flag	unscharf ausfuehren
+     lvl	ab welchem (Magierlevel) funktioniert das Kommando
+
+BESCHREIBUNG:
+     Dem Spieler wird ein neues Kommando definiert. Dieses kann eine Methode
+     in ihm sein, so wie bei allen Spielerkommandos ueblich, kann aber auch
+     eine Closure (Lfun-Closure oder Lambda) enthalten.
+
+     Mittels "flag" kann man die Kommandoerkennung unscharf halten, d.h. wie
+     bei AddCmd(L) und add_action(E) wird ein 'cmd' bei 'flag = 1' auch
+     schon von Praefix-Strings (hier ohne Leerzeichen) getriggert:
+     AddAction([...], "muh", 1, 0) wird zB auch von 'muhtens' oder 'muh4'
+     ausgeloest.
+
+     Mit "lvl" begrenzt man die Ausfuehrbarkeit. Spieler haben ein
+     Magierlevel von 0, Seher von 1.
+
+     Das Kommando wird in P_LOCALCMDS eingetragen. Diese Property wird
+     nicht gespeichert! Effektiv kann man mit AddAction() ein kommando-
+     gebendes Objekt im Spieler einsparen.
+
+BEMERKUNGEN:
+     - es gibt _noch_ kein RemoveAction! Per Hand in P_LOCALCMDS editieren
+       kann zu ernsten Fehlern fuehren.
+     - echte Spielerkommandos kann man damit _nicht_ ueberschreiben,
+       ein AddAction(...,"sag",1,0); funktioniert nicht
+     - ein generelles AddAction(...,"",1,0); geht nicht
+
+BEISPIELE:
+     ...
+     this_player()->AddAction(symbol_function("zeige_mysterium",
+                                              find_object(".../mystzeiger")),
+			      "knorfula",0,0);
+     write(break_string("Wann immer du jetzt das Kommando \"knorfula\" "
+			"eingibst, werden dir Mysterien enthuellt!",78));
+     ...
+
+     // im Objekt "knorfula" ...
+     int zeige_mysterium(string str) {
+       string myst;
+       myst=environment(TP)->QueryMysterium(str);
+       if(myst) {
+         write("Du hast ein Mysterium entdeckt!\n");
+	 write(break_string(myst,78));
+	 say(break_string(
+		TP->Name(WER)+" scheint nach kurzer Konzentration etwas "
+		"entdeckt zu haben!",78));
+       } else {
+         write(break_string(
+		"Leider entdeckst du trotz deiner magischen Faehigkeit "
+		"kein Mysterium in deiner Umgebung.",78));
+	 say(break_string(
+		TP->Name(WER)+" konzentriert sich sichtbar, sieht dann "
+		"jedoch etwas enttaeuscht aus.",78));
+       }
+       return 1;
+     }
+
+SIEHE AUCH:
+			P_LOCALCMDS
+     Fehlermeldungen:	notify_fail(E), _notify_fail(E)
+     Argumentstring:	query_verb(E), _unparsed_args(L)
+     Sonstiges:		replace_personal(E), enable_commands(E)
+     Alternativen:	AddCmd(L), add_action(E)
+
+24. Maerz 2004 Gloinson
diff --git a/doc/lfun/AddAdjective b/doc/lfun/AddAdjective
new file mode 100644
index 0000000..6b58101
--- /dev/null
+++ b/doc/lfun/AddAdjective
@@ -0,0 +1,39 @@
+AddAdjective()
+
+FUNKTION:
+     void AddAdjective(string|string* adj);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     adj
+          String oder Array von String mit den Adjektiven.
+
+BESCHREIBUNG:
+     Zusaetzlich zu den mit AddId() vergebenen Bezeichnern laesst sich mit
+     der Vergabe von Adjektiven die Ansprechbarkeit eines Objektes erhoehen.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Die Adjektive werden nicht dekliniert, man muss also fuer jeden
+     sinnvollen Fall ein Adjektiv uebergeben.
+
+BEISPIELE:
+
+       AddId( ({ "zettel", "blatt" }) );
+       AddAdjective( ({ "kleinen", "kleines" }) );
+
+     Das Objekt reagiert jetzt auf "zettel", "kleinen zettel", "blatt",
+     "kleines blatt" sowie auf die (sprachlich nicht ganz so korrekten)
+     Konstruktionen "kleines zettel", "kleinen blatt", "kleines kleinen
+     zettel", ...
+
+SIEHE AUCH:
+     AddId(), RemoveAdjective() id(), present(), /std/thing/description.c
+
+----------------------------------------------------------------------------
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AddAmount b/doc/lfun/AddAmount
new file mode 100644
index 0000000..3be8e3f
--- /dev/null
+++ b/doc/lfun/AddAmount
@@ -0,0 +1,25 @@
+AddAmount()
+
+FUNKTION:
+     void AddAmount(int menge);
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     menge
+          Die Menge, die der Unit hinzugefuegt werden soll (kann auch
+          negativ sein).
+
+BESCHREIBUNG:
+     menge wird zur aktuellen Menge hinzugezaehlt. Sollte das Ergebnis 0
+     werden, wird die Unit in absehbarer Zeit zerstoert.
+
+RUeCKGABEWERT:
+     keiner
+
+SIEHE AUCH:
+     /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:15:50 1996 by Wargon
diff --git a/doc/lfun/AddClass b/doc/lfun/AddClass
new file mode 100644
index 0000000..f97730c
--- /dev/null
+++ b/doc/lfun/AddClass
@@ -0,0 +1,28 @@
+AddClass()
+FUNKTION:
+     void AddClass(string|string* class);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     string/string* class	- String oder Stringarray der Klasse(n)
+
+BESCHREIBUNG:
+     Dem Objekt werden weitere Klassifizierungen hinzugefuegt.
+
+     Die allgemein verfuegbaren Klassen sind unter /sys/class.h definiert.
+
+BEMERKUNGEN:
+     Vor dem 7. Nov 2012 pruefte is_class_member() auch die P_IDS. Damit war
+     zB ein AddId("daemon") gleichbedeutend einem AddClass(CL_DEMON).
+
+     Bitte prueft eure Objekte (NPCs, Krankheiten, Gifte, ...) auf korrekte
+     Klassifizierung.
+
+SIEHE AUCH:
+     RemoveClass(), is_class_member()
+     P_CLASS
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AddCmd b/doc/lfun/AddCmd
new file mode 100644
index 0000000..aeea8db
--- /dev/null
+++ b/doc/lfun/AddCmd
@@ -0,0 +1,210 @@
+AddCmd(L)
+FUNKTION:
+    varargs void AddCmd(mixed cmd, mixed func, [mixed flag, [mixed id]]);
+
+DEFINIERT IN:
+    /std/thing/commands.c
+
+ARGUMENTE:
+    cmd
+       Verben, auf die reagiert werden soll
+       ODER
+       Regel mit Triggerverb und noetigen Keywords/Synonymen
+    func
+       Funktionsname im selben Objekt oder Closure (Funktionspointer)
+    flag (optional)
+       Unscharfe Ausfuehrung == 1
+       ODER
+       Fehlermeldungen bei Nutzung von Regeln
+    id (optional)
+       eine ID, ueber die das Kommando eindeutig wieder geloescht
+       werden kann
+
+BESCHREIBUNG:
+    Wenn ein Spieler im Einflussbereich des Objektes das Verb benutzt,
+    wird die entsprechende Funktion im Objekt aufgerufen:
+    - die Verben sollten Imperative sein
+    - die Funktion muss 1 fuer ERFOLG (und FPs!) und 0 sonst zurueckgeben
+      (sonst werden evtl. weitere Funktionen mit diesem Kommandoverb gerufen)
+    - innerhalb der Funktionen koennen Fehlermeldungen fuer den totalen
+      Misserfolg des Kommandos mit notify_fail gesetzt werden
+      (anstatt "Wie bitte?")
+
+    AddCmd ist ein dynamischer Ersatz fuer add_action - im Gegensatz
+    zu add_action koennen auch ohne erneuten Aufruf der init() neue
+    Kommandos hinzugefuegt werden.
+
+    AddCmd kann das Leben einfacher machen mit:
+    ### REGELN: ###
+      Bei komplexen Syntaxen kann ein String angegeben werden, der die
+      _notwendigen_ (nicht die erlaubten!) Schluesselworte und deren
+      zulaessige Synonyme beschreibt. Damit kann man sich einen grossen
+      Teil eigener Auswertung ersparen.
+
+      Nur wenn in richtiger Reihenfolge aus JEDER der durch & getrennten
+      Synonymgruppen ein Wort im Spielerkommando enthalten ist, wird
+      die zugehoerige Funktion ausgefuehrt.
+
+      Trenner sind: | fuer Alternativen
+                    & fuer Konjunktionen
+
+      Beispiel:
+        "ritz|ritze|schnitz|schnitze&mit&messer|schnitzmesser&"
+        "herz|herzchen&rinde|baumrinde"
+      wuerde z.B. durch
+        "ritz mit dem Messer ein Herz in die Rinde des Baumes"
+        "schnitz mit Messer Herzchen Baumrinde"
+        "schnitz mit meinem Messer Herzchen in die harte Baumrinde"
+      erfuellt werden.
+
+      Spezialregelteile sind:
+      - @PRESENT: entspricht einem Objekt in Inv oder Env des Spielers
+      - @ID:      entspricht der ID des kommandobesitzenden Objektes
+                  (wo die Kommandomethode definiert ist, ist noch unwichtig)
+      - @PUT_GET_DROP, @PUT_GET_TAKE, @PUT_GET_NONE:
+                  entsprechend den Filteroptionen fuer find_obs()
+      ACHTUNG: Zusaetzliche Ziffern in Verbindung mit den @-Spezialregeln
+               sind schlecht. @-Regeln versuchen gierig, Objekte exakt im
+               Inventory zu matchen ("objekt 3" anstatt "objekt") und miss-
+               interpretieren daher zB die 4 in "stopf objekt 3 in loch 4" als
+               Teil des Objekt-ID-Strings.
+               Interna: 3 Substrings fuer @PRESENT/@ID ("gruener kristall 2")
+                        5 fuer @PUT... ("kristall 2 in beutel 3")
+
+    ### FEHLERMELDUNGEN (bei Anwendung von Regeln): ###
+      Als dritter Parameter koennen auch Fehlermeldungen fuer jeweils
+      fehlende Synonymgruppen (ausser der ersten - den Kommandoverben)
+      angegeben werden. Sie werden in derselben Reihenfolge (!) wie die
+      Synonymgruppen angegeben.
+
+      Mit nicht von Spielern erfuellbaren Regeln und ^-Fehlermeldungen
+      kann man auch ohne Ausfuehrung einer Funktion Texte an Spieler
+      und Umgebung ausgeben. Siehe dazu AddCmd_bsp.
+
+      Trenner sind: | zum Trennen der einzelnen Fehlermeldungen
+                    ^ um
+                       - die Auswertung (ab dieser Fehlermeldung!) mit
+                         "return 1;" zu beenden und
+                       - eine write^say-Meldung zu trennen und
+                       - (fuer funktionslose AddCmd auch FPs zu vergeben!)
+
+      Beispielfehlermeldungen fuer obige Regel:
+        "Womit willst Du schnitzen?|Was willst Du schnitzen?|"
+        "Wohinein willst Du das schnitzen?"
+
+      Es koennen in den Fehlermeldungen folgende Platzhalter benutzt
+      werden:
+      - @verb (ersetzt durch query_verb() ohne beendendes 'e')
+      - @VERB (ersetzt durch capitalize(query_verb()) ohne beendendes 'e')
+      - @WERx, @WESSENx, @WEMx, @WENx: siehe alles aus replace_personal()
+        - @WE..1 ist immer der aktive Spieler
+        - alle folgenden sind die matchenden Parameter der Spielereingabe
+          - (x-1)<=Fehlermeldung (da x=1 Spieler und
+                                  (x-1)>Fehlermeldungsobjekt nicht existent)
+
+      Ausfuehrungsbeispiel:
+        AddCmd("ritz|ritze|schnitz|schnitze&mit&messer|schnitzmesser&"
+               "herz|herzchen&rinde|baumrinde",#'fun,
+              "Willst Du mit etwas @verben?|Womit willst du @verben?|"
+              "Was willst du mit dem @WEM3 @verben?|"
+              "Wohinein willst Du das @WEN4 schnitzen?");
+        1. "ritze" == "Willst Du mit etwas ritzen?"
+        2. "schnitz mit" == "Womit willst du schnitzen?"
+        3. "ritz mit messer" == "Was willst du mit dem messer ritzen?"
+        4. "ritze mit dem messer ein herz" ==
+             "Wohinein willst Du das herz schnitzen?"
+        5. "ritze mit dem messer ein herzchen in die baumrinde"
+             == Erfolg!
+
+    ### UNSCHARFER AUSFUEHRUNG: ###
+      Bei unscharfer Ausfuehrung wird die zugehoerige Methode auch dann
+      ausgefuehrt, wenn das verwendete Verb ein Superstring ist und
+      bisher noch nicht behandelt wurde.
+      Dieses Verhalten sollte nur beim generellen Abfangen von
+      Befehlsgruppen benutzt werden und ist ansonsten veraltet. Es
+      entsprich add_action("fun","kommando",1).
+
+
+      Beispiel:
+        1. AddCmd("klett","fun",1);
+        2. AddCmd("kletter|klettere&hoch",#'fun2,"Wohin klettern?");
+
+        a) "klett"
+        b) "kletter"
+        c) "klettere hoch"
+
+        Ausgefuehrte Funktion bei: 1a, 1b, 1c; 2c
+       (1 wuerde also immer ausgefuehrt)
+        Fehlermeldung bei: 2b ("Wohin klettern?")
+
+BEMERKUNGEN:
+    - Methoden der put_and_get (nimm/nehme) sollten so nicht versucht
+      werden zu ueberschreiben - dazu sind invis Container da
+    - benutzt man fuer <function> eine Closure, kann man die Fkt. auch
+      protected oder private deklarieren _und_ sie kann in einem
+      anderen Objekt sein
+    - bei Regeln wird an die ggf. gerufene Methode als zweiter Parameter
+      ein Array der erfuellenden Eingabeteile uebergeben:
+      "steck&@PRESENT&in&loch" bei Erfuellung -> ({<Objekt>,"in","loch})
+      - bei Nutzung von @PUT_GET_XXX koennen die Parameter wiederum
+        Arrays sein ("jede Hose" -> mehrere gueltige Objekte)
+    - juengere AddCmd ueberschreiben aeltere, bzw. werden vor diesen
+      ausgewertet
+    - @PUT_GET_XXX kosten sehr viel Auswertungszeit
+
+BEISPIELE (SIEHE AUCH ADDCMD_BSP):
+    // SIMPEL: ganz simpel, beinahe wie add_action
+    AddCmd("befiehl","action_befehlen");
+    ...
+    int action_befehlen(string str) {
+     if(!str || !strlen(str))
+      // Fehlermeldung, falls gar keine Funktion 1 dafuer zurueckgibt
+      notify_fail("Was willst du befehlen?!\n");
+     else {
+      write("Du befiehlst \""+str+"\", und alle folgen!\n");
+      say(TP->Name(WER)+" befiehlt \""+str+"\", und du folgst!\n");
+      return 1;  // ERFOLG - Abbruch der Kommandoauswertung
+     }
+     return 0;  // MISSERFOLG - Fehlermeldung oben gesetzt
+    }
+
+    // SIMPEL .. weitere Beispiele
+    AddCmd(({"kletter","klettere"}),"action_klettern" );
+    AddCmd(({"renn","renne"}),#'action_rennen);
+
+    // REGELN: eine komplexere Regel
+    AddCmd("loesch|loesche|ersticke&feuer|brand|flammen&decke|wolldecke",
+           "action_loeschen",
+           "Was willst du loeschen?|Womit willst du loeschen?");
+
+    // REGELN: mit Platzhaltern im Fehlerstring
+    AddCmd("spring|springe|huepf|huepfe&von|vom&baum|ast|eiche",
+           #'action_huepfe,
+           "Willst du von etwas @verben?|Von wo willst du @verben?");
+
+    // SCHLECHT: eine unscharfe Regel - sie sollten eine Ausnahme sein (!)
+    AddCmd("kletter","fun_klettern",1);
+
+    // FALSCH: sehr schlecht, kein Imperativ verwendet
+    // ausserdem sollte man fuer solche Syntaxen AddReadDetail benutzen
+    AddCmd("lese","eval_lesen");
+
+    // SIMPLE REGEL OHNE METHODE
+    // mit Regeln kann man auch Aktivitaeten im Raum erlauben, ohne eine
+    // Funktion aufrufen zu muessen: die letzte Regel ist fuer Spieler
+    // unmoeglich zu erfuellen, die dazugehoerige Fehlermeldung wird mit
+    // dem ^ (write-Flag) versehen und entsprechend an den Spieler
+    // (und den Raum (hinter dem ^)) ausgegeben
+    AddCmd("spring|springe&herunter|runter&\n\bimpossible",0,
+           "Wohin oder wovon willst Du springen?|"
+           "Du springst vom Baum und kommst hart auf.^"
+           "@WER1 springt vom Baum und kommt hart auf.");
+
+SIEHE AUCH:
+    AddCmd_bsp, RemoveCmd(L), init(E)
+    Fehlermeldungen: notify_fail(E), _notify_fail(E)
+    Argumentstring: query_verb(E), _unparsed_args(L)
+    Sonstiges:  replace_personal(E), enable_commands(E)
+    Alternativen: AddAction(L), add_action(E)
+
+30. Aug 2013 Gloinson
diff --git a/doc/lfun/AddCmd_bsp b/doc/lfun/AddCmd_bsp
new file mode 100644
index 0000000..edb8d98
--- /dev/null
+++ b/doc/lfun/AddCmd_bsp
@@ -0,0 +1,320 @@
+ADDCMD() - BEISPIELE
+FUNKTION
+    varargs void AddCmd(mixed cmd, mixed func, mixed flag);
+
+BEMERKUNGEN
+    Die hier aufgefuehrten Komplexbeispiele sind zum Verstaendnis gedacht,
+    daher fuehren sie oft Alternativen auf. Die letzte Variante ist dann
+    jeweils diejenige, welche am leichtesten das Problem loesen koennte.
+    Falls die einem zu komplex ist, hilft vielleicht die vorletzte.
+
+BEISPIELE
+    // SIMPEL: ganz simpel, beinahe wie add_action
+    AddCmd("befiehl","action_befehlen");
+    ...
+    int action_befehlen(string str) {
+     if(!str || !strlen(str))
+      // Fehlermeldung, falls gar keine Funktion 1 dafuer zurueckgibt
+      notify_fail("Was willst du befehlen?!\n");
+     else {
+      write("Du befiehlst \""+str+"\", und alle folgen!\n");
+      say(TP->Name(WER)+" befiehlt \""+str+"\", und du folgst!\n");
+      return 1;		// ERFOLG - Abbruch der Kommandoauswertung
+     }
+     return 0;		// MISSERFOLG - Fehlermeldung oben gesetzt
+    }
+
+    // SIMPEL .. weitere Beispiele
+    AddCmd(({"kletter","klettere"}),"action_klettern" );
+    AddCmd(({"renn","renne"}),#'action_rennen);
+
+    // REGELN: eine komplexere Regel
+    AddCmd("loesch|loesche|ersticke&feuer|brand|flammen&decke|wolldecke",
+           "action_loeschen",
+           "Was willst du loeschen?|Womit willst du loeschen?");
+
+    // REGELN: mit Platzhaltern im Fehlerstring
+    AddCmd("spring|springe|huepf|huepfe&von|vom&baum|ast|eiche",
+           #'action_huepfe,
+           "Willst du von etwas @verben?|Von wo willst du @verben?");
+
+    // SCHLECHT: eine unscharfe Regel - sie sollten eine Ausnahme sein (!)
+    AddCmd("kletter","fun_klettern",1);
+
+    // FALSCH: sehr schlecht, kein Imperativ verwendet
+    // ausserdem sollte man fuer solche Syntaxen AddReadDetail benutzen
+    AddCmd("lese","eval_lesen");
+
+    // SIMPLE REGEL
+    static int action_jump(string str);        // Prototype (wegen closure)
+    ...
+    AddCmd("spring|springe|huepf|huepfe&von&baum|ast",#'action_jump,
+           "Willst Du von etwas @verben?|Wovon willst Du @verben?");
+    ...
+    static int action_jump(string str) {
+      write(break_string("Du springst vom Baum und kommst hart auf!",78));
+      this_player()->move((XXXROOM+"boden"), M_GO, 0,
+                          "springt unelegant vom Baum","faellt vom Baum");
+      this_player()->Defend(random(100),({DT_BLUDGEON}),([SP_RECURSIVE:1]),
+                            this_object());
+      return 1;
+    }
+
+    // SIMPLE REGEL OHNE METHODE
+    // mit Regeln kann man auch Aktivitaeten im Raum erlauben, ohne eine
+    // Funktion aufrufen zu muessen: die letzte Regel ist fuer Spieler
+    // unmoeglich zu erfuellen, die dazugehoerige Fehlermeldung wird mit
+    // dem ^ (write-Flag) versehen und entsprechend an den Spieler
+    // (und den Raum (hinter dem ^)) ausgegeben
+    AddCmd("spring|springe&herunter|runter&\n\bimpossible",0,
+           "Wohin oder wovon willst Du springen?|"
+           "Du springst vom Baum und kommst hart auf.^"
+           "@WER1 springt vom Baum und kommt hart auf.");
+
+## Komplexbeispiel: Regeln mit Fehlermeldungen ##
+ ## Variante 1, OHNE REGELN ##
+    // bei Nichtverwendung von Regeln muss man Parameter selbst auswerten
+    AddCmd(({"bohr","bohre"}),#'action_bohren);
+    ...
+    private static int action_bohren(string str) {
+      string *tmp;
+      notify_fail("Wo willst (etwas) Du bohren?\n");
+      if(!str) return 0;       // Tja, keine Argumente ...
+      tmp=explode(str," ");    // nach " " in Argument-Array aufspalten
+      if((i=member(tmp,"loch"))>=0) { // aha, ab jetzt uebernehmen wir :)
+       if((j=member(tmp[(i+1)..],"in"))<0 &&
+          (j=member(tmp[(i+1)..],"durch"))<0)
+         write("Willst Du das Loch in etwas bohren?\n");
+        else if((i=member(tmp[(j+1)..],"boden"))<0 &&
+                (i=member(tmp[(j+1)..],"erde"))<0)
+         write("In/Durch was willst du das Loch bohren?\n");
+        else {
+         write("Du bohrst ein Loch in den Boden.\n");
+         say(this_player()->Name(WER)+" bohrt ein Loch in den Boden.\n");
+        }
+        return 1;      // "bohre loch" war so eindeutig, dass nur diese
+                       // Methode gemeint sein konnte, also brechen wir die
+                       // weitere Auswertung auf jeden Fall ab (und geben
+                       // eine write-Fehlermeldung)
+      } // end if(..."loch")
+      return 0;        // "bohre" allein muss nicht diese Methode meinen,
+                       // also nur obige notify_fail()-Meldung, falls
+                       // sich nach dieser Methode gar keine sonst
+                       // angesprochen fuehlt
+    } // end fun
+
+ ## Variante 1a, OHNE REGELN ##
+    // prinzipiell koennte die Methode action_bohren auch so
+    // aussehen, ist aber nicht ganz so flexibel:
+    private static int action_bohren(string str) {
+     string tmp;
+     if(!str || (sprintf(str,"loch in erde%s",tmp)!=1 &&
+                 sprintf(str,"loch durch erde%s",tmp)!=1 &&
+                 sprintf(str,"loch in boden%s",tmp)!=1 &&
+                 sprintf(str,"loch durch boden%s",tmp)!=1))
+      notify_fail("Willst Du in irgendwas ein Loch bohren?\n");
+     else {
+      ...
+      return 1;
+     }
+     return 0;
+    }
+
+ ## Variante 2, MIT REGEL ##
+    // das gleiche in etwa mal als einfache Regel
+    AddCmd("bohr|bohre&loch&in|durch&erde|boden",#'action_bohren,
+           "Was willst du (wohin) bohren?|"
+           "Willst du das Loch in etwas bohren?|"
+           "Wohin willst du das Loch bohren?");
+    ...
+    private static int action_bohren(string str, mixed *param) {
+     write("Du bohrst ein Loch in den Boden.\n");
+     say(this_player()->Name(WER)+" bohrt ein Loch in den Boden.\n");
+     ...
+     return 1;
+    }
+
+ ## Variante 3, MIT REGEL UND FEHLERMELDUNG ##
+    // und nun mit Fehlermeldungen mit Ersetzungen, so dass wir mehr
+    // auf die Eingaben des Spielers eingehen
+    AddCmd("bohr|bohre&loch&in|durch&erde|boden",#'action_bohren,
+           "Was willst du (wohin) @verben?|"
+           "Willst du das Loch in etwas @verben?|"
+           "@WER3 was willst du das Loch @verben?");
+    ...
+    private static int action_bohren(string str, mixed *param) ...
+
+ ## Variante 4, MIT REGEL, FEHLERMELDUNG UND RETURN 1 ##
+    // in Variante 1 kam sinnvollerweise sehr frueh der Abbruch mit
+    // "return 1;" und die Ausgabe von write-Fehlermeldungen,
+    // das koennen wir auch
+    AddCmd("bohr|bohre&loch&in|durch&erde|boden",#'action_bohren,
+           "Was willst du (wohin) @verben?|"
+           "Willst du das Loch in etwas @verben?^|"
+           "@WER3 was willst du das Loch @verben?^");
+    ...
+    private static int action_bohren(string str, mixed *param) ...
+
+ ## Variante 5, MIT REGEL, FEHLERMELDUNG, RETURN 1, OHNE FUN ##
+    // und falls in action_bohren() nichts ausser Ausgaben passiert, koennen
+    // wir uns die auch ganz sparen indem wir eine nichterfuellbare Regel
+    // samt Fehlermeldung bauen
+    AddCmd("bohr|bohre&loch&in|durch&erde|boden&\nimpossible",0,
+           "Was willst du (wohin) @verben?|"
+           "Willst du das Loch in etwas @verben?^|"
+           "@WER3 was willst du das Loch @verben?^|"
+           "Du @verbst ein Loch @WER3 den Boden.^@WER1 @verbt "
+           "ein Loch @WER3 den Boden.");
+
+   --- Ende Komplexbeispiel Regeln mit Fehlermeldungen ---
+
+## Komplexbeispiel: Spezialregeln @PRESENT und @ID ##
+ ## Variante 1, OHNE REGELN ##
+    // oft agieren Kommandos auf Objekten im Raum, diese muessen dabei per
+    // present() identifiziert werden:
+    // Beispiel ist ein Geldautomat (den man besser mit einem Container
+    // mit PreventInsert() basteln sollte)
+    AddCmd(({"stopf","stopfe"}),#'action_stopf);
+    ...
+    private static int action_stopf(string str) {
+     string tmp,tmp2;
+     object o;
+
+     if(str && (sprintf("%s in automat%s",tmp,tmp2)==2 ||
+                sprintf("%s in geldautomat%s",tmp,tmp2)==2 ||
+                sprintf("%s in bankomat%s",tmp,tmp2)==2) {
+      o=present(tmp,this_player());
+      if(o) {
+       if(o->QueryProp(...)) {
+        write(break_string(
+         "Du stopfst "+o->name(WEN,1)+" in den Automaten.",78));
+        say(...);
+       } else {
+        write(break_string(
+         "Du versuchst "+o->name(WEN,1)+" in den Automaten zu stopfen, "
+         "aber "+o->QueryPronoun(WER)+" passt nicht hinein.",78));
+        say(...);
+       }
+      } else {
+       write("Was willst du in den Automaten stopfen?\n");
+       say(....);
+      }
+      return 1;
+     }
+     notify_fail("Was willst du wohin stecken?\n");
+     return 0;
+    }
+
+ ## Variante 2, MIT REGEL ##
+    // einerseits koennen wir das Finden von Objekten in Inv und Env
+    // integrieren und uns andererseits das Aufzaehlen aller IDs des
+    // Automaten ersparen
+    AddCmd("steck|stecke&@PRESENT&in&@ID",#'action_stopf,
+           "Was willst du wohin stopfen?|"
+           "Willst du @WEN2 in etwas stopfen?|"
+           "Wohinein willst du @WEN2 stopfen?");
+    ...
+    // dabei werden wie immer die gefunden Matches als Parameterarray
+    // uebergeben ... und die @PRESENT und @ID als Objekte!
+    private static int action_stopf(string str, mixed *param) {
+     if(param[0]->QueryProp(...)) {
+      write(break_string(
+       "Du stopfst "+param[0]->name(WEN,1)+" in den Automaten.",78));
+      say(...);
+     } else {
+      write(break_string(
+       "Du versuchst "+param[0]->name(WEN,1)+" in den Automaten zu "
+       "stopfen, aber "+param[0]->QueryPronoun(WER)+" passt nicht "
+       "hinein.",78));
+      say(...);
+     }
+     return 1;
+    }
+
+   --- Ende Komplexbeispiel Spezialregeln @PRESENT und @ID  ---
+
+## Komplexbeispiel: gleiches Verb, mehrere Regeln ##
+ // Das Problem mehrerer Regeln fuer ein Kommandoverb besteht darin, dass
+ // letztlich nur eine der Fehlermeldungen zum Tragen kommt - welche
+ // genau ist etwas vage.
+ // Dabei kann man sich auf eines verlassen: juengere AddCmd werden
+ // zuerst ausgewertet. Wenn sich das aendert, tretet euren EM.
+
+ ## Problem 1: Mehrere Regeln weil mehrere Zwecke ##
+    ## Variante 1 - GLEICHLAUTENDE FEHLERMELDUNG
+    // fuer alles wird eine identische Fehlermeldung gesetzt, das ist
+    // natuerlich nicht sehr flexibel oder schoen
+    AddCmd("kriech|krieche&hoch|hinauf|hinaus|heraus|raus",#'result_kriech,
+           "Wohin willst Du kriechen?");
+    AddCmd("kriech|krieche&nach&oben",#'result_kriech,
+           "Wohin willst Du kriechen??|Wohin willst Du kriechen?");
+    AddCmd("kriech|krieche&aus&loch|grube|falle",#'result_kriech);
+           "Wohin willst Du kriechen?|Wohin willst Du kriechen?");
+
+    // oder man versucht eine bessere Regel zu schaffen, was hier durch
+    // die Moeglichkeit von zwei oder drei Parameter unmoeglich ist
+
+    ## Variante 2 - EIGENE AUSWERTUNG
+    // es bietet sich also eigene Weiterauswertung an, was durch die
+    // Uebergabe der getriggerten Verben erleichtert wird:
+    AddCmd("kriech|krieche&hoch|hinauf|hinaus|heraus|raus|aus|nach",
+           #'result_kriech,
+           "Wohin willst Du kriechen?");
+    ...
+    static int result_kriech(string str, mixed *extra) {
+      if(member(extra,"aus")>=0 &&
+         !sizeof(({str}),"*.\\<(hoehle|grube|falle)\\>.*"))
+       notify_fail("Woraus willst Du kriechen?\n");
+      else if(member(extra,"nach")>=0 && strstr(str,"oben")<0)
+       notify_fail("In welche Richtung willst Du kriechen?\n");
+      else if(this_player()->QueryAttribute(A_DEX)>10 ||
+              member(holding_root,this_player())) {
+        write("Du kriechst mit Muehe heraus.\n");
+        this_player()->move((XXXROOM+"draussen"), M_GO, 0,
+                            "kriecht mit Muehe aus der Grube",
+                            "kriecht aus einer Grube");
+        return 1;
+      } else
+        write("Du bist zu ungeschickt, halt Dich irgendwo fest.\n");
+        return 1;
+      }
+      return 0;
+    }
+    // (ob sich der Aufwand fuer diese Beispielsyntax lohnt ist fraglich)
+
+ ## Problem 2: mehrere Regeln, weil optionale Parameter ##
+    // Manchmal will man optionale Parameter erlauben, die aber eine
+    // Wirkung zeigen sollen:
+    AddCmd("schlag|schlage&@ID&hart",#'action_schlag_hart,
+           "Was oder wen willst du @verben?|"
+           "Wie willst du @WEN2 schlagen?");
+    AddCmd("schlag|schlage&@ID",#'action_schlag,
+           "Was oder wen willst du @verben?");
+
+    // Da juengere AddCmd aelteren vorgehen, wird die komplexere Regel samt
+    // ihrer Fehlermeldung nie ausgewertet, da ein "schlag ball hart" auch
+    // die zweite Regel triggert.
+
+    // anders herum:
+    AddCmd("schlag|schlage&@ID",#'action_schlag,
+           "Was oder wen willst du @verben?");
+    AddCmd("schlag|schlage&@ID&hart",#'action_schlag_hart,
+           "Was oder wen willst du @verben?|"
+           "Wie willst du @WEN2 schlagen?");
+
+    // Jetzt wird die komplexere Regel zuerst ueberprueft und triggert
+    // auch die richtige Funktion.
+    // Leider kommt die Fehlermeldung nie zum Tragen, denn was durch Regel 2
+    // durchfaellt, triggert entweder Regel 1 oder faellt auch durch Regel 1
+    // durch und ueberschreibt dabei die Meldung.
+
+    AddCmd("schlag|schlage&@ID",#'action_schlag,
+           "Was oder wen willst du wie @verben?");
+    AddCmd("schlag|schlage&@ID&hart",#'action_schlag_hart);
+
+    // Fast perfekt. Besser wird es nicht.
+
+
+    --- Ende Komplexbeispiel mehrere Regeln ---
+
+10 Juni 2004 Gloinson
diff --git a/doc/lfun/AddDefender b/doc/lfun/AddDefender
new file mode 100644
index 0000000..3eb7923
--- /dev/null
+++ b/doc/lfun/AddDefender
@@ -0,0 +1,34 @@
+AddDefender()
+
+FUNKTION:
+	void AddDefender(object friend);
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	friend
+	  Objekt (normal Lebewesen), welches zukuenftig ueber Angriffe
+	  informiert werden soll oder diese sogar abwehrt.
+
+BESCHREIBUNG:
+	Ein Lebewesen, welches angegriffen wird, kann andere Objekte ueber
+	einen solchen Angriff per InformDefend() informieren oder ihnen
+	sogar die Moeglichkeit geben, per DefendOther() direkt in den
+	laufenden Angriff einzugreifen (Schaeden abwehren oder umwandeln).
+	Im Normalfall handelt es sich hierbei um andere Lebewesen, welche
+	als Verteidiger des angegriffenen Lebewesens auftreten: Daher der
+	Name der Funktion.
+	Die Objekte sind in Form eines Arrays in der Property P_DEFENDERS
+	abgespeichert und koennen dort abgerufen werden. Natuerlich kann
+	man weitere Objekte direkt dort eintragen, jedoch sollte man die
+	hierfuer bereitgestellte Funktionen AddDefender() verwenden.
+	Zum Loeschen von Eintraegen im Array steht ebenfalls eine Funktion
+	bereit: RemoveDefender().
+
+SIEHE AUCH:
+	RemoveDefender(), InformDefend(), DefendOther(),
+	P_DEFENDERS, /std/living/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Thu Jul 29 18:48:45 1999 by Patryn
diff --git a/doc/lfun/AddDetail b/doc/lfun/AddDetail
new file mode 100644
index 0000000..229197b
--- /dev/null
+++ b/doc/lfun/AddDetail
@@ -0,0 +1,91 @@
+AddDetail()
+
+FUNKTION:
+    void AddDetail(string|string* keys,
+                   string|string*|mapping|closure desc);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den Namen der Details.
+    desc
+      String, Mapping, String-Array oder Closure mit/zur Beschreibung.
+
+BESCHREIBUNG:
+    Die Beschreibung der Details <keys> wird gesetzt. Wie die Details
+    bei der Untersuchung aussehen, haengt im wesentlichen vom Typ der
+    Beschreibung <desc> ab:
+      <desc> ist ein String.
+        Beim Untersuchen wird dieser String zurueckgegeben.
+      <desc> ist ein String-Array.
+        Beim Untersuchen wird zufaellig einer der Strings zurueckgegeben.
+      <desc> ist ein Mapping.
+        Das Mapping muss folgenden Aufbau haben:
+          ([0:        "Defaulttext",
+            "rasse1": "r1text", ...]).
+
+        Falls fuer die Rasse des das Detail untersuchenden Spielers ein
+        Eintrag im Mapping existiert, wird der entsprechende Text
+        zurueckgegeben, ansonsten der Defaulttext. Auf diese Weise sind
+        rassenabhaengige Details moeglich. Siehe auch die Beispiele.
+      <desc> ist eine Closure.
+        In diesem Fall wird die Closure ausgefuehrt und das Ergebnis
+        zurueckgegeben. Die Closure bekommt dabei den Namen des Details
+        als Parameter uebergeben.
+
+    Fuer Details koennen Forscherpunkte eingetragen werden.
+
+BEISPIELE:
+    Ein schlichtes Detail:
+
+      AddDetail(({"sofa","couch"}), "Eine kleine Couch.\n");
+
+    Laengere Details sollten hierbei nicht per Hand umgebrochen werden,
+    sondern man kann hierzu die Funktion break_string() nutzen:
+
+      AddDetail("detail", break_string(
+        "Du wolltest es ja nicht anders, jetzt musst Du Dir dieses "
+        "fuerchterlich lange Detail durchlesen!!!", 78));
+
+    Noetige Zeilenumbrueche bei Zeilenlaengen groesser 77 werden so
+    automatisch generiert.
+    Ein rassenabhaengiges Detail:
+
+      AddDetail(({"bett","bettchen"}),
+        ([0      :"Eine kleines Bett.\n", // Der Defaulttext
+          "zwerg":                        // Die Rasse klein schreiben
+                "Das Bett laedt geradezu zu einem Nickerchen ein.\n"]));
+
+    Und nun ein Detail mit Closure (diese Version ersetzt das Verhalten
+     von AddSpecialDetail).
+
+      int hebel_betaetigt;
+      ...
+      string hebel(string str); // Funktion bekannt machen (Prototyping)
+      ...
+      AddDetail(({"hebel","schalter"}), #'hebel);
+      ...
+      string hebel(string key) {
+        if(hebel_betaetigt)
+          return "Der "+capitalize(key)+" steht auf EIN.\n";
+        else
+          return "Der "+capitalize(key)+" steht auf AUS.\n";
+      }
+
+    Man erhaelt verschiedene Ergebnisse beim Untersuchen, je nachdem
+    ob das Flag hebel_betaetigt gesetzt ist oder nicht.
+
+SIEHE AUCH:
+    Setzen:    AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS,
+               P_TOUCH_DETAILS, P_SPECIAL_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AddDrink b/doc/lfun/AddDrink
new file mode 100644
index 0000000..6b99e08
--- /dev/null
+++ b/doc/lfun/AddDrink
@@ -0,0 +1,12 @@
+AddDrink()
+
+BEMERKUNGEN:
+
+        Die Funktion AddDrink() sollte NICHT MEHR BENUTZT werden.
+        Bitte AddToMenu() verwenden.
+
+SIEHE AUCH:
+	AddToMenu(), RemoveFromMenu()
+
+----------------------------------------------------------------------------
+Last modified: Fri Mar 03 13:23:00 2000 by Paracelsus
diff --git a/doc/lfun/AddExit b/doc/lfun/AddExit
new file mode 100644
index 0000000..a070682
--- /dev/null
+++ b/doc/lfun/AddExit
@@ -0,0 +1,91 @@
+AddExit()
+FUNKTION:
+     void AddExit(string|string* cmd, closure|string dest);
+
+DEFINIERT IN:
+     /std/room/exits
+
+ARGUMENTE:
+     string/string* cmd
+          die Richtung(en), in die der Ausgang fuehrt
+     string/closure dest
+          das Ziel des Ausgangs mit Text/Closure
+
+BESCHREIBUNG:
+
+     Es wird ein Ausgang in die Richtung(en) cmd eingefuegt. Die Art des
+     Ausgangs haengt ab von dest:
+
+     - ein String:
+       - mit einem Dateinamen:
+         Der Ausgang fuehrt in den Raum, den der Dateiname bezeichnet.
+       - der Form "<msg>#dateiname"
+         Der Ausgang fuehrt in den Raum, den der Dateiname bezeichnet,
+         bei der Benutzung wird jedoch statt "<name> geht nach <richtung>"
+         "<name> geht nach <msg>" ausgegeben.
+     - eine Closure:
+       Die Closure wird bei Nutzung des Ausgangs aufgerufen. Das entspricht
+       eine SpecialExit - in der gerufenen Funktion muss man den Spieler
+       selbst in den Zielraum bewegen.
+       Gegebenenfalls kann das durch AddCmd() ersetzt werden.
+
+BEMERKUNGEN:
+     Man kann fuer den Dateinamen des Zielraumes auch einen relativen Pfad
+     angeben. Die Auswertung erfolgt nach folgendem Schema:
+     - "./<dateiname>"
+       Es wird ein Zielraum relativ zum gleichen Verzeichnis wie dieser
+       Raum angesprochen.
+     - "../<dateiname>"
+       Es wird ein Zielraum relativ zur Verzeichnisebene ueber der
+       dieses Raumes angesprochen (analog mit mehrerern "../..")
+
+     Mittels P_HIDE_EXITS kann man Ausgaenge verstecken.
+
+     Bei der Benutzung eines Ausgangs wird der Hook H_HOOK_EXIT_USE
+     ausgeloest.
+
+BEISPIELE:
+     ### normale Ausgaenge ###
+     // Beim Kommando "sueden" kommt: "<name> geht nach Sueden."
+     AddExit("sueden", "/gilden/abenteurer");
+
+     // Beim Kommando "sueden" kommt: "<name> geht in die Gilde."
+     AddExit("sueden", "in die Gilde#/gilden/abenteurer");
+
+     ### Ausgaenge mit relativen Pfaden ###
+     // Der Name des Raumes sei "/d/inseln/wargon/hafen1"
+     // Dieser Ausgang geht nach "/d/inseln/wargon/kneipe":
+     AddExit("norden", "./kneipe" );
+
+     // Und dieser nach "/d/inseln/anthea/anlege":
+     AddExit("sueden", "../anthea/anlege" );
+
+     ### dynamische Ausgaenge ###
+     // ein Ausgang soll nur von Froeschen benutzbar sein:
+
+     static int lochfkt(string dir);		// Prototyp
+     ...
+     AddExit("loch", #'lochfkt);
+     // auch identisch zu:
+     // AddSpecialExit("loch", #'lochfkt); [eine Closure] oder
+     // AddSpecialExit("loch", "lochfkt"); [ein Funktionsname]
+
+     static int lochfkt(string dir) {
+       if (!(this_player()->QueryProp(P_FROG))) {
+         // Kein Frosch => passt nicht!
+         notify_fail("Du bist zu gross!\n");
+         return 0;
+       }
+       // Meldungen werden im move() gleich mitgegeben
+       return this_player()->move("/room/loch", M_GO, 0,
+                    "huepft ins Loch", "huepft herein");
+     }
+
+SIEHE AUCH:
+     AddSpecialExit(), GetExits()
+     RemoveExit(), RemoveSpecialExit(),
+     H_HOOK_EXIT_USE, P_EXITS, P_HIDE_EXITS, /std/room/exits.c
+     ausgaenge
+
+31.01.2015, Zesstra
+
diff --git a/doc/lfun/AddExp b/doc/lfun/AddExp
new file mode 100644
index 0000000..8baed55
--- /dev/null
+++ b/doc/lfun/AddExp
@@ -0,0 +1,32 @@
+AddExp()
+FUNKTION:
+     int AddExp(int e)
+
+DEFINIERT IN:
+     /std/living/life.c
+
+ARGUMENTE:
+     int e - Anzahl der hinzuzufuegenden (abzuziehenden) XP
+
+BESCHREIBUNG:
+     Dem Living werden e XP auf seine bisherigen P_XP addiert.
+
+     Falls es sich um einen Spieler mit P_KILLS>0 handelt und
+     e positiv ist, bekommt der Spieler keine XP gutgeschrieben.
+
+     P_LAST_XP wird aktualisiert.
+
+BEMERKUNG:
+     - positive und negative Werte sind moeglich
+     - P_XP wird nicht <0 gesetzt.
+
+RUECKGABEWERT:
+     int - neuer XP-Wert
+
+SIEHE AUCH:
+     Funktionen:  do_damage(), DistributeExp()
+     Properties:  P_XP, P_LAST_XP
+     Sonstiges:   P_NO_XP, P_NO_SCORE
+                  create_default_npc()
+
+14.Feb 2007 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/AddExtraLook b/doc/lfun/AddExtraLook
new file mode 100644
index 0000000..526a851
--- /dev/null
+++ b/doc/lfun/AddExtraLook
@@ -0,0 +1,96 @@
+AddExtraLook()
+varargs int AddExtraLook(string look, [int duration, string key,
+                         string lookende, object ob]);
+DEFINIERT IN:
+   /std/living/description.c
+
+BESCHREIBUNG:
+   Der Extralook erscheint in der Langbeschreibung des Lebewesens.
+   Eintraege koennen mit dieser Funktion hinzugefuegt werden. Dies ist der
+   bevorzugte Weg, wenn ansonsten extra ein Objekt im Spielerinventar abgelegt
+   werden muesste.
+   
+   Alle Parameter bis auf <look> sind optional.
+
+ARGUMENTE:
+  - string look:
+    String, der in der Langbeschreibung des Lebewesens zusaetzlich ausgegeben
+    wird.
+    Kann auch ein Funktionsname sein, wenn <ob> angegeben wird (s.u.).
+  - int duration:
+    > 0: Wie lang bleibt der Extralook gueltig (in Sekunden)? Anschliessend 
+         wird er automatisch geloescht.
+    0:   Dieser Eintrag bleibt unbegrenzt gueltig.
+    < 0: Dieser Eintrag bleibt bis zum Ende/Reboot bestehen.
+  - string key:
+    Schluesselwort, unter dem der Eintrag registriert wird und mit dem man ihn
+    auch mittels RemoveExtraLook() entfernen kann. Sollte natuerlich
+    moeglichst eindeutig sein. ;-) Wenn <key> nicht angeben wird, wird der 
+    Objektname (object_name()) benutzt.
+  - string lookende:
+    String, der an das Lebewesen (nur bei Spielern) ausgegeben wird, wenn der
+    eingetragene Extralook abgelaufen ist.
+    Kann auch ein Funktionsname sein, wenn <ob> angegeben wird.
+  - object ob:
+    Wenn hier ein Objekt angegeben wird, werden <look> und <lookende> als
+    Funktonsnamen aufgefasst. Diese Funktionen werden in <ob> aufgerufen, wenn
+    der Extralook des Lebewesen angezeigt wird bzw. der eingetragene Extralook
+    abgelaufen ist. Diese Funktionen bekommen das jeweilige Lebenwesen als
+    Objekt uebergeben. Sie muessen einen String zurueckliefern, der ausgegeben
+    wird. Dieser String wird direkt so ausgeben, also selber fuer Zeilenumbruch
+    etc. sorgen!
+    WICHTIG: Das Objekt sollte nach Moeglichkeit eine Blueprint sein, da das
+    ganze nix mehr ausgibt, sobald der Clone zerstoert wird, falls hier 
+    einer angeben wird. Wenn ihr keine BP uebergebt: Wisst, was ihr tut. ;-)
+
+RUECKGABEWERTE:
+  > 0, falls der Eintrag erfolgreich registriert wurde.
+  < 0 sonst.
+    -1: <key> war nicht gueltig und es konnte keiner ermittelt werden.
+    -2: <look> war kein gueltiger String.
+    -3: <duration> war kein Integer.
+    -4: unter <key> gibt es schon einen Eintrag.
+
+BEMERKUNGEN:
+  Die Strings <look> und <lookende> werden vor Ausgabe durch
+  replace_personal() geschickt, daher ist die Verwendung von @WER1, @WESSEN1
+  usw. moeglich (s. replace_personal). Dies gilt aber _nicht_ fuer den Fall,
+  dass die entsprechenden Funktionen in <ob> gerufen werden, dann muessen die
+  Funktionen selber umbrechen, etc.
+  Nach replace_personal() werden die Strings noch von break_string() auf 78
+  Zeilen umgebrochen, allerdings bleiben dabei vorhandene Umbrueche erhalten.
+  Die Meldung von <lookende> bzw. der Funktionsaufruf erfolgt, wenn der
+  Extralook der Lebewesen das erste Mal nach Ablauf der Gueltigkeit aufgerufen
+  wird.
+
+BEISPIELE:
+  # einfacher Eintrag, "fuer die Ewigkeit"
+  living->AddExtraLook("@WER1 hat den Drachengott der SSP besiegt.");
+
+  # Eintrag der nach 1h automatisch weg ist.
+  living->AddExtraLook("@WER1 ist ganz mit Marmelade bedeckt.", 3600);
+  
+  # Eintrag mit bestimmten Schluessel, damit man ihn wieder entfernen kann.
+  living->AddExtraLook("@WER1 ist ganz mit Marmelade bedeckt.", 3600,
+                       "humni_marmeladen_look");
+  
+  # Mit "Ende"-Meldung, aber kein eigener Schluessel.
+  living->AddExtraLook("@WER1 ist patschnass.", 1200, 0,
+                       "Du bist endlich wieder trocken. Puuh.");
+  
+  # Mit Objekt, was den Extralook dynamisch erzeugt
+  living->AddExtraLook("get_my_special_extralook", 3600, 0, 0, this_object());
+    In diesem Fall muss this_object() natuerlich die Funktion
+    "get_my_special_extralook()" definieren, die einen String zurueckgibt.
+
+  # Mit Objekt, was den Extralook und die Endemeldung dynamisch erzeugt
+  living->AddExtraLook("get_my_special_extralook", 3600, 0,
+                       "extralookende", this_object());
+
+SIEHE AUCH:
+   RemoveExtraLook(),
+   replace_personal(), break_string()
+   P_INTERNAL_EXTRA_LOOK
+
+14.05.2007, Zesstra
+
diff --git a/doc/lfun/AddFixedObject b/doc/lfun/AddFixedObject
new file mode 100644
index 0000000..3e2e172
--- /dev/null
+++ b/doc/lfun/AddFixedObject
@@ -0,0 +1,52 @@
+AddFixedObject()
+
+FUNKTION:
+        varargs void AddFixedObject(string str, int val, mixed ids);
+
+DEFINIERT IN:
+        /std/room/shop.c
+
+ARGUMENTE:
+        str
+          Der absolute Filename eines Objekts, das in quasi beliebiger Menge
+          vom betreffenden Laden verkauft werden soll.
+        val
+          Sofern angegeben der angenommene Wert des Objekts. Falls val nicht
+          angegeben oder 0 ist, wird der Wert aus dem angegebenen Objekt
+          selbst ermittelt.
+          Der Verkaufspreis ist 3 * Wert des Objekts.
+        ids
+          String oder Stringarray mit der ID oder den IDs, ueber die man das
+          Objekt im Laden ansprechen kann. Falls nicht angegeben, wird die
+          ID-Liste aus der blueprint des Objekts ausgelesen.
+
+BESCHREIBUNG:
+        Mit dieser Funktion kann man einem Laden mitteilen, dass ein Objekt
+        in ihm in unbegrenzter Anzahl verkauft werden soll.
+        WICHTIG: Das zu verkaufende Objekt sollte dies insofern unterstuetzen, 
+        dass die Blueprint die notwendigen Informationen
+        (P_SHORT, P_IDS, P_VALUE, P_LONG, P_NAME) beinhaltet. Dies bedeutet im
+        einfachsten Fall, dass im create() auf
+          if (!clonep()) return;
+        verzichtet wird.
+
+RUeCKGABEWERT:
+        keiner
+        
+BEISPIELE:
+        AddFixedObject("/obj/fackel", 5000, "fackel");
+          Der Laden verkauft Fackeln zum Preis von 3*5000 Goldmuenzen und man
+          kann die Fackel (ausser ueber die Inventarnummer) nur mittels der
+          id "fackel" kaufen.
+          
+        AddFixedObject("/obj/fackel");
+          Der Laden verkauft Fackeln zum dreifachen Wert dessen, was im Objekt
+          /obj/fackel.c angegeben ist (derzeit sind das 5 Muenzen) und laesst
+          alle IDs zu, die in /obj/fackel.c angegeben sind. Derzeit ist das
+          auch nur "fackel".
+
+SIEHE AUCH:
+	RemoveFixedObject(), SetStorageRoom(), /std/store.c
+        
+----------------------------------------------------------------------------
+Letzte Aenderung: Sat Nov  9 12:59:25 2002 durch Bambi
diff --git a/doc/lfun/AddFood b/doc/lfun/AddFood
new file mode 100644
index 0000000..2da18e5
--- /dev/null
+++ b/doc/lfun/AddFood
@@ -0,0 +1,12 @@
+AddFood()
+
+BEMERKUNGEN:
+
+        Die Funktion AddFood() sollte NICHT MEHR BENUTZT werden.
+        Bitte AddToMenu() verwenden.
+
+SIEHE AUCH:
+        AddToMenu(), RemoveFromMenu()
+
+----------------------------------------------------------------------------
+Last modified: Fri Mar 03 13:23:00 2000 by Paracelsus
diff --git a/doc/lfun/AddFuel b/doc/lfun/AddFuel
new file mode 100644
index 0000000..bf00350
--- /dev/null
+++ b/doc/lfun/AddFuel
@@ -0,0 +1,29 @@
+AddFuel()
+
+FUNKTION:
+     void AddFuel(int fuel);
+
+DEFINIERT IN:
+     /std/lightsource.c
+
+ARGUMENTE:
+     fuel
+          Die zusaetzliche Brenndauer in Sekunden.
+
+BESCHREIBUNG:
+     Die Brenndauer der Lichtquelle wird um fuel Sekunden verlaengert.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Es werden keine Checks durchgefuehrt! Wenn man seine Lichtquelle
+     nachfuellbar gestalten will, sollte die Nachfuellfunktion vor dem
+     AddFuel()-Aufruf nachsehen, wie voll die Lichtquelle noch ist, und fuel
+     entsprechend begrenzen.
+
+SIEHE AUCH:
+     /std/lightsource.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:16:39 1996 by Wargon
diff --git a/doc/lfun/AddFun b/doc/lfun/AddFun
new file mode 100644
index 0000000..925b5ac
--- /dev/null
+++ b/doc/lfun/AddFun
@@ -0,0 +1,63 @@
+AddFun()
+
+FUNKTION:
+     void AddFun(string fun, int next);
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     fun
+          Name der Funktion.
+     next
+          Zeit bis zur naechsten Fahrplanstation.
+
+BESCHREIBUNG:
+     Dem Fahrplan wird der Aufruf der Funktion fun, die im Transporter
+     definiert sein muss, hinzugefuegt. Nach Aufruf der Funktion vergehen
+     next Sekunden, bis die naechste Station angefahren wird.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+     Wenn ein zufaellig ausgewaehlter Passagier eines Schiffes unterwegs
+     seekrank werden soll, koennte man das wie folgt realisieren:
+
+     create()
+     {
+       ...
+
+       AddFun("seekrank", 5);
+       ...
+     }
+
+     seekrank()
+     {
+       object *passagiere, opfer;
+
+       // soll nicht immer passieren
+       if (random(5))
+         return;
+
+       // Opfer auswaehlen
+       passagiere = QueryPassengers();
+       if (sizeof(passagiere))
+         opfer = passagiere[random(sizeof(passagiere))];
+
+       // Und viel Spass...
+       tell_object(opfer,
+         "Du wirst seekrank! Schnell stuerzt Du zur Reling um  Dich zu\n"
+        +"uebergeben.\n");
+       tell_room(this_object(),
+         sprintf("%s ueberkommt die Seekrankheit!\n%s stuerzt an die Reling, "
+                +"um sich zu uebergeben.\n",
+                 capitalize(opfer->name(WEN)),
+                 capitalize(opfer->QueryPronoun(WER))), ({ opfer }) );
+     }
+
+SIEHE AUCH:
+     AddRoute(), AddMsg(), /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:16:46 1996 by Wargon
diff --git a/doc/lfun/AddId b/doc/lfun/AddId
new file mode 100644
index 0000000..fa1ce76
--- /dev/null
+++ b/doc/lfun/AddId
@@ -0,0 +1,50 @@
+AddId()
+
+FUNKTION:
+     void AddId(string|string* ids);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     ids
+          String oder Array von Strings mit den Bezeichnungen, mit denen
+          sich sich das Objekt ansprechen lassen soll.
+
+BESCHREIBUNG:
+     Jedes Objekt sollte sich auf die eine oder andere Weise ansprechen
+     lassen. Zu diesem Zweck kann man dem Objekt mit dieser Funktion
+     Bezeichner uebergeben.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Jedes Objekt sollte man zumindest mit seiner Kurzbeschreibung
+     ansprechen koennen! Fuer Abfragen von Questobjeken o.ae. sollte man
+     zusaetzlich IDs verwenden, die Sonderzeichen wie "\n" oder "\t"
+     enthalten, damit sichergestellt ist, dass der Spieler auch wirklich die
+     richtigen Objekte dabeihat.
+
+BEISPIELE:
+
+     AddId( "buch" );
+     AddId( "buechlein" );
+
+     Das Objekt laesst sich jetzt als "buch" und als "buechlein" ansprechen.
+
+     AddId( ({ "buch", "buechlein" }) );
+
+     Diese Zeile bewirkt das gleiche wie die obigen zwei Zeilen.
+
+     AddId( ({ "puzzle", "\nquest_puzzle" }) );
+
+     Der Spieler kann das Objekt als "puzzle" ansprechen, questrelevante
+     Objekte koennen mit der ID "\nquest_puzzle" nach ihm suchen.
+
+SIEHE AUCH:
+     AddAdjective(), RemoveId(), id(), present(), /std/thing/description.c
+
+     -----------------------------------------------------------------------
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AddInfo b/doc/lfun/AddInfo
new file mode 100644
index 0000000..9de7bd2
--- /dev/null
+++ b/doc/lfun/AddInfo
@@ -0,0 +1,219 @@
+AddInfo()
+FUNKTION:
+     varargs void AddInfo( frage, meldung
+			   [, indent [, [silent [, casebased] ] ] );
+
+DEFINIERT IN:
+     /std/npc/info.c
+
+ARGUMENTE:
+     string/string* frage
+	Schluesseltext(e) auf die Informationen gegeben werden sollen.
+     string/closure meldung
+	Information, die gegeben werden soll/Closure
+     string indent
+	Text, der sich bei mehrzeiligen Meldungen wiederholen soll.
+     int/string silent
+	Ist silent gesetzt, so erfolgt Antwort nur an Fragenden.
+     string/closure casebased
+	Closure mit Returnwert string oder int.
+
+BESCHREIBUNG:
+     Wenn ein Spieler ein NPC mittels "frage <monstername> nach <frage>" nach
+     einer Information mit dem Schluessel 'frage' fragt, so wird die
+     entsprechende 'meldung' ausgegeben (oder die Closure in 'meldung'
+     gerufen und der zurueckgegebene Text ausgegeben). Der Meldung wird
+     der Name des Monsters vorangestellt.
+
+     Frage:
+      Schluessel muessen kleingeschrieben sein, koennen aber Leerzeichen
+      enthalten.
+
+     Meldung:
+      Wenn kein 'indent' angegeben ist, muss man die Meldung selbst
+      umbrechen.
+
+     Indent:
+      Wird ein 'indent' angegeben so wird jeder Zeile hinter dem
+      Monsternamen noch das 'indent' vorangesetzt. Zusaetzlich wird
+      'meldung' auf jeden Fall sauber umgebrochen.
+      Ein typisches indent ist "sagt: ".
+
+     Silent:
+      Bei 'silent'==1 erfolgt keine Textausgabe der Antwortmeldung im Raum,
+      ist 'silent' ein String, so wird jener an alle anderen Spieler ausser
+      dem Fragesteller im Raum ausgegeben.
+
+     Casebased:
+      Die als Closure angegebene Methode entscheidet, ob oder wie der NPC 
+      auf diese Frage antworten soll:
+      - return 0:	normale Antwort mit "meldung"
+      - return 1:	keine Antwort/Antwort mit DEFAULT_NOINFO
+      - return string:	Antwort mit string unter Beruecksichtigung eines
+			indent
+
+     Die Strings von 'silent' und 'meldung' werden geparsed. Dabei werden die
+     Schluesselworte @WER, @WESSEN, @WEM, @WEN durch TP->Name(..) ersetzt und
+     @CAP_WER, @CAP_WESSEN, @CAP_WEM, @CAP_WEN durch capitalize(TP-Name(..)).
+
+     Mittels der in <npc.h> definierten Frage DEFAULT_INFO kann eine
+     Meldung gesetzt werden, die gegeben werden soll, wenn der Spieler
+     etwas fragt, auf das keine Antwort vorgegeben ist (das loest
+     SetProp(P_DEFAULT_INFO, <text>) ab).
+
+BEISPIELE:
+     ### eine Standardantwort setzen ###
+     AddInfo(DEFAULT_INFO, "starrt Dir boese in die Augen.\n");
+     // identisch zu
+     SetProp(P_DEFAULT_INFO, "starrt Dir boese in die Augen.\n");
+
+     ### einfache Beispiele, auch mit casebased ###
+     AddInfo(({"knete","kohle"}),
+	     "sagt: ich habe so etwas nicht.\n");
+     AddInfo("geld",
+	     "Ich habe zwar kein Geld, aber ... blablabla ...",
+	     "sagt: " );
+     AddInfo("muenzen",
+	     "fluestert: Du willst Geld?\n",
+	     0,
+	     "fluestert @WEM etwas zu.\n");
+
+     // "frage monster nach geld": alle im Raum hoeren
+     //  Das Monster sagt: Ich habe zwar kein Geld, aber ...
+     //  Das Monster sagt: ... blablabla ...
+
+     // "frage monster nach muenzen":
+     // - der Fragensteller hoert:
+     //   "Das Monster fluestert: Du willst Geld?"
+     // - alle andere hoeren:
+     //   "Das Monster fluestert <Fragenstellernamen> etwas zu."
+
+     ### dynamisch ###
+     // ein Prototyp, damit wir die Methode bekannt machen
+     static string query_kekse();
+     ...
+     AddInfo(({"keks","kekse"}),
+	     #'query_kekse,		// ein Verweis auf die Funktion
+	     "sagt: ");
+     ...
+     static string query_kekse() {
+      if(present("keks"))
+       return("Ich hab noch welche. Aetsch!");
+      return("Menno. Keine mehr da!");
+     }
+
+     // "frage monster nach keks":
+     // - wenn es noch Kekse hat, hoeren alle:
+     //   "Das Monster sagt: Ich hab noch welche. Aetsch!
+     // - sonst:
+     //   "Das Monster sagt: "Menno. Keine mehr da!
+
+     ### dynamischer ###
+     // ein Prototyp, damit wir die Methode bekannt machen
+     static string query_kekse();
+     static mixed case_fighting();
+     ...
+     AddInfo(({"keks","kekse"}),
+	     #'query_kekse,"		// ein Verweis auf die Funktion
+	     sagt: ",
+	     0,				// nicht silent :)
+	     #'case_fighting);		// noch ein Funktionsverweis
+     ...
+     static string query_kekse() {
+      if(present("keks"))
+       return("Ich hab noch welche. Aetsch!");
+      return("Menno. Keine mehr da!");
+     }
+
+     static mixed case_fighting() {
+      if(InFight())
+       return("Keine Zeit fuer Kekse. Muss kaempfen.");
+      return 0;
+     }
+
+     // "frage monster nach keks":
+     // - wenn es kaempft, hoeren alle:
+     //   "Das Monster sagt: Keine Zeit fuer Kekse. Muss kaempfen.
+     // - sonst, wenn es noch Kekse hat, hoeren alle:
+     //   "Das Monster sagt: Ich hab noch welche. Aetsch!
+     // - sonst:
+     //   "Das Monster sagt: "Menno. Keine mehr da!
+
+
+     ### dynamisch und komplex ###
+     // ein Prototyp, damit wir die Methode bekannt machen
+     static string question_gold();
+     ...
+
+     // "gold" wird eine Closure auf die Methode question_gold()
+     // zugewiesen, ausserdem soll es still bleiben (wir informieren
+     // den Restraum selbst)
+     AddInfo("gold",#'question_gold,"murmelt: ",1);
+     ...
+
+     // los gehts, wir generieren unsere Antwort selbst
+     static string question_gold() {
+      int money;
+      string *y, objstr;
+      object o;
+      // wieviel Kohle hat der Spieler
+      money=this_player()->QueryMoney();
+      y=allocate(0);
+      // und jetzt suchen wir die Dinge aus Gold
+      o=first_inventory(this_player());
+      while(o) {
+       if(o->QueryMaterial(MAT_GOLD)>0 &&
+          strstr(object_name(o),"/obj/money"))
+        y+=({o->name(WER,1)});
+       o=next_inventory(o);
+      }
+
+      // das geht an alle anderen im Raum, silent bietet sich hier
+      // nicht an, weil es mehrere Moeglichkeiten gibt
+      say(break_string(
+       Name(WER,1)+" murmelt "+
+       this_player()->name(WEM,1)+
+       " etwas zu"+
+       ((money || sizeof(y))?
+        " und glotzt "+
+        this_player()->QueryPronoun(WEN)+" gierig an.":
+        "."),78),({this_player()}));
+
+      // und hier die Antwort an den Spieler selbst, mit vielen
+      // Verzweigungen fuer dessen Besitztum
+      return("Ich hab kein Gold bei mir."+
+          ((money || sizeof(y))?
+           " Aber du "+
+           (money?"hast ja jede Menge Kohle bei dir, so etwa "+money+
+            " Muenzen."+
+            (sizeof(y)?
+             " Ausserdem "+
+             ((sizeof(y)==1)?"ist":"sind")+
+             " auch noch "+CountUp(y)+" aus Gold.":
+             ""):
+            (sizeof(y)?" Aber was du so bei dir hast: "+
+             CountUp(y)+
+             (sizeof(y)==1?" ist":" sind")+
+             " aus Gold.":"")):
+           ""));
+     }
+
+     // "frage monster nach gold"
+     // - der Fragesteller hoert zB:
+     //   Das Monster murmelt: Ich hab kein Gold bei mir. Aber du hast ja
+     //   Das Monster murmelt: jede Menge Kohle bei dir, so etwas <number>
+     //   Das Monster murmelt: Muenzen. Ausserdem ist/sind noch <object1>
+     //   Das Monster murmelt: und <object2> aus Gold."
+     // - die Umstehenden hoeren:
+     //   "Das Monster murmelt @WEM etwas zu."
+     //   oder
+     //   "Das Monster murmelt @WEM etwas zu und glotzt ihn/sie gierig an."
+
+SIEHE AUCH:
+     Verwandt:  AddSpecialInfo(L), RemoveInfo(L)
+     Props:     P_PRE_INFO, P_DEFAULT_INFO
+     Files:     /std/npc/info.c
+     Loggen:    P_LOG_INFO
+     Interna:   GetInfoArr, do_frage
+
+7.Apr 2004 Gloinson
diff --git a/doc/lfun/AddItem b/doc/lfun/AddItem
new file mode 100644
index 0000000..8e812ea
--- /dev/null
+++ b/doc/lfun/AddItem
@@ -0,0 +1,159 @@
+AddItem()
+
+FUNKTION:
+	varargs object AddItem(mixed filename,int refresh,mixed props);
+
+DEFINIERT IN:
+	/std/room/items.c
+	/std/npc/items.c
+
+ARGUMENTE:
+	filename
+	  String mit dem Namen des zu erzeugenden Objektes oder Array von
+	  Strings mit den Namen der zu erzeugenden Objekte. Bei einem Array
+	  wird ein Name zufaellig ausgewaehlt.
+	refresh
+	  Wann und wie soll das Objekt erneuert werden:
+	  - REFRESH_NONE      - Kein Refresh bis zum Neuladen des Raums
+                        - oder NPCs.
+	  - REFRESH_DESTRUCT  - Refresh bei Reset, wenn Item zerstoert
+	                        wurde.
+	  - REFRESH_REMOVE    - Refresh bei Reset, wenn Item entfernt wurde.
+	  - REFRESH_ALWAYS    - Neuer Clone bei jedem Reset.
+	  - REFRESH_MOVE_HOME - Objekt wird bei Reset automatisch
+	                        zurueckgeholt, wenn es wegbewegt wurde.
+	                        (nur in Raeumen!)
+	  Bei NPC's gilt zusaetzlich:
+	  - CLONE_WEAR       - Item Anziehen, wenn es eine Ruestung ist.
+	  - CLONE_WIELD      - Item zuecken, wenn es eine Waffe ist.
+	  - CLONE_NO_CHECK   - Zuecken oder Anziehen ohne Ueberpruefungen.
+	props (optional)
+	  Mapping mit denen in einem geclonten Objekt zu setzenden
+	  Properties oder 1 fuer die Erzeugung einer Blueprint.
+
+RUeCKGABEWERT:
+	Innerhalb von Raeumen wird das erzeugte Objekt zurueckgeliefert. Bei
+	NPC's klappt dies leider nicht, da dort die Objekte nicht sofort
+	erzeugt werden, sondern erst, nachdem der NPC an seinen
+	Bestimmungsort transferiert wurde. Daher wird bei NPC immer 0 
+	zurueckgegeben.
+
+BESCHREIBUNG:
+	Abhaengig von <filename> und <props> wird ein Objekt erzeugt und in
+	den Raum bzw. NPC bewegt. Dabei gibt es folgende Moeglichkeiten:
+	- <filename> ist ein Dateiname.
+	  Es wird ein Clone dieser Datei erstellt oder (wenn <props>=1 ist)
+	  deren Blueprint verwendet.
+	- <filename> ist ein Array von Dateinamen.
+	  Es wird eine Datei zufaellig aus dem Array ausgewaehlt und von
+	  dieser Datei ein Clone erstellt oder (wenn <props>=1 ist) deren
+	  Blueprint verwendet.
+	Uebergibt man fuer <props> ein Mapping mit dem Aufbau
+	  ([prop_name:prop_wert,...]),
+	so werden diese Properties im erzeugten Objekt gesetzt.
+	Der Parameter <refresh> gibt an, was waehrend eines Resets im Raum
+	bzw. in NPC's oder was beim Erzeugen von NPC's geschehen soll:
+	In <rooms.h> sind dazu folgende Moeglichkeiten definiert:
+	- REFRESH_NONE
+            Das Objekt wird niemals erneuert; falls es zerstoert wurde, wird
+	    es erst dann wieder erzeugt, wenn der Raum erneut geladen bzw.
+	    der NPC neu erzeugt wird. Man beachte, dass nicht jeder NPC
+	    wirklich refreshende Objekte benoetigt, REFRESH_NONE spart
+	    hierbei sowohl Rechenzeit als auch Speicher!
+	- REFRESH_DESTRUCT
+	    Das Objekt wird nur dann erneuert, wenn es in der Zwischenzeit
+	    zerstoert wurde (bei NPC's ist das zum Beispiel der Fall, wenn
+	    sie getoetet wurden).
+	    REFRESH_NONE & REFRESH_DESTRUCT + Blueprint-Objekt bedeutet bei
+	    NPC's ein Unique-Objekt, es wird also nicht beim Neuerzeugen des
+	    NPC's zurueckgesetzt.
+	- REFRESH_REMOVE
+	    Das Objekt wird erneuert, wenn es sich nicht mehr im Raum bzw.
+	    im NPC befindet. Das kein sein, weil es zerstoert wurde, aber
+	    auch zum Beispiel in folgenden Faellen:
+	    * weil es jemand mitgenommen hat
+	       (in Raeumen bei Gegenstaenden)
+	    * weil es fortgegangen ist
+	       (in Raeumen bei NPC's, die herumlaufen)
+	    * weil es weggeworfen wurde
+	       (in NPC's bei Gegenstaenden)
+	- REFRESH_ALWAYS
+	    Das Objekt wird immer erneuert. Von dieser Refreshmethode sollte
+	    man allerdings Abstand nehmen, da sich sonst mit der Zeit
+	    gewaltige Mengen von Objekten ansammeln koennen!
+	- REFRESH_MOVE_HOME
+	    Das Objekt wird in einen Raum zurueckbewegt, sofern es noch
+	    existiert, jedoch nicht mehr in dem Raum ist. Sinnvoll ist dies
+	    eigentlich nur fuer Lebewesen, funktioniert aber auch bei
+	    beliebigen Objekten. Hauptsaechlich geht es hierbei darum,
+	    herumlaufende NPCs oder bei erzwungenen Bewegungen nicht von
+	    P_GUARD zurueckgehaltene NPCs wieder an einen definierten
+	    Ausgangsort zurueckzubringen.
+	Hat man in Raeumen als <filename> ein Array von Dateinamen
+	uebergeben, so wird beim Reset jedesmal aufs Neue ein zufaelliges
+	Objekt aus der Liste ausgewaehlt (nicht in NPC's).
+	In NPC's gilt der Grundsatz der Vermeidung von ueberfluessigen
+	Objekten im MUD. Neu erzeugt werden Objekte beim Erzeugen eines
+	NPC's oder bei einem Reset im selbigen. Anstatt die Objekte gleich
+	neu zu erschaffen, wird erst geschaut, ob sich identische Objekte
+	schon im Raum befinden. Ist dies der Fall, so nimmt der NPC sie auf,
+	ruft jedoch vorher nochmals create() in ihnen auf!
+	  (noetig wegen moeglicher Veraenderungen an den Objekten)
+	Was dann passiert, haengt von weiteren Angaben in <refresh> ab.
+	Folgende weitere Moeglichkeiten sind in <npc.h> definiert:
+        - CLONE_WEAR
+	  Ist das hinzugefuegte Item eine Ruestung, so wird sie nach
+	  Aufnahme oder Neuerzeugung angezogen.
+        - CLONE_WIELD
+	  Ist das hinzugefuegte Item eine Waffe, so wird sie nach Aufnahme
+	  oder Neuerzeugung gezueckt.
+        - CLONE_NO_CHECK
+	  Hiermit verhindert man eine Ueberpruefung, ob eine Ruestung
+	  angezogen oder eine Waffe gezueckt werden kann. Es ist jedoch
+	  Vorsicht geboten: So kann es ohne weiteres passieren, dass ein NPC
+	  mehrere Ruestungen gleichen Typs angezogen oder mehrere Waffen
+	  gezueckt hat.
+	Benutzt man Blueprints (<props>=1) mit REFRESH_REMOVE oder
+	REFRESH_ALWAYS, so kann es zu ungewollten Ueberraschungen kommen, da
+	die Blueprint dann unabhaengig von ihrem momentanen Aufenthaltsort
+	wieder in den Raum bzw. NPC bewegt wird, von dem sie erzeugt wurde!
+
+BEMERKUNGEN:
+	Wenn man Blueprints benutzt, sollte man daran denken, dass sich von
+	dieser dann keine Clones mehr erstellen lassen!
+	RemoveItem() zum Entfernen von Items ist nur fuer Raeume definiert!
+
+	Die Option CLONE_NEW ist veraltet. Die Objekte werden nun immer
+	neu erzeugt. Die Option darf noch angegeben werden, hat aber keine
+	Bedeutung mehr.
+
+BEISPIELE:
+	// Ein Wuerfel, der sich nach Entfernen erneuert:
+	  AddItem("/obj/misc/wuerfel",REFRESH_REMOVE);
+	// Ein etwas veraenderter Wuerfel:
+	  AddItem("/obj/misc/wuerfel",
+	          REFRESH_REMOVE,
+	          ([P_SHORT :"Ein schwerer Wuerfel",
+	            P_WEIGHT:100]));
+	// Eine Blueprint, die nur einmal im MUD existiert. Wenn sie
+	// zerstoert wurde, wird sie bei Reset neu erzeugt:
+	  AddItem("/mon/angsthase",REFRESH_DESTRUCT,1);
+	// Eine Blueprint, die nur einmal im MUD existiert. Wenn sie aus dem
+	// Raum entfernt wurde, wird sie bei Reset zurueckgeholt:
+	  AddItem("/mon/angsthase",REFRESH_MOVE_HOME,1);
+	// Ein zufaelliges Objekt:
+	  AddItem(({"/obj/misc/lolli",
+	            "/obj/misc/bonbon",
+	            "/obj/misc/bier"}),REFRESH_REMOVE);
+	// Eine Ruestung, die auch angezogen wird (nur in NPC's):
+	  AddItem("/ruestung/sommerkleid",REFRESH_REMOVE|CLONE_WEAR);
+	// Eine Unique-Waffe, die auch gezueckt wird (nur in NPC's):
+	  AddItem("/waffe/zapper",REFRESH_DESTRUCT|CLONE_WIELD,1);
+
+SIEHE AUCH:
+	RemoveItem(), replace_program(), create(), P_GUARD,
+	/std/room/items.c, /std/npc/items.c,
+	/sys/rooms.h, /sys/npc.h
+
+----------------------------------------------------------------------------
+Last modified: Thu Nov 23 13:43:30 CET 2006 by Rumata
diff --git a/doc/lfun/AddKnownPotion b/doc/lfun/AddKnownPotion
new file mode 100644
index 0000000..4d4d296
--- /dev/null
+++ b/doc/lfun/AddKnownPotion
@@ -0,0 +1,25 @@
+AddKnownPotion()
+
+FUNKTION:
+     int AddKnownPotion(int nr)
+
+DEFINIERT IN:
+     /std/player/potion.c
+
+ARGUMENTE:
+     int nr       Nummer eines ZTs
+
+BESCHREIBUNG:
+     Addiert einen ZT als bekannt in einem Spieler. Nur vom Orakel rufbar.
+
+RUeCKGABEWERT:
+     1  Erfolg
+     -1 fehlende Berechtigung
+     -2 Nummer bereits eingetragen
+
+SIEHE AUCH:
+     Sonstiges: zaubertraenke, /secure/potionmaster.c, /room/orakel.c
+     Verwandt:  FindPotion(), RemoveKnownPotion(), InList()
+     Props:     P_POTIONROOMS, P_KNOWN_POTIONROOMS
+
+6.Feb 2016 Gloinson
diff --git a/doc/lfun/AddMaterial b/doc/lfun/AddMaterial
new file mode 100644
index 0000000..d4f50b7
--- /dev/null
+++ b/doc/lfun/AddMaterial
@@ -0,0 +1,76 @@
+AddMaterial()
+FUNKTION:
+     private static varargs void AddMaterial(string mat, int gender,
+                                             mixed names, mixed groups,
+                                             mixed dif) {
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+ARGUMENTE:
+     string mat
+       Materialstring, definiert in <thing/material.h>
+
+     int gender
+       Geschlecht des einzutragenden Materials
+
+     mixed names
+       Name des Materials:
+       - "<Nominativ>" oder (meist nur Nom. und Gen. noetig)
+       - ({"<Nominativ>","<Genitiv>","<Dativ>","<Akkusativ>"})
+
+     mixed groups
+       Eingruppierung des Materials:
+       - MATGROUP_XXX oder ({MATGROUP_XXX,...})
+       - ([MAT_GROUP_XXX:xx,MATGROUP_YYY:yy,...])
+
+     mixed dif
+       Schwierigkeiten bei der Erkennbarkeit:
+       - int x oder ({MINMAT,x1,MATPOS1,x2,MATPOS2 ...})
+       - xn: Erkennbarkeitsschwierigkeit (100=100%) -100..100
+       - MINMAT: Erkennung zumindest als _dieses_ Material
+                 moeglich
+       - MATPOSn: moegliches Material, erkennbar, wenn
+                  Erkennbarkeitfaehigkeit>=xn
+                  -> das letzte MATPOS muss natuerlich
+                     string mat entsprechen
+
+BESCHREIBUNG:
+     Es wird in die Materialiendatenbank eine neues Material aufgenommen,
+     die Stringkonstante dafuer wird vorher in <thing/material.h> fest-
+     gelegt. Falls der Genitiv nicht Nominativ+"s" entspricht (z.B. "Seide"),
+     sollte dieser explizit angegeben werden.
+     Nach Neuladen der Datenbank ist dieses Material auch per MaterialName(),
+     'erkennbar' (siehe mixed dif, siehe Beispiel) bzw. seinen einzelnen
+     Gruppen zuordnbar.
+
+BEISPIELE:
+     AddMaterial(MAT_NITROGLYCERINE,NEUTER,"Nitroglycerin",
+                 ({MATGROUP_EXPLOSIVE,MATGROUP_FLUID}),
+                 ({MAT_OIL,25,MAT_MISC_EXPLOSIVE,50,MAT_NITROGLYCERINE}));
+
+     Damit wird das Material Nytroglycerin aufgenommen, ein explosiver
+     (damit entflammbarer) sowie fluessiger Stoff. Liegt die Erkennungs-
+     faehigkeit (MaterialName()) unter 25, wird es nur als Oel erkannt,
+     liegt sie unter 50, wird es zumindest als explosives Material erkannt,
+     liegt sie ueber 49, so wird es korrekt erkannt (wie schade :) ).
+
+BEMERKUNGEN:
+     Wird in der create() der Datenbank aufgerufen. Zu beachten:
+     - vor Eintrag eines _neuen_ Materials die Datenbank durchsuchen!
+     - bei den Materialiengruppen die automatischen Abhaengigkeiten in
+       AddMaterial() durchsehen!
+     - bitte Datenbank neu laden
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterial(), QueryMaterialGroup(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/AddMiniQuest b/doc/lfun/AddMiniQuest
new file mode 100644
index 0000000..91e7857
--- /dev/null
+++ b/doc/lfun/AddMiniQuest
@@ -0,0 +1,54 @@
+AddMiniQuest()
+
+FUNKTION:
+    int AddMiniQuest(int stupse, string questgeber, string desc, int active,
+                     string titel, string erledigt, mapping voraussetzungen,
+                     string region, string *erlaubte)
+
+DEFINIERT IN:
+    /secure/questmaster
+
+BESCHREIBUNG:
+    Diese Funktion traegt eine neue Miniquest im Questmaster ein.
+
+ARGUMENTE:
+
+    stupse (>0)  - Anzahl Stufenpunkte, die fuer die MQ gutgeschrieben werden
+    questgeber   - Ladename des Objekts, das GiveMiniQuest() aufruft
+    desc         - Aufgabenbeschreibung der Miniquest
+    active (0/1) - ist die Miniquest aktiv, d.h. spielbar, oder nicht?
+    titel        - Titel der Miniquest, darf weder "in", noch "im" enthalten,
+                   weil dann der Eintrag in der Fraternitas-Bibliothek nicht
+                   gelesen werden kann.
+    erledigt     - Beschreibung der Miniquest, nachdem man sie erledigt hat
+                   Der Text kann in der Bibliothek der kleinen und grossen
+                   Heldentaten in der Fraternitas eingesehen werden.
+    voraussetzungen - Mapping im Format von P_RESTRICTIONS (s. dort), um
+                   die Voraussetzungen festzulegen, die ein Spieler 
+                   erfuellen muss, um die MQ ueberhaupt spielen zu koennen
+                   Wird fuer die regionsbezogenen Informationspunkte/-NPCs
+                   ausgewertet. 0 oder ([]) eintragen, wenn keine 
+                   Voraussetzungen bestehen.
+    region       - Zuordnung der Miniquest zu einer Region; wird fuer der
+                   Bibliothek der Fraternitas verwendet, um die MQs der
+                   einzelnen Regionen herauszufiltern.
+    erlaubte     - Array mit Ladenamen von Objekten, die berechtigt sind,
+                   die Daten der MQ abzufragen, um Spielern einen Hinweis
+                   darauf zu geben, die sie noch nicht bestanden haben.
+
+RUECKGABEWERTE:
+     1: Hat geklappt
+    -1: Parameterformat stimmt nicht (questgeber kein String oder Leerstring,
+        voraussetzungen kein Mapping, region oder titel keine Strings, 
+        erlaubte kein Array)
+    -2: weniger als 1 Stufenpunkt einzutragen versucht
+    -3: Das Array in "erlaubte" ist leer, oder zum angegebenen Questgeber
+        wurde keine Datei gefunden.
+    -4: Der angegebene Questgeber vergibt schon eine andere Miniquest
+
+
+SIEHE AUCH:
+    GiveMiniQuest(L), HasMiniQuest(L)
+    P_RESTRICTIONS
+    /secure/questmaster.c
+
diff --git a/doc/lfun/AddMoney b/doc/lfun/AddMoney
new file mode 100644
index 0000000..229d1cc
--- /dev/null
+++ b/doc/lfun/AddMoney
@@ -0,0 +1,62 @@
+AddMoney(L)
+FUNKTION:
+     public int AddMoney(int amount);
+
+DEFINIERT IN:
+     /std/container/moneyhandler.c
+     /std/living/moneyhandler.c
+     /std/player/moneyhandler.c
+
+ARGUMENTE:
+     int amount
+         Die zufuehrende oder abziehende Geldmenge
+
+BESCHREIBUNG:
+     Dem Spieler wird die in <amount> festgelegte Geldmenge abgezogen oder
+     zugefuehrt.
+
+RUeCKGABEWERT:
+     Technisch gesehen wird Geld mit entsprechendem <amount> erzeugt
+     ("/items/money.c") und mittels "move" in den Spieler bewegt.  Das Ergebnis
+     dieses "move"-Aufrufes wird hier uebergeben, z.B. 1 fuer OK.
+     Die moeglichen Fehler-Konstanten sind in /sys/moving.h definiert, siehe
+     auch Dokumentation zu "move".
+
+BEMERKUNGEN:
+     <amount> kann sowohl positiv als auch negativ sein. Welche Auswirkungen
+     beide Faelle haben, sollte klar sein. Doch sollte bei einem negativen
+     <amount> vorher mittels QueryMoney() abgefragt werden, ob der Spieler
+     auch ueber ausreichend Geld verfuegt.
+     Wird dem Spieler Geld abgezogen, ist darauf zu achten, dieses in der
+     Zentralbank einzuzahlen (s.a.:PayIn() ). 
+     Verschafft man dem Spieler Geld aus dem Nichts, muss es vorher bei der
+     Zentralbank abgebucht (WithDraw()) werden.
+
+     Achtung: Kann der Spieler die in <amount> angebene Geldmenge nicht
+	      tragen, werden ihm keine Muenzen in sein Inventar bewegt.  Die
+	      Fehlermeldung erkennt man an dem Rueckgabewert ME_TOO_HEAVY.
+
+     Im Gegensatz zu Spielern haben alle anderen Objekte (Raeume, NPC, etc.)
+     standardmaessig keinen Moneyhandler. In diesem Fall muss in Lebewesen
+     "/std/living/moneyhandler"
+     und in nicht-Lebewesen
+     "/std/container/moneyhandler"
+     geerbt werden.
+
+BEISPIELE:
+     // gib ihm Geld
+     this_player()->AddMoney(50);
+
+     // nimm ihm Geld
+     if(this_player()->AddMoney(-50)==1)
+      write("Der Ork beklaut dich!\n");
+
+SIEHE AUCH:
+     Geldhandling:	QueryMoney(L)
+     Zentralbank:	PayIn(L), WithDraw(L)
+     Sonstiges:		move(L),
+			/items/money.c, /sys/moving.h, /sys/money.h, /sys/bank.h
+			/std/container/moneyhandler.c
+
+18.02.2013, Zesstra
+
diff --git a/doc/lfun/AddMsg b/doc/lfun/AddMsg
new file mode 100644
index 0000000..974c905
--- /dev/null
+++ b/doc/lfun/AddMsg
@@ -0,0 +1,42 @@
+AddMsg()
+
+FUNKTION:
+     void AddMsg(string msg, int next);
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     msg
+          Die auszugebende Meldung.
+     next
+          Zeit bis zur naechsten Fahrplanstation.
+
+BESCHREIBUNG:
+     Dem Fahrplan wird die Ausgabe einer Meldung an den Transporter
+     hinzugefuegt. Diese Meldung koennte zum Beispiel das Nahen der
+     naechsten Haltestelle ankuendigen o.ae. Nach Ausgabe der Meldung
+     vergehen next Sekunden, bis die naechste Station angefahren wird.
+
+     Um das Umbrechen der Meldung (normalerweise auf 78 Zeichen pro Zeile)
+     muss sich der Aufrufer selber kuemmern.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+
+     AddMsg("In der Ferne taucht eine kleine Inseln auf.\n", 10);
+     AddMsg("Das Schiff steuert einen kleinen Steg an.\n");
+     AddRoute(...);
+
+     Nach der Ankuendigung der Insel vergehen 10 Sekunden, bis die naechste
+     Meldung ausgegeben wird. Da bei der zweiten Meldung keine Zeit
+     angegeben war, legt das Schiff direkt nach der Ausgabe der Meldung an.
+
+SIEHE AUCH:
+     AddRoute(), AddFun(), /std/transport.c
+
+----------------------------------------------------------------------------
+25.01.2015, Zesstra
+
diff --git a/doc/lfun/AddPlant b/doc/lfun/AddPlant
new file mode 100644
index 0000000..a79bcff
--- /dev/null
+++ b/doc/lfun/AddPlant
@@ -0,0 +1,58 @@
+AddPlant()
+
+FUNKTION:
+        varargs int AddPlant(string filename, [string|string* npcId]) 
+
+DEFINIERT IN:
+        /std/room/kraeuter.c
+
+ARGUMENTE:
+        filename
+          Der Filename des Krauts das hier gefunden werden soll.
+        npcId
+          Die ID eines NPCs oder die IDs einer Liste von NPCs, der/die das 
+          Kraut bewachen soll/en. Befindet sich ein NPC mit einer dieser IDs
+          im Raum, kann das Kraut nicht gepflueckt werden. Dieses Argument 
+          ist optional!
+
+RUeCKGABEWERT:
+        -1 wenn das Objekt nicht geclont werden konnte
+        >=0 sonst
+
+BESCHREIBUNG:
+        Mit Hilfe dieser Funktion koennen Kraeuter fuer den mudweiten
+        Kraeuterskill recht einfach eingebaut werden. Alles was man
+        noch machen muss, ist den Namen der Pflanze in einem Detail oder
+        der Langbeschreibung zu erwaehnen.
+        Mit dem Befehl "showplant" in /obj/tools/planttool kann man sich 
+        bequem anzeigen lassen, was es alles an Kraeutern gibt, die man 
+        nehmen kann.
+
+BEMERKUNGEN:
+        Damit die Kraeuter von den Spielern zum Brauen von Traenken benutzt
+        werden koennen, muss der Raum erst in einem Master eingetragen werden.
+        Derzeit schickt ihr dazu am besten eine kurze Mail an einen Erzmagier,
+        gerne nimmt Humni die derzeit entgegen.
+        Die Kraeuter wurden von der Balance bereits alle im vorhinein
+        abgenommen. Lediglich die Einhaltung der Kategorien ist zu beachten.
+        Sind Kraeuter nicht im Master konfiguriert (wie z.B. im Homemud), sind
+        alle erzeugten Kraeuter nur "Testkraeuter" mit nur der ID "kraut".
+
+BEISPIELE:
+        #include <items/kraeuter/kraeuterliste.h>
+        inherit "/std/room/kraeuter";
+        inherit "/std/room";
+        
+        void create()
+        {
+          ::create();
+          SetProp(P_INT_LONG, "Du siehst eine Wiese voller Feldklee.\n");
+          AddPlant(FELDKLEE);
+        }
+
+SIEHE AUCH:
+        AddItem();
+
+----------------------------------------------------------------------------
+18.01.2015, Zesstra
+
diff --git a/doc/lfun/AddPluralId b/doc/lfun/AddPluralId
new file mode 100644
index 0000000..fd37bb2
--- /dev/null
+++ b/doc/lfun/AddPluralId
@@ -0,0 +1,27 @@
+AddPluralId()
+
+FUNKTION:
+     void AddPluralId(mixed id);
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     id
+          Identfikationsstring oder Array von Strings
+
+BESCHREIBUNG:
+     Es werden ein oder mehrere Bezeichner hinzugefuegt, mit denen sich 
+     mehrere Einheiten der Menge ansprechen lassen.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+     siehe /items/money.c
+
+SIEHE AUCH:
+     AddSingularId(), RemovePluralId(), AddId(), id(), /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Mon Jul 14 11:30:00 1997 by Silvana
diff --git a/doc/lfun/AddPursuer b/doc/lfun/AddPursuer
new file mode 100644
index 0000000..451ea9d
--- /dev/null
+++ b/doc/lfun/AddPursuer
@@ -0,0 +1,29 @@
+AddPursuer()
+
+FUNKTION:
+  void AddPursuer(object pursuer)
+
+ARGUMENTE:
+  pursuer: Objekt, das demjenigen folgen soll, in dem AddPursuer
+           aufgerufen wurde.
+
+FUNKTION:
+  Durch den Aufruf von AddPursuer in einem Objekt, welches living() ist,
+  wird das Object, welches als Argument uebergeben wurde in die Liste
+  der Verfolger eingetragen. Alle Objekte, die in der Verfolgerliste stehen
+  werden bei Bewegungen des Verfolgten in dasselbe Environment bewegt.
+
+RUECKGABEWERT:
+  keiner
+
+BEMERKUNG:
+  Im Verfolger wird PreventFollow mit dem Zielobjekt, in das der Verfolgte 
+  bewegt wird, aufgerufen. Dadurch kann der raeumliche Bereich, in dem 
+  verfolgt wird, eingeschraenkt werden.
+
+BEISPIELE:
+  find_player("jof")->AddPursuer(find_player("kirk"))
+  Danach wird Jof von Kirk verfolgt.
+
+SIEHE AUCH:
+  "RemovePursuer", "PreventFollow"
diff --git a/doc/lfun/AddReadDetail b/doc/lfun/AddReadDetail
new file mode 100644
index 0000000..c8de775
--- /dev/null
+++ b/doc/lfun/AddReadDetail
@@ -0,0 +1,80 @@
+AddReadDetail()
+
+FUNKTION:
+    void AddReadDetail(string|string*keys,
+                       string|string*|mapping|closure desc);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den Namen der Details.
+    desc
+      String, Mapping, String-Array oder Closure mit/zur Beschreibung.
+
+BESCHREIBUNG:
+    Die Beschreibung der Details <keys> wird gesetzt. Wie die Details
+    beim Lesen ausgegeben werden, haengt im wesentlichen vom Typ der
+    Beschreibung <desc> ab:
+      <desc> ist ein String.
+       Beim Lesen wird dieser String zurueckgegeben.
+      <desc> ist ein String-Array.
+       Beim Lesen wird zufaellig einer der Strings zurueckgegeben.
+      <desc> ist ein Mapping.
+        Das Mapping muss folgenden Aufbau haben:
+          ([0:        "Defaulttext",
+            "rasse1": "r1text", ...]).
+
+        Falls fuer die Rasse des das Detail untersuchenden Spielers ein
+        Eintrag im Mapping existiert, wird der entsprechende Text
+        zurueckgegeben, ansonsten der Defaulttext. Auf diese Weise sind
+        rassenabhaengige Texte moeglich.
+      <desc> ist eine Closure.
+        In diesem Fall wird die Closure ausgefuehrt und das Ergebnis
+        zurueckgegeben. Die Closure bekommt dabei den Namen des Details
+        als Parameter uebergeben.
+
+    Fuer lesbare Details koennen Forscherpunkte eingetragen werden.
+
+    Will man ein lesbares Detail an einem Objekt haben, welches der Spieler
+    mit "lies <id>" (<id> ist eine ID des Objekts) bekommt, muss man ein
+    Detail SENSE_DEFAULT hinzufuegen.
+    (Ein Detail "<id>" hinzuzufuegen, hat einen ganz anderes Effekt! Dieses
+     wuerde vom Spieler mit "lies <id> an <id>" gelesen werden und ist
+     meistens nicht das, was gewuenscht wird.)
+
+BEMERKUNGEN:
+    (1) Auf die 'desc' wird kein process_string() mehr angewendet.
+        Bitte stattdessen lfun closures bzw. 'inline closures'
+        verwenden.
+
+    (2) Im Gegensatz zum Verhalten von AddTouchDetail(), AddSmells() und
+        AddSounds() wirkt ein SENSE_DEFAULT-Detail in einem Raum nicht.
+        Ein einfaches "lies" bleibt dann ohne Rueckgabewert.
+
+BEISPIELE:
+    AddReadDetail( ({ "schild" }),
+      "BETRETEN STRENGSTENS VERBOTEN!\n" );
+
+    AddReadDetail("inschrift",
+                  ([0: "Dort steht: Ein Ring sie zu binden. ....\n",
+                    "elf": "Alles in dir straeubt sich, DAS DA zu lesen.\n"]));
+
+    AddReadDetail("regeln",
+      function string() {
+        this_player()->More("/etc/WIZRULES", 1);
+        return "";
+      });
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AddResistanceModifier b/doc/lfun/AddResistanceModifier
new file mode 100644
index 0000000..6476f86
--- /dev/null
+++ b/doc/lfun/AddResistanceModifier
@@ -0,0 +1,49 @@
+AddResistanceModifier()
+
+FUNKTION:
+     varargs int AddResistanceModifier(mapping mod, string add)
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+ARGUMENTE:
+     mapping mod:
+      Mapping mit Schadensarten und ihrem Resistenzmodifikator (der im Bereich
+      von -1.0 bis +x liegen kann), z.B. ([DT_FIRE:-1.0]) (Totalresistenz).
+     string add:
+      Ein Identifikator fuer _diesen_ Eintrag des setzenden Objektes.
+
+BESCHREIBUNG:
+     Es werden Resistenzen in dem Objekt gesetzt, die solange bestehen, wie
+     das setzende Objekt existiert, oder nicht RemoveResistanceModifier
+     (mit eventuellem Schluessel add) aufgerufen wird. Zusaetzliche Resistenzen
+     werden eingerechnet.
+
+BEMERKUNGEN:
+     Fuer Ruestungen kann und sollte man P_RESISTANCE_STRENGTHS verwenden.
+
+BEISPIELE:
+     // Oel mit vervierfachtem Feuerschaden
+     int add_action() {
+      ...
+      write(break_string("Du schuettest das Oel ueber "+
+			 npc->name(WEN)+".",78));
+      ...
+      npc->AddResistanceModifier(([DT_FIRE:3.0]), "oel");
+      SetProp(P_INVIS,1);
+      SetProp(P_EXTRA_LOOK, "Ueberall tropft Oel herunter.\n");
+      move(npc,M_NOCHECK);
+      ...
+     }
+
+RUeCKGABEWERT:
+     1 fuer Erfolg
+
+SIEHE AUCH:
+     Modifikatoren:	RemoveResistanceModifier(), P_RESISTANCE_MODIFIER
+     simple Resistenz:	P_RESISTANCE, P_VULNERABILITY
+     Hauptmapping:	P_RESISTANCE_STRENGTHS
+     Berechnung:	CheckResistance(), UpdateResistanceStrengths()
+     anderes:		balance, /std/armour/combat.c, /std/living/combat.c
+
+29.Apr 2002, Gloinson@MG
diff --git a/doc/lfun/AddRoomCmd b/doc/lfun/AddRoomCmd
new file mode 100644
index 0000000..5e206fe
--- /dev/null
+++ b/doc/lfun/AddRoomCmd
@@ -0,0 +1,13 @@
+AddRoomCmd()
+
+SYNTAX:
+	AddRoomCmd( string kommando, string funktion );
+	AddRoomCmd( string *kommandos, string funktion );
+
+FUNKTION:
+	
+	Diese Funktion ist veraltet. Sie wird vollstaendig durch
+	die Funktion AddCmd ersetzt.
+
+SIEHE AUCH:
+	"AddCmd"
diff --git a/doc/lfun/AddRoomMessage b/doc/lfun/AddRoomMessage
new file mode 100644
index 0000000..4a9ca12
--- /dev/null
+++ b/doc/lfun/AddRoomMessage
@@ -0,0 +1,80 @@
+AddRoomMessage()
+
+FUNKTION:
+     void AddRoomMessage(string *msg, int time, mixed *func);
+
+DEFINIERT IN:
+     /std/room/description.c
+
+ARGUMENTE:
+     msg
+          Array von Strings mit den Meldungen.
+     time
+          Der Abstand zwischen zwei Meldungen in Sekunden.
+     func (optional)
+          String oder Array von Strings mit Funktionsnamen
+
+BESCHREIBUNG:
+     Mit dieser Funktion legt man fest, dass in bestimmten Zeitabstaenden
+     Meldungen an den Raum geschickt werden sollen.
+
+     Es wird alle time Sekunden zufaellig eine der in msg angegebenen
+     Meldungen ausgegeben. Hat man auch noch func angegeben, so wird
+     zusaetzlich diese Funktion (bei einem Array: eine zufaellig ausgesuchte
+     Funktion) im Raum aufgerufen. Als Parameter bekommt die Funktion die
+     Nummer der ausgegebenen Meldung.
+
+     Bevor man allerdings jeden Raum mit AddRoomMessage() pflastert, sollte
+     man folgendes bedenken:
+        o Viele Meldungen in vielen Raeumen tendieren dazu, den Spielern auf
+          die Nerven zu gehen!
+        o Da das Timing ueber einen call_out() gesteuert wird, ist das Ganze
+          aus Sicht des GameDrivers auch noch relativ teuer!
+     Fazit: weniger ist mehr!
+
+BEMERKUNGEN:
+     * Falls time < 15 Sekunden ist, wird auf 15 Sekunden aufgerundet.
+     * der Praefix Add... taeuscht hier. Ein Aufruf von AddRoomMessage()
+       ueberschreibt alle vorherigen Werte
+     * THIS_PLAYER() NICHT VERWENDEN!
+     In Funktionen, die durch AddRoomMessage() ausgeloest werden, darf
+     this_player() nicht verwendet werden. AddRoomMessage ist call_out-
+     gesteuert und speichert somit das this_player(). Damit ist this_player()
+     immer der Spieler, der den Raum geladen, also den Raum als erster
+     betreten hat. 
+     Spieler also bitte selbst ueber filter(all_inventory(this_object()),
+                                            #'interactive) suchen.
+
+BEISPIELE:
+     Es soll alle halbe Minute eine Meldung ausgegeben werden. Falls es
+     unter den Fuessen knackt, soll man zudem mit 30%-iger
+     Wahrscheinlichkeit zusammenzucken:
+
+     inherit "/std/room";
+
+     void create() {
+       ::create();
+       AddRoomMessage( ({ "In der Ferne schreit ein Kaeuzchen.\n",
+                          "Es raschelt im Gebuesch.\n",
+                          "Etwas knackt unter Deinen Fuessen.\n" }),
+                        30, ({"sound", "sound_more_rnd"}) );
+       ...
+     }
+
+     void sound(int msg) {
+       if (msg == 2)         // Es hat geknackt...
+         if (random(10) < 3) // Schreck lass nach! ;-)
+           tell_room(this_object(), "Erschrocken faehrst Du zusammen!\n" );
+     }
+
+     // Extra-Beispiel: wir setzen die Wartedauer (Parameter tim) neu
+     void sound_more_rnd() {
+       sound(0);   // die Message-Nummer ist hier unwichtig
+       SetProp(P_MSG_PROB, 25+random(20));  // neue Wartedauer
+     }
+
+SIEHE AUCH:
+     Verwandt: tell_room(), ReceiveMsg()
+     Props:    P_ROOM_MSG, P_FUNC_MSG, P_MSG_PROB
+
+2.Feb 2016 Gloinson
diff --git a/doc/lfun/AddRoute b/doc/lfun/AddRoute
new file mode 100644
index 0000000..3ca0093
--- /dev/null
+++ b/doc/lfun/AddRoute
@@ -0,0 +1,84 @@
+AddRoute()
+FUNKTION:
+    public varargs void AddRoute(string room, int stay, int next, 
+        string harbour_desc, mixed dest_ids, string deststr)
+
+DEFINIERT IN:
+    /std/transport.c
+
+ARGUMENTE:
+    string room
+        Filename der Haltestelle (des Ziels)
+    int stay
+        Aufenthaltszeit an der Haltestelle.
+    int next
+        Fahrtzeit von dort bis zum naechsten Fahrplanpunkt
+    string harbour_desc
+        Name der Haltestelle (fuer QueryArrived)
+    mixed dest_ids
+        kleingeschriebene IDs der Haltestelle
+    string destrstr
+        Unbenutzt / Undefiniert.
+
+BESCHREIBUNG:
+    Dem Fahrplan des Transporters wird eine neue Haltestelle hinzugefuegt.
+
+    Bei Erreichen der Haltestelle wird der Transporter in den Raum 'room'
+    bewegt und sichtbar gemacht. Nun kann man ihn fuer 'stay' Sekunden
+    betreten oder verlassen, bevor er ablegt (unsichtbar gemacht wird).
+    Nach 'next' Sekunden wird dann der naechste Punkt des Fahrplans
+    ausgefuehrt.
+     
+    'harbour_desc' ist ein String, den QueryArrived() zurueckgibt, wenn sich
+    der Transporter an einer Haltestelle befindet. In der Regel ist das ein
+    String, der die Haltestelle naeher beschreibt.
+    
+    'dest_ids' ist ein Array von Strings, die als ID-Code fuer diese 
+    Haltstelle dienen. Das wird zB bei der Ermittlung einer Haltestelle bei 
+    "reise nach" benutzt. Wenn 'dest_ids' nicht gesetzt ist, und auch 
+    P_HARBOUR des Zielhafens nicht korrekt gesetzt ist, werden 
+    grossgeschriebene Begriffe aus 'harbour_desc' verwendet.
+
+BEISPIELE:
+    #1 Hier ein Auszug aus /d/inseln/schiffe/jolle.c:
+
+      AddRoute("/d/ebene/room/PortVain/po_haf2", 40,
+               10, "Hafen von Port Vain");
+
+    Die Jolle wird also beim Anlegen in den Port Vainer Hafen bewegt und
+    laesst sich dort 40 Sekunden lang betreten oder verlassen.
+    QueryArrived() liefert waehrend dieser Zeit den String "Hafen von Port
+    Vain" zurueck. Nach den 40 Sekunden legt die Jolle ab, und nach
+    weiteren 10 Sekunden wird die naechste Station in ihrem Fahrplan
+    angefahren.
+
+    #2 Die Galeere nach Orkhausen:
+      AddRoute(INSEL("steg"), 30, 20, "Verlorene Land ( Orkhausen )" );
+      - haelt 30 Sekunden
+      - reist 20 Sekunden
+      - reist nach INSEL("steg"), bekannt als "Verlorene Land ( Orkhausen )"
+      - da keine 'dest_ids' angegeben sind, waere eine so definierte 
+        Haltstelle nur mit den IDs ansprechbar, die in P_HARBOURS im Zielraum
+        angegeben sind.
+
+    Wenn man nun erreichen wollte, dass das Ziel auch mit dem Kuerzel "vland"
+    ansprechbar ist, kann man zum einen explizite 'dest_ids' eintragen:
+      AddRoute(INSEL("steg"), 30, 20, "Verlorene Land ( Orkhausen )",
+               ({"verlorenes", "land", "orkhausen", "vland"}));
+    Dies laesst sich im Zielhafen aber auch durch Eintragen des Kuerzels
+    "vland" in P_HARBOUR erreichen. Dies hat den Vorteil, dass dieser Hafen
+    dann von allen Transportern, die dort anlegen, unter demselben Namen
+    erreicht werden kann.
+    
+HINWEISE:
+    Dadurch, dass die Eintraege aus P_HARBOUR und 'dest_ids' gleichberechtigt
+    fuer "reise nach <ziel>" verwendet werden koennen, ist es moeglich,
+    dass die Reiseziele auf einem Schiff unter zusaetzlichen Bezeichnungen 
+    bekannt sind, als an Land (zum Beispiel koennte eine fernwestliche
+    Besatzung die Ziele anders nennen).
+
+SIEHE AUCH:
+Funktionen:  AddMsg(L), AddFun(L), /std/transport.c
+Properties:  P_HARBOUR, P_NO_TRAVELING, P_TRAVEL_INFO
+
+2015-Jan-18, Arathorn.
diff --git a/doc/lfun/AddSingularId b/doc/lfun/AddSingularId
new file mode 100644
index 0000000..d956567
--- /dev/null
+++ b/doc/lfun/AddSingularId
@@ -0,0 +1,27 @@
+AddSingularId()
+
+FUNKTION:
+     void AddSingularId(mixed id);
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     id
+          Identifikationsstring oder Array von Strings
+
+BESCHREIBUNG:
+     Es werden ein oder mehrere Bezeichner hinzugefuegt, mit denen sich eine
+     einzelne Einheit ansprechen laesst.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+     siehe /items/money.c
+
+SIEHE AUCH:
+     AddPluralId(), RemoveSingularId(), AddId(), id(), /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Mon Jul 14 11:31:00 1997 by Silvana
diff --git a/doc/lfun/AddSmells b/doc/lfun/AddSmells
new file mode 100644
index 0000000..5682f00
--- /dev/null
+++ b/doc/lfun/AddSmells
@@ -0,0 +1,71 @@
+AddSmells()
+
+FUNKTION:
+    void AddSmells(string|string* keys, string|string*|mapping|closure desc);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den Namen der Details.
+    desc
+      String, Mapping, String-Array oder Closure mit/zur Beschreibung.
+
+BESCHREIBUNG:
+    Diese Funktion entspricht dem AddDetail() fuer Standarddetails, nur
+    koennen hiermit Gerueche realisiert werden:
+    Die Beschreibung der Details <keys> wird gesetzt. Wie die Details
+    bei der Untersuchung aussehen, haengt im wesentlichen vom Typ der
+    Beschreibung <desc> ab:
+      <desc> ist ein String.
+        Beim Untersuchen wird dieser String zurueckgegeben.
+      <desc> ist ein String-Array.
+        Beim Untersuchen wird zufaellig einer der Strings zurueckgegeben.
+      <desc> ist ein Mapping.
+        Das Mapping muss folgenden Aufbau haben:
+          ([0:        "Defaulttext",
+            "rasse1": "r1text", ...]).
+
+        Falls fuer die Rasse des das Detail untersuchenden Spielers ein
+        Eintrag im Mapping existiert, wird der entsprechende Text
+        zurueckgegeben, ansonsten der Defaulttext. Auf diese Weise sind
+        rassenabhaengige Details moeglich. Siehe auch die Beispiele.
+      <desc> ist eine Closure.
+        In diesem Fall wird die Closure ausgefuehrt und das Ergebnis
+        zurueckgegeben. Die Closure bekommt dabei den Namen des Details
+        als Parameter uebergeben.
+
+    Fuer Geruchsdetails koennen Forscherpunkte eingetragen werden.
+
+    Gerueche koennen allgemein einen Raum oder Objekt zugeordnet werden:
+    dafuer muss man als <key> SENSE_DEFAULT uebergeben.
+    
+    Spielerkommandos: "riech", "rieche", "schnupper", "schnuppere"
+
+BEISPIELE:
+    Ein kleines Beispiel fuer rassenabhaengige Gerueche mit Closures:
+      string strafe(string key);
+      ...
+      AddSmells(SENSE_DEFAULT,
+        "Der Geruch von Knoblauch ist ueberwaeltigend!\n");
+      AddSmells(({"knoblauch","geruch"}),
+                ([0:        "Puhh, das stinkt!\n",
+                  "vampir": #'strafe]));
+      ...
+      string strafe(string key) {
+        this_player()->reduce_hit_points(100);
+        return "Der Knoblauch schmerzt dich furchtbar!\n";
+      }
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AddSounds b/doc/lfun/AddSounds
new file mode 100644
index 0000000..b38389a
--- /dev/null
+++ b/doc/lfun/AddSounds
@@ -0,0 +1,63 @@
+AddSounds()
+
+FUNKTION:
+    void AddSounds(string|string* keys, string|string*|mapping|closure desc);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den Namen der Details.
+    desc
+      String, Mapping, String-Array oder Closure mit/zur Beschreibung.
+
+BESCHREIBUNG:
+    Diese Funktion entspricht dem AddDetail() fuer Standarddetails, nur
+    koennen hiermit Geraeusche realisiert werden:
+    Die Beschreibung der Details <keys> wird gesetzt. Wie die Details
+    bei der Untersuchung aussehen, haengt im wesentlichen vom Typ der
+    Beschreibung <desc> ab:
+      <desc> ist ein String.
+        Beim Untersuchen wird dieser String zurueckgegeben.
+      <desc> ist ein String-Array.
+        Beim Untersuchen wird zufaellig einer der Strings zurueckgegeben.
+      <desc> ist ein Mapping.
+        Das Mapping muss folgenden Aufbau haben:
+          ([0:        "Defaulttext",
+           "rasse1": "r1text", ...]).
+
+        Falls fuer die Rasse des das Detail untersuchenden Spielers ein
+        Eintrag im Mapping existiert, wird der entsprechende Text
+        zurueckgegeben, ansonsten der Defaulttext. Auf diese Weise sind
+        rassenabhaengige Details moeglich. Siehe auch die Beispiele.
+      <desc> ist eine Closure.
+        In diesem Fall wird die Closure ausgefuehrt und das Ergebnis
+        zurueckgegeben. Die Closure bekommt dabei den Namen des Details
+        als Parameter uebergeben.
+
+    Fuer Geraeuschdetails koennen Forscherpunkte eingetragen werden.
+
+    Gerauesche koennen allgemein einen Raum oder Objekt zugeordnet werden:
+    dafuer muss man als <key> SENSE_DEFAULT uebergeben.
+
+    Spielerkommandos: "lausche", "lausch", "hoer", "hoere"
+
+BEISPIELE:
+    Ein kleines Beispiel fuer rassenabhaengige Gerauesche
+      AddSounds(SENSE_DEFAULT, "Die Zwergenmusik uebertoent alles!\n");
+      AddSounds(({"zwergenmusik","musik"}),
+                ([0      : "Seltsamer Krach!\n",
+                  "zwerg": "Das klingt einfach fantastisch!\n"]));
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSmells(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AddSpecialDetail b/doc/lfun/AddSpecialDetail
new file mode 100644
index 0000000..90c5543
--- /dev/null
+++ b/doc/lfun/AddSpecialDetail
@@ -0,0 +1,61 @@
+VERALTET: AddSpecialDetail()
+
+FUNKTION:
+    void AddSpecialDetail(string|string* keys, string func);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den Namen der Details.
+    func
+      String mit dem Namen der Funktion, die zur Auswertung aufgerufen
+      wird.
+
+BESCHREIBUNG:
+    Es wird ein Detail hinzugefuegt, dessen Inhalt nicht von vornherein
+    feststeht, sondern von aeusseren Bedingungen abhaengt. Zu diesem
+    Zweck wird immer, wenn dieses Detail untersucht wird, die Funktion
+    func aufgerufen, um den aktuellen Zustand des Details zu bestimmen.
+    Der Funktion wird als Parameter das Schluesselwort uebergeben, mit
+    dem das Detail untersucht wurde.
+
+    VERALTET: Bitte AddDetail mit Closure benutzen.
+
+BEISPIELE:
+    Ein zustandsabhaengiges Detail:
+
+      int hebel_betaetigt;
+      string hebel(string key);
+      ...
+      // ALT: AddSpecialDetail( ({ "hebel", "schalter" }), "hebel" );
+      AddDetail(({ "hebel", "schalter" }), #'hebel );
+      ...
+      string hebel(string key)
+      { if(hebel_betaetigt)
+          return "Der "+capitalize(key)+" steht auf EIN.\n";
+        else
+          return "Der "+capitalize(key)+" steht auf AUS.\n";
+      }
+
+    Man erhaelt verschiedene Ergebnisse beim Untersuchen, je nachdem
+    ob das Flag hebel_betaetigt gesetzt ist oder nicht.
+
+BEMERKUNG:
+    Intern werden Details und SpecialDetails im selben Mapping
+    verwaltet.
+    Man kann statt dieser Funktion deshalb auch AddDetail mit Closures
+    nutzen.
+
+SIEHE AUCH:
+    Setzen :   AddDetail(), AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AddSpecialExit b/doc/lfun/AddSpecialExit
new file mode 100644
index 0000000..de7e5b8
--- /dev/null
+++ b/doc/lfun/AddSpecialExit
@@ -0,0 +1,57 @@
+AddSpecialExit()
+FUNKTION:
+     void AddSpecialExit(string|string* cmd, string|closure func);
+
+DEFINIERT IN:
+     /std/room/exits
+
+ARGUMENTE:
+     string/string* cmd
+          die Richtung(en), in die der Ausgang fuehrt
+     string/closure func
+          der Name der aufzurufenden Funktion/Closure
+
+BESCHREIBUNG:
+     Es wird ein Ausgang in die Richtung(en) cmd eingefuegt. Wird der
+     Ausgang benutzt, so wird die Closure bzw. Funktion func ausgefuehrt.
+
+     AddSpecialExit(cmd, "func") entspricht:
+     - AddExit(keys, #'func)
+
+BEMERKUNGEN:
+     In func muss man den Spieler selbst in den Zielraum bewegen. Im
+     Erfolgsfall sollte man einen Wert >0 zurueckgeben, im Fehlerfall einen
+     Wert <=0.
+
+     func bekommt als Parameter einen String mit der gewaehlten
+     Bewegungsrichtung uebergeben.
+
+BEISPIELE:
+     // ein Ausgang soll nur von Froeschen benutzbar sein:
+
+     AddSpecialExit("loch", "lochfkt");
+     // der gleiche Aufruf, nur anders:
+     // static int lochfkt(string dir);		// Prototyp
+     // ...
+     // AddSpecialExit("loch", #'lochfkt);
+     // auch identisch zu:
+     // AddExit("loch", #'lochfkt);
+
+     static int lochfkt(string dir) {
+       if (!(this_player()->QueryProp(P_FROG))) {
+         // Kein Frosch => passt nicht!
+         notify_fail("Du bist zu gross!\n");
+         return 0;
+       }
+       // Meldungen werden im move() gleich mitgegeben
+       return this_player()->move("/room/loch", M_GO, 0,
+                    "huepft ins Loch", "huepft herein");
+     }
+
+SIEHE AUCH:
+     AddExit(), GetExits()
+     RemoveExit(), RemoveSpecialExit()
+     H_HOOK_EXIT_USE, P_EXITS, P_HIDE_EXITS, /std/room/exits.c
+     ausgaenge
+
+31.01.2015, Zesstra
diff --git a/doc/lfun/AddSpecialInfo b/doc/lfun/AddSpecialInfo
new file mode 100644
index 0000000..735983f
--- /dev/null
+++ b/doc/lfun/AddSpecialInfo
@@ -0,0 +1,64 @@
+AddSpecialInfo()
+FUNKTION:
+     varargs void AddSpecialInfo( frage, meldung
+			   [, indent [, [silent [, casebased] ] ] );
+
+ARGUMENTE:
+     string/string* frage
+	Schluesseltext(e) auf die Informationen gegeben werden sollen.
+     string/closure function
+	Methodenname im NPC/Closure
+     string indent
+	Text, der sich bei mehrzeiligen Meldungen wiederholen soll.
+     int/string silent
+	Ist silent gesetzt, so erfolgt Antwort nur an Fragenden.
+     string/closure casebased
+	Funktionsname oder Closure mit Returnwert string oder int.
+
+DEFINIERT IN:
+     /std/npc/info.c
+
+BESCHREIBUNG:
+     Wenn ein Spieler ein NPC mittels "frage <monstername> nach <frage>" nach
+     einer Information mit dem Schluessel frage fragt, so wird die Methode
+     "function" gerufen. Die Rueckgabe wird als Meldung ausgegeben.
+
+     Fuer die Beschreibung der weiteren Parameter siehe man AddInfo(L).
+
+     AddSpecialInfo(keys, "function", ...) entspricht:
+     - AddInfo(keys, #'function, ...) 
+
+BEMERKUNGEN:
+     Da AddSpecialInfo() und AddInfo() auf die gleichen Daten zugreifen,
+     kann man Informationen, die mit AddSpecialInfo() gesetzt wurden, auch
+     mit RemoveInfo() entfernen. Es gibt kein RemoveSpecialInfo().
+
+BEISPIELE:
+     // Das folgende Beispiel ist auch unter man AddInfo(L) zu finden.
+     ### dynamisch ###
+     AddSpecialInfo(({"keks","kekse"}),
+		    "query_kekse",	// der Methodenname
+		    "sagt: ");
+     // ist uebrigens das gleiche wie:
+     // static string query_kekse();
+     // ...
+     // AddInfo(({"keks","kekse"}),
+     //		#'query_kekse,		// ein Verweis auf die Methode
+     //		"sagt: ");
+     ...
+     static string query_kekse() {
+      if(present("keks"))
+       return("Ich hab noch welche. Aetsch!");
+      return("Menno. Keine mehr da!");
+     }
+
+     // "frage monster nach keks":
+     // - wenn es noch Kekse hat, hoeren alle:
+     //   "Das Monster sagt: Ich hab noch welche. Aetsch!
+     // - sonst:
+     //   "Das Monster sagt: "Menno. Keine mehr da!
+
+SIEHE AUCH:
+     AddInfo(L), RemoveInfo(L)
+
+7.Apr 2004 Gloinson
diff --git a/doc/lfun/AddSpell b/doc/lfun/AddSpell
new file mode 100644
index 0000000..dbc6869
--- /dev/null
+++ b/doc/lfun/AddSpell
@@ -0,0 +1,149 @@
+AddSpell()
+
+FUNKTION:
+    varargs int AddSpell(int rate, int damage, string TextForEnemy,
+                         string TextForOthers, string|string* dam_type,
+                         string func, int|mapping spellarg)
+
+DEFINIERT IN:
+    /std/npc/combat.c
+
+ARGUMENTE:
+    rate          - Relative Haeufigkeit der Anwendung (*),
+                    muss >= 0 sein
+    damage        - Der Schadenswert fuer Defend(),
+                    muss > 0 sein
+    TextForEnemy  - Text, den der Feind erhalten soll
+    TextForOthers - Text, den andere im Raum erhalten sollen
+    dam_type      - Schadenstyp(en) fuer Defend(),
+                    (Default: ({DT_MAGIC}) )
+    func          - Funktionsname, die nach Anwendung aufgerufen werden soll
+                    (Optional, gerufen an this_object(), bekommt als Argumente
+                     object enemy, int real_damage, string* dam_type)
+    spellarg      - Spell-Argument fuer Defend(), Default ist "1"
+
+BESCHREIBUNG:
+    Ermoeglicht einfache Angriffs-Zaubersprueche fuer NPCs. Das Ausfuehren von
+    Spells verursacht bei dem NPC keine KP-Kosten.
+
+    Mit P_SPELLRATE wird die generelle Wahrscheinlichkeit der Ausfuehrung
+    solcher Spells im Heartbeat angegeben, mit 'rate' kann man die relative
+    Wahrscheinlichkeit der Spells untereinander steuern.
+
+    (*) Relative Haeufigkeit heisst, dass sich alle 'rate' der Spells
+    aufaddieren und ein einzelnes 'rate' dann in Relation zur Gesamtsumme
+    steht. D.h. drei Spells mit 80, 10, 10 (Summe 100) haben die selben
+    Aufruf-Wahrscheinlichkeiten wie drei Spells mit 120, 15, 15 oder drei
+    Spells mit 160, 20, 20.
+
+    Ein Spell wird immer in folgender Reihenfolge abgearbeitet:
+     1. Die Texte werden an die Beteiligten ausgegeben.
+     2. Es wird ggf. SpellDefend gerufen (wenn kein SP_PHYSICAL_ATTACK).
+        Abbruch bei Schutz.
+     3. Im Opfer wird Defend() mit den angegebenen Werten aufgerufen.
+        Abbruch bei Tod/Zerstoerung des Opfers.
+     4. Eine Funktion, so definiert, wird ausgefuehrt.
+
+BEMERKUNGEN:
+    TextForOthers wird vor der Ausgabe der Meldung durch replace_personal()
+    geschickt, d.h. es koennen Platzhalter wie @WER1, @WEMQP1 und aehnliche
+    verwendet werden (siehe auch die Manpage von replace_personal()).
+    Da Ersetzungen nur fuer das Gegnerobjekt beruecksichtigt werden, koennen
+    nur Platzhalter mit Endziffer 1 verwendet werden. Die Ersetzungen werden
+    so gesteuert, dass die eingefuegten Namen nach Satzanfaengen automatisch
+    gross geschrieben werden.
+    Frueher wurden statt replace_personal() die Platzhalter @WER, @WESSEN, 
+    @WEM, @WEN verwendet. Diese funktionieren weiterhin, sollten aber nicht 
+    mehr in neuem Code benutzt werden.
+
+    In der von AddSpell gerufenen Methode "func" koennen speziellere
+    Sachen mit dem aktuellen Feind angestellt werden koennen. Die Methode
+    darf als Sichtbarkeitsmodifikator maximal "", "public" oder "static"
+    (obsolet) haben und muss im selben Objekt definiert sein.
+
+    Will man einen physischen Angriff ausloesen, MUSS <spellarg> ein Mapping
+    mit ([SP_PHYSICAL_ATTACK: 1]) sein. Bei Uebergeben einer 0 oder Weglassen
+    des Werts wird an Defend das Default '1' (da es Spells sind) uebergeben.
+
+    Wenn damage<=0 oder rate<0 oder keine Meldungen uebergeben werden, wird
+    der Spell NICHT eingetragen, sondern die Funktion bricht mit Rueckgabe
+    von 0 ab.
+
+BEISPIELE:
+    // #1 Einfacher NPC mit drei Spells, Gesamtrate = 100, also sind die
+    //    Raten direkt als Prozent Aufrufwahrscheinlichkeit lesbar.
+    AddSpell(80, 400,
+             "Der Hexer greift Dich mit einem kleinen Feuerball an.\n",
+             "Der Hexer greift @WEN mit einem kleinen Feuerball an.\n",
+             ({DT_FIRE, DT_MAGIC}));
+    AddSpell(10, 800,
+             "Der Hexer greift Dich mit einem riesigen Feuerball an.\n",
+             "Der Hexer greift @WEN mit einem riesigen Feuerball an.\n",
+             ({DT_FIRE, DT_MAGIC}));
+    AddSpell(8, 100,
+             "Der Hexer piekst Dir in die Augen!",
+             "Der Hexer piekst @WEM in die Augen!", ({DT_PIERCE}),
+             "augen_stechen");
+    AddSpell(2, 5, (string)0, (string)0, (string*)0, "salto_mortalis");
+
+    (Kleiner Feuerball mit 80% Wahrscheinlichkeit, riesiger mit 10%,
+     "augen_stechen" mit 8%, "salto_mortalis" mit 2%)
+
+    // Die Funktion "augen_stechen" kann dann so aussehen:
+    void augen_stechen(object enemy, int damage, mixed dam_types ) {
+      if (damage>10 && !enemy->QueryProp(P_BLIND)) {
+        enemy->SetProp(P_BLIND, 1);
+        if(enemy->QueryProp(P_BLIND))
+          tell_object(enemy, "Du bist nun blind!\n");
+      }
+    }
+
+    // Zur Funktion "salto_mortalis" gibt es keine Meldungen, dennoch
+    // wird Defend mit: enemy->Defend(5, ({DT_MAGIC}), 1, this_object())
+    // gerufen!
+    void salto_mortalis(object enemy, int damage, mixed dam_types ) {
+      // dem geneigten Leser ueberlassen, den Gegner zu toeten
+    }
+
+    // #2 Physische Angriffe: die Ruestungen sollen beruecksichtigt werden!
+    //    SP_PHYSICAL_ATTACK muss in einem Mapping auf 1 gesetzt werden,
+    //    damit Ruestungen physisch wirken (ansonsten werden nur ihre
+    //    DefendFuncs() ausgewertet). Es muss auch eine physische Schadensart
+    //    enthalten sein!
+    //    SpellDefend() wird bei diesem Flag nicht mehr am Gegner gerufen.
+    AddSpell(100, 200+random(200),
+      "Die kleine Ratte beisst Dich!\n",
+      "@WER wird von einer kleinen Ratte gebissen!\n",
+      ({DT_PIERCE, DT_POISON}), (string)0,
+      ([SP_PHYSICAL_ATTACK:1]));
+
+    // #3 Selektive physische Angriffe (siehe auch man Defend_bsp):
+    //    Will man erreichen, dass einige Ruestungen wirken, andere aber
+    //    nicht oder nur teilweise, kann man das ueber die Spellparameter
+    //    ausfuehrlich steuern:
+
+    // erstmal fuer alle Ruestungsarten einen Schutz von 0% einstellen:
+    mapping armours = map_indices(VALID_ARMOUR_CLASS, #'!);
+    armours[AT_TROUSERS] = 120;  // 120% Schutz durch Hosen
+    armours[AT_BOOT] = 30;       //  30% Schutz durch Stiefel
+
+    AddSpell(20,200+random(200),
+      "Die kleine Ratte beisst Dir blitzschnell in die Wade!\n",
+      "@WER wird von einer kleinen Ratte in die Wade gebissen!\n",
+      ({DT_PIERCE, DT_POISON}), (string)0,
+      ([SP_PHYSICAL_ATTACK:1, SP_NO_ACTIVE_DEFENSE:1,
+        SP_REDUCE_ARMOUR: armours]));
+
+    // SP_NO_ACTIVE_DEFENSE = 1 schaltet aktive Abwehr (Karate/Klerus) ab
+    // SP_REDUCE_ARMOUR enthaelt eine Liste von Ruestungstypen mit ihren
+    // neuen Wirkungsgraden in Prozent. Nicht enthaltene Ruestungen haben
+    // weiterhin 100% Schutzwirkung.
+
+SIEHE AUCH:
+     Sonstiges:  SpellAttack, SpellDefend, Defend, QueryDefend, SelectEnemy
+                 replace_personal
+     Properties: P_DISABLE_ATTACK, P_SPELLRATE, P_AGGRESSIVE
+     Abwehr:     Defend, Defend_bsp, SpellDefend
+     Methoden:   modifiers
+
+11.12.2015 Arathorn
diff --git a/doc/lfun/AddToMenu b/doc/lfun/AddToMenu
new file mode 100644
index 0000000..82407f4
--- /dev/null
+++ b/doc/lfun/AddToMenu
@@ -0,0 +1,233 @@
+AddToMenu()
+
+FUNKTION:
+        varargs string AddToMenu(string  menuetext,
+                                 mixed   ids,
+                                 mapping minfo,
+                                 mixed   rate,
+                                 mixed   msg,
+                                 mixed   refresh,
+                                 mixed   delay,
+                                 mixed   d_msg);
+
+DEFINIERT IN:
+        /std/pub.c
+
+ARGUMENTE:
+        Die Erlaeuterung der Parameter beschraenkt sich im Folgenden
+        zunaechst auf die Grundfunktionalitaet bei Verwendung fester
+        Werte. Die Moeglichkeiten zur Realisierung dynamischen Verhaltens
+        sind in den Fussnoten zu den einzelnen Parametern beschrieben.
+
+        menuetext
+          Der Text steht als kurze Beschreibung im Menue.
+        ids
+          String oder Array von Strings, mit denen sich die Speise bzw. das
+          Getraenk beim Bestellen ansprechen laesst.
+        minfo
+          Mapping mit Eintraegen fuer:
+          P_HP      LP-Heilung in Punkten [*]
+          P_SP      KP-Heilung in Punkten [*]
+          P_FOOD    Saettigungswirkung der Speise [*]
+          P_DRINK   Saettigungswirkung des Getraenks [*]
+          P_ALCOHOL Alkoholgehalt des Getraenks [*]
+          P_VALUE   Preis der Speise bzw. des Getraenks [*]
+        rate [*]
+          Heilrate in Punkten pro HeartBeat.
+        msg [**]
+          Meldung beim Essen:
+          Array mit 2 Strings: (1) fuer Empfaenger, (2) fuer Andere.
+          Verfuegbare Platzhalter sind weiter unten im Abschnitt "Beispiel"
+          dokumentiert.
+        refresh
+          Mapping mit Eintraegen fuer:
+            PR_USER (Kontingent fuer einzelnen Spieler) [*]
+            PR_ALL  (Zusatzkontingent fuer alle) [*]
+          Alternativ: 0 fuer unbegrenzte Verfuegbarkeit
+          Einem Key muessen dabei zwei Werte zugeordnet werden:
+          Der Erste gibt die Hoehe des Kontingents an, der Zweite legt
+          fest, alle wieviel reset()s das Kontingent wieder aufgefuellt
+          wird.
+          Verwendung des Mappings erfordert Inkludieren von pub.h.
+        delay [*]
+          Zahl der Sekunden, um die verzoegert die Heilung eintritt,
+          z.B. weil das Essen erst zubereitet werden muss.
+        d_msg [**]
+          Meldung beim Bestellen, falls die Heilung verzoegert wird
+          Array mit 2 Strings: (1) fuer Empfaenger, (2) fuer Andere.
+
+          
+        [*] Dieser Parameter kann statt eines festen Zahlenwerts mit 
+            folgenden Werten gefuellt werden:
+
+            1) Mapping <racemodifier> der Form:
+                   ([ 0 : <standardwert> ,
+                    <rasse_1> : <wert_1>, 
+                    ... , 
+                    <rasse_n> : <wert_n> ]).
+               Die Eintraege in diesem Mapping werden gegen die Rasse des
+               bestellenden Spielers geprueft und entsprechend die 
+               zugehoerigen Werte verwendet.
+            2) string <func>: Aufruf erfolgt mittels 
+                 call_other(this_object(), func, empfaenger);
+               gerufen (aber: siehe Hinweise).
+            3) closure <func>: Aufruf erfolgt mittels
+                 funcall(func, empfaenger);
+            4) Array der Form  ({string <obj>, string <func>}) oder
+                               ({object <obj>, string <func>})
+               Aufruf erfolgt mittels
+                 call_other(obj, func, empfaenger);
+               (aber: siehe Hinweise). <obj> ist folglich als Objektpointer 
+               oder dessen object_name() anzugeben. <func> wird mittels 
+               function_exists() auf Existenz ueberprueft.
+
+               HINWEISE: im Falle von Lieferverzoegerung ("delay") und
+               Preis (P_VALUE) wird bei allen Funktionsaufrufen NICHT der 
+               Empfaenger, sondern der Zahler uebergeben.
+               Im Falle der Kontingent-Liste ("refresh") kann nur die
+               verfuegbare Menge modifiziert werden, nicht die Zeit
+               bis zum Wieder-Auffuellen.
+
+        [**] Zur Erzeugung variabler Meldungen koennen folgende Werte
+             eingetragen werden:
+
+             1) closure <func>: Aufruf erfolgt mittels 
+                  funcall(func, zahler, empfaenger, ident, minfo);
+             2) string <func>: Aufruf erfolgt mittels
+                  call_other(this_object(), func, zahler, empfaenger, 
+                             ident, minfo);
+             <func> bekommt Zahler und Empfaenger als Objektpointer,
+             ident als String und minfo als Mapping mit den 
+             jeweiligen Heilwerten uebergeben. minfo entspricht hierbei
+             den Daten, die als dritter Parameter an AddToMenu()
+             uebergeben wurden.
+             HINWEIS: wenn in das minfo-Mapping keine int-Festwerte 
+             eingetragen wurden, werden diese gemaess den Regeln unter [*]
+             geprueft; Funktionen/Closures werden ggf. ausgewertet und 
+             deren Rueckgabewerte an die Funktion <func> uebergeben.
+             WICHTIG: Die Rueckgabewerte der Funktion werden nicht 
+             ausgewertet. Jeder, der anstatt einer Meldung einen 
+             Funktionsaufruf programmiert, muss fuer die Ausgabe der
+             Meldungen selbst sorgen.
+                   
+BESCHREIBUNG:
+        Mit dieser Funktion werden Speisen oder Getraenke in die Karte
+        von Kneipen und Restaurants eingefuegt.
+
+RUECKGABEWERT:
+        Rueckgabewert ist ein String "menuentry%d", wobei %d eine Nummer
+        ist, die darueber Auskunft gibt, den wievielten Eintrag in die
+        interne Karte der Kneipe diese Speise bzw. dieses Getraenk
+        darstellt. Im Prinzip handelt es sich bei dem String um einen Key
+        fuer ein Mapping, in dem die Speisen bzw. Getraenke gespeichert
+        sind.
+
+BEMERKUNGEN:
+        Die aelteren Funktionen 'AddDrink' bzw. 'AddFood' werden zwar mithilfe
+        dieser maechtigeren Funktion aus Gruenden der Abwaertskompatibilitaet
+        simuliert, sollen aber nicht mehr eingesetzt werden.
+        
+        Fuer das Testen der Kneipe gibt es in jeder Kneipe den Befehl
+        'pubinit'. Hiermit lassen sich die Speisen und Getraenke durch-
+        checken. Steht in der Ausgabe bei einem Getraenk/Essen ein FAIL,
+        so wird die entsprechende Speise (oder Getraenk) NICHT an Spieler
+        verkauft. Ausnahmen fuer Speisen/Getraenke mit hoeheren maximalen
+        Werten sind durch Balance-EM zu genehmigen.
+
+BEISPIEL:
+
+        include <pub.h>
+
+        create()
+        {
+        AddToMenu("'Opa's Drachenkeule'",({"drachenkeule","keule"}),
+        ([P_HP:63,P_SP:63,P_FOOD:9,P_VALUE:528]), 5,
+        ({"Du isst die Keule mit einem schlechten Gewissen.",
+          "&& isst die Keule mit einem schlechten Gewissen."}),
+        ([ PR_USER : 4; 1 , PR_ALL : 20; 3 ]), 9,
+        ({"Der unsichtbare Kneipier schneidet einem Rentner ein grosses "
+          "Stueck aus dessen Keule und bereitet sie Dir zu. Komisch, muss "
+          "wohl ein Tippfehler auf der Karte gewesen sein.",
+          "Der unsichtbare Kneipier schneidet einem hilflosen Opa ein "
+          "Stueck aus dessen Keule und braet diese fuer &&."}) );
+        }
+
+        1) Name der Speise (des Getraenks) auf der Karte (bei menue).
+
+           AddToMenu("'Opa's Drachenkeule'",     
+
+        2) ids mit denen sich bestellen laesst (z.B. "kaufe keule").
+
+           ({"drachen","drachenkeule","keule"}),
+
+        3) Heilung fuer LP und KP, Saettigung (P_FOOD oder P_DRINK,
+           P_ALCOHOL nach Belieben setzen), Preis (P_VALUE). 
+           HP und SP muessen nicht gleich sein. Speisen und Getraenke,
+           die nur eines von beiden heilen, sind auch moeglich.
+
+           ([P_HP:63,P_SP:63,P_FOOD:9,P_VALUE:528]),
+
+        4) Heilung pro Heartbeat (in diesem Beispiel je 5 KP/LP).
+    
+           5,
+
+        5) Meldungen fuer Spieler und Umstehende die bei Genuss ausgege-
+           ben werden (also NICHT der Bestell-Text).
+
+           ({"Du isst die Keule mit einem schlechten Gewissen.",
+             "&& isst die Keule mit einem schlechten Gewissen."}),
+
+           Verfuegbare Platzhalter sind (pl = this_player()):
+
+           &&  - pl->name(WER,2)
+           &1& - pl->name(WER,2)
+           &2& - pl->name(WESSEN,2)
+           &3& - pl->name(WEM,2)
+           &4& - pl->name(WEN,2)
+           &1# - capitalize(pl->name(WER,2))
+           &2# - capitalize(pl->name(WESSEN,2))
+           &3# - capitalize(pl->name(WEM,2))
+           &4# - capitalize(pl->name(WEN,2))
+           &!  - pl->QueryPronoun(WER)
+           &5& - pl->QueryPronoun(WE);
+           &6& - pl->QueryPronoun(WESSEN)
+           &7& - pl->QueryPronoun(WEM)
+           &8& - pl->QueryPronoun(WEN)
+           &5# - capitalize(pl->QueryPronoun(WER))
+           &6# - capitalize(pl->QueryPronoun(WESSEN))
+           &7# - capitalize(pl->QueryPronoun(WEM))
+           &8# - capitalize(pl->QueryPronoun(WEN))
+          
+        6) Die Speise ist in ihrer Anzahl begrenzt. Fuer jeden Spieler
+           sind 4 Keulen pro reset() da. Ausserdem gibt es noch einen
+           "Notvorrat" von 20 Keulen, der alle 3 reset()s aufgefuellt
+           wird. Aus diesem (so noch vorhanden) werden die Spieler
+           versorgt, wenn ihr "persoenlicher Vorrat" aufgebraucht ist.
+
+           ([ PR_USER : 4; 1 , PR_ALL : 20; 3 ]),
+           
+           HINWEIS: bei Benutzung des Mappings muss <pub.h> inkludiert 
+           werden!
+           
+           Wenn man keine reset-abhaengigen Speisen haben moechte, traegt
+           man hier eine 0 ein.
+
+        7) Die Zahl ist die Wartezeit in Sekunden, die der Wirt z.B. fuer
+           die Zubereitung und Auslieferung an den Spieler braucht.
+
+           9,
+         
+        8) Letztendlich die Meldungen an Spieler und Umstehende, die bei Be-
+           stellung (hier 'kaufe keule') ausgegeben werden.
+
+           ({"Der unsichtbare Kneipier schneidet einem Rentner ein grosses "
+           "Stueck aus dessen Keule und bereitet sie Dir zu. Komisch, muss "
+           "wohl ein Tippfehler auf der Karte gewesen sein.",
+           "Der unsichtbare Kneipier schneidet einem hilflosen Opa ein "
+           "Stueck aus dessen Keule und braet diese fuer &&."}));
+
+SIEHE AUCH:
+        AddFood(), AddDrink(), /sys/pub.h
+        RemoveFromMenu()
+----------------------------------------------------------------------------
+Last modified: Sam, 01. Okt 2011, 23:40 by Arathorn
diff --git a/doc/lfun/AddTouchDetail b/doc/lfun/AddTouchDetail
new file mode 100644
index 0000000..413e3ca
--- /dev/null
+++ b/doc/lfun/AddTouchDetail
@@ -0,0 +1,71 @@
+AddTouchDetail()
+
+FUNKTION:
+    void AddTouchDetail(string|string* keys,
+                        string|string*|mapping|closure desc);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+     String oder Array von Strings mit den Namen der Details.
+    desc
+     String, Mapping, String-Array oder Closure mit/zur Beschreibung.
+
+BESCHREIBUNG:
+    Diese Funktion entspricht dem AddDetail() fuer Standarddetails, nur
+    koennen hiermit (ab)tastbare bzw. fuehlbare Details realisiert werden:
+    Die Beschreibung der Details <keys> wird gesetzt. Wie die Details
+    beim (Ab)Tasten aussehen, haengt im wesentlichen vom Typ der
+    Beschreibung <desc> ab:
+     <desc> ist ein String.
+       Beim Untersuchen wird dieser String zurueckgegeben.
+      <desc> ist ein String-Array.
+        Beim Untersuchen wird zufaellig einer der Strings zurueckgegeben.
+     <desc> ist ein Mapping.
+       Das Mapping muss folgenden Aufbau haben:
+         ([0:        "Defaulttext",
+           "rasse1": "r1text", ...]).
+
+       Falls fuer die Rasse des das Detail untersuchenden Spielers ein
+       Eintrag im Mapping existiert, wird der entsprechende Text
+       zurueckgegeben, ansonsten der Defaulttext. Auf diese Weise sind
+       rassenabhaengige Details moeglich. Siehe auch die Beispiele.
+     <desc> ist eine Closure.
+       In diesem Fall wird die Closure ausgefuehrt und das Ergebnis
+       zurueckgegeben. Die Closure bekommt dabei den Namen des Details
+       als Parameter uebergeben.
+
+    Fuer fuehlbare Details koennen Forscherpunkte eingetragen werden.
+
+    Fuehlbare Details koennen allgemein einen Raum oder Objekt zugeordnet
+    werden: dafuer muss man als <key> SENSE_DEFAULT uebergeben.
+
+    Spielerkommandos: "taste"
+
+BEISPIELE:
+    Ein kleines Beispiel fuer rassenabhaengige, fuehlbare Details mit Closures:
+      string strafe(string key);
+      ...
+      AddTouchDetail(SENSE_DEFAULT, "Du fuehlst einige Knollen\n");
+      AddTouchDetail(({"knollen"}),
+                     ([0:       "Sie fuehlen sich an wie Knoblauchknollen. "
+                                "Riech doch mal daran.\n",
+                       "vampir": #'strafe]));
+
+      string strafe(string key) {
+        this_player()->reduce_hit_points(100);
+        return "Au! Das waren ja Knoblauchknollen!\n";
+      }
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSmells(), AddSounds()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/AllGroups b/doc/lfun/AllGroups
new file mode 100644
index 0000000..8ffbbca
--- /dev/null
+++ b/doc/lfun/AllGroups
@@ -0,0 +1,21 @@
+AllGroups()
+FUNKTION:
+     string *AllGroups()
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+BESCHREIBUNG:
+     Gibt ein Array aller existenten Materialgruppen zurueck (ihre
+     Definitionsform wie in <thing/material.h> aufgelistet).
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Listen:	  AllMaterials(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/AllMaterials b/doc/lfun/AllMaterials
new file mode 100644
index 0000000..6230e9b
--- /dev/null
+++ b/doc/lfun/AllMaterials
@@ -0,0 +1,21 @@
+AllMaterials()
+FUNKTION:
+     string *AllMaterials()
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+BESCHREIBUNG:
+     Gibt ein Array aller existenten Materialien zurueck (ihre Definitions-
+     form wie in <thing/material.h> aufgelistet).
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Listen:	  AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/AssocMember b/doc/lfun/AssocMember
new file mode 100644
index 0000000..349157b
--- /dev/null
+++ b/doc/lfun/AssocMember
@@ -0,0 +1,52 @@
+
+AssocMember()
+
+
+FUNKTION:
+        int AssocMember(object npc)
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        Der zuzuordnende NPC.
+
+BESCHREIBUNG:
+        Ordnet einen NPC einem Spieler zu. Dieser ist dann
+        immer im Team des Spielers, moeglichst in der gleichen Reihe.
+
+RUECKGABEWERT:
+        1, falls Zuordnung erfolgreich, sonst 0.
+
+BEISPIEL:
+        void fun(object pl)
+        {
+          if ( pl && pl->AssocMember(this_object()) )
+            tell_object(pl,break_string(
+              "Ich kaempfe nun auf Deiner Seite!\n",78,"Ein Feuerteufel "
+              "teilt Dir mit:");
+         ...
+        }
+
+BEMERKUNGEN:
+        1. Kann nur von Gilden, Spellbooks, vom Objekt selber und vom
+           zuzuordnenden NPC aufgerufen werden.
+        2. Einem NPC, der selber einem Spieler zugeordnet ist, kann kein
+           NPC zugeordnet werden.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_TEAM_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 04.10.2011, Zesstra
+
diff --git a/doc/lfun/Attack b/doc/lfun/Attack
new file mode 100644
index 0000000..4656ae9
--- /dev/null
+++ b/doc/lfun/Attack
@@ -0,0 +1,22 @@
+Attack()
+
+FUNKTION:
+	void Attack(object enemy)
+
+ARGUMENTE:
+	enemy: Der Feind.
+
+BESCHREIBUNG:
+	Der Feind wird der Staerke der Waffe (bzw. der Haende) entsprechend
+	stark angegriffen.
+
+RUECKGABEWERT:
+	Keiner.
+
+BEMERKUNG:
+	Diese Funktion gibt die Angriffsmeldung aus.
+	Falls mit blossen Haenden angegriffen wird, ist die Staerke
+	(2*Staerke_der_Haende + 10*A_STR)/3
+
+SIEHE AUCH:
+	"Defend", "QueryDamage"
diff --git a/doc/lfun/BecomesNetAlive b/doc/lfun/BecomesNetAlive
new file mode 100644
index 0000000..22a6cdc
--- /dev/null
+++ b/doc/lfun/BecomesNetAlive
@@ -0,0 +1,46 @@
+BecomesNetAlive()
+
+FUNKTION:
+    void BecomesNetAlive(object pl);
+
+GERUFEN VON:
+    /std/player/base.c
+
+ARGUMENTE:
+    pl
+      Spieler, der Verbindung zum MUD wiedererlangt.
+
+BESCHREIBUNG:
+    Spieler, welche die Verbindung zum MUD freiwillig
+    (z.B. per 'schlafe ein') oder unfreiwillig verlieren, gehen in den
+    Netztotenstatus ueber. Sie verbleiben noch eine definierte Zeit in
+    der zuletzt betretenen Umgebung und werden schliesslich automatisch
+    in den Netztotenraum ueberfuehrt.
+    Wird die Verbindung wieder aufgebaut, so wird der Spielercharakter
+    wieder zum Leben erweckt und gegebenenfalls zuvor aus dem
+    Netztotenraum zurueck zu seiner letzten Umgebung teleportiert.
+    Um nun einen Ueberblick darueber zu erhalten, wann ein Spieler die
+    Verbindung zum MUD wiederherstellt, gibt es die Funktion
+    BecomesNetAlive(). Sie wird automatisch in der Umgebung des
+    Spielers, in allen Objekten in der Umgebung des Spielers
+    (nicht rekursiv) und in allen Objekten im Spieler (rekursiv)
+    aufgerufen. Uebergeben wird hierbei das Spielerobjekt.
+
+    Es gibt auch noch die Funktion BecomesNetDead(), mit der man
+    auf aehnliche Weise einschlafende Spieler registrieren kann.
+
+BEISPIELE:
+    In einem NPC waere folgendes denkbar:
+    
+    void BecomesNetAlive(object pl) {
+      tell_room(environment(),break_string(
+        "Guten Morgen "+pl->name(WER)+", auch schon ausgeschlafen?!", 77,
+        Name(WER)+" sagt grinsend: "));
+    }
+    Steht der NPC in einem Raum, wo ein Spieler aufwacht, so wird der
+    Spieler gebuehrend begruesst.
+
+SIEHE AUCH:
+    BecomesNetDead(), PlayerQuit(), /std/player/base.c, /room/netztot.c
+
+24. Aug 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/BecomesNetDead b/doc/lfun/BecomesNetDead
new file mode 100644
index 0000000..fcfed7c
--- /dev/null
+++ b/doc/lfun/BecomesNetDead
@@ -0,0 +1,45 @@
+BecomesNetDead()
+
+FUNKTION:
+    void BecomesNetDead(object pl);
+
+GERUFEN VON:
+    /std/player/base.c
+
+ARGUMENTE:
+    object pl
+      Spieler, der Verbindung zum MUD verliert.
+
+BESCHREIBUNG:
+    Spieler, welche die Verbindung zum MUD freiwillig
+    (z.B. per 'schlafe ein') oder unfreiwillig verlieren, gehen in den
+    Netztotenstatus ueber. Sie verbleiben noch eine definierte Zeit in
+    der zuletzt betretenen Umgebung und werden schliesslich automatisch
+    in den Netztotenraum ueberfuehrt.
+    Um nun einen Ueberblick darueber zu erhalten, wann ein Spieler die
+    Verbindung zum MUD verliert, gibt es die Funktion BecomesNetDead().
+    Sie wird automatisch in der Umgebung des Spielers, in allen Objekten
+    in der Umgebung des Spielers (nicht rekursiv) und in allen Objekten
+    im Spieler (rekursiv) aufgerufen. Uebergeben wird hierbei das
+    Spielerobjekt.
+
+    Es gibt auch noch die Funktion BecomesNetAlive(), mit der man
+    auf aehnliche Weise erwachende Spieler registrieren kann.
+
+BEISPIELE:
+    Es gibt Gebiete, in denen netztote Spieler unerwuenscht sind.
+    Folgendermassen kann man sich ihrer wirkungsvoll entledigen:
+    
+    void BecomesNetDead(object pl) {
+      pl->move("eingangsraum zu gebiet", M_TPORT|M_NOCHECK);
+    }
+    Man schickt diese Spieler wieder zum Eingang des Gebietes.
+    Da der letzte Aufenthaltsort eines Spielers, der in den
+    Netztotenstatus uebergeht, erst nach Aufruf der Funktion
+    BecomesNetDead() abgespeichert wird, wacht der Spieler dann an dem
+    Ort auf, wo man Ihn innerhalb dieser Funktion hinteleportiert hat.
+
+SIEHE AUCH:
+    BecomesNetAlive(), PlayerQuit(), /std/player/base.c, /room/netztot.c
+
+24. Aug 2011, Gloinson
\ No newline at end of file
diff --git a/doc/lfun/CannotSee b/doc/lfun/CannotSee
new file mode 100644
index 0000000..3869541
--- /dev/null
+++ b/doc/lfun/CannotSee
@@ -0,0 +1,30 @@
+CannotSee()
+
+FUNKTION:
+     varargs int CannotSee(int silent);
+
+DEFINIERT IN:
+     /std/living/light.c
+
+ARGUMENTE:
+     silent - Soll an das Lebewesen direkt automatisch eine Meldung
+              ausgegeben werden wenn es nichts sehen kann?
+
+BESCHREIBUNG:
+     Diese Funktion prueft ob das Lebewesen etwas sehen kann, oder nicht.
+     Hierbei wird sowohl das Lichtlevel mit saemtlichen Modifikatoren,
+     als auch Nachtsicht und die Property P_BLIND beruecksichtigt. Da
+     diese Funktion bei zukuenftigen Mudlibaenderungen immer aktualisiert
+     werden duerfte, sollte man sie nach Moeglichkeit benutzen und die
+     Abfragen nicht selbst implementieren.
+
+RUeCKGABEWERT:
+     0, wenn der Spieler etwas sehen kann
+     1, wenn der Spieler nichts sehen kann: Blindheit
+     2, wenn der Spieler nichts sehen kann: zu wenig Licht/keine Nachtsicht
+
+SIEHE AUCH:
+     P_BLIND, P_LIGHT_MODIFIER, P_PLAYER_LIGHT
+
+----------------------------------------------------------------------------
+Last modified: Mon Jan 17 18:22:27 2000 by Padreic
diff --git a/doc/lfun/ChangeMiniQuest b/doc/lfun/ChangeMiniQuest
new file mode 100644
index 0000000..a6bfb7d
--- /dev/null
+++ b/doc/lfun/ChangeMiniQuest
@@ -0,0 +1,48 @@
+FUNKTION:
+    int ChangeMiniQuest(mixed questgeber, int parameter, mixed newvalue)
+
+DEFINIERT IN:
+    /secure/questmaster
+
+BESCHREIBUNG:
+    Diese Funktion aendert einen Parameter einer Miniquest im Questmaster,
+    schreibt fuer diese Aktion einen Log-Eintrag und erstellt das Miniquest-
+    Dumpfile neu.
+
+ARGUMENTE:
+    questgeber - Ladename des Objekts (string), das die Miniquest vergibt, 
+                 oderdie Indexnummer (int) der Miniquest in der MQ-Liste
+    parameter  - Angabe des zu aendernen Parameters (Position des Values
+                 im Miniquests-Mapping):
+                 0 : Miniquest-Stufenpunkte, mind. 1
+                 2 : Aufgabenbeschreibung der Miniquest (string)
+                 3 : Sichtbarkeit der Miniquest (0/1), default ist 1
+                 4 : aktiv/inaktiv (1/0)
+                 5 : Titel der Miniquest
+                 6 : "geschafft"-Beschreibung nach Abschluss der MQ
+                 7 : Voraussetzungen, Mapping im Format von P_RESTRICTIONS
+                 8 : zugeordnete Region, String wie z.B."polar", "gebirge"
+                 9 : erlaubte Abfrageobjekte, Array von Ladenamen, z.B.
+                     ({"/d/region/magier/npc/infonpc"}), es koennen mehrere 
+                     Objekte eingetragen sein
+    newvalue   - neuer Wert fuer den angegebenen Parameter
+
+RUECKGABEWERTE:
+     1: hat geklappt
+     0: Zugriff verweigert
+    -2: ungueltiger Datentyp eines der Argumente, bei Parameter 9 wird
+        ein uebergebenes Array zusaetzlich auf Leerstrings und Elemente
+        geprueft, die keine Strings sind. Wenn das Array ausschliesslich
+        aus solchen Elementen besteht, wird ebenfalls -2 zurueckgegeben.
+
+BEMERKUNGEN:
+    Das Flag "active" laesst sich bequemer ueber die Questmaster-Funktion
+    SwitchMiniQuestActive() umschalten.
+    Der Miniquest-Titel darf kein "in" oder "im" enthalten, weil dann die
+    Eintraege in der Fraternitas-Bibliothek nicht gelesen werden
+    koennen.
+
+SIEHE AUCH:
+   AddMiniQuest(L)
+   P_RESTRICTIONS
+
diff --git a/doc/lfun/ChangeReputation b/doc/lfun/ChangeReputation
new file mode 100644
index 0000000..e7c3af6
--- /dev/null
+++ b/doc/lfun/ChangeReputation
@@ -0,0 +1,45 @@
+ChangeReputation
+FUNKTION:
+     public varargs int ChangeReputation(string repid, int value, int silent)
+
+DEFINIERT IN:
+     /std/player/reputation.c
+
+ARGUMENTE:
+     repid
+       Jede neue Reputationsgruppe muss anfangs mit einer eindeutigen ID von 
+       einem EM in den Reputationsmaster eingetragen werden. Danach kann man 
+       ueber die eindeutige ID <repid> auf sie zugreifen.
+     value
+       Der Wert, um den die Reputation geaendert werden soll. Positive Werte 
+       erhoehen die Reputation, negative verschlechtern sie.
+     silent
+       Ein optionales Flag. Falls gesetzt, wird keine Standardmeldung ueber 
+       die Reputationsaenderung an den Spieler ausgegeben. Man koennte dann 
+       eigene Meldungen ausgeben.
+
+BESCHREIBUNG:
+     Vor der Aenderung wird ein Check auf die UID des ausfuehrenden Objektes
+     ausgefuehrt, "fremde" Reputationen darf man somit nicht veraendern.
+     Man kann aber selbstverstaendlich in begruendeten Faellen mit dem
+     zustaendigen Magier/Regionsmagier sprechen, ob man ebenfalls Zugriff
+     erhaelt. Eingetragen wird dies schlussendlich durch einen EM.
+
+RUeCKGABEWERT:
+     REP_RET_SUCCESS    Reputation wurde veraender.
+     REP_RET_SUCCESSCUT Reputation wurde auf Min / Max veraendert
+     REP_RET_WRONGARGS  Falsche Argumente fuer ChangeRep()
+     REP_RET_INVALIDUID Unzulaessige UID / keine Zugriffsrechte
+     REP_RET_ALREADYMAX Reputation bereits Max / Min
+     REP_RET_INACTIVE   Reputation momentan inaktiv
+     REP_RET_INVALIDREP Reputation nicht vorhanden
+
+BEISPIELE:
+     s. reputation
+
+SIEHE AUCH:
+     reputation
+     GetReputation(), GetReputations()
+
+ZULETZT GEAeNDERT:
+06.04.2009, Zesstra
diff --git a/doc/lfun/CheckFindRestrictions b/doc/lfun/CheckFindRestrictions
new file mode 100644
index 0000000..f9c96e5
--- /dev/null
+++ b/doc/lfun/CheckFindRestrictions
@@ -0,0 +1,23 @@
+CheckFindRestrictions
+
+FUNKTION:
+    varargs int CheckFindRestrictions(object ob, mixed restr, closure qp)
+ 
+DEFINIERT IN:
+    /std/room/shop.c
+ 
+ARGUMENTE:
+    ob     - Objekt
+    restr  - zusaetzliches Argument
+    qp     - symbol_function("QueryProp",ob)
+
+BESCHREIBUNG:
+    Funktion, die FindBestWeapon / FindBestArmours einschraenkt.
+    Wird in Wert ungleich 0 zurueckgeliefert, so wird das Objekt
+    nicht genommen.
+
+RUECKGABEWERT:
+    Normalerweise 0
+
+SIEHE AUCH:
+    FindBestWeapon(), FindBestArmours()
diff --git a/doc/lfun/CheckLightType b/doc/lfun/CheckLightType
new file mode 100644
index 0000000..1a0490a
--- /dev/null
+++ b/doc/lfun/CheckLightType
@@ -0,0 +1,84 @@
+CheckLightType()
+
+FUNKTION:
+	varargs int CheckLightType(int lighttype, int mode);
+
+DEFINIERT IN:
+	/std/thing/description.c
+
+ARGUMENTE:
+	lighttype
+	  Auf diesen Lichttyp wird getestet.
+	mode
+	  Die Methode, nach der der Lichttyp ueberprueft wird.
+
+BESCHREIBUNG:
+        Die Funktion prueft, ob der uebergebene lighttype mit dem in
+        P_LIGHT_TYPE definierten Lichttyp uebereinstimmt. 
+
+        Dabei kann in verschiedenen Modi getestet werden:
+
+        LT_CHECK_ANY
+          Es wird geprueft, ob mindestens einer der in lighttype ueber
+          gebenen Lichttypen im Objekt vorhanden ist. Dies ist das
+          Standardverhalten (default) der Funktion.
+
+        LT_CHECK_ALL     
+          Es wird geprueft, ob alle in lighttype definierten Lichttypen
+          vorhanden sind. Es koennen aber auch mehr Lichttypen definiert
+          sein.
+
+        LT_CHECK_MATCH   
+          Es wird geprueft, ob genau die in lighttype definierten Licht-
+          tyen definiert sind, sind mehr oder weniger vorhanden, gibt die
+          Funktion 0 zurueck.
+
+        LT_CHECK_NONE    
+          Es wird geprueft, ob keiner der uebergebenen Lichttypen vorhanden
+          sind. Ob sonst noch andere Lichttypen vorhanden sind, ist dabei 
+          egal.
+
+RUeCKGABEWERT:
+	0 wenn die geprueften Bedingungen nicht korrekt sind, sonst 
+        ein Wert ungleich 0.
+
+BEISPIELE:
+        In einem Raum scheint die Sonne, ausserdem gibt es dort ein Lager-
+        feuer und ein Objekt mit magischem Gluehen (meine Phantasie streikt
+        grad):
+
+        raum->SetProp( P_LIGHT_TYPE, LT_SUN|LT_OPEN_FIRE|LT_GLOWING );
+
+        Es soll getestet werden, ob an in dem Raum Tageslicht herrscht:
+
+        raum->CheckLightType(LT_DAYLIGHT, LT_CHECK_ANY);
+        raum->CheckLightType(LT_DAYLIGHT); // gleichwertig
+
+        Die Funktion ergibt wahr, da LT_DAYLIGHT unter anderem LT_SUN ent-
+        haelt (vgl man P_LIGHT_TYPES).
+
+        Es soll getestet werden, dass weder Mond noch Sterne im Raum sind:
+
+        raum->CheckLightType(LT_MOON|LT_STARS, LT_CHECK_NONE);
+
+        Die Funktion ergibt wahr, da die beiden nicht gesetzt sind.
+
+        Es soll geprueft werden, ob Mond und Sterne im Raum leuchten:
+
+        raum->CheckLightType(LT_MOON|LT_STARS, LT_CHECK_ALL);
+
+        Die Funktion ergibt falsch, da keins der beiden Lichter vorhanden
+        ist. Sie ergaebe aber auch falsch, wenn einer der beiden Typen
+        vorhanden waer. Nur wenn beide vorhanden sind, gibt LT_CHECK_ALL
+        wahr.
+
+BEMERKUNG:
+        Lighttypes haben nichts mit dem Lichtsystem zu tun. Sie dienen 
+        nur der Beschreibung der Lichtverhaeltnisse an/in einem Objekt.
+        Objekte mit verschiedenen Lichtverhaeltnissen beeinflussen sich
+        gegenseitig nicht.
+
+SIEHE AUCH:
+        /std/thing/description.c, /std/thing/lighttypes.h, P_LIGHT_TYPE
+----------------------------------------------------------------------------
+Last modified: Fri Jun 11 20:47:33 2004 by Vanion
diff --git a/doc/lfun/CheckResistance b/doc/lfun/CheckResistance
new file mode 100644
index 0000000..45486a5
--- /dev/null
+++ b/doc/lfun/CheckResistance
@@ -0,0 +1,20 @@
+CheckResistance()
+
+FUNKTION:
+	CheckRessistance(string* dam_type_list)
+
+ARGUMENTE:
+	dam_type_list: Liste der Schadensarten, die geprueft werden
+
+BESCHREIBUNG:
+	Diese Funktion ueberprueft, gegen welche der angegebenen
+	Schadensarten das Lebewesen resistent oder verletzlich ist und
+	gibt einen Faktor zurueck, der mit dem Schaden multipliziert wird.
+	Dieser Faktor betraegt normalerweise 1, bei bei jeder Resistenz
+	wird er halbiert und bei jeder Verletzlichkeit verdoppelt.
+
+RUECKGABEWERT:
+	Ein Faktor, der mit dem Schaden multipliziert wird, vom Typ "float".
+
+SIEHE AUCH:
+	"Defend"
diff --git a/doc/lfun/CheckSensitiveAttack b/doc/lfun/CheckSensitiveAttack
new file mode 100644
index 0000000..32aec2e
--- /dev/null
+++ b/doc/lfun/CheckSensitiveAttack
@@ -0,0 +1,33 @@
+CheckSensitiveAttack()
+FUNKTION:
+     void CheckSensitiveAttack(int dam, string *dam_type, mixed spell,
+			       object enemy)
+
+DEFINIERT IN:
+     /std/living/inventory.c
+
+ARGUMENTE:
+     dam	- an Defend uebergebener Schaden
+     dam_type	- Schadenstyp(en)
+     spell	- spell, int oder mapping
+     enemy	- Feindesobjekt
+
+BESCHREIBUNG:
+     Wird von Defend() aufgerufen und prueft die Listen in
+     P_SENSITIVE_ATTACK durch.
+     Wenn die Schluessel und Threshold-Werte stimmen, wird
+     trigger_sensitive_attack(enemy,key,dam,spell,options)
+     im Objekt gerufen.
+
+BEMERKUNGEN:
+     Objekte mit P_SENSITIVE mit Schluessel SENSITIVE_ATTACK bitte vorsichtig
+     verwenden, da rechenintensiv.
+
+SIEHE AUCH:
+     P_SENSITIVE
+     InsertSensitiveObject, RemoveSensitiveObject
+     insert_sensitive_inv_trigger, insert_sensitive_inv
+     P_SENSITIVE_ATTACK, P_SENSITIVE_INVENTORY,
+     P_SENSITIVE_INVENTORY_TRIGGER
+
+28.Jan.2001, Gloinson@MG
diff --git a/doc/lfun/CheckSpellFatigue b/doc/lfun/CheckSpellFatigue
new file mode 100644
index 0000000..0d7cc2a
--- /dev/null
+++ b/doc/lfun/CheckSpellFatigue
@@ -0,0 +1,61 @@
+CheckSpellFatigue
+
+FUNKTION:
+    public varargs int CheckSpellFatigue(string key)
+
+DEFINIERT IN:
+    /std/living/skills.c
+    /std/player/skills.c
+    /sys/living/skills.h
+
+ARGUMENTE:
+    string key  : Eindeutiger Name des Spruches, einer Gruppe von Spruechen
+                  oder 0 fuer die globale Spruchermuedung.
+
+BESCHREIBUNG:
+    Diese Funktion dient zum Pruefen von individuellen Spruchermuedungen
+    (Spellfatigue, Spruchsperren).
+    Hiermit lassen sich unabhaengige Ermuedungen/Sperren fuer einzelne
+    Sprueche oder Gruppen von Spruechen gestalten.
+
+    Wird <key> nicht angegeben oder ist 0, wird die globale Spruchsperre
+    geprueft (identisch zu der Property P_NEXT_SPELL_TIME), anderenfalls 
+    die unter <key> gespeicherte Spruchermuedung.
+    Prueft man einen Eintrag ohne Angabe von <key> ist das Ergebnis dieser
+    Funktion identisch zur Abfrage von P_NEXT_SPELL_TIME.
+
+RUeCKGABEWERT:
+    0    Spruchermuedung existiert nicht oder ist abgelaufen.
+
+    >0   Spruchermuedung ist noch nicht abgelaufen, Rueckgabewert ist die
+         Zeit, bei der dieser Eintrag ablaeuft. Der Spruch darf _nicht_
+         ausgefuehrt werden.
+
+BEISPIELE:
+    Ein Spell gehoert zu einer Gruppe von Spells mit dem Namen 'extrasuess'.
+    Er darf nur ausgefuehrt werden, wenn seit 5s kein anderer Spruch aus der
+    Gruppe ausgefuehrt wurde.
+    if (ob->CheckSpellFatigue("extrasuess") {
+      // alte Sperre noch nicht abgelaufen.
+      tell_object(ob, "Deine unendliche Schokotorte ist noch nicht wieder "
+        "nachgewachsen.\n");
+      return ... ;
+    }
+
+BEMERKUNGEN:
+    Die genauen Zeitdauern koennen von Spielern beeinflusst werden, sie
+    unterliegen der jeweiligen Einstellung von 'spruchermuedung', d.h. koennen
+    auf volle 2s aufgerundet werden.
+    Auch wenn diese Funktion zum Verwalten von beliebigen Zeitsperren genutzt
+    werden koennen, beschraenkt euch bitte auf Spruchermuedungen und benutzt
+    ansonsten check_and_update_timed_key(). Falls ihr diesbzgl. weitere/andere
+    Wuensche habt, sprecht den/die Mudlib-EM an.
+
+SIEHE AUCH:
+    SetSpellFatigue(L), DeleteSpellFatigue(L)
+    P_NEXT_SPELL_TIME
+    spruchermuedung
+
+----------------------------------------------------------------------------
+27.03.2010, Zesstra
+
diff --git a/doc/lfun/ClearRingBuffer b/doc/lfun/ClearRingBuffer
new file mode 100644
index 0000000..0095dec
--- /dev/null
+++ b/doc/lfun/ClearRingBuffer
@@ -0,0 +1,34 @@
+ClearRingBuffer()
+
+FUNKTION:
+    protected struct std_ringbuffer ClearRingBuffer(struct std_ringbuffer b);
+
+DEFINIERT IN:
+    /std/util/ringbuffer.c
+    /sys/util/ringbuffer.h
+
+ARGUMENTE:
+    b - der zu loeschende Ringpuffer
+
+BESCHREIBUNG:
+    Diese Funktion loescht alle Daten aus dem Puffer <b> und re-initialisiert
+    ihn.
+    
+RUeCKGABEWERT:
+    Der geloeschte Puffer <b> wird wieder zurueckgegeben.
+
+BEISPIELE:
+    // Ringpuffer anlegen:
+    struct std_ringbuffer buffer=CreateRingBuffer(10, MODE_FIFO);
+    // mit irgendwelchen Daten fuellen...
+    // ...
+    // Puffer loeschen
+    buffer = ClearRingBuffer(buffer);
+    // oder:
+    ClearRingBuffer(buffer);
+
+SIEHE AUCH:
+    CreateRingBuffer(), RingBufferGet(), ResizeRingBuffer()
+
+23.05.2008, Zesstra
+
diff --git a/doc/lfun/Configure b/doc/lfun/Configure
new file mode 100644
index 0000000..9763999
--- /dev/null
+++ b/doc/lfun/Configure
@@ -0,0 +1,76 @@
+Configure()
+
+  public mixed Configure(mixed data)
+
+DEFINIERT IN:
+   Beliebigen Objekten
+
+ARGUMENTE:
+   <data>
+     0 fuer Datenabfrage
+     beliebige Daten, die ein Configure(0) vorher lieferte
+
+BESCHREIBUNG:
+   Viele Objekte werden fuer bestimmte Spieler konfiguriert und so
+   personalisiert. Sie enthalten zusaetzlich zu den Daten, welche waehrend des
+   create() gesetzt wurden, noch weitere spieler-individuelle Daten.
+   Damit diese Objekte im Bedarfsfall neu erstellt werden koennen, sollte ein
+   geeignetes Configure() definfiert werden, um diese Daten abzurufen und in
+   einem neuen Clone (oder neugeladener Blueprint) wieder zu setzen.
+   
+   Existiert Configure() im Objekt, MUSS dieses bei einem Aufruf mit
+   <data>==0 (d.h. Configure(0)) alle individuellen Daten zurueckliefern,
+   die noetig sind, um den aktuellen Zustand des Objektes spaeter
+   wiederherzustellen.
+   Das Objekt darf nach dem Zurueckgeben dieser Daten diese NICHT mehr
+   veraendern, d.h. es muss ggf. eine Kopie erstellt werden (copy, deep_copy)
+
+   Genau diese Daten werden in einem neu geclonten Objekt durch den Aufruf
+   von Configure(data) wieder gesetzt. Das Configure MUSS genau die Daten, die
+   es im alten Objekt zurueckliefert, wieder akzeptieren.
+
+RUeCKGABEWERT:
+   Wenn <data>==0:
+     Alle individuellen Daten in einer beliebigen Form. Ein Mapping bietet
+     sich jedoch an.
+     Nicht erlaubt sind: Objekte und Closures.
+
+   Wenn <data>!=0:
+     1, wenn die Daten zur Konfiguration akzeptiert wurden.
+     0, sonst.
+
+BEMERKUNGEN:
+   Configure() ist nicht verpflichtet, erneut Daten zu akzeptieren, wenn es
+   bereits einmal mit gueltigen Daten aufgerufen wurde.
+   Das Zurueckschreiben der Daten kann auch nach Ablauf laengerer Zeit
+   und/oder in einer anderen Uptime erfolgen.
+
+BEISPIELE:
+   Ein Objekt, welches ein anderes Objekt sicher ersetzt, d.h. die
+   individuelle Konfiguration bleibt erhalten:
+   mixed data;
+   if (call_resolved(data,ob,"Configure",0) == 1) {
+     string obname = load_name(ob);
+     ob->remove();
+     ob = clone_object(obname);
+     if (data) {
+       if (ob->Configure(data) == 1) {
+         printf("Instanz von %s erfolgreich ersetzt, neues Objekt: %O\n",
+             obname,ob);
+       }
+       else {
+         raise_error(sprintf("Configure() in %O akzeptierte Daten nicht!\n",
+             ob));
+       }
+     }
+   }
+   else {
+     printf(break_string(
+         "Das Objekt %O definiert keine Funktion Configure(). Es kann "
+         "nicht sicher ersetzt werden, da unbekannt ist, ob es individuelle "
+         "Daten enthaelt.",78));
+   }
+
+LETZTE AeNDERUNG:
+26.09.2011, Zesstra
+
diff --git a/doc/lfun/ConvMaterialList b/doc/lfun/ConvMaterialList
new file mode 100644
index 0000000..ab4618a
--- /dev/null
+++ b/doc/lfun/ConvMaterialList
@@ -0,0 +1,41 @@
+ConvMaterialList()
+FUNKTION:
+     varargs string ConvMaterialList(mixed mats, int casus, mixed idinf)
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+ARGUMENTE:
+     mixed mats:  - das zu erkennende Material:
+                    - ein Mapping, ein String oder ein Stringarray
+                      ([MAT_A:y,MAT_B:x,..]) oder MAT_A oder ({MAT_A,MAT_B,..})
+     int casus:   - der Fall: 0..3 -> <language.h>: WAS, WESSEN, WEM, WEN
+     mixed idinf  - Dinge, welche die Faehigkeiten des Erkennens beeinflussen
+		    (siehe "man MaterialList")
+
+BESCHREIBUNG:
+     Man uebergibt ConvMaterialList() eine Liste von Materialien, die die
+     Funktion unter Verwendung von MaterialName() in ihre Bestandteile
+     aufsplittet und mit "und" und "," verknuepft zurueckgibt.
+
+RUECKGABEWERT:
+     string - Materialien, durch Komma und "und" getrennt oder
+              "unbekanntes Material"
+
+BEMERKUNGEN:
+     Wird von /std/thing/description::MaterialList() gerufen.
+     Bitte an Objekten auch MaterialList() verwenden.
+     Ruft direkt MaterialName() auf.
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterial(), QueryMaterialGroup(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/CreateRingBuffer b/doc/lfun/CreateRingBuffer
new file mode 100644
index 0000000..0471af6
--- /dev/null
+++ b/doc/lfun/CreateRingBuffer
@@ -0,0 +1,45 @@
+CreateRingBuffer()
+
+FUNKTION:
+    protected struct std_ringbuffer CreateRingBuffer(int size, int newmode);
+
+DEFINIERT IN:
+    /std/util/ringbuffer.c
+    /sys/util/ringbuffer.h
+
+ARGUMENTE:
+    size    - Groesse des neuen Ringpuffers (int)
+    newmode - Ausgabemodus beim Abrufen des Puffers (int):
+              MODE_FIFO: First-in-First-Out
+              MODE_LIFO: Last-in-First-Out
+
+BESCHREIBUNG:
+    Diese Funktion erstellt einen neuen, leeren Ringpuffer der Groesse <size>
+    und liefert ihn zurueck. Die Daten des Puffers werden spaeter gemaess
+    <newmode> so gespeichert, dass bei der Ausgabe des Puffers mittels
+    RingBufferGet() die entweder die neuesten Daten zuerst (MODE_LIFO) oder
+    die aeltesten Daten zuerst (MODE_FIFO) geliefert werden.
+
+RUeCKGABEWERT:
+    Der neue Ringpuffer. Dieser wird in einer Struct std_ringbuffer
+    gespeichert. Er ist in einer Variable 'mixed' oder in einer mittels
+    'struct std_ringbuffer' angelegten Variable speicherbar.
+
+BEMERKUNGEN:
+    Der gelieferte Ringpuffer sollte nicht per Hand verarbeitet oder
+    genaendert werden, sondern nur ueber die Verwaltungsfunktionen aus
+    /std/util/ringbuffer.c.
+
+BEISPIELE:
+    // Variable anlegen:
+    struct std_ringbuffer buffer;
+    // _oder_: mixed buffer;
+    // neuen Puffer mit max. 50 Elementen anlegen, der bei der Abfrage die
+    // aeltesten Daten zuerst zurueckliefert:
+    buffer = CreateRingBuffer(50, MODE_FIFO);
+
+SIEHE AUCH:
+    RingBufferPut(), RingBufferGet(), ResizeRingBuffer()
+
+23.05.2008, Zesstra
+
diff --git a/doc/lfun/CustomizeObject b/doc/lfun/CustomizeObject
new file mode 100644
index 0000000..4b35092
--- /dev/null
+++ b/doc/lfun/CustomizeObject
@@ -0,0 +1,52 @@
+CustomizeObject()
+
+FUNKTION:
+   string CustomizeObject();
+
+DEFINIERT IN:
+   /std/virtual/v_compiler.c
+
+ARGUMENTE:
+   keine
+
+RUeCKGABEWERT:
+   Den Objektnamen, den das zuletzt erzeugte Objekt (welches gerade die
+   Funktion aufruft) spaeter vom Driver bekommen wird.
+
+BESCHREIBUNG:
+   Diese Funktion ist aus dem Grunde da, da zum Zeitpunkt des Clonens des
+   VC-Objektes (P_STD_OBJECT) dieses Objekt ja noch nicht weiss Wer
+   oder Was es spaeter mal sein wird.
+   Deshalb kann dieses VC-Objekt im create() (und nur da!) die Funktion
+   CustomizeObject() in dem virtual_compiler aufrufen, welches das Objekt
+   geclont hat und bekommt von diesem den Objektnamen zureck, welches es
+   spaeter mal bekommen wird.
+   Da das VC-Objekt vom VC geclont wurde, ist previous_object() im create()
+   des VC-Objektes der VC, in dem man CustomizeObject() ruft.
+
+BEMERKUNGEN:
+   Das CustomizeObject() im Standard-VC gibt nur den zukuenftigen Objektnamen
+   zurueck und macht sonst nix.
+
+BEISPIELE:
+   create() eines VC-Objektes:
+   
+   protected void create() {
+     ...
+     
+     // wer bin ich denn eigentlich?
+     string myname = previous_object()->CustomizeObject();
+     switch(myname) {
+       // Kram konfigurier, ja nach myname... 
+     }
+     
+     ...
+   }
+
+SIEHE AUCH:
+     virtual_compiler
+     CustomizeObject(), Validate(), NoParaObjects(), 
+     P_COMPILER_PATH, P_PARA
+     /std/virtual/v_compiler.c
+----------------------------------------------------------------------------
+21.10.2007, Zesstra
diff --git a/doc/lfun/Damage b/doc/lfun/Damage
new file mode 100644
index 0000000..3258531
--- /dev/null
+++ b/doc/lfun/Damage
@@ -0,0 +1,34 @@
+Damage()
+
+FUNKTION:
+     int Damage(int dam);
+
+DEFINIERT IN:
+     /std/armour/combat.c und
+     /std/weapon/combat.c
+
+ARGUMENTE:
+     dam  Der Wert, mit dem die Waffe/Ruestung beschaedig werden soll.
+
+BESCHREIBUNG:
+     P_WC bzw. P_AC wird um dam reduziert und P_DAMAGED wird um
+     dam erhoeht.
+     Bei dam>0 wird das Objekt beschaedigt, bei dam<0 repariert.
+     Dabei werden sowohl die Obergrenzen (s. /sys/combat.h) wie auch
+     die Untergrenzen (Waffen:30, Ruestungen: 0) fuer P_WC und P_AC
+     beachtet. Es kann auch nicht mehr repariert werden, als vorher
+     beschaedigt wurde.
+
+RUeCKGABEWERT:
+     Der Wert der Beschaedigung, die tatsaechlich vorgenommen wurde.
+
+BEMERKUNGEN:
+     Ist das Objekt in Benutzung, setzt die Funktion Damage automatisch
+     die Properties P_TOTAL_WC bzw. P_TOTAL_AC in dem benutzenden Spieler
+     auf die richtigen Werte.
+
+SIEHE AUCH:
+     /std/armour/combat.c, /std/weapon/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Thu May 22 10:13:23 1997 by Paracelsus
diff --git a/doc/lfun/DeAssocMember b/doc/lfun/DeAssocMember
new file mode 100644
index 0000000..5f35326
--- /dev/null
+++ b/doc/lfun/DeAssocMember
@@ -0,0 +1,48 @@
+
+DeAssocMember()
+
+
+FUNKTION:
+        int DeAssocMember(object npc)
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        Der NPC, der nicht mehr zugeordnet sein soll.
+
+BESCHREIBUNG:
+        Hebt die Zuordnung eines NPCs zu einem Spieler auf.
+
+RUECKGABEWERT:
+        1, falls Aufhebung erfolgreich, sonst 0.
+
+BEISPIEL:
+        void fun(object pl)
+        {
+         if ( pl && pl->DeAssocMember(this_object()) )
+          tell_object(pl,break_string(
+              "Ich kaempfe nun nicht mehr auf Deiner Seite!\n",78,
+              "Ein Feuerteufel teilt Dir mit:");
+         ...
+        }
+
+BEMERKUNGEN:
+        Kann nur von Gilden, Spellbooks, vom Objekt selber und vom
+        zugeordneten NPC aufgerufen werden.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/DeclAdj b/doc/lfun/DeclAdj
new file mode 100644
index 0000000..f6e4244
--- /dev/null
+++ b/doc/lfun/DeclAdj
@@ -0,0 +1,46 @@
+DeclAdj()
+
+FUNKTION:
+     varargs string DeclAdj( string adj, int casus, int demon);
+
+DEFINIERT IN:
+     /std/thing/language.c
+
+ARGUMENTE:
+     adj
+          Das zu deklinierende Adjektiv.
+
+     casus
+          Der Fall, in den es dekliniert werden soll.
+
+     demon
+          Bezieht sich das Adjektiv auf einen bestimmten oder einen
+          unbestimmten Gegenstand?
+
+BESCHREIBUNG:
+     Dekliniert das uebergebene Adjektiv in den angegebenen Fall. Ist demon
+     ungleich Null, so wird das Adjektiv so behandelt, als wuerde es sich
+     auf einen bestimmten Gegenstand beziehen, ansonsten bezieht es sich auf
+     einen unbestimmten Gegenstand.
+
+RUeCKGABEWERT:
+     Das deklinierte Adjektiv. Es wird zusaetzlich noch ein Leerzeichen
+     hinten angefuegt!
+
+BEISPIELE:
+     Zunaechst ein bestimmtes Adjektiv:
+
+     printf("Der %sBall.\n", ball->DeclAdj("gruen", WER, 1);
+
+     Nun ein unbestimmtes Adjektiv:
+
+     printf("Ein %sBall.\n", ball->DeclAdj("gruen", WER, 0);
+
+     Da DeclAdj() "gruene " bzw. "gruener " zurueckgibt, darf zwischen dem
+     "%s" und dem "Ball" kein Leerzeichen stehen!
+
+SIEHE AUCH:
+     /std/thing/language.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:18:05 1996 by Wargon
diff --git a/doc/lfun/Defend b/doc/lfun/Defend
new file mode 100644
index 0000000..e02264a
--- /dev/null
+++ b/doc/lfun/Defend
@@ -0,0 +1,150 @@
+Defend()
+FUNKTION:
+     public int Defend(int dam, string|string* dam_type, int|mapping spell, 
+                        object enemy)
+
+DEFINIERT IN:
+     /std/living/combat
+
+ARGUMENTE:
+     int dam                  initiale Staerke des Angriffs (10 dam ~ 1 HP)
+     string* dam_type         Art(en) des Schadens, der angerichtet werden
+                              soll
+                              Muss ein Array von Schadenstypen sein,
+                              alte Objekte uebergeben hier manchmal strings.
+     int/mapping spell        - 0 fuer normale Angriffe (keine Zauber)
+                              - 1 fuer Zauber (Standardruestungen ignorieren)
+                              - mapping fuer mehr Informationen
+                              Heute bitte nach Moeglichkeit ein Mapping
+                              uebergeben.
+     object enemy             der Feind/Schadenverursacher
+
+BESCHREIBUNG:
+     1. Generell
+     Wenn das Lebewesen angegriffen wird, wird geprueft, wie stark die
+     Ruestungen und koerpereigenen Abwehrkraefte sind und die Staerke des
+     Schadens dementsprechend vermindert.
+     Ggf. wird der Schaden zugefuegt und der Feind in  die Liste der Feinde
+     aufgenommen. Der Schaden betraegt:
+      (dam-Summe(Ruestungsstaerken)-random(P_BODY+A_DEX))*CheckResistance/10
+     aber nicht unter 0.
+
+     2. Der Parameter 'spell'
+     Ist 'spell' 0, dann gilt der Angriff als normale physische Attacke
+     Uebergibt man als 'spell'-Parameter ein Mapping, so gibt es dafuer
+     diverse Flags, die das Ergebnis manipulieren (in new_skills.h
+     enthalten). Nichtangabe eines Flags gilt als 0.
+
+     - SP_PHYSICAL_ATTACK ---------- 0/1
+                1, wenn Ruestungen wirken sollen, 0 sonst
+                -> entspricht !spell, wenn dieses Int ist
+     - SP_NO_ENEMY ----------------- 0/1
+                1, falls der Angriff nicht toedlich ist, es also keinen echten
+                Gegner gibt
+                -> es wird dann reduce_hit_points() gerufen statt do_damage()
+     - SP_NO_ACTIVE_DEFENSE -------- 0/1
+                1, falls aktive Abwehren (wie zurueckschlagende Amulette,
+                Karateabwehren oder Ausweichmanoever) unterbleiben sollen
+                -> zB bei Kratzen durch Dornen oder Fall aus grosser Hoehe
+                   ist aktive Abwehr oder Ausweichen unlogisch
+     - SP_RECURSIVE ---------------- 0/1
+                1, falls der Spell aus einem Defend gerufen wurde (oder einer
+                DefendFunc)
+                -> verhindert Rekursionsprobleme
+     - SP_NAME --------------------- string
+                Name des Spells
+     - SP_REDUCE_ARMOUR ------------ Mapping: keys AT_X/P_BODY, values int>=0
+                Die Schutzwirkung durch P_AC/Magie einer Ruestung wird
+                typabhaengig reduziert. Aufbau eines Mappings im Beispiel:
+                ([AT_BOOTS: 0,  // Stiefel schuetzen gar nicht
+                  P_BODY:  50,  // Koerper zu 50%
+                  AT_BELT: 600  // Guertel zu 600%
+                ])
+                -> alle 'fehlenden' Eintraege wirken normal
+     - SP_SHOW_DAMAGE -------------- 0/1 oder Array von Arrays
+                0, fuer keine Treffermeldung, 1 sonst
+                In einem Array koennen Ersatz-Treffermeldungen definiert
+                werden. Format ist:
+                ({
+                 ({ int lphit1, string mess_me,
+                                string mess_en,
+                                string mess_room }),
+                 ({ lphit2, mess_me, mess_en, mess_room }),
+                 ...
+                 ({ lphitn, mess_me, mess_en, mess_room }),
+                })
+                wobei lphit1<lphit2<...<lphitn sein muss, d.h. das Array-
+                Array aufsteigend sortiert.
+
+                Ist ein Treffer x LP hart, werden die Meldungen des lphit-
+                Arrays ausgegeben, dessen Wert am naehesten unter dem Schaden
+                liegt.
+
+                In den Meldungen mess_me (an den Getroffenen), mess_en (an
+                den Feind), mess_room (an die restlichen Umstehenden) koennen
+                Ersatzstrings wie folgt verwendet werden:
+                @WER1/@WESSEN1/@WEM1/@WEN1 - name(casus) des Getroffenen (TO)
+                @WER2/@WESSEN2/@WEM2/@WEN2 - name(casus) des Feindes (enemy)
+     - EINFO_DEFEND ------------ Mapping
+                Dieses Mapping liefert erweiterte Informationen zu dem
+                bisherigen Ablauf des aktiven Attacks.
+                Die verfuegbaren Informationen sind in der Manpage zu
+                DefendInfo festgehalten.
+
+     3. Reihenfolgen in Defend
+     - das Living wird angegriffen, wenn
+       - P_NO_ATTACK != 0
+       - 'enemy' existiert und kein netztoter Spieler ist
+     - P_DEFENDERS werden durchgegangen (und eventuell benachrichtigt)
+     - P_TMP_ATTACK_HOOK wird abgefragt
+     - die Ruestungen werden vom Schaden gegebenenfalls abgezogen
+     - magischer Ausweichskill beruecksichtigt
+     - sensitive Objekte werden ggf. benachrichtigt
+     - InternalModifyDefend wird gerufen
+     - Koerperabwehr abgezogen
+     - der Schaden an do_damage()/reduce_hit_points() uebergeben
+     - Flucht ueberpruefen mit CheckWimpyAndFlee()
+
+BEMERKUNGEN:
+     Ruestungen wirken konventionell nur, wenn mindestens ein Schadensanteil
+     mechanisch ist und es kein Spell oder ein Spell mit SP_PHYSICAL_ATTACK
+     auf 1 ist.
+
+     Defend() beruecksichtigt magische Verteidigungen, die der Spieler bei
+     sich hat, sollte also aus Fairness gegenueber den Objekten anderer
+     Magier immer dem direkten reduce_hit_points() oder do_damage()
+     vorgezogen werden. Mittels der Flags in 'spell' kann man sehr viel
+     aendern.
+
+RUECKGABEWERT:
+     Hoehe des tatsaechlichen Schadens. Dies kann mehr sein als die
+     Lebenspunkte des Lebewesens.
+
+BEISPIELE (SIEHE AUCH Defend_bsp):
+     // ein simpler Angriff:
+     enem->Defend(100, ({DT_BLUDGEON}), 0, this_object());
+
+     // ein magischer Angriff (ohne Treffermeldung):
+     enem->Defend(100, ({DT_BLUDGEON, DT_FIRE}), 1, this_object());
+
+     // ein magischer Angriff mit Treffermeldung:
+     enem->Defend(100, ({DT_BLUDGEON, DT_FIRE}), ([SP_SHOW_DAMAGE:1]),
+                         this_object());
+
+SIEHE AUCH:
+     Angriff:   Attack(L), P_NO_ATTACK, InsertEnemy(L)
+     Schaden:   P_ENABLE_IN_ATTACK_OUT, P_LAST_MOVE,
+                do_damage(L), reduce_hit_points(L)
+     Schutz:    P_DEFENDERS, InformDefend(L), DefendOther(L)
+                P_ARMOURS, P_AC, P_DEFEND_FUNC, QueryDefend(L)
+                P_BODY, A_DEX
+     Daten:     P_LAST_COMBAT_TIME
+                P_LAST_DAMTYPES, P_LAST_DAMTIME, P_LAST_DAMAGE
+                P_DAMAGE_MSG
+     Resistenz: P_RESISTANCE_STRENGTHS, CheckResistance(L)
+     Sonstiges: CheckSensitiveAttack(L)
+                InternalModifyDefend(L)
+                UseSkill(L),
+                DefendInfo
+
+15.09.2010, Zesstra
diff --git a/doc/lfun/DefendFunc b/doc/lfun/DefendFunc
new file mode 100644
index 0000000..7043e04
--- /dev/null
+++ b/doc/lfun/DefendFunc
@@ -0,0 +1,78 @@
+DefendFunc(L)
+
+FUNKTION:
+     int DefendFunc(string|string *dtyp, int|mappingspell, object enemy);
+
+DEFINIERT IN:
+     eigenen Objekten; fuer /std/armour/combat.c
+
+ARGUMENTE:
+     dtyp
+          Schadenstypen der Angriffsart.
+          Sollte heute ein string* sein.
+     spell
+          0 bei veralteten konventionellen Angriffen im Regelfall jedoch
+          ein Mapping mit weiteren Infos.
+          Bei einem konventionellen Angriff ist spell[SP_PHYSICAL_ATTACK] gleich
+          1.
+     enemy
+          Der angreifende Gegner
+
+BESCHREIBUNG:
+     Anhand der uebergebenen Parameter kann hier ein Ruestungsbonus (oder
+     auch ein Ruestungsmalus) errechnet werden, der zu dem normalen
+     Ruestungswert (abhaengig von der Angriffsart) hinzuaddiert wird.
+
+RUeCKGABEWERT:
+     Der Ruestungsbonus, der zur Ruestungsklasse addiert werden soll.
+
+BEMERKUNGEN:
+     Auch wenn man eine DefendFunc() benutzt, darf der Rueckgabewert
+     zusammen mit der P_AC insgesamt nur in sehr seltenen, wohldurch-
+     dachten Ausnahmefaellen die maximal zulaessige P_AC fuer diesen
+     Ruestungstyp ueberschreiten. In solchen Ausnahmefaellen duerfen
+     die DefendFuncs nicht konstant wirken.
+
+     Bei aktivem Zurueckschlagen IMMER auf Flags wie SP_RECURSIVE und
+     SP_NO_ACTIVE_DEFENSE pruefen und ggf. abbrechen.
+
+BEISPIELE:
+     Eine Ruestung, die bei Angriffen mit Feuer ihre volle Staerke entfaltet
+     und bei Angriffen durch Geister geschwaecht wird:
+
+     void create()
+     {
+       ::create();
+
+       SetProp(P_ARMOUR_TYPE, AT_ARMOUR);
+       SetProp(P_AC, 20);
+       ...
+       // Die DefendFunc() ist in der Ruestung selbst definiert
+       SetProp(P_DEFEND_FUNC, this_object());
+     }
+
+     int DefendFunc(string *dtyp, mixed spell, object enemy)
+     {
+       int prot;
+
+       // Zuerst fragen wir den Angriff durch Feuer ab:
+       if (member(dtyp, DT_FIRE) >= 0)  // Feuer gehoert zu den Schadenstypen
+         prot = 5 + random(10); // Das ergibt maximal 14. Zusammen mit P_AC
+                                // kommt man also maximal auf 14+20 = 34,
+                                // liegt also unter der fuer AT_ARMOUR
+                                // geltenden Obergrenze
+
+       // Und jetzt der Geistertest
+       if (enemy->QueryProp(P_RACE) == "Geist" ||
+           enemy->is_class_member(CL_GHOST))
+         prot -= random(10);
+
+       // Der Rueckgabewert wird auf den aus P_AC errechneten Wert draufgeschlagen
+       return prot;
+     }
+
+SIEHE AUCH:
+     P_DEFEND_FUNC, QueryDefend(), /std/armour/combat.c
+
+----------------------------------------------------------------------------
+Last modified: 18.Jul 2006 Muadib
diff --git a/doc/lfun/DefendInfo b/doc/lfun/DefendInfo
new file mode 100644
index 0000000..460352a
--- /dev/null
+++ b/doc/lfun/DefendInfo
@@ -0,0 +1,168 @@
+DefendInfo
+FUNKTION:
+
+DEFINIERT IN:
+     /sys/combat.h
+
+ARGUMENTE:
+
+BESCHREIBUNG:
+     Die DefendInformationen werden im Runde eines Attack/Defend Vorgangs 
+     in Attack initial angelegt und dem Defend ueber den Parameter spell
+     uebergeben. Ist dieser Parameter ein Mapping, so sind die 
+     DefendInformationen ueber den Key EINFO_DEFEND zu erhalten.
+     Die Informationen liegen in Form eines Mappings vor.
+     Vor Zugriff sollte immer auf die Existenz dieses Keys in dem Mapping
+     geprueft werden, da nicht alle Informationen immer existieren.
+     Die Keys sind in combat.h definiert und sind folgende:
+     
+    ORIGINAL_AINFO - Mapping 
+        Hier ist eine Kopie des originalen ainfo-mappings des Attacks 
+        vorhanden mit folgenden Eintraegen:
+        Immer vorhandene Eintraege:
+          SI_ENEMY              der angegriffene Gegner
+        
+        Angriff mit gezueckter Waffe:
+          P_WEAPON              das Waffenobjekt selbst
+          P_WEAPON_TYPE         P_WEAPON_TYPE der Waffe
+          P_WC                  P_WC der Waffe
+          P_NR_HANDS            P_NR_HANDS der Waffe
+          SI_SKILLDAMAGE_TYPE   P_DAM_TYPE der Waffe
+          SI_SKILLDAMAGE        waffe->QueryDamage(enemy)
+             bei vorhandenem Zweihandskill SK_TWOHANDED wird nur der durch 
+             den Skill modifizierte Schadenswert uebernommen
+          SI_SKILLDAMAGE_MSG    "mit "+waffe->name(WEM,0)
+          SI_SKILLDAMAGE_MSG2   "mit "+waffe->name(WEM,1)
+          SI_SPELL              0
+
+        Angriff mit blossen Haenden:
+          P_WEAPON_TYPE         WT_HANDS
+          P_WC                  P_HANDS[1]
+          SI_SKILLDAMAGE        Schadenswert, aus P_HANDS[1] und A_STR 
+                                berechnet
+          SI_SKILLDAMAGE_TYPE   P_HANDS[2]
+          SI_SKILLDAMAGE_MSG
+          SI_SKILLDAMAGE_MSG2   beides P_HANDS[0]
+          SI_SPELL              0
+          
+        Angriff mit einem Spell (SK_MAGIC_ATTACK):
+          SI_SKILLDAMAGE        Schadenswert des Spells
+          SI_SKILLDAMAGE_TYPE   Schadenstypen des Spells
+          SI_SKILLDAMAGE_MSG    Schadensmeldung des Spells, wenn vorhanden,
+                                sonst "mit magischen Faehigkeiten"
+          SI_SKILLDAMAGE_MSG2   entsprechende Meldung des Spells, wenn 
+                                gesetzt, ansonsten identisch mit 
+                                SI_SKILLDAMAGE_MSG
+          P_WEAPON_TYPE         P_WEAPON_TYPE des Spells, wenn vorhanden,
+                                sonst WT_MAGIC
+          SI_SPELL              SI_SPELL des Spells
+          
+        Hinweise:
+        - Alle Eintraege in diesem Mapping koennen bereits durch
+          InternalModifyAttack() veraendert worden sein.
+        - Die Daten werden mittels deep_copy(ainfo) eingetragen.
+        - Daten in den Eintraegen SI_SKILLDAMAGE* und SI_SPELL koennen bei
+          physikalischen Angriffen durch die Skills FIGHT(P_WEAPON_TYPE) oder
+          SK_FIGHT oder durch einen P_TMP_ATTACK_MOD bzw. Hook vom Typ 
+          H_HOOK_ATTACK_MOD modifiziert worden sein.
+        
+    ORIGINAL_DAM - int
+        Der Originalschaden aus dem Attack
+
+    ORIGINAL_DAM_TYPE - string/string* 
+        Der Originaldamagetyp aus dem Attack
+
+    CURRENT_DAM - int
+        Der momentane Schaden, nach schon erfolgten Modifikationen
+  
+    CURRENT_DAM_TYPE - string/string*
+        Der momentane Damagetyp, nach schon erfolgten Modifikationen
+  
+    ENEMY_INSERTED - int
+        0 oder 1 je nachdem ob der Angreifer schon in der enemy-list
+        vorhanden war oder nicht
+  
+    RFR_REDUCE - int 
+        0 oder reduzierter Schaden durch RFR Modifikation
+  
+    PRESENT_DEFENDERS - Array 
+        Liste der durch InformDefend informierten Defender als Objekt.
+        Ein Defender wird immer NACH InformDefend
+        dazugefuegt
+  
+    DEFENDING_DEFENDER - Array ({})
+        Hat ein durch InformDefend ein Defender verteidigt, so wird
+        fuer diesen Defender ein Eintrag in diesem Array vorgenommen,
+        welcher folgende Struktur besitzt.
+                ({
+                        DEF_DEFENDER - Object
+                          Der Verteidiger, welcher VOR
+                          DefendOther eingefuegt wird
+                        DEF_DAM - int
+                          Der veraenderte Schaden, welcher NACH 
+                          DefendOther eingefuegt wird
+                        DEF_DAMTYPE string/string*  
+                          Die veraenderte Schadensart, welche 
+                          NACH DefendOther eingefuegt wird
+                        DEF_SPELL - Mapping   
+                          Das Mapping des veraenderten Spells, welches
+                          als Kopie NACH DefendOther eingefuegt wird
+                })
+  
+    DEFEND_HOOK - Int/Array 
+        DI_NOHOOK, wenn kein Hook da war, DI_HOOKINTERRUPT, wenn der
+        Hook das Defend unterbricht, DI_HOOK, wenn ein Hook vorhanden 
+        ist, dieser das Defend aber unveraendert laesst.
+        Veraendert ein Hook das Defend, so ist hier ein Array zu finden
+        mit den veraenderten Parametern in der Struktur:
+                ({
+                        HOOK_DAM - int
+                           Der veraenderte Schaden
+                        HOOK_DAMTYPE - string/string*   
+                           Die veraenderte Schadensart
+                        HOOK_SPELL - Mapping 
+                           Das Mapping des veraenderten Spells als Kopie
+                })
+  
+    DEFEND_ARMOURS - Mapping (2 Werte pro Key)
+        Liste der beruecksichtigten Ruestungen. Fuer jede Ruestung
+        wird ein Eintrag vorgenommen, mit dem Objekt der jeweiligen
+        Ruestung als Key. Hierbei werden die Ruestungen erst eingetragen,
+        wenn ihr jeweiliges QueryDefend() aufgerufen wird, d.h. es sind nicht
+        von Anfang an alle getragenen Ruestung drin. Jeder Eintrag im Mapping
+        besitzt die folgenden 2 Werte:
+                DEF_ARMOUR_DAM - int 
+                    Der Schaden NACH QueryDefend (vorher 0)
+                DEF_ARMOUR_PROT - int
+                    Verteidigungswert der Ruestung VOR DefendFunc
+        Bsp: Ich will wissen, wie gut 'ruestung' schuetzte:
+             spell[EINFO_DEFEND][DEFEND_ARMOURS][ruestung,DEF_ARMOUR_PROT]
+
+    DEFEND_GUILD - Array 
+        Eine Liste mit der Modifikation der Gilde mit der Struktur
+                ({
+                        GUILD_DAM - int
+                          Der veraenderte Schaden
+                        GUILD_DAMTYPE - string/string*
+                          Die veraenderte Schadensart
+                })
+  
+    DEFEND_RESI - int
+        Schaden nach CheckResistance
+  
+    DEFEND_BODY - int
+        Schaden nach Beruecksichtigung des Bodies (nur
+        physikalisch)
+  
+    DEFEND_LOSTLP - int
+        Tatsaechlich abgezogene LP
+  
+    DEFEND_CUR_ARMOUR_PROT - int
+        Schutz der Ruestung vor Call der
+        DefendFunc. Ist nur in der DefendFunc definiert. Kann auch aus
+        DEFEND_ARMOURS entnommen werden
+     
+SIEHE AUCH:
+     Attack, Defend
+
+18.Jul 2006 Muadib
diff --git a/doc/lfun/DefendOther b/doc/lfun/DefendOther
new file mode 100644
index 0000000..a0b2277
--- /dev/null
+++ b/doc/lfun/DefendOther
@@ -0,0 +1,85 @@
+DefendOther()
+
+FUNKTION:
+	mixed DefendOther(int dam,mixed dam_type,mixed spell,object enemy);
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	dam
+	  Der Schaden, der voraussichtlich beim zu verteidigenden Lebewesen
+	  verursacht werden soll.
+	dam_type
+	  Der Schadenstyp (oder die Schadenstypen), der beim zu
+	  verteidigenden Lebewesen verursacht werden sollen.
+	spell
+	  Wenn das zu verteidigende Lebewesen mit Spells angegriffen wurde,
+	  so koennte man hier mehr Infos entnehmen.
+	enemy
+	  Der Feind, der ein zu verteidigendes Lebewesen angegriffen hat.
+
+RUeCKGABEWERT:
+	Array mit den Eintraegen der gegebenenfalls veraenderten
+	uebergebenen Parameter: 
+            (1) dam      [Typ int], 
+            (2) dam_type [Typ string*], 
+            (3) spell    [Typ mapping].
+
+BESCHREIBUNG:
+	Es ist moeglich, dass Objekte Angriffe auf Lebewesen abwehren oder
+	umwandeln, sofern diese Objekte bei dem angegriffenen Lebewesen
+	mittels AddDefender() angemeldet wurden und sich der selben Umgebung
+	befinden.
+	Zumeist wird es sich bei den Objekten natuerlich ebenfalls um
+	andere Lebewesen handeln, die das Lebewesen, bei dem sie angemeldet
+	sind, verteidigen sollen.
+	Bei einem Angriff auf das Lebewesen koennen alle Objekte per Aufruf
+	von DefendOther() in einen Angriff eingreifen, wobei die
+	Schadensstaerke, der Schadenstyp (die Schadenstypen),
+	Zusatzinformationen fuer Angriffsspells und der Angreifer als
+	Parameter uebergeben werden.
+	Desweiteren ist zu beachten, dass bei als physikalisch markierten
+	Angriffen in einem Team nur Verteidiger aus der ersten Reihe
+	beruecksichtigt werden und dass bei einem Angriff zufaellig aus
+	allen moeglichen Verteidigern ausgewaehlt wird.
+	Standardmaessig ist diese Funktion in Lebewesen bereits definiert,
+	wobei der Skill SK_DEFEND_OTHER, sofern vorhanden, aufgerufen wird.
+
+BEISPIEL:
+	Sehr beliebt sind in Gilden NPCs, die den Beschwoerer begleiten und
+	verteidigen, z.B. beschworene Daemonen:
+	  inherit "std/npc";
+	  include <properties.h>
+	  object owner;
+	  void create()
+	  { ::create();
+	    SetProp(P_NAME,"Daemon");
+	    ...
+	  }
+	// nach Clonen des Daemons folgende Funktion mit Beschwoerer als
+	// Parameter aufrufen
+	  Identify(object caster)
+	  { if(!objectp(caster))
+	      call_out(#'remove,0);
+	    owner=caster;
+	    owner->AddDefender(this_object());
+	  }
+	// der Daemon wehrt jeden Angriff mit Feuer voll ab, man muss zuerst
+	// den Verteidiger umbringen, um den Beschwoerer toeten zu koennen
+	  mixed DefendOther(int dam,mixed dam_type,mixed spell,object enemy)
+	  { if(sizeof(dam_type)&&member_array(DT_FIRE,dam_type)!=-1)
+	      dam=0;
+	    return({dam,dam_type,spell});
+	  }
+	Soll der Daemon sich auch in ein Team einordnen, in welchem sich der
+	Beschwoerer eventuell befindet, so ist zusaetzlich AssocMember() in
+	diesem Beschwoerer aufzurufen, wobei der Daemon als Parameter
+	uebergeben wird.
+
+SIEHE AUCH:
+	AddDefender(), RemoveDefender(), InformDefend(), Kill(), IsEnemy(),
+	P_DEFENDERS, /std/living/combat.c, /sys/new_skills.h
+
+----------------------------------------------------------------------------
+Last modified: Fri Feb 25 14:45:00 2000 by Paracelsus
diff --git a/doc/lfun/Defend_bsp b/doc/lfun/Defend_bsp
new file mode 100644
index 0000000..06458a5
--- /dev/null
+++ b/doc/lfun/Defend_bsp
@@ -0,0 +1,137 @@
+Defend() - BEISPIELE
+
+FUNKTION:
+     varargs int Defend(int dam, mixed dam_type, mixed spell, object enemy)
+
+BEMERKUNGEN:
+     Die hier aufgefuehrten Komplexbeispiele sind zum Verstaendnis gedacht.
+
+BEISPIELE:
+  1) Ein ordinaerer Biss ins Bein.
+     this_player()->Defend(random(500),
+                           ({DT_PIERCE, DT_RIP}),
+                           0,
+                           this_object());
+
+  2) Ein Biss ins Bein, mit der Hose als 200%ige Ruestung und Rest mit 100%.
+     this_player()->Defend(random(500),
+                           ({DT_PIERCE, DT_RIP}),
+                           ([SP_PHYSICAL_ATTACK: 1,
+                             SP_REDUCE_ARMOUR:   ([AT_TROUSERS: 200])
+                           ]),
+                           this_object());
+
+  3) Der Biss, wenn ein Tier in die Hose gekrochen ist und dieser ohne
+     Treffermeldung und physischen Ruestungsschutz durchgeht.
+     this_player()->Defend(random(500),
+                           ({DT_PIERCE, DT_RIP}),
+                           ([SP_PHYSICAL_ATTACK: 0]),
+                           this_object());
+
+  4) Spell-Parameter
+     // Beispiel fuer einen Spell, der nur vom Helm normal und von einem
+     // Amulett mit 115% aufgehalten wird, alle anderen (angebenenen)
+     // Ruestungen haben 0% Schutzwirkung.
+     // Mit Ausgabe eigener Meldungen: beginnend mit -1, da der verursachte
+     // Schadenswert minimal 0 wird (fuers Ersetzen: Feind: @WEx2,
+     // Spieler: WEx1); maximal wird er (Empfindlichkeiten jetzt mal aussen
+     // vor) 49 (499/10 = 49), nicht 499!!!
+     this_player()->Defend(
+       random(500),
+       ({DT_PIERCE, DT_AIR}),
+       ([SP_PHYSICAL_ATTACK: 1, // wegen DT_PIERCE
+         SP_REDUCE_ARMOUR:   ([AT_ARMOUR:   0,
+                               AT_HELMET: 100,
+                               AT_RING:     0,
+                               AT_GLOVE:    0,
+                               AT_CLOAK:    0,
+                               AT_BOOT:     0,
+                               AT_TROUSERS: 0,
+                               AT_SHIELD:   0,
+                               AT_AMULET: 115,
+                               AT_MISC:     0,
+                               AT_BELT:     0,
+                               AT_QUIVER:   0])
+         SP_SHOW_DAMAGE:
+               ({({-1,"@WER2 schrammt Dich mit einem durchbohrenden Blick.",
+                      "Du schrammst @WEN1 mit einem durchbohrenden Blick.",
+                      "@WER2 schrammt @WEN1 mit einem durchbohrenden Blick."
+                 }),
+                 ({5,"Der durchbohrende Blick von @WEM2 trifft Dich.",
+                     "Dein durchbohrender Blick trifft @WEN1.",
+                     "Der durchbohrende Blick von @WEM2 trifft @WEN1."
+                 }),
+                 ({20,"@WESSEN2 stechender Blick durchbohrt Dich.",
+                      "Dein stechender Blick durchbohrt @WEN1.",
+                      "@WESSEN2 stechender Blick durchbohrt @WEN1."
+               })})
+       ]),
+       this_object());
+
+     // Etwas geschickter geht das Ganze, wenn wir einfach aus der Mudlib
+     // alle existierenden Ruestungen in ein Mapping packen und diese
+     // nullen (damit sind wir auch gegen neue Ruestungstypen sicher):
+     mapping amap = map_indices(VALID_ARMOUR_CLASS,#'!);
+     amap[AT_HELMET]=100;
+     amap[AT_AMULET]=115;
+
+     this_player()->Defend(random(500),
+                           ({DT_PIERCE, DT_AIR}),
+                           ([SP_PHYSICAL_ATTACK: 1,
+                             SP_REDUCE_ARMOUR: amap,
+                             SP_SHOW_DAMAGE: ({ ... (siehe oben)
+
+  5) Der Biss von weiter oben mit Meldung.
+     // Eine Meldung, die nur ausgegeben wird, wenn der Biss auch mindestens
+     // einen LP abzieht.
+     this_player()->Defend(random(500),
+                           ({DT_PIERCE, DT_RIP}),
+                           ([SP_PHYSICAL_ATTACK: 1,
+                             SP_REDUCE_ARMOUR:   ([AT_TROUSERS: 200]),
+                             SP_SHOW_DAMAGE: ({
+                               ({1,"@WER2 beisst Dich ins Bein!",
+                                   "Du beisst @WEN1 ins Bein!",
+                                   "@WER2 beisst @WEN1 ins Bein!"
+                                })           })
+                           ]),
+                           this_object());
+
+  6) DefendFunc() und Defend() in einem Objekt
+     6a)
+     // eine Luftangriffe reflektierende Ruestung:
+     int DefendFunc(string *dtyp, mixed spell, object enemy) {
+       if(member(dtyp, DT_AIR)>=0 && !spell[SP_RECURSIVE])
+         enemy->Defend(random(200),
+                       ({DT_AIR}),
+                       ([SP_RECURSIVE: 1,
+                         SP_SHOW_DAMAGE:
+                         ({"Ein Luftwirbel erfasst auch Dich.",
+                           "Deine Ruestung wirbelt @WEN1 herum.",
+                           "@WESSEN2 Ruestung wirbelt @WEN1 herum."
+                          })
+                       ]),
+                       QueryProp(P_WORN));
+
+       return 0; // -> In diesem Fall gibts keinen Ruestungsbonus!
+     }
+
+     6b)
+     // Eine NUR REINE Luftangriffe reflektierende Ruestung:
+     int DefendFunc(string *dtyp, mixed spell, object enemy) {
+       if(!sizeof(dtyp-({DT_AIR})) && !spell[SP_RECURSIVE])
+         ...
+
+SIEHE AUCH:
+     Angriff:   Attack(L), P_NO_ATTACK, InsertEnemy(L)
+     Schaden:   P_ENABLE_IN_ATTACK_OUT, P_LAST_MOVE, do_damage(L),
+                reduce_hit_points(L), reduce_spell_points(L)
+     Schutz:    P_DEFENDERS, InformDefend(L), DefendOther(L),
+                P_ARMOURS, P_AC, P_DEFEND_FUNC, QueryDefend(L),
+                P_BODY, A_DEX, Defend(L)
+     Daten:     P_LAST_COMBAT_TIME, P_LAST_XP, P_LAST_DAMAGE,
+                P_LAST_DAMTYPES, P_LAST_DAMTIME
+     Resistenz: P_RESISTANCE_STRENGTHS, CheckResistance(L)
+     Sonstiges: CheckSensitiveAttack(L), UseSkill(L),
+                InternalModifyDefend(L)
+
+25. Mai 2011 Gabylon
diff --git a/doc/lfun/DeleteSpellFatigue b/doc/lfun/DeleteSpellFatigue
new file mode 100644
index 0000000..c0049d9
--- /dev/null
+++ b/doc/lfun/DeleteSpellFatigue
@@ -0,0 +1,37 @@
+DeleteSpellFatigue
+
+FUNKTION:
+    public void DeleteSpellFatigue(string key)
+
+DEFINIERT IN:
+    /std/living/skills.c
+    /std/player/skills.c
+    /sys/living/skills.h
+
+ARGUMENTE:
+    string key  : Eindeutiger Name des Spruches, einer Gruppe von Spruechen
+                  oder 0 fuer die globale Spruchermuedung.
+
+BESCHREIBUNG:
+    Diese Funktion dient zum Loeschen von individuellen Spruchermuedungen
+    (Spellfatigue, Spruchsperren).
+
+    Ist <key> 0, wird die globale Spruchsperre geloescht (identisch zu der
+    Property P_NEXT_SPELL_TIME), anderenfalls die unter <key> gespeicherte
+    Spruchermuedung.
+    Loescht man einen Eintrag 0 ist das Ergebnis dieser Funktion identisch zum
+    Loeschen/Nullen von P_NEXT_SPELL_TIME.
+
+BEMERKUNGEN:
+    Spruchsperren (insb. fremde) duerfen nicht ohne weiteres geloescht oder
+    geaendert werden. Dieses bedarf grundsaetzlich der Genehmigung durch die
+    Gildenbalance!
+
+SIEHE AUCH:
+    SetSpellFatigue(L), CheckSpellFatigue(L)
+    P_NEXT_SPELL_TIME
+    spruchermuedung
+
+----------------------------------------------------------------------------
+27.03.2010, Zesstra
+
diff --git a/doc/lfun/DeleteTimedAttrModifier b/doc/lfun/DeleteTimedAttrModifier
new file mode 100644
index 0000000..e51b6c9
--- /dev/null
+++ b/doc/lfun/DeleteTimedAttrModifier
@@ -0,0 +1,30 @@
+DeleteTimedAttrModifier()
+FUNKTION:
+     int DeleteTimedAttrModifier(string key)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     key	-	aus P_TIMED_ATTR_MOD zu loeschender Eintrag
+
+BESCHREIBUNG:
+     Der zu key gehoerende Eintrag in P_TIMED_ATTR_MOD wird geloescht und
+     update_max_sp_and_hp ausgeführt.

+

+RUeCKGABEWERT:

+     TATTR_INVALID_ARGS      -     Im Falle eines fehlenden key-Arguments 
+     TATTR_NO_SUCH_MODIFIER  -     Falls der Modifier mit diesem Key nicht
+                                   existiert

+     TATTR_OK                -     Im Erfolgsfall

+     

+     Die Rueckgabewerte sind in /sys/living/attributes.h definiert.

+    
+SIEHE AUCH:

+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+	SetTimedAttrModifier(), QueryTimedAttrModifier(), 

+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,

+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+----------------------------------------------------------------------------

+Last modified: Tue Jul 27 20:00:20 2004 by Muadib

diff --git a/doc/lfun/DiscoverDoor b/doc/lfun/DiscoverDoor
new file mode 100644
index 0000000..88310d5
--- /dev/null
+++ b/doc/lfun/DiscoverDoor
@@ -0,0 +1,31 @@
+DiscoverDoor()
+
+FUNKTION:
+    varargs int DiscoverDoor(string dname)
+
+ARGUMENTE:
+    dname: Name des Raumes, in dem der Seher das Sehertor kennenlernen soll.
+           Default: Die Umgebung des Sehers.
+
+BESCHREIBUNG:
+    Nachdem diese Funktion aufgerufen wurde, kann der Seher (this_player())
+    das Tor in dem angegebenen Raum immer verwenden.
+
+RUECKGABEWERT:
+    1, falls der Seher ein NEUES Tor kennengelernt hat
+    0, falls er das Tor schon kannte oder kein Seher war
+
+BEMERKUNGEN:
+    Von einem Sehertor wird diese Funktion automatisch beim Betreten des
+    umgebenden Raumes aufgerufen, falls P_SEERDOOR_DISCOVER gesetzt ist. Wenn
+    ein Tor auf diese Art nicht entdeckt werden soll, so darf
+    P_SEERDOOR_DISCOVER nicht gesetzt sein und muss DiscoverDoor() separat,
+    z.B. von einem Questobjekt, aufgerufen werden.
+    Diese Funktion wird von /d/seher/portale/sehertormaster definiert.
+
+BEISPIELE:
+    write("Der Zauberer sagt: Im Nichts wirst Du ein weiteres Tor finden!\n");
+    "/d/seher/portale/sehertormaster"->DiscoverDoor("/room/void");
+
+SIEHE AUCH:
+    DoorIsKnown, ShowDoors, Teleport, GetDoorsMapping
diff --git a/doc/lfun/DistributeExp b/doc/lfun/DistributeExp
new file mode 100644
index 0000000..f02f69a
--- /dev/null
+++ b/doc/lfun/DistributeExp
@@ -0,0 +1,24 @@
+DistributeExp()

+FUNKTION:

+     private static void DistributeExp(object enemy, int exp_to_give)

+

+DEFINIERT IN:

+     /std/living/life.c

+

+ARGUMENTE:

+     object enemy     - toetender Feind

+     int exp_to_give  - zu verteilende XP (== P_XP/100)

+

+BESCHREIBUNG:

+     Das sterbende Wesen verteilt seine XP an seine Feinde.

+

+     Dabei bekommt jeder Gegner seinen Anteil (abhängig von 50% von seinem

+     gemachten Schaden) und einen Teamanteil (die anderen 50% über das

+     gesamte Team addiert und durch die Teamanzahl geteilt).

+

+SIEHE AUCH:

+     Funktionen:  AddExp()

+     Properties:  P_XP

+     Sonstiges:   teamkampf

+

+14.Feb 2007 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/DoDecay b/doc/lfun/DoDecay
new file mode 100644
index 0000000..85cf541
--- /dev/null
+++ b/doc/lfun/DoDecay
@@ -0,0 +1,44 @@
+DoDecay()
+
+FUNKTION:
+      public  int    DoDecay(int silent) 
+
+DEFINIERT IN:
+      /std/unit.c
+
+ARGUMENTE:
+     silent (int)
+       Falls != 0, erfolgt beim Zerfall keine Meldung, d.h. doDecayMessaage()
+       wird nicht gerufen.
+
+RUeCKGABEWERT:
+     Die Funktion gibt die nach dem Zerfall noch uebrig gebliebene Menge
+     zurueck (int).
+
+BESCHREIBUNG:
+     Diese Funktion wird in Clones von Unitobjekten aus der Blueprint gerufen,
+     wenn ein Zerfallsintervall abgelaufen ist (natuerlich nur, wenn in der BP
+     der Zerfall konfiguriert ist).
+     Die Funktion prueft normalerweise via P_UNIT_DECAY_FLAGS, ob der Zerfall
+     stattfinden soll, bestimmt aus P_UNIT_DECAY_QUOTA die zu zerfallende
+     Menge, ruft DoDecayMessage() und reduziert P_AMOUNT.
+     
+     Sie kann auch von Hand gerufen werden, um einen Zerfall auszuloesen, auch
+     wenn mir gerade nicht einfaellt, in welchen Situationen das sinnvoll
+     waere (vielleicht als Spruchmisserfolg. *g*)
+
+BEMERKUNGEN:
+     Wenn man einen anderen Zerfallsmechanismus haben, will muss man diese
+     Funktion wohl ueberschreiben. In fast allen Faellen sollte dies jedoch
+     unnoetig sein. Hat jemand das Verlangen, diese Funktion zu
+     ueberschreiben, ist vielleicht vorher eine Diskussion mit dem Mudlib-EM
+     angebracht.
+
+SIEHE AUCH:
+     unit
+     P_UNIT_DECAY_INTERVAL, P_UNIT_DECAY_FLAGS, P_UNIT_DECAY_QUOTA,
+     P_UNIT_DECAY_MIN
+     DoDecayMessage()
+     /std/unit.c
+
+14.10.2007, Zesstra
diff --git a/doc/lfun/DoDecayMessage b/doc/lfun/DoDecayMessage
new file mode 100644
index 0000000..fc39309
--- /dev/null
+++ b/doc/lfun/DoDecayMessage
@@ -0,0 +1,34 @@
+DoDecayMessage()
+
+FUNKTION:
+      protected void DoDecayMessage(int oldamount, int zerfall);
+      
+DEFINIERT IN:
+      /std/unit.c
+
+ARGUMENTE:
+     oldamount (int)
+        Menge vor dem Zerfall
+     zerfall (int)
+        jetzt zerfallende Menge
+
+BESCHREIBUNG:
+     Diese Funktion wird von DoDecay() gerufen und gibt die Standardmeldungen
+     beim Zerfall von Unitobjekten aus.
+     Hierbei ist an der Unit noch alles unveraendert, wenn diese Funktion
+     gerufen wird, die Reduktion von P_AMOUNT erfolgt direkt im Anschluss.
+     Die Funktion wird nicht gerufen, wenn DoDecay() mit silent!=0 gerufen
+     wird.
+
+BEMERKUNGEN:
+     Will man nicht die Standardzerfallsmeldungen (wovon ich meist ausgehe),
+     kann man diese Funktion ueberschreiben und eigene Meldungen erzeugen.
+
+SIEHE AUCH:
+     unit
+     P_UNIT_DECAY_INTERVAL, P_UNIT_DECAY_FLAGS, P_UNIT_DECAY_QUOTA,
+     P_UNIT_DECAY_MIN
+     DoDecay()
+     /std/unit.c
+
+14.10.2007, Zesstra
diff --git a/doc/lfun/DoUnwear b/doc/lfun/DoUnwear
new file mode 100644
index 0000000..638eda7
--- /dev/null
+++ b/doc/lfun/DoUnwear
@@ -0,0 +1,33 @@
+DoUnwear()
+
+FUNKTION:
+     varargs int DoUnwear(int silent, int all);
+
+DEFINIERT IN:
+     /std/clothing/wear.c
+
+ARGUMENTE:
+     silent
+          Falls ungleich 0, so werden keine Meldungen ausgegeben.
+          Falls (silent&M_NOCHECK) werden auch verfluchte Ruestungen
+          ausgezogen
+     all
+          Ungleich 0, wenn DoUnwear() aus einem "ziehe alles aus" heraus
+          aufgerufen wurde.
+
+BESCHREIBUNG:
+     Es wird versucht, die Ruestung auszuziehen. Dabei werden eine eventuell
+     vorhandene RemoveFunc() und Flueche mit beruecksichtigt.
+
+RUeCKGABEWERT:
+     0, wenn die Ruestung gar nicht getragen war, ansonsten 1.
+
+BEMERKUNGEN:
+     Auch wenn eine 1 zurueckgegeben wird, muss das nicht heissen, dass die
+     Ruestung erfolgreich ausgezogen wurde!
+
+SIEHE AUCH:
+     DoWear(), RemoveFunc(), InformUnwear(), /std/armour/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Sun Jun 27 22:22:00 1999 by Paracelsus
diff --git a/doc/lfun/DoUnwield b/doc/lfun/DoUnwield
new file mode 100644
index 0000000..be27b2c
--- /dev/null
+++ b/doc/lfun/DoUnwield
@@ -0,0 +1,30 @@
+DoUnwield()
+
+FUNKTION:
+     varargs int DoUnwield(int silent);
+
+DEFINIERT IN:
+     /std/weapon/combat.c
+
+ARGUMENTE:
+     silent
+          Ungleich 0, wenn die Waffe ohne Meldungen weggesteckt werden soll.
+
+BESCHREIBUNG:
+     Es wird versucht, die Waffe wegzustecken.
+
+RUeCKGABEWERT:
+     0, wenn die Waffe gar nicht gezueckt war, ansonsten 1.
+
+BEMERKUNGEN:
+     Anhand des Rueckgabewertes laesst sich nicht ersehen, ob die Waffe sich
+     wegstecken liess oder nicht!
+
+     Wenn die Waffe verflucht ist oder (falls definiert) UnwieldFunc() 0
+     zurueckgibt, laesst sie sich nicht wegstecken.
+
+SIEHE AUCH:
+     UnwieldFunc(), InformUnwield(), /std/weapon.c
+
+----------------------------------------------------------------------------
+Last modified: Sun Jun 27 22:24:00 1999 by Paracelsus
diff --git a/doc/lfun/DoWear b/doc/lfun/DoWear
new file mode 100644
index 0000000..0d64e5a
--- /dev/null
+++ b/doc/lfun/DoWear
@@ -0,0 +1,42 @@
+DoWear()
+
+FUNKTION:
+     varargs int DoWear(int silent, int all);
+
+DEFINIERT IN:
+     /std/armour/combat.c
+
+ARGUMENTE:
+     silent
+          Falls ungleich 0, so werden keine Meldungen ausgegeben.
+     all
+          Ungleich 0, wenn DoWear() aus einem "ziehe alles an" heraus
+          aufgerufen wurde.
+
+BESCHREIBUNG:
+     Es wird versucht, die Ruestung anzuziehen. Dabei wird eine eventuell
+     vorhandene WearFunc() mit beruecksichtigt.
+
+RUeCKGABEWERT:
+     0, wenn man die Ruestung gar nicht bei sich hat oder sie schon an hat,
+     ansonsten 1.
+
+BEMERKUNGEN:
+     Auch wenn eine 1 zurueckgegeben wird, muss das nicht heissen, dass die
+     Ruestung erfolgreich angezogen wurde!
+
+     Gruende fuer ein Fehlschlagen des Anziehens koennen sein:
+        o Man hat die Ruestung nicht bei sich.
+        o Man hat die Ruestung schon an.
+        o Man hat schon eine Ruestung des gleichen Typs an.
+        o Der Typ der Ruestung oder die Ruestungsklasse ist illegal.
+        o Falls definiert: WearFunc() gab 0 zurueck.
+        o Falls es sich um einen Schild handelt: Man hat keine Hand mehr
+          frei.
+
+SIEHE AUCH:
+     DoUnwear(), WearFunc(), InformWear(), P_EQUIP_TIME, 
+     /std/armour/combat.c, P_UNWEAR_MSG, P_WEAR_MSG
+
+----------------------------------------------------------------------------
+Last modified: Sun Jun 27 22:22:00 1999 by Paracelsus
diff --git a/doc/lfun/DoWield b/doc/lfun/DoWield
new file mode 100644
index 0000000..9fc436d
--- /dev/null
+++ b/doc/lfun/DoWield
@@ -0,0 +1,41 @@
+DoWield()
+
+FUNKTION:
+     varargs int DoWield(int silent);
+
+DEFINIERT IN:
+     /std/weapon/combat.c
+
+ARGUMENTE:
+     silent
+          Ungleich 0, wenn die Waffe ohne Meldungen gezueckt werden soll.
+
+BESCHREIBUNG:
+     Es wird versucht, die Waffe zu zuecken. Hat man schon eine Waffe
+     gezueckt, so wird versucht, diese wegzustecken. Klappt das nicht, kann
+     die Waffe nicht gezueckt werden.
+
+RUeCKGABEWERT:
+     0, wenn man die Waffe gar nicht bei sich traegt, ansonsten 1.
+
+BEMERKUNGEN:
+     Anhand des Rueckgabewertes laesst sich nicht entscheiden, ob die Waffe
+     sich erfolgreich zuecken liess!
+
+     Gruende, warum sich eine Waffe nicht zuecken lassen kann, sind
+     folgende:
+        o Man traegt sie nicht bei sich (oder sie steckt in einem Beutel
+          o.ae.).
+        o Man hat sie schon gezueckt.
+        o Falls definiert: WieldFunc() gibt 0 zurueck.
+        o Man ist nicht geschickt genug (das haengt von der Waffenklasse
+          ab).
+        o Eine schon gezueckte Waffe laesst sich nicht wegstecken.
+        o Die Waffenklasse ist hoeher als erlaubt.
+        o Man hat nicht genug Haende frei.
+
+SIEHE AUCH:
+     WieldFunc(), InformWield(), P_EQUIP_TIME, /std/weapon.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Apr 08 10:25:00 2004 by Muadib
diff --git a/doc/lfun/DoorIsKnown b/doc/lfun/DoorIsKnown
new file mode 100644
index 0000000..b909e30
--- /dev/null
+++ b/doc/lfun/DoorIsKnown
@@ -0,0 +1,24 @@
+DoorIsKnown()
+
+FUNKTION:
+	int DoorIsKnown()
+
+ARGUMENTE:
+	Keine.
+
+BESCHREIBUNG:
+	Testet, ob der Seher (this_player()) das Tor in seiner momentanen
+	Umgebung schon kennt.
+
+RUECKGABEWERT:
+	Die Nummer des Tores.
+
+BEMERKUNGEN:
+    Diese Funktion wird von /d/seher/portale/sehertormaster definiert.
+
+BEISPIELE:
+    /d/seher/portale/sehertormaster->DoorIsKnown()
+
+SIEHE AUCH:
+    DiscoverDoor, ShowDoors, Teleport, GetDoorsMapping
+
diff --git a/doc/lfun/Dump b/doc/lfun/Dump
new file mode 100644
index 0000000..274fbb4
--- /dev/null
+++ b/doc/lfun/Dump
@@ -0,0 +1,23 @@
+Dump()
+FUNKTION:
+     void Dump()
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+BESCHREIBUNG:
+     Schreibt alle Materialien samt ihren Gruppen und alle Gruppen mit
+     dazugehoerenden Materialien in DUMPFILE (/p/daemon/save/MATERIALS)
+     Wird in create() der Materialiendatenbank automatisch aufgerufen.
+     Das Dumpfile ist zum Recherchieren der Materialien gedacht.
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Listen:	  AllMaterials(), AllGroups()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/EnemyPresent b/doc/lfun/EnemyPresent
new file mode 100644
index 0000000..365ae3d
--- /dev/null
+++ b/doc/lfun/EnemyPresent
@@ -0,0 +1,19 @@
+EnemyPresent
+FUNKTION:
+     public mixed EnemyPresent()
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+BESCHREIBUNG:
+     Gibt aus der Feindesliste den ersten anwesenden, lebenden und 
+     angreifbaren aktuellen Gegner im Raum zurueck.
+     Damit ist die Funktion identisch zu InFight().
+
+     Will man alle Gegner, auf die diese Kriterien zutreffen, sollte man
+     PresentEnemies() verwenden.
+
+SIEHE AUCH:
+     PresentEnemies(), Infight()
+
+22.03.2009, Zesstra
diff --git a/doc/lfun/Enter b/doc/lfun/Enter
new file mode 100644
index 0000000..7987efa
--- /dev/null
+++ b/doc/lfun/Enter
@@ -0,0 +1,40 @@
+Enter()
+
+FUNKTION:
+     int Enter();
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Wenn sich der Spieler noch nicht auf dem Transporter befindet, und der
+     Transporter momentan an einer Haltestelle liegt, betritt der Spieler
+     den Transporter.
+
+RUeCKGABEWERT:
+     Null, wenn der Spieler den Transporter nicht betreten konnte, sonst
+     ungleich Null.
+
+BEMERKUNGEN:
+     Es werden keine Tests durchgefuehrt, ob der Transporter ueberhaupt
+     angesprochen wurde! Das muss man selber machen.
+
+BEISPIELE:
+
+     int myEnter(string str)
+     {
+       if (str && id(str))
+         return Enter();
+
+       notify_fail("Was willst Du betreten?\n");
+       return 0;
+     }
+
+SIEHE AUCH:
+     Leave(), /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:18:42 1996 by Wargon
diff --git a/doc/lfun/EvalArmour b/doc/lfun/EvalArmour
new file mode 100644
index 0000000..f1d356a
--- /dev/null
+++ b/doc/lfun/EvalArmour
@@ -0,0 +1,21 @@
+EvalArmour()
+
+FUNKTION:
+    int EvalArmour(object ob, closure qp)
+ 
+DEFINIERT IN:
+    /std/room/shop.c
+ 
+ARGUMENTE:
+    ob - Eine Ruestung.
+    qp - symbol_function("QueryProp",ob)
+
+BESCHREIBUNG:
+    Bewertet die Ruestung.
+ 
+RUECKGABEWERT:
+    Max(P_AC,P_EFFECTIVE_AC);
+ 
+SIEHE AUCH:
+    FindBestArmour()
+
diff --git a/doc/lfun/EvalWeapon b/doc/lfun/EvalWeapon
new file mode 100644
index 0000000..1e671a3
--- /dev/null
+++ b/doc/lfun/EvalWeapon
@@ -0,0 +1,21 @@
+EvalWeapon()
+
+FUNKTION:
+    int EvalWeapon(object ob, closure qp)
+ 
+DEFINIERT IN:
+    /std/room/shop.c
+ 
+ARGUMENTE:
+    ob - Eine Waffe.
+    qp - symbol_function("QueryProp",ob)
+
+BESCHREIBUNG:
+    Bewertet die Waffe.
+ 
+RUECKGABEWERT:
+    Max(P_WC,P_EFFECTIVE_WC);
+ 
+SIEHE AUCH:
+    FindBestWeapon()
+
diff --git a/doc/lfun/ExtraAttack b/doc/lfun/ExtraAttack
new file mode 100644
index 0000000..016b5c1
--- /dev/null
+++ b/doc/lfun/ExtraAttack
@@ -0,0 +1,30 @@
+ExtraAttack()
+
+FUNKTION:
+	varargs public void ExtraAttack(object enemy, int ignore_previous);
+
+ARGUMENTE:
+	enemy: Der Feind.
+	ignore_previous: Ein Flag
+
+BESCHREIBUNG:
+	Der Feind wird der Staerke der Waffe (bzw. der Haende) entsprechend
+	stark angegriffen. Hierbei wird Attack() aufgerufen.
+	Ist ignore_previous ungleich 0, dann wird die Erstschlagsperre von
+	Attack ignoriert. Dieser Angriff ist also auch dann moeglich, wenn
+	das Lebewesen eigentlich keinen Schlag mehr in dieser Runde ausfuehren
+	duerfte.
+
+RUECKGABEWERT:
+	Keiner.
+
+BEMERKUNG:
+	Der Einsatz dieser Funktion ist genehmigungspflichtig.
+	Weitere Hinweise siehe "man Attack".
+
+SIEHE AUCH:
+	"Attack"
+	/std/living/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Sun Nov 21 12:32:20 2004 by Bambi
diff --git a/doc/lfun/FilterArmours b/doc/lfun/FilterArmours
new file mode 100644
index 0000000..f934933
--- /dev/null
+++ b/doc/lfun/FilterArmours
@@ -0,0 +1,69 @@
+FilterArmours
+FUNKTION:
+     public object *FilterArmours(closure filterfun, varargs mixed* extra)
+
+DEFINIERT IN:
+     /std/living/clothing.c
+
+ARGUMENTE:
+     closure filterfun
+       Die Closure, die entscheiden soll, ob eine Ruestung im Ergebnisarray
+       enthalten sein soll.
+     
+     mixed extra
+       Beliebig viele Extra-Argumente, die <filterfun> uebergeben werden.
+
+BESCHREIBUNG:
+     Diese Funktion ruft <filterfunc> fuer jede getragene Ruestung des
+     Lebewesen mit der jeweiligen Ruestung als Argument auf und liefert ein
+     Array mit allen Ruestungen zurueck, fuer die <filterfun> einen Wert != 0
+     zurueckliefert.
+     Die <extra> Argumente werden als zusaetzliche Parameter an <filterfun>
+     uebergeben und duerfen keine Referenzen sein.
+     
+     Diese Variante ist zu bevorzugen, wenn man Ruestungen nach bestimmten
+     Kriterien durchsuchen will und QueryArmourByType() nicht ausreichend sein
+     sollte.
+
+RUeCKGABEWERT:
+     Ein Array von Objekten mit allen passenden Ruestungen.
+
+BEISPIELE:
+     1) Ich moechte gerne alle Ruestungen haben, die beschaedigt sind:
+     private int _is_damaged(object ruestung) {
+         return ruestung->QueryProp(P_DAMAGE);
+     }
+     ...
+     object *damaged_armours = PL->FilterArmours(#'_is_damaged);
+
+     2) Ich moechte alle Ruestungen, die groesser als 50cm sind.
+     private int _armour_is_bigger(object ruestung, int size) {
+       return ruestung->QueryProp(P_SIZE) > size;
+     }
+     ...
+     object *big_armours = PL->FilterArmours(#'_amour_is_bigger, 50); 
+
+     3) alle Ruestungen mit einer speziellen ID.
+     private int _has_id(object ruestung, string idstr) {
+       return ruestung->id(idstr);
+     }
+     object *has_id = PL->FilterArmours(#'_has_id, "\ntolleruestung");
+
+     4) alle Ruestungen mit einer speziellen ID, die groesser als 50cm sind.
+     private int _has_id(object ruestung, string idstr, int size) {
+       return ruestung->id(idstr) && ruestung->QueryProp(P_SIZE) > size;
+     }
+     object *has_id = PL->FilterArmours(#'_has_id, "\ntolleruestung", 50);
+
+     5) ueberhaupt alle getragene Ruestung
+     object *rue = PL->FilterArmours(#'objectp)
+
+
+SIEHE AUCH:
+     Wear(), WearArmour(), WearClothing(), Unwear(), UnwearArmour(), 
+     UnwearClothing()
+     P_CLOTHING, P_ARMOURS
+     FilterClothing(), QueryArmourByType()
+
+ZULETZT GEAeNDERT:
+14.03.2009, Zesstra
diff --git a/doc/lfun/FilterClothing b/doc/lfun/FilterClothing
new file mode 100644
index 0000000..95b00e3
--- /dev/null
+++ b/doc/lfun/FilterClothing
@@ -0,0 +1,51 @@
+FilterClothing
+FUNKTION:
+     public object *FilterClothing(closure filterfun, varargs mixed* extra)
+
+DEFINIERT IN:
+     /std/living/clothing.c
+
+ARGUMENTE:
+     closure filterfun
+       Die Closure, die entscheiden soll, ob eine Kleidung im Ergebnisarray
+       enthalten sein soll.
+
+BESCHREIBUNG:
+     Diese Funktion ruft <filterfunc> fuer jede getragene Kleidung des
+     Lebewesen mit der jeweiligen Kleidung als Argument auf und liefert ein
+     Array mit aller Kleidung zurueck, fuer die <filterfun> einen Wert != 0
+     zurueckliefert.
+     Die <extra> Argumente werden als zusaetzliche Parameter an <filterfun>
+     uebergeben und duerfen keine Referenzen sein.
+     
+     Diese Variante ist zu bevorzugen, wenn man die getrage Kleidung nach
+     bestimmten Kriterien durchsuchen will. 
+
+RUeCKGABEWERT:
+     Ein Array von Objekten mit allen passenden Kleidung.
+
+BEISPIELE:
+     1) Ich moechte alle Kleidung, die groesser als 50cm ist.
+     private int _armour_is_bigger(object clothing, int size) {
+       return clothing->QueryProp(P_SIZE) > size;
+     }
+     ...
+     object *big_armours = PL->FilterClothing(#'_amour_is_bigger, 50); 
+
+     2) alle Kleidung mit einer speziellen ID.
+     private int _has_id(object clothing, string idstr) {
+       return clothing->id(idstr);
+     }
+     object *has_id = PL->FilterClothing(#'_has_id, "\ntollekleidung");
+
+     3) ueberhaupt alle getragene Kleidung
+     object *clothing = PL->FilterClothing(#'objectp)
+
+SIEHE AUCH:
+     Wear(), WearArmour(), WearClothing(), Unwear(), UnwearArmour(), 
+     UnwearClothing()
+     P_CLOTHING, P_ARMOURS
+     FilterArmours(), QueryArmourByType()
+
+ZULETZT GEAeNDERT:
+14.03.2009, Zesstra
diff --git a/doc/lfun/FindBestArmours b/doc/lfun/FindBestArmours
new file mode 100644
index 0000000..68e734b
--- /dev/null
+++ b/doc/lfun/FindBestArmours
@@ -0,0 +1,38 @@
+FindBestArmours()
+
+FUNKTION:
+    varargs object *FindBestArmours(mixed type, int maxmon, int maxw,
+                                    mapping minac, mixed restr)
+ 
+DEFINIERT IN:
+    /std/room/shop.c
+ 
+ARGUMENTE:
+    type   - gewuenschter Ruestungstyp / Ruestungstypen
+    maxmon - Geld das ausgegeben werden darf
+    maxw   - Maximales Gewicht
+    minac  - minimale gewuenschte Ruestungsklasse pro Typ
+    restr  - zusaetzliches Argument fuer CheckFindRestrictions()
+
+BESCHREIBUNG:
+    Sucht die besten Ruestungen, die der Laden verkaufen kann.
+ 
+RUECKGABEWERT:
+    Die besten Ruestungen
+ 
+BEMERKUNG:
+    Die Qualitaet der Ruestung wird mit EvalArmour() bestimmt.
+    Haben zwei Ruestungen die gleiche Qualitaet,
+    wird die preiswertere genommen.
+ 
+BEISPIEL:
+    FindBestArmours(AT_ARMOUR,5000)
+    Bestes Ruestung unter 5000 Muenzen.
+
+    FindBestArmours(({AT_ARMOUR,AT_CLOAK,AT_BOOT}),10000,([AT_ARMOUR:20]))
+    Finded beste Ruestung, Umhang und Schuhe, die der Laden fuer
+    insgesamt 10000 Muenzen verkaufen kann, wobei die Ruestung mindestens
+    AC 20 haben muss.
+
+SIEHE AUCH:
+    FindBestWeapon(), CheckFindRestrictions(), EvalArmour()
diff --git a/doc/lfun/FindBestWeapon b/doc/lfun/FindBestWeapon
new file mode 100644
index 0000000..d0ba8f1
--- /dev/null
+++ b/doc/lfun/FindBestWeapon
@@ -0,0 +1,33 @@
+FindBestWeapon()
+
+FUNKTION:
+    varargs object FindBestWeapon(mixed type, int maxmon, int maxw, int hands,
+                                  int minwc, mixed restr)
+ 
+DEFINIERT IN:
+    /std/room/shop.c
+ 
+ARGUMENTE:
+    type   - gewuenschter Waffentyp / Waffentypen
+    maxmon - Geld das ausgegeben werden darf
+    maxw   - Maximales Gewicht
+    hands  - Anzahl Haende, die die Waffe belegen darf
+    minwc  - minimale gewuenschte Waffenklasse
+    restr  - zusaetzliches Argument fuer CheckFindRestrictions()
+
+BESCHREIBUNG:
+    Sucht die beste Waffe, die der Laden verkaufen kann.
+ 
+RUECKGABEWERT:
+    Die beste Waffe :-)
+ 
+BEMERKUNG:
+    Die Qualitaet der Waffe wird mit EvalWeapon() bestimmt.
+    Haben zwei Waffen die gleiche Qualitaet, wird die preiswertere genommen.
+ 
+BEISPIEL:
+    FindBestWeapon(WT_SWORD,5000,1)
+    Bestes einhaendiges Schwert unter 5000 Muenzen.
+
+SIEHE AUCH:
+    FindBestArmours(), CheckFindRestrictions(), EvalWeapon()
diff --git a/doc/lfun/FindDistantEnemyVictim b/doc/lfun/FindDistantEnemyVictim
new file mode 100644
index 0000000..a51c27f
--- /dev/null
+++ b/doc/lfun/FindDistantEnemyVictim
@@ -0,0 +1,32 @@
+FindDistantEnemyVictim()
+
+FUNKTION:
+	object FindDistantEnemyVictim(string wen, object pl, string msg,
+	                              int dist, int dy)
+
+DEFINIERT IN:
+	/std/spellbook.c
+
+ARGUMENTE:
+	wen  - id des gewuenschten Gegners, falls nicht angegeben:
+               SelectEnemy(FindDistantGroup(pl,-1,dist,dy,10000)
+	pl   - Caster.
+	msg  - Nachricht falls Gegner nicht anwesend ist.
+	dist - Entfernung
+	dy   - 2*erlaubte Abweichung von der Entfernung, default 100
+
+BESCHREIBUNG:
+	Findet einen Gegner in Entfernung dist-dy/2 bis dist+dy/2
+	z.B. fuer einen Angriffsspruch.
+	
+RUECKGABEWERT:
+	Der Auserwaehlte :-)
+
+BEMERKUNGEN:
+	1. Der Gegner wird auf jeden Fall angegriffen.
+	2. dist wird mit SA_RANGE modifiziert,
+	   dy wird mit SA_EXTENSION modifiziert.
+	3. Die Entfernung ist relativ zum Spieler.
+
+SIEHE AUCH:
+	teams, FindEnemyVictim, FindNearEnemyVictim, FindFarEnemyVictim
diff --git a/doc/lfun/FindDistantGroup b/doc/lfun/FindDistantGroup
new file mode 100644
index 0000000..4dedab6
--- /dev/null
+++ b/doc/lfun/FindDistantGroup
@@ -0,0 +1,31 @@
+FindDistantGroup()
+
+FUNKTION:
+	varargs object *FindDistantGroup(object pl, int who,
+                                         int dist, int dy, int dx)
+
+DEFINIERT IN:
+	/std/spellbook.c
+
+ARGUMENTE:
+	pl   - Caster
+	who  - 1=Freunde, -1=Gegner, 0=beide
+	dist - Entfernung
+	dy   - Tiefe      (default 100)
+	dx   - Breite     (default 100*MAX_TEAM_ROWLEN)
+
+BESCHREIBUNG:
+	Ermittelt Lebewesen, die sich in Entfernung <dist> in einem Bereich
+	der Breite <dx> und Tiefe <dy> befinden.
+
+RUECKGABEWERT:
+	Array mit den gefundenen Lebewesen.
+
+BEMERKUNGEN:
+	Genauere Hinweise unter "FindDistantGroups".
+	Wer sowohl Freunde wie auch Feinde in getrennten Arrays braucht,
+	sollte FindDistantGroups statt FindDistantGroup verwenden.
+
+SIEHE AUCH:
+	teams, FindDistantGroups
+
diff --git a/doc/lfun/FindDistantGroups b/doc/lfun/FindDistantGroups
new file mode 100644
index 0000000..507b72e
--- /dev/null
+++ b/doc/lfun/FindDistantGroups
@@ -0,0 +1,59 @@
+FindDistantGroups()
+
+FUNKTION:
+	varargs mixed FindDistantGroups(object pl, int dist, int dy, int dx)
+
+DEFINIERT IN:
+	/std/spellbook.c
+
+ARGUMENTE:
+	pl   - Caster
+	dist - Entfernung
+	dy   - Tiefe      (default 100)
+	dx   - Breite     (default 100*MAX_TEAM_ROWLEN)
+
+BESCHREIBUNG:
+	Ermitteld feindliche (bei Spielern NPCs, bei NPCs Spieler) und
+	freundliche (bei Spielern Spieler, bei NPCs NPCs) Lebewesen,
+	die sich in Entfernung <dist> in einem Bereich der Breite <dx>
+	und Tiefe <dy> befinden.
+
+RUECKGABEWERT:
+	Array mit zwei Arrays als Inhalt:
+	({ feindliche Lebewesen, freundliche Lebewesen })
+
+BEMERKUNGEN:
+	Die Entfernungsangaben sind als cm. zu verstehen.
+	Jedes Lebewesen belegt 50cm x 50cm mit Abstand 50cm
+	zum naechsten Lebewesen in jeder Richtung.
+	Die Breitenangabe wirkt sich nur in der Anzahl der
+	Lebewesen aus, die zufaellig pro Reihe ausgewaehlt werden.
+	Die Skillattribute SA_RANGE und SA_EXTENSION werden beruecksichtigt.
+
+BEISPIEL:
+	dist=200, dy=200, dx=200, ein Punkt = 50cm x 50cm
+	   . . . . . . . . . . . . .
+	3. . . . . . . G . . . . . .
+	   . . . . . . . . . . . . .
+	2. . . . . . G . G . . . . .dist+dy/2-+
+	   . . . . . . . . . . . . .          |  
+	1. . . . . G . G . G . . . .     dist +-+ (Gegner G)
+	---.-.-.-.-.-.-.-.-.-.-.-.-.          | |
+	1. . . . . F . F . F . . . .dist-dy/2-+ | (Freunde F)
+	   . . . . . . . . . . . . .            |
+	2. . . . . . F . S . . . . .------------+ (Reihe des Spielers S)
+	   . . . . . . . . . . . . .
+	3. . . . . . . F . . . . . .
+	   . . . . . . . . . . . . .
+	Abgedeckter Bereich:           100cm  bis  300cm
+                Reihe 3:  375cm..425cm         375>300 -> nicht erwischt
+                Reihe 2:  275cm..325cm         275<300 -> erwischt
+	Gegner  Reihe 1:  175cm..225cm 100<175,225<300 -> erwischt
+	Freunde Reihe 1:   75cm..125cm 100<125         -> erwischt
+	        Reihe 2:  -25cm...25cm 100> 25         -> nicht erwischt
+                Reihe 3: -125cm..-75cm 100>-75         -> nicht erwischt
+	Ergebnis: ({({G,G,G,G}),({F,F})})
+	(Maximal 2 Lebewesen pro Reihe bei Breite 200).
+
+SIEHE AUCH:
+	teams, FindDistantGroup
diff --git a/doc/lfun/FindEnemyVictim b/doc/lfun/FindEnemyVictim
new file mode 100644
index 0000000..0ab72fc
--- /dev/null
+++ b/doc/lfun/FindEnemyVictim
@@ -0,0 +1,24 @@
+FindEnemyVictim()
+
+FUNKTION:
+	object FindEnemyVictim(string wen, object pl, string msg)
+
+DEFINIERT IN:
+	/std/spellbook.c
+
+ARGUMENTE:
+	wen - id des gewuenschten Gegners, falls nicht angegeben SelectEnemy.
+	pl  - Caster.
+	msg - Nachricht falls Gegner nicht anwesend ist.
+
+BESCHREIBUNG:
+	Findet einen Gegner, z.B. fuer einen Angriffsspruch.
+	
+RUECKGABEWERT:
+	Der Auserwaehlte :-)
+
+BEMERKUNGEN:
+	Der Gegner wird auf jeden Fall angegriffen.
+
+SIEHE AUCH:
+	FindLivingVictim
diff --git a/doc/lfun/FindFarEnemyVictim b/doc/lfun/FindFarEnemyVictim
new file mode 100644
index 0000000..e43dda6
--- /dev/null
+++ b/doc/lfun/FindFarEnemyVictim
@@ -0,0 +1,30 @@
+FindFarEnemyVictim()
+
+FUNKTION:
+	object FindFarEnemyVictim(string wen, object pl, string msg,
+	                          int min, int max)
+
+DEFINIERT IN:
+	/std/spellbook.c
+
+ARGUMENTE:
+	wen - id des gewuenschten Gegners, SelectFarEnemy falls n/a.
+	pl  - Caster.
+	msg - Nachricht falls Gegner nicht anwesend ist.
+	min - minimale Kampfreihe
+	max - maximale Kampfreihe
+
+BESCHREIBUNG:
+	Findet einen Gegner aus Kampfreihe <min> bis <max>
+	z.B. fuer einen Angriffsspruch.
+	
+RUECKGABEWERT:
+	Der Auserwaehlte :-)
+
+BEMERKUNGEN:
+	1. Der Gegner wird auf jeden Fall angegriffen.
+	2. Die Reihenangaben werden NICHT mit Skillattributen modifiziert.
+	3. Die Angabe der Reihe ist absolut.
+
+SIEHE AUCH:
+	teams, FindEnemyVictim, FindNearEnemyVictim, FindDistantEnemyVictim
diff --git a/doc/lfun/FindGroup b/doc/lfun/FindGroup
new file mode 100644
index 0000000..ec1c693
--- /dev/null
+++ b/doc/lfun/FindGroup
@@ -0,0 +1,76 @@
+FindGroup()
+
+FUNKTION:
+    object*FindGroup(object pl,int who);
+
+DEFINIERT IN:
+    /std/spellbook.c
+
+ARGUMENTE:
+    pl
+      Lebewesen, von welchem die Freunde oder Feinde in der Umgebung
+      gefunden werden sollen.
+    who
+      Flag, welches anzeigt, ob Freunde oder Feinde gefunden werden
+      sollen (Konstanten definiert in '/sys/new_skills.h'):
+        FG_ENEMIES - (Wert -1) Feinde sollen gefunden werden
+        FG_FRIENDS - (Wert  1) Freunde sollen gefunden werden
+        FG_ALL     - (Wert  0) alle Lebewesen sollen gefunden werden
+
+RUeCKGABEWERT:
+    Array mit gefundenen Lebewesen
+
+BESCHREIBUNG:
+    Bei Spells, die sich auf mehrere Gegner auswirken oder bei denen man
+    per Hand ein Opfer auswaehlen moechte, laesst sich mittels der
+    Funktion FindGroup() eine Liste von Lebewesen ermitteln, welche in
+    der Umgebung von <pl> zu finden sind.
+    Je nachdem, was man denn genau vorhat, kann man sich von der
+    Funktion freundlich oder feindlich gesinnte Lebewesen heraussuchen
+    lassen.
+    Will man die freundlich gesinnten Lebewesen ermitteln, so uebergibt
+    man in <who> die Konstante FG_FRIENDS, bei feindlich gesinnten die
+    Konstante FG_ENEMIES, und wenn man alle Lebewesen bekommen moechte
+    schliesslich FG_ALL.
+    Bei der Auswahl gelten folgende Regeln:
+      (1) Lebewesen, mit denen <pl> im Kampf ist, sind grundsaetzlich
+          feindlich gesinnt.
+      (2) Teammitglieder von <pl> sind grundsaetzlich freundlich
+          gesinnt.
+      (3) Spieler sind gegenueber Spielern freundlich gesinnt, NPCs
+          gegenueber NPCs. NPCs kann man hierbei mit Hilfe der Property
+          P_FRIEND den Spielern zuordnen.
+      (4) Daraus folgt natuerlich, dass Spieler und NPCs grundsaetzlich
+          eine feindliche Einstellung gegenueber haben, sofern die NPCs
+          nicht die Property P_FRIEND gesetzt haben
+           (was standardmaessig natuerlich nicht der Fall ist).
+      (5) Netztote werden nicht erkannt.
+      (6) Magier werden nicht erkannt, wenn sie unsichtbar sind.
+      (7) Ein Magier wird als feindlich gesinnt nur dann erkannt, wenn
+          <pl> mit ihm im Kampf ist.
+      (6) Sucht man feindlich gesinnte Lebewesen, so werden die, welche
+          eine von den Properties P_NO_ATTACK oder P_NO_GLOBAL_ATTACK
+          gesetzt haben, nicht erkannt.
+    Die Property P_FRIEND sollte man in NPCs setzen, die dem Spieler
+    hilfreich beiseite stehen, z.B. vom Spieler beschworene HilfsNPCs.
+
+BEISPIELE:
+    Wenn man einen Feuerball nach jemandem wirft, so trifft dieser unter
+    Umstaenden auch andere, wenn er gross genug ist. Man nimmt hierbei
+    an, dass sich die freundlich gesinnten Lebewesen des Gegners auch
+    naeher bei ihm befinden als die feindlich gesinnten:
+      victim->Defend(500,DT_FIRE,([SP_SHOW_DAMAGE:1]),caster);
+      victimList=FindGroup(victim,FG_FRIENDS);
+      map_objects(victimList,
+                      "Defend",
+                      100,
+                      DT_FIRE,
+                      ([SP_SHOW_DAMAGE:1]),
+                      caster);
+    Hiermit trifft man also auch die Freunde von <victim>.
+
+SIEHE AUCH:
+    FindGroupN(), FindGroupP(), P_FRIEND, P_NO_GLOBAL_ATTACK
+
+----------------------------------------------------------------------------
+Last modified: Mon Jan 28 21:45:00 2002 by Tiamak
diff --git a/doc/lfun/FindGroupN b/doc/lfun/FindGroupN
new file mode 100644
index 0000000..8364f77
--- /dev/null
+++ b/doc/lfun/FindGroupN
@@ -0,0 +1,45 @@
+FindGroupN()
+
+FUNKTION:
+	object*FindGroupN(object pl,int who,int n);
+
+DEFINIERT IN:
+	/std/spellbook.c
+
+ARGUMENTE:
+	pl
+	  Lebewesen, von welchem die Freunde oder Feinde in der Umgebung
+	  gefunden werden sollen.
+	who
+	  Flag, welches anzeigt, ob Freunde oder Feinde gefunden werden
+	  sollen (Konstanten definiert in '/sys/new_skills.h'):
+	    FG_ENEMIES - (Wert -1) Feinde sollen gefunden werden
+	    FG_FRIENDS - (Wert  1) Freunde sollen gefunden werden
+	    FG_ALL     - (Wert  0) alle Lebewesen sollen gefunden werden
+	n
+	  Anzahl der Lebewesen, die zurueckgegeben werden sollen.
+	  Hierbei geht vorher noch das Skillattribute SA_EXTENSION ein!
+	  Es wird mindestens 1 Lebewesen zurueckgeliefert (sofern gefunden).
+
+RUeCKGABEWERT:
+	Array mit gefundenen Lebewesen
+
+BESCHREIBUNG:
+	Ausgesucht werden die Lebewesen genauso wie bei FindGroup(), nur
+	dass zum Schluss die Anzahl noch begrenzt wird.
+
+BEISPIELE:
+	Man moechte maximal 5 Feinde finden, die man gleichzeitig mit einem
+	Spell belegen kann:
+	  enemyList=FindGroupN(caster,FG_ENEMIES,5);
+	Dies gilt jedoch nur bei SA_EXTENSION==100, sonst wird
+	dementsprechend mehr oder weniger zurueckgegeben.
+	 (also bei SA_EXTENSION==200 doppelt so viele -> 10 Lebewesen)
+	Das Skillattribute SA_EXTENSION kann auch durch SA_QUALITY
+	veraendert worden sein; das sollte beachtet werden.
+
+SIEHE AUCH:
+	FindGroup(), FindGroupP(), P_FRIEND, P_NO_GLOBAL_ATTACK
+
+----------------------------------------------------------------------------
+Last modified: Mon Jan 25 15:04:31 1999 by Patryn
diff --git a/doc/lfun/FindGroupP b/doc/lfun/FindGroupP
new file mode 100644
index 0000000..efef568
--- /dev/null
+++ b/doc/lfun/FindGroupP
@@ -0,0 +1,46 @@
+FindGroupP()
+
+FUNKTION:
+	object*FindGroupP(object pl,int who,int pr);
+
+DEFINIERT IN:
+	/std/spellbook.c
+
+ARGUMENTE:
+	pl
+	  Lebewesen, von welchem die Freunde oder Feinde in der Umgebung
+	  gefunden werden sollen.
+	who
+	  Flag, welches anzeigt, ob Freunde oder Feinde gefunden werden
+	  sollen (Konstanten definiert in '/sys/new_skills.h'):
+	    FG_ENEMIES - (Wert -1) Feinde sollen gefunden werden
+	    FG_FRIENDS - (Wert  1) Freunde sollen gefunden werden
+	    FG_ALL     - (Wert  0) alle Lebewesen sollen gefunden werden
+	pr
+	  Wahrscheinlichkeit, mit der ein Lebewesen ausgesucht werden soll.
+	  Hierbei geht vorher noch das Skillattribute SA_EXTENSION ein!
+
+RUeCKGABEWERT:
+	Array mit gefundenen Lebewesen
+
+BESCHREIBUNG:
+	Ausgesucht werden die Lebewesen genauso wie bei FindGroup(), nur
+	dass zum Schluss die einzelnen Lebewesen per Zufall ausgewaehlt
+	werden. Es ist also nicht gesichert, dass ueberhaupt ein Lebewesen
+	zurueckgeliefert wird, trotzdem welche gefunden wurden.
+
+BEISPIELE:
+	Man moechte im Schnitt 50% der Feinde finden, die man gleichzeitig
+	mit einem Spell belegt:
+	  enemyList=FindGroupP(caster,FG_ENEMIES,50);
+	Dies gilt jedoch nur bei SA_EXTENSION==100, sonst wird mit
+	dementsprechend mehr oder weniger Wahrscheinlichkeit zurueckgegeben.
+	 (also bei SA_EXTENSION==200 doppelt so viele -> 100%, also alle)
+	Das Skillattribute SA_EXTENSION kann auch durch SA_QUALITY
+	veraendert worden sein; das sollte beachtet werden.
+
+SIEHE AUCH:
+	FindGroup(), FindGroupP(), P_FRIEND, P_NO_GLOBAL_ATTACK
+
+----------------------------------------------------------------------------
+Last modified: Mon Jan 25 15:04:31 1999 by Patryn
diff --git a/doc/lfun/FindNearEnemyVictim b/doc/lfun/FindNearEnemyVictim
new file mode 100644
index 0000000..86d77ce
--- /dev/null
+++ b/doc/lfun/FindNearEnemyVictim
@@ -0,0 +1,25 @@
+FindNearEnemyVictim()
+
+FUNKTION:
+	object FindNearEnemyVictim(string wen, object pl, string msg)
+
+DEFINIERT IN:
+	/std/spellbook.c
+
+ARGUMENTE:
+	wen - id des gewuenschten Gegners, SelectNearEnemy falls n/a.
+	pl  - Caster.
+	msg - Nachricht falls Gegner nicht anwesend ist.
+
+BESCHREIBUNG:
+	Findet einen im Nahkampf erreichbaren Gegner,
+	z.B. fuer einen Angriffsspruch.
+	
+RUECKGABEWERT:
+	Der Auserwaehlte :-)
+
+BEMERKUNGEN:
+	Der Gegner wird auf jeden Fall angegriffen.
+
+SIEHE AUCH:
+	teams, FindEnemyVictim, FindFarEnemyVictim, FindDistantEnemyVictim
diff --git a/doc/lfun/FindPotion b/doc/lfun/FindPotion
new file mode 100644
index 0000000..417c89b
--- /dev/null
+++ b/doc/lfun/FindPotion
@@ -0,0 +1,49 @@
+FindPotion()
+
+FUNKTION:
+     varargs int FindPotion(string s);
+
+DEFINIERT IN:
+     /std/player/potion.c
+
+ARGUMENTE:
+     string s
+       Ausgabetext. Wenn 0/Leerstring, wird Default verwendet.
+
+BESCHREIBUNG:
+     Diese Funktion gibt einem aufrufenden Spieler eventuell diesen ZT.
+     
+     Das aufrufende Spielerobjekt muss dafuer:
+     * diesen ZT im Potionmaster in seiner Liste eingetragen haben
+     * diesen ZT in der Liste der bekannten Traenke haben (durch
+       Orakel also fuer ihn auch freigeschaltet)
+     * darf keine Playerkills haben (P_KILLS)
+     * darf nicht im Editiermodus sein
+     * darf kein Geist sein (Ausnahme: Geisterschloss)
+
+     Wenn alle Kriterien erfolgreich erfuellt sind, wird 's' oder 
+     "Du findest einen Zaubertrank, den Du sofort trinkst." ausgegeben
+     und dem Spieler ggf die Wahl der Attribute gegeben.
+
+RUeCKGABEWERT:
+     0 bei Nichtvergabe, 1 bei erfolgreicher Vergabe.
+
+BEISPIELE:
+     string detail_papiere() {
+       if (this_player()->FindPotion(
+         break_string("Beim Rumwuehlen in den Papieren entdeckst Du einen "
+                      "kleinen Zaubertrank, den Du sofort trinkst.", 78)))
+         return "";  
+         // Es muss ein String zurueckgegeben werden, da man sonst
+         // die Fehlermeldung "Sowas siehst du hier nicht." bekommt
+       else
+         return "Die Papiere sind alle unbeschriftet.\n";
+     }
+
+SIEHE AUCH:
+     Sonstiges: zaubertraenke, /secure/potionmaster.c, /room/orakel.c
+     Verwandt:  AddKnownPotion(), RemoveKnownPotion(), InList()
+     Props:     P_POTIONROOMS, P_KNOWN_POTIONROOMS
+     Befehl:    traenke (fuer Magier zum Einschalten des Findens von ZTs)
+
+6.Feb 2016 Gloinson
diff --git a/doc/lfun/FindRangedTarget b/doc/lfun/FindRangedTarget
new file mode 100644
index 0000000..75970fb
--- /dev/null
+++ b/doc/lfun/FindRangedTarget
@@ -0,0 +1,40 @@
+FindRangedTarget()
+
+FUNKTION:
+    static string FindRangedTarget(string str, mapping shoot)
+
+DEFINIERT IN:
+    /std/ranged_weapon.c
+
+ARGUMENTE:
+    string str    - Schusssyntax
+    mapping shoot - Schussdaten
+
+BESCHREIBUNG:
+    Erhaelt von /std/ranged_weapon::cmd_shoot() die Schussdaten und eine
+    eventuell bereits modifizierte Syntax und versucht einen passenden Gegner
+    im Raum oder im Gebiet (P_SHOOTING_AREA) zu finden.
+    Dieser wird in SI_ENEMY im Mapping 'shoot' eingetragen und ein Wert != 0
+    zurueckgegeben.
+
+RUECKGABEWERT:
+    0     bei Fehlschlag
+    != 0  bei gueltigem SI_ENEMY in 'shoot'
+
+BEMERKUNGEN:
+    'shoot' enthaelt normalerweise folgende Eintraege:
+    * Key P_WEAPON:       die Schusswaffe
+    * Key P_WEAPON_TYPE:  P_AMMUNITION, also die Munitions-ID
+    * Key P_STRETCH_TIME: P_STRETCH_TIME der Waffe
+    * Key P_WC:           P_SHOOTING_WC der Waffe
+
+SIEHE AUCH:
+    Generell:  P_AMMUNITION, P_SHOOTING_WC, P_STRETCH_TIME
+    Methoden:  shoot_dam(L), cmd_shoot(L)
+    Gebiet:    P_RANGE, P_SHOOTING_AREA, P_TARGET_AREA
+    Team:      PresentPosition(L)
+    Suche:     present, SelectFarEnemy(L)
+    Syntax:    _unparsed_args(L)
+    Sonstiges: fernwaffen
+
+28.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/Flee b/doc/lfun/Flee
new file mode 100644
index 0000000..6a63d89
--- /dev/null
+++ b/doc/lfun/Flee
@@ -0,0 +1,57 @@
+Flee()
+
+FUNKTION:
+        public varargs void Flee( object oldenv, int force )
+
+DEFINIERT IN:
+        /sys/living/combat.h
+        /std/living/combat.c
+
+ARGUMENTE:
+        oldenv
+          Ein Raum oder 0.
+          Wird ein Raum angegeben, dann muss sich der Fluechtende in diesem
+          Raum befinden, damit er versucht, zu fluechten, es sei denn, das
+          optionale Flag "force" ist gesetzt.
+        force
+          1, wenn der spieler unabhaengig von seiner Vorsicht fluechten soll.
+          0 sonst.
+
+BESCHREIBUNG:
+        Flee() wird im heart_beat() oder von CheckWimpyAndFlee() aufgerufen,
+        um den Spieler fluechten zu lassen. Man kann die Funktion im Spieler
+        auch "von Hand" aufrufen, beispielsweise in einem Spell. Man sollte
+        dann force auf 1 setzen, damit der Spieler unabhaengig von seiner
+        Vorsicht fluechtet.
+        Hierbei kann die Flucht dazu fuehren, dass man die Teamreihe wechselt,
+        aber auch, dass man den Raum verlaesst.
+        
+RUeCKGABEWERT:
+        keiner
+
+BEMERKUNGEN:
+
+BEISPIELE:
+        this_player()->Flee(0, 1);
+        // Der Spieler soll fluechten, egal, ob seine Lebenspunkte geringer
+        // als seine Vorsicht sind und unabhaengig von seiner Position.
+        
+        this_player()->Flee( find_object("/gilden/abenteurer") );
+        // Der Spieler soll fluechten, wenn er sich in der Abenteurergilde
+        // befindet (oder wenn diese nicht existiert)
+        
+        this_player()->Flee( "/gilden/abenteurer" );
+        // Der Spieler wird nicht fluechten, da der Vergleich von Dateiname
+        // und dem Raum 0 ergibt.
+
+        this_player()->Flee( find_object("/gilden/abenteurer"), 1);
+        // Der Spieler soll auf jeden Fall fluechten, egal ob er sich in der
+        // Abenteurergilde befindet oder nicht. Grund: Gesetztes force-Flag.
+        
+        
+        
+SIEHE AUCH:
+        CheckWimpyAndFlee(), Defend(), heart_beat(), 
+
+----------------------------------------------------------------------------
+Last modified: Wed Nov 12 14:44:42 2003 by Bambi
diff --git a/doc/lfun/FreeHands b/doc/lfun/FreeHands
new file mode 100644
index 0000000..2bed9b0
--- /dev/null
+++ b/doc/lfun/FreeHands
@@ -0,0 +1,36 @@
+FreeHands
+FUNKTION:
+     public varargs int FreeHands(object ob)
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+ARGUMENTE:
+     ob - das Objekt, dessen Handnutzung vorbei ist
+        - kann 0 sein, dann wird PO benutzt
+
+RUECKGABEWERT:
+     0, wenn kein Objekt uebergeben wurde oder kein PO existiert
+     1, sonst
+
+BESCHREIBUNG:
+     Befreit die Haende eines Livings von ein bestimmten Objekt.
+     Es werden _alle_ Haende wieder freigegeben.
+
+BEISPIELE:
+     > halte seil fest
+     ...
+     this_player()->UseHands(this_object(),2);
+     ...
+
+     > lasse seil los
+     ...
+     this_player()->FreeHands(this_object());
+     ...
+
+SIEHE AUCH:
+     P_HANDS, P_HANDS_USED_BY
+     P_MAX_HANDS, P_USED_HANDS, P_FREE_HANDS
+     UseHands
+
+1.Feb.2004 Gloinson
diff --git a/doc/lfun/GetAquarium b/doc/lfun/GetAquarium
new file mode 100644
index 0000000..cea8d49
--- /dev/null
+++ b/doc/lfun/GetAquarium
@@ -0,0 +1,37 @@
+GetAquarium()
+
+FUNKTION:
+     varargs public string* GetAquarium(object angel)
+
+ARGUMENTE:
+     Das optionale Argument <angel> ist die Angel selbst.
+
+BESCHREIBUNG:
+     Die Funktion wird beim Angeln in Raeumen gerufen, wenn diese als 
+     Gewaessertyp W_USER gesetzt haben (siehe Manpage zu P_WATER).
+     Aus der zurueckgegebenen Liste der Pfade wird einer zufaellig aus-
+     gewaehlt und das Objekt geclont. 
+
+RUECKGABEWERT:
+     String-Array mit Pfadnamen zu den in diesem Raum fangbaren Fischen.
+
+BEMERKUNG:
+     Man kann die Fangchancen durch Mehrfachnennung einzelner Eintraege 
+     modifizieren. Es muss sich bei den Eintraegen um lad- und clonebare
+     Objekte handeln.
+     Fuer selbstprogrammierte Fische ist das Basisobjekt 
+     /std/items/fishing/fish zu verwenden. Einige vorgefertigte Fische 
+     finden sich darueber hinaus in /items/fishing/aquarium/
+
+BEISPIEL:
+     varargs string* GetAquarium(object angel) {
+       return ({"/d/dschungel/rikus/q4e/obj/stichling",
+                "/d/dschungel/rikus/q4e/obj/karpfen",
+                "/p/seher/partymonster/obj/fisch"});
+     }
+
+SIEHE AUCH:
+    Properties: P_WATER, P_FISH
+
+-----------------------------------------------------------------------------
+zuletzt geaendert: 2014-Sep-02, Arathorn
diff --git a/doc/lfun/GetDetail b/doc/lfun/GetDetail
new file mode 100644
index 0000000..4bd7301
--- /dev/null
+++ b/doc/lfun/GetDetail
@@ -0,0 +1,67 @@
+GetDetail()
+
+FUNKTION:
+    varargs string GetDetail(string key, string race, int sense)
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    key
+      Das zu ermittelnde Detail.
+    race
+      Rasse des ermittelnden Objektes (falls es ein Lebewesen ist).
+    sense
+      Die Art des zu untersuchenden Details:
+        Untersuchen, Riechen, Hoeren, Tasten.
+
+BESCHREIBUNG:
+    Die Beschreibung des gewuenschten Details wird ermittelt. Dabei
+    werden rassenspezifische Details beruecksichtigt. Es gibt hierbei
+    verschiedene Detailarten, deren Typ man in <sense> angibt:
+      SENSE_VIEW    - Fuer Defaultdetails zum Untersuchen.
+      SENSE_SMELL   - Fuer Details, die man riechen kann.
+      SENSE_SOUND   - Fuer Details, die man hoeren kann.
+      SENSE_TOUCH   - Fuer Details, die man abtasten kann.
+      SENSE_READ    - Fuer Details, die man lesen kann.
+
+    Dabei ist 0 == SENSE_VIEW.
+
+RUeCKGABEWERT:
+    Die Beschreibung des Details oder 0, wenn es dieses Detail nicht
+    gibt.
+
+BEISPIEL:
+    Im folgenden wird ein kleines Testdetail generiert:
+      AddDetail("test","Das ist ein Test!\n");
+    Im folgenden wird das Detail entfernt, wenn es existiert. Dies ist
+    eigentlich nicht noetig, da RemoveDetail() damit zurechtkommt, aber
+    eventuell sind ja noch weitere Aktionen noetig.
+      if(GetDetail("test"))
+      { RemoveDetail("test");
+        ...
+      }
+    Ein Geruch kann man folgendermassen erzeugen:
+      AddSmells("gold",
+        ([0      :"Gold kann man nicht riechen!\n",
+          "zwerg":"Deine trainierte Nase riecht es muehelos!\n"]));
+    Die Abfrage des Details gestaltet sich recht einfach:
+      GetDetail("gold","zwerg",SENSE_SMELL);
+    Die Funktion liefert das Detail fuer den Zwerg.
+      GetDetail("gold",0,SENSE_SMELL);
+    Die Funktion liefert das Detail fuer die restlichen Rassen.
+      GetDetail("gold",0,SENSE_SOUND);
+    Ein Sounddetail mit dem Namen "gold" existiert nicht, die Funktion
+    liefert 0 zurueck.
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveReadDetail(), RemoveSmells(), RemoveDetail(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS,
+               P_TOUCH_DETAILS, P_SPECIAL_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: break_string()
+
+27. Jan 2013 Gloinson
diff --git a/doc/lfun/GetDoorsMapping b/doc/lfun/GetDoorsMapping
new file mode 100644
index 0000000..4c68a9d
--- /dev/null
+++ b/doc/lfun/GetDoorsMapping
@@ -0,0 +1,24 @@
+GetDoorsMapping()
+
+FUNKTION:
+    mapping GetDoorsMapping()
+
+BESCHREIBUNG:
+    Mit dieser Funktion erhaelt man das Mapping der vorhandenen
+    Seherportale.
+    
+    Die Struktur ist von der Form: 
+	([ Pfad: Portalnummer; Portalbeschreibung, ])
+    Es wird eine Kopie dieses Mappings geliefert.
+
+RUECKGABEWERT:
+    Das Sehertormapping
+
+BEMERKUNGEN:
+    Diese Funktion wird von /d/seher/portale/sehertormaster definiert.
+
+BEISPIELE:
+    "/d/seher/portale/sehertormaster"->GetDoorsMapping();
+
+SIEHE AUCH:
+    DoorIsKnown, ShowDoors, Teleport, DiscoverDoor
diff --git a/doc/lfun/GetEnemies b/doc/lfun/GetEnemies
new file mode 100644
index 0000000..334d0bf
--- /dev/null
+++ b/doc/lfun/GetEnemies
@@ -0,0 +1,34 @@
+GetEnemies()
+
+FUNKTION:
+	mapping GetEnemies();
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	keine
+
+RUeCKGABEWERT:
+	Mapping mit bekannten Gegnern als Schluessel und Zeiten als
+	Eintraegen.
+
+BESCHREIBUNG:
+	Diese Funktion liefert das interne Mapping zurueck, in dem alle
+	Gegner abgespeichert sind. Diese Gegner stellen die Schluessel in
+	dem Mapping dar. Als Eintraege sind die Zeiten vermerkt, nach
+	welcher Zeit ein Gegner automatisch wieder vergessen werden soll.
+	Mehr Informationen dazu sind in der Dokumentation zur aehnlich
+	gearteten Funktion QueryEnemies() zu finden, die jedoch zwei Arrays
+	getrennte zurueckliefert.
+	Achtung: Es wird keine Kopie des Mappings erstellt. Saemtliche
+	Veraenderungen in dem Mapping wirken sich unmittelbar auf die
+	interne Gegnerliste aus. Die Funktion sollte deshalb nicht genutzt
+	werden. Gegner ein- und austragen sollte man nur mittels
+	InsertEnemy() und StopHuntFor().
+
+SIEHE AUCH:
+	QueryEnemies(), SetEnemies(), InsertEnemy(), StopHuntFor()
+
+----------------------------------------------------------------------------
+Last modified: Wed May 26 16:47:51 1999 by Patryn
diff --git a/doc/lfun/GetExits b/doc/lfun/GetExits
new file mode 100644
index 0000000..d2f004e
--- /dev/null
+++ b/doc/lfun/GetExits
@@ -0,0 +1,23 @@
+GetExits()
+
+FUNKTION:
+     varargs string GetExits(object viewer);
+
+DEFINIERT IN:
+     /std/room/exits
+
+ARGUMENTE:
+     viewer
+          Derjenige, der sich die Ausgaenge anschaut.
+
+BESCHREIBUNG:
+     Es wird eine Liste der fuer viewer sichtbaren Ausgaenge erstellt.
+
+RUeCKGABEWERT:
+     String mit der Liste der sichtbaren Ausgaenge.
+
+SIEHE AUCH:
+     AddExit(), AddSpecialExit(), /std/room/exits.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:18:47 1996 by Wargon
diff --git a/doc/lfun/GetFValue b/doc/lfun/GetFValue
new file mode 100644
index 0000000..ac17224
--- /dev/null
+++ b/doc/lfun/GetFValue
@@ -0,0 +1,37 @@
+FUNKTION:
+
+	varargs int GetFValue(string vname, mapping map, object pl) 
+
+
+ARGUMENTE:
+
+	vname	: name des parameters aus dem spellmapping
+	map   	: spellmapping
+	pl 	: caster
+
+
+BESCHREIBUNG:
+
+	Berechnet den Wert und den Factor des Parameters in spellmapping.
+
+
+RUECKGABEWERT:
+
+	Berechneter Wert*Factor aus dem Spellmapping.
+
+
+BEMERKUNGEN:
+
+	Ruft GetValue(vname,map,pl)*GetFactor(vname,map,pl)/100 auf.
+
+
+BEISPIEL:
+
+	xxx=GetFValue(SI_SKILLDAMAGE,sinfo,caster);
+
+Siehe auch:
+
+	"GetValue", "GetFactor", "GetOffset", "GetValueO", "GetFValueO"
+
+	Ausfuehrliches Beispiel siehe "GetFValueO".
+
diff --git a/doc/lfun/GetFValueO b/doc/lfun/GetFValueO
new file mode 100644
index 0000000..e954e4b
--- /dev/null
+++ b/doc/lfun/GetFValueO
@@ -0,0 +1,74 @@
+FUNKTION:
+
+	varargs int GetFValueO(string vname, mapping map, object pl) 
+
+
+ARGUMENTE:
+
+	vname	: name des parameters aus dem spellmapping
+	map   	: spellmapping
+	pl 	: caster
+
+
+BESCHREIBUNG:
+
+	'Berechnet' den Wert, den Factor und den Offset des Parameters 
+	in spellmapping.
+
+
+RUECKGABEWERT:
+
+	Berechneter (Wert*Factor)/100+Offset aus dem Spellmapping.
+
+
+BEMERKUNGEN:
+
+	Ruft (GetValue(vname,map,pl)*GetFactor(vname,map,pl))/100+
+	GetOffset(vname,map,pl) auf.
+
+
+BEISPIEL:
+
+	AddSpell("egal",10,
+	([
+	OFFSET(SI_COST):([SM_RACE:(["Zwerg":4]) ]),
+	FACTOR(SI_COST):([SM_RACE:(["Mensch":90]) ]),
+	SI_SKILLDAMAGE:100,
+	OFFSET(SI_SKILLDAMAGE):25,
+	SI_SKILLDAMAGE_TYPE:DT_EXAMPLE,
+	FACTOR(SI_SKILLDAMAGE):([SM_RACE:(["Zwerg":80,"Elf":120]) ]) 
+	]));
+
+	So, was sollen uns diese Zeilen sagen?
+
+	Es wird ein Spruch Names 'egal' ins Spellbook eingetragen. Er kostet
+	regulaer 10 MP. Fuer Zwerge allerdings wird ein Offset von 4 MP 
+	aufgeschlagen. Ausserdem machen Zwerge nur 80% Schaden, Elfen 
+	hingegen 120%. Der Grundschaden betraegt 100 Schadenspunkte, der 
+	Offset des Schadens nochmal 25. Menschen bezahlen fuer diesen 
+	Spruch nur 90% der Kosten.
+
+	Nun die Rechenbeispiele:
+
+	Fuer die Kosten:
+		Value	ValueO	FValue	FValueO
+	Mensch	   10	    10	     9	      9
+	Elf   	   10	    10	    10       10
+	Hobbit	   10	    10	    10	     10
+	Zwerg	   10	    14	    10	     14
+
+	Fuer den Schaden:
+			Value	ValueO	FValue	FValueO
+	Mensch		100	125	100	125
+	Elf  		100	125	120	150
+	Hobbit		100	125	100	125
+	Zwerg		100	125	 80	100
+
+	An diesem Beispiel sieht man deutlich, wie man mit ein paar 
+	Offsets und Faktoren die Wirkung eines Spruches deutlich 
+	veraendern kann. Es sollte bei eigenen Berechnungen immer 
+	GetFValueO benutzt werden.
+
+Siehe auch:
+
+	"GetValue", "GetFactor", "GetOffset", "GetFValue", "GetValueO"
diff --git a/doc/lfun/GetFactor b/doc/lfun/GetFactor
new file mode 100644
index 0000000..42812dd
--- /dev/null
+++ b/doc/lfun/GetFactor
@@ -0,0 +1,37 @@
+FUNKTION:
+
+	varargs int GetFactor(string vname, mapping map, object pl) 
+
+
+ARGUMENTE:
+
+	vname	: name des parameters aus dem spellmapping
+	map   	: spellmapping
+	pl 	: caster
+
+
+BESCHREIBUNG:
+
+	'Berechnet' den Factor des Parameters in spellmapping.
+
+
+RUECKGABEWERT:
+
+	Berechneter Factor aus dem Spellmapping.
+
+
+BEMERKUNGEN:
+
+	Beschraekung auf 10-1000. Werte groesser oder kleiner als diese
+	werden 'abgeschnitten'.
+
+
+BEISPIEL:
+
+	xxx=GetFactor(SI_SKILLDAMAGE,sinfo,caster);
+
+Siehe auch:
+
+	"GetValue", "GetOffset", "GetFValue", "GetValueO", "GetFValueO"
+
+	Ausfuehrliches Beispiel siehe "GetFValueO".
diff --git a/doc/lfun/GetGroupMembers b/doc/lfun/GetGroupMembers
new file mode 100644
index 0000000..ef70aa3
--- /dev/null
+++ b/doc/lfun/GetGroupMembers
@@ -0,0 +1,36 @@
+GetGroupMembers()
+FUNKTION:
+     string *GetGroupMembers(string grp)
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+ARGUMENTE:
+     string grp - Gruppenname
+
+BESCHREIBUNG:
+     Gibt alle dieser Gruppe zugehoerigen Materialien zurueck. Dazu gut, sich
+     einen Ueberblick ueber die aktuelle Liste zu verschaffen.
+
+RUECKGABEWERT:
+     Array von Strings mit Materialien oder ({})
+
+BEISPIELE:
+     // wir wollen irgend ein Metall haben, nennen dies aber beim Namen
+     int ind;
+     string* likeit;
+     likeit=MATERIALDB->GetGroupMembers(MATGROUP_METAL);
+     ind=random(sizeof(likeit));
+     ...
+     write("Der Schmied sagt: Mir fehlt noch "+
+	   MATERIALDB->MaterialName(likeit[ind], WER, 100)+".\n");
+     ...
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetMatMembership()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/GetInfoArr b/doc/lfun/GetInfoArr
new file mode 100644
index 0000000..f1e251a
--- /dev/null
+++ b/doc/lfun/GetInfoArr
@@ -0,0 +1,31 @@
+GetInfoArr()
+FUNKTION:
+     static mixed *GetInfoArr(string str)
+
+DEFINIERT IN:
+     /std/npc/info.c
+
+ARGUMENTE:
+     string str	 - Schluesselwort der Frage
+
+BESCHREIBUNG:
+     Sucht nach einem Schluesselwort in den abgelegten Antworten
+     und gibt die Informationen oder einen 0er-Array zurück.
+
+BEMERKUNGEN:
+     Ueberschreibbar :)
+
+RUECKGABEWERT:
+     Siehe Parameter von AddInfo:
+
+     Array mit:
+     ({ <Infostring> (0 fuer keine Antwort),
+        <Indent-String> (Default: 0),
+        <Silent> (Default: 0),
+        <Casebased> (Default: 0)
+     })
+
+SIEHE AUCH:
+     Verwandt: AddInfo, do_frage
+
+31.Mar 2007 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/GetMatMembership b/doc/lfun/GetMatMembership
new file mode 100644
index 0000000..8859a38
--- /dev/null
+++ b/doc/lfun/GetMatMembership
@@ -0,0 +1,55 @@
+GetMatMembership()
+FUNKTION:
+     string *GetMatMembership(string mat)
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+ARGUMENTE:
+     string mat - ein Material
+
+BESCHREIBUNG:
+     Gibt alle Gruppen, denen das Material angehoert zurueck. Geeignet, um
+     die Eigenschaften eines Materials zu ueberpruefen.
+
+RUECKGABEWERT:
+     Array von Strings mit Materialiengruppen oder ({})
+
+BEISPIELE:
+     // ein weiser Schmied:
+     int i;
+     string *mat, mname, mgroup;
+     mat=m_indices(ob->QueryProp(P_MATERIAL));
+     i=sizeof(mat);
+
+     write("Der Schmied sagt: "+ob->Name(WER)+" besteht aus ...\n");
+     while(i--) {
+      // den Namen erkennen/aussprechen:
+      // Materialien werden allgemein etwas besser erkannt (zu 5%), aber
+      // alles aus Metall wird zu +100% besser erkannt ...
+      mname=MATERIALDB->MaterialName(mat[i], WER,
+	     ({5, ([MATRGROUP_METAL, 100])}));
+
+      // und nur Metalle analysieren ...
+      if(MATERIALDB->MaterialGroup(([mat[i]:100]),MATGROUP_METAL)>=100) {
+       int j;
+       string *mgr;
+       mgr=MATERIALDB->GetMatMembership(mat[i]);
+       j=sizeof(mgr);
+       mgroup=" gehoert zu ";
+       while(j--) {
+        mgroup+=MATERIALDB->GroupName(mgr[j]);
+        if(j>0) mgroup+=", ";
+       }
+      } else mgroup=" kenne ich nicht";
+      printf("%-12.12s: %s\n",mname, mgroup);
+     }
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/GetOffset b/doc/lfun/GetOffset
new file mode 100644
index 0000000..e3eba54
--- /dev/null
+++ b/doc/lfun/GetOffset
@@ -0,0 +1,38 @@
+FUNKTION:
+
+	varargs int GetOffset(string vname, mapping map, object pl) 
+
+
+ARGUMENTE:
+
+	vname	: name des parameters aus dem spellmapping
+	map   	: spellmapping
+	pl 	: caster
+
+
+BESCHREIBUNG:
+
+	'Berechnet' den Offset des Parameters in spellmapping.
+
+
+RUECKGABEWERT:
+
+	Berechneter Offset aus dem Spellmapping.
+
+
+BEMERKUNGEN:
+
+	Beschraekung auf -10000 bis +10000. Werte groesser oder kleiner 
+	als diese werden 'abgeschnitten'. Mehr als 100% Bonus oder Malus
+	gibts nicht ;-).
+
+
+BEISPIEL:
+
+	xxx=GetOffset(SI_SKILLDAMAGE,sinfo,caster);
+
+Siehe auch:
+
+	"GetValue", "GetFactor", "GetFValue", "GetValueO", "GetFValueO"
+
+	Ausfuehrliches Beispiel siehe "GetFValueO".
diff --git a/doc/lfun/GetOwner b/doc/lfun/GetOwner
new file mode 100644
index 0000000..f6b0f98
--- /dev/null
+++ b/doc/lfun/GetOwner
@@ -0,0 +1,19 @@
+GetOwner(L)
+FUNKTION:
+     string GetOwner();
+
+BESCHREIBUNG:
+     Wird vom Hoerrohr gerufen:
+      /d/inseln/shakedbeer/shakyisland/obj/hoerrohr.c
+     und kann einen Besitzer der Dateien zurueckgeben, der vom Besitzer
+     der Pfade in denen die Datei liegt abweicht.
+
+BEISPIELE:
+     string GetOwner() {
+      return "Tiamak";
+     }
+
+SIEHE AUCH:
+     P_INFO
+
+11. Mai 2004 Gloinson
diff --git a/doc/lfun/GetPhiolenInfos b/doc/lfun/GetPhiolenInfos
new file mode 100644
index 0000000..604d697
--- /dev/null
+++ b/doc/lfun/GetPhiolenInfos
@@ -0,0 +1,97 @@
+GetPhiolenInfos(L)
+
+FUNKTION:
+     mixed *GetPhiolenInfos();
+
+BESCHREIBUNG:
+
+     Wird von der Phiole aufgerufen:
+     /d/inseln/miril/sternquest/obj/phiole.c
+     Der Raum muss /p/service/miril/phiole.h includen.     
+     Mit der Phiole kann ein Spieler durch Tueren schauen. Bei Tueren, die
+     vom Doormaster (/obj/doormaster.c) verwaltet werden, klappt dies auto-
+     matisch. Moechte man das verbieten, so muss die Funktion 
+     GetPhiolenInfos() im entsprechenden Raum definiert sein.
+     Befinden sich Tueren im Raum, die nicht vom Doormaster verwaltet werden,
+     aber bei denen die Phiole funktionieren soll, so kann dies ebenfalls
+     mittels GetPhiolenInfos() geschehen.
+     
+     Funktion der Phiole:
+     Sie projiziert ein Bild dessen, was hinter der Tuer liegt auf die Tuer.
+     Steht die Tuer offen, so sieht der Spieler nur eine Wand, denn es wird
+     gezeigt, was hinter dieser Tuer ist.
+     
+     Ist die Tuer jedoch ge- oder verschlossen, so sieht er auf der Tuer
+     die Langbeschreibung des Raumes, der hinter der Tuer liegt, sowie das
+     Inventar dieses Raumes. 
+
+     Aufbau der Funktion:
+     mixed *GetPhiolenInfos() {
+       return ({
+                ([
+                  PHIOLE_DEST:     string,       
+                  PHIOLE_IDS:      *string,             
+                  PHIOLE_GENDER:   int,           
+                  PHIOLE_STATUS:   int,     (optional)
+                  PHIOLE_LONG:     string,  (optional)
+                  PHIOLE_VERBOTEN: int      (optional)
+                ]),
+                ([
+                  ... Naechste Tuer
+                ])
+              });
+     }
+     
+     PHIOLE_DEST      Dateiname des Zielraums
+     PHIOLE_IDS	      Array der Strings, mit denen sich die Tuer 
+                      ansprechen laesst
+     PHIOLE_GENDER    Geschlecht der Tuer
+     PHIOLE_STATUS    aktueller Status der Tuer:
+                      0 geschlossen/verschlossen, 1 offen
+                      Bei Tueren, die mit NewDoor erzeugt wurden
+                      nicht setzen
+     PHIOLE_LONG      Beschreibung des Zielraums (z.B. bei einer 
+                      Faketuer)
+     PHIOLE_VERBOTEN  0 erlaubt, 1 verboten
+
+BEISPIEL:
+     Ein Raum enthaelt eine Holztuer und ein Portal. Erstere ist mittels 
+     NewDoor(...) gebaut, soll aber nicht zu durchschauen sein, letztere ist 
+     selbstgestrickt. Die erste fuehrt in den Workroom von Jof, die zweite
+     ist nur ein Fake und immer geschlossen. Bei vom Doormaster erzeugten 
+     Tueren sollte PHIOLE_STATUS nicht gesetzt werden, da dies automatisch
+     abgefragt wird.
+     
+     #include "/p/service/miril/phiole.h"
+     ...
+     mixed *GetPhiolenInfos(){
+       return ({
+                ([
+                  PHIOLE_DEST:"/players/jof/workroom",
+                  PHIOLE_IDS:({"holztuer"}),           
+                  PHIOLE_GENDER:FEMALE,                    
+                  PHIOLE_VERBOTEN:1          
+                ]),
+                ([
+                  PHIOLE_DEST:0,
+                  PHIOLE_IDS:({"portal"}),           
+                  PHIOLE_GENDER:NEUTER, 
+                  PHIOLE_STATUS:0,
+                  PHIOLE_LONG:"Du stehst in einer riesigen Schatzkammer und "
+                              "kannst Dein Glueck kaum fassen. Nun brauchst "
+                              "Du nur noch zuzugreifen und bist der reichste "
+                              "Bewohner des MorgenGrauen.",
+                  PHIOLE_VERBOTEN:0
+                ])
+              });
+      }
+      Mittels PHIOLE_LONG laesst sich auch bei erlaubten und verbotenen Tueren 
+      einstellen, was der Spieler statt der normalen Raumbeschreibung und den 
+      im Raum befindlichen Objekten sehen soll. Das koennte z.B. sinnvoll 
+      sein, falls der Spieler zwar die Raumbeschreibung, aber nicht den fiesen 
+      Drachen sehen soll, der sich ebenfalls im Raum befindet.
+      
+SIEHE AUCH:
+      NewDoor(), QueryDoorStatus(), SetDoorStatus(), QueryAllDoors()
+-----------------------------------------------------------------------------
+Letzte Aenderung: Sam, 14. Jan 2006, 12:21, Miril
diff --git a/doc/lfun/GetReputation b/doc/lfun/GetReputation
new file mode 100644
index 0000000..b60cdf8
--- /dev/null
+++ b/doc/lfun/GetReputation
@@ -0,0 +1,26 @@
+GetReputation
+FUNKTION:
+     public int GetReputation(string repid)
+
+DEFINIERT IN:
+     /std/player/reputation.c
+
+ARGUMENTE:
+     repid
+       Eindeutige ID der angefragten Reputation.
+
+BESCHREIBUNG:
+     Liefert den aktuellen Wert der angegebenen Reputation <repid> zurueck.
+
+RUeCKGABEWERT:
+     Zahlenwert, Integer.
+
+BEISPIELE:
+     s. reputation
+
+SIEHE AUCH:
+     reputation
+     ChangeReputation(), GetReputations()
+
+ZULETZT GEAeNDERT:
+06.04.2009, Zesstra
diff --git a/doc/lfun/GetReputations b/doc/lfun/GetReputations
new file mode 100644
index 0000000..81d571e
--- /dev/null
+++ b/doc/lfun/GetReputations
@@ -0,0 +1,23 @@
+GetReputations
+FUNKTION:
+     public mapping GetReputations()
+
+DEFINIERT IN:
+     /std/player/reputation.c
+
+BESCHREIBUNG:
+     Liefert ein Mapping aller im Spieler gespeicherten Reputationen und ihrer
+     Werte zurueck.
+
+RUeCKGABEWERT:
+     Mapping ([(string)repid: (int)wert])
+
+BEISPIELE:
+     s. repuation
+
+SIEHE AUCH:
+     reputation
+     GetReputation(), GetReputations()
+
+ZULETZT GEAeNDERT:
+06.04.2009, Zesstra
diff --git a/doc/lfun/GetValue b/doc/lfun/GetValue
new file mode 100644
index 0000000..1c95119
--- /dev/null
+++ b/doc/lfun/GetValue
@@ -0,0 +1,37 @@
+FUNKTION:
+
+	varargs int GetValue(string vname, mapping map, object pl) 
+
+
+ARGUMENTE:
+
+	vname	: name des parameters aus dem spellmapping
+	map   	: spellmapping
+	pl 	: caster
+
+
+BESCHREIBUNG:
+
+	'Berechnet' den Wert des uebergebenen Parameters aus dem 
+	Spellmapping.
+
+
+RUECKGABEWERT:
+
+	Berechneter Wert aus dem Spellmapping.
+
+
+BEMERKUNGEN:
+
+	
+
+
+BEISPIEL:
+
+	xxx=GetValue(SI_SKILLDAMAGE,sinfo,caster);
+
+Siehe auch:
+
+	"GetFactor", "GetOffset", "GetFValue", "GetValueO", "GetFValueO"
+
+	Ausfuehrliches Beispiel siehe "GetFValueO".
diff --git a/doc/lfun/GetValueO b/doc/lfun/GetValueO
new file mode 100644
index 0000000..e55b8f3
--- /dev/null
+++ b/doc/lfun/GetValueO
@@ -0,0 +1,36 @@
+FUNKTION:
+
+	varargs int GetValueO(string vname, mapping map, object pl) 
+
+
+ARGUMENTE:
+
+	vname	: name des parameters aus dem spellmapping
+	map   	: spellmapping
+	pl 	: caster
+
+
+BESCHREIBUNG:
+
+	Berechnet den Wert und den Offset des Parameters in spellmapping.
+
+
+RUECKGABEWERT:
+
+	Berechneter Wert+Offset aus dem Spellmapping.
+
+
+BEMERKUNGEN:
+
+	Ruft GetValue(vname,map,pl)+GetOffset(vname,map,pl) auf.
+
+
+BEISPIEL:
+
+	xxx=GetValueO(SI_SKILLDAMAGE,sinfo,caster);
+
+Siehe auch:
+
+	"GetValue", "GetFactor", "GetOffset", "GetFValue", "GetFValueO"
+
+	Ausfuehrliches Beispiel siehe "GetFValueO".
diff --git a/doc/lfun/Gildenproperties b/doc/lfun/Gildenproperties
new file mode 100644
index 0000000..30a16c3
--- /dev/null
+++ b/doc/lfun/Gildenproperties
@@ -0,0 +1,131 @@
+Name			Beschreibung
+
+P_GUILD_SKILLS		Property fuer Skills in der Gilde
+P_GUILD_RESTRICTIONS 	Restriktionen fuer den Eintritt in die Gilde
+P_GUILD_DEFAULT_SPELLBOOK  
+P_GUILD_MALE_TITLES 	Maennliche Gildentitel
+P_GUILD_FEMALE_TITLES	Weibliche Gildentitel
+P_GUILD_LEVELS		Gildenstufen
+P_SB_SPELLS 		Property fuer Spells in Spellbook
+P_GLOBAL_SKILLPROPS	Properties der Gilde UND des Spellbooks
+
+Properties des Spielers:
+P_GUILD			String mit dem Namen der Gilde
+P_GUILD_LEVEL		Gildenstufe
+P_GUILD_TITLE		Gildentitel
+P_GUILD_RATING		Rating in der Gilde
+P_NEWSKILLS		mapping mit Skills und Spells
+P_NEXT_SPELL_TIME	Zeit bis der naechste Spell gesprochen werden kann
+P_TMP_ATTACK_HOOK	Angriffs-Ersatzfunktion
+P_TMP_ATTACK_MOD	Angriffs-Modifizierung
+P_TMP_DEFEND_HOOK	Abwehr-Ersatzfunktion
+P_TMP_DIE_HOOK		"Die"-Ersatzfunktion
+P_TMP_MOVE_HOOK		Bewegungs-Ersatzfunktion
+P_DEFENDERS		Verteidiger
+P_PREPARED_SPELL	Vorbereiteter Spell
+P_DEFAULT_GUILD		Standardgilde
+P_MAGIC_RESISTANCE_OFFSET Offset fuer Magie-Resistenzen
+
+Standard-Skills:
+SK_FIGHT		Kampfskill(global)
+SK_SWORDFIGHTING	Schwertkampf
+SK_WEAPONLESS		Waffenloser Kampf
+SK_TWOHANDED       	Zweihandkampf
+SK_CASTING         	Zauber-Skill
+SK_MAGIC_ATTACK    	Magischer Angriff
+SK_MAGIC_DEFENSE   	Magische Abwehr
+SK_NIGHTVISION     	Nachtsicht
+SK_BOOZE           	Sauf-Skill
+SK_INFORM_DEFEND   	
+SK_DEFEND_OTHER		
+SK_CARRY		Trage-Skill
+SK_SPELL_DEFEND		Spruch-Abwehr
+
+Skill-Attribute:
+P_SKILL_ATTRIBUTES	Property fuer Skill-Attribute
+P_SKILL_ATTRIBUTE_OFFSETS   Property fuer Offsets der Skill-Attribute
+SA_QUALITY		Allgemeine Qualitaet
+SA_DAMAGE		Schaden
+SA_SPEED		Geschwindigkeit
+SA_DURATION		Dauer
+SA_EXTENSION		Ausdehnung
+SA_RANGE		Reichweit
+SA_ENEMY_SAVE: identisch zu SA_SPELL_PENETRATION (OBSOLET!)
+SA_SPELL_PENETRATION: Chance des _Casters_, einen Spell durch ein
+                      P_NOMAGIC durchzukriegen.
+
+Skill-Info:
+FACTOR(x)		Faktor
+OFFSET(x)		Offset
+SI_SKILLFUNC		Funktion, die aufgerufen wird
+SI_CLOSURE		Intern (Geschwindigkeitsoptimierung)
+SI_SPELLBOOK		Spellbook, in dem der Spell steht
+SI_SPELLCOST		Kosten des Spells
+SI_TIME_MSG		Die Meldung wird anstelle von "Du bist noch zu 
+			erschoepft von Deinem letzten Spruch." ausgegeben.
+SI_SP_LOW_MSG		Die Meldung wird anstelle von "Du hast zu wenig 
+			Zauberpunkte fuer diesen Spruch." ausgegeben.
+SI_NOMAGIC		Prozentwert, mit dem P_NOMAGIC mgangen werden kann
+SI_SPELLFATIGUE		Erschoepfung - Zeit, in der keine weiteren Spells
+			aufgerufen werden koennen
+SI_SKILLLEARN		Lerngeschwindigkeit in 0.01% pro A_INT/2
+SI_SKILLABILITY		Faehigkeit, diesen Spruch zu benutzen
+SI_SKILLARG		Argumente, die uebergeben wurden
+SI_SKILLRESTR_USE	Beschraenkungen beim Gebrauch
+SI_SKILLRESTR_LEARN	Beschraenkungen beim Lernen
+SI_SKILLINFO		Kurzer Informationstext
+SI_SKILLINFO_LONG	Langer Informationstext
+SI_SKILLDAMAGE		Schaden
+SI_SKILLDAMAGE_TYPE	Art des Schadens
+SI_SKILLDAMAGE_MSG	Meldung die anstelle einer Waffe kommen soll
+SI_SKILLDAMAGE_MSG2	dito fuer den Text fuer andere im Raum
+SI_SPELL		Spell, mit dem angegriffen wurde
+SI_INHERIT		Skill, von dem etwas uebernommen werden soll
+SI_DIFFICULTY		Wert, der die Obergrenze der Faehigkeit abgrenzt
+SI_LASTLIGHT		Fuer Nachtsicht: Wann hat der Spieler zum letzten 
+			mal Licht gesehen.
+SI_SKILLHEAL		Heilung
+SI_USR			selbst definierte Infos
+SI_GUILD		Gilde, falls Auswahl aus mehreren moeglich
+SI_ENEMY		Feind bei Kampfspruechen
+SI_FRIEND		Der zu verteidigende Freund bei DefendOther 
+			und InformDefend
+SI_MAGIC_TYPE		Von was fuer einer Art ist die Magie (s.u.)
+SI_PREPARE_TIME		Zeit die zur Vorbereitung benoetigt wird.
+SI_ATTACK_BUSY_MSG	Meldung, wenn der Spieler zu beschaeftigt ist
+SI_NO_ATTACK_BUSY	Wenn der Spell nicht als Taetigkeit zaehlen/gezaehlt 
+			werden soll, kann man hier 
+			NO_ATTACK_BUSY[_SET|_QUERY] setzen
+SP_NAME			Name des Spells, falls Mapping
+SP_SHOW_DAMAGE		Treffermeldung soll gezeigt werden.
+SP_REDUCE_ARMOUR	AC soll Typabhaengig reduziert werden.
+SP_PHYSICAL_ATTACK	Koerperlicher Angriff
+SP_RECURSIVE		Rekursionen
+
+Skill-Restrictions:
+SR_FUN			Funktion, die weitere Einschraenkungen prueft
+SR_EXCLUDE_RACE		Ausgeschlossene Rassen
+SR_INCLUDE_RACE		Eingeschlossene Rassen
+SR_GOOD			Align < 
+SR_BAD			Align >
+SR_FREE_HANDS		Benoetigte freie Haende
+SR_SEER			Muss Seher sein
+SR_MIN_SIZE		Mindestgroesse
+SR_MAX_SIZE		Maximalgroesse
+SM_RACE			Rassenspezifische Besonderheiten
+
+Magie-Arten:
+MT_ANGRIFF      	Angriff
+MT_SCHUTZ       	Schutz
+MT_ILLUSION     	Illusion
+MT_BEHERRSCHUNG 	Beherrschung
+MT_HELLSICHT    	Hellsicht
+MT_VERWANDLUNG  	Verwandlung
+MT_BESCHWOERUNG 	Beschwoerung
+MT_BEWEGUNG     	Bewegung
+MT_SAKRAL       	'Goettliches'
+MT_HEILUNG      	Heilung
+MT_CREATION     	Erschaffung
+MT_PSYCHO       	Psycho-Kram
+MT_MISC         	Sonstiges
+
diff --git a/doc/lfun/GiveMiniQuest b/doc/lfun/GiveMiniQuest
new file mode 100644
index 0000000..c08418c
--- /dev/null
+++ b/doc/lfun/GiveMiniQuest
@@ -0,0 +1,43 @@
+GiveMiniQuest()
+
+FUNKTION:
+        int GiveMiniQuest(object winner)
+
+DEFINIERT IN:
+        /secure/questmaster
+
+ARGUMENTE:
+	winner
+	  Spielerobjekt, das die Quest bestanden hat.
+
+RUeCKGABEWERT:
+        (Die Defines fuer den Rueckgabewert finden sich in 
+         /secure/questmaster.h)
+         1 : Hat geklappt                           (OK)
+        -1 : Spieler hat die Quest bereits geloest  (MQ_ALREADY_SET)
+        -2 : Ungueltiger Questname                  (MQ_KEY_INVALID)
+        -3 : Unbefugter Zugriff                     (MQ_ILLEGAL_OBJ)
+        -4 : Quest zur Zeit inaktiv                 (MQ_IS_INACTIVE)
+        -5 : Gaeste loesen keine Quests             (MQ_GUEST)
+
+BESCHREIBUNG:
+	Mit dieser Funktion wird nach dem erfolgreichen Loesen einer 
+        MiniQuest die Quest im Spieler eingetragen. Dabei muss der
+        Aufruf in dem Objekt erfolgen, welches im Questmaster 
+        eingetragen ist. Als Argument muss das Spielerobjekt 
+	angegeben werden, welches die Quest bestanden hat.
+        
+BEISPIEL:
+	QM->GiveMiniQuest(this_player());
+
+SIEHE AUCH:
+        HasMiniQuest
+        /secure/questmaster.h, /secure/questmaster.c
+
+HINWEIS:
+        Die Informationen fuer den EM fuer Quests sollten diesem
+        beim Eintragen der Miniquest in den Questmaster per Mail
+        zugeschickt werden. Siehe dazu die Hilfe zu AddMiniQuest.
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: Don, 30. Jan 2014, 22:14:12 von Ark.
diff --git a/doc/lfun/GiveQuest b/doc/lfun/GiveQuest
new file mode 100644
index 0000000..613a501
--- /dev/null
+++ b/doc/lfun/GiveQuest
@@ -0,0 +1,63 @@
+GiveQuest()
+
+FUNKTION:
+        varargs int GiveQuest(string questname, string message)
+
+DEFINIERT IN:
+        /std/player/quests.c
+
+ARGUMENTE:
+        questname
+          Questname, wie er im Questmaster eingetragen wurde.
+        message 
+          Optionale Meldung, die auf dem Abenteuer-Kanal statt der 
+          Standardmeldung gesendet wird.
+          Dabei wird @@name@@ durch den Spielernamen ersetzt.
+
+RUeCKGABEWERT:
+        (Die Defines fuer den Rueckgabewert finden sich in 
+         /secure/questmaster.h)
+         1 : Hat geklappt                           (OK)
+        -1 : Spieler hat die Quest bereits geloest  (GQ_ALREADY_SET)
+        -2 : Ungueltiger Questname                  (GQ_KEY_INVALID)
+        -3 : Unbefugter Zugriff                     (GQ_ILLEGAL_OBJ)
+        -4 : Quest zur Zeit inaktiv                 (GQ_IS_INACTIVE)
+
+BESCHREIBUNG:
+        Mit dieser Funktion wird nach dem erfolgreichen Loesen einer 
+        Quest die Quest im Spieler eingetragen. Dabei muss der Aufruf 
+        in dem Objekt erfolgen, welches im Questmaster eingetragen ist.
+        Zusaetzlich wird der Zeitpunkt eingetragen, an dem die Quest
+        bestanden wurde.
+        
+        Wer sich da nicht sicher ist, kann mit dem Questtool 
+        (/obj/tools/questtool) nachsehen. 
+
+        Nachdem eine Quest als geloest markiert wurde, ist dies in einem 
+        Logfile fuer die Quest im Verzeichnis /log/quest einzutragen. Dazu
+        wird write_file verwendet.
+
+BEISPIEL:
+
+        int quest;
+
+        quest = this_player()->GiveQuest("Zacharias Eispalast");
+
+        if (quest == 1)
+        {
+          write("Du fuehlst, wie Deine Erfahrung ansteigt.\n");
+          write_file("/log/quest/eispalast", 
+                     dtime(time())+"   Aufgabe geloest von "
+                     +this_player()->name()+"\n");
+        } 
+        else if (quest != -1)
+          write( "Die Weltenmaschine will Dir Deine Arbeit "
+                 +"nicht anerkennen.\n"
+                 +"Frage einen Erzmagier um Hilfe.\n" );
+
+SIEHE AUCH:
+        /secure/questmaster.h, /obj/tools/questtool
+        QueryQuest(), write_file(), ModifyQuestTime()
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: Son, 27. Apr 2014, Arathorn
diff --git a/doc/lfun/GroupName b/doc/lfun/GroupName
new file mode 100644
index 0000000..7a81c45
--- /dev/null
+++ b/doc/lfun/GroupName
@@ -0,0 +1,63 @@
+GroupName()
+FUNKTION:
+     string GroupName(string grp)
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+ARGUMENTE:
+     string grp - ein Gruppenname
+
+BESCHREIBUNG:
+     Gibt die Langbeschreibung des Gruppennamens zurueck.
+
+RUECKGABEWERT:
+     Die Gruppenbeschreibung oder "Unbekanntes"
+
+BEISPIELE:
+     // simpel
+     tmp=m_indices(ob->QueryProp(P_MATERIAL));
+     write("Dieses Objekt gehoert u.a. zur Gruppe "+
+           MATERIALDB->GroupName(MATERIALDB->GetMatMembership(tmp[0])[0])+
+           ".\n");
+     // gibt die erste Gruppenzugehoerigkeit des erste Materials in
+     // P_MATERIAL zurueck (bei MATGROUP_METAL z.B. "... zur Gruppe Metalle.")
+
+     // ein weiser Schmied:
+     int i;
+     string *mat, mname, mgroup;
+     mat=m_indices(ob->QueryProp(P_MATERIAL));
+     i=sizeof(mat);
+
+     write("Der Schmied sagt: "+ob->Name(WER)+" besteht aus ...\n");
+     while(i--) {
+      // den Namen erkennen/aussprechen:
+      // Materialien werden allgemein ganz schlecht erkannt (zu 5%), aber
+      // alles aus Metall wird zu +100% gut erkannt ...
+      mname=MATERIALDB->MaterialName(mat[i], WER,
+	     ({5, ([MATERIAL_SYMMETRIC_RECOGNIZABILITY:
+			({MATGROUP_METAL, 100})])}));
+
+      // und nur Metalle analysieren ...
+      if(MATERIALDB->MaterialGroup(([mat[i]:100]),MATGROUP_METAL)>=100) {
+       int j;
+       string *mgr;
+       mgr=MATERIALDB->GetMatMembership(mat[i]);
+       j=sizeof(mgr);
+       mgroup=" gehoert zu ";
+       while(j--) {
+        mgroup+=MATERIALDB->GroupName(mgr[j]);
+        if(j>0) mgroup+=", ";
+       }
+      } else mgroup=" kenne ich nicht";
+      printf("%-12.12s: %s\n",mname, mgroup);
+     }
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/GuardExit b/doc/lfun/GuardExit
new file mode 100644
index 0000000..0ba53c4
--- /dev/null
+++ b/doc/lfun/GuardExit
@@ -0,0 +1,85 @@
+FUNKTION:
+     protected <int|<string|closure>* >* GuardExit(object room, int hookid,
+                                                   <string|closure>* hdata);
+
+DEFINIERT IN:
+     /std/npc/moving.c
+
+ARGUMENTE:
+     room
+          Der den Hook ausloesende Raum (environment())
+     hookid
+          Die ID des Hooks (H_HOOK_EXIT_USE)
+     hdata
+          Ein Array mit 3 Elementen:
+          ({
+              verb - Das Kommandoverb/Ausgangsname (string)
+              dest - Zielraum (string) oder closure (special exits)
+              msg  - Bewegungsrichtung (string) oder 0
+          })
+
+BESCHREIBUNG:
+     Ist diese Funktion in einem NPC definiert, traegt sich der NPC bei jeder
+     Bewegung automatisch als Konsument von H_HOOK_EXIT_USE ein und diese
+     Funktion wird immer gerufen, wenn ein Lebewesen im gleichen Environment
+     wie der NPC versucht, einen Ausgang zu benutzen.
+     Der NPC kann dann die Bewegung abbrechen (und so den Ausgang
+     blockieren), Ziel oder Bewegungsmeldung aendern oder keine Veraenderung
+     vornehmen.
+     Die Konstanten fuer Hookid und Hookstatus (s. Rueckgabewert) sind in
+     <hook.h> definiert.
+
+RUeCKGABEWERT:
+     Array mit zwei Elementen:
+     ({
+         H_NO_MOD / H_ALTERED / H_CANCELLED,
+         hdata
+     })
+     hdata ist ggf. das geaenderte Array, welches die Funktion uebergeben
+     wird. Weitere Details s. auch /doc/std/hooks
+
+BEMERKUNGEN:
+     Die Anzahl an Konsumenten eines Hooks ist begrenzt. Es ist daher
+     moeglich, dass die Registrierung nicht klappt, wenn zuviele (>5) Waechter
+     im Raum sind. Will man darauf reagieren, muesste man die Registrierung
+     pruefen.
+     Ein NPC, welcher GuardExit() definiert, aber im aktuellen Environment
+     keine Wache halten will, könnte sich selber de-registrieren.
+
+BEISPIELE:
+     <int|<string|closure>* >* GuardExit(object room, int hookid,
+                                         <string|closure>* hdata)
+     {
+       // Nur in Gefaengnisraeumen Wache halten
+       if (strstr(object_name(environment()), "/room/jail")==0)
+       {
+         // Hier gehts nicht raus. ;-)
+         if (hdata[0] == "raus") {
+             tell_object(this_player(), ...);
+             return ({H_CANCELLED, hdata});
+         }
+         // Special exits ersetzen wir durch einen eigenen
+         else if (closurep(hdata[1])) {
+           hdata[1] = #'my_special_exit;
+           return ({H_ALTERED, hdata});
+         }
+         // alle anderen Ausgaenge in die persoenliche Zelle
+         else {
+           tell_object(this_player(), ...);
+           hdata[1] = "/room/jail_"+getuid(this_player());
+           hdata[2] = "Sueden";
+           return ({H_ALTERED, hdata});
+         }
+      }
+      // in allen anderen Raeumen nicht eingreifen
+      return ({H_NO_MOD, hdata});
+    }
+
+
+SIEHE AUCH:
+     AddExit, AddSpecialExit, RemoveExit
+     HRegisterToHook, HRegisterModifier, HUnregisterFromHook
+     /doc/std/hooks
+----------------------------------------------------------------------------
+20.02.2016, Zesstra
+22.05.2016, Mupfel (Beispiel korrigiert)
diff --git a/doc/lfun/Halt b/doc/lfun/Halt
new file mode 100644
index 0000000..06bfda4
--- /dev/null
+++ b/doc/lfun/Halt
@@ -0,0 +1,30 @@
+Halt()
+
+FUNKTION:
+     void Halt();
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Die Fahrt des Transporters wird abgebrochen. Sie muss explizit mit
+     Start() wieder aufgenommen werden!
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Es gibt keine einfache Moeglichkeit, die Fahrt eines Transporters an
+     der Stelle wieder aufzunehmen, an der sie unterbrochen wurde. Man
+     muesste die aktuelle Position mit QueryPosition() ermitteln, mit Hilfe
+     der AddXXX()-Aufrufe in eine Positionsnummer umwandlen und diese an
+     Start() uebergeben.
+
+SIEHE AUCH:
+     Start(), /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:19:23 1996 by Wargon
diff --git a/doc/lfun/HasMiniQuest b/doc/lfun/HasMiniQuest
new file mode 100644
index 0000000..76fc394
--- /dev/null
+++ b/doc/lfun/HasMiniQuest
@@ -0,0 +1,37 @@
+HasMiniQuest()
+
+FUNKTION:
+        int HasMiniQuest(mixed pl, mixed name)
+
+DEFINIERT IN:
+        /secure/questmaster
+
+ARGUMENTE:
+        pl
+          Name des Spielers oder das Spielerobjekt
+        name
+          Filename des Objekts oder das Objekt selbst, welches die Miniquest
+          im Spieler eintragen darf, oder die Nummer (int) der Miniquest
+
+RUeCKGABEWERT:
+         1 : Der Spieler hat die MiniQuest
+         0 : Der Spieler hat die MiniQuest noch nicht
+        -2 : angegebene Miniquest existiert nicht
+        -3 : falsche Datentypen fuer pl oder name uebergeben
+
+BESCHREIBUNG:
+        Mit dieser Funktion kann getestet werden, ob ein Spieler eine 
+        MiniQuest bereits geloest hat. Dabei ist entweder der Filename des 
+        Objektes anzugeben, das die Quest im Spieler eintragen darf oder
+        das Objekt selbst.
+        
+BEISPIEL:
+        if( QM->HasMiniQuest(getuid(this_player()), this_object())!=1 )
+          write("Du bist noch nicht reif genug.\n");
+
+SIEHE AUCH:
+        GiveMiniQuest(L)
+        /secure/questmaster.h, /secure/questmaster.c
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: 2014-Feb-03, Arathorn.
diff --git a/doc/lfun/HitFunc b/doc/lfun/HitFunc
new file mode 100644
index 0000000..3d22075
--- /dev/null
+++ b/doc/lfun/HitFunc
@@ -0,0 +1,68 @@
+HitFunc()
+
+FUNKTION:
+     int HitFunc(object enemy);
+
+DEFINIERT IN:
+     eigenen Objekten, fuer /std/weapon/combat.c
+
+ARGUMENTE:
+     enemy
+          Der Gegner, gegen den die Waffe eingesetzt wird.
+
+BESCHREIBUNG:
+     Die Waffe kann anhand des Gegners enemy entscheiden, ob ein
+     Schadensbonus oder auch ein Schadensmalus wirksam wird. Dieser Bonus
+     wird zu dem normalen Schaden der Waffe hinzuaddiert.
+
+RUeCKGABEWERT:
+     Der Schadensbonus bzw. der Abschlag.
+
+BEMERKUNGEN:
+     Wenn durch den Bonus die Genehmigungsgrenzen der Balance
+     ueberschritten werden koennen, muss man seinen Regionsmagier und
+     die Objekt-Balance konsultieren!
+
+     Werte der HitFunc sollten immer ueber ein random() zurueckgegeben 
+     werden!
+
+     Diese Funktion sollte die Waffe nicht zerstoeren! Falls ihr im Kampf eine
+     Waffe (ggf. in Abhaengigkeit vom Gegner) zerstoeren wollt, nutzt dazu
+     bitte TakeFlaw(). 
+
+BEISPIELE:
+     Eine Waffe, die gegen Orks besonders gut wirkt:
+
+     inherit "std/weapon";
+
+     #include <properties.h>
+     #include <combat.h>
+     #include <class.h>
+
+     create(){
+       if(!clonep(this_object())) {
+           set_next_reset(-1);
+           return;
+       }
+       ::create();
+       /* 
+       zig SetProp's, um die Waffe zu konfigurieren
+       HitFunc() ist in der Waffe selbst definiert 
+       */
+       SetProp(P_HIT_FUNC, this_object());
+     }
+
+     int HitFunc(object enemy)
+     {
+       /* laesst sich der Gegner als Ork ansprechen? */
+       if (enemy->is_class_member(CL_ORC))
+         return random(10+random(50)); /* Ja => Schaden erhoehen */
+
+       return 0;   /* ansonsten keinen zusaetzlichen Schaden anrichten */
+     }
+
+SIEHE AUCH:
+     QueryDefend(), /std/weapon.c
+     TakeFlaw()
+----------------------------------------------------------------------------
+11.08.2007, Zesstra
diff --git a/doc/lfun/Identify b/doc/lfun/Identify
new file mode 100644
index 0000000..836e58b
--- /dev/null
+++ b/doc/lfun/Identify
@@ -0,0 +1,24 @@
+Identify()
+
+FUNKTION:
+     void Identify(object ob);
+
+DEFINIERT IN:
+     /std/corpse.c
+
+ARGUMENTE:
+     ob
+          Das kuerzlich nach langem, hartem Kampf verstorbene Objekt.
+
+BESCHREIBUNG:
+     In dieser Funktion werden Lang- und Kurzbeschreibung der Leiche gesetzt
+     sowie die Verwesung in Gang gesetzt.
+
+RUeCKGABEWERT:
+     keiner
+
+SIEHE AUCH:
+     /std/corpse.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:19:57 1996 by Wargon
diff --git a/doc/lfun/InFight b/doc/lfun/InFight
new file mode 100644
index 0000000..086c5bd
--- /dev/null
+++ b/doc/lfun/InFight
@@ -0,0 +1,32 @@
+InFight()
+
+FUNKTION:
+        mixed InFight()
+
+ARGUMENTE:
+        keine
+
+BESCHREIBUNG:
+        Diese Funktion wurde dazu geschrieben, um herauszufinden,
+        ob sich ein PC/NPC direkt im Kampf befindet. Dazu wird
+        das Array mit den Namen der Feinden des PC/NPCs durch die
+        Funktion environment gefiltert und so festgestellt, ob
+        die Umgebung der beiden Feinde gleich ist.
+
+RUECKGABEWERT: 
+        Als Rueckgabewert enthaelt man entweder 0, wenn das Objekt
+        im Moment keine Feinde hat bzw. die nicht im selben Raum
+        sind, oder aber das Feindobjekt, das als erstes im Array
+        steht und anwesend ist.
+
+BEISPIEL:
+        Selbsterklaerend ;)
+
+BEMERKUNG:
+        InFight() gibt lediglich das Ergebnis von EnemyPresent() zurueck.
+
+SIEHE AUCH:
+        EnemyPresent(), PresentEnemies()
+        /std/living/combat.c
+
+22.03.2009, Zesstra
diff --git a/doc/lfun/InList b/doc/lfun/InList
new file mode 100644
index 0000000..adcd431
--- /dev/null
+++ b/doc/lfun/InList
@@ -0,0 +1,28 @@
+InList()
+
+FUNKTION:
+     int InList(object room, int *potionlist, int *knownlist)
+
+DEFINIERT IN:
+     /secure/potionmaster.c
+
+ARGUMENTE:
+     Implizit: previous_object() - Spielerobjekt, das ZT bekommen soll
+     object room                 - Objekt, welches ZT vergeben will
+     int* potionlist             - Liste der ZTs des Spielers
+     int* knownlist              - Liste der bekannten ZTs des Spielers
+
+BESCHREIBUNG:
+     Prueft, ob 'room' einen ZT vergeben darf und gibt zurueck, ob die
+     Nummer dieses ZTs in der 'knownlist' enthalten ist.
+
+RUeCKGABEWERT:
+     0  Kein aktiver ZT oder nicht in Liste enthalten.
+     1  Aktiver ZT und in Liste.
+
+SIEHE AUCH:
+     Sonstiges: zaubertraenke, /room/orakel.c
+     Verwandt:  FindPotion(), RemoveKnownPotion(), AddKnownPotion()
+     Props:     P_POTIONROOMS, P_KNOWN_POTIONROOMS
+
+6.Feb 2016 Gloinson
diff --git a/doc/lfun/InformAlcoholEffect b/doc/lfun/InformAlcoholEffect
new file mode 100644
index 0000000..0fa5297
--- /dev/null
+++ b/doc/lfun/InformAlcoholEffect
@@ -0,0 +1,43 @@
+InformAlcoholEffect
+
+FUNKTION:
+	void InformAlcoholEffect(object pl, int msgid, int area)
+
+DEFINIERT IN:
+     eigenen Objekten; fuer /std/living/life.c
+ 
+ARGUMENTE:
+	pl
+          Das Lebewesen, das alkoholisiert ist.
+        msgid
+          Flag fuer die Meldung, die ausgegeben wird.
+        area
+          Aufruf erfolgt in Gilde (0) oder im Environment (1).
+
+BESCHREIBUNG:
+        Wenn ein Lebewesen alkoholisiert ist, werden in unregelmaessigen
+        Abstaenden Meldungen an die Umgebung und ans Lebewesen ausgegeben.
+        Gleichzeitig wird die Funktion InformAlcoholEffect in der Gilde
+        und im Environment des Lebewesens aufgerufen.
+        
+        Es gibt vier verschiedene Meldungen (definiert in /sys/health.h):
+        ALC_EFFECT_HICK      (0) : "<Hick>! Oh, Tschuldigung.\n"
+        ALC_EFFECT_RUELPS    (1) : "Du ruelpst.\n"
+        ALC_EFFECT_LOOKDRUNK (2) : "Du fuehlst Dich benommen.\n"
+        ALC_EFFECT_STUMBLE   (3) : "Du stolperst.\n"
+        
+        Wird die Funktion in einem Gildenraum implementiert, so kann man
+        anhand des 3. Parameters unterscheiden, ob die Gilde als Gilde
+        oder als Raum gemeint ist (die Funktion wird je einmal aufgerufen):
+        ALC_EFFECT_AREA_GUILD (0) : der Aufruf betrifft die Gilde,
+        ALC_EFFECT_AREA_ENV   (1) : der Aufruf betrifft die Umgebung.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        P_ALCOHOL, /sys/health.h
+
+----------------------------------------------------------------------------
+Last modified: Thu May 23 23:08:00 2002 by Mupfel
+
diff --git a/doc/lfun/InformDefend b/doc/lfun/InformDefend
new file mode 100644
index 0000000..eb36921
--- /dev/null
+++ b/doc/lfun/InformDefend
@@ -0,0 +1,62 @@
+InformDefend()
+
+FUNKTION:
+	void InformDefend(object enemy);
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	enemy
+	  Der Feind, der ein zu verteidigendes Lebewesen angegriffen hat.
+
+BESCHREIBUNG:
+	Es ist moeglich, dass Objekte ueber Angriffe auf Lebewesen
+	informiert werden, sofern diese Objekte bei dem angegriffenen
+	Lebewesen mittels AddDefender() angemeldet wurden und sich der
+	selben Umgebung befinden.
+	Zumeist wird es sich bei den Objekten natuerlich ebenfalls um
+	andere Lebewesen handeln, die das Lebewesen, bei dem sie angemeldet
+	sind, verteidigen sollen.
+	Bei einem Angriff auf das Lebewesen werden alle Objekte per Aufruf
+	von InformDefend() darueber informiert, wobei der Angreifer als
+	Parameter uebergeben wird.
+	Standardmaessig ist diese Funktion in Lebewesen bereits definiert,
+	wobei der Skill SK_INFORM_DEFEND, sofern vorhanden, aufgerufen wird.
+
+BEISPIEL:
+	Sehr beliebt sind in Gilden NPCs, die den Beschwoerer begleiten und
+	verteidigen, z.B. beschworene Daemonen:
+	  inherit "std/npc";
+	  include <properties.h>
+	  object owner;
+	  void create()
+	  { ::create();
+	    SetProp(P_NAME,"Daemon");
+	    ...
+	  }
+	// nach Clonen des Daemons folgende Funktion mit Beschwoerer als
+	// Parameter aufrufen
+	  Identify(object caster)
+	  { if(!objectp(caster))
+	      call_out(#'remove,0);
+	    owner=caster;
+	    owner->AddDefender(this_object());
+	  }
+	// folgende Funktion wird automatisch aufgerufen, wenn der
+	// Beschwoerer angegriffen wird
+	  void InformDefend(object enemy)
+	  { if(!IsEnemy(enemy)&&enemy!=owner)
+	      Kill(enemy);
+	  }
+	Soll der Daemon sich auch in ein Team einordnen, in welchem sich der
+	Beschwoerer eventuell befindet, so ist zusaetzlich AssocMember() in
+	diesem Beschwoerer aufzurufen, wobei der Daemon als Parameter
+	uebergeben wird.
+
+SIEHE AUCH:
+	AddDefender(), RemoveDefender(), DefendOther(), Kill(), IsEnemy(),
+	P_DEFENDERS, /std/living/combat.c, /sys/new_skills.h
+
+----------------------------------------------------------------------------
+Last modified: Thu Jul 29 18:48:45 1999 by Patryn
diff --git a/doc/lfun/InformRowChange b/doc/lfun/InformRowChange
new file mode 100644
index 0000000..e2aa8fc
--- /dev/null
+++ b/doc/lfun/InformRowChange
@@ -0,0 +1,23 @@
+InformRowChange()
+
+FUNKTION:
+	varargs void InformRowChange(int from, int to, object caster);
+
+DEFINIERT IN:
+	/std/living/team.c
+
+ARGUMENTE:
+	from   - Reihe, in die der Spieler vorher war.
+	to     - Reihe in der der Spieler jetzt ist.
+	caster - Der Spieler, falls die Funktion in der Gilde aufgerufen wird.
+        
+BESCHREIBUNG:
+	Diese Funktion wird im Spieler und in seiner Gilde aufgerufen,
+	falls sich die aktuelle Kampfreihe in der Teamaufstellung
+	aendert.
+
+RUECKGABEWERT:
+	Keiner.
+
+SIEHE AUCH:
+	teams
diff --git a/doc/lfun/InformUnwear b/doc/lfun/InformUnwear
new file mode 100644
index 0000000..9471028
--- /dev/null
+++ b/doc/lfun/InformUnwear
@@ -0,0 +1,29 @@
+InformUnwear
+
+FUNKTION:
+	protected void InformUnwear(object pl, int silent, int all)
+
+DEFINIERT IN:
+        /std/clothing/wear.c
+
+ARGUMENTE:
+	pl
+          Das Lebewesen, das die Ruestung ausgezogen hat.
+        silent
+          Flag, ob Meldungen unterdruckt werden sollen.
+        all
+          Flag, ob die Ruestung mit "ziehe alles aus"/
+          "ziehe alle ruestungen aus" ausgezogen wurde.
+
+BESCHREIBUNG:
+        Diese Funktion wird aufgerufen, wenn die Ruestung erfolgreich
+        ausgezogen wurde.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        InformUnwield(), InformWield(), InformWear()
+
+----------------------------------------------------------------------------
+06.10.2007, Zesstra
diff --git a/doc/lfun/InformUnwield b/doc/lfun/InformUnwield
new file mode 100644
index 0000000..ef2d9bc
--- /dev/null
+++ b/doc/lfun/InformUnwield
@@ -0,0 +1,26 @@
+InformUnwield
+
+FUNKTION:
+	protected void InformUnwield(object pl, int silent)
+
+DEFINIERT IN:
+	/std/weapon/combat.c
+
+ARGUMENTE:
+	pl
+          Das Lebewesen, das die Waffe gezueckt hatte.
+        silent
+          Flag, ob Meldungen unterdruckt werden sollen.
+
+BESCHREIBUNG:
+        Diese Funktion wird aufgerufen, wenn die Waffe erfolgreich
+        weggesteckt wurde.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        InformWield(), InformWear(), InformUnwear()
+
+----------------------------------------------------------------------------
+06.10.2007, Zesstra
diff --git a/doc/lfun/InformWear b/doc/lfun/InformWear
new file mode 100644
index 0000000..4c7c9b4
--- /dev/null
+++ b/doc/lfun/InformWear
@@ -0,0 +1,29 @@
+InformWear
+
+FUNKTION:
+	protected void InformWear(object pl, int silent, int all)
+
+DEFINIERT IN:
+        /std/clothing/wear.c
+
+ARGUMENTE:
+	pl
+          Das Lebewesen, das die Ruestung angezogen hat.
+        silent
+          Flag, ob Meldungen unterdruckt werden sollen.
+        all
+          Flag, ob die Ruestung mit "trage alles"/"trage alle ruestungen"
+          angezogen wurde.
+
+BESCHREIBUNG:
+        Diese Funktion wird aufgerufen, wenn die Ruestung erfolgreich
+        angezogen wurde.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        InformUnwield(), InformWield(), InformUnwear()
+
+----------------------------------------------------------------------------
+06.10.2007, Zesstra
diff --git a/doc/lfun/InformWield b/doc/lfun/InformWield
new file mode 100644
index 0000000..67c6b98
--- /dev/null
+++ b/doc/lfun/InformWield
@@ -0,0 +1,26 @@
+InformWield
+
+FUNKTION:
+	protected void InformWield(object pl, int silent)
+
+DEFINIERT IN:
+	/std/weapon/combat.c
+
+ARGUMENTE:
+	pl
+          Das Lebewesen, das die Waffe gezueckt hat.
+        silent
+          Flag, ob Meldungen unterdruckt werden sollen.
+
+BESCHREIBUNG:
+        Diese Funktion wird aufgerufen, wenn die Waffe erfolgreich
+        gezueckt wurde.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        InformUnwield(), InformWear(), InformUnwear()
+
+----------------------------------------------------------------------------
+06.10.2007, Zesstra
diff --git a/doc/lfun/InsertEnemy b/doc/lfun/InsertEnemy
new file mode 100644
index 0000000..03d1d7d
--- /dev/null
+++ b/doc/lfun/InsertEnemy
@@ -0,0 +1,28 @@
+gefunden : lfun/InsertEnemy
+
+FUNKTION:
+        int InsertEnemy(object enemy)
+        
+DEFINIERT IN:
+        /std/living/combat.c
+        
+ARGUMENTE:
+        enemy: Das Lebewesen, das angegriffen werden soll.
+        
+BESCHREIBUNG:
+        Nach Aufruf der Funktion wird das Wesen in die Liste der Feinde
+        aufgenommen.
+        In jedem heart_beat() wird dann ein anwesender Feind
+        angegriffen.
+        
+RUECKGABEWERT:
+        0, falls der Feind nicht existiert, kein Lebewesen ist, ein Geist ist, 
+           oder im Gegner P_NO_ATTACK gesetzt ist, oder schon angegegriffen 
+           wurde
+        1  sonst
+        
+SIEHE AUCH:
+        Kill, IsEnemy, StopHuntFor, P_NO_ATTACK
+
+LETZTE AENDERUNG:
+26.08.2010, Zesstra
diff --git a/doc/lfun/InsertEnemyTeam b/doc/lfun/InsertEnemyTeam
new file mode 100644
index 0000000..e9ade63
--- /dev/null
+++ b/doc/lfun/InsertEnemyTeam
@@ -0,0 +1,46 @@
+
+InsertEnemyTeam()
+
+
+FUNKTION:
+        varargs void InsertEnemyTeam(mixed ens, int rek)
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        ens     object Feind oder object *Feinde
+        rek     Wurde von InsertEnemyTeam aufgerufen
+
+BESCHREIBUNG:
+        Alle Teammitglieder des Feindes bzw. die angegebenen Feinde (aber
+        nicht deren Teammitglieder) werden zu Feinden
+         a) des Spielers und aller Teammitglieder, falls rek==0
+         b) des Spielers, falls rek!=0
+
+RUECKGABEWERT:
+        keiner
+
+BEMERKUNGEN:
+        1. Nur wenn Gegner und Teammitglied im gleichen Raum stehen (aber
+           nicht notwendigerweise im gleichen Raum wie der Spieler) werden
+           sie zu Feinden.
+        2. Falls Teammitglied und Gegner beides Spieler sind, werden sie
+           nicht zu Feinden gemacht.
+        3. Ist der Gegner im eigenen Team, so wird nichts gemacht.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/InsertSensitiveObject b/doc/lfun/InsertSensitiveObject
new file mode 100644
index 0000000..c89cef8
--- /dev/null
+++ b/doc/lfun/InsertSensitiveObject
@@ -0,0 +1,48 @@
+InsertSensitiveObject()
+FUNKTION:
+     void InsertSensitiveObject(object ob, mixed *arg)
+
+DEFINIERT IN:
+     /std/container/inventory.c
+     generalizes /std/living/inventory.c
+
+BESCHREIBUNG:
+     Fuegt "ob" in die Benachrichtigungslisten des Containers ein.
+     Wird von thing/moving.c im Ziel-Environment gerufen, wenn
+     P_SENSITIVE gesetzt ist.
+
+BEMERKUNGEN:
+     Setzt man P_SENSITIVE nicht als Default sondern situationsabhaengig,
+     dann muss man auch InsertSensitiveObject() im Environment
+     auch selbst rufen!
+
+BEISPIEL:
+     // Fackel (inheriting lightsource)
+     // wenn angezuendet, aendert es die Eigenschaften und wird zum
+     // aktiven Objekt - das muss man dem environment() mitteilen
+     static int light(string str) {
+      int i;
+      i=::light(str);
+      if(i && QueryProp(P_LIGHT)>0) {
+       SetProp(P_SENSITIVE,
+        ({({SENSITIVE_INVENTORY_TRIGGER,DT_FIRE,120})}));
+       if(environment())
+        environment()->InsertSensitiveObject(this_object(),
+					     QueryProp(P_SENSITIVE));
+      }
+      return i;
+     }
+
+     - falls ein empfindliches Objekt im environment() ist, dann wird
+       in diesem nun eventuell (Treshold) trigger_sensitive_inv()
+       gerufen
+
+SIEHE AUCH:
+     P_SENSITIVE
+     RemoveSensitiveObject
+     insert_sensitive_inv_trigger, insert_sensitive_inv
+     P_SENSITIVE_ATTACK, P_SENSITIVE_INVENTORY, P_SENSITIVE_INVENTORY_TRIGGER
+     CheckSensitiveAttack
+
+25.Apr.2001, Gloinson@MG
+
diff --git a/doc/lfun/InternalModifyAttack b/doc/lfun/InternalModifyAttack
new file mode 100644
index 0000000..0ac2d19
--- /dev/null
+++ b/doc/lfun/InternalModifyAttack
@@ -0,0 +1,37 @@
+InternalModifyAttack(L)
+
+FUNKTION:
+     protected void InternalModifyAttack(mapping ainfo)
+
+DEFINIERT IN:
+     /std/living/combat
+
+ARGUMENTE:
+     mapping ainfo		Werte aus der Attack
+
+BESCHREIBUNG:
+     Dient dazu noch Aenderungen am Verhalten der Attack() vornehmen zu
+     koennen. Die Parameter werden alle per Referenz uebergeben, Aenderungen
+     wirken also direkt in der Attack()!
+     Einfach ueberschreiben (aber ::InternalModifyAttack(&ainfo) nicht
+     vergessen!
+
+     Aufbau von 'ainfo':
+     ([ SI_ENEMY :            object Angreifer,			(-> Defend)
+        SI_SPELL :           0/1/array Spellparameter,		(-> Defend)
+        P_WEAPON :           - oder Waffe,
+        SI_SKILLDAMAGE_MSG:  string Angriffsmeldungsende an Raum,
+        SI_SKILLDAMAGE_MSG2: string Angriffsmeldungsende an Kaempfende,
+        SI_SKILLDAMAGE:      int Schaden in Zehntel HP (Skills schon drin)
+								(-> Defend),
+        SI_SKILLDAMAGE_TYPE: string/string* Schadenstypen,	(-> Defend)
+        P_WEAPON_TYPE:       string Waffentyp (combat.h),
+        P_WC:		     - oder int WC der Waffe/Hand,
+        P_NR_HANDS:	     - oder int Hands der Waffe/Hand,
+     ]);
+
+SIEHE AUCH:
+     InternalModifyDefend(L)
+     Attack(L)
+
+28.03.2008, Zesstra
diff --git a/doc/lfun/InternalModifyDefend b/doc/lfun/InternalModifyDefend
new file mode 100644
index 0000000..93f0d39
--- /dev/null
+++ b/doc/lfun/InternalModifyDefend
@@ -0,0 +1,29 @@
+InternalModifyDefend(L)
+
+FUNKTION:
+     protected void InternalModifyDefend(int dam, mixed dt, mixed spell,
+				      object enemy)
+
+DEFINIERT IN:
+     /std/living/combat
+
+ARGUMENTE:
+     int dam             Staerke des abzuwehrenden Angriffs (in HP/10)
+     string/string* dt   Art(en) des Schadens, der angerichtet werden soll
+     int/mapping spell   0 fuer normale Angriffe (keine Zauber)
+                         1 fuer Zauber (Standardruestungen ignorieren)
+                         mapping fuer mehr Informationen
+     object enemy        der Feind/Schadenverursacher
+
+BESCHREIBUNG:
+     Dient dazu noch Aenderungen am Verhalten der Defend() vornehmen zu
+     koennen. Die Parameter werden alle per Referenz uebergeben, Aenderungen
+     wirken also direkt in der Defend()!
+     Einfach ueberschreiben, aber ::InternalModifyDefend(&..., &....) nicht
+     vergessen!
+
+SIEHE AUCH:
+     InternalModifyAttack(L)
+     Defend(L)
+
+28.03.2008, Zesstra
diff --git a/doc/lfun/IsEnemy b/doc/lfun/IsEnemy
new file mode 100644
index 0000000..c406cd5
--- /dev/null
+++ b/doc/lfun/IsEnemy
@@ -0,0 +1,31 @@
+IsEnemy()
+
+FUNKTION:
+	int IsEnemy(object wer);
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	wer
+	  Das Objekt, welches darauf ueberprueft werden soll, ob es
+	  derzeit als Gegner bekannt ist.
+
+RUeCKGABEWERT:
+	Flag: 1 bei Feindschaft, 0 sonst
+
+BESCHREIBUNG:
+	Mit dieser Funktion kann man ueberpruefen, ob das Objekt <wer>, also
+	im Normalfall ein Lebewesen, derzeit als Gegner erkannt wird. Nach
+	einer gewissen Zeit laeuft die Feindschaft automatisch aus, sodass
+	man sich nicht darauf verlassen, dass ein Gegner auch zukuenftig als
+	solchiger erkannt wird. (Diese Zeit betraegt normal 300 Sekunden.)
+	Solch eine Feindschaft kann im uebrigen auch einseitig sein! Mehr
+	dazu findet man in der Dokumentation zu StopHuntFor(), einer
+	Funktion, die Frieden zwischen Gegnern stiften soll.
+
+SIEHE AUCH:
+	SelectEnemy(), QueryEnemies(), StopHuntFor()
+
+----------------------------------------------------------------------------
+Last modified: Wed May 26 16:47:51 1999 by Patryn
diff --git a/doc/lfun/IsEqual b/doc/lfun/IsEqual
new file mode 100644
index 0000000..806661e
--- /dev/null
+++ b/doc/lfun/IsEqual
@@ -0,0 +1,39 @@
+IsEqual()
+
+FUNKTION
+    int IsEqual(object ob)
+
+DEFINIERT IN:
+    /std/unit.c
+
+ARGUMENTE:
+    ob      Das Objekt das geprueft werden soll.
+
+BESCHREIBUNG:                                                               
+    Diese Funktion prueft ob zwei Objekte vom gleichen Typ sind, also ob
+    z.B. ob und this_object() beides Muenzen sind oder beides Edelsteine.
+    Bei einem Ergebnis != 0 fasst unit.c diese zwei Objekte automatisch
+    zusammen, wenn ob->IsEqual(this_object()) auch einen Wert != 0 ergibt.
+    Hierbei wird das IsEqual() von beiden beteiligten Objekten gerufen und sie
+    muessen uebereinstimmen, dass sie eigentlich das gleiche Objekt sind.
+    Selbstverstaendlich ist diese Funktion nur im Falle von Unitobjekten
+    sinnvoll.
+
+RUeCKGABEWERT:
+    0 - this_object() ist nicht vom selben Typ wie ob
+    1 - this_object() ist vom gleichen Typ wie ob
+
+BEISPIELE:
+    o Ein Unitobjekt das verschiedene Beschreibungen haben kann...
+
+       int IsEqual(object ob)
+       {
+          if (!(int)::IsEqual(ob)) return 0;
+          return (QueryProp(P_SHORT)==ob->QueryProp(P_SHORT));
+       }
+
+SIEHE AUCH:
+    /std/unit.c
+------------------------------------------------------------------------------
+25.01.2015, Zesstra
+
diff --git a/doc/lfun/IsTeamLeader b/doc/lfun/IsTeamLeader
new file mode 100644
index 0000000..eaa008f
--- /dev/null
+++ b/doc/lfun/IsTeamLeader
@@ -0,0 +1,48 @@
+
+IsTeamLeader()
+
+
+FUNKTION:
+        object IsTeamLeader()
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        keine
+
+BESCHREIBUNG:
+        Testet, ob der Spieler ein Teamleiter ist.
+
+RUECKGABEWERT:
+        Falls der Spieler Teamleiter ist, wird das Teamobjekt zurueckgegeben,
+        sonst 0.
+
+BEISPIEL:
+        string leader_test(object pl)
+        {
+         ...
+
+         if ( objectp(pl->IsTeamLeader()) )
+          return "Als Leiter eines Teams hast Du grosse Verantwortung zu "
+            "tragen!";
+         else
+          return "Wenn Du mal Leiter eines Teams sein moechtes, solltest "
+            "Du Dir vorher der Verantwortung bewusst werden!";
+        }
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/IsTeamMove b/doc/lfun/IsTeamMove
new file mode 100644
index 0000000..844b041
--- /dev/null
+++ b/doc/lfun/IsTeamMove
@@ -0,0 +1,40 @@
+
+IsTeamMove()
+
+
+FUNKTION:
+        object IsTeamMove()
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        keine
+
+BESCHREIBUNG:
+        Testet, ob momentan die Angriffsbewegung ausgefuehrt wird.
+
+RUECKGABEWERT:
+        Falls die Angriffsbewegung gerade ausgefuehrt wird, wird das
+        Teamobjekt zurueckgegeben, sonst 0.
+
+BEMERKUNGEN:
+        Wird intern benoetigt, damit der Begruessungsschlag verzoegert
+        werden kann, bis alle Teammitglieder ihre Angriffsbewegung
+        ausgefuehrt haben.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/IsUnit b/doc/lfun/IsUnit
new file mode 100644
index 0000000..bce8ab0
--- /dev/null
+++ b/doc/lfun/IsUnit
@@ -0,0 +1,23 @@
+IsUnit()
+
+FUNKTION:
+     int IsUnit();
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Diese Funktion liefert immer 1 zurueck und zeigt damit an, dass es sich
+     bei diesem Objekt um ein Mengenobjekt handelt.
+
+RUeCKGABEWERT:
+     1 bei allen Objekten, die /std/unit.c erben, ansonsten 0.
+
+SIEHE AUCH:
+     /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:20:19 1996 by Wargon
diff --git a/doc/lfun/Kill b/doc/lfun/Kill
new file mode 100644
index 0000000..a8e4540
--- /dev/null
+++ b/doc/lfun/Kill
@@ -0,0 +1,24 @@
+Kill()
+
+FUNKTION:
+	int Kill(object enemy)
+
+ARGUMENTE:
+	enemy: Der boese, boese Feind.
+
+BESCHREIBUNG:
+	Nach Aufruf der Funktion wird der Feind in jedem
+	heart_beat() attackiert.
+
+RUECKGABEWERT:
+	0,  Falls der Feind nicht existiert
+  -1, falls der Feind ein Geist ist
+  -2, falls der Feind P_NO_ATTACK gesetzt hat
+  -3, falls der Angreifer selber P_NO_ATTACK gesetzt hat
+  -4, falls der Feind bereits angegriffen wurde
+	1   falls der Feind erfolgreich als Find registriert wurde.
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+	InsertEnemy
diff --git a/doc/lfun/LearnSkill b/doc/lfun/LearnSkill
new file mode 100644
index 0000000..6373fbb
--- /dev/null
+++ b/doc/lfun/LearnSkill
@@ -0,0 +1,35 @@
+LearnSkill()
+FUNKTION:
+    public varargs void LearnSkill(string sname, int add, int diff)
+
+DEFINIERT IN:
+    /std/living/skills.c
+
+ARGUMENTE:
+    string sname     der zu lernende Skill
+    string add       Anzahl zu lernender Skillpunkte
+    int diff         Schwierigkeit
+
+BESCHREIBUNG:
+    Die Methode laesst einen interaktiven (eingeloggten) Spieler den
+    Skill 'sname' um 'add' Punkte lernen.
+
+    Dabei wird sichergestellt, dass 'add' den Wert MAX_SKILLEARN nicht
+    ueberschreitet, der Skill nicht verschwindet und fuer uebergeordnete
+    Skills (SI_INHERIT) dieser uebergeordnete Skill auch einen Lerneffekt
+    erfaehrt.
+
+    Wird zB von Learn (spellbook) und SpellSuccess (spellbook) gerufen.
+
+SIEHE AUCH:
+    Skills Lernen:  ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung
+    * Properties:   P_NEWSKILLS
+    Spellbook:      Learn, SpellSuccess
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/Leave b/doc/lfun/Leave
new file mode 100644
index 0000000..b3b52d2
--- /dev/null
+++ b/doc/lfun/Leave
@@ -0,0 +1,40 @@
+Leave()
+
+FUNKTION:
+     int Leave();
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Wenn sich der Spieler auf einem Transporter befindet, und dieser sich
+     momentan an einer Haltestelle liegt, verlaesst der Spieler den
+     Transporter.
+
+RUeCKGABEWERT:
+     Null, wenn der Spieler den Transporter nicht verlassen konnte, sonst
+     ungleich Null.
+
+BEMERKUNGEN:
+     Es werden keine Tests durchgefuehrt, ob der Transporter ueberhaupt
+     angesprochen wurde! Das muss man selber machen.
+
+BEISPIELE:
+
+     int myLeave(string str)
+     {
+       if (str && id(str))
+         return Leave();
+
+       notify_fail("Was willst Du verlassen?\n");
+       return 0;
+     }
+
+SIEHE AUCH:
+     Enter(), /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:20:30 1996 by Wargon
diff --git a/doc/lfun/LimitAbility b/doc/lfun/LimitAbility
new file mode 100644
index 0000000..e6a2810
--- /dev/null
+++ b/doc/lfun/LimitAbility
@@ -0,0 +1,47 @@
+LimitAbility()
+FUNKTION:
+    protected varargs mixed LimitAbility(mixed sinfo, int diff)
+
+DEFINIERT IN:
+    /std/living/skills.c
+
+ARGUMENTE:
+    mixed sinfo      Skill-Informationen
+    int diff         Schwierigkeit
+
+BESCHREIBUNG:
+    Setzt ein Maximum an Skillfertigkeit basierend auf der Schwierigkeit
+    und dem P_LEVEL des Spielers.
+    
+    Folgend eine Kopie (!) der Tabelle aus /std/living/skills:
+    diff|lvl 1:|   3:|   7:| 10:| 13:| 16:| 19:| 22:| 25:| 28:| 31:| 34:|
+    ----+------+-----+-----+----+----+----+----+----+----+----+----+----+
+     -50|   83%|  84%|  86%| 87%| 89%| 90%| 92%| 93%| 95%| 96%| 98%| 99%|
+     -10|   69%|  72%|  74%| 77%| 80%| 82%| 85%| 88%| 91%| 93%| 96%| 99%|
+       0|   66%|  69%|  72%| 75%| 78%| 81%| 84%| 87%| 90%| 93%| 96%| 99%|
+      10|   62%|  65%|  69%| 72%| 75%| 79%| 82%| 85%| 89%| 92%| 95%| 98%|
+      20|   59%|  62%|  66%| 70%| 73%| 77%| 80%| 84%| 88%| 91%| 95%| 98%|
+      30|   55%|  59%|  63%| 67%| 71%| 75%| 79%| 83%| 87%| 90%| 94%| 98%|
+      40|   52%|  56%|  60%| 65%| 69%| 73%| 77%| 81%| 86%| 90%| 94%| 98%|
+      50|   49%|  53%|  58%| 62%| 67%| 71%| 76%| 80%| 85%| 89%| 94%| 98%|
+     100|   32%|  38%|  44%| 50%| 56%| 62%| 68%| 74%| 80%| 86%| 92%| 98%|
+     150|   15%|  22%|  30%| 37%| 45%| 52%| 60%| 67%| 75%| 82%| 90%| 97%|
+     200|   -2%|   7%|  16%| 25%| 34%| 43%| 52%| 61%| 70%| 79%| 88%| 97%|
+     250|  -19%|  -8%|   2%| 12%| 23%| 33%| 44%| 54%| 65%| 75%| 86%| 96%|
+     300|  -36%| -24%| -12%|  0%| 12%| 24%| 36%| 48%| 60%| 72%| 84%| 96%|
+     400|  -70%| -55%| -40%|-25%|-10%|  5%| 20%| 35%| 50%| 65%| 80%| 95%|
+     500| -104%| -86%| -68%|-50%|-32%|-14%|  4%| 22%| 40%| 58%| 76%| 94%|
+     600| -138%|-117%| -96%|-75%|-54%|-33%|-12%|  9%| 30%| 51%| 72%| 93%|
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung
+    * Properties:   P_NEWSKILLS
+    Spellbook:      Learn, SpellSuccess
+
+3. Okt 2011 Gloinson
diff --git a/doc/lfun/MaterialGroup b/doc/lfun/MaterialGroup
new file mode 100644
index 0000000..da51cad
--- /dev/null
+++ b/doc/lfun/MaterialGroup
@@ -0,0 +1,37 @@
+MaterialGroup()
+FUNKTION:
+     int MaterialGroup(mapping mats, string grp)
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+ARGUMENTE:
+     mapping mats - Materialienmapping
+     string grp   - Materialiengruppe
+
+BESCHREIBUNG:
+     Die Materialien im Mapping werden auf Zugehoerigkeit zu der Gruppe
+     untersucht und der Gesamtanteil dieser Materialiengruppe am Mapping
+     in Prozent zurueckgegeben (wenn das Mapping sich auf 100% aufaddiert).
+
+RUECKGABEWERT:
+     int - prozentualer Anteil der Materialiengruppe -100 ... 100 %
+
+BEISPIELE:
+     if(MATERIALDB->MaterialGroup(
+		([MAT_MISC_STONE:40,MAT_AMETHYST:50,MAT_MISC_METAL:10]),
+		MATGROUP_JEWEL)>50)
+      write("Oh ja, darin sind sehr viele Edelsteine!\n");
+
+BEMERKUNGEN:
+     Wird von /std/thing/description::QueryMaterialGroup() gerufen.
+     Bitte an Objekten auch QueryMaterialGroup() verwenden.
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Master:	  AddMaterial(), ConvMaterialList()
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/MaterialList b/doc/lfun/MaterialList
new file mode 100644
index 0000000..17ef526
--- /dev/null
+++ b/doc/lfun/MaterialList
@@ -0,0 +1,65 @@
+MaterialList(L)
+FUNKTION:
+     varargs string MaterialList(int casus, mixed idinf)
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     int casus	 - der Fall, in dem die Materialien dekliniert werden sollen
+     mixed idinf - Dinge, welche die Faehigkeiten des Erkennens beeinflussen:
+		   Einzelne Werte:
+                   * x: allgemeine Erkennung -100 ... 100
+                   * who: der Spieler - P_MATERIAL_KNOWLEDGE wird abgefragt
+                   * fun: wird evaluiert
+                   * what, kann folgendes enthalten:
+                     - Eintrag fuer Materialien ([MAT_XXX:-100...100])
+                     - Eintrag fuer Materialiengruppen (dito)
+                     - ([MATERIAL_SYMMETRIC_RECOGNIZABILITY: mixed mg])
+                       * mg ein Array:
+                         ({MATGROUP_X1,int z1, MATGROUP_X2, int z2, ...})
+                         wobei bei Zugehoerigkeit von string mat zu Gruppe
+                         z<n> auf die Faehigkeit addiert, andernfalls davon
+                         subtrahiert wird
+		   Array mit obigen Werten:
+                   - alle Parameter des Arrays sind optional und additiv
+                   - ({int x, object who, mapping what, closure fun})
+
+BESCHREIBUNG:
+     Listet die Materialien auf, aus denen ein Objekt besteht.
+     Dabei haengt die Genauigkeit der Materialerkennung von idinf ab. D.h.
+     je nach den Faehigkeiten/der angegebenen Faehigkeit wird zB Wolfram
+     als "Wolfram" oder nur als "Metall" erkannt.
+
+     Wenn ein Spieler etwas identifiziert, sollte auch TP uebergeben werden,
+     bei NPCs koennte das anders aussehen.
+
+RUECKGABEWERT:
+     String mit Liste der Materialien.
+
+BEMERKUNGEN:
+     - es werden nur die Materialien angegeben, nicht die Menge.
+     - ruft ConvMaterialList() an der MATERIALDB
+
+BEISPIELE:
+     // simpel
+     write("Der Gegenstand besteht aus"+ob->MaterialList(WEM,TP)+".\n")
+     // -> "Der Gegenstand besteht aus Gold, Silber und Rubin.\n"
+
+     // komplexer
+     ob->SetProp(P_MATERIAL, ([P_NITROGLYCERINE:90,P_GUNPOWDER:10]));
+     write("Das enthaelt "+ob->MaterialList(WER,TP)+".\n");
+     // -> "Das enthaelt Schwarzpulver und Nitroglycerin."
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterial(), QueryMaterialGroup()
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/MaterialName b/doc/lfun/MaterialName
new file mode 100644
index 0000000..0e338a3
--- /dev/null
+++ b/doc/lfun/MaterialName
@@ -0,0 +1,72 @@
+MaterialName()
+FUNKTION:
+     varargs string MaterialName(string mat, int casus, mixed idinf)
+
+DEFINIERT IN:
+     /p/daemon/materialdb.c (MATERIALDB)
+
+ARGUMENTE:
+     string mat	 - das zu erkennende Material
+     int casus	 - der Fall
+     mixed idinf - Dinge, welche die Faehigkeiten des Erkennens beeinflussen
+		   (siehe "man MaterialList")
+
+BESCHREIBUNG:
+     Diese Funktion sucht unter Beruecksichtigung der Erkennungsbe-
+     schraenkungen des Materials und Faehigkeiten des Spielers den
+     Klarnamen des Materials heraus und gibt den zurueck.
+
+RUECKGABEWERT:
+     string: Materialname oder genereller Name.
+
+BEISPIELE:
+     // der hier mag alle existierenden Juwelen, auch wenn welche ergaenzt
+     // werden sollten
+     // Parameter: 1. ein Juwel, 2. Casus, 3. 100% Erkennung - ob er sie
+     // beim Empfang dann auch zu 100% erkennt, steht hier nicht!
+     string* likeit;
+     likeit=MATERIALDB->GetGroupMembers(MATGROUP_JEWEL);
+     ...
+     write("Der Alte sagt: Ich mag "+
+	   MATERIALDB->MaterialName(likeit[random(sizeof(likeit))], WEN, 100)+
+	   ".\n");
+     ...
+
+     // ein weiser schmied:
+     int i;
+     string *mat, mname, mgroup;
+     mat=m_indices(ob->queryprop(p_material));
+     i=sizeof(mat);
+
+     write("der schmied sagt: "+ob->name(wer)+" besteht aus ...\n");
+     while(i--) {
+      // den namen erkennen/aussprechen:
+      // materialien werden allgemein ganz schlecht erkannt (zu 5%), aber
+      // alles aus metall wird zu +100% gut erkannt ...
+      mname=materialdb->materialname(mat[i], wer,
+	     ({5, ([material_symmetric_recognizability:
+			({matgroup_metal, 100})])}));
+
+      // und nur metalle analysieren ...
+      if(materialdb->materialgroup(([mat[i]:100]),matgroup_metal)>=100) {
+       int j;
+       string *mgr;
+       mgr=materialdb->getmatmembership(mat[i]);
+       j=sizeof(mgr);
+       mgroup=" gehoert zu ";
+       while(j--) {
+        mgroup+=materialdb->groupname(mgr[j]);
+        if(j>0) mgroup+=", ";
+       }
+      } else mgroup=" kenne ich nicht";
+      printf("%-12.12s: %s\n",mname, mgroup);
+     }
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName()
+		  GetGroupMembers(), GetMatMembership()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/MayAddObject b/doc/lfun/MayAddObject
new file mode 100644
index 0000000..d502da4
--- /dev/null
+++ b/doc/lfun/MayAddObject
@@ -0,0 +1,33 @@
+MayAddObject()
+
+FUNKTION:
+     int MayAddObject(object ob);
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     ob - Das Object bei dem geprueft werden soll, ob es noch in den
+          Container passt.
+
+BESCHREIBUNG:
+     Wenn ein Objekt in einen Container bewegt wird, prueft move() ueber
+     diese Funktion, ob das Objekt ueberhaupt noch in den Behaelter hinein
+     passt. Dazu uebergibt move() das Objekt das in den Container bewegt
+     werden soll. (In Raeumen ist diese Funktionen ueberschrieben und
+     liefert immer True zurueck.)
+
+RUeCKGABEWERT:
+     1 - wenn das Objekt noch vom Container aufgenommen werden kann.
+     0 sonst.
+
+BEMERKUNGEN:
+     invis-Objekte passen immer in den Container hinein!
+     move() ruft diese Funktion nicht auf, wenn in den Flags M_NOCHECK
+     gesetzt war!
+
+SIEHE AUCH:
+     MayAddWeight(), PreventInsert(), move(), /std/container/restrictions.c
+
+----------------------------------------------------------------------------
+Last modified: 23.09.2007, Zesstra
diff --git a/doc/lfun/MayAddWeight b/doc/lfun/MayAddWeight
new file mode 100644
index 0000000..1cc4e47
--- /dev/null
+++ b/doc/lfun/MayAddWeight
@@ -0,0 +1,47 @@
+MayAddWeight()
+
+FUNKTION:
+     int MayAddWeight(int gewicht);
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     gewicht
+          Das zu pruefende Gewicht.
+
+BESCHREIBUNG:
+     Wenn ein Objekt ein einen Behaelter bewegt wird, prueft move() ueber
+     diese Funktion, ob das Objekt ueberhaupt noch in den Behaelter hinein
+     passt. Dazu uebergibt move() dieser Funktion das Gewicht des zu
+     bewegenden Objektes.
+
+RUeCKGABEWERT:
+     0, wenn der Behaelter noch ein gewicht Gramm wiegendes Objekt aufnehmen
+     kann, -1 im anderen Fall.
+
+BEMERKUNGEN:
+     move() ruft diese Funktion nicht auf, wenn in den Flags M_NOCHECK
+     gesetzt war!
+
+BEISPIELE:
+     Die entsprechende Abfrage in /std/thing/moving.c sieht etwa
+     folgendermassen aus:
+
+     int weight;
+
+     ...
+     weight = QueryProp(P_TOTAL_WEIGHT);   // Behaelter? Ja => Gesamtgewicht
+     if (!weight)
+       weight = QueryProp(P_WEIGHT);       // Nein: einfaches Gewicht
+
+     if (ziel->MayAddWeight(weight) == -1) // Passt es noch rein?
+       return ME_TOO_HEAVY;                // Nein, entspr. Fehler zurueckgeben
+
+     ...
+
+SIEHE AUCH:
+     MayAddObject(), PreventInsert(), move(), /std/container/restrictions.c
+
+----------------------------------------------------------------------------
+Last modified: 23.09.2007, Zesstra
diff --git a/doc/lfun/Message b/doc/lfun/Message
new file mode 100644
index 0000000..3635f6e
--- /dev/null
+++ b/doc/lfun/Message
@@ -0,0 +1,23 @@
+Message()
+
+FUNKTION:
+        varargs int Message(string str, int flag)
+
+ARGUMENTE:
+        str: Den zu uebermittelnden Text.
+	flag: Beschreibt die Art der Meldung naeher, siehe
+	      /sys/player/comm.h
+
+BESCHREIBUNG:
+        Einem Spieler wird der Text str uebermittelt.
+
+RUECKGABEWERT:
+        1 bei erfolgreicher Uebermittlung
+        0 wenn der Kobold aktiv war
+       <0 wenn Spieler oder verwendetes Verb ignoriert
+          werden
+
+SIEHE AUCH:
+     P_IGNORE, TestIgnore()
+
+12. Mai 2004 Gloinson
diff --git a/doc/lfun/ModifyQuestTime b/doc/lfun/ModifyQuestTime
new file mode 100644
index 0000000..0020bad
--- /dev/null
+++ b/doc/lfun/ModifyQuestTime
@@ -0,0 +1,44 @@
+ModifyQuestTime()
+
+FUNKTION:
+        int ModifyQuestTime(string questname, int zeit)
+
+DEFINIERT IN:
+        /std/player/quests.c
+
+ARGUMENTE:
+        questname
+          Questname, wie er im Questmaster eingetragen wurde.
+        zeit
+          Zeitpunkt, zu dem die Quest geloest wurde
+
+RUeCKGABEWERT:
+         1 : Questzeitpunkt erfolgreich nachgetragen
+        -1 : keine Zugriffsrechte (nur EM+ und der Tagebuchmaster erlaubt)
+        -2 : Questliste im Spielerobjekt ist unerwartet kein Mapping
+        -3 : Spieler hat diese Quest noch nicht bestanden
+        -4 : kein gueltiger Zeitpunkt uebergeben (kein Integer, Wert < -1
+             oder Wert > time()).
+
+BESCHREIBUNG:
+        Mit dieser Funktion kann der Zeitpunkt nachgetragen werden, zu
+        dem ein Spieler eine bestimmte Quest bereits geloest hat. 
+        Als Questname wird dazu der Name angegeben, der im Questmaster 
+        eingetragen ist. Der Zeitpunkt ist als Integer-Wert im ueblichen
+        time()-Format anzugeben. Uebergibt man -1 als <zeit>, dann wird
+        der Tagebuchmaster erneut versuchen, das Logfile einzulesen, 
+        wenn der Spieler das naechste mal sein Abenteuertagebuch liest.
+
+HINWEIS:
+        Die Funktion mktime() ist nuetzlich, wenn der Zeitpunkt des 
+        Bestehens einer Quest manuell rekonstruiert werden muss, der
+        Zeitpunkt aber nur als Datums-/Zeitangabe in Textform vorliegt 
+        (etwa aus einem Logfile oder aus der Quest-Feedbackmail).
+
+SIEHE AUCH:
+        /secure/questmaster.h, /obj/tools/questtool
+        GiveQuest(L)
+        mktime(E), dtime(SE)
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: Mon, 27. Jan. 2015, Arathorn
diff --git a/doc/lfun/ModifySkill b/doc/lfun/ModifySkill
new file mode 100644
index 0000000..8dd622f
--- /dev/null
+++ b/doc/lfun/ModifySkill
@@ -0,0 +1,73 @@
+ModifySkill()
+FUNKTION:
+    public varargs void ModifySkill(string sname, mixed val,
+                                    int diff, string gilde)
+
+DEFINIERT IN:
+    /std/living/skills.c
+
+ARGUMENTE:
+    string sname     der zu aendernde Skill
+    mixed val        Aenderungswert: int fuer SI_SKILLABILITY, sonst mapping
+    int diff         Schwierigkeit (optional: default ist existierendes diff)
+    string gilde     Gilde (optional: default ist eigene Gilde)
+
+BESCHREIBUNG:
+    Mit der Methode kann man die Werte eines Skills/Spells veraendern. Dabei
+    wird ein Skill immer in ein Mapping umgewandelt (Skills/Spells koennen
+    auch einfach nur ihren Skillwert enthalten, diese ist aequivalent zu
+    einem Mapping mit ([SI_SKILLABILITY:<Skillwert>]).
+
+    Ist 'val' ein int, wird dieses als SI_SKILLABILITY gesetzt. Falls der
+    Skill nur ein int war, wird ein 'diff'!=0 als SI_DIFFICULTY gesetzt.
+
+    Ist 'val' ein Mapping, wird dieses zum Skillmapping addiert.
+    
+    Etwaige SI_SKILLABILITY-Aenderungen laufen danach noch durch LimitAbility.
+
+BEISPIELE:
+    // #1a: Lerne einen Spell/Skill (einer Gilde)
+    caster->ModifySkill("feuerball", MAX_ABILITY, 100, "abenteurer")
+    // #1b: ... oder ...
+    caster->ModifySkill("feuerball", ([SI_SKILLABILITY: MAX_ABILITY]), 100,
+                        "abenteurer")
+    // #1c: ... oder fuer einen Abenteurer ...
+    caster->ModifySkill("feuerball", ([SI_SKILLABILITY: MAX_ABILITY]), 100);
+    
+    // #2: Setze eine Skill-Funktion fuer einen Kampfskill des Klerus
+    this_player()->ModifySkill(FIGHT(WT_CLUB),
+                               ([SI_SKILLFUNC: "Keulenkampf",
+                                 SI_DIFFICULTY: 100]),
+                               100, "klerus");
+
+    // #3: Speichere im Skill (also Spieler) eine Option fuer diesen Skill
+    // Vorteil: dieser Eintrag wird dem Spell immer uebergeben
+    caster->ModifySkill("blitz", (["klerus_spell_option": 2]));
+
+    (Code in /doc/beispiele/testobjekte/modifyskillspell_test)
+    // #4: Lerne einen unabhaengigen Spell: ACHTUNG
+    // dieser Spell funktioniert nur solange, wie die Closure existiert,
+    // SI_SKILLABILITY und Spell bleiben jedoch im Spieler gespeichert (!)
+    this_player()->ModifySkill("fnrx",
+      ([SI_CLOSURE:
+          function int (object caster, string skill, mapping sinf) {
+            caster->LearnSkill("fnrx", 1);
+            tell_object(caster, "Peng! Dein Skillwert steigt auf "+
+                                caster->QuerySkillAbility("fnrx")+".\n");
+            return ERFOLG;
+          },
+        SI_SKILLABILITY: 8432]),
+      100,
+      "ANY");
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung
+    * Properties:   P_NEWSKILLS
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/ModifySkillAttribute b/doc/lfun/ModifySkillAttribute
new file mode 100644
index 0000000..e5b3669
--- /dev/null
+++ b/doc/lfun/ModifySkillAttribute
@@ -0,0 +1,105 @@
+ModifySkillAttribute()
+FUNKTION:
+    public int ModifySkillAttribute(string atrname, mixed value, 
+                                    int duration)
+
+DEFINIERT IN:
+    /std/living/skill_attributes.c
+
+ARGUMENTE:
+    <atrname>   string
+                Name des zu veraendernden Attributes
+                (Definiert in /sys/living/skill_attributes.h)
+
+    <value>     int oder closure
+                Wert des Modifikators
+                oder
+                eine Closure, welche bei Abfrage des betreffenden SAs
+                abgefragt um den Modifikator zu bestimmen.
+
+    <duration>  int
+                Dauer in Sekunden
+
+BESCHREIBUNG:
+    Aendert temporaer, d.h. fuer eine bestimmte Zeit, ein Skill-Attribut
+    eines Lebewesen, indem ein Modifikator hinzugefuegt wird.
+    
+    Der Standardwert eines SA wird von P_SKILL_ATTRIBUTE_OFFSETS festgelegt
+    oder ist 100, wenn besagte Property leer ist.
+    Alle Modifikatoren (negativ wie positiv) werden addiert und bilden
+    zusammen mit dem Standardwert eine Gesamtsumme.
+    Bei allen SAs ausser SA_QUALITY wird diese Gesamtsumme noch mit
+    SA_QUALITY (welches sich damit auf alle anderen Skill-Attribute
+    auswirkt) multipliziert und das Ergebnis stellt den Endwert des SA dar.
+    (Beispiel s.u.)
+
+    Der Wert eines Modifikators muss zwischen -1000 und 1000 liegen. Der
+    Gesamtwert eines SA kann 10 nicht unter- und 1000 nicht ueberschreiten.
+
+    Falle <value> eine Closure ist, wird diese Closure jedesmal
+    ausgefuehrt, wenn das entsprechende SA abgefragt wird. Der
+    Rueckgabewert dieser Closure stellt dann den Wert des Modifikators
+    dar. Auch dieser muss zwischen -1000 und 1000 liegen. Gibt die
+    Closure keinen int zurueck, wird der Modifikator geloescht.
+
+    Gueltige Skill-Attribute sind momentan:
+    * SA_QUALITY:    Allgemeine Qualitaet: wirkt sich auf alle anderen
+                     Attribute auch aus (multplikativ auf Basis 100)
+    * SA_DAMAGE:     Schaden, den das Lebewesen macht
+    * SA_SPEED:      Geschwindigkeit des Lebewesens (zB Angriffe/Runde)
+    * SA_DURATION:   Spell-/Skilldauer
+    * SA_ENEMY_SAVE: identisch zu SA_SPELL_PENETRATION (OBSOLET!)
+    * SA_SPELL_PENETRATION: Chance des _Casters_, einen Spell durch ein
+                            P_NOMAGIC durchzukriegen.
+    * SA_RANGE:      Reichweite des Lebewesens (eher unbenutzt)
+    * SA_EXTENSION:  "Ausdehnung" bei Gruppen-/Flaechenspells: FindGroupN/P
+
+RUECKGABEWERT:
+    SA_MOD_OK              wenn der Modifikator gesetzt wurde
+    SA_TOO_MANY_MODS       wenn die max. Anzahl an Mods schon erreicht ist.
+    SA_MOD_TOO_SMALL       wenn der Modifikator zu klein ist 
+    SA_MOD_TOO_BIG         wenn der Modifikator zu gross ist
+    SA_MOD_INVALID_ATTR    wenn das gewuenschte SA gar nicht existiert
+    SA_MOD_INVALID_OBJECT  wenn das setzende Objekt ungueltig ist
+    SA_MOD_INVALID_VALUE   wenn der Modifikator ungueltig ist
+    Wenn man nur wissen will, ob die Operation erfolgreich war, empfiehlt
+    es sich, auf == SA_MOD_OK zu pruefen.
+
+BEMERKUNGEN:
+    Nachdem ein Objekt, welches Modifikatoren setzte, zerstoert wurde,
+    werden die Modifikatoren spaetestens ungueltig, sobald in dem
+    manipulierten Lebewesen erneut ModifySkillAttribute() gerufen wird!
+    Bei Closures ist der Mod sofort weg.
+
+BEISPIELE:
+    // sei PL ein Spieler, den mein NPC schwaechen will:
+    PL->ModifySkillAttribute(SA_QUALITY, -75, 13);
+    // Fuer 13s wird SA_QUALITY um 75 reduziert. Dies wirkt sich auf alle
+    // anderen SAs aus! (s. drittes Beispiel)
+
+    // sei PL ein Lebewesen, welchem ich fuer 11s 2 Schlaege pro Kampfrunde
+    // zusaetzlich geben moechte:
+    PL->ModifySkillAttribute(SA_SPEED, 200, 11);
+    // wenn keine weiteres Modifikatoren wirken, hat PL jetzt 3 Schlaege
+    // pro Kampfrunde (Basiswert 100 + 200 == 300 => 3).
+
+    Angenommen, ein Lebewesen hat einen Basiswert von 130 auf SA_SPEED und
+    100 auf SA_QUALITY (P_SKILL_ATTRIBUTE_OFFSETS) und nun 3 Modifikatoren
+    gesetzt: SA_SPEED +100, SA_SPEED -30 und SA_QUALITY von -10:
+    Zunaechst wird SA_QUALITY bestimmt: 100 - 10 = 90  => 0.9
+    Anschliessend wird SA_SPEED bestimmt: 130 + 100 - 30 = 200 => 2
+    Nun wird SA_SPEED noch mit SA_QUALITY multipliziert: 2 * 0.9 = 1.8
+    Das Lebewesen hat nun also im Endeffekt 1.8 Schlaege pro Kampfrunde.
+
+    
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill
+    * Modifikation: QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+
+5. Okt 2011 Gloinson
diff --git a/doc/lfun/More b/doc/lfun/More
new file mode 100644
index 0000000..2e73fa2
--- /dev/null
+++ b/doc/lfun/More
@@ -0,0 +1,56 @@
+More()
+
+FUNKTION:
+     varargs public void More(string txt, int file,
+                              mixed ctrl, mixed *ctrlargs, int flags);
+
+DEFINIERT IN:
+     /std/util/pager.c
+
+ARGUMENTE:
+     txt  - entweder ein Text der ausgegeben werden soll, oder ein filename.
+     file - das flag file gibt an, ob es sich bei <txt> um einen text oder
+            einen Filenamen handelt. Bei einem Filenamen wird der Inhalt
+            dieses Files eingelesen und ausgegeben.
+     ctrl - Eine closure, die aufgerufen wird, falls kein <txt> angegeben
+            wurde.
+     ctrlargs - ctrlargs wird als Parameter an ctrl uebergeben.
+     flags - flags wird mit den im Spieler definierten P_MORE_FLAGS
+             kombiniert.
+
+BESCHREIBUNG:
+
+     More() dient der Ausgabe von Texten an Spieler. Mit Hilfe eines
+     PL->More(txt) oder PL->More(txt, 1) ist es sehr einfach laengere Texte
+     an Spieler auszugeben. Bei der Ausgabe werden die persoenlichen
+     Einstellungen des Spielern (wie z.b. Zeilen pro Bildschirmseite)
+     automatisch beruecksichtigt und der Text dadurch ggf. zerstueckelt
+     und in mehreren Schritten nacheinander angezeigt.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Beim einlesen des Files sind die Leserechte des Spieler in dem More()
+     aufgerufen wird von Bedeutung und nicht die Rechte des Objektes das
+     More() aufruft. Spielerobjekte haben im MorgenGrauen jedoch nur sehr
+     eingeschraenkte Leserechte! Ausgegeben werden koennen nur files
+     aus /p/*, /gilden/* und /d/* die _keinen_ code enthalten. Als Code
+     wird hierbei jedes File betrachtet das als vorletztes Zeichen einen .
+     hat (also .c, .h, .o usw.).
+     Will man aus irgendwelchen Gruenden ein File (z.b. aus /players/)
+     ausgeben, so sollte man stattdessen folgendes verwenden:
+     this_player()->More(read_file(filename))
+
+BEISPIELE:
+
+     // Ausgabe eines normalen textes...
+     this_player()->More("Einfach nur mal so ein Test...\n");
+
+     // Ausgabe eines kompletten files
+     this_player()->More("/etc/WIZRULES", 1);
+
+SIEHE AUCH:
+
+----------------------------------------------------------------------------
+Last modified: Mon Feb 22 15:09:18 1999 by Padreic
diff --git a/doc/lfun/NPC_Killed_by b/doc/lfun/NPC_Killed_by
new file mode 100644
index 0000000..37392ba
--- /dev/null
+++ b/doc/lfun/NPC_Killed_by
@@ -0,0 +1,13 @@
+FUNKTION:
+	void NPC_Killed_By(object pl)
+	
+ARGUMENTE:
+	Spieler, der einen NPC gekillt hat.
+	
+BESCHREIBUNG:
+	Wird in der Gilde des Spielers aufgerufen,
+	wenn dieser einen NPC gekillt hat.
+	
+RUECKGABEWERT:
+	Keiner
+	
diff --git a/doc/lfun/Name b/doc/lfun/Name
new file mode 100644
index 0000000..774ac68
--- /dev/null
+++ b/doc/lfun/Name
@@ -0,0 +1,28 @@
+Name()
+
+FUNKTION:
+     varargs string Name(int casus, int demon);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     casus
+          Der Fall, in dem der Name dekliniert werden soll.
+     demon
+          Gibt an, ob der Name mit bestimmtem oder unbestimmtem Artikel
+          versehen werden soll:
+             + demon = 0: Unbestimmter Artikel.
+             + demon = 1: Bestimmter Artikel.
+             + demon = 2: Finde selbst heraus, ob ein bestimmter oder ein
+               unbestimmter Artikel verwendet werden soll.
+
+BESCHREIBUNG:
+     Dieser Funktionsaufruf ist ein Alias fuer 
+     capitalize( name( casus, demon ) )
+
+SIEHE AUCH:
+     name(), /std/thing/description.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Aug  3 11:24:06 2002 by Vanion
diff --git a/doc/lfun/NewDoor b/doc/lfun/NewDoor
new file mode 100644
index 0000000..09f5796
--- /dev/null
+++ b/doc/lfun/NewDoor
@@ -0,0 +1,223 @@
+FUNKTION:
+     varargs int NewDoor(string|string* cmds, string dest, string|string* ids,
+                         mapping|<int|string|string*>* props);
+DEFINIERT IN:
+     /std/room/doors.c
+
+ARGUMENTE:
+     cmds (string|string*)
+          String oder Array von Strings mit den Befehlen, mit denen man
+          durch die Tuer geht (in der Regel Richtungen wie "norden").
+     dest (string)
+          Pfad des Zielraumes, OHNE ".c", sonst wird eine zweiseitige Tuer
+          (wie sie ueblich ist) nicht als solche erkannt.
+     ids (string|string*)
+          String oder Array von Strings mit den Bezeichnern der Tuer. Kann
+          auch 0 sein; in diesem Fall laesst sich die Tuer nur als "tuer"
+          ansprechen.
+     props (mapping|<int|string|string*>*)
+          Die Eigenschaften der Tuer (s.u.).
+
+BESCHREIBUNG:
+     Es wird eine neue Tuer geschaffen. Die Tuer laesst sich, wenn sie
+     geoeffnet ist, mit den in <cmds> angegebenen Befehlen durchschreiten.
+     Man gelangt dann in den Raum <dest>.
+
+     Die Kommandos werden bei geoeffneter Tuer in die Liste der sichtbaren
+     Ausgaenge eingefuegt.
+
+     In <props> lassen sich Aussehen und Eigenschaften der Tuer festlegen.
+     Historisch ist es ein Array mit Paaren von Schluesseln und Werten, d.h.
+     es kommt immer erst ein Element, welches die Eigenschaft bezeichnet und
+     dann ein Element mit dem Wert dieser Eigenschaft.
+     Moderner ist es, ein Mapping mit den entsprechenden Schluesseln und
+     Werten zu uebergeben. Dies ist auch dringend empfohlen.
+
+     In <doorroom.h> sind dazu folgende Eigenschaften definiert:
+     D_FLAGS
+          DOOR_OPEN
+               Die Tuer ist beim Erzeugen geoeffnet.
+          DOOR_CLOSED
+               Die Tuer ist beim Erzeugen geschlossen.
+          DOOR_NEEDKEY
+               Man benoetigt einen Schluessel zum Oeffnen der Tuer.
+          DOOR_CLOSEKEY
+               Man benoetigt einen Schluessel zum Schliessen der Tuer.
+          DOOR_RESET_CL
+               Die Tuer schliesst sich beim Reset.
+          DOOR_RESET_OP
+               Die Tuer oeffnet sich beim Reset.
+
+     D_LONG
+          Die Langbeschreibung der Tuer. 
+          Hier kann ein Mapping eingetragen werden, das als Keys den Tuer-
+          Status hat und die zugehoerige Langbeschreibung dazu. Beispiel:
+          ([ D_STATUS_CLOSED : "Die Tuer ist geschlossen.\n",
+             D_STATUS_OPEN   : "Die Tuer ist offen.\n" ])
+          
+          Default: "Eine Tuer.\n"
+
+     D_SHORT
+          Die Kurzbeschreibung der Tuer. Ein "%s" wird durch "geoeffnet"
+          bzw. "geschlossen" ersetzt.
+
+          Es werden die Kurzbeschreibungen aller im Raum vorhandenen Tueren
+          aneinandergehaengt (es wird jeweils ein Leerzeichen eingeschoben),
+          das Ganze mit break_string() umgebrochen und an P_INT_LONG
+          angehaengt.
+
+          Default: "Eine %se Tuer."
+
+     D_NAME
+          Der Name der Tuer. Dieser Name wird beim Oeffnen und Schliessen
+          der Tuer sowie bei Fehlermeldungen ausgegeben. Man kann wie bei
+          P_NAME einen String oder ein Array von Strings angeben.
+
+          Default: "Tuer"
+
+     D_GENDER
+          Das Geschlecht der Tuer.
+
+          Default: FEMALE
+
+     D_MSGS
+          String oder Array von drei Strings. Diese Strings werden beim
+          Durchschreiten der Tuer an move() als dir bzw. dir, textout und
+          textin uebergeben.
+
+     D_FUNC
+          String mit dem Namen einer Funktion, die im Startraum vor dem
+          Durchschreiten der Tuer aufgerufen werden soll. Diese Funktion
+          kann das Durchschreiten jedoch nicht verhindern!
+
+     D_FUNC2
+          String mit dem Namen einer Funktion, die im Zielraum nach dem
+          Durchschreiten der Tuer aufgerufen werden soll.
+
+     D_TESTFUNC
+          Falls auf den Namen einer Funktion gesetzt, wird diese Funktion
+          vor dem Durchschreiten im Startraum aufgerufen. Wenn sie einen
+          Wert != 0 zurueckliefert, wird die Tuer NICHT durchschritten. 
+
+     D_RESET_MSG
+          Meldung, die beim Reset der Tuer ausgegeben wird.
+
+     D_OPEN_WITH_MOVE
+          Tuer oeffnet automatisch bei Eingabe des Befehls zum 
+          Hindurchgehen.
+          
+RUECKGABEWERT:
+     1, wenn die Tuer ordungsgemaess eingebaut werden konnte, sonst 0.
+
+BEMERKUNGEN:
+     Zwei Tuerseiten gelten als verschiedene Seiten einer Tuer, wenn als
+     Ziel in Raum A Raum B und in Raum B Raum A angegeben ist. Der Zustand
+     wird abgefragt, wenn der Raum betreten wird (init), wenn die Tuer
+     geoeffnet/geschlossen wird, P_INT_LONG oder P_EXITS abgefragt wird
+     und beim Reset.
+
+     Es sind auch Tueren moeglich, die nur auf einer Seite existieren, oder
+     auch solche, die auf beiden Seiten verschieden aussehen oder gar auf
+     einer Seite nur mit einem Schluessel zu oeffnen sind, auf der anderen
+     jedoch kein Schluessel noetig ist.
+
+     Wer aus irgendeinem Grund den Zustand einer Tuer selber abfragen oder
+     veraendern will, kann dafuer in /obj/doormaster die Funktionen
+     QueryDoorStatus(ziel) bzw. SetDoorStatus(ziel,status) aufrufen.
+
+     *** ACHTUNG ***
+     Es gibt eine Questbelohnung (Phiole aus der Sternenlicht-Quest von
+     Miril), mit der man durch Tueren hindurchschauen kann. Derzeit ist das
+     per default fuer alle Tueren erlaubt. Wenn man das nicht moechte,
+     oder andere Texte ausgeben, als die Phiole normalerweise erzeugt,
+     dann kann man dies durch Nutzung bestimmter Funktionen bzw. Flags
+     erreichen. Zur Dokumentation siehe Manpage zu GetPhiolenInfos().
+
+BEISPIELE:
+
+  ** Dies ist eine gewoehnliche Tuer ohne Besonderheiten und ohne
+     Extra-Beschreibung:
+
+     NewDoor("sueden","/players/rochus/room/test1");
+
+  ** Ein Portal:
+
+     NewDoor("norden","/players/rochus/room/test2",
+             "portal",
+             ([ D_NAME:   "Portal",
+                D_GENDER: NEUTER,
+                D_SHORT:  "Im Norden siehst Du ein %ses Portal.",
+                D_LONG:   "Das Portal ist einfach nur gigantisch.\n",
+              ]) );
+
+     Alternativ mit props in alter Arraynotation:
+     NewDoor("norden","/players/rochus/room/test2",
+             "portal",
+             ({ D_NAME,   "Portal",
+                D_GENDER, NEUTER,
+                D_SHORT,  "Im Norden siehst Du ein %ses Portal.",
+                D_LONG,   "Das Portal ist einfach nur gigantisch.\n"
+              }) );
+     
+  ** Tueren mit Bewegungsmeldung:
+
+     NewDoor("norden","/room/see2",
+             ({ D_MSGS,  ({"nach Norden","schwimmt",
+                           "kommt hereingeschwommen"}) }) );
+
+  ** Eine Tuer mit Testfunktion:
+
+     NewDoor("osten","/mein/zielraum",
+             ({ D_TESTFUNC, "blocker_da" }) );
+
+     Die Funktion blocker_da:
+
+     int blocker_da()      // KEINE protected-Funktion! Sie wird sonst NICHT
+     {                     // aufgerufen und ausgewertet!
+       if ( present("mein_fieses_mo\nster",this_object()) )
+        {
+         write("Ein fieses Monster stellt sich Dir in den Weg.\n");
+         return 1;
+        }
+       return 0;           // optional
+     }
+
+  ** Nun noch eine Tuer mit einigen Extras:
+
+     NewDoor("nordwesten","/rooms/kammer",
+             ({"tuer","holztuer"}),
+             ({
+               D_FLAGS,  (DOOR_CLOSED|DOOR_RESET_CL),
+               D_MSGS,   ({"nach Nordwesten","geht",
+                         "kommt durch eine Tuer herein"}),
+               D_SHORT,  "Im Nordwesten siehst Du eine %se Holztuer.",
+               D_LONG,   "Sie trennt den Laden vom dahinterliegenden Raum.\n",
+               D_NAME,   "Holztuer",
+               D_FUNC,   "view",
+               D_FUNC2,  "look_up"
+             }) );
+
+     Im Startraum:
+
+     void view()
+     {
+       write("Der Angestellte wirft Dir einen missbilligenden Blick zu, "
+             "laesst Dich aber passieren.\n");
+     }
+
+     Im Zielraum:
+
+     void look_up()
+     {
+       write("Ein alter Mann schaut kurz zu Dir auf und vertieft sich dann "
+             "wieder in seine Akten.\n");
+     }
+
+
+SIEHE AUCH:
+    QueryDoorKey(), QueryDoorStatus(), SetDoorStatus(),
+    /std/room/doors.c, /obj/doormaster.c, GetPhiolenInfos(), QueryAllDoors()
+
+-----------------------------------------------------------------------------
+08.02.2015, Arathorn
+
diff --git a/doc/lfun/NoParaObjects b/doc/lfun/NoParaObjects
new file mode 100644
index 0000000..804e7b7
--- /dev/null
+++ b/doc/lfun/NoParaObjects
@@ -0,0 +1,28 @@
+********************** VERALTETE LFUN ****************************
+NoParaObjects()
+
+FUNKTION:
+	int NoParaObjects()
+
+DEFINIERT IN:
+	/std/virtual/v_compiler.c
+
+RUeCKGABEWERT:
+    1, wenn der VC keine Parawelt-Objekte erzeugt,
+    0, wenn er es doch tut.
+
+BESCHREIBUNG:
+    Diese Funktion ist veraltet. QueryValidObject() ist genereller und
+    einfacher zu handhaben. Bitte in Zukunft P_PARA im VC setzen, siehe hierzu
+    die Manpage von QueryValidObject().
+
+    Die Funktion gibt an, ob ein Virtual Compiler auch Parawelt-Objekte
+    erzeugen kann.
+    Wichtig: Entweder dieser Funktion im VC definieren, wenn der VC keine
+    Para-Objekte erzeugen wird oder P_PARA passend setzen!
+
+SIEHE AUCH:
+	virtual_compiler, P_PARA, QueryValidObject
+
+----------------------------------------------------------------------------
+04.03.2007, Zesstra
diff --git a/doc/lfun/NotifyDestruct b/doc/lfun/NotifyDestruct
new file mode 100644
index 0000000..48e71ee
--- /dev/null
+++ b/doc/lfun/NotifyDestruct
@@ -0,0 +1,47 @@
+NotifyDestruct()
+
+FUNKTION:
+     public int|string NotifyRemove(object zerstoerer);
+
+ARGUMENTE:
+     zerstoerer
+          Das Objekt, welches destruct() auf dieses Objekt anwendet.
+
+BESCHREIBUNG:
+     Diese Funktion wird vom Master der Mudlib in jedem Objekt gerufen,
+     welches zerstoert wird, um Objekten eine letzte Chance zu geben, sich
+     aufzuraeumen.
+     Wenn ihr diese Funktion selber definiert, achtet bittet darauf, dass sie
+     in keinem Fall Fehler ausloesen sollte, d.h. testet entsprechend
+     gruendlich.
+     Wenn ihr aus /std/ erbt und diese Funktion ueberschreibt,, _muesst_ ihr
+     die geerbte NotifyDestruct() aufrufen, da sonst das Lichtsystem nicht
+     aktualisiert wird.
+
+     Privilegierte Objekte (z.B. Root-Objekte, spezielle Ausnahmen wie der
+     Netztotenraum, Armageddon) koennen die Zerstoerung in letzter Sekunde
+     verhindern, indem sie hier einen Wert != 0 zurueckliefern. Wird ein
+     string zurueckgeliefert, wird dieser die Fehlermeldung des
+     prepare_destruct() im Master sein.
+     Bei nicht-privilegierten Objekten (also fast alle) ist an dieser Stelle
+     _kein_ Abbruch der Zerstoerung moeglich!
+
+RUeCKGABEWERT:
+     Der Rueckgabewert muss ein string oder ein int sein. Allerdings wird der
+     Master den Rueckgabewert nur fuer privilegierte Objekte auswerten.
+
+BEMERKUNGEN:
+     Wie gesagt, bitte keine Fehler ausloesen (auch wenn der Master
+     grundsaetzlich damit klar kommt). Speziell ist ein raise_error() zur
+     Verhinderung eines destructs nutzlos.
+     Bitte macht in dieser Funkion nur das, was _unbedingt_ notwendig ist.
+     Wenn jemand ein destruct() anwendet statt ein remove() zu rufen, hat das
+     in der Regel einen Grund (z.B. um buggende remove() zu umgehen). Insb.
+     ist ein save_object() in remove() und NotifyDestruct() vollstaendig
+     ueberfluessig.
+
+SIEHE AUCH:
+    NotifyLeave(), NotifyInsert(), NotifyRemove()
+
+----------------------------------------------------------------------------
+Last modified: 25.02.2009, Zesstra
diff --git a/doc/lfun/NotifyInsert b/doc/lfun/NotifyInsert
new file mode 100644
index 0000000..aa2c6ec
--- /dev/null
+++ b/doc/lfun/NotifyInsert
@@ -0,0 +1,28 @@
+NotifyInsert()
+
+FUNKTION:
+     void NotifyInsert(object ob, object oldenv);
+
+ARGUMENTE:
+     ob
+          Das Objekt, das in den Behaelter eingefuegt wurde.
+     oldenv
+          Das Objekt, aus dem <ob> kam.
+
+BESCHREIBUNG:
+     Diese Funktion wird im Behaelter aufgerufen, nachdem ein Objekt in
+     besagten Behaelter hinein bewegt wurde. 
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Diese Funktion wird nur im Falle unbelebter Objekte gerufen. Fuer 
+     Lebewesen s. bitte. init().
+
+SIEHE AUCH:
+    NotifyLeave(), PreventInsert(), PreventLeave(), move(), NotifyRemove()
+    exit(), init(), NotifyMove(), PreventMove()
+
+----------------------------------------------------------------------------
+Last modified: 21.05.2012, Zesstra
diff --git a/doc/lfun/NotifyLeave b/doc/lfun/NotifyLeave
new file mode 100644
index 0000000..621fca8
--- /dev/null
+++ b/doc/lfun/NotifyLeave
@@ -0,0 +1,28 @@
+NotifyLeave()
+
+FUNKTION:
+     void NotifyLeave(object ob, object dest);
+
+ARGUMENTE:
+     ob
+          Das Objekt, das aus dem Behaelter entfernt wurde.
+     dest
+          Das Objekt, in das <ob> bewegt wurde.
+
+BESCHREIBUNG:
+     Diese Funktion wird im Behaelter aufgerufen, nachdem ein Objekt aus
+     besagten Behaelter entfernt wurde.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Diese Funktion wird nur im Falle unbelebter Objekte gerufen. Fuer
+     Lebewesen s. bitte. exit().
+
+SIEHE AUCH:
+    NotifyRemove(), NotifyInsert(), PreventInsert(), PreventLeave(), move(),
+    exit(), init(), NotifyMove(), PreventMove()
+
+----------------------------------------------------------------------------
+Last modified: 21.05.2012, Zesstra
diff --git a/doc/lfun/NotifyMove b/doc/lfun/NotifyMove
new file mode 100644
index 0000000..9fe1861
--- /dev/null
+++ b/doc/lfun/NotifyMove
@@ -0,0 +1,58 @@
+
+FUNKTION:
+     protected void NotifyMove(object dest, object oldenv, int method);
+
+DEFINIERT IN:
+     /std/thing/moving.c
+     /std/living/moving.c
+     /std/player/moving.c
+
+ARGUMENTE:
+     dest
+          Das Ziel des Moves bzw. das jetzt aktuelle Environment
+     oldenv
+          Das alte Environment des Objekts
+     method
+          Die Move-Methode(n), mit der/denen bewegt wurde.
+
+BESCHREIBUNG:
+     Diese Funktion wird vom move() im Objekt gerufen, sobald die Bewegung im
+     wesentlichen abgeschlossen ist. Sie soll einerseits das Objekt ueber eine
+     stattgefundene Bewegung informieren, aber auch einige Dinge erledigen,
+     die bei der Bewegung stattfinden muessen (bei Livings z.B. das Team
+     nachholen).
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Diese Funktion kann ueberschrieben werden, damit das Objekt Bewegungen
+     mitgekommt, ohne das move() selber zu ueberschreiben oder einen Move-Hook
+     zu setzen. Dabei aber bitte unbedingt beachten:
+     Das geerbte NotifyMove() _MUSS IN JEDEM FALL_ mit aufgerufen werden!
+     Solltet ihr das vergessen, werden eure Objekte buggen. ;-)
+     Die Funktion darf nur objektintern verwendet werden. Beim Ueberschreiben
+     das 'protected' nicht vergessen!
+
+BEISPIELE:
+     Eine Bombe, die in Seherhaustruhen explodiert:
+
+     protected void NotifyMove(object dest, object oldenv, int method) {
+         ::NotifyMove(dest, oldenv, method); // WICHTIG!
+         if (objectp(dest) &&
+             load_name(dest) == "/d/seher/haeuser/truhe") {
+             if (find_call_out("explodiere")==-1)
+                 call_out("explodiere",900);
+         }
+         else
+             remove_call_out("explodiere");
+     }
+
+
+SIEHE AUCH:
+     PreventLeave(), NotifyInsert(), NotifyLeave(), MayAddObject(),
+     PreventInsertLiving(), PreventLeaveLiving(), NotifyMove(),
+     PreventMove(), MayAddWeight(), move(), /std/container/restrictions.c
+
+----------------------------------------------------------------------------
+Last modified: 04.08.2007, Zesstra
diff --git a/doc/lfun/NotifyPlayerDeath b/doc/lfun/NotifyPlayerDeath
new file mode 100644
index 0000000..9166150
--- /dev/null
+++ b/doc/lfun/NotifyPlayerDeath
@@ -0,0 +1,74 @@
+NotifyPlayerDeath()
+
+FUNKTION:
+  void NotifyPlayerDeath(object victim,object killer,int lost_exp);
+
+DEFINIERT IN:
+  /std/player/life.c
+
+ARGUMENTE:
+  victim
+    Getoeteter Spieler.
+  killer
+    Objekt, welches den Spieler getoetet hat.
+  lost_exp
+    Erfahrungspunkte, die der Spieler durch den Tod verloren hat.
+
+BESCHREIBUNG:
+  Diese Funktion wird aus dem Spielerobjekt heraus immer dann
+  aufgerufen, wenn der Spieler stirbt und zwar:
+    1) im Gegner, der den Spieler getoetet hat,
+    2) im Environment des getoeteten Spielers,
+    3) in der Gilde des Spielers,
+    4) in allen Objekten in diesem Environment und
+    5) in allen Objekten (auch innerhalb Containern) im Spieler.
+  Der Gegner wird hierbei nur einmal informiert, also bei letzteren
+  Faellen herausgefiltert, falls noetig!
+  Hauptaufgabe dieser Funktion ist es somit, auf Tode von Spielern zu
+  reagieren oder selbige einfach nur mitzuloggen.
+
+  Zu dem Zeitpunkt des Aufrufs dieser Funktion ist der Spieler noch _nicht_
+  Geist und noch _nicht_ im Todesraum - dies wird im Anschluss an den Aufruf
+  der NotifyPlayerDeath() durchgefuehrt.
+  
+  Aufgerufen wird die Funktion aus '/std/player/life.c' mittels catch() und
+  werden mit limited() auf max. 150k (Gegner, Environment, Gilde) bzw. 80k 
+  (alle anderen Objekte) Ticks beschraenkt.
+  Fehler in dieser Funktion haben somit keine negativen Auswirkungen
+  auf das Sterben des Spielers.
+
+RUeCKGABEWERT:
+  keiner
+
+BEISPIELE:
+  Folgendes Beispiel demonstriert beispielsweise, wie man Tode von
+  Spielern mitloggen kann (das Beispiel ist hierbei auf den am
+  haeufigsten auftretenden Fall bezogen, dass nur das toetende Objekt
+  den Tod protokollieren soll):
+
+    void NotifyPlayerDeath(object dead, object killer, int lost_exp) 
+    { 
+      if ( intp(lost_exp) && objectp(dead) && objectp(killer) && 
+           killer==this_object() )
+        write_file( "/log/patryn/dead", sprintf(
+          "%s - %s von %s getoetet. XP: -%d", ctime(), getuid(dead),
+           killer->name(WEM), lost_exp) );
+    }
+
+  Bitte beachten: write_file() schreibt ohne Groessenbegrenzung in das
+  Logfile. Da dies auf Dauer bzw. in Gebieten mit hoher Log-Aktivitaet
+  zu Logfiles von enormer Groesse fuehren kann, ist die Verwendung
+  von write_file() nicht empfehlenswert. Ausnahmen koennen natuerlich
+  mit dem zustaendigen Regionsmagier abgesprochen werden, z.B. fuer
+  begrenzte Anwendung etwa bei sehr starken, selten besiegten Gegnern.
+
+  Weiterhin ist es empfehlenswert, das toetende Objekt (killer) nicht
+  im NotifyPlayerDeath() zu zestoeren, sondern etwas zeitversetzt,
+  damit nicht etwa im nachfolgenden NotifyPlayerDeath() eines anderen
+  Objektes (s.o. Reihenfolge) killer==0 ist.
+
+SIEHE AUCH:
+  Defend(), do_damage(), NotifyHpChange(), catch(), write_file(), log_file()
+  P_LAST_DEATH_PROPS
+----------------------------------------------------------------------------
+24.03.2012, Zesstra
diff --git a/doc/lfun/NotifyRemove b/doc/lfun/NotifyRemove
new file mode 100644
index 0000000..48b04fa
--- /dev/null
+++ b/doc/lfun/NotifyRemove
@@ -0,0 +1,26 @@
+NotifyRemove()
+
+FUNKTION:
+     void NotifyRemove(object ob);
+
+ARGUMENTE:
+     ob
+          Das Objekt, das aus dem Behaelter entfernt wurde.
+
+BESCHREIBUNG:
+     Diese Funktion wird im Behaelter aufgerufen, wenn ein Objekt im
+     besagten Behaelter zerstoert wird.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Wird nicht gerufen, wenn ein Spielerobjekt zerstoert wird.
+
+SIEHE AUCH:
+    NotifyLeave(), NotifyInsert(), PreventInsert(), PreventLeave(), move(),
+    NotifyMove(), PreventMove(),
+    BecomesNetDead()
+
+----------------------------------------------------------------------------
+Last modified: 04.08.2007, Zesstra
diff --git a/doc/lfun/NotifyTimedAttrModExpired b/doc/lfun/NotifyTimedAttrModExpired
new file mode 100644
index 0000000..f59a79a
--- /dev/null
+++ b/doc/lfun/NotifyTimedAttrModExpired
@@ -0,0 +1,20 @@
+NotifyTimedAttrModExpired
+FUNKTION:
+     void NotifyTimedAttrModExpired(string key)
+
+DEFINIERT IN:
+     Push-Methode in notify-Objekten.
+
+ARGUMENTE:
+     string key		- der geloeschte Modifier
+
+BESCHREIBUNG:
+     Wird aus dem Lebewesen aus aufgerufen, in dem der entsprechenden
+     Modifier soeben ungueltig geworden ist.     
+
+SIEHE AUCH:
+     Properties: P_ATTRIBUTES, P_TIMED_ATTR_MOD
+     Methoden:	 SetTimedAttrModifier(L), DeleteTimedAttrModifier(L),
+		 QueryTimedAttrModifier(L)
+
+27. Juli 2004 Gloinson
diff --git a/doc/lfun/NotifyXMAttrModLimitViolation b/doc/lfun/NotifyXMAttrModLimitViolation
new file mode 100644
index 0000000..44f39c0
--- /dev/null
+++ b/doc/lfun/NotifyXMAttrModLimitViolation
@@ -0,0 +1,20 @@
+NotifyXMAttrModLimitViolation()
+FUNKTION:
+      void NotifyXMAttrModLimitViolation()
+
+DEFINIERT IN:
+     /std/thing/restrictions.c
+

+BESCHREIBUNG:
+     Wird gerufen wenn die Summe der in P_X_ATTR_MOD oder P_X_ATTR_MOD
+     angegebenen Modifikatoren die Summe aller Modifikatoren im Spieler 
+     ueber den zugelassenen Grenzwert hebt und somit nicht mehr in die
+     Berechnung eingeht.
+     
+SIEHE AUCH:
+     QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+     SetAttr(), SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+     P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_ATTRIBUTES_MODIFIER,

+     P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+
+13.Jun.2004, Muadib
\ No newline at end of file
diff --git a/doc/lfun/Pacify b/doc/lfun/Pacify
new file mode 100644
index 0000000..b90ed83
--- /dev/null
+++ b/doc/lfun/Pacify
@@ -0,0 +1,113 @@
+FUNKTION
+	public int Pacify(object caster)
+
+DEFINIERT IN
+	/std/living/combat.c
+
+BESCHREIBUNG
+	Diese Funktion versucht, ein Lebewesen zu befrieden.
+  Will eine Gilde ein Lebewesen befrieden, muss sie hierfuer diese Funktion
+  in dem Lebewesen aufrufen.
+
+  Ein immer befriedbarer NPC kann durch das Setzen von P_ACCEPT_PEACE in einem
+  Lebewesen realisiert werden.
+
+	Standardmaessig funktioniert die Funktion wie folgt:
+  * Kommt der Versuch vom Spellcaster selbst, ist er immer erfolgreich.
+  * Kommt der Versuch von einem Teamkollegen, ist er immer erfolgreich.
+  * Hat das Lebewesen keine Gegner, ist der Versuch immer erfolglos.
+  In diesen Faellen erfolgt auch keine Erhoehung des Befriedezaehlers.
+  
+  In anderen Faellen wird die in P_PEACE_HISTORY fuer die Gilde des Casters
+  abgelegte Zahl erfolgreicher Befriedungen (ANZ), die Intelligenz des
+  Casters (INT_CASTER) und die Intelligenz des Lebenwesens selber (INT_ME)
+  ermittelt.
+  Anschliessend wird eine Wahrscheinlichkeit w ausgerechnet:
+  
+    w = (INT_CASTER + 10 - ANZ*4) / (INT_ME + 10)
+  
+  Hierbei gibt w die Chance auf eine erfolgreiche Befriedung an. Mittels einer
+  Zufallszahl wird bestimmt, ob der aktuelle Versuch erfolgreich ist. Falls
+  ja, wird der Zaehler fuer die Gilde des Casters in P_PEACE_HISTORY erhoeht.
+
+  Je oefter ein Lebewesen als von einer Gilde schon befriedet wurde, desto
+  unwahrscheinlicher, dass es erneut darauf 'hereinfaellt'.
+
+BEMERKUNGEN:
+  *	Die Funktion kann auch ueberschrieben werden, um ein vom Magier
+    gewuenschtes Verhalten zu realisieren. Ein komplettes Abhaengen von
+    Befriedungen sollte dabei aber die Ausnahme sein!
+  * Diese Funktion verwaltet auch das P_PEACE_HISTORY, speziell die Reduktion
+    der Erfolgszaehler. Ueberschreibt man sie ohne das geerbte Pacify()
+    zu nutzen, wird P_PEACE_HISTORY nicht mehr verwaltet.
+
+RUECKGABEWERTE:
+    1 - das Lebewesen wurde erfolgreich befriedet..
+    0 - der Befriedeversuch ist gescheitert.
+    
+BEISPIELE:
+    Angenommen, der Caster hat eine Intelligenz von 22. Die folgende Tabelle
+    gibt dann die Wahrscheinlichkeiten fuer eine erfolgreiche Befriedung an:
+    (in Abhaengigkeit von eigener Intelligenz und vergangener erfolgreicher
+     Versuche)
+ INT_ME  Erfolgswahrscheinlichkeiten je nach Anzahl erfolgreicher Versuche
+              1       2       3       4       5       6       7       8
+      0     280     240     200     160     120      80      40       0
+      2  233,33     200  166,67  133,33     100   66,67   33,33       0
+      4     200  171,43  142,86  114,29   85,71   57,14   28,57       0
+      6     175     150     125     100      75      50      25       0
+      8  155,56  133,33  111,11   88,89   66,67   44,44   22,22       0
+     10     140     120     100      80      60      40      20       0
+     12  127,27  109,09   90,91   72,73   54,55   36,36   18,18       0
+     14  116,67     100   83,33   66,67      50   33,33   16,67       0
+     16  107,69   92,31   76,92   61,54   46,15   30,77   15,38       0
+     18     100   85,71   71,43   57,14   42,86   28,57   14,29       0
+     20   93,33      80   66,67   53,33      40   26,67   13,33       0
+     22    87,5      75    62,5      50    37,5      25    12,5       0
+     24   82,35   70,59   58,82   47,06   35,29   23,53   11,76       0
+     26   77,78   66,67   55,56   44,44   33,33   22,22   11,11       0
+     28   73,68   63,16   52,63   42,11   31,58   21,05   10,53       0
+     30      70      60      50      40      30      20      10       0
+     32   66,67   57,14   47,62    38,1   28,57   19,05    9,52       0
+     34   63,64   54,55   45,45   36,36   27,27   18,18    9,09       0
+     35   62,22   53,33   44,44   35,56   26,67   17,78    8,89       0
+     36   60,87   52,17   43,48   34,78   26,09   17,39     8,7       0
+     38   58,33      50   41,67   33,33      25   16,67    8,33       0
+     40      56      48      40      32      24      16       8       0
+     42   53,85   46,15   38,46   30,77   23,08   15,38    7,69       0
+     44   51,85   44,44   37,04   29,63   22,22   14,81    7,41       0
+     46      50   42,86   35,71   28,57   21,43   14,29    7,14       0
+     48   48,28   41,38   34,48   27,59   20,69   13,79     6,9       0
+     50   46,67      40   33,33   26,67      20   13,33    6,67       0
+     52   45,16   38,71   32,26   25,81   19,35    12,9    6,45       0
+     54   43,75    37,5   31,25      25   18,75    12,5    6,25       0
+     56   42,42   36,36    30,3   24,24   18,18   12,12    6,06       0
+     58   41,18   35,29   29,41   23,53   17,65   11,76    5,88       0
+     60      40   34,29   28,57   22,86   17,14   11,43    5,71       0
+     62   38,89   33,33   27,78   22,22   16,67   11,11    5,56       0
+     64   37,84   32,43   27,03   21,62   16,22   10,81    5,41       0
+     66   36,84   31,58   26,32   21,05   15,79   10,53    5,26       0
+     68    35,9   30,77   25,64   20,51   15,38   10,26    5,13       0
+     70      35      30      25      20      15      10       5       0
+     72   34,15   29,27   24,39   19,51   14,63    9,76    4,88       0
+     74   33,33   28,57   23,81   19,05   14,29    9,52    4,76       0
+     76   32,56   27,91   23,26    18,6   13,95     9,3    4,65       0
+     78   31,82   27,27   22,73   18,18   13,64    9,09    4,55       0
+     80   31,11   26,67   22,22   17,78   13,33    8,89    4,44       0
+     82   30,43   26,09   21,74   17,39   13,04     8,7    4,35       0
+     84   29,79   25,53   21,28   17,02   12,77    8,51    4,26       0
+     86   29,17      25   20,83   16,67    12,5    8,33    4,17       0
+     88   28,57   24,49   20,41   16,33   12,24    8,16    4,08       0
+     90      28      24      20      16      12       8       4       0
+     92   27,45   23,53   19,61   15,69   11,76    7,84    3,92       0
+     94   26,92   23,08   19,23   15,38   11,54    7,69    3,85       0
+     96   26,42   22,64   18,87   15,09   11,32    7,55    3,77       0
+     98   25,93   22,22   18,52   14,81   11,11    7,41     3,7       0
+    100   25,45   21,82   18,18   14,55   10,91    7,27    3,64       0
+
+SIEHE AUCH
+        P_ACCEPT_PEACE, P_PEACE_HISTORY
+
+LETZTE AENDERUNG
+07.06.2008, Zesstra
+
diff --git a/doc/lfun/PayIn b/doc/lfun/PayIn
new file mode 100644
index 0000000..0714c53
--- /dev/null
+++ b/doc/lfun/PayIn
@@ -0,0 +1,47 @@
+PayIn()
+FUNKTION:
+     varargs void PayIn(int amount, int percent);
+
+DEFINIERT IN:
+     /p/daemon/zentralbank.c
+
+ARGUMENTE:
+     int amount	-	einzuzahlender Betrag
+     int percent -	Bewertungsprozentsatz
+
+BESCHREIBUNG:
+     Es wird Brutto amount Geld in die Bank eingezahlt. Der Prozentsatz legt
+     fest, wieviel tatsaechlich gutgeschrieben wird:
+     Gutschrift = amount*percent/100
+
+     Wird percent nicht angegeben, dann wird der derzeitige Bankbewertungs-
+     massstab fuer Geld angenommen.
+
+BEISPIELE:
+     #include <bank.h>
+     ...
+     AddCmd("spende",#'action_spende,
+	    "Was willst du spenden?");
+     ...
+     int action_spende(string str, extra *o) {
+      int i;
+      if(sscanf("%d muenze",i)==1 && i>0)
+       if(this_player()->QueryMoney(i) && this_player()->AddMoney(-i)) {
+        write("Du spendest "+i+" Muenzen.\n");
+	say(this_player()->Name(WER)+" spendet "+i+" Muenzen.\n");
+	ZENTRALBANK->PayIn(i);
+	
+       } else
+        write("Soviel hast du nicht dabei!\n");
+      ...
+
+BEMERKUNGEN:
+     Unsere Zentralbank ist korrupt, vor allem dadurch, dass in Laeden und
+     an anderen Stellen Geld erzeugt wird.
+
+SIEHE AUCH:
+     Geldhandling:	AddMoney(L), QueryMoney(L)
+     Zentralbank:	WithDraw(L), _query_current_money(L)
+     Sonstiges:		/items/money.c, /sys/bank.h
+
+27. Apr 2004 Gloinson
diff --git a/doc/lfun/PlayerQuit b/doc/lfun/PlayerQuit
new file mode 100644
index 0000000..22e3d6e
--- /dev/null
+++ b/doc/lfun/PlayerQuit
@@ -0,0 +1,20 @@
+PlayerQuit()
+
+FUNKTION:
+    void PlayerQuit(object pl);
+
+GERUFEN VON:
+    /std/player/base.c
+
+ARGUMENTE:
+    object pl
+      Spieler, der Verbindung beendet
+
+BESCHREIBUNG:
+    Wird im environment() gerufen, wenn der Spieler das MUD mit "ende"
+    verlaesst.
+
+SIEHE AUCH:
+    BecomesNetAlive(), BecomesNetDead()
+    
+24. Aug 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/PresentEnemies b/doc/lfun/PresentEnemies
new file mode 100644
index 0000000..9c31efe
--- /dev/null
+++ b/doc/lfun/PresentEnemies
@@ -0,0 +1,71 @@
+FUNKTION:
+	object *PresentEnemies();
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	keine
+
+RUeCKGABEWERT:
+	anwesende Feinde
+
+BESCHREIBUNG:
+	Diese Funktion liefert genau die Feinde zurueck, die sich derzeit im
+	selben Raum befinden. Die Feinde unterliegen hierbei noch gewissen
+	Einschraenkungen:
+	  (1) Sie duerfen als NPC nicht gestorben sein, das heisst, sie
+	      muessen als Objekt noch existieren.
+	  (2) Sie duerfen als Spieler nicht gestorben sein, das heisst, sie
+	      duerfen keine Geister sein (Property P_GHOST nicht gesetzt).
+	  (3) Sie muessen angreifbar sein, das heisst, die Property
+	      P_NO_ATTACK darf nicht gesetzt sein.
+	Wird eine dieser Bedingungen verletzt, so wird der Gegner aus der
+	internen Gegnerliste entfernt. Zusaetzlich gilt:
+	  Netztote werden nur als Gegner erkannt, wenn keine anderen Gegner
+	  zur Verfuegung stehen.
+
+BEISPIEL:
+	Im Folgenden erblinden alle Gegner im Raum:
+	  string blindThemAll()
+	  { ob*livList;
+	    if(!livList=PresentEnemies())
+	      return break_string(
+	 "Mist...keiner da, der blind werden moechte.",77,
+	 Name(WER)+" grummelt: ");
+	    for(i=sizeof(livList);i--;)
+	    { if(livList[i]->QueryProp(P_BLIND))
+	      { tell_object(this_object(),break_string(
+	 livList[i]->Name(WER)+" ist schon blind.",77));
+	        continue;
+	      }
+	      tell_object(this_object(),break_string(
+	 "Du kratzt "+livList[i]->name(WEM)+" die Augen aus.",77));
+	      tell_object(livList[i],break_string(
+	 Name(WER)+" kratzt Dir die Augen aus!",77));
+	      tell_room(environment(this_object()),break_string(
+	 Name(WER)+" kratzt "+livList[i]->name(WEM)
+	+" die Augen aus.",77),({this_object(),livList[i]}));
+	      livList[i]->SetProp(P_BLIND,1);
+	    }
+	    return"";
+	  }
+	Aufgerufen wird das ganze am Besten in einem Chat:
+	  void create()
+	  { ::create();
+	    ...
+	    SetProp(P_CHAT_CHANCE,10);
+	    SetChats(20,({break_string(
+	 "Nicht angreifen, sonst wirst Du noch blind!",77,
+	 Name(WER)+" bruellt: "),
+	                  "@@blindThemAll@@"}));
+	  }
+	Natuerlich sind auch noch mehr Funktionen und Meldungen als Chats
+	moeglich: Die zwei im Beispiel sind im Normalfall etwas wenig.
+
+SIEHE AUCH:
+	SelectEnemy(), QueryEnemies(), IsEnemy(), P_GHOST, P_NO_ATTACK,
+	SetChats, P_CHAT_CHANCE
+
+----------------------------------------------------------------------------
+Last modified: Thu May 27 15:01:48 1999 by Patryn
diff --git a/doc/lfun/PresentEnemyRows b/doc/lfun/PresentEnemyRows
new file mode 100644
index 0000000..339642c
--- /dev/null
+++ b/doc/lfun/PresentEnemyRows
@@ -0,0 +1,40 @@
+
+PresentEnemyRows()
+
+
+FUNKTION:
+        varargs mixed *PresentEnemyRows(object *here)
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        Rueckgabewert von PresentEnemies kann uebergeben werden.
+
+BESCHREIBUNG:
+        Ergibt die feindlichen Reihen.
+
+RUECKGABEWERT:
+        Ein Array, bestehend aus MAX_TEAMROWS Arrays mit den Objekten
+        der anwesenden Feinde.
+
+BEMERKUNGEN:
+        Jede Reihe ist Summe der entsprechenden Reihen der
+        anwesenden Teams.
+        Feinde, die in keinem Team sind, stehen im ersten Array.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentTeamPosition,
+                    SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/PresentPosition b/doc/lfun/PresentPosition
new file mode 100644
index 0000000..ea765cf
--- /dev/null
+++ b/doc/lfun/PresentPosition
@@ -0,0 +1,38 @@
+
+PresentPosition()
+
+
+FUNKTION:
+        varargs int PresentPosition(mixed pmap)
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        Rueckgabewert von PresentTeamRows() oder PresentTeamPositions()
+        kann uebergeben werden.
+
+BESCHREIBUNG:
+        Ergibt die Nummer der Reihe, in der der Spieler gerade steht.
+
+RUECKGABEWERT:
+        Reihennummer im Bereich von 1 bis TEAM_MAXROWS.
+
+BEMERKUNGEN:
+        Ist ein Spieler in keinem Team, so steht er automatisch in Reihe 1.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentRows, PresentEnemyRows, PresentTeamPosition,
+                    SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/PresentRows b/doc/lfun/PresentRows
new file mode 100644
index 0000000..e8c854a
--- /dev/null
+++ b/doc/lfun/PresentRows
@@ -0,0 +1,88 @@
+
+PresentRows()
+
+
+FUNKTION:
+    mixed *PresentRows(object env);
+
+DEFINIERT IN:
+    TEAM_OBJECT (s. <living/team.h>)
+
+ARGUMENTE:
+    object env
+        Das Environment des gewuenschten Objektes.
+
+BESCHREIBUNG:
+    Mit dieser Funktion bekommt man die aktuellen Teamreihen, die im Argument
+    env anwesend sind, des Teams zurueckgegeben. Ist env kein Objekt, so
+    wird environment(this_player()) als solches angenommen.
+
+RUECKGABEWERT:
+    Es wird ein mixed-Array zurueckgegeben, dabei sind die einzelnen Reihen
+    selbst wiederum Arrays mit den Spielerobjekten.
+
+BEISPIEL:
+
+    Ein NPC im Kampf laesst eine Feuerwalze auf ein Team los, welche aber nur
+    Spieler in der ersten und zweiten Teamreihe Schaden zufuegen soll.
+
+    void Attack( object enemy )
+    {
+     ...
+
+     object team = enemy->QueryProp(P_TEAM);
+
+     if ( objectp(team) )
+      {
+       mixed teamrows = team->PresentRows(enemy);
+
+//  Inhalt von "teamrows" zu diesem Zeitpunkt:
+
+//  ({ ({[/dwarf:hauweg]}),({}),({[/elf:spitzohr]}),({}),({}),({}) })
+
+//  In der Umgebung von Zwerg Hauweg steht also noch Elf Spitzohr, und zwar
+//  in der dritten Teamreihe (der hat Glueck gehabt).
+//  Wenn dem Team noch mehr Spieler angehoeren, befinden sie sich gerade
+//  nicht in der Umgebung (sprich im selben Raum) wie Hauweg.
+
+       foreach ( i : 2 )
+        {
+         foreach ( object pl : teamrows[i] )
+          {
+           tell_object(pl,"Der Feuerteufel laesst eine Feuerwalze auf Dich "
+               "und Dein Team los.\n");
+
+           pl->Defend(200+random(200),({DT_FIRE}),([SP_SHOW_DAMAGE:1]),TO);
+          }
+        }
+      }
+     else
+      {
+       tell_object(enemy,"Der Feuerteufel laesst eine Feuerwalze auf Dich "
+           "los.\n");
+
+       enemy->Defend(200+random(200),({DT_FIRE}),([SP_SHOW_DAMAGE:1]),TO);
+      }
+
+     ...
+    }
+
+BEMERKUNG:
+    Man beachte, dass das erste Argument (also Argument 0) die erste
+    Teamreihe ist.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentEnemyRows, PresentTeamPosition,
+                    SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/PresentTeamPositions b/doc/lfun/PresentTeamPositions
new file mode 100644
index 0000000..76adc17
--- /dev/null
+++ b/doc/lfun/PresentTeamPositions
@@ -0,0 +1,40 @@
+
+PresentTeamPositions()
+
+
+FUNKTION:
+        varargs mapping PresentTeamPositions(mixed pmap)
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        Rueckgabewert von PresentTeamRows() kann uebergeben werden.
+
+BESCHREIBUNG:
+        Ermittelt die Reihennummern aller anwesender Teammitglieder.
+
+RUECKGABEWERT:
+        Ein Mapping mit den Reihennummern (von 1 bis MAX_TEAMROWS)
+        der anwesenden Teammitglieder.
+
+BEMERKUNGEN:
+        Kann auch zur Konvertierung anderer Kampfreihen-Arrays in
+        ein Positions-Mapping verwendet werden.
+        Ist der Spieler in keinem Team, so steht er in Reihe 1.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/PresentTeamRows b/doc/lfun/PresentTeamRows
new file mode 100644
index 0000000..38bfa7e
--- /dev/null
+++ b/doc/lfun/PresentTeamRows
@@ -0,0 +1,24 @@
+PresentTeamRows()
+
+FUNKTION:
+	mixed *PresentTeamRows()
+
+DEFINIERT IN:
+	/std/living/team.c
+
+ARGUMENTE:
+	keine
+
+BESCHREIBUNG:
+	Ergibt die Reihen mit den anwesenden Teammitgliedern.
+
+RUECKGABEWERT:
+	Ein Array bestehend aus MAX_TEAMROWS Arrays mit den Objekten
+        der anwesenden Teammitglieder.
+
+BEMERKUNGEN:
+	Wenn der Spieler in keinem Team ist, enthaelt das erste Array
+	nur den Spieler und die anderen Arrays sind leer.
+
+SIEHE AUCH:
+	teams
diff --git a/doc/lfun/PreventFollow b/doc/lfun/PreventFollow
new file mode 100644
index 0000000..100f92d
--- /dev/null
+++ b/doc/lfun/PreventFollow
@@ -0,0 +1,49 @@
+PreventFollow()
+
+FUNKTION:
+  int PreventFollow(object dest)
+
+ARGUMENTE:
+  dest: Zielobjekt, in das der Verfolgte bewegt werden soll.
+
+FUNKTION:
+  In jedem Verfolger, der mit AddPursuer in die Liste der Verfolger 
+  eingetragen wurde, wird vor dem Bewegen in das Zielobjekt die Funktion
+  PreventFollow mit dem Zielobjekt als Argument aufgerufen.
+
+RUECKGABEWERT:
+  0: Verfolger darf in das Zielobjekt folgen
+  1: Verfolger darf in dieses Zielobjekt nicht folgen
+     (Verfolgung bleibt weiterhin aktiv)
+  2: Verfolger darf in dieses Zielobjekt nicht folgen
+     (Verfolgung wird abgebrochen und Verfolger aus der Verfolgerliste
+      ausgetragen)
+
+BEMERKUNG:
+  Durch PreventFollow kann der raeumliche Bereich, in dem verfolgt werden
+  darf, eingeschraenkt werden.
+
+BEISPIELE:
+  Man moechte, dass ein NPC auf einer Insel nicht mit dem Spieler in das
+  Boot steigt, um mit dem Spieler zusammen von der Insel herunterzukommen.
+
+  #define PATH(x) ("/d/.../.../mein/pfad/+(x)")                           
+
+  ...                                          
+
+  int PreventFollow(object boot)                                           
+   {
+    if ( object_name(boot)[0..strlen(PATH("boot"))-1] == PATH("boot") )
+     return 1;
+   }                                                                         
+
+  Diese Funktions-Definition ist sehr flexibel, denn sie erlaubt sowohl
+  spaetere Pfadanpassung als auch mehrere Boote.
+  Da ueber die Funktion strlen() nur bis zum letzten Buchstaben des    
+  angegebenen Strings getestet wird, wird also gleichzeitig auch auf          
+  boot[1], boot[2] usw. getestet.
+
+SIEHE AUCH:
+  "AddPursuer", "RemovePursuer"
+----------------------------------------------------------------------------
+Last modified: Tue Jun 10 13:59:30 2003 by Gabylon
\ No newline at end of file
diff --git a/doc/lfun/PreventInsert b/doc/lfun/PreventInsert
new file mode 100644
index 0000000..55c1533
--- /dev/null
+++ b/doc/lfun/PreventInsert
@@ -0,0 +1,46 @@
+PreventInsert()
+
+FUNKTION:
+     int PreventInsert(object ob);
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     ob
+          Das Objekt, das in den Behaelter eingefuegt werden soll.
+
+BESCHREIBUNG:
+     Mit dieser Funktion kann ein Behaelter pruefen, ob er das Objekt ob
+     aufnehmen moechte oder nicht.
+
+RUeCKGABEWERT:
+     0, wenn das Objekt aufgenommen werden kann; ein Wert groesser als 0
+     zeigt an, dass das Objekt nicht aufgenommen werden soll.
+
+BEMERKUNGEN:
+     Wenn ob mit dem Flag M_NOCHECK bewegt wird, wird PreventInsert() zwar
+     aufgerufen, das Objekt wird jedoch auf jeden Fall in den Behaelter
+     bewegt, unabhaengig vom Rueckgabewert!
+
+BEISPIELE:
+     Um zu verhindern, dass man Geld in einen Behaelter stecken kann, sollte
+     man wie folgt vorgehen:
+
+     varargs int PreventInsert(object ob)
+     {
+       // Wenn es Geld ist, erheben wir sofort Einspruch
+       if (ob->id("geld"))
+         return 1;
+       // Ansonsten koennte ein ererbtes Objekt noch Einspruch erheben!
+       else
+         return ::PreventInsert(ob);
+     }
+
+SIEHE AUCH:
+     PreventLeave(), NotifyInsert(), NotifyLeave(), MayAddObject(),
+     PreventInsertLiving(), PreventLeaveLiving(), NotifyMove(),
+     PreventMove(), MayAddWeight(), move(), /std/container/restrictions.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Dec 18 02:00:00 1999 by Tiamak
diff --git a/doc/lfun/PreventInsertLiving b/doc/lfun/PreventInsertLiving
new file mode 100644
index 0000000..78f431f
--- /dev/null
+++ b/doc/lfun/PreventInsertLiving
@@ -0,0 +1,35 @@
+PreventInsertLiving()
+
+FUNKTION:
+     int PreventInsertLiving(object ob);
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     ob
+          Das Living, das in den Behaelter eingefuegt werden soll.
+
+BESCHREIBUNG:
+     Mit dieser Funktion kann ein Behaelter pruefen, ob er das Living ob
+     aufnehmen moechte oder nicht.
+
+RUeCKGABEWERT:
+     0, wenn das Living aufgenommen werden kann; ein Wert groesser als 0
+     zeigt an, dass das Living nicht aufgenommen werden soll.
+
+BEMERKUNGEN:
+     Wenn ob mit dem Flag M_NOCHECK bewegt wird, wird PreventInsertLiving() 
+     zwar aufgerufen, das Living wird jedoch auf jeden Fall in den Behaelter
+     bewegt, unabhaengig vom Rueckgabewert!
+
+
+SIEHE AUCH:
+     PreventLeaveLiving(), /std/container/restrictions.c,
+     PreventMove(), PreventInsert(), PreventLeave(),
+     NotifyMove(), NotifyInsert(), NotifyLeave(), NotifyRemove(),
+     move(), init(), exit(),
+     InitAttack(), ExitAttack()
+
+----------------------------------------------------------------------------
+Last modified: 04.08.2007, Zesstra
diff --git a/doc/lfun/PreventLeave b/doc/lfun/PreventLeave
new file mode 100644
index 0000000..85d46a3
--- /dev/null
+++ b/doc/lfun/PreventLeave
@@ -0,0 +1,35 @@
+PreventLeave()
+
+FUNKTION:
+     int PreventLeave(object ob, mixed dest);
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     ob
+          Das Objekt, das aus dem Behaelter genommen werden soll.
+     dest 
+          Das Ziel in das das Objekt ob bewegt werden soll.
+
+BESCHREIBUNG:
+     Mit dieser Funktion kann ein Behaelter pruefen, ob er das Objekt ob
+     sich bewegen lassen moechte oder nicht.
+
+RUeCKGABEWERT:
+     0, wenn das Objekt bewegt werden kann; ein Wert groesser als 0
+     zeigt an, dass das Objekt nicht bewegt werden soll.
+
+BEMERKUNGEN:
+     Wenn ob mit dem Flag M_NOCHECK bewegt wird, wird PreventLeave() zwar
+     aufgerufen, das Objekt wird jedoch auf jeden Fall aus dem Behaelter
+     bewegt, unabhaengig vom Rueckgabewert!
+
+SIEHE AUCH:
+     PreventInsert(), NotifyInsert(), NotifyLeave(),
+     MayAddWeight(), move(), /std/container/restrictions.c
+     PreventLeaveLiving(), PreventInsertLiving(), PreventMove(),
+     NotifyMove(), MayAddObject(), NotifyRemove()
+
+----------------------------------------------------------------------------
+Last modified: 04.08.2007, Zesstra
diff --git a/doc/lfun/PreventLeaveLiving b/doc/lfun/PreventLeaveLiving
new file mode 100644
index 0000000..4d13b54
--- /dev/null
+++ b/doc/lfun/PreventLeaveLiving
@@ -0,0 +1,35 @@
+PreventLeaveLiving()
+
+FUNKTION:
+     int PreventLeaveLiving(object ob, mixed dest);
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     ob
+          Das Living, das aus dem Behaelter genommen werden soll.
+     dest 
+          Das Ziel in das das Living ob bewegt werden soll.
+
+BESCHREIBUNG:
+     Mit dieser Funktion kann ein Behaelter pruefen, ob er das Living ob
+     sich bewegen lassen moechte oder nicht.
+
+RUeCKGABEWERT:
+     0, wenn das Living bewegt werden kann; ein Wert groesser als 0
+     zeigt an, dass das Living nicht bewegt werden soll.
+
+BEMERKUNGEN:
+     Wenn ob mit dem Flag M_NOCHECK bewegt wird, wird PreventLeave() zwar
+     aufgerufen, das Living wird jedoch auf jeden Fall aus dem Behaelter
+     bewegt, unabhaengig vom Rueckgabewert!
+
+SIEHE AUCH:
+     PreventInsertLiving(), /std/container/restrictions.c
+     PreventMove(), PreventLeave(), PreventInsert(),
+     NotifyMove(), NotifyLeave(), NotifyInsert(), NotifyRemove(),
+     move(), exit(), init(),
+     InitAttack, ExitAttack()
+----------------------------------------------------------------------------
+Last modified: 04.08.2007, Zesstra
diff --git a/doc/lfun/PreventMove b/doc/lfun/PreventMove
new file mode 100644
index 0000000..798ee0b
--- /dev/null
+++ b/doc/lfun/PreventMove
@@ -0,0 +1,81 @@
+PreventInsert()
+
+FUNKTION:
+     protected int PreventMove(object dest, object oldenv, int method);
+
+DEFINIERT IN:
+     /std/thing/moving.c
+     /std/living/moving.c
+     /std/player/moving.c
+
+ARGUMENTE:
+     dest
+          Das Ziel des Moves
+     oldenv
+          Das (Noch-)Environment des Objekts
+     method
+          Die Move-Methode(n), mit der/denen bewegt werden soll
+
+BESCHREIBUNG:
+     Mit dieser Funktion prueft ein Objekt, ob es von 'oldenv' nach 'dest'
+     bewegt werden mag. Dabei wird 'method' beruecksichtigt (z.B. schaltet
+     M_NOCHECK die meisten Pruefungen ab).
+     Bei Gegenstaenden wird z.B. P_NODROP, P_NOGET, das Gewicht, ob das Ziel
+     das Objekt aufnehmen will (MayAddWeight(), PreventInsert) oder auch
+     PreventLeave() geprueft.
+     Bei Lebewesen wird z.B. P_NO_TPORT in 'dest' und 'oldenv' und
+     PreventLeaveLiving/PreventInsertLiving() ausgewertet.
+     Bei Spielern wird auch noch getestet, ob method M_GO oder M_TPORT
+     enthaelt und ob das Ziel nur von Testspielern betreten werden kann.
+
+RUeCKGABEWERT:
+     0, wenn das Objekt bewegt werden darf.
+     Wenn es nicht bewegt werden darf, sind als Rueckgabewerte die in
+     /sys/moving.h definierten Move-Fehlerwerte zulaessig (s. move()). Sollte
+     hier ein ungueltiger Fehlerwert zurueckgegeben werden, wird das move()
+     ebenfalls abgebrochen und ME_DONT_WANT_TO_BE_MOVED zurueckgeben.
+
+BEMERKUNGEN:
+     Diese Funktion kann ueberschrieben, um feinere Kontrolle ueber die
+     Bewegungen des Objekt zu haben. Dabei aber bitte einige Dinge beachten:
+     1. Denkt daran, ggf. M_NOCHECK zu beruecksichtigen und und eure
+     Pruefungen nur zu machen, wenn es nicht in method vorkommt.
+     2. GANZ WICHTIG: Wenn ihr mit euren Pruefungen fertig sein und das Objekt
+     bewegt werden duerfte, die geerbten Pruefungen noch testen, also _IMMER_
+     das geerbte PreventMove() noch aufrufen und dessen Wert
+     zurueckgeben/beruecksichtigen, da sonst Pruefungen des Gewichts etc. 
+     nicht funktionieren oder bei Lebewesen die Prevent*() im Environment 
+     nicht gerufen werden!
+     3. Die Funktion ist nur objektintern zu verwenden, Call-Other von aussen
+     sind nicht moeglich, beim Ueberschreiben 'protected' nicht vergessen.
+     4. Nochmal: Geerbtes PreventMove() _NICHT VERGESSEN_!
+
+BEISPIELE:
+     Ein Objekt, was nur im Sternenlicht aufgenommen werden kann (warum
+     auch immer):
+
+     protected int PreventMove(object dest, object oldenv, int method) {
+       if ( (method & M_NOCHECK) ) {
+           // wenn mit M_NOCHECK bewegt, ist das Sternenlicht egal, nur
+           // geerbtes PreventMove() beruecksichten:
+           return ::PreventMove(dest, oldenv, method);
+       }
+       else if ( method & M_GET) {
+           // wenn es aufgenommen werden soll: nach Sternenlicht im Raum
+           // gucken:
+           if (objectp(dest) && 
+               (dest->QueryProp(P_LIGHT_TYPE) != LT_STARS))
+               return ME_CANT_BE_TAKEN;
+       }
+       // Fall-through:
+       return ::PreventMove(dest, oldenv, method);
+     }
+
+
+SIEHE AUCH:
+     PreventLeave(), NotifyInsert(), NotifyLeave(), MayAddObject(),
+     PreventInsertLiving(), PreventLeaveLiving(), NotifyMove(),
+     PreventMove(), MayAddWeight(), move(), /std/container/restrictions.c
+
+----------------------------------------------------------------------------
+Last modified: 04.08.2007, Zesstra
diff --git a/doc/lfun/Query b/doc/lfun/Query
new file mode 100644
index 0000000..2b39998
--- /dev/null
+++ b/doc/lfun/Query
@@ -0,0 +1,81 @@
+Query()
+FUNKTION:
+     public varargs mixed Query(string name, int Type);
+
+DEFINIERT IN:
+     /std/thing/properties.c
+
+ARGUMENTE:
+     string name - Property, deren Wert(e) ausgelesen werden
+     int type  - Art der gewuenschten Information.
+
+BESCHREIBUNG:
+     Der Wert einer der inneren Eigenschaften der Property 'name' wird
+     zurueckgegeben.  'Type' ist dabei einer der in /sys/thing/properties.h
+     und folgend aufgelisteten F_XXX-Werte:
+
+     F_VALUE (==0, Default)
+         Unter Umgehung einer eventuell vorhandenen Abfragemethode oder
+         _query_'name'() wird der Datenwert der Property 'name'
+         zurueckgegeben.
+     F_MODE
+          Die internen Flags der Property werden zurueckgegeben.Dies koennen
+          (logisch mit & verknuepft) sein:
+          SAVE  - Property soll bei save_object() gespeichert werden
+          PROTECTED - Objekt selbst/EM/Root kann Property manipulieren
+          SECURED  - wie PROTECTED, das Flag kann aber nicht
+                     zurueckgesetzt werden (immer SECURED)
+          NOSETMETHOD - niemand kann Property manipulieren
+                        (auch kein F_SET_METHOD oder _set_'name'())
+     F_SET_METHOD
+          Ein eventuell fuer die Property eingetragene F_SET_METHOD wird
+          zurueckgegeben.
+          (_set_'name'()-Methoden werden so nicht aufgefuehrt!)
+     F_QUERY_METHOD
+          Ein eventuell fuer die Property eingetragene F_QUERY_METHOD wird
+          zurueckgegeben.
+          (_query_'name'()-Methoden werden so nicht aufgefuehrt!)
+
+RUeCKGABEWERT:
+     Die gewuenschte Eigenschaft, abhaengig von 'Type'.
+
+BEMERKUNGEN:
+     - Query() sollte nicht zum regulaeren Auslesen des Inhalt einer
+       Property verwendet werden, da sowohl F_QUERY_METHOD als auch
+       libinterne _query_'name'()-Methoden umgangen werden und das Ergebnis
+       fuer so veraenderte Propertys undefiniert ist
+     - _set_'name'() und _query_'name'() sind alte Propertymethoden und
+       sollten nicht in normalen Objekten benutzt werden ->
+       F_SET_METHOD/F_QUERY_METHOD (ggf. mit PROTECTED) nutzen
+     - F_SET/F_QUERY_METHODs koennen 'protected' (empfohlen) oder 'static'
+       sein. _set_/_query_ duerfen momentan _nicht_ 'protected' sein, fuer
+       diese geht nur 'static' (in diesem Fall empfohlen).
+
+BEISPIELE:
+     // Auslesen des Wertes unter Umgehung einer Abfragemethode
+     Query(P_XYZ, F_VALUE);
+
+     // Auslesen der Flags erfaehrt man mit:
+     Query(P_XYZ, F_MODE);
+
+     // sauberes Programmieren, wir wollen eine F_QUERY_METHOD setzen,
+     // pruefen vorher auf Existenz:
+     if(this_player()->Query(P_FROG, F_QUERY_METHOD) {
+      write(break_string(
+       "Ich kann dich nicht weiter vor Froschsein schuetzen!",
+       "Der Magier winkt ab: ", 78));
+      say(break_string(
+       "Ich kann dich nicht weiter vor Froschsein schuetzen!",
+       "Der Magier sagt zu "+this_player()->name(WEM)+": ", 78));
+     } else {
+      this_player()->Set(P_FROG, #'query_protect_frog, F_QUERY_METHOD);
+      ...
+     }
+
+SIEHE AUCH:
+     Aehnliches: SetProp(L), QueryProp(L), Set(L)
+     Generell:  SetProperties(L), QueryProperties(L)
+     Konzept:  properties, /std/thing/properties.c
+     Sonstiges:  P_AUTOLOADOBJ
+
+28.03.2008, Zesstra
diff --git a/doc/lfun/QueryAllDoors b/doc/lfun/QueryAllDoors
new file mode 100644
index 0000000..3bbbfbb
--- /dev/null
+++ b/doc/lfun/QueryAllDoors
@@ -0,0 +1,32 @@
+FUNKTION:
+     mapping QueryAllDoors();
+
+DEFINIERT IN:
+     /obj/doormaster.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Es werden die Zustaende ALLER Tueren im MorgenGrauen ermittelt.
+
+RUECKGABEWERT:
+     Ein Mapping mit den Zustaenden aller Tueren im MorgenGrauen. Als
+     Schluessel dienen die Dateinamen der Start- und Zielraeume in
+     lexikographischer (alphabetischer) Reihenfolge, getrennt durch ":",
+     der Wert des Keys ist der aktuelle Zustand dieser Tuer, z.B.:
+
+    ([ "/d/inseln/schiffe/jolle:/d/inseln/schiffe/jolle/masch" : -1,
+       ...
+     ]);
+
+     Es gibt also eine Tuer zwischen Jolle und Maschinenraum, die
+     momenten geschlossen ist (-1 = D_STATUS_CLOSED).
+
+
+SIEHE AUCH:
+    NewDoor(), QueryDoorKey(), QueryDoorStatus(), SetDoorStatus(),
+    /std/room/doors.c, /obj/doormaster.c, GetPhiolenInfos(), P_DOOR_INFOS
+
+-----------------------------------------------------------------------------
+Letzte Aenderung: Don, 08.05.2014, Gabylon
diff --git a/doc/lfun/QueryArmourByType b/doc/lfun/QueryArmourByType
new file mode 100644
index 0000000..22d43e9
--- /dev/null
+++ b/doc/lfun/QueryArmourByType
@@ -0,0 +1,64 @@
+QyeryArmourByType()
+
+FUNKTION:
+     mixed QueryArmourByType(string type)
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+ARGUMENTE:
+     string type
+        Typ der Ruestung aus /sys/combat.h, auf die getestet werden soll.
+
+BESCHREIBUNG:
+     Abfrage, ob das Lebewesen eine Ruestung des angegebenen Typs traegt.
+
+     Zurueckgegeben wird je nach Tragestatus und <type>:
+     * 0, falls das Lebewesen die gesuchte Ruestungsart nicht traegt
+     * im Erfolgsfall das Ruestungsobjekt
+     * falls <type> AT_MISC ist:
+       * ({}), wenn es keine AT_MISC-Ruestung traegt
+       * ein Array von AT_MISC-Ruestungen
+     * falls <type> 0 ist: ein Mapping, das diese Informationen mit dem
+       Ruestungstypen als Schluessel enthaelt:
+       ([AT_MISC: ({[object], ...}),
+         AT_...: <object>,
+         ... ])
+
+BEMERKUNG:
+     Ist <type> AT_MISC, so wird auf jeden Fall ein Array zurueckgegeben!
+
+BEISPIELE:
+     Wir wollen wissen, ob this_player() Handschuhe traegt:
+
+     if (objectp(this_player()->QueryArmourByType(AT_GLOVE)))
+       ...
+
+
+     Wir bauen einen Tuersteher, der auf AT_MISC-Kleidung achtet:
+
+     if (sizeof(this_player()->QueryArmourByType(AT_MISC)) > 3) {
+       if(this_player()->ReceiveMsg(
+            "Du darfst nicht passieren, Du hast zuviele "
+            "unpassende Dinge an!",
+            MT_LISTEN|MSG_DONT_STORE, MA_TELL,
+            "Der Waechter teilt Dir mit: ")<MSG_DELIVERED && // taub?
+          this_player()->ReceiveMsg(
+            "Der Waechter haelt dich auf.", MT_LOOK)<MSG_DELIVERED) // blind?
+            this_player()->ReceiveMsg(
+              "Jemand haelt dich auf.", MT_FEEL); // nu aber!
+       // Aufhalten!
+     } else this_player()->ReceiveMsg(
+              "Du darfst passieren, viel Spass im Casino!",
+              MT_LISTEN|MSG_DONT_STORE, MA_TELL,
+              "Der Waechter teilt Dir mit: ");
+       // im Erfolgsfall ist es uns egal, wenn es der Spieler nicht
+       // liest: er wird dann eben "wortlos" durchgelassen
+
+SIEHE AUCH:
+     Wear(), WearArmour(), WearClothing(), Unwear(), UnwearArmour(),
+     UnwearClothing(), FilterClothing(),
+     P_ARMOUR_TYPE, P_CLOTHING, P_ARMOURS,
+     /std/living/combat.c
+
+02.02.2016, Gloinson
diff --git a/doc/lfun/QueryArrived b/doc/lfun/QueryArrived
new file mode 100644
index 0000000..33cf887
--- /dev/null
+++ b/doc/lfun/QueryArrived
@@ -0,0 +1,26 @@
+QueryArrived()
+
+FUNKTION:
+     mixed QueryArrived();
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Diese Funktion ermittelt, ob sich der Transporter momentan an einer
+     Haltestelle befindet (und bestiegen oder verlassen werden kann) oder ob
+     er unterwegs ist.
+
+RUeCKGABEWERT:
+     Null, wenn der Transporter unterwegs ist. Liegt der Transporter an
+     einer Haltestelle, so wird der mit AddRoute als name uebergebene String
+     zurueckgegeben.
+
+SIEHE AUCH:
+     AddRoute(), /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:21:47 1996 by Wargon
diff --git a/doc/lfun/QueryArticle b/doc/lfun/QueryArticle
new file mode 100644
index 0000000..0993b3e
--- /dev/null
+++ b/doc/lfun/QueryArticle
@@ -0,0 +1,92 @@
+QueryArticle()
+
+FUNKTION:
+     varargs string QueryArticle(int casus, int dem, int force);
+
+DEFINIERT IN:
+     /std/thing/language.c
+
+ARGUMENTE:
+     casus
+          Der Fall, in dem der Artikel gewuenscht wird.
+          (Konstanten aus /sys/thing/language.h: WER, WEM, WESSEN, WEN.)
+
+     dem
+          Wird ein bestimmter oder ein unbestimmter Artikel verlangt?
+             + dem = 0: Unbestimmter Artikel!
+             + dem = 1: Bestimmter Artikel!
+             + dem = 2: Finde selbst heraus, welcher Artikel passt!
+
+     force
+          Falls ungleich Null, so wird auf jeden Fall ein Artikel
+          zurueckgegeben, trotz P_ARTICLE == 0.
+
+BESCHREIBUNG:
+     Diese Funktion gibt einen zum Geschlecht des Objektes passenden Artikel
+     zurueck, der in den passenden Fall dekliniert wird.
+
+     Das Herausfinden des passenden Artikels bei 'dem' = 2 bezieht sich auf
+     Situationen, in denen mehrere gleichnamige Objekte im selben Environment
+     sind. Man 'nimmt' dann zB nicht "den Stamm" sondern "einen Stamm".
+
+     Ist P_ARTICLE = 0, so wird ein Leerstring zurueckgegeben, es sei denn,
+     man uebergibt in dem Argument 'force' einen Wert ungleich Null.
+
+BEMERKUNGEN:
+     Achtung: bei gueltigem Artikel wird ein Leerzeichen angehaengt!
+
+     Name()/name() nutzen bereits QueryArticle(), wenn P_ARTICLE gesetzt
+     ist. Deshalb muss man sich "Eines Orks" nicht selbst aus dem
+     QueryArticle() und dem Namen zusammenbasteln, wenn mehrere Orks
+     im Raum herumstehen und man eine Nachricht wie:
+       "Du haust den Ork." und folgend
+       "[Des|Eines] Orks Nase schwillt an."
+     haben moechte:
+       "Du haust "+ork->name(WEN, 1)+". "
+       ork->Name(WESSEN, 2)+" Nase schwillt an."
+
+RUeCKGABEWERT:
+     * gewuenschter Artikel als String plus Leerzeichen (!) ODER
+     * Leerstring
+
+BEISPIELE:
+     // "X haut Y auf die Nase. [Der|Die|Das] ist nicht beeindruckt."
+     // Man will:
+     // * auf jeden Fall einen Artikel, auch wenn kein P_ARTICLE gesetzt ist
+     // * nur den bestimmten Artikel
+     send_room(this_object(),
+       pl1->Name(WER)+" haut "+pl2->name(WEM)+" auf die Nase. "+
+       capitalize(pl2->QueryArticle(WER, 1, 1))+"ist nicht beeindruckt.",
+       MT_LOOK|MT_LISTEN, 0, 0, ({pl1, pl2}));
+
+     // "X gibt dir Y. [Er|Sie|Es] prueft [den|die|das] ..."
+     // Man will:
+     // * auf jeden Fall einen Artikel, auch wenn kein P_ARTICLE gesetzt ist
+     // * nur den bestimmten Artikel
+     send_room(this_object(),
+       pl1->Name(WER)+" gibt "+pl2->name(WEM)+" "+obj->name(WER)+". "+
+       capitalize(pl2->QueryPronoun(WER))+" prueft "+
+       ob->QueryArticle(WEN, 1, 1)+"...",
+       MT_LOOK|MT_LISTEN, 0, 0, ({pl1, pl2}));
+
+     // "Dir faellt X auf den Kopf. Du siehst [die|den|das|eine|einen|eines "
+     // "auf dem Boden liegen. [Sie|Er|Es] sieht blutig aus. Aua. Ist das "
+     // "von dir?"
+     // Man will:
+     // * auf jeden Fall einen Artikel, auch wenn kein P_ARTICLE gesetzt ist
+     // * bestimmte/unbestimmte Artikel, wenn bereits gleiche Gegenstaende
+     //   (zB Kokosnuesse) auf dem Boden liegen ...
+     ob->move(environment(), M_NOCHECK); // vorher machen!
+     pl->ReceiveMsg(
+       "Dir faellt "+ob->name(WER, 0)+" auf den Kopf. Du siehst "+
+       ob->QueryArticle(WEN, 2, 1)+" auf dem Boden liegen. "+
+       capitalize(ob->QueryPronoun(WER))+" sieht blutig ...
+
+SIEHE AUCH:
+     Aehnlich:  SuggestArticle(), query_c_article(), query_g_suffix()
+     Sonstiges: QueryOwn(), QueryDu(),
+                QueryPronoun(), QueryPossPronoun()
+                DeclAdj()
+                name()
+
+9. Jun 2016, Gloinson
diff --git a/doc/lfun/QueryAttribute b/doc/lfun/QueryAttribute
new file mode 100644
index 0000000..60a68c9
--- /dev/null
+++ b/doc/lfun/QueryAttribute
@@ -0,0 +1,32 @@
+QueryAttribute()
+FUNKTION:
+     int QueryAttribute(string attr)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     attr       - interessierendes Gesamtattribut
+
+BESCHREIBUNG:
+     Das Attribut samt seiner Offsets (Modifier) wird zurueckgegeben.
+
+RUeCKGABEWERT:
+     Wert des Attributes, bei Spielern nicht groesser als 30.
+
+BEISPIELE:
+     if (this_player()->QueryAttribute(A_CON) > 20)
+       write("Du schaffst es den Berg hoch. Aber nur muehsam.\n");
+
+BENERKUNGEN:
+     Wenn es um Attributabfragen geht, bitte diese Methode verwenden!
+
+SIEHE AUCH:

+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+	SetTimedAttrModifier(), QueryTimedAttrModifier(), 

+	DeleteTimedAttrModifier(),

+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,

+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+----------------------------------------------------------------------------

+Last modified: Tue Jul 27 20:00:20 2004 by Muadib

diff --git a/doc/lfun/QueryAttributeOffset b/doc/lfun/QueryAttributeOffset
new file mode 100644
index 0000000..f938ab8
--- /dev/null
+++ b/doc/lfun/QueryAttributeOffset
@@ -0,0 +1,26 @@
+QueryAttributeOffset()
+FUNKTION:
+     int QueryAttributeOffset(string attr)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     attr	-	gesuchter AttributOffset
+
+BESCHREIBUNG:
+     Die Offsets des Attributs (inklusive Modifier) werden zurueckgegeben.
+
+BEISPIELE:
+     if(this_player()->QueryAttributeOffset(A_STR)<0)
+      write("Du bist geschwaecht.\n");
+
+SIEHE AUCH:

+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+	SetTimedAttrModifier(), QueryTimedAttrModifier(), 

+	DeleteTimedAttrModifier(),

+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,

+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+----------------------------------------------------------------------------

+Last modified: Tue Jul 27 20:00:20 2004 by Muadib

diff --git a/doc/lfun/QueryBuyFact b/doc/lfun/QueryBuyFact
new file mode 100644
index 0000000..435e8be
--- /dev/null
+++ b/doc/lfun/QueryBuyFact
@@ -0,0 +1,22 @@
+QueryBuyFact()
+
+FUNKTION:
+     int QueryBuyFact();
+
+DEFINIERT IN:
+     /std/laden.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Gibt den mit SetBuyFact() gesetzten Faktor zurueck.
+
+RUeCKGABEWERT:
+     Der Einkaufspreismultiplikator.
+
+SIEHE AUCH:
+     SetBuyFact(), /std/laden.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:21:57 1996 by Wargon
diff --git a/doc/lfun/QueryBuyValue b/doc/lfun/QueryBuyValue
new file mode 100644
index 0000000..261a435
--- /dev/null
+++ b/doc/lfun/QueryBuyValue
@@ -0,0 +1,52 @@
+QueryBuyValue()

+

+Funktion:

+    static varargs int QueryBuyValue(mixed ob, object client)

+

+Definiert in:

+    /std/room/shop

+

+Argumente:

+    ob: 

+      Das zu kaufende Objekt (String oder object).

+      Im Normalfall handelt es sich um ein Objekt. Ausnahme sind 

+      Gegenstaende, die mit AddFixedObject() hinzugefuegt wurden.

+    client: 

+      Der Kaeufer.

+

+Beschreibung:

+    Ermittelt den Preis, den <client> fuer <ob> zu bezahlen hat.

+

+Rueckgabewert:

+    Der Preis als Integer.

+

+Beispiel:

+    Ein Haendler, der Spielern die ihm geholfen haben einen Rabatt von 10% 

+    gewaehrt:

+    

+    object *helpers;

+    protected void create()

+    {

+      ::create();

+      helpers=({});

+      ...

+    }

+    

+    static varargs int QueryBuyValue(mixed ob, object client)

+    {

+      if(member(helpers,client)!=-1)

+      {

+        return ::QueryBuyValue(ob,client)*9/10;

+      }

+      return ::QueryBuyValue(ob,client);

+    }

+

+Siehe auch:

+    Funktionen:

+      AddFixedObject(), RemoveFixedObject(), SetStorageRoom(), 

+      QueryStorageRoom(), QueryBuyFact(), sell_obj(), buy_obj()

+    Properties:

+      P_KEEPER, P_MIN_STOCK, P_STORE_CONSUME

+

+------------------------------------------------------------------------------

+Letzte Aenderung: 21.05.2014, Bugfix
\ No newline at end of file
diff --git a/doc/lfun/QueryCoinsPerUnits b/doc/lfun/QueryCoinsPerUnits
new file mode 100644
index 0000000..948c1b0
--- /dev/null
+++ b/doc/lfun/QueryCoinsPerUnits
@@ -0,0 +1,31 @@
+QueryCoinsPerUnit()
+
+FUNKTION:
+     int *QueryCoinsPerUnits();
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Liefert das Wertverhaeltnis fuer die Einheiten zurueck.
+
+RUeCKGABEWERT:
+     Ein Array von zwei Zahlen. Die erste Zahl ist der Wert der in der
+     zweiten Zahl angegebenen Einheiten.
+
+BEISPIELE:
+     Steht im Unit-Objekt folgende Wertzuweisung:
+
+       SetCoinsPerUnits(7,2);
+
+     so liefert QueryCoinsPerUnits() als Ergebnis ({7, 2}).
+
+SIEHE AUCH:
+     SetCoinsPerUnits(), SetGramsPerUnits(), QueryGramsPerUnit(),
+     /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:22:02 1996 by Wargon
diff --git a/doc/lfun/QueryDamage b/doc/lfun/QueryDamage
new file mode 100644
index 0000000..99c4fed
--- /dev/null
+++ b/doc/lfun/QueryDamage
@@ -0,0 +1,39 @@
+QueryDamage()
+
+FUNKTION:
+     int QueryDamage(object enemy);
+
+DEFINIERT IN:
+     /std/weapon/combat.c
+
+ARGUMENTE:
+     enemy
+          Der Gegner, gegen den die Waffe eingesetzt wird.
+
+BESCHREIBUNG:
+     Dies ist die zentrale Funktion der Waffe. Sie wird in jeder Kampfrunde
+     von Attack() aus aufgerufen und gibt den Schaden zurueck, den der
+     Gegner abwehren muss.
+
+     In den Schaden gehen sowohl die Staerke der Waffe als auch die Staerke
+     des Traegers der Waffe ein.
+
+     Wurde eine HitFunc() angegeben, so wird diese mit den gleichen
+     Parametern wie QueryDamage() aufgerufen.
+
+RUeCKGABEWERT:
+     Die Staerke des Schlages fuer diese Kampfrunde. Sie ermittelt sich als
+     Zufallszahl zwischen 0 und einem Wert, der sich aus der Staerke der
+     Waffe und der Staerke ihres Traegers ergibt. Das Ergebnis des
+     HitFunc()-Aufrufs wird zu dieser Zahl hinzugezaehlt.
+
+BEMERKUNGEN:
+     Auch wenn man eine HitFunc() verwendet, darf der Rueckgabewert
+     insgesamt nicht groesser als 200 werden. Im Zweifelsfall sollte 
+     man sich mit der zustaendigen Balance besprechen!
+
+SIEHE AUCH:
+     HitFunc(), Attack(), /std/weapon.c, grenzwerte
+
+----------------------------------------------------------------------------
+Last modified: Fre Feb 16.02.01 12:58:00 von Tilly
diff --git a/doc/lfun/QueryDefend b/doc/lfun/QueryDefend
new file mode 100644
index 0000000..4d3d3e0
--- /dev/null
+++ b/doc/lfun/QueryDefend
@@ -0,0 +1,45 @@
+QueryDefend()
+
+FUNKTION:
+     int QueryDefend(string|string* dtyp, int|mapping spell, object enemy);
+
+DEFINIERT IN:
+     /std/armour/combat.c
+
+ARGUMENTE:
+     dtyp  - Schadenstypen der Angriffsart
+     spell - 0       bei konventionellem Angriff,
+             != 0    bei Angriff mit einem nichtphysischen Spell,
+             mapping bei genaueren Angaben zur Wirkung
+     enemy - Der angreifende Gegner
+
+BESCHREIBUNG:
+     Dies ist die zentrale Funktion einer Ruestung. Sie wird in jeder
+     Kampfrunde aus /std/living/combat::Defend() fuer jede Ruestung aufgerufen,
+     die der Spieler angezogen hat.
+
+     Der Schutzwert von P_AC entfaltet seine Wirkung nur bei konventionellen
+     Angriffen:
+     * wenn 'spell' 0 ist (bei Aufruf aus der Defend heraus ausgeschlossen)
+     * wenn 'spell' ein Mapping mit dem Flag SP_PHYSICAL_ATTACK != 0 UND
+                    in 'dtyp' mindestens ein physischer Schaden enthalten ist
+
+RUeCKGABEWERT:
+     Die Ruestungsstaerke in dieser Kampfrunde. Sie ermittelt sich als
+     Zufallszahl zwischen 0 und P_AC, zuzueglich des Ergebnisses des
+     DefendFunc()-Aufrufs.
+
+BEMERKUNGEN:
+     Auch wenn man eine DefendFunc() benutzt, darf der Rueckgabewert
+     insgesamt nicht groesser werden als der fuer den Ruestungstyp
+     maximal zulaessige!
+
+SIEHE AUCH:
+     Ruestungen: P_ARMOUR_TYPE, P_NR_HANDS, P_ARMOURS, P_WORN
+     Schutz:     P_AC, Defend(), DefendFunc
+     Sonstiges:  P_EQUIP_TIME, P_LAST_USE, P_DAM_TYPE
+     Verwandt:   QueryArmourByType(L), P_WEAPON, FilterClothing(),
+                 FilterArmours()
+     Resistenz:  P_RESISTANCE_STRENGTHS, CheckResistance(L)
+
+28.Jul 2014 Gloinson
diff --git a/doc/lfun/QueryDisguise b/doc/lfun/QueryDisguise
new file mode 100644
index 0000000..c30aa3f
--- /dev/null
+++ b/doc/lfun/QueryDisguise
@@ -0,0 +1,29 @@
+QueryDisguise()
+
+FUNKTION:
+     mixed QueryDisguise();
+
+DEFINIERT IN:
+     ???
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Prueft, ob der Spieler durch einen Shadow (meistens der Tarnhelm) 
+     'manipuliert' ist.
+
+RUeCKGABEWERT:
+     0, wenn dies nicht der Fall ist, ansonsten die Beschreibung des Shadow
+     vom Typ string.
+
+BEMERKUNGEN:
+     In Waffen / Ruestungen u.ae. die P_RESTRICTIONS gesetzt haben,
+     eruebrigt sich eine Abfrage auf QueryDisguise(), da dies bereits im
+     restriction_checker erledigt wird.
+
+SIEHE AUCH:
+     P_RESTRICTIONS, /std/restriction_checker.c
+
+----------------------------------------------------------------------------
+Last modified: Mon Mar 26 14:48:20 2001 von Tilly
diff --git a/doc/lfun/QueryDoorKey b/doc/lfun/QueryDoorKey
new file mode 100644
index 0000000..cfd6a29
--- /dev/null
+++ b/doc/lfun/QueryDoorKey
@@ -0,0 +1,48 @@
+FUNKTION:
+     mixed QueryDoorKey();
+
+DEFINIERT IN:
+     versch. Schluesseln
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Diese Funktion wird in einem Schluessel aufgerufen, wenn man mit diesem
+     eine Tuer auf- oder abschliessen will. Anhand des Rueckgabewertes wird
+     entschieden, ob der Schluessel passt oder nicht.
+
+RUECKGABEWERT:
+     String oder Array von Strings der Raumpfade, deren gemeinsame Tueren
+     sich mit diesem Schluessel auf- bzw. abschliessen lassen. Die Keys sind
+     dabei die Raumpfade, getrennt durch ein ":". Dabei muessen die Pfade
+     in lexikographischer (alphabetischer) Reihenfolge sortiert sein:
+
+     "<name_raum_1>:<name_raum_2>"
+
+BEISPIELE:
+     Ein Schluessel, mit dem sich eine einzige Tuer oeffnen laesst (falls es
+     jemals eine Tuer zwischen Karate- und Abenteurergilde geben sollte...):
+
+     string QueryDoorKey()
+     {
+       return "/gilden/abenteurer:/gilden/karate";
+     }
+
+     Ein Schluessel, der in mehreren Tueren passt:
+
+     string* QueryDoorKey()
+     {
+       return ({ "/gilden/abenteurer:/players/wargon/workroom",
+                 "/gilden/abenteurer:/gilden/karate",
+                 "/players/jof/workroom:/players/wargon/workroom"
+              });
+     }
+
+
+SIEHE AUCH:
+    NewDoor(), QueryDoorStatus(), SetDoorStatus(), P_DOOR_INFOS,
+    /std/room/doors.c, /obj/doormaster.c, GetPhiolenInfos(), QueryAllDoors()
+
+-----------------------------------------------------------------------------
+Letzte Aenderung: Don, 08.05.2014, Gabylon
diff --git a/doc/lfun/QueryDoorStatus b/doc/lfun/QueryDoorStatus
new file mode 100644
index 0000000..c1ee6b8
--- /dev/null
+++ b/doc/lfun/QueryDoorStatus
@@ -0,0 +1,28 @@
+FUNKTION:
+     int QueryDoorStatus(string dest);
+
+DEFINIERT IN:
+     /obj/doormaster.c
+
+ARGUMENTE:
+     <dest> = Zielraum der Tuer.
+
+BESCHREIBUNG:
+     Es wird der Zustand der Tuer, die von diesem Raum nach <dest> fuehrt,
+     ermittelt.
+
+RUeCKGABEWERT:
+     0 bei nicht vorhandene Tuer, ansonsten einer der folgenden Zustaende (aus
+       <doorroom.h>):
+
+       D_STATUS_LOCKED - Tuer abgeschlossen
+       D_STATUS_CLOSED - Tuer geschlossen
+       D_STATUS_OPEN   - Tuer geoeffnet
+
+
+SIEHE AUCH:
+    NewDoor(), QueryDoorKey(), SetDoorStatus(), P_DOOR_INFOS,
+    /std/room/doors.c, /obj/doormaster.c, GetPhiolenInfos(), QueryAllDoors()
+
+-----------------------------------------------------------------------------
+Letzte Aenderung: Don, 08.05.2014, Gabylon
diff --git a/doc/lfun/QueryDu b/doc/lfun/QueryDu
new file mode 100644
index 0000000..9be62a8
--- /dev/null
+++ b/doc/lfun/QueryDu
@@ -0,0 +1,39 @@
+QueryDu()
+
+FUNKTION:
+     varargs string QueryDu(int casus, int gender, int anzahl);
+
+DEFINIERT IN:
+     /std/thing/language.c
+
+ARGUMENTE:
+     casus
+          Der Fall fuer die Anrede.
+
+     gender
+          Das Geschlecht des anzuredenden Objektes.
+
+     anzahl
+          Ist nur ein Objekt anzusprechen oder mehrere?
+
+BESCHREIBUNG:
+     Diese Funktion liefert die dem Anlass entsprechende Anrede fuer ein
+     Objekt.
+
+RUeCKGABEWERT:
+     Ein String mit der Anrede.
+
+BEISPIELE:
+
+     printf("%s setzt %s auf den Boden.\n",
+           capitalize(QueryDu(WER, TP->QueryProp(P_GENDER), SINGULAR),
+           QueryDu(WEN, TP->QueryProp(P_GENDER), SINGULAR));
+
+     (In den meisten Faellen kann man hier auch direkt "Du" und "dich"
+     einsetzen.)
+
+SIEHE AUCH:
+     /std/thing/language.c
+     QueryPossPronoun(), QueryOwn(), QueryPronoun()
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:22:27 1996 by Wargon
diff --git a/doc/lfun/QueryEnemies b/doc/lfun/QueryEnemies
new file mode 100644
index 0000000..7c393b4
--- /dev/null
+++ b/doc/lfun/QueryEnemies
@@ -0,0 +1,33 @@
+FUNKTION:
+	mixed QueryEnemies();
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	keine
+
+RUeCKGABEWERT:
+	Array mit Array aus bekannten Gegnern und Array aus Zeiten
+
+BESCHREIBUNG:
+	Diese Funktion enthaelt ein Array, das zwei Elemente enthaelt, die
+	wiederum Arrays sind:
+	  1. Array: Die bekannten Gegner als Objektpointer.
+	  2. Array: Die zugeordneten Zeiten, wie lange ein Gegner noch als
+	            solcher bekannt sein soll.
+	Im Normalfall wird ein Gegner dann bekannt, wenn man gezielt
+	jemanden atackiert, oder wenn man einen Angriff abwehren muss.
+	Dann wird der Gegner intern abgespeichert, und es wird eine Zeit
+	gesetzt, die dann runtergezaehlt wird. Ist die Zeit auf 0, so wird
+	der Gegner wieder automatisch ausgetragen.
+	(Standardmaessig betraegt diese Zeit 600 Sekunden (300 Heartbeats).)
+	Man kann sich die Gegner auch in Form eines Mappings zurueckgeben
+	lassen. Dies erreicht man mittels der Funktion GetEnemies().
+
+SIEHE AUCH:
+	Kill(), Attack(), Defend(), do_my_heart_beat(), PresentEnemies(),
+	GetEnemies(), SelectEnemy(), QueryPreferedEnemy(), P_PREFERED_ENEMY
+
+----------------------------------------------------------------------------
+29.12.2007, Zesstra
diff --git a/doc/lfun/QueryFlaw b/doc/lfun/QueryFlaw
new file mode 100644
index 0000000..8137d81
--- /dev/null
+++ b/doc/lfun/QueryFlaw
@@ -0,0 +1,41 @@
+QueryFlaw()
+
+FUNKTION:
+     mixed *QueryFlaw();
+
+DEFINIERT IN:
+     /std/armour/combat.c,
+     /std/weapon/combat.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     QueryFlaw() liefert Informationen ueber den Grad der Abnutzung der
+     Waffe bzw. Ruestung. Der Zustand wird als Array mit der Zahl der
+     TakeFlaw()-Aufrufe und dem Datum des ersten TakeFlaw()-Aufrufs
+     zurueckgegeben.
+
+RUeCKGABEWERT:
+     Ein Array mit drei Elementen:
+       1. der aktuelle Zaehlerstand
+       2. Zeit der ersten Benutzung
+       3. die Zeit der ersten Benutzung als String
+
+BEISPIELE:
+     Den aktuellen Abnutzungsgrad einer Ruestung kann man sich wie folgt
+     anzeigen lassen:
+
+     mixed *flaw;
+
+     flaw = ruestung->QueryFlaw();
+
+     printf("Zaehlerstand: %d, erster Schlag: %s\n", flaw[0], flaw[2]);
+     // oder analog:
+     printf("Zaehlerstand: %d, erster Schlag: %s\n", flaw[0], dtime(flaw[1]));
+
+SIEHE AUCH:
+     TakeFlaw(), /std/armour/combat.c, /std/weapon/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:22:32 1996 by Wargon
diff --git a/doc/lfun/QueryGenderString b/doc/lfun/QueryGenderString
new file mode 100644
index 0000000..967a16e
--- /dev/null
+++ b/doc/lfun/QueryGenderString
@@ -0,0 +1,23 @@
+QueryGenderString()
+
+FUNKTION:
+     string QueryGenderString();
+
+DEFINIERT IN:
+     /std/thing/language.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Es wird ein String mit dem Geschlecht des Objektes zurueckgegeben
+     ("maennlich", "weiblich", "saechlich").
+
+RUeCKGABEWERT:
+     Der String mit dem Geschlecht.
+
+SIEHE AUCH:
+     /std/thing/language.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:23:00 1996 by Wargon
diff --git a/doc/lfun/QueryGramsPerUnits b/doc/lfun/QueryGramsPerUnits
new file mode 100644
index 0000000..3549e54
--- /dev/null
+++ b/doc/lfun/QueryGramsPerUnits
@@ -0,0 +1,31 @@
+QueryGramsPerUnits()
+
+FUNKTION:
+     int *QueryGramsPerUnits();
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Liefert das Gewichtsverhaeltnis fuer die Einheiten zurueck.
+
+RUeCKGABEWERT:
+     Ein Array von zwei Zahlen. Die erste Zahl ist das Gewicht der in der
+     zweiten Zahl angegebenen Einheiten.
+
+BEISPIELE:
+     Steht im Unit-Objekt folgende Gewichtszuweisung:
+
+       SetGramsPerUnits(4,1);
+
+     so liefert QueryGramsPerUnits() als Ergebnis ({4, 1}).
+
+SIEHE AUCH:
+     SetCoinsPerUnits(), QueryCoinsPerUnits() SetGramsPerUnits(),
+     /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:22:39 1996 by Wargon
diff --git a/doc/lfun/QueryGroupedKeys b/doc/lfun/QueryGroupedKeys
new file mode 100644
index 0000000..ce7e316
--- /dev/null
+++ b/doc/lfun/QueryGroupedKeys
@@ -0,0 +1,26 @@
+QueryGroupedKeys()
+
+FUNKTION:
+    mixed *QueryGroupedKeys()
+
+DEFINIERT IN:
+    /secure/questmaster.c
+
+ARGUMENTE:
+    keine
+
+RUECKGABEWERT:
+    Array mit Arrays mit den Schluesselwoertern der Quests
+
+BESCHREIBUNG:
+    Diese Funktion liefert ein Array mit mehreren Arrays zurueck, die
+    die Schluesselwoerter der Quests enthalten. Dabei enthaelt das 
+    erste Array die Schluesselwoerter der Quests der ersten Gruppe etc.
+    Das letzte Array enthaelt die Gruppe der optionalen Quests.
+
+SIEHE AUCH:
+    GiveQuest, QueryQuest, /secure/questmaster.h
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: Son, 19. Nov 2000, 13:22:15 von Zook.
+
diff --git a/doc/lfun/QueryGuest b/doc/lfun/QueryGuest
new file mode 100644
index 0000000..cc9971b
--- /dev/null
+++ b/doc/lfun/QueryGuest
@@ -0,0 +1,33 @@
+QueryGuest()
+FUNKTION:
+     int QueryGuest();
+
+DEFINIERT IN:
+     /std/player/base
+
+BESCHREIBUNG:
+     Auf der uid basierende Hilfsfunktion, um Gaeste zu identifizieren.
+
+RUeCKGABEWERT:
+     1, wenn Spielerobjekt ein Gast ist; 0 sonst
+
+BEISPIELE:
+     if(this_interactive()->QueryGuest())
+     {
+       (this_interactive()->ReceiveMsg(
+          "Wir bedienen hier nur ordentliche Charaktere.",
+          MT_LISTEN, MA_SAY,
+          "Der Wirt sagt: ") != MSG_SENSE_BLOCK) ||
+       (this_interactive()->ReceiveMsg(
+          "Der Wirt gestikuliert dich hinaus.",
+          MT_LOOK, MA_LOOK) != MSG_SENSE_BLOCK) ||
+       (this_interactive()->ReceiveMsg(
+          "Irgendwer stupst dich an. Du sollst wohl gehen.",
+          MT_FEEL, MA_FEEL));
+       return 1;
+     }
+
+SIEHE AUCH:
+     getuid()
+
+14. Mai 2015 Gloinson
diff --git a/doc/lfun/QueryHealInfo b/doc/lfun/QueryHealInfo
new file mode 100644
index 0000000..07b7542
--- /dev/null
+++ b/doc/lfun/QueryHealInfo
@@ -0,0 +1,26 @@
+QueryHealInfo()
+
+FUNKTION:
+     string QueryHealInfo();
+
+DEFINIERT IN:
+     /std/corpse.c,
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     QueryHealInfo() liefert einen Standardtext zurueck, der grob Auskunft 
+     darueber gibt, welche Auswirkungen das Essen einer Leiche haette. 
+     Diese Info kann z.B. von Gilden verwendet werden, die P_HEAL (s.dort)
+     einer Leiche nicht selbst auswerten wollen.
+
+RUeCKGABEWERT:
+     Ein nicht umbrochener String. Fuer Zeilenumbrueche kann derjenige,
+     der den Text ausliest, selbst sorgen.
+
+SIEHE AUCH:
+     /std/corpse.c, P_HEAL
+
+----------------------------------------------------------------------------
+Last modified: 31.03.2008, Arathorn
diff --git a/doc/lfun/QueryMaterial b/doc/lfun/QueryMaterial
new file mode 100644
index 0000000..71e3a33
--- /dev/null
+++ b/doc/lfun/QueryMaterial
@@ -0,0 +1,34 @@
+QueryMaterial(L)
+FUNKTION:
+     int QueryMaterial(string mat)
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     string mat -	Material, auf das getestet werden soll
+
+BESCHREIBUNG:
+     Testet, ob ein Gegenstand aus dem angegebenen Material besteht
+     und gibt dessen Anteil zurueck.
+     Die Rueckgabe ist im Wertebereich -100 (Antigruppen) bis +100 (%).
+
+RUECKGABEWERT:
+     Anteil in Prozent.
+
+BEISPIELE:
+     if(ob->QueryMaterial(MAT_IVORY)<=0)
+       write("Daraus kannst Du keine Billiardkugeln schnitzen!\n");
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterialGroup(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/QueryMaterialGroup b/doc/lfun/QueryMaterialGroup
new file mode 100644
index 0000000..c3b6860
--- /dev/null
+++ b/doc/lfun/QueryMaterialGroup
@@ -0,0 +1,50 @@
+QueryMaterialGroup(L)
+FUNKTION:
+     int QueryMaterialGroup(string grp)
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     string grp		- Materialgruppe, auf die getestet werden soll
+
+BESCHREIBUNG:
+     Liefert eine Angabe, zu welchem Anteil das Objekt aus Materialien
+     dieser Gruppe besteht.
+     Die Rueckgabe ist im Wertebereich -100 (Antigruppen) bis +100 (%).
+
+RUECKGABEWERT:
+     Anteil in Prozent.
+
+BEMERKUNGEN:
+     Ruft MaterialGroup() an der MATERIALDB.
+
+BEISPIELE:
+     // kann man damit was anfangen?
+     if(ob->QueryMaterialGroup(MATGROUP_METAL)<50)
+       write("Der Schmied sagt: Daraus kann ich kein Schwert fertigen.\n");
+
+     // verbrennt das Ding?
+     if(ob->QueryMaterialGroup(MATGROUP_INFLAMMABLE)>50) {
+       write(ob->Name(WER)+" geht in Flammen auf.\n");
+       ob->remove();
+     }
+
+     // wie magnetisch ist es denn?
+     if(ob->QueryMaterialGroup(MATGROUP_MAGNETIC)>50)
+      write(break_string(
+       ob->Name(WER)+" flutscht Dir aus der Hand und bleibt am Magneten "
+		     "kleben!",78));
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterial(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/QueryMaxQP b/doc/lfun/QueryMaxQP
new file mode 100644
index 0000000..9fa0f5a
--- /dev/null
+++ b/doc/lfun/QueryMaxQP
@@ -0,0 +1,27 @@
+QueryMaxQP()
+
+FUNKTION:
+    int QueryMaxQP()
+
+DEFINIERT IN:
+    /secure/questmaster.c
+
+ARGUMENTE:
+    keine
+
+RUECKGABEWERT:
+    Abenteuerpunkte der Pflichtquests
+
+BESCHREIBUNG:
+    Diese Funktion liefert die Abenteuerpunkte der als Pflichtquest
+    eingetragenen Abenteuer zurueck. Pflichtquest bedeutet entweder,
+    dass die Quest zwingend geloest werden muss oder dass sie zu
+    der 80%-Regel gehoert.
+
+SIEHE AUCH:
+    GiveQuest, QueryQuest, /secure/questmaster.h, QueryGroupedKeys,
+    QueryOptQP, QueryTotalQP
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: Sam, 25. Nov 2000, 14:04:28 von Zook.
+
diff --git a/doc/lfun/QueryMoney b/doc/lfun/QueryMoney
new file mode 100644
index 0000000..899b50e
--- /dev/null
+++ b/doc/lfun/QueryMoney
@@ -0,0 +1,28 @@
+QueryMoney()
+FUNKTION:
+     int QueryMoney()
+
+DEFINIERT IN:
+     /std/player/moneyhandler.c
+
+BESCHREIBUNG:
+     Testet, ob ein Spieler, Objekt, Raum oder Npc ueber eine definierte 
+     Geldmenge verfuegt, oder nicht.
+
+RUECKGABEWERT:
+     Geldmenge im Besitz des abgefragten Spielers
+
+BEISPIELE:
+     int i;
+     i=50+random(10);
+     if(!this_player()->QueryMoney())
+       write("Du besitzt keine Muenzen!\n");
+     if(this_player()->QueryMoney() < i)
+       write("Du besitzt nicht die erforderlichen "+i+" Muenzen.\n");
+
+SIEHE AUCH:
+     Geldhandling:	AddMoney(L)
+     Zentralbank:	PayIn(L), WithDraw(L), _query_current_money(L)
+     Sonstiges:		/items/money.c
+
+Last modified: Die,  1. Aug 2000, 16:39:06 by Tilly
diff --git a/doc/lfun/QueryName b/doc/lfun/QueryName
new file mode 100644
index 0000000..d26cd1a
--- /dev/null
+++ b/doc/lfun/QueryName
@@ -0,0 +1,24 @@
+QueryName()
+
+FUNKTION:
+     mixed QueryName();
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     DIESE FUNKTION SOLLTE NICHT MEHR BENUTZT WERDEN!
+     Es wird der Inhalt der Property P_NAME zuueckgegeben; dies laesst sich
+     jedoch genau so gut mit QueryProp(P_NAME) bewerkstelligen!
+
+RUeCKGABEWERT:
+     String oder Array von Strings mit dem Namen des Objektes.
+
+SIEHE AUCH:
+     QueryProp(), Name(), name(), /std/thing/description.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Aug  3 11:21:05 2002 by Vanion
diff --git a/doc/lfun/QueryOpenMiniQuestsForPlayer b/doc/lfun/QueryOpenMiniQuestsForPlayer
new file mode 100644
index 0000000..40246ae
--- /dev/null
+++ b/doc/lfun/QueryOpenMiniQuestsForPlayer
@@ -0,0 +1,54 @@
+FUNKTION:
+    mapping QueryOpenMiniQuestsForPlayer(object player)
+
+DEFINIERT IN:
+    /secure/questmaster
+
+BESCHREIBUNG:
+    Diese Funktion gibt die Liste der offenen Miniquests des Spielers als
+    Mapping zurueck.
+
+ARGUMENTE:
+    player - das interessierende Spielerobjekt
+
+RUECKGABEWERTE:
+    Mapping mit der Liste der Miniquests, fuer die das abfragende Objekt
+    zustaendig ist, oder leeres Mapping, wenn der Spieler keine MQs mehr
+    offen hat.
+
+    Die Liste enthaelt die Miniquestnummer als Key. Diesem sind zwei Werte
+    zugeordnet: zum einen ein Miniquest-Aufgabentext, und zum anderen -
+    falls der Spieler eine der Vorbedingungen fuer die Miniquest nicht
+    erfuellt - ein Hinweistext, der Auskunft gibt, welche Bedingung noch
+    zu erfuellen ist ("Seherstatus fehlt"). Diese Hinweistexte entsprechen
+    denen aus check_restrictions() in /std/restriction_checker.c. Der 
+    jeweils andere Text wird auf 0 gesetzt.
+
+    Die Struktur des Mappings ist daher folgende:
+      ([ MQ-Nummer : <Aufgabenstellung> ; <Hinderungsgrund> ])
+    
+    Beispiel: ein Spieler hat die Miniquests 18 und 49 noch nicht geloest,
+    erfuellt aber nur fuer Miniquest 49 die Anforderungen. Miniquest 18
+    erfordert den Seherstatus. Dann saehe das Mapping so aus:
+      ([ 18 : 0                    ; "Dazu musst Du erst Seher werden.\n",
+         49 : "Aufgabentext_zu_49" ; 0 ])
+
+    Jedes abfragende Objekt muss daher dieses Mapping zunaecht geeignet
+    auf seinen Inhalt pruefen, um zu ermitteln, welche Meldung jeweils
+    auszugeben ist.
+
+BEMERKUNGEN:
+    Das abfragende Objekt muss von einem Erzmagier oder Gott (z.B. dem
+    zustaendigen Quest-EM) im Questmaster als zugriffsberechtigt bei den-
+    jenigen Miniquests eingetragen sein, fuer die es die entsprechenden
+    Miniquest-Hinweise ausgeben darf. Diese Berechtigung ist mit dem 
+    Quest-EM abzustimmen. Anderen Objekten wird ein leeres Mapping zurueck-
+    gegeben.
+
+SIEHE AUCH:
+    AddMiniQuest(L), ChangeMiniQuest(L)
+    P_RESTRICTIONS
+    erzmagier
+
+----------------------------------------------------------------------------
+Last modified: 6. Juni 2014, Arathorn.
diff --git a/doc/lfun/QueryOwn b/doc/lfun/QueryOwn
new file mode 100644
index 0000000..b1a55f6
--- /dev/null
+++ b/doc/lfun/QueryOwn
@@ -0,0 +1,32 @@
+QueryOwn()
+
+FUNKTION:
+     varargs string QueryOwn(int casus)
+
+DEFINIERT IN:
+     /std/thing/language.c
+
+ARGUMENTE:
+     casus
+          Der Fall fuer die Anrede.
+
+BESCHREIBUNG:
+     Diese Funktion liefert das dem Anlass entsprechende Possessiv-
+     pronomen fuer den Spieler selber (Dein/Deine).
+
+RUeCKGABEWERT:
+     Ein String mit dem Pronomen.
+
+BEISPIELE:
+
+     printf("%s %s loest sich auf.\n",
+           capitalize(obj->QueryOwn(WER)),obj->name(WER));
+
+     (In den meisten Faellen kann man hier auch direkt "Dein" oder "Deine"
+      einsetzen.)
+
+SIEHE AUCH:
+     /std/thing/language.c
+
+----------------------------------------------------------------------------
+Last modified: Sun Aug 10 23:55:27 2003 by Mandragon
diff --git a/doc/lfun/QueryPassengers b/doc/lfun/QueryPassengers
new file mode 100644
index 0000000..a71af67
--- /dev/null
+++ b/doc/lfun/QueryPassengers
@@ -0,0 +1,29 @@
+QueryPassengers()
+
+FUNKTION:
+     object *QueryPassengers();
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Diese Funktion ermittelt die momentan auf dem Transporter befindlichen
+     Passagiere.
+
+RUeCKGABEWERT:
+     Array von Objekten mit den Passagieren.
+
+BEMERKUNGEN:
+     Es werden nur die Passagiere zurueckgegeben, die sich in dem
+     eigentlichen Transporterobjekt befinden! Wenn der Transporter noch um
+     zusaetzliche Raeume vergroessert wird, werden unter Umstaenden nicht
+     alle Passagiere erfasst!
+
+SIEHE AUCH:
+     /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:22:48 1996 by Wargon
diff --git a/doc/lfun/QueryPosition b/doc/lfun/QueryPosition
new file mode 100644
index 0000000..4d5179d
--- /dev/null
+++ b/doc/lfun/QueryPosition
@@ -0,0 +1,29 @@
+QueryPosition()
+
+FUNKTION:
+     string *QueryPosition();
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Es wird ein Array von zwei Strings mit Kennzeichnern der letzten (oder
+     aktuellen) und der naechsten Station im Fahrplan zurueckgegeben.
+
+     Die Kennzeichner sind dabei die ersten Argumente der entsprechenden
+     AddXXX()-Aufrufen, also der Name der Haltestelle bei AddRoute, der Text
+     der Meldung bei AddMsg() und der Name der Funktion bei AddFun().
+
+RUeCKGABEWERT:
+     Array mit zwei Strings. Der erste String gibt den Kennzeichner der
+     momentanen Fahrplanstation an, der zweite String den Kennzeichner der
+     naechsten Fahrplanstation.
+
+SIEHE AUCH:
+     AddRoute(), AddMsg(), AddFun(), /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:22:52 1996 by Wargon
diff --git a/doc/lfun/QueryPossPronoun b/doc/lfun/QueryPossPronoun
new file mode 100644
index 0000000..c3f4106
--- /dev/null
+++ b/doc/lfun/QueryPossPronoun
@@ -0,0 +1,48 @@
+QueryPossPronoun()
+
+FUNKTION:
+     varargs string QueryPossPronoun(mixed what, int casus, int anzahl);
+
+DEFINIERT IN:
+     /std/thing/language.c
+
+ARGUMENTE:
+     what
+          Geschlecht des Objektes, das besessen wird, oder das Objekt
+          selbst.
+
+     casus
+          Der Fall, in dem das Objekt besessen wird.
+
+     anzahl
+          Handelt es sich um nur ein Objekt oder um mehrere?
+
+BESCHREIBUNG:
+     Diese Funktion gibt ein Possessivpronomen zurueck, das das
+     Besitzverhaeltnis eines Objektes zu diesem Objekt anzeigt.
+
+RUeCKGABEWERT:
+     Das Possessivpronomen im entsprechenden Fall.
+
+BEMERKUNGEN:
+     what und casus beziehen sich auf das Objekt, welches besessen wird, und
+     nicht auf den Besitzer!!!
+
+BEISPIELE:
+     Um eine korrekte Ausgabe beim Haendeklatschen zu erreichen, koennte man
+     zB. folgende Zeile verwenden:
+
+      printf("%s klatscht in %s Haende.\n",this_player()->name(WER),
+           this_player()->QueryPossPronoun(FEMALE, WEN, PLURAL));
+
+     FEMALE, da "die Hand" weiblich ist, WEN, da man im Akkusativ klatscht,
+     und PLURAL, da man dazu beide Haende braucht.
+
+     Ein beliebter Fehler ist es, als Fall WESSEN zu verwenden (in WESSEN
+     Haende klatscht man? => in seine).
+     Die richtige Frage waere aber: WEN klatscht man? (in die Haende)
+
+SIEHE AUCH:
+     QueryOwn(), QueryPronoun(), /std/thing/language.c
+----------------------------------------------------------------------------
+Last modified: Wed Jan 11 13:13:35 CET 2006 by Rumata
diff --git a/doc/lfun/QueryPrayRoom b/doc/lfun/QueryPrayRoom
new file mode 100644
index 0000000..0a097d3
--- /dev/null
+++ b/doc/lfun/QueryPrayRoom
@@ -0,0 +1,33 @@
+QueryPrayRoom()
+
+FUNKTION:
+     public string QueryPrayRoom()
+
+DEFINIERT IN:
+     /std/player/base.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+    Dies ist der Raum, in den der Spieler nach dem Ende der Todessequenz
+    bewegt wird, d.h. ein Raum, wo er beten kann, um einen neuen Koerper zu
+    erhalten.
+    Der Raum wird als String angegeben (kein Objekt).
+
+    Jede Rasse hat einen Default fuer diese Funktion, welcher mit
+    SetDefaultPrayRoom() gesetzt wird. Dieser Default kann mit der Property
+    P_PRAY_ROOM ueberlagert werden. Wird die Property auf 0 dgesetzt, wird
+    dieser Default aktiv.
+
+RUeCKGABEWERT:
+    Der Objektname des Betraums (string)
+
+
+SIEHE AUCH:
+     P_PRAY_ROOM
+     SetDefaultPrayRoom
+
+----------------------------------------------------------------------------
+21.05.2013, Zesstra
+
diff --git a/doc/lfun/QueryPreferedEnemy b/doc/lfun/QueryPreferedEnemy
new file mode 100644
index 0000000..267d27d
--- /dev/null
+++ b/doc/lfun/QueryPreferedEnemy
@@ -0,0 +1,35 @@
+FUNKTION:
+	object QueryPreferedEnemy();
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	keine
+
+RUeCKGABEWERT:
+	bevorzugter Gegner
+
+BESCHREIBUNG:
+	Diese Funktion liefert unter folgenden Bedingungen zufaellig eines
+	der Lebewesen als bevorzugten Gegner zurueck, welche in der
+	Property P_PREFERED_ENEMY in einem Array eingetragen sind:
+	  (1) Der erste Eintrag des erwaehnten Propertyarrays enthaelt
+	      einen Wert zwischen 0 und 100, der die Wahrscheinlichkeit
+	      dafuer angibt, dass ein Lebewesen als Gegner bevorzugt werden
+	      soll. Es wird also nicht immer bevorzugt, wenn dort ein Wert
+	      kleiner 100 steht! In diesem Fall wird eine 0 zurueckgegeben.
+	  (2) Das per Zufall aus den Arrayelementen ab Element 2 gewaehlte
+	      Lebewesen muss auch wirklich existieren. Ist dies nicht der
+	      Fall, wird das nunmehr leere Element aus dem Array entfernt
+	      und eine 0 zurueckgeliefert.
+	  (3) Das Lebewesen muss derzeit auch wirklich Feind sein! Ist dies
+	      nicht der Fall, wird eine 0 zurueckgegeben.
+	Will man eine andere Bevorzugung von Gegnern erreichen,
+	ueberschreibt man am besten diese Funktion.
+
+SIEHE AUCH:
+	SelectEnemy(), IsEnemy(), P_PREFERED_ENEMY
+
+----------------------------------------------------------------------------
+Last modified: Wed May 26 16:47:51 1999 by Patryn
diff --git a/doc/lfun/QueryPronoun b/doc/lfun/QueryPronoun
new file mode 100644
index 0000000..fd041cb
--- /dev/null
+++ b/doc/lfun/QueryPronoun
@@ -0,0 +1,32 @@
+QueryPronoun()
+
+FUNKTION:
+     string QueryPronoun(int casus);
+
+DEFINIERT IN:
+     /std/thing/language.c
+
+ARGUMENTE:
+     casus
+          Der Fall, in dem das Personalpronomen verlangt wird.
+
+BESCHREIBUNG:
+     Es wird ein Personalpronomen ("er", "sie", "es") im entsprechenden Fall
+     fuer dieses Objekt berechnet.
+
+RUeCKGABEWERT:
+     Das Pronomen im entsprechenden Fall.
+
+BEISPIELE:
+
+     printf("Du versucht, %s zu nehmen, aber %s ist zu schwer.\n",
+           ob->name(WEN), ob->QueryPronoun(WER));
+
+     Hier wird immer das richtige Pronomen verwendet, egal, welches
+     Geschlecht das Objekt ob hat.
+
+SIEHE AUCH:
+     SuggestArticle(), QueryPossPronoun(), /std/thing/language.c
+     QueryOwn()
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:23:14 1996 by Wargon
diff --git a/doc/lfun/QueryProp b/doc/lfun/QueryProp
new file mode 100644
index 0000000..ee752e0
--- /dev/null
+++ b/doc/lfun/QueryProp
@@ -0,0 +1,39 @@
+QueryProp()
+FUNKTION:
+     mixed QueryProp(string name);
+
+DEFINIERT IN:
+     /std/thing/properties.c
+
+ARGUMENTE:
+     string name	- abzufragende Property
+
+BESCHREIBUNG:
+     Der Datenwert der Property 'name' wird zurueckgegeben.
+
+     Existiert eine F_QUERY_METHOD oder eine _query_'name'()-Methode fuer
+     diese Property, so wird diese aufgerufen und ihr 'Value' uebergeben.
+     Eine F_QUERY_METHOD hat dabei Vorrang vor _query_'name'(), d.h.
+     _query_'name'() wird nach erfolgreicher F_QUERY_METHOD nicht mehr
+     gerufen.
+
+     (Diese Methoden nutzen dann Set(), um auf den Datenwert der Property
+      'name' zurueckzugreifen. Teilweise werden aber auch interne Variablen
+      so oeffentlich gemacht und sind nicht in der ueber Set/Query
+      verfuegbaren Property 'name' abgelegt.)
+
+RUeCKGABEWERT:
+     Der Datenwert der Property.
+     0, falls diese nicht existiert.
+
+BEISPIELE:
+     // wie hoch sind die aktuelle LP des Spielers?
+     hp = this_player()->QueryProp(P_HP);
+
+SIEHE AUCH:
+     Aehnliches:	SetProp(L), Set(L), Query(L)
+     Generell:		SetProperties(L), QueryProperties(L)
+     Konzept:		properties, /std/thing/properties.c
+     Sonstiges:		P_AUTOLOADOBJ
+
+15.Dez 2004 Gloinson
diff --git a/doc/lfun/QueryProperties b/doc/lfun/QueryProperties
new file mode 100644
index 0000000..aa740b5
--- /dev/null
+++ b/doc/lfun/QueryProperties
@@ -0,0 +1,30 @@
+QueryProperties()
+FUNKTION:
+     mapping QueryProperties()
+
+DEFINIERT IN:
+     /std/thing/properties.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Diese Funktion liefert ein Mapping mit allen fuer das Objekt
+     definierten Properties zurueck.
+
+RUeCKGABEWERT:
+     Ein Mapping mit den Properties. Das Mapping hat folgenden Aufbau:
+	([ name: wert; flags; set_method; query_method,
+	   name2: ... ]);
+
+BEMERKUNGEN:
+     - diese Funktion wird von restore_object() und save_object()
+     - F_QUERY_METHODs und _query_'prop'()-Methoden haben keine Auswirkung
+       auf die Wertefelder!
+
+SIEHE AUCH:
+     Aehnliches:	SetProp(L), QueryProp(L), Set(L), Query(L)
+     Generell:		SetProperties(L) 
+     Konzept:		properties, /std/thing/properties.c
+
+1.Mai 2004 Gloinson
diff --git a/doc/lfun/QueryQuest b/doc/lfun/QueryQuest
new file mode 100644
index 0000000..295ad16
--- /dev/null
+++ b/doc/lfun/QueryQuest
@@ -0,0 +1,34 @@
+QueryQuest()
+
+FUNKTION:
+        int QueryQuest(string questname)
+
+DEFINIERT IN:
+        /std/player/quests.c
+
+ARGUMENTE:
+        questname
+          Questname, wie er im Questmaster eingetragen wurde.
+
+RUeCKGABEWERT:
+        (Die Defines fuer den Rueckgabewert finden sich in 
+         /secure/questmaster.h)
+         1 : Spieler hat die Quest bereits geloest  (OK)
+         0 : Ungueltiger Questname oder der Spieler
+             hat die Quest noch nicht.              (QQ_KEY_INVALID)
+         2 : Gaeste koennen keine Quest loesen      (QQ_QUEST)
+
+BESCHREIBUNG:
+	Mit dieser Funktion kann getestet werden, ob ein Spieler eine 
+        bestimmte Quest bereits geloest hat. Als Questname wird dazu
+        der Name angegeben, der im Questmaster eingetragen wurde.
+
+        Wer sich da nicht sicher ist, kann mit dem Questtool 
+        (/obj/tools/questtool) nachsehen. 
+
+SIEHE AUCH:
+        /secure/questmaster.h, /obj/tools/questtool
+        GiveQuest
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: Mon, 17. Jul 2000, 12:16:41 von Zook.
diff --git a/doc/lfun/QueryQuestTime b/doc/lfun/QueryQuestTime
new file mode 100644
index 0000000..2410d6a
--- /dev/null
+++ b/doc/lfun/QueryQuestTime
@@ -0,0 +1,29 @@
+QueryQuestTime()
+
+FUNKTION:
+        int QueryQuestTime(string questname)
+
+DEFINIERT IN:
+        /std/player/quests.c
+
+ARGUMENTE:
+        questname
+          Questname, wie er im Questmaster eingetragen wurde.
+
+RUeCKGABEWERT:
+        Questzeitpunkt in Sekunden seit Epoch als positiver Integer-Wert
+         0 : Tagebuchmaster hat keine Daten in den Logfiles gefunden und
+             macht das auf diese Weise kenntlich
+        -1 : Questzeitpunkt unbekannt
+
+BESCHREIBUNG:
+        Mit dieser Funktion kann der Zeitpunkt abgefragt werden, zu
+        dem ein Spieler eine bestimmte Quest geloest hat. 
+        Als Questname wird dazu der Name angegeben, der im Questmaster 
+        eingetragen ist.
+
+SIEHE AUCH:
+        GiveQuest(L), QueryQuest(L), ModifyQuestTime(L)
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: 19. Dez. 2015, Arathorn
diff --git a/doc/lfun/QueryRealAttribute b/doc/lfun/QueryRealAttribute
new file mode 100644
index 0000000..7ee9f83
--- /dev/null
+++ b/doc/lfun/QueryRealAttribute
@@ -0,0 +1,26 @@
+QueryRealAttribute()
+FUNKTION:
+     int QueryRealAttribute(string attr)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     attr       -       das interessierende Attribut
+
+BESCHREIBUNG:
+     Das reale Attribut (ohne Offsets) wird zurueckgegeben.
+
+BEISPIELE:
+     if(this_player()->QueryRealAttribute(A_INT)>15)
+      write("Du bist auch so ganz schoen clever.\n");
+
+SIEHE AUCH:

+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+	SetTimedAttrModifier(), QueryTimedAttrModifier(), 

+	DeleteTimedAttrModifier(),

+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,

+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+----------------------------------------------------------------------------

+Last modified: Tue Jul 27 20:00:20 2004 by Muadib

diff --git a/doc/lfun/QuerySellValue b/doc/lfun/QuerySellValue
new file mode 100644
index 0000000..544cb29
--- /dev/null
+++ b/doc/lfun/QuerySellValue
@@ -0,0 +1,43 @@
+FUNKTION:
+
+      varargs int QuerySellValue(object ob, object client);
+
+DEFINIERT IN:
+
+      /std/trading_price.c
+
+BESCHREIBUNG:
+
+      Diese Funktion kann dazu genutzt werden, den Verkaufspreis in einem 
+      Laden global zu veraendern. Sofern dies zugunsten der Spieler geschieht,
+      muss dafuer die Zustimmung des zustaendigen Regionsmagiers und der
+      Balance eingeholt werden. Zudem sollte es nicht in jedem x-beliebigen 
+      Laden genutzt werden, sondern nur in recht abgelegenen Gebieten, in
+      die man nicht einfach skripten kann.
+
+      Ein Beispiel ist der Laden auf dem Kutter in Port Vain, der nur in
+      laengeren Intervallen mal zugaenglich ist.
+
+BEISPIEL:
+
+      Ein Laden zahlt 10% ueber dem normalen Verkaufspreis:
+
+      private int sell_factor = 110;
+
+      varargs int QuerySellValue(object ob, object client) {
+        // Es wird nicht naeher geprueft, ob <ob> ein gueltiger Objektpointer
+        // ist, da der Laden selbst sicherstellt, dass das so ist. Wenn 
+        // das doch einmal nicht der Fall sein sollte, liegt der Fehler
+        // woanders. Einen Bug auszuloesen ist dann sinnvoll.
+
+        // Basispreis ermitteln 
+        int preis = ::QuerySellValue(ob, client);
+        // und den Bonus aufschlagen.
+        preis = (sell_factor * preis)/100; 
+
+        // Nicht mehr auszahlen, als das Objekt an sich wert ist.
+        return min(preis, ob->QueryProp(P_VALUE));
+      }
+
+----------------------------------------------------------------------------
+LETZTE AENDERUNG: 18-Jun-2015, Arathorn
diff --git a/doc/lfun/QuerySkill b/doc/lfun/QuerySkill
new file mode 100644
index 0000000..017b9f9
--- /dev/null
+++ b/doc/lfun/QuerySkill
@@ -0,0 +1,35 @@
+QuerySkill()
+FUNKTION:
+    public varargs mapping QuerySkill(string sname, string gilde)
+
+DEFINIERT IN:
+    /std/living/skills.c
+    
+ARGUMENTE:
+    string sname    Name des abzufragenden Skill
+    string gilde    Name der Gilde, unter der der Skill gesucht werden soll
+
+BESCHREIBUNG:
+    Diese Funktion liefert das Skillmappings des Skills 'snme' im Lebewesen
+    zurueck. Diese enthaelt Eintraege, die in der Man-Page skill_info_liste
+    beschrieben sind.
+
+    Falls 'gilde' nicht angegeben wird, wird der Skill zuerst fuer die Gilde
+    P_GUILD des Lebewesens gesucht, ansonsten in den allgemeinen Skills
+    "ANY" (es wird NICHT in Gildenobjekt oder Spellbook etwas abgefragt).
+
+RUECKGABEWERT:
+    Ein Mapping mit Skillinfos oder 0, falls der Skill nicht vorhanden ist.
+    Das Mapping ist eine Kopie.
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+
+5. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/QuerySkillAbility b/doc/lfun/QuerySkillAbility
new file mode 100644
index 0000000..5cfd815
--- /dev/null
+++ b/doc/lfun/QuerySkillAbility
@@ -0,0 +1,29 @@
+QuerySkillAbility()
+FUNKTION:
+    public varargs int QuerySkillAbility(string sname, string gilde)
+
+DEFINIERT IN:
+    /std/living/skills.c
+    
+ARGUMENTE:
+    string sname        Name des abzufragenden Skill
+    string gilde         Gilde, unter der der Skill gesucht werden soll
+
+BESCHREIBUNG:
+    Diese Funktion liefert einen Wert zurueck, der aussagt, wie gut das
+    Lebewesen den Skill 'sname' beherrscht (Key SI_SKILLABILITY im
+    Skillmapping).
+    Dieser Wert kann zwischen -MAX_ABILITY und MAX_ABILITY liegen,
+    normal ist 0 bis MAX_ABILITY (10000 - Skill perfektioniert).
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+
+5. Okt 2011 Gloinson
diff --git a/doc/lfun/QuerySkillAttribute b/doc/lfun/QuerySkillAttribute
new file mode 100644
index 0000000..d0b1bd1
--- /dev/null
+++ b/doc/lfun/QuerySkillAttribute
@@ -0,0 +1,58 @@
+QuerySkillAttribute()
+FUNKTION:
+    public int QuerySkillAttribute(string atrname)
+
+DEFINIERT IN:
+    /std/living/skill_attributes.c
+    
+ARGUMENTE:
+    string atrname            Name des abzufragenden Attributs
+    
+BESCHREIBUNG:
+    Mit dieser Funktion kann man den Wert bestimmter Attribute
+    abfragen, dabei werden das abgefragte Attribut, Todesfolgen,
+    SA_QUALITY und Werte in P_SKILL_ATTRIBUTE_OFFSETS
+    beruecksichtigt.
+    
+    Momentane Skills siehe ModifySkillAttribute.
+
+RUECKGABEWERT:
+    Der Wert des Attributs. Ist nichts bestimmtes gesetzt, wird
+    der Standardwert 100 zurueckgegeben.
+    Der Rueckgabewert liegt zwischen 10 bis 1000 (Prozent).
+    
+BEMERKUNG:
+    Die Funktion ist zwar als 'varargs' definiert, gibt man allerdings
+    keinen Attributnamen an, wird immer 100 zurueckgegeben.
+    
+BEISPIEL:
+    // ein Spieler kann ein Stueck Kaese stibitzen, wenn er schnell
+    // genug ist ... (15% ueber normal)
+    if(this_player()->QuerySkillAttribute(SA_SPEED)>=115) {
+      tell_object(this_player(),
+        "Du schnappst das Stueck Kaese aus der Falle.\n");
+      obj kaese = clone_object(...);
+      [...]
+    } else {
+      mapping amap=map_indices(VALID_ARMOUR_CLASS,#'!);
+      amap[AT_GLOVE]=100;
+      tell_object(this_player(),
+        "Du bist zu langsam und die Falle schnappt hungrig zu.\n");
+      this_player()->Defend(random(100),
+                           ({DT_PIERCE, DT_SQUEEZE}),
+                           ([SP_PHYSICAL_ATTACK: 1,
+                             SP_REDUCE_ARMOUR: amap,
+                             SP_SHOW_DAMAGE: 0]));
+    }
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+
+5. Okt 2011 Gloinson
diff --git a/doc/lfun/QuerySkillAttributeModifier b/doc/lfun/QuerySkillAttributeModifier
new file mode 100644
index 0000000..507c51b
--- /dev/null
+++ b/doc/lfun/QuerySkillAttributeModifier
@@ -0,0 +1,90 @@
+QuerySkillAttributeModifier()
+FUNKTION:
+    public varargs mapping QuerySkillAttributeModifier(object caster, 
+                                                    string *atrnames)
+
+DEFINIERT IN:
+    /std/living/skill_attributes.c
+
+ARGUMENTE:
+    <caster>    object
+                Objekt, welches die gesuchten Mods gesetzt hat
+
+    <atrnames>  string*
+                Array von Skill-Attributen, welche durchsucht werden sollen.
+
+BESCHREIBUNG:
+    Diese Funktion liefert alle Mods von <caster> auf den Skill-
+    Attributen <atrnames> in einem Mapping zurueck.
+    Wird <atrnames> nicht angegeben oder ist ein leeres Array, werden alle
+    Skill-Attribute nach Mods abgesucht.
+    Wird <caster> nicht angeben oder ist 0, so werden alle Mods der 
+    gewuenschten Skill-Attribute geliefert.
+    Dementsprechend bekommt man alle Mods aller Skill-Attribute, wenn keins
+    von beidem angegeben wird.
+
+RUECKGABEWERT:
+    ([]), falls keine Modifikatoren gefunden wurden.
+    In anderen Faellen ist die Datenstruktur des Mappings wie folgt:
+    ([ atrname1: ([ <caster>: <value>; <duration> ]),
+       atrname2: ([ <caster>: <value>; <duration> ]) ])
+    Die Schluessel im Mapping sind die jeweiligen Skill-Attribute, die Werte
+    des Mappings sind erneut Mappings, welche als Schluessel die Objekte
+    haben, welche die Mods gesetzt haben. In diesem Mapping gehoeren zu jedem
+    Schluessel zwei Werte, den Wert des Modifikators und die Ablaufzeit.
+    <value> kann hierbei ein int oder eine closure sein, <duration> ist ein
+    int, <caster> ist ein Objekt.
+    Ggf. kann das innere Mapping natuerlich auch mehrere Modifikatoren
+    enthalten (also caster1, caster2, usw.).
+
+BEMERKUNGEN:
+
+BEISPIELE:
+     Ein Objekt moechte seinen bestehenden Modifikator um 20 und die
+     Gueltigkeit um 13 erhoehen.
+     mapping res = ob->QuerySkillAttributeModifier(this_object(),
+                                                  ({SA_DAMAGE}) );
+     if (member(res, SA_DAMAGE) && member(res[SA_DAMAGE], this_object())) {
+          // alten Mod ueberschreiben und Werte dabei anheben.
+          ob->ModifySkillAttributeModifier(SA_DAMAGE,
+              res[SA_DAMAGE][this_object(),0] + 20,
+              res[SA_DAMAGE][this_object(),1] + 13 );
+     }
+     else
+          // neuen Mod setzen.
+          ob->ModifySkilAttributeModifier(SA_DAMAGE, 20, 13);
+      
+     Ein Objekt hat den Fluch der unpraezisen Schnelligkeit, welcher SA_DAMAGE
+     reduziert, sofern das Lebewesen einen positiven Modifikator auf SA_SPEED
+     hat:
+     mapping res = ob->QuerySkillAttributeModifier(0, ({SA_SPEED}) );
+     if (member(res, SA_SPEED) {
+         int val, int dur;
+         foreach(object caster, int v, int d: res[SA_SPEED]) {
+             // groessten Mod rausfinden, dabei keine closures
+             // beruecksichtigen.
+             if (intp(v) && v>val) {
+                 val=v;
+                 dur=d;
+             }
+         }
+         if (val > 0) {
+             // pos. Mod auf SA_SPEED gefunden, entsprechenden neg. Mod auf
+             // SA_DAMAGE setzen, der zum gleichen Zeitpunkt ungueltig wird
+             // wie der Mod auf SA_SPEED.
+             if (ob->ModifySkillAttribute(SA_DAMAGE, -val, dur) == SA_MOD_OK)
+                tell_object(ob, "tolle Fluchmeldung.");
+         }
+     }
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+
+14.08.2008, Zesstra
diff --git a/doc/lfun/QuerySkillBonus b/doc/lfun/QuerySkillBonus
new file mode 100644
index 0000000..1a4ef47
--- /dev/null
+++ b/doc/lfun/QuerySkillBonus
@@ -0,0 +1,65 @@
+QuerySkillBonus()
+
+FUNKTION:
+     int QuerySkillBonus(object caster, object target, mapping sinfo)
+
+DEFINIERT IN:
+     beliebigen Objekten
+
+ARGUMENTE:
+     object caster
+          der Benutzer eines Skills/Spells (Lebewesen)
+     object target
+          das Ziel eines Skills/Spells (beliebiges Objekt oder 0)
+     mapping sinfo
+          das Skillinfomapping
+
+BESCHREIBUNG:
+     Diese Funktion wird von der Gilde des Casters im Environment und ggf.
+     auch im Ziel eines Skills/Spells gerufen.
+     Die Gilde uebergibt neben Caster und Ziel ein Mapping mit Skillinfos (s.
+     SI Konstanten aus new_skills.h fuer Details), welches alle wesentlichen
+     Informationen ueber den benutzten Skill/Spell enthaelt.
+
+     QuerySkillBonus() liefert einen Bonus (oder Malus) zurueck, den der
+     Aufrufer als Faktor in der Berechnung des Effekts des Skills
+     beruecksichtigen kann (aber nicht muss).
+     Der Bonus/Malus wird hierbei als ganzzahliger 0.01-Prozentwert aufgefasst
+     (10000 == 100% == keine Veraenderung, 1 == 0.01%).
+
+     Diese Funktion kann in beliebigen Objekten (re-)definiert werden. Im
+     Falle mobiler Objekte oder anhaltender Effekte ist jedoch eine
+     Balancegenehmigung erforderlich, sofern kampfrelevante Skills beeinflusst
+     werden.
+     Eine flaechendeckende Reduzierung von Skills/Gildenfaehigkeiten ist
+     explizit _nicht_ erwuenscht und soll auf einzelne Raeume und Objekte
+     beschraenkt sein.
+
+BEMERKUNGEN:
+     Das Mapping <sinfo> kann in dieser Funktion geaendert werden. Dieses kann
+     allerdings sehr weitreichende Folgen haben, speziell bei mangelnden
+     Kenntnissen ueber Interna des Skillsystems. Daher bitte von Aenderungen
+     absehen bzw. vorher mit dem jeweiligen Gildenmagier und/oder der
+     Gildenbalance abklaeren.
+     Die Bedeutung der Werte in <sinfo> kann je nach Gilde variieren. Im
+     Zweifelsfall bitte bei den jeweiligen Gildenmagiern nachfragen. 
+     Die Gilde kann diese Funktion rufen, muss aber nicht. Ebenso kann sie das
+     Ergebnis beruecksichtigen, muss aber nicht.
+
+BEISPIELE:
+     In einem Raum sollen Heilzauber besonders effizient sein:
+     int QuerySkillBonus(object caster, object target, mapping sinfo) {
+        if (pointerp(sinfo[SI_MAGIC_TYPE])
+            && member(sinfo[SI_MAGIC_TYPE], MT_HEILUNG) > -1)
+        {
+            return 12000 + random(3000); // bonus von 120-150%
+        }
+        return 10000;
+     }
+
+SIEHE AUCH:
+     gilden-doku
+     <new_skills.h>
+
+LETZTE AeNDERUNG:
+19.08.2013, Zesstra
diff --git a/doc/lfun/QueryStorageRoom b/doc/lfun/QueryStorageRoom
new file mode 100644
index 0000000..b62e40d
--- /dev/null
+++ b/doc/lfun/QueryStorageRoom
@@ -0,0 +1,21 @@
+QueryStorageRoom()

+

+Funktion:

+    string QueryStorageRoom()

+

+Definiert in:

+    /std/room/shop

+

+Rueckgabewert:

+    Dateiname des Lagers, in dem die aufgekauften Gegenstaende aufbewahrt 

+    werden.

+

+Siehe auch:

+    Funktionen:

+      AddFixedObject(), RemoveFixedObject(), SetStorageRoom(), 

+      QueryBuyValue(), QueryBuyFact(), sell_obj(), buy_obj()

+    Properties:

+      P_KEEPER, P_MIN_STOCK, P_STORE_CONSUME

+

+------------------------------------------------------------------------------

+Letzte Aenderung: 21.05.2014, Bugfix

diff --git a/doc/lfun/QueryTimedAttrModifier b/doc/lfun/QueryTimedAttrModifier
new file mode 100644
index 0000000..1908608
--- /dev/null
+++ b/doc/lfun/QueryTimedAttrModifier
@@ -0,0 +1,42 @@
+QueryTimedAttrModifier()
+FUNKTION:
+     mapping QueryTimedAttrModifier(string key)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     key	-	aus P_TIMED_ATTR_MOD abzufragender Eintrag
+
+BESCHREIBUNG:
+     Der zu key gehoerende Eintrag in P_TIMED_ATTR_MOD wird abgefragt.

+

+RUeCKGABEWERT:

+     Ein leeres Mapping im Falle eines fehlerhaften key-Argumentes oder 
+     eines nicht existenten Keys.

+     

+     Ansonsten wird ein Mapping der Form

+     

+        ([

+           Key : ([ Mapping mit den Modifikatoren ]) ;

+                 Ablaufzeit ; Ablaufobjekt ; Nachrichtenempfaenger 

+        ])    

+

+     zurueckgegeben.Die Ablaufzeit ist hierbei die Zeit in Sekunden seit

+     dem 1. Jan 1970, 0.0:0 GMT, das Ablaufobjekt ist das Objekt an dessen

+     Existenz die Attributveraenderungen gebunden ist und der

+     Nachrichtenempfaenger ist dasjenigen Objekte welches im Falle 

+     durch den Aufruf von "NotifyTimedAttrModExpired" benachrichtigt 

+     wird sobald das Attribut abgelaufen ist. 

+     Der Funktion NotifyTimedAttrModExpired wird als Argument der key

+     der abgelaufenen Attributveraenderung uebergeben.

+     Das Mapping ist eine Kopie der Originaldatenstruktur zu diesem Key.

+    
+SIEHE AUCH:

+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+	SetTimedAttrModifier(), DeleteTimedAttrModifier(),

+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,

+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+----------------------------------------------------------------------------

+Last modified: Tue Jul 27 20:00:20 2004 by Muadib

diff --git a/doc/lfun/QueryTotalQP b/doc/lfun/QueryTotalQP
new file mode 100644
index 0000000..cf15cc0
--- /dev/null
+++ b/doc/lfun/QueryTotalQP
@@ -0,0 +1,25 @@
+QueryTotalQP()
+
+FUNKTION:
+    int QueryTotalQP()
+
+DEFINIERT IN:
+    /secure/questmaster.c
+
+ARGUMENTE:
+    keine
+
+RUECKGABEWERT:
+    Abenteuerpunkte saemtlicher Quests
+
+BESCHREIBUNG:
+    Diese Funktion liefert die Abenteuerpunkte der saemtlicher aktivierter
+    Quests zurueck.
+
+SIEHE AUCH:
+    GiveQuest, QueryQuest, /secure/questmaster.h, QueryGroupedKeys,
+    QueryMaxQP, QueryOptQP
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: Sam, 25. Nov 2000, 14:04:28 von Zook.
+
diff --git a/doc/lfun/QueryUser b/doc/lfun/QueryUser
new file mode 100644
index 0000000..129a0a5
--- /dev/null
+++ b/doc/lfun/QueryUser
@@ -0,0 +1,50 @@
+QueryUser()
+
+FUNKTION:
+     public object QueryUser()
+
+DEFINIERT IN:
+     /std/npc/combat.c
+     /std/clothing/wear.c
+     /std/weapon/combat.c
+     alle Objekte, in denen es darueber hinaus noetig ist
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Liefert den aktuellen Nutzer (Lebewesen) eines Items oder NPCs.
+     
+     Diese Funktion wird z.B. von get_killing_player() benutzt, um
+     herauszufinden, zu welchem Spieler denn das Objekt gehoert, was den
+     toedlichen Schaden verursacht hat.
+
+     Im Falle eines NPCs ist dies standardmaessig der Spieler, bei dem der
+     NPC als Helfer-NPC eingetragen ist (s. RegisterHelperNPC).
+     Im Falle einer Ruestung ist es das Lebewesen, welches sie gerade traegt.
+     Im Falle einer Waffe ist es das Lebewesen, welches sie gerade gezueckt
+     hat.
+     Alle anderen Objekte enthalten keinen Default fuer diese Funktion.
+
+RUeCKGABEWERT:
+     Das nutzende Lebewesen, falls es ermittelt werden konnte, sonst 0.
+
+BEMERKUNGEN:
+     Sollte in allen Objekten definiert werden, welche Lebewesen Schaden
+     zufuegen, ohne dass das verursachende Lebewesen dabei als Feind im
+     Defend() angeben wird.
+     Der gelieferte Nutzer muss explizit kein Spieler sein. Es waere z.B.
+     moeglich, dass von einem Spieler kontrollierter NPC einen Bumerang nutzt.
+
+BEISPIELE:
+     Ein von einem Spieler beschworenes Wesen wirft einen Bumerang nach einem
+     Feind.
+     Dann liefert QueryUser() im Bumerang den NPC als Nutzer und
+     QueryUser() im NPC wiederum den Spieler.
+     
+SIEHE AUCH:
+     RegisterHelperNPC(), get_killer_player()
+     P_WORN, P_WIELDED
+----------------------------------------------------------------------------
+12.11.2013, Zesstra
+
diff --git a/doc/lfun/QueryValidObject b/doc/lfun/QueryValidObject
new file mode 100644
index 0000000..4622d65
--- /dev/null
+++ b/doc/lfun/QueryValidObject
@@ -0,0 +1,47 @@
+QueryValidObject()
+
+FUNKTION:
+     public int QueryValidObject(string oname);
+
+DEFINIERT IN:
+     /std/virtual/v_compiler.c
+
+ARGUMENTE:
+     oname
+       Objektname, der geprueft werden soll (kompletter Pfad mit / am Anfang) 
+
+RUeCKGABEWERT:
+     <=0 - falls VC nicht zustaendig ist.
+     >0 - falls der VC sich fuer das Objekt zustaendig erklaert.
+
+BESCHREIBUNG:
+     Ueber die Funktion laesst sich herausfinden, ob ein VC sich fuer das
+     gewuenschte Objekt zustaendig fuehlt. Dabei wird Validate(),
+     P_COMPILER_PATH, NoParaObjects() und P_PARA im VC ausgewertet:
+     1. Zuerst wird mit Validate() geprueft, ob der Filename (ohne Pfad) ok ist.
+     2. wird geguckt, ob das angefragte Objekt im richtigen Pfad liegt 
+        (P_COMPILER_PATH).
+     3. wenn das angefragte Objekt ein Para-Objekt ist:
+       a) wird NoParaObjects() geprueft, wenn das !=0 ist, sind gar keine Para-
+          Objekte erlaubt.
+       b) wird P_PARA _im VC_ abgefragt, dort kann man ein Array aller 
+          erlaubten Para-Dimensionen reinschreiben. Fuer alle anderen erklaert 
+          sich der VC fuer nicht zustaendig. Wenn P_PARA nicht gesetzt ist, 
+          sind alle erlaubt. Ein leeres Array ({}) wuerde einem 
+          NoParaObjects() {return 1;} entsprechen.
+
+BEMERKUNGEN:
+     Diese Funktion wird vom move abgefragt. Bitte auf jeden Fall P_PARA oder
+     NoParaObjects() passend definieren, sonst buggts.
+
+     Wenn jemand mit dem oben beschrieben Standardverhalten nicht gluecklich
+     ist, kann man die Funktion passend ueberschreiben.
+
+
+SIEHE AUCH:
+     virtual_compiler
+     CustomizeObject(), Validate(), NoParaObjects(), 
+     P_COMPILER_PATH, P_PARA
+     /std/virtual/v_compiler.c
+----------------------------------------------------------------------------
+21.10.2007, Zesstra
diff --git a/doc/lfun/ReceiveMsg b/doc/lfun/ReceiveMsg
new file mode 100644
index 0000000..6443bcd
--- /dev/null
+++ b/doc/lfun/ReceiveMsg
@@ -0,0 +1,250 @@
+ReceiveMsg()
+
+public varargs int ReceiveMsg(string msg, int msg_typ, string msg_action,
+                              string msg_prefix, mixed origin)
+
+DEFINIERT IN:
+    /std/living/comm.c
+    /std/npc/comm.c
+    /std/player/comm.c
+    /std/room/items.c
+
+ARGUMENTE:
+    string msg
+      String mit der uebermittelten Nachricht. Muss nicht umgebrochen sein,
+      da ReceiveMsg() das ebenfalls erledigt.
+    int msg_typ
+      Nachrichtentyp(en) fuer Filterung und Flags fuer Behandlung/Umbruch.
+      Siehe unten fuer mit | kombinierbare Konstanten.
+    string msg_action (optional)
+      Ausloesende Aktion, wird auch fuer Ignorieren verwendet.
+      Default ist query_verb(). Siehe unten fuer alternative Konstanten.
+    string msg_prefix (optional)
+      String, welcher ggf. im break_string() als indent verwendet wird.
+      Default ist 0 (kein Indent)
+    mixed origin (<object>) (optional)
+      Das die Meldung ausloesende Objekt, wird fuer Ignorieren verwendet.
+      Default: previous_object()
+
+BESCHREIBUNG:
+    ReceiveMsg() wird benutzt, um einem Lebewesen eine Nachricht zu senden.
+    Dabei ruft es das sonst uebliche tell_object() fuer Spieler bzw.
+    catch_tell() im NPC auf.
+
+    Gerade fuer Nachrichten an Spieler bietet die Methode weitere Features,
+    die bisher sonst haendisch zu implementieren waren:
+    1) Pruefung auf Empfangbarkeit, je nach 'msg_typ', zB
+       MT_LOOK nur an Nichtblinde
+       MT_LISTEN nur an Nichttaube
+       MT_DEBUG nur an Magier/Testspieler
+    2) Pruefen auf Ignorieren von
+       - Aktion ('msg_action')
+         - mit 'msg_action' || query_verb()
+       - Urheber ('origin')
+         - fuer sendende Spieler mit origin->query_realname()
+         - fuer sendende NPCs mit origin->Name(RAW))
+    3) Speicherung in der tmhist (Typ MT_COMM)
+    4) Speicherung im Kobold (Typ MT_COMM + aktiver Kobold)
+    5) Umbrechen unter Beruecksichtigung von indent, 'msg_typ'-Flags
+       fuer Umbruch und P_PREPEND_BS
+
+    Raeume definieren standardmaessig ebenfalls ein ReceiveMsg(), welches in
+    jedem Objekt im Raum ReceiveMsg() mit den uebergebenen Argumenten aufruft.
+    In diesem Fall ist der Rueckgabe der kleinste von allen gerufenen
+    ReceiveMsg() zurueckgelieferte Wert.
+    
+RUeCKGABEWERT:
+    > 0 fuer Erfolg, < 0 fuer Misserfolg, s.u.
+    MSG_DELIVERED    bei erfolgreicher Zustellung
+    MSG_BUFFERED     bei Zwischenspeicherung durch den Kobold
+
+    MSG_FAILED       nicht naeher spezifizierter Fehler bei Zustellung
+    MSG_IGNORED      Nachricht wurde ignoriert (Absender, origin)
+    MSG_VERB_IGN     Nachricht wurde ignoriert (Kommandoverb, msg_action)
+    MSG_MUD_IGN      Absendendes Mud wurde ignoriert.
+    MSG_SENSE_BLOCK  Passende Sinne des Empfaenger sind blockiert (z.B.
+                     blind, taub)
+    MSG_BUFFER_FULL  Kobold kann sich nichts mehr merken
+
+BEMERKUNGEN:
+    Fuer saemtliche Alternativmeldungen im Falle einer nicht erfolgreich
+    zugestellten Nachricht ist der Aufrufer von ReceiveMsg() verantwortlich.
+
+    NPCs:
+    * ReceiveMsg() ruft zwecks Abwaertskompatibilitaet catch_tell() auf
+    * empfohlen ist, in NPCs nun ReceiveMsg() zu ueberschreiben.
+      * catch_tell() muss weiterhin fuer andere tell_object()
+        ueberschrieben  werden
+
+BEISPIELE:
+    #1.1 Nachricht an einen Spieler, zB in der Wueste
+    this_player()->ReceiveMsg("Die Sonne brennt dir auf den Kopf.",
+                              MT_FEEL|MT_LOOK);
+
+    #1.2 Nachricht an einen Spieler von einem NPC mit Indent
+    // bei aktivem Editor+Kobold landet dieser Text auch im Kobold
+    this_player()->ReceiveMsg("Du haust ja ganz schoen rein!",
+                              MT_COMM|MT_FAR|MSG_DONT_STORE,
+                              MA_TELL,
+                              "Arkshat teilt dir mit: ");
+
+    #1.3 Nachricht an einen Spieler mit Fallback-Kaskade
+    // Achtung, bei MT_COMM oder Ignorieren gibt es natuerlich auch
+    // Misserfolgs-Rueckgaben. Bei einem normalen Kommando wie diesem
+    // hier ist das unproblematisch und daher sinnvoll:
+    if(this_player()->ReceiveMsg(
+         "Du drueckst den Knopf und es oeffnet sich knirschend "
+         "ein kleines Fach in der Wand.", MT_LOOK) < MSG_DELIVERED &&
+       this_player()->ReceiveMsg(
+         "Du drueckst den Knopf und irgend etwas scheint sich "
+         "knirschend zu oeffnen. Das Geraeusch kam von der Wand.",
+         MT_LISTEN) < MSG_DELIVERED) // leider blind UND taub ... also:
+      this_player()->ReceiveMsg(
+        "Du drueckst den Knopf und irgend etwas scheint zu passieren, "
+        "aber leider siehst und hoerst du nichts.", MT_FEEL);
+
+
+    #2.1 Im NPC als Empfaenger auf ein TM reagieren
+    public varargs int ReceiveMsg(string msg, int msg_typ, string msg_action,
+                                  string msg_prefix, mixed origin) {
+      int ret = MSG_DELIVERED;  // Default
+
+      // eine OOC-Kommunikation?
+      if(msg_typ&MT_COMM) {
+        if(strstr(msg, "hilfe")>=0)
+          if(environment(origin)==environment()) {
+            origin->ReceiveMsg("Ich werd dir gleich helfen!",
+                               MT_COMM|MSG_DONT_STORE, MA_TELL,
+                               "Arkshat teilt dir mit: ");
+          } else {
+            origin->ReceiveMsg("Hilf dir selbst, dann hilft dir Gott!",
+                               MT_COMM|MT_FAR|MSG_DONT_STORE,
+                               MA_TELL,
+                               "Arkshat teilt dir mit: ");
+          }
+        else if(...)
+        [...]
+      } else if(msg_typ&MT_LISTEN && msg_action==MA_SAY) {
+        [...]
+      }
+
+      return ret;
+    }
+
+
+    #3.1 als Sender an viele, Variante mit eigenem filter
+    // Achtung: siehe 3.3. send_room() loest vieles.
+    // Living nickt nur seinen Nichtgegnern zu
+    object *all = filter(all_inventory(environment(this_player())),
+                         #'living) - ({this_player()});
+    all -= this_player()->PresentEnemies();
+    all->ReceiveMsg(this_player()->Name()+
+                    " nickt dir verstohlen zu und scheint bereit.",
+                    MT_LOOK, MA_EMOTE);
+
+    #3.2 als Sender an viele, Variante mit einzelnem Iterieren
+    // Achtung: siehe 3.3. send_room() loest vieles.
+    // Living trinkt etwas, jeder im Raum soll es sehen oder hoeren
+    object ob = first_inventory(environment(this_player()));
+    do {
+      if(living(ob) && ob!=this_player())
+        ob->ReceiveMsg(this_player()->Name()+" trinkt einen Schnaps aus.",
+                       MT_LOOK|MT_LISTEN,
+                       MA_DRINK);
+      ob = next_inventory(ob);
+    } while(ob);
+
+    #3.3 als Sender an viele, Variante mit send_room
+    // Living gruesst seine Freunde
+    // send_room() ruft ReceiveMsg mit allen entsprechenden Parametern
+    object *exclude = this_player()->PresentEnemies();
+    send_room(this_object(),
+              this_player()->Name()+" gruesst dich.",
+              MT_LOOK|MT_LISTEN,
+              MA_EMOTE,
+              0,
+              exclude);
+
+    #3.4 als Sender an viele mit send_room und ReceiveMsg()
+    // Living gruesst seine Freunde, seine Feinde sehen das
+    // send_room() ruft ReceiveMsg mit allen entsprechenden Parametern
+    object *exclude = this_player()->PresentEnemies();
+    send_room(this_object(),
+              this_player()->Name()+" gruesst dich.",
+              MT_LOOK|MT_LISTEN, MA_EMOTE, 0, exclude);
+    exclude->ReceiveMessage(
+      this_player()->Name()+" gruesst, aber nicht dich.",
+      MT_LOOK|MT_LISTEN, MA_EMOTE);
+
+KONSTANTEN FUER PARAMETER:
+    Saemtlich in "/sys/living/comm.h". Hier nicht notwendigerweise
+    immer aktuell oder vollstaendig.
+
+    <msg_typ>
+      MT_UNKNOWN      unspez. Nachrichtentyp (nicht verwenden). Es wird
+                      versucht, aufgrund <msg_action> den Typ zu erraten.
+      MT_LOOK         alles, was man sieht
+      MT_LISTEN       alles, was man hoert
+      MT_FEEL         alles, was man fuehlt
+      MT_TASTE        alles, was man schmeckt
+      MT_SMELL        alles, was man riecht
+      MT_MAGIC        alle sonstigen (uebersinnlichen) Wahrnehmungen
+      MT_NOTIFICATION Statusmeldungen, Kommandobestaetigungen
+      MT_COMM         alle OOC-Kommunikation, d.h. nicht durch o.g. Sinne
+                      abgedeckt.
+      MT_FAR          alles, was aus der Ferne / einem anderen Raum kommt.
+                      muss mit min. einem anderen Typ kombiniert werden
+      MT_DEBUG        Debugmeldungen, sehen nur Magier im Magiermodus
+      MT_NEWS         Mails & MPA
+
+      MSG_DONT_BUFFER Nachricht darf nicht im Kobold gespeichert werden
+      MSG_DONT_STORE  Nachricht darf nicht in die Comm-History
+      MSG_DONT_WRAP   Nachricht nicht per break_string umbrechen
+      MSG_DONT_IGNORE Nachricht kann nicht ignoriert werden
+
+      MSG_BS_LEAVE_LFS    wie BS_LEAVE_MY_LFS fuer break_string()
+      MSG_BS_SINGLE_SPACE wie BS_SINGLE_SPACE fuer break_string()
+      MSG_BS_BLOCK        wie BS_BLOCK fuer break_string()
+      MSG_BS_NO_PARINDENT wie BS_NO_PARINDENT fuer break_string()
+      MSG_BS_INDENT_ONCE  wie BS_INDENT_ONCE fuer break_string()
+      MSG_BS_PREP_INDENT  wie BS_PREPEND_INDENT fuer break_string()
+
+    <msg_action> (optional)
+      MA_UNKNOWN     Unspez. Aktion. Es wird der Default query_verb()
+                     benutzt bzw. versucht, die Aktion zu erraten.
+      MA_PUT         Jemand legt etwas hin und gibt jemanden etwas
+      MA_TAKE        Jemand nimmt etwas
+      MA_MOVE_IN     Jemand betritt den Raum
+      MA_MOVE_OUT    Jemand verlaesst den Raum
+      MA_MOVE        Jemand bewegt sich 
+      MA_FIGHT       Jemand kaempft
+      MA_WIELD       Jemand zueckt eine Waffe
+      MA_UNWIELD     Jemand steckt eine Waffe weg
+      MA_WEAR        Jemand zieht etwas an
+      MA_UNWEAR      Jemand zieht etwas aus
+      MA_EAT         Jemand isst etwas
+      MA_DRINK       Jemand trinkt etwas
+      MA_SPELL       Jemand wirkt einen Spell
+      MA_LOOK        Jemand sieht etwas an, untersucht etwas
+      MA_LISTEN      Jemand horcht oder lauscht an etwas
+      MA_FEEL        Jemand betastet etwas
+      MA_SMELL       Jemand schnueffelt herum
+      MA_SENSE       Jemand macht eine uebersinnliche Wahrnehmung
+      MA_READ        Jemand liest etwas
+      MA_USE         Jemand benutzt etwas
+      MA_SAY         Jemand sagt etwas
+      MA_REMOVE      Etwas verschwindet
+      // MA_CHAT        Chatkrams (z.B. teile-mit, Teamkampfchat)
+      MA_CHANNEL     Ebenen
+      MA_EMOTE       (r)Emotes, Soulverben (remotes mit Typ MT_COMM|MT_FAR)
+      MA_SHOUT       Rufen (nicht: shout()!)
+      MA_SHOUT_SEFUN Rufen ueber shout(SE)
+
+SIEHE AUCH:
+    Verwandt: send_room(SE)
+    Lfuns:    TestIgnore(L)
+    Efuns:    tell_object(E), catch_tell(L), catch_msg(L)
+              query_verb(E), query_once_interactive(E), break_string(SE)
+
+13.03.2016, Zesstra
+
diff --git a/doc/lfun/RegisterEvent b/doc/lfun/RegisterEvent
new file mode 100644
index 0000000..8bc5d8d
--- /dev/null
+++ b/doc/lfun/RegisterEvent
@@ -0,0 +1,82 @@
+
+FUNKTION:
+     int RegisterEvent(string eid, string fun, object listener);
+
+DEFINIERT IN:
+     /p/daemon/eventd.c
+DEKLARIERT IN:
+     /sys/events.h
+
+ARGUMENTE:
+     string eid,
+       Die ID des Events, fuer den man sich registrieren will. Da dieser
+       String fuer alle Events jeweils eindeutig sein muss, empfiehlt es sich,
+       fuer eigene Events z.B. als Praefix den eigenen Magiernamen zu nehmen,
+       z.B. "zesstra_vulkanausbruch".
+       ACHTUNG: IDs, die mit '_evt_lib_' beginnen, sind AUSSCHLIESSLICH der
+       Mudlib vorbehalten!
+     string fun,
+       Name der Funktion, die im Objekt listener bei Auftreten des Events
+       gerufen werden soll.
+     object listener,
+       Das Objekt, das als Lauscher fuer diesen Event registriert werden soll.
+
+BESCHREIBUNG:
+     Das Objekt 'listener' wird als Lauscher dieses Events registriert. Ab
+     diesem Moment wird immer dann, wenn ein Event mit der ID 'eid' ausgeloest
+     wird, in 'listener' die Funktion 'fun' aufgerufen (zeitverzoegert, meist
+     0-2s).
+     
+     Die Funktion wird dabei immer mit 3 Argumenten aufgerufen:
+     listener->fun(eid, triggerob, data);
+     Hierbei ist 'eid' die jeweilige Event-ID und 'triggerob' ist das Objekt,
+     welches den Event ausloeste. 
+     'data' kann jeder LPC-Datentyp sein und enthaelt die Daten, die das
+     triggernde Objekt an alle Listener uebermitteln will (damit sind Datentyp
+     und Inhalt komplett abhaengig vom Event!)
+
+     Existiert bisher noch kein Event mit der ID 'eid', wird implizit ein
+     neuer Event erstellt, der erstmal nur das sich gerade registrierende
+     Objekt als Lauscher hat.
+
+
+RUeCKGABEWERT:
+     1 fuer Erfolg, <=0 fuer Misserfolg.
+     1   - Erfolg, 'listener' wurde eingetragen.
+     -1  - falsche Argumente wurden uebergeben
+     -2  - nicht-oeffentlicher Event und 'listener' wurde nicht fuer diesen
+           Event freigegeben (momentan gibt es noch keine nicht-oeffentlichen
+           Events)
+     -3  - 'fun' in 'listener' ist nicht vorhanden oder nicht von aussen 
+           aufrufbar (protected, static, private).
+     
+BEMERKUNGEN:
+     Wenn 'listener' bereits fuer den Event registriert wird, wird die alte
+     Registrierung ueberschrieben (als ggf. gilt dann der jetzt uebergebene
+     Funktionsname).
+     Die Funktion 'fun' sollte sparsam mit den Eval-Ticks umgehen. Momentan
+     ist die max. Menge an Ticks auf 30000 beschraenkt. Dies kann bei
+     Problemen auch jederzeit reduziert werden!
+     Der EVENTD merkt sich Event-Lauscher nicht ueber Reboots hinaus.
+     Sollte sich eine Blueprint anmelden, sich zerstoeren und neugeladen
+     werden, ist die neue Blueprint noch angemeldet, weil das neue Objekt
+     unter dem alten Namen wiedergefunden wird. Dies gilt _nicht_ fuer
+     Clones!
+
+BEISPIELE:
+     1. Ein Objekt moechte ueber Spielertode informiert werden:
+          EVENTD->RegisterEvent(EVT_LIB_PLAYER_DEATH, "spieler_ist_tot", 
+                                this_object());
+        Ab jetzt wird im Objekt jedes Mal, wenn ein Spieler stirbt, die 
+        Funktion "spieler_ist_tot" aufgerufen.
+
+     2. Ein Objekt will informiert werden, wenn der Event
+        "boing_zwergenkoenig_angriff" ausgeloest wird:
+           EVENTD->RegisterEvent("boing_zwergenkoenig_angriff","alarm",
+                                  this_object());
+
+SIEHE AUCH:
+     events, eventd, UnregisterEvent(), TriggerEvent()
+
+----------------------------------------------------------------------------
+Last modified: 15.08.2007, Zesstra
diff --git a/doc/lfun/RegisterHelperNPC b/doc/lfun/RegisterHelperNPC
new file mode 100644
index 0000000..170e8b1
--- /dev/null
+++ b/doc/lfun/RegisterHelperNPC
@@ -0,0 +1,87 @@
+RegisterHelperNPC()
+FUNKTION:
+     public int RegisterHelperNPC(object npc, int flags);
+
+DEFINIERT IN:
+     /std/player/combat.c
+     /sys/living/combat.h
+
+ARGUMENTE:
+     object npc
+       Objekt des helfenden NPC, der angemeldet werden soll.
+
+     int flags
+       ver-oder-te Konstanten, die die Art des Helfer-NPC beschreiben (s.u.)
+
+BESCHREIBUNG:
+     Mit dieser Funktion wird ein einem Spieler helfender NPC im Spieler
+     angemeldet. Hierdurch kann spaeter herausgefunden werden, welche NPC
+     einem Spieler helfen und ggf. den von diesen verursachten Schaden im
+     Kampf dem Spieler zuzurechnen.
+
+     Die Flags sind eine der folgenden Konstanten oder eine beliebige durch
+     ver-oder-ung gebildete Kombination.
+
+     Momentan gibt es 2 Klassen von Helfer-NPC:
+     + GUILD_HELPER: der Helfer-NPC ist ein Gilden-NPC
+     + MISC_HELPER:  der Helfer-NPC ist irgendein NPC, der nicht zu einer Gilde
+                     gehoert.
+
+     Zusaetzlich zu den Klassen gibt es noch weitere Flags, die etwas ueber
+     den Helfer-NPC sagen:
+
+     + EXCLUSIVE_HELPER: dieser Helfer-NPC duldet keinen weiteren NPC der
+                         gleichen Klasse.
+     + ACTIVE_HELPER: ist dieses Flag gesetzt, ist der NPC mehr als nur reiner
+                      Schlagfaenger.
+
+     Wird EXCLUSIVE_HELPER gesetzt und es ist in der gleichen Klasse schon ein
+     NPC angemeldet, schlaegt die Registrierung fehl.
+     Ist in der gleichen Klasse bereits ein NPC mit EXCLUSIVE_HELPER
+     angemeldet, schlaegt die Registierung ebenfalls fehl, auch wenn der neue
+     NPC kein EXCLUSIVE_HELPER setzt.
+
+RUeCKGABEWERT:
+     1, wenn die Registrierung erfolgreich war.
+     0 sonst. In diesem Fall darf der NPC dem Spieler NICHT helfen, weder
+       passiv (Schlagfaenger), noch aktiv.
+
+BEMERKUNGEN:
+     Diese Funktion setzt bei der Erfolg die Property P_HELPER_NPC in <npc>
+     auf passende Werte.
+     Bitte auf gar keinen Fall die numerischen Werte der Konstanten fuer
+     <flags> nutzen, diese koennen sich jederzeit aendern.
+
+BEISPIELE:
+     1. Ein nicht-exklusiver Gilden-NPC, der dem Spieler folgt.
+     if (spieler->RegisterHelperNPC(this_object(), GUILD_HELPER) == 1) {
+       move(environment(spieler), M_GO);
+       spieler->AddPursuer(this_object());
+       // meldung ausgebene...
+     }
+
+     2a. Ein exklusiver Nicht-Gilden-NPC
+     if (spieler->RegisterHelperNPC(this_object(),
+                                    MISC_HELPER|EXCLUSIVE_HELPER) == 1) {
+       move(environment(spieler), M_GO);
+     }
+
+     2b. Ein nicht-exklusiver Nicht-Gilde-NPC, der nach 2a. kommt.
+     if (spieler->RegisterHelperNPC(this_object(), MISC_HELPER) == 1) {
+       // ... wenn der NPC aus 2a noch existiert, trifft dies hier nie zu.
+     }
+
+     3. Ein exklusiver NPC, der weitere Gilden- und sonstige NPC ausschliesst
+        (Solche Kombination bitte mit der Gilden-Balance abstimmen.)
+     if (spieler->RegisterHelperNPC(this_object(), 
+                            MISC_HELPER|GUILD_HELPER|EXCLUSIVE_HELPER) == 1) {
+       move(environment(spieler), M_GO);
+     }
+
+     4. Die Registrierung ohne Klasse schlaegt fehl, z.B.:
+       spieler->RegisterHelperNPC(this_object(), 0);
+       spieler->RegisterHelperNPC(this_object(), EXCLUSIVE_HELPER);
+
+SIEHE AUCH:
+    UnregisterHelperNPC()
+    P_HELPER_NPC
diff --git a/doc/lfun/RegisterHelperObject b/doc/lfun/RegisterHelperObject
new file mode 100644
index 0000000..aa1cb66
--- /dev/null
+++ b/doc/lfun/RegisterHelperObject
@@ -0,0 +1,113 @@
+
+FUNKTION:
+     int RegisterHelperObject(object helper, int type, 
+                              string|closure callback);
+
+DEFINIERT IN:
+     /std/living/helpers.c
+
+ARGUMENTE:
+     object helper
+       Das Objekt, das bei einem Lebewesen als Hilfsobjekt registriert 
+       werden soll. Das Objekt muss sich dazu nicht im Inventar des
+       Lebewesens befinden.
+     int type
+       Helfertyp, einer der in /sys/living/helpers.h definierten Typen:
+       - HELPER_TYPE_AERIAL fuer die Flug-/Segelunterstuetzung
+       - HELPER_TYPE_AQUATIC fuer Tauchunterstuetzung
+     string|closure callback
+        Closure oder Funktionsname als String; dies ist die Funktion, die im
+        Objekt helper gerufen wird, um abzufragen, ob es sich aktuell fuer
+        zustaendig erklaert oder nicht.
+
+BESCHREIBUNG:
+     Das Objekt "helper" wird als Hilfsobjekt fuer bestimmte Aktivitaeten wie
+     zum Beispiel Fliegen oder Tauchen registriert. 
+     
+     Die als Callback uebergebene Funktion wird bei der Abfrage der 
+     P_*_HELPERS-Properties (siehe unten) aufgerufen und deren 
+     Rueckgabewert in der Property vermerkt. 
+     
+     Der Rueckgabewert der Callback-Methode muss im Wertebereich 
+     0..10000 liegen, wobei ein Wert von 0 bedeutet, dass das Hilfsobjekt 
+     sich gerade nicht zustaendig fuehlt. Bei den Werten >0 ist es dem 
+     abfragenden Objekt ueberlassen, wie es diese Daten bewertet.
+
+     Die Funktion muss existieren und public sein, d.h. von aussen gerufen 
+     werden koennen.
+     
+     Die Funktion bekommt das Spielerobjekt und das abfragende Objekt als
+     Parameter uebergeben.
+
+HINWEIS:
+     Es ist ein Unterschied, ob sich ein Objekt via UnregisterHelperObject()
+     als Helfer austraegt, oder ob der Aufruf der Callback-Funktion eine
+     0 zurueckgibt. Im letzteren Fall ist das Objekt nach wie vor 
+     registriert und kann trotzdem vom abfragenden Objekt als 
+     funktionsfaehig angesehen werden.
+
+RUECKGABEWERTE:
+      1  Objekt wurde erfolgreich registriert (HELPER_SUCCESS)
+     -1  angegebenes Hilfsobjekt existiert nicht (HELPER_NO_CALLBACK_OBJECT)
+     -2  angegebenes Hilfsobjekt ist bereits fuer diese Art der
+         Unterstuetzung registriert (HELPER_ALREADY_LISTED)
+
+BEISPIELE:
+     a) Eine luftgefuellte Blase will sich als Tauch-Helfer am Spieler
+     anmelden und ist zustaendig, solange sich noch Luft in ihr befindet:
+
+     int luft = 5; // globale Variable z.B. fuer Luftinhalt von 5 Atemzuegen
+
+     // Registrierung im Spielerobjekt
+     if ( TP->RegisterHelperObject(ME, HELPER_TYPE_AQUATIC,
+          "DivingCallback") == HELPER_SUCCESS ) {
+       tell_object(TP, "Du kannst jetzt mit Hilfe der Luftblase unter Wasser "
+         "atmen.\n");
+     }
+
+     // hier koennen natuerlich auch noch komplexere Dinge ablaufen, z.B.
+     // wenn ein Wert zurueckgegeben werden soll, der nicht nur 0 oder 1 ist.
+     public int DivingCallback(object player, object caller) {
+       return (environment(ME)==player && luft>0);
+     }
+
+     b) Ein Spieler befindet sich in einem Raum mit einem steilen Abhang, den
+     man hinunterspringen kann. Dies geht aber nur dann gefahrlos, wenn es
+     Hilfsobjekte gibt, die den (Segel)flug erlauben:
+
+     // cmd_springen() sei die Funktion, die bei der Eingabe des Befehls durch
+     // den Spieler aufgerufen wird.
+     static int cmd_springen(string str) {
+       [...]
+       // Property abfragen
+       mapping helpers = TP->QueryProp(P_AERIAL_HELPERS);
+       // Liste der Werte fuer die einzelnen Unterstuetzungsobjekte ermitteln
+       int *values = m_values(helpers,0);
+       // Spieler schonmal runterbewegen, die Folgen seines Handelns spuert
+       // er dann, wenn er unten angekommen ist.
+       TP->move(zielraum, M_GO|M_SILENT);
+       // "helpers" ist immer ein Mapping, das pruefen wir nicht extra.
+       // Wenn die Liste der Objekte noch mindestens ein Element enthaelt,
+       // nachdem alle unzustaendigen Hilfsobjekte (Rueckgabewert der
+       // Callback-Funktion == 0) rausgerechnet wurden, existiert mindestens
+       // ein geeignetes Hilfsobjekt.
+       if ( sizeof(values-({0})) ) {
+         tell_object(TP, "Sanft segelst Du den Hang hinab.\n");
+       }
+       else {
+         tell_object(TP, BS("Todesmutig springst Du den Hang hinab und "
+           "schlaegst hart unten auf. Du haettest vielleicht daran denken "
+           "sollen, Dir geeignete Hilfsmittel fuer so eine Aktion zu "
+           "besorgen.");
+         TP->Defend(800, ({DT_BLUDGEON}), ([SP_NO_ACTIVE_DEFENSE:1]), ME);
+       }
+       return 1;
+     }
+
+SIEHE AUCH:
+     Funktionen:  UnregisterHelperObject()
+     Properties:  P_HELPER_OBJECTS, P_AERIAL_HELPERS, P_AQUATIC_HELPERS
+     Sonstiges:   /sys/living/helpers.h
+
+05.02.2015 Arathorn
+
diff --git a/doc/lfun/RemoveAdjective b/doc/lfun/RemoveAdjective
new file mode 100644
index 0000000..48605dd
--- /dev/null
+++ b/doc/lfun/RemoveAdjective
@@ -0,0 +1,24 @@
+RemoveAdjective()
+
+FUNKTION:
+     void RemoveAdjective(string|string* adj);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     adj
+          String oder Array von String mit den Adjektiven.
+
+BESCHREIBUNG:
+     Falls einige der vorhandenen Adjektive nicht mehr verwendet werden
+     sollen, koennen sie mit dieser Funktion entfernt werden.
+
+RUeCKGABEWERT:
+     keiner
+
+SIEHE AUCH:
+     AddAdjective(), RemoveId(), /std/thing/description.c
+
+----------------------------------------------------------------------------
+20.01.2015, Zesstra
diff --git a/doc/lfun/RemoveClass b/doc/lfun/RemoveClass
new file mode 100644
index 0000000..3eeda6c
--- /dev/null
+++ b/doc/lfun/RemoveClass
@@ -0,0 +1,23 @@
+RemoveClass()
+
+FUNKTION:
+     void RemoveClass(string|string* class);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     string/string* class	- String oder Stringarray der Klasse(n)
+
+BESCHREIBUNG:
+     Dem Objekt werden einige der mit AddClass() gesetzten Klassen wieder 

+     entzogen.
+     Die allgemein verfuegbaren Klassen sind unter /sys/class.h definiert.
+
+SIEHE AUCH:
+     AddClass(), is_class_member()
+     P_CLASS
+
+----------------------------------------------------------------------------
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/RemoveCmd b/doc/lfun/RemoveCmd
new file mode 100644
index 0000000..25941c6
--- /dev/null
+++ b/doc/lfun/RemoveCmd
@@ -0,0 +1,60 @@
+RemoveCmd(L)
+FUNKTION:
+    varargs int RemoveCmd(mixed cmd, int norule, mixed id)
+
+DEFINIERT IN:
+    /std/thing/commands.c
+
+ARGUMENTE:
+    com
+         String oder Array von Strings mit den zu entfernenden Kommandos.
+    norule
+         Kommandos mit Regeln werden nicht entfernt (ausser bei cmd==0)
+    id
+         eine ID, mit der man ein vorher mit dieser ID gespeichertes
+         Kommando eindeutig lvschen kann
+
+BESCHREIBUNG:
+    Mit AddCmd() hinzugefuegte Kommandos koennen mit diesem Befehl wieder
+    abgemeldet werden. Die entfernten Kommandos sind direkt nach dem
+    RemoveCmd()-Aufruf nicht mehr ansprechbar.
+
+    Wird ein Regelstring angegeben, so wird die identische AddCmd-
+    Regel entfernt.
+
+BEMERKUNGEN:
+    Uebergibt man fuer com eine 0, so werden alle definierten Kommandos
+    entfernt!
+
+RUECKGABEWERT:
+    Anzahl der entfernten Kommandos.
+
+BEISPIELE:
+    (1) AddCmd("test");
+    (2) AddCmd("test|teste&mit&parameter");
+    (3) AddCmd(({"test"}),1);
+    (4) AddCmd("test",0,0,"XYZ");
+    (5) AddCmd("test&mit&parameter",0,0,"XYZ");
+
+    RemoveCmd(0);
+    - entfernt alle Kommandos
+    RemoveCmd("test",1);
+    - entfernt (1) und (3)
+    RemoveCmd("test");
+    - entfernt (1), (3) und einen Teil von (2),
+      es verbleibt "teste&mit&parameter"
+    RemoveCmd("test|teste&mit&parameter"
+    - entfernt (2)
+    RemoveCmd("test",0,"XYZ");
+    - entfernt (4) und (5)
+    RemoveCmd("test",1,"XYZ");
+    - entfernt (4), nicht (5)
+    RemoveCmd(0,0,"XYZ");
+    - entfernt (4) und (5)
+
+SIEHE AUCH:
+			AddCmd(L), AddCmd_bsp
+    Sonstiges:		replace_personal(E), enable_commands(E), init(E)
+    Alternativen:	AddAction(L), add_action(E)
+
+24.Maerz 2004 Gloinson
diff --git a/doc/lfun/RemoveDefender b/doc/lfun/RemoveDefender
new file mode 100644
index 0000000..aad46df
--- /dev/null
+++ b/doc/lfun/RemoveDefender
@@ -0,0 +1,36 @@
+RemoveDefender()
+
+FUNKTION:
+	void RemoveDefender(object friend);
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	friend
+	  Objekt (normal Lebewesen), welches zukuenftig nicht mehr ueber
+	  Angriffe informiert werden soll und diese auch nicht mehr abwehrt.
+
+BESCHREIBUNG:
+	Ein Lebewesen, welches angegriffen wird, kann andere Objekte ueber
+	einen solchen Angriff per InformDefend() informieren oder ihnen
+	sogar die Moeglichkeit geben, per DefendOther() direkt in den
+	laufenden Angriff einzugreifen (Schaeden abwehren oder umwandeln).
+	Im Normalfall handelt es sich hierbei um andere Lebewesen, welche
+	als Verteidiger des angegriffenen Lebewesens auftreten: Daher der
+	Name der Funktion. Ausserdem besteht die Einschraenkung, dass diese
+	Objekte in der gleichen Umgebung sein muessen, wie das zu
+	verteidigende Lebewesen.
+	Die Objekte sind in Form eines Arrays in der Property P_DEFENDERS
+	abgespeichert und koennen dort abgerufen werden. Natuerlich kann
+	man alte Objekte direkt dort loeschen, jedoch sollte man die
+	hierfuer bereitgestellte Funktionen RemoveDefender() verwenden.
+	Zum Hinzufuegen von Eintraegen im Array steht ebenfalls eine
+	Funktion bereit: AddDefender().
+
+SIEHE AUCH:
+	AddDefender(), InformDefend(), DefendOther(),
+	P_DEFENDERS, /std/living/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Thu Jul 29 18:48:45 1999 by Patryn
diff --git a/doc/lfun/RemoveDetail b/doc/lfun/RemoveDetail
new file mode 100644
index 0000000..f73af2a
--- /dev/null
+++ b/doc/lfun/RemoveDetail
@@ -0,0 +1,57 @@
+RemoveDetail()
+
+FUNKTION:
+    void RemoveDetail(mixed *keys);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den zu entfernenden Details.
+
+BESCHREIBUNG:
+    Entfernt die in <keys> angegebenen Details aus der Liste der
+    vorhandenen Details. Uebergibt man fuer <keys> eine 0, so werden
+    saemtliche Details entfernt!
+
+BEISPIEL:
+    Ein kleines Beispiel, bei dem eine Oeffnung erscheint und wieder
+    verschwindet, je nachdem, ob man eine Luke oeffnet oder schliesst.
+      int oeffneLuke(string str);
+      int schliesseLuke(string str);
+      ...
+      AddCmd("oeffne", #'oeffneLuke);
+      AddCmd("schliesse", #'schliesseLuke);
+      ...
+      int oeffneLuke(string str) {
+        if(str!="luke" || GetDetail("oeffnung"))
+          return 0;
+        AddDetail("oeffnung","Du siehst eine kleine Oeffnung.\n");
+        return 1;
+      }
+
+      int schliesseLuke(string str) {
+        if(str!="luke" || !GetDetail("oeffnung"))
+          return 0;
+        RemoveDetail("oeffnung"); // Detail wieder entfernen
+        return 1;
+      }
+
+BEMERKUNGEN:
+    Da intern Details und SpecialDetails im gleichen Mapping verwaltet
+    werden, lassen sich mit dieser Funktion auch SpecialDetails
+    entfernen.
+    Die Funktion RemoveSpecialDetail() sollte also nicht genutzt werden!
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS,
+               P_TOUCH_DETAILS, P_SPECIAL_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+8. Juli 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/RemoveExit b/doc/lfun/RemoveExit
new file mode 100644
index 0000000..edc61f2
--- /dev/null
+++ b/doc/lfun/RemoveExit
@@ -0,0 +1,28 @@
+RemoveExit()
+FUNKTION:
+     void RemoveExit(string|string* cmd);
+
+DEFINIERT IN:
+     /std/room/exits
+
+ARGUMENTE:
+     string/string* cmd
+          Richtung(en), die entfernt werden sollen.
+
+BESCHREIBUNG:
+     Die in cmd angegebenen Ausgaenge werden wieder entfernt.
+
+     Ist cmd = 0, so werden alle Ausgaenge entfernt.
+
+BEMERKUNGEN:
+     Ausgaenge werden an der gleichen Stelle gespeichert:
+     - RemoveExit() greift auf die gleichen Daten wie RemoveSpecialExit()
+       zu, entfernt also auch spezielle Ausgaenge!
+
+SIEHE AUCH:
+     AddExit(), AddSpecialExit(), GetExits()
+     RemoveSpecialExit(),
+     H_HOOK_EXIT_USE, P_EXITS, P_HIDE_EXITS, /std/room/exits.c
+     ausgaenge
+
+31.01.2015, Zesstra
diff --git a/doc/lfun/RemoveExtraLook b/doc/lfun/RemoveExtraLook
new file mode 100644
index 0000000..1ba196e
--- /dev/null
+++ b/doc/lfun/RemoveExtraLook
@@ -0,0 +1,39 @@
+RemoveExtraLook()
+
+int RemoveExtraLook(string look);
+
+DEFINIERT IN:
+   /std/living/description.c
+
+BESCHREIBUNG:
+   Der Extralook erscheint in der Langbeschreibung des Lebewesens.
+   Eintraege koennen mit dieser Funktion (vorzeitig) wieder entfernt werden.
+
+ARGUMENTE:
+  - string key:
+    Schluesselwort, unter dem der Eintrag, den man entfernen moechte, von
+    AddExtraLook() registriert wurde.
+
+RUECKGABEWERTE:
+  > 0, falls der Eintrag erfolgreich entfernt wurde.
+  < 0 sonst.
+    -1: keinen (gueltigen) <key> uebergeben.
+    -2: kein Eintrag fuer <key> gefunden.
+
+BEMERKUNGEN:
+  Beim Entfernen mit dieser Funktion wird die "Endemeldung" des entfernten
+  Eintrages nicht ausgegeben.
+
+BEISPIELE:
+  # Extralook registrieren.
+  living->AddExtraLook("@WER1 wird von einer Horde Daemonen verfolgt.",
+                       "ennox_daemonenhordenverfolgerlook");
+  # Nun kann der Eintrag auch wieder entfernt werden:
+  living->RemoveExtraLook("ennox_daemonenhordenverfolgerlook");
+
+SIEHE AUCH:
+   AddExtraLook(),
+   P_INTERNAL_EXTRA_LOOK
+
+14.05.2007, Zesstra
+
diff --git a/doc/lfun/RemoveFixedObject b/doc/lfun/RemoveFixedObject
new file mode 100644
index 0000000..7616b2b
--- /dev/null
+++ b/doc/lfun/RemoveFixedObject
@@ -0,0 +1,40 @@
+RemoveFixedObject()
+
+FUNKTION:
+	void RemoveFixedObject(string filename);
+
+DEFINIERT IN:
+	/std/laden.c
+
+ARGUMENTE:
+	str
+	  Dateiname des Objektes, welches nicht mehr dauerhaft im Laden sein
+	  soll.
+
+RUeCKGABEWERT:
+        keiner
+
+BESCHREIBUNG:
+	Objekte, die mittels der Funktion AddFixedObject() im Laden
+	eingebunden werden, sind dort staendig verfuegbar. Um diesen Zustand
+	wieder aufzuheben, kann man sie mittels dieser Funktion wieder
+	entfernen. Eventuell im Lager befindliche Objekte dieser Art werden
+	hierbei nicht zerstoert und koennen durchaus noch gekauft werden,
+	bis sie alle sind. Danach gibt es sie dort nicht mehr!
+
+BEISPIELE:
+	Im allen Laeden gibt es schon ein Objekt, welches dort
+	standardmaessig erhaeltlich ist. Folgende Zeile sorgt dafuer:
+	  AddFixedObject("/obj/boerse",80,({"boerse","geldboerse"}));
+	Wenn man das in seinem Laden nicht wuenscht, kann man die Geldboerse
+	mittels folgender Zeile wieder aus dem Laden loeschen:
+	  RemoveFixedObject("/obj/boerse");
+	Es ist nicht moeglich, keine oder mehrere Objekte anzugeben, um auf
+	diese Weise alle bzw. mehrere Objekte als nicht mehr staendig
+	verfuegbar zu markieren.
+
+SIEHE AUCH:
+	AddFixedObject(), SetStorageRoom(), /std/store.c
+
+----------------------------------------------------------------------------
+Last modified: Thu Jun 18 14:19:19 1998 by Patryn
diff --git a/doc/lfun/RemoveFromMenu b/doc/lfun/RemoveFromMenu
new file mode 100644
index 0000000..a8326af
--- /dev/null
+++ b/doc/lfun/RemoveFromMenu
@@ -0,0 +1,32 @@
+RemoveFromMenu()
+
+FUNKTION:
+     int RemoveFromMenu(mixed ids)
+
+DEFINIERT IN:
+     /std/pub.c
+
+ARGUMENTE:
+     ids - string oder string*
+	   String oder Array von Strings, mit denen sich die Speise bzw.
+           das Getraenk beim Bestellen ansprechen laesst.
+
+RUECKGABEWERT:
+     int - Anzahl entfernter Einzelmenueeintraege
+
+BESCHREIBUNG:
+     Mit dieser Methode kann man id-basiert Speisen und Getraenke
+     wieder von der Karte entfernen (wenn zB nur saisonbasiert
+     bestimmte Dinge angeboten werden sollen).
+     
+BEMERKUNGEN:
+     - sich zwischen zwei Speisen ueberschneidende IDs fuehren zu
+       undefiniertem Verhalten!
+     - bei Benutzung von RemoveFromMenu sollte man in Delay-Speisen oder
+       -Getraenken auf die Nutzung vom ident-Parameter in den
+       Serviernachrichten verzichten (es sei, man weiss was man tut)
+
+SIEHE AUCH:
+     AddToMenu(), AddFood(), AddDrink(), /sys/pub.h
+
+15. Februar 2009 Gloinson
diff --git a/doc/lfun/RemoveFunc b/doc/lfun/RemoveFunc
new file mode 100644
index 0000000..054abe4
--- /dev/null
+++ b/doc/lfun/RemoveFunc
@@ -0,0 +1,87 @@
+RemoveFunc()
+
+FUNKTION:
+     int RemoveFunc(object ruest, int info, object user);
+
+DEFINIERT IN:
+     eigenen Objekten (fuer /std/clothing/wear)
+
+ARGUMENTE:
+     ruest (object)
+          Die Ruestung/Kleidung, die ausgezogen werden soll.
+     info (int)
+          Bei (info&M_SILENT) wird keine Meldung ueber das Ausziehen
+          ausgegeben.
+          Bei (info&M_NOCHECK) wird die Kleidung ausgezogen, egal was diese
+          Funktion zurueckgibt. Dies tritt insbesondere dann auf, wenn der
+          Spieler, der die Ruestung traegt, stirbt und die Ruestung in
+          die Leiche bewegt wird.
+     user (object)
+          Das Lebewesen, welches die Ruestung/Kleidung gerade traegt und sie
+          ausziehen will.
+
+BESCHREIBUNG:
+     Mit dieser Funktion kann man pruefen, ob sich das Kleidungsstueck bzw.
+     Ruestung <ruest> von this_player() ausziehen laesst oder nicht.
+     Kann die Ruestung ausgezogen werden, so muss ein Wert ungleich 0
+     zurueckgegeben werden.
+     
+     Diese Funktion meldet nur einen _Wunsch_ an. Dieser kann ignoriert
+     werden (z.B. bei bestimmten Bewegungen, Tod des Spielers etc.).
+     Unabhaengig vom Wert dieser Funktion kann das Ausziehen noch Scheitern
+     oder Erzwungen werden.
+     Wenn ihr sicher sein wollt, dass der Spieler ein Objekt angezogen hat,
+     benutzt bitte InformUnwear().
+
+RUeCKGABEWERT:
+     0, wenn sich die Ruestung nicht ausziehen laesst, ansonsten ungleich 0.
+
+BEMERKUNGEN:
+     Verfluchte Ruestungen, die sich erst nach Entfernung des Fluches wieder
+     ausziehen lassen, sollte man besser mit P_CURSED realisieren (man spart
+     die RemoveFunc() ein).
+     Bitte nicht drauf verlassen, dass this_player() das ausziehende Lebewesen
+     ist.
+     Die Reihenfolge der Argumente ist etwas unschoen, aber leider wurde <user>
+     erheblich spaeter hinzugefuegt und es war unmoeglich, einige hundert
+     Objekte zu aendern.
+
+BEISPIELE:
+     Ein Umhang, den man nur mit guter Einstellung wieder ausziehen kann:
+
+     inherit "std/armour.c";
+
+     #include <properties.h>
+     #include <moving.h>
+
+     create()
+     {
+       ::create();
+
+       SetProp(P_ARMOUR_TYPE, AT_CLOAK);
+       /* zig weitere SetProp's, um den Umhang zu konfigurieren */
+
+       /* RemoveFunc() ist im Umhang selbst zu finden */
+       SetProp(P_REMOVE_FUNC, this_object());
+     }
+
+     int RemoveFunc(object me, int info, object user)
+     {
+       if (user->QueryProp(P_ALIGN) >= 0 || (info&M_NOCHECK))
+         return 1;   /* gute Charaktere koennen den Umhang ausziehen */
+
+       /* Ansonsten geben wir evtl. einen entsprechenden Hinweis aus: */
+       if (!(info&M_SILENT))
+           write( "Der Umhang wird von Deiner Bosheit so sehr "
+                 +"angezogen, dass Du ihn\nnicht mehr ausziehen kannst!\n");
+       return 0;
+     }
+
+SIEHE AUCH:
+     P_WEAR_MSG, P_UNWEAR_MSG, P_WIELD_MSG, P_UNWIELD_MSG
+     DoUnwear(), DoWear(), InformWear(), InformUnwear()
+     /std/clothing/wear.c
+
+----------------------------------------------------------------------------
+02.07.2013, Zesstra
+
diff --git a/doc/lfun/RemoveId b/doc/lfun/RemoveId
new file mode 100644
index 0000000..85e7099
--- /dev/null
+++ b/doc/lfun/RemoveId
@@ -0,0 +1,26 @@
+RemoveId()
+
+FUNKTION:
+     void RemoveId(string|string* ids);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     ids
+          String oder Array von Strings mit den Bezeichnungen, die aus der
+          Liste der IDs des Objektes entfernt werden sollen.
+
+BESCHREIBUNG:
+     Wenn ein Objekt sich nicht mehr mit gewissen Bezeichnern ansprechen
+     lassen soll, kann man diese mit dieser Funktion entfernen.
+
+RUeCKGABEWERT:
+     keiner
+
+SIEHE AUCH:
+     AddId(), RemoveAdjective(), /std/thing/description.c
+
+----------------------------------------------------------------------------
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/RemoveInfo b/doc/lfun/RemoveInfo
new file mode 100644
index 0000000..5ced62c
--- /dev/null
+++ b/doc/lfun/RemoveInfo
@@ -0,0 +1,24 @@
+RemoveInfo()
+FUNKTION:
+     void RemoveInfo(string key)
+
+DEFINIERT IN:
+     /std/npc/info.c
+
+ARGUMENTE:
+     key	zu loeschender Schluessel
+
+BESCHREIBUNG:
+     Loescht die Antwort zum entsprechenden Frageschluessel.
+
+BEISPIEL:
+     // erstellen und loeschen
+     AddInfo("gold","sagt: Ich habe keines.\n");
+     RemoveInfo("gold");
+
+SIEHE AUCH:
+     AddInfo(L), AddSpecialInfo(L)
+     P_PRE_INFO, P_DEFAULT_INFO
+     /std/npc/info.c
+
+17.Aug.2003 Gloinson
diff --git a/doc/lfun/RemoveItem b/doc/lfun/RemoveItem
new file mode 100644
index 0000000..aa454f7
--- /dev/null
+++ b/doc/lfun/RemoveItem
@@ -0,0 +1,41 @@
+RemoveItem()
+
+FUNKTION:
+	void RemoveItem(mixed file);
+
+DEFINIERT IN:
+	/std/room/items.c
+
+ARGUMENTE:
+	file
+	     String oder Array von Strings mit dem Namen des zu entfernenden
+	     Objekts.
+
+BESCHREIBUNG:
+	Das mit AddItem(file) dem Raum hinzugefuegte Objekt wird wieder aus
+	der Liste der Objekte entfernt.
+	Wurde bei AddItem() ein Array von Dateinamen uebergeben, so muss das
+	selbe Array auch bei RemoveItem() uebergeben werden!
+	Falls das Objekt, das durch den AddItem()-Aufruf erzeugt wurde, sich
+	noch im Raum befindet, wird es durch den RemoveItem()-Aufruf zerstoert.
+
+RUECKGABEWERT:
+	keiner
+
+BEISPIELE:
+	Ein muellschluckerfreier Laden laesst sich wie folgt erzeugen:
+
+	inherit "/std/laden";
+	#include <properties.h>
+
+	create()
+	{
+	  ::create();  // Hier wird u.a. der Muellschlucker erzeugt
+
+	  RemoveItem("/obj/entsorg"); // und weg damit!
+
+	  SetProp(...);  // und die normale Beschreibung...
+	}
+
+SIEHE AUCH:
+	AddItem(), /std/room/items.c
diff --git a/doc/lfun/RemoveKnownPotion b/doc/lfun/RemoveKnownPotion
new file mode 100644
index 0000000..5b1418c
--- /dev/null
+++ b/doc/lfun/RemoveKnownPotion
@@ -0,0 +1,25 @@
+RemoveKnownPotion()
+
+FUNKTION:
+     int RemoveKnownPotion(int nr)
+
+DEFINIERT IN:
+     /std/player/potion.c
+
+ARGUMENTE:
+     int nr       Nummer eines ZTs
+
+BESCHREIBUNG:
+     Entfernt einen bekannten ZT aus einen Spieler. Nur vom Orakel rufbar.
+
+RUeCKGABEWERT:
+     1  Erfolg
+     -1 fehlende Berechtigung
+     -2 Nummer nicht eingetragen
+
+SIEHE AUCH:
+     Sonstiges: zaubertraenke, /secure/potionmaster.c, /room/orakel.c
+     Verwandt:  FindPotion(), AddKnownPotion(), InList()
+     Props:     P_POTIONROOMS, P_KNOWN_POTIONROOMS
+
+6.Feb 2016 Gloinson
diff --git a/doc/lfun/RemovePluralId b/doc/lfun/RemovePluralId
new file mode 100644
index 0000000..0960e02
--- /dev/null
+++ b/doc/lfun/RemovePluralId
@@ -0,0 +1,28 @@
+RemovePluralId()
+
+FUNKTION:
+     void RemovePluralId(mixed id);
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     id
+          Identfikationsstring oder Array von Strings
+
+BESCHREIBUNG:
+     Es werden ein oder mehrere Bezeichner entfernt, mit denen sich 
+     mehrere Einheiten der Menge ansprechen lassen.
+
+RUECKGABEWERT:
+     keiner
+
+BEISPIELE:
+     siehe /items/money.c
+
+SIEHE AUCH:
+     RemoveSingularId(), AddPluralId(), AddId(), id(), /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Mon Jul 14 11:30:00 1997 by Silvana
+
diff --git a/doc/lfun/RemovePursuer b/doc/lfun/RemovePursuer
new file mode 100644
index 0000000..8ba2358
--- /dev/null
+++ b/doc/lfun/RemovePursuer
@@ -0,0 +1,26 @@
+RemoveRursuer()
+
+FUNKTION:
+  void RemovePursuer(object pursuer)
+
+ARGUMENTE:
+  pursuer: Objekt, das aus der Verfolgerliste des Objektes, in dem
+           RemovePursuer aufgerufen wurde, ausgetragen werden soll.
+
+FUNKTION:
+  Durch den Aufruf von RemovePursuer in einem Objekt, welches living() ist,
+  wird das Object, welches als Argument uebergeben wurde aus der Liste
+  der Verfolger ausgetragen.
+
+RUECKGABEWERT:
+  keiner
+
+BEMERKUNG:
+  keine
+
+BEISPIELE:
+  find_player("jof")->RemovePursuer(find_player("kirk"))
+  Danach wird Jof nicht mehr von Kirk verfolgt.
+
+SIEHE AUCH:
+  "AddPursuer", "PreventFollow"
diff --git a/doc/lfun/RemoveReadDetail b/doc/lfun/RemoveReadDetail
new file mode 100644
index 0000000..f357954
--- /dev/null
+++ b/doc/lfun/RemoveReadDetail
@@ -0,0 +1,31 @@
+RemoveReadDetail()
+
+FUNKTION:
+    void RemoveReadDetail(string|string* keys);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+         String oder Array von Strings mit den zu entfernenden Details.
+
+BESCHREIBUNG:
+    Entfernt die in keys angegebenen Details aus der Liste der vorhandenen
+    lesbaren Details.
+
+BEMERKUNGEN:
+    Uebergibt man fuer keys eine 0, so werden saemtliche lesbaren Details
+    entfernt!
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/RemoveResistanceModifier b/doc/lfun/RemoveResistanceModifier
new file mode 100644
index 0000000..0e630fb
--- /dev/null
+++ b/doc/lfun/RemoveResistanceModifier
@@ -0,0 +1,37 @@
+RemoveResistanceModifier()
+
+FUNKTION:
+     varargs void RemoveResistanceModifier(string add);
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+ARGUMENTE:
+     string add:
+      Ein eventueller Identifikator fuer einen gesetzten Modifikator.
+
+BESCHREIBUNG:
+     Die von einem Objekt im Zielobjekt gesetzte Resistenz wird geloescht,
+     der Schluessel add wird dazu benutzt, eine bestimmte Resistenz zu
+     loeschen (so kann ein setzendes Objekt mehrere verschiedene Re-
+     sistenzen setzen und selektiv loeschen).
+
+BEISPIELE:
+     // unser Oel aus AddResistanceModifier() verbrennt endgueltig
+     varargs void trigger_sensitive_attack() {
+      ...
+      if(environment() && living(environment())) {
+       environment()->RemoveResistanceModifier("oel");
+       tell_object(environment(),"Das Oel verbrennt endgueltig.\n");
+      }
+      remove();
+     }
+
+SIEHE AUCH:
+     Modifikatoren:	AddResistanceModifier, P_RESISTANCE_MODIFIER
+     simple Resistenz:	P_RESISTANCE, P_VULNERABILITY
+     Hauptmapping:	P_RESISTANCE_STRENGTHS
+     Berechnung:	CheckResistance(), UpdateResistanceStrengths()
+     anderes:		balance, /std/armour/combat.c, /std/living/combat.c
+
+29.Apr 2002, Gloinson@MG
diff --git a/doc/lfun/RemoveRoute b/doc/lfun/RemoveRoute
new file mode 100644
index 0000000..e301719
--- /dev/null
+++ b/doc/lfun/RemoveRoute
@@ -0,0 +1,23 @@
+RemoveRoute()
+
+FUNKTION:
+     void RemoveRoute();
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Der Transporter wird angehalten und der gesamte Fahrplan wird
+     geloescht. Damit lassen sich zum Beispiel variable Routen konstruieren.
+
+RUeCKGABEWERT:
+     keiner
+
+SIEHE AUCH:
+     AddRoute(), AddMsg(), AddFun(), /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:24:26 1996 by Wargon
diff --git a/doc/lfun/RemoveSensitiveObject b/doc/lfun/RemoveSensitiveObject
new file mode 100644
index 0000000..5f6e0dc
--- /dev/null
+++ b/doc/lfun/RemoveSensitiveObject
@@ -0,0 +1,56 @@
+RemoveSensitiveObject()
+FUNKTION:
+     void RemoveSensitiveObject(object ob)
+
+DEFINIERT IN:
+     /std/container/inventory.c
+     generalizes /std/living/inventory.c
+
+ARGUMENTE:
+     ob - zu entfernendes Objekt
+
+BESCHREIBUNG:
+     Entfernt ob aus den Benachrichtigungslisten des Containers.
+     Wird von thing/moving.c im alten Environment gerufen, wenn
+     P_SENSITIVE gesetzt ist.
+     Ruft dazu RemoveSensitiveObjectFromList().
+
+BEMERKUNGEN:
+     Setzt man P_SENSITIVE nicht als Default sondern situationsabhaengig,
+     dann muss man auch RemoveSensitiveObject im Environment
+     auch selbst rufen!
+
+BEISPIEL:
+     // Fackel (inheriting lightsource)
+     void create() {
+     ...
+       SetProp(P_SENSITIVE,
+        ({({SENSITIVE_INVENTORY_TRIGGER,DT_FIRE,120})}));
+     ...
+     }
+
+     // wenn die Fackel geloescht wird, verliert sie ihre aktive
+     // Eigenschaft und muss das dem environment() mitteilen
+     static int extinguish(string str) {
+      int i;
+      i=::extinguish(str);
+      if(i && QueryProp(P_LIGHT)<=0) {
+       SetProp(P_SENSITIVE,0);
+       if(environment())
+        environment()->RemoveSensitiveObject(this_object());
+      }
+      return i;
+     }
+
+     - empfindliche Objekte wie Eiszapfen koennen jetzt wieder gefahrlos
+       in das selbe environment() bewegt werden
+
+SIEHE AUCH:
+     P_SENSITIVE
+     InsertSensitiveObject
+     insert_sensitive_inv_trigger, insert_sensitive_inv
+     P_SENSITIVE_ATTACK, P_SENSITIVE_INVENTORY, P_SENSITIVE_INVENTORY_TRIGGER
+     CheckSensitiveAttack
+
+25.Apr.2001, Gloinson@MG
+
diff --git a/doc/lfun/RemoveSingularId b/doc/lfun/RemoveSingularId
new file mode 100644
index 0000000..016999c
--- /dev/null
+++ b/doc/lfun/RemoveSingularId
@@ -0,0 +1,28 @@
+RemoveSingularId()
+
+FUNKTION:
+     void RemoveSingularId(mixed id);
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     id
+          Identifikationsstring oder Array von Strings
+
+BESCHREIBUNG:
+     Es werden ein oder mehrere Bezeichner entfernt, mit denen sich eine
+     einzelne Einheit ansprechen laesst.
+
+RUECKGABEWERT:
+     keiner
+
+BEISPIELE:
+     siehe /items/money.c
+
+SIEHE AUCH:
+     AddSingularId(), RemovePluralId(), AddId(), id(), /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Mon Jul 14 11:31:00 1997 by Silvana
+
diff --git a/doc/lfun/RemoveSkillAttributeModifier b/doc/lfun/RemoveSkillAttributeModifier
new file mode 100644
index 0000000..71dfd10
--- /dev/null
+++ b/doc/lfun/RemoveSkillAttributeModifier
@@ -0,0 +1,59 @@
+RemoveSkillAttributeModifier()
+FUNKTION:
+    public int RemoveSkillAttributeModifier(object caster, string atrname)
+
+DEFINIERT IN:
+    /std/living/skill_attributes.c
+
+ARGUMENTE:
+    <atrname>   string
+                Name des Skill-Attributes, von dem der Modifikator geloescht
+                werden soll.
+                (Definiert in /sys/living/skill_attributes.h)
+
+    <caster>    object
+                Objekt, dessen Modifikator wieder entfernt werden soll.
+
+BESCHREIBUNG:
+    Entfernt den Modifikator, den Object <caster> gesetzt hat, wieder. Dies
+    ist nur notwendig, wenn der Effekt vor Ablauf der Gueltigkeit des
+    Modifikators aufgehoben werden soll.
+
+RUECKGABEWERT:
+    SA_MOD_REMOVED         wenn der Modifikator geloescht wurde
+    SA_MOD_NOT_FOUND       wenn der Modifikator nicht gefunden wurde
+    Wenn man nur wissen will, ob die Operation erfolgreich war, empfiehlt es
+    sich, auf == SA_MOD_REMOVED zu pruefen.
+
+BEISPIELE:
+    // eine Waffe setzt im InformWield() einen Bonus auf SA_DAMAGE fuer 10min
+    protected void InformWield(object pl, int silent) {
+      if (objectp(pl)) {
+        if (pl->ModifySkillAttribute(SA_DAMAGE, 20, 600) == SA_MOD_OK)
+          // Erfolgsmeldung an Spieler
+        else
+          // Misserfolgsmeldung an Spieler.
+      }
+    }
+
+    // wenn der Spieler die Waffe vor Ablauf der 600s wegstecken will, muss
+    // der Bonus natuerlich auch wieder raus
+    protected void InformUnwield(object pl, int silent) {
+      if (objectp(pl))
+        pl->RemoveSkillAttributeModifier(this_object(), SA_DAMAGE);
+        // falls kein solcher Mod mehr gesetzt war, liefert RSAM()
+        // SA_MOD_NOT_FOUND zurueck. Auswertung des Rueckgabewertes ist
+        // vernachlaessigt.
+    }
+    
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+
+13.08.2008, Zesstra
diff --git a/doc/lfun/RemoveSmells b/doc/lfun/RemoveSmells
new file mode 100644
index 0000000..cc72207
--- /dev/null
+++ b/doc/lfun/RemoveSmells
@@ -0,0 +1,38 @@
+RemoveSmells()
+
+FUNKTION:
+    void RemoveSmells(string|string* keys);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den zu entfernenden Details.
+
+BESCHREIBUNG:
+    Diese Funktion entspricht dem RemoveDetail() fuer Standarddetails,
+    nur koennen hiermit Gerueche entfernt werden:
+    Entfernt die in <keys> angegebenen Details aus der Liste der
+    vorhandenen Details. Uebergibt man fuer <keys> eine 0, so werden
+    saemtliche Details entfernt!
+
+BEISPIEL:
+    Zuerst erzeugen wir ein kleines Detail, mit dem wir am Rauch riechen
+    koennen. Das Feuer brennt langsam ab und das Detail wird wieder
+    entfernt:
+
+      AddSmells("rauch",* H U S T *\n");
+      call_out(#'RemoveSmells, 100, "rauch");
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/RemoveSounds b/doc/lfun/RemoveSounds
new file mode 100644
index 0000000..50d900a
--- /dev/null
+++ b/doc/lfun/RemoveSounds
@@ -0,0 +1,46 @@
+RemoveSounds()
+
+FUNKTION:
+    void RemoveSounds(string|string* keys);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den zu entfernenden Details.
+
+BESCHREIBUNG:
+    Diese Funktion entspricht dem RemoveDetail() fuer Standarddetails,   
+    nur koennen hiermit Gerauesche entfernt werden:
+    Entfernt die in <keys> angegebenen Details aus der Liste der
+    vorhandenen Details. Uebergibt man fuer <keys> eine 0, so werden
+    saemtliche Details entfernt!
+
+BEISPIEL:
+    Wir lassen etwas Musik spielen und wenn wir den Plattenspieler
+    ausmachen, dann endet sie und man hoert auch nichts mehr:
+
+      int ausmachen(string str);
+      ...
+      AddSounds(({"musik","hip-hop"}) ,"Klingt nach Hip-Hop...\n");
+      AddCmd("mach|mache&plattenspieler&aus", #'ausmachen,
+             "Was willst du (aus)machen?|Willst du den ausmachen?^");
+      ...
+      int ausmachen(string str) {
+        if(!GetDetail("musik", 0, SENSE_SOUND)) // existiert Musikdetail ?
+          return("Der Plattenspieler laeuft doch gar nicht!\n", 1);
+        RemoveSounds(0);
+         return 1;
+      }
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+8. Juli 2011 Gloinson
diff --git a/doc/lfun/RemoveSpecialDetail b/doc/lfun/RemoveSpecialDetail
new file mode 100644
index 0000000..ebec4cb
--- /dev/null
+++ b/doc/lfun/RemoveSpecialDetail
@@ -0,0 +1,37 @@
+VERALTET: RemoveSpecialDetail()
+
+FUNKTION:
+    void RemoveSpecialDetail(string|string* keys);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den zu entfernenden Details.
+
+BESCHREIBUNG:
+    Entfernt die in keys angegebenen Details aus der Liste der
+    vorhandenen SpecialDetails.
+
+    VERALTET: Bitte RemoveDetail() benutzen.
+
+BEMERKUNGEN:
+    Uebergibt man fuer keys eine 0, so werden saemtliche SpecialDetails
+    entfernt!
+    Da intern Details und SpecialDetails im gleichen Mapping verwaltet
+    werden, lassen sich mit dieser Funktion auch Details entfernen.
+    Man sollte diese Funktion deshalb nicht mehr verwenden, siehe
+    AddDetail mit Closures.
+
+SIEHE AUCH:
+    Setzen :   AddDetail(), AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds(), RemoveTouchDetail()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/RemoveSpecialExit b/doc/lfun/RemoveSpecialExit
new file mode 100644
index 0000000..69a18e4
--- /dev/null
+++ b/doc/lfun/RemoveSpecialExit
@@ -0,0 +1,29 @@
+RemoveSpecialExit()
+FUNKTION:
+     void RemoveSpecialExit(string|string* cmd);
+
+DEFINIERT IN:
+     /std/room/exits
+
+ARGUMENTE:
+     string/string* cmd
+          Richtung(en), die entfernt werden sollen.
+
+BESCHREIBUNG:
+     Die in cmd angegebenen Ausgaenge werden wieder entfernt.
+
+     Ist cmd = 0, so werden alle Ausgaenge entfernt.
+
+BEMERKUNGEN:
+     Ausgaenge werden an der gleichen Stelle gespeichert:
+     - RemoveSpecialExit() greift auf die gleichen Daten wie RemoveExit()
+       zu, entfernt also auch normale Ausgaenge!
+
+SIEHE AUCH:
+     AddExit(), AddSpecialExit(), AddGuardedExit(), GetExits()
+     RemoveExit(),
+     P_EXITS, P_HIDE_EXITS, /std/room/exits.c
+     ausgaenge
+
+31.01.2015, Zesstra
+
diff --git a/doc/lfun/RemoveTouchDetail b/doc/lfun/RemoveTouchDetail
new file mode 100644
index 0000000..8b816a4
--- /dev/null
+++ b/doc/lfun/RemoveTouchDetail
@@ -0,0 +1,54 @@
+RemoveTouchDetail()
+
+FUNKTION:
+    void RemoveTouchDetail(string|string* keys);
+
+DEFINIERT IN:
+    /std/thing/description.c
+
+ARGUMENTE:
+    keys
+      String oder Array von Strings mit den zu entfernenden Details.
+
+BESCHREIBUNG:
+    Diese Funktion entspricht dem RemoveDetail() fuer Standarddetails,
+    nur koennen hiermit (ab)tastbare Details entfernt werden:
+    Entfernt die in <keys> angegebenen Details aus der Liste der
+    vorhandenen Details. Uebergibt man fuer <keys> eine 0, so werden
+    saemtliche tastbaren/fuehlbaren Details entfernt!
+
+BEISPIEL:
+    Zuerst wird ein Detail "boden" erzeugt, das abgetastet werden kann.
+    Dieses kann durch Betaetigen eines Knopfes, aeh, entfernt werden.
+
+      int knopf();
+      void knopf2();
+
+      AddTouchDetail("boden", "Er ist aus Stein.\n");
+      AddCmd("drueck|druecke&knopf", #'knopf, "Was willst du druecken?");
+
+      void knopf() {
+        tell_room(this_object(), break_string(
+          this_player()->Name(WER)+" drueckt einen Knopf, der dabei satt "+
+          "klackt.", 78));
+
+        if(find_call_out(#'knopf2)<=0)
+          call_out(#'knopf2, 1);
+      }
+      
+      void knopf2() {
+        tell_room(this_object(), "Uhoh. Der Boden klappt weg. Du faellst.");
+        RemoveTouchDetails("boden");
+      }
+
+SIEHE AUCH:
+    Setzen:    AddDetail(), AddReadDetail(), AddSmells(), AddSounds(),
+               AddTouchDetail()
+    Loeschen:  RemoveDetail(), RemoveReadDetail(), RemoveSmells(),
+               RemoveSounds()
+    Daten:     P_DETAILS, P_READ_DETAILS, P_SMELLS, P_SOUNDS, P_TOUCH_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail(), P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/ResizeRingBuffer b/doc/lfun/ResizeRingBuffer
new file mode 100644
index 0000000..c5a6c08
--- /dev/null
+++ b/doc/lfun/ResizeRingBuffer
@@ -0,0 +1,44 @@
+ResizeRingBuffer()
+
+FUNKTION:
+    protected struct std_ringbuffer buf RingBufferPut(
+                                                   struct std_ringbuffer buf, 
+                                                   int size);
+
+DEFINIERT IN:
+    /std/util/ringbuffer.c
+    /sys/util/ringbuffer.h
+    
+ARGUMENTE:
+    buf  - Ringpuffer, dessen Groesse geaendert werden soll
+    size - neue Groesse (int) 
+
+BESCHREIBUNG:
+    Diese Funktion erstellt einen neuen Ringpuffer der Groesse <size>, welcher
+    den gleichen Modus hat wie <buf> und die gleichen Daten enthaelt.
+    Ist der neue Puffer kleiner als <buf>, so kommt es hierbei zu
+    Datenverlust.
+    <buf> wird nicht veraendert. Ist die Groesse von <buf> gleich der
+    neuen gewuenschten Groesse, wird letztendlich der Ringpuffer kopiert. 
+    Je nach Groesse von <buf> und Wert von <size> kann dies eine teure
+    Angelegenheit sein.
+
+RUeCKGABEWERT:
+    Der neue Ringpuffer mit Groesse <size>.
+
+BEISPIELE:
+    // Ringpuffer anlegen:
+    struct std_ringbuffer buffer = CreateRingBuffer(5, MODE_FIFO);
+    // 5 Werte reinschreiben:
+    foreach(int i: 5) RingBufferPut(buffer, i);
+    // Groesse aendern
+    buffer = ResizeRingBuffer(buffer, 10);
+    // Daten als Array ermitteln:
+    mixed array = RingBufferGet(buffer);
+    // array enthaelt: ({0,0,0,0,0,0,1,2,3,4})
+
+SIEHE AUCH:
+    RingBufferGet(), RingBufferPut(), CreateRingBuffer()
+
+23.05.2008, Zesstra
+
diff --git a/doc/lfun/RingBufferGet b/doc/lfun/RingBufferGet
new file mode 100644
index 0000000..8d6b467
--- /dev/null
+++ b/doc/lfun/RingBufferGet
@@ -0,0 +1,41 @@
+RingBufferGet()
+
+FUNKTION:
+    protected mixed RingBufferGet(struct std_ringbuffer buf);
+
+DEFINIERT IN:
+    /std/util/ringbuffer.c
+    /sys/util/ringbuffer.h
+
+ARGUMENTE:
+    buf - Ringpuffer, welcher ausgeben werden soll
+
+BESCHREIBUNG:
+    Diese Funktion liefert die Daten des Ringpuffers in Form eines Arrays
+    zurueck, welches dann weiterverarbeitet werden kann.
+    Die Reihenfolge der Daten ist entsprechend des beim Anlegen des
+    Ringpuffers angebenen Modes:
+    MODE_FIFO: aelteste Daten zuerst
+    MODE_LIFO: neueste Daten zuerst
+
+BEMERKUNGEN:
+    Aenderungen am Array beeinflussen die Daten des Ringpuffers nicht. Aber:
+    Hierbei werden die Daten nicht tief kopiert. D.h. enthaelt der Ringpuffer
+    Referenzen auf weitere Daten, zeigen der Ringpuffer und das hier
+    gelieferte Array auf die gleichen Daten.
+
+BEISPIELE:
+    // Ringpuffer anlegen:
+    struct std_ringbuffer buffer = CreateRingBuffer(10, MODE_FIFO);
+    // 15 Werte reinschreiben:
+    foreach(int i: 15) RingBufferPut(buffer, i);
+    // Werte abrufen:
+    mixed array=RingBufferGet(buffer);
+    // array enthaelt nun:
+    // ({5,6,7,8,9,10,11,12,13,14}) 
+
+SIEHE AUCH:
+    CreateRingBuffer(), RingBufferPut(), ResizeRingBuffer()
+
+23.05.2008, Zesstra
+
diff --git a/doc/lfun/RingBufferPut b/doc/lfun/RingBufferPut
new file mode 100644
index 0000000..82a78bb
--- /dev/null
+++ b/doc/lfun/RingBufferPut
@@ -0,0 +1,30 @@
+RingBufferPut()
+
+FUNKTION:
+    protected void RingBufferPut(struct std_ringbuffer buf, mixed val);
+
+DEFINIERT IN:
+    /std/util/ringbuffer.c
+    /sys/util/ringbuffer.h
+
+ARGUMENTE:
+    buf - Ringpuffer, in den <val> geschrieben werden soll
+    val - neues Datum
+
+BESCHREIBUNG:
+    Diese Funktion schreibt <val> in den Ringpuffer <buf>. Hierbei wird ggf.
+    das aelteste im Puffer existierende Datum ueberschrieben. <buf> muss eine
+    von CreateRingBuffer() oder ResizeRingBuffer() zurueckgelieferter
+    Ringpuffer sein.
+
+BEISPIELE:
+    // Ringpuffer anlegen:
+    struct std_ringbuffer buffer = CreateRingBuffer(10, MODE_FIFO);
+    // 15 Werte reinschreiben:
+    foreach(int i: 15) RingBufferPut(buffer, i);
+
+SIEHE AUCH:
+    RingBufferGet(), CreateRingBuffer(), ResizeRingBuffer()
+
+23.05.2008, Zesstra
+
diff --git a/doc/lfun/SearchPath b/doc/lfun/SearchPath
new file mode 100644
index 0000000..035fdcb
--- /dev/null
+++ b/doc/lfun/SearchPath
@@ -0,0 +1,83 @@
+SearchPath
+
+FUNKTION:
+     public int SearchPath(string from, string to, int para,
+                           closure callback)
+
+DEFINIERT IN:
+     /p/daemon/pathd.c
+     <sys/path.d>
+
+ARGUMENTE:
+     from     - Der Startpunkt
+     to       - Der Endpunkt
+     para     - Die Parawelt in der gesucht wird (Normalwelt: 0)
+     callback - Closure, die am Ende der Pfadsuche gerufen wird
+
+BESCHREIBUNG:
+    Diese Funktion berechnet - sofern moeglich - den kuerzesten Pfad zwischen
+    <from> und <to> in der (Para-)Welt <para>.
+    
+    Die Pfadsuche wird anhand von Daten ueber von Spielern gelaufene Wege
+    durchgefuehrt. D.h. Gebiete, die von Spielern nicht (in letzter Zeit mal)
+    betreten werden, sind auch dem Pfaddaemon nicht bekannt. Auch kann es
+    Gebiete geben, wo zwar gebietsintern Pfade bekannt sind, aber keine Wege
+    in den Rest vom MG.
+
+    Da diese Suche im Allgemeinen SEHR aufwendig sein kann, wird sie meistens
+    nicht sofort fertig, sondern dauert eine Weile. Wenn sie fertig ist, wird
+    die Closure <callback> aufgerufen und ihr die Argumente <from>, <to>,
+    <parawelt>, <kosten>, <path> und <cmds> uebergeben. Die Bedeutung
+    dieser Argumente ist unten erklaert.
+
+    Eine Suche nach einem Pfad in einer Parawelt fuehrt durch Raeume der
+    gewuenschen Parawelt und durch Raeume der Normalwelt.
+
+RUeCKGABEWERT:
+     1      - Suche wurde gestartet
+     2      - Pfad gefunden (und callback gerufen)
+    -1      - es laeuft schon ein Suchauftrage fuer die UID des anfragenden
+              Objektes
+    -2      - es laufen bereits zuviele Suchanfragen
+    -3      - <from> und/oder <to> sind nicht bekannt
+    
+    An <callback> uebergebene Argumente am Ende der Pfadsuche:
+        <from> - Startpunkt des Weges (string)
+        <to>   - Zielpunkt des Weges (string)
+        <para> - Parawelt des Weges (int)
+        <costs>- Kosten des Wege. (int) Je hoeher, desto
+                 laenger/unguenstiger. 0, wenn kein Pfad gefunden
+        <path> - Array mit Raumnamen, die durchlaufen werden (string*)
+                 0, wenn kein Pfad gefunden
+        <cmds> - Array mit Kommandos zum Ablaufen des Weges (string*)
+                 0, wenn kein Pfad gefunden
+
+BEMERKUNGEN:
+   Es ist natuerlich nicht dazu gedacht, Spielern fertige Routen zwischen
+   Orten zu geben - bzw. nur in Ausnahmefaellen.
+   Pfadabfrgen werden geloggt.
+
+   Die Angabe <costs> sagt grob etwas ueber die Laenge und vor allem ueber die
+   "Qualitaet" des Pfades aus. Die steigt bei Paraweltwechseln, wenig
+   abgelaufenen Verbindungen zwischen Raeumen oder wenn eine Verbindung kein
+   normaler Ausgang ist.
+
+   Die Closure <callback> sollte nicht zuviele Ticks verbrauchen.
+
+BEISPIEL:
+   #include <pathd.h>
+   void suchergebnis(string from, string to, int para, int costs, string*
+        path, string* cmds) {
+        tell_object(find_player("zesstra"), sprintf(
+            "Ergebnis Pfadsuche von %s nach %s in Para %d fuer %d:\n %O\n %O\n",
+            from, to, para, costs, path, cmds));
+   };
+
+   ...
+   mixed res=PATHD->SearchPath("/gilden/abenteurer",
+                               "/d/ebene/dancer/lucky/room/pova_la3",
+                               0, #'suchergebnis);
+
+----------------------------------------------------------------------------
+22.12.2015, Zesstra
+
diff --git a/doc/lfun/SelectEnemy b/doc/lfun/SelectEnemy
new file mode 100644
index 0000000..863e0c0
--- /dev/null
+++ b/doc/lfun/SelectEnemy
@@ -0,0 +1,32 @@
+SelectEnemy()
+
+FUNKTION:
+	varargs object SelectEnemy(object*here);
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	here
+	  Gegner, aus welchen ausgewaehlt werden soll (optional!)
+
+RUeCKGABEWERT:
+	Ausgewaehlter Gegner, der angegriffen werden soll.
+
+BESCHREIBUNG:
+	Diese Funktion waehlt einen Gegner aus, der angegriffen werden soll.
+	Werden keine Gegner im Parameter <here> angegeben, so wird der
+	Rueckgabewert der Funktion PresentEnemies() verwandt, welche die
+	aktuell anwesenden Gegner im Raum liefert.
+	Sind keine Gegner anwesend, so wird 0 zurueckgeliefert.
+	Danach wird geschaut, ob Gegner bevorzugt ausgewaehlt werden sollen.
+	Dies geschieht mittels der Funktion QueryPreferedEnemy().
+	Auch dieser bevorzugte Gegner muss im selben Raum sein! Wenn nicht,
+	wird doch irgendein anderer Gegner ausgewaehlt und zurueckgegeben.
+
+SIEHE AUCH:
+	PresentEnemies(), QueryPreferedEnemy(), P_PREFERED_ENEMY,
+	InsertEnemy(), StopHuntFor()
+
+----------------------------------------------------------------------------
+Last modified: Thu May 27 15:01:48 1999 by Patryn
diff --git a/doc/lfun/SelectFarEnemy b/doc/lfun/SelectFarEnemy
new file mode 100644
index 0000000..d574dcc
--- /dev/null
+++ b/doc/lfun/SelectFarEnemy
@@ -0,0 +1,45 @@
+
+SelectFarEnemy()
+
+
+FUNKTION:
+        varargs object SelectFarEnemy(object *here, int min, int max,
+                                      int forcefrom)
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        here       - Rueckgabewert von PresentEnemies()
+        min        - minimale Kampfreihe
+        max        - maximale Kampfreihe
+        forcefrom  - Gegner MUSS aus uebergebenem Array ausgewaehlt werden
+
+BESCHREIBUNG:
+        Waehlt einen Feind aus Reihe <min> bis <max> aus.
+
+RUECKGABEWERT:
+        Der Auserwaehlte :-)
+
+BEMERKUNGEN:
+        1. Wenn in den angegeben Reihen kein Feind ist oder <max> kleiner
+           als <min> ist, wird auch keiner zurueckgegeben.
+        2. Aus Effizienzgruenden sollte forcefrom nur benutzt werden, wenn
+           es wirklich noetig ist (s. hierzu auch SelectNearEnemy()).
+        3. 0 <= <min> <= <max> < MAX_TEAMROWS
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/SelectNearEnemy b/doc/lfun/SelectNearEnemy
new file mode 100644
index 0000000..998bee8
--- /dev/null
+++ b/doc/lfun/SelectNearEnemy
@@ -0,0 +1,49 @@
+
+SelectNearEnemy()
+
+
+FUNKTION:
+        varargs object SelectNearEnemy(object *here, int forcefrom)
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        here      - Rueckgabewert von PresentEnemies()
+        forcefrom - Gegner MUSS aus uebergebenem Array ausgewaehlt werden
+
+BESCHREIBUNG:
+        Waehlt einen im Nahkampf erreichbaren Feind aus
+
+RUECKGABEWERT:
+        Der Auserwaehlte :-)
+
+BEMERKUNGEN:
+        1. Falls der Spieler in einem Team ist und in einer hinteren Reihe
+           steht, wird kein Feind ausgewaehlt, es sei denn, der Spieler hat
+           einen Kampf mit einem Teammitglied angefangen.
+        2. Wenn ein bevorzugter Feind in einer der hinteren Reihen eines
+           Teams steht, wird solange das Team bevorzugt.
+        3. Auch Feinde in den hinteren Reihen koennen im Nahkampf erreichbar
+           sein, wenn die vorderen Reihen nicht genuegend Deckung bieten.
+        4. ACHTUNG: Der Auserwaehlte kommt nicht notwendigerweise aus dem
+           uebergebenen Array, wenn forcefrom=0 ist. Normalerweise ist dieses
+           Verhalten beabsichtigt, damit jemand, der sich in der Reihe vor
+           einen Gegner stellt, angegriffen wird, auch wenn er noch nicht
+           Feind ist.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/Set b/doc/lfun/Set
new file mode 100644
index 0000000..42e6930
--- /dev/null
+++ b/doc/lfun/Set
@@ -0,0 +1,137 @@
+Set()
+FUNKTION:
+     public varargs mixed Set(string name, mixed Value, int Type, int extern);
+
+DEFINIERT IN:
+     /std/thing/properties.c
+     /sys/thing/properties.h (Prototyp)
+
+ARGUMENTE:
+     name - Property, die manipuliert werden soll
+     Value - der zu setzende/aendernde Wert
+     Type - die Eigenschaft der Property, die manipuliert werden soll
+     extern - Interne Verwendung:
+    Wurde Set ueber SetProp von aussen gerufen.
+
+BESCHREIBUNG:
+     Eine der inneren Eigenschaften der Property 'name' wird veraendert.
+     'Type' ist dabei einer der in /sys/thing/properties.h definierten
+     F_XXX - Werte:
+
+     F_VALUE (==0, default)
+       Setzt den Inhalt der Property auf 'Value'. Aehnlich "SetProp",
+       umgeht jedoch eine etwaige F_SET_METHOD oder _set_'name'()-Methode.
+     F_MODE
+     F_MODE_AS
+     F_MODE_AD
+       Aendert eines der internen Flags der Property. F_MODE negiert den
+       vorherigen Wert vom Flag 'Value', F_MODE_AS setzt und F_MODE_AD
+       loescht ihn.
+       Verfuegbare interne Flags:
+         SAVE 
+           Property wird bei save_object() gespeichert
+         PROTECTED 
+           Flag setzbar durch:   beliebiges Objekt
+           Flag loeschbar durch: this_object(), ROOT, EM+
+           Inhalt der Property veraendern sowie Set- und Query-Methoden
+           setzen oder loeschen duerfen nur noch this_object(), ROOT, EM+
+           WARNUNG: Dieses Flag nicht leichtfertig bei Spielern setzen!
+         SECURED  
+           Flag setzbar durch:   this_object(), ROOT, EM+
+           Flag loeschbar durch: Niemanden!
+           Inhalt der Property veraendern sowie Set- und Query-Methoden
+           setzen oder loeschen duerfen nur noch this_object(), ROOT, EM+
+         NOSETMETHOD 
+           Property nicht mehr ueber SetProp() aenderbar
+           (damit entfallen auch SET_METHOD, _set_'name')
+     F_SET_METHOD
+       Aendert den Eintrag fuer eine SetMethod - eine Closure, die anstatt
+       des Setzens der Property beim Aufruf von SetProp mit 'Value'
+       aufgerufen wird.
+     F_QUERY_METHOD
+       Aendert den Eintrag fuer eine QueryMethod - eine Closure, die anstatt
+       des Lesens der Property beim Aufruf von QueryProp aufgerufen wird.
+
+RUeCKGABEWERT:
+     Das Ergebnis der Manipulation bzw. einer der definierten
+     Fehlercodes.
+
+BEMERKUNGEN:
+     - Set() sollte nicht zum regulaeren Manipulieren des Inhalts einer
+       Property verwendet werden, da sowohl F_SET_METHOD als auch libinterne
+       _set_'name'()-Methoden umgangen werden und das Ergebnis fuer so
+       veraenderte Properties undefiniert ist.
+     - eine gesetzte F_SET/F_QUERY_METHOD hat bei SetProp/QueryProp Vorrang
+       vor einer _set/_query_method
+       -> _set/_query wird nach erfolgreichem Ruf von F_XXX_METHOD ignoriert
+     - F_SET/F_QUERY_METHOD sollte normalerweise Vorzug vor einer
+       _set_/_query_* gegeben werden.
+
+    SetMethods/QueryMethods:
+     - falls ihr Query/SetMethods an oeffentlichen Properties setzen
+       wollt, prueft bitte vorher, ob dort nicht schon eine (fremde) gesetzt
+       ist und brecht ggf. euer Set() ab, um nicht die Arbeit anderer
+       Mitmagier zu sabotieren (z.B. P_HANDS)
+     - Properties sollten mit Query- oder SetMethoden nur so lange wie
+       noetig belegt werden
+       -> manche Properties sollte man als Wert setzen, _auch wenn_ die
+          Spieler sie zuruecksetzen koennten (zB P_MSGIN/P_MSGOUT)
+     - auf keinen Fall den Wert speichern, ueberschreiben, rueckschreiben,
+       das fuehrt fast immer zu Problemen.
+     - Set/QueryMethoden sollten nicht als Trigger/Listener fuer ein
+       Ereignis (z.B. P_DIE_MSG fuer das Ereignis "Tod des Spielers")
+       missbraucht werden
+       -> es gibt sichere und saubere Moeglichkeiten (NotifyPlayerDeath),
+          und wenn nicht, wendet euch an den EM eures Vertrauens
+     - F_SET/F_QUERY_METHODs koennen 'protected' (empfohlen) oder 'static'
+       sein. _set_/_query_ duerfen momentan _nicht_ 'protected' sein, fuer
+       geht nur 'static' (in diesem Fall empfohlen).
+
+BEISPIELE:
+     ### Aendern von Eigenschaften einer Property ###
+     // Setzen des SAVE-Flags (bei save_object() mitzuspeichern)
+     Set(P_XYZ, SAVE, F_MODE_AS);
+
+     // Loeschen des SAVE-Flags
+     Set(P_XYZ, SAVE, F_MODE_AD);
+     
+     // Negieren des bisherigen SAVE-Flags
+     Set(P_XYZ, SAVE, F_MODE);
+     // Hinweis: das Setzen des Flags funktioniert mittels F_MODE nur dann,
+     // wenn sichergestellt ist, dass es vorher nicht gesetzt war. Die 
+     // sichere Variante ist daher, F_MODE_AS zu verwenden.
+
+     // Sperren des SetProp/SET_METHOD-Zugriffs:
+     Set(P_XYZ, NOSETMETHOD, F_MODE_AS);
+
+     // Vorlaeufiger Zugriffsschutz fuer eine Property:
+     Set(P_XYZ, PROTECTED, F_MODE_AS);
+
+     // Permanenter Zugriffsschutz fuer eine Property:
+     Set(P_XYZ, SECURED, F_MODE_AS);
+
+     ### Setzen einer SetMethod/QueryMethod ###
+     // Setzen einer internen SetMethod
+     mixed foo(mixed val);
+     ...
+     Set(P_XYZ, #'foo, F_SET_METHOD);
+     ...
+
+     // Setzen einer QueryMethod bei einem anderen Objekt
+     mixed bar();
+     ...
+     other->Set(P_XYZ, #'bar, F_QUERY_METHOD);
+     ...
+
+     // Der Vollstaendigkeit halber sei das Aendern einer Property unter
+     // Umgehung von Set-Methoden angegeben. Es ist aber aus o.g. Gruenden
+     // zu empfehlen, diese Variante nicht zu verwenden.
+     Set(P_XYZ, "bla", F_VALUE);
+
+SIEHE AUCH:
+     Aehnliches: SetProp(L), QueryProp(L), Query(L)
+     Generell:  SetProperties(L), QueryProperties(L)
+     Konzept:  properties, /std/thing/properties.c
+     Sonstiges:  P_AUTOLOADOBJ
+
+06. Jan 2008 Arathorn
diff --git a/doc/lfun/SetAttackChats b/doc/lfun/SetAttackChats
new file mode 100644
index 0000000..87203a1
--- /dev/null
+++ b/doc/lfun/SetAttackChats
@@ -0,0 +1,68 @@
+SetAttackChats()
+
+FUNKTION:
+     void SetAttackChats(int chance, mixed strs);
+
+DEFINIERT IN:
+     /std/npc/chat.c
+
+ARGUMENTE:
+     chance
+          Prozentuale Wahrscheinlichkeit einer Ausgabe
+     strs
+          Stringarray mit den Monsterchats
+
+BESCHREIBUNG:
+     Der NPC gibt mit der Wahrscheinlichkeit 'chance' einen zufaellig
+     gewaehlten Text aus 'strs' von sich. Die Arrayelemente koennen 
+     auch Funktionen ("@@func@@") oder Closures enthalten, die dann
+     aufgerufen werden und deren Rueckgabewerte das Monster dann ausgibt.
+
+RUECKGABEWERT:
+     keiner
+     
+BEMERKUNGEN:
+     AttackChats werden nur im Kampf ausgegeben. Ansonsten ist SetChats()
+     zu verwenden.
+     
+     'chance' wird in der Property P_ACHAT_CHANCE abgelegt. Um einen NPC
+     voruebergehend 'stillzulegen', kann man P_ACHAT_CHANCE auf 0 setzen.
+     
+     Man kann AttackChats nutzen, um Monsterspells zu realisieren. Besser
+     ist es aber, dafuer 'AddSpell' zu verwenden.
+     
+BEISPIELE:
+
+     SetAttackChats( 20,
+       ({ "Der Ork tritt Dir in den Hintern.\n",
+          "Der Ork bruellt: Lebend kommst Du hier nicht raus!\n",
+          "Der Ork blutet schon aus mehreren Wunden.\n",
+          "@@knirsch@@" }) );
+          
+     string knirsch()
+     {
+       object *ruestung, *tmp, helm;
+       
+       ruestung = this_player()->QueryProp(P_ARMOURS); // getragene Ruestung
+       tmp = filter_objects(ruestung, "id", AT_HELMET);
+       // Wenn der Spieler einen Helm traegt, enthaelt 'tmp' jetzt
+       // ein Array mit dem Helmobjekt als einzigem Element
+       if (sizeof(tmp)) helm = tmp[0];
+	 if (objectp(helm))
+	 {
+	   // AC nur dann senken, wenn sie nicht schon 0 ist.
+	   if (helm->QueryProp(P_AC)>0) {
+	     helm->Damage(1);
+	     return "Der Ork beschaedigt Deinen Helm!\n";
+	   }
+	   return "";
+	 }
+	 else
+	   return ""; // keine Meldung
+     }
+
+SIEHE AUCH:
+     P_ACHAT_CHANCE, SetChats(), /std/npc/chat.c, AddSpell()
+
+LETZTE AENDERUNG:
+	Don, 27.12.2007, 16:35:00 von Arathorn
diff --git a/doc/lfun/SetAttr b/doc/lfun/SetAttr
new file mode 100644
index 0000000..8ecf381
--- /dev/null
+++ b/doc/lfun/SetAttr
@@ -0,0 +1,31 @@
+SetAttr()
+FUNKTION:
+     private static int SetAttr(string attr, int val)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     attr       - zu setzendes Attribut
+     val        - Wert
+
+BESCHREIBUNG:
+     Filtert den Wert durch _filterattr(). Dadurch werden STR, INT, CON, DEX
+     auf 20 begrenzt. Setzt dann das Attribut.
+     Offsets werden hier nicht beruecksichtigt, QueryAttribute() gibt also
+     val + etwaige Offsets/Modifier zurueck.
+
+RUeCKGABEWERT:
+     Tatsaechlich gesetzter Wert.
+
+BEMERKUNGEN:
+     Wird von SetAttribute() und SetRealAttribute() aufgerufen.
+
+SIEHE AUCH:
+     QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+     SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+     TestAttributeLock(),

+     P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_ATTRIBUTES_MODIFIER,

+     P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+
+13.Nov.2002, Gloinson
\ No newline at end of file
diff --git a/doc/lfun/SetAttribute b/doc/lfun/SetAttribute
new file mode 100644
index 0000000..bab54f2
--- /dev/null
+++ b/doc/lfun/SetAttribute
@@ -0,0 +1,28 @@
+SetAttribute()
+FUNKTION:
+     int SetAttribute(string attr, int val)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     attr       - zu setzendes Attribut
+     val        - Wert
+
+BESCHREIBUNG:
+     Nimm val als Gesamtwert des Attributes, d.h. zieht etwaige Offsets vor
+     Setzen ab. (QueryAttribute gibt dann also val zurueck)
+
+RUeCKGABEWERT:
+     Den durch SetAttr gefilterten gesetzten Wert.
+     Bitte nicht auf Spieler anwenden!
+
+SIEHE AUCH:

+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+	SetTimedAttrModifier(), QueryTimedAttrModifier(), 

+	DeleteTimedAttrModifier(),

+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,

+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+----------------------------------------------------------------------------

+Last modified: Tue Jul 27 20:00:20 2004 by Muadib

diff --git a/doc/lfun/SetBuyFact b/doc/lfun/SetBuyFact
new file mode 100644
index 0000000..b5154c7
--- /dev/null
+++ b/doc/lfun/SetBuyFact
@@ -0,0 +1,36 @@
+SetBuyFact()
+
+FUNKTION:
+     void SetBuyFact(int fact);
+
+DEFINIERT IN:
+     /std/laden.c
+
+ARGUMENTE:
+     fact
+          Der Einkaufspreismultiplikator.
+
+BESCHREIBUNG:
+     Der Preis, der beim Kauf eines Objekts im Laden zu entrichten ist,
+     errechnet sich aus seinem Wert ( P_VALUE), multipliziert mit dem Faktor
+     fact. Dieser Preis ist konstant und nicht von der aktuellen Marktlage
+     abhaengig.
+
+     Der Defaultwert ist 3. Ein hoeherer Wert entspricht einem teuren Laden,
+     waehrend ein kleinerer Wert zu kleinen Preisen fuehrt.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Normalerweise kommt man ohne diese Funktion aus: in teuren Laeden wird
+     nicht viel eingekauft (es sei denn, es liegen standardmaessig gute
+     Objekte im Speicher), einem Billigladen wird bald das Geld ausgehen mit
+     der Folge, dass der Ladenbesitzer nichts mehr ankaufen kann und sein
+     Lager gaehnend leer ist.
+
+SIEHE AUCH:
+     QueryBuyFact(), /std/laden.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:24:52 1996 by Wargon
diff --git a/doc/lfun/SetChats b/doc/lfun/SetChats
new file mode 100644
index 0000000..3f425a8
--- /dev/null
+++ b/doc/lfun/SetChats
@@ -0,0 +1,69 @@
+SetChats()
+
+FUNKTION:
+	void SetChats(int chance,mixed strs);
+
+DEFINIERT IN:
+	/std/npc/chat.c
+
+ARGUMENTE:
+	chance
+	  Prozentuale Wahrscheinlichkeit einer Ausgabe
+	strs
+	  Stringarray mit den Monsterchats
+
+BESCHREIBUNG:
+	Der NPC gibt mit der Wahrscheinlichkeit <chance> pro Heartbeat einen
+	zufaellig gewaehlten Text aus dem Array <strs> von sich.
+	Die Arrayelemente koennen auch Closures oder
+	process_string()-Funktionen ("@@func@@") enthalten, die dann
+	aufgerufen werden und deren Rueckgabewerte das Monster dann ausgibt.
+	 (Fuer keine Ausgabe dann Leerstring "" zurueckgeben!)
+	In diesen Funktionen ist this_player() das Monster selbst!
+	Fuer Zeilenumbrueche ist immer selbst zu sorgen.
+
+RUECKGABEWERT:
+	keiner
+
+BEISPIELE:
+	Ein einfaches Beispiel:
+	  // Prototype fuer Closure.
+	  static string info1();
+	  void create()
+	  { ...
+	    SetChats(20,
+	   ({"Der Ork sagt: Hau ab, bevor ich Dich fresse.\n",
+	     "Der Ork grinst Dich unverschaemt an.\n",
+	     "Der Ork wedelt mit seinem Saebel vor Deinem Gesicht herum.\n",
+	     "Der Ork droht Dir mit der Faust.\n",
+             #'info1,
+	     "@@info2@@"}));
+          }
+	  // Funktion als Closure. Prototype notwendig!
+	  static string info1()
+	  { if(QueryProp(P_HP)<QueryProp(P_ALIGN))
+	      return"Gleich werde ich von hier fliehen!\n";
+	    return"";
+	  }
+	  // Funktion als process_string().
+	  string info2()
+	  { return QueryProp(P_HP)==QueryProp(P_MAX_HP)?
+	 "Der Ork grinst: Mir geht es fantastisch!\n":
+	 "Der Ork seufzt: Mir ging es wirklich schon mal besser.\n";
+	  }
+
+BEMERKUNGEN:
+	Im Kampf werden keine Chats ausgegeben. Es ist dann SetAttackChats()
+	zu verwenden.
+	Funktionen als process_string() sollte man nicht mehr verwenden.
+	<chance> wird in der Property P_CHAT_CHANCE abgelegt. Um einen NPC
+	voruebergehend 'stillzulegen', kann man P_CHAT_CHANCE auf 0 setzen.
+  Wenn kein Spieler anwesend ist, haben NPC in der Regel keinen Heartbeat,
+  weswegen dann auch die Chats ausgeschaltet sind.
+  Spieler koennen NPC 'stillen', d.h. Chats und AttackChats abschalten.
+
+SIEHE AUCH:
+	P_CHAT_CHANCE, SetAttackChats(), process_string()
+
+----------------------------------------------------------------------------
+Last modified: Sat Jan 18 18:48:06 2003 by Patryn
diff --git a/doc/lfun/SetCoinsPerUnits b/doc/lfun/SetCoinsPerUnits
new file mode 100644
index 0000000..07e3879
--- /dev/null
+++ b/doc/lfun/SetCoinsPerUnits
@@ -0,0 +1,38 @@
+SetCoinsPerUnits()
+
+FUNKTION:
+     void SetCoinsPerUnits(int coins, int units);
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     coins
+          Zahl der Muenzen
+     units
+          Zahl der Einheiten
+
+BESCHREIBUNG:
+     Es wird festgelegt, wieviel eine bestimmte Menge der Einheiten kostet.
+     Eine einzelne Einheit kostet coins/units Muenzen.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Bei der Preisberechnung wird abgerundet. Hat man also ein Verhaeltnis
+     von einer Muenze pro zwei Einheiten, so ist der Preis einer einzelnen
+     Einheit 0!
+
+BEISPIELE:
+     Eine Einheit soll 3.5 Muenzen wert sein:
+
+     /* 7 Muenzen / 2 Einheiten = 3.5 Muenzen / Einheit */
+     SetCoinsPerUnits(7,2);
+
+SIEHE AUCH:
+     QueryCoinsPerUnits(), SetGramsPerUnits(), QueryGramsPerUnits(),
+     /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:24:57 1996 by Wargon
diff --git a/doc/lfun/SetDoorStatus b/doc/lfun/SetDoorStatus
new file mode 100644
index 0000000..1948637
--- /dev/null
+++ b/doc/lfun/SetDoorStatus
@@ -0,0 +1,29 @@
+FUNKTION:
+     void SetDoorStatus(string dest, int status);
+
+DEFINIERT IN:
+     /obj/doormaster.c
+
+ARGUMENTE:
+     <dest>   = Zielraum der Tuer.
+     <status> = Der neue Zustand der Tuer.
+
+BESCHREIBUNG:
+     Der Zustand der Tuer, die von diesem Raum nach <dest> fuehrt, wird auf
+     <status> geaendert. Hierbei muss <status> einer der drei folgenden Werte
+     aus <doorroom.h> sein:
+
+       D_STATUS_LOCKED - Tuer abgeschlossen
+       D_STATUS_CLOSED - Tuer geschlossen
+       D_STATUS_OPEN   - Tuer geoeffnet
+
+RUECKGABEWERT:
+     keiner
+
+
+SIEHE AUCH:
+    NewDoor(), QueryDoorKey(), QueryDoorStatus(), P_DOOR_INFOS,
+    /std/room/doors.c, /obj/doormaster.c, GetPhiolenInfos(), QueryAllDoors()
+
+-----------------------------------------------------------------------------
+Letzte Aenderung: Don, 08.05.2014, Gabylon
diff --git a/doc/lfun/SetEnemies b/doc/lfun/SetEnemies
new file mode 100644
index 0000000..6c79a56
--- /dev/null
+++ b/doc/lfun/SetEnemies
@@ -0,0 +1,33 @@
+SetEnemies()
+
+FUNKTION:
+     mapping SetEnemies(object *myenemies);
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+ARGUMENTE:
+     myenemies
+	  Array: ({Gegnerarray, Zeitenarray})
+
+RUeCKGABEWERT:
+     Internes Mapping mit bekannten Gegnern und Zeiten.
+
+BESCHREIBUNG:
+     Normalerweise fuegt man einzelne Gegner mittels InsertEnemy() ein und
+     loescht alte Feinde mittels StopHuntFor().
+
+     Um jedoch mit einem Schlag viele Veraenderungen vorzunehmen, kann man
+     die Funktion SetEnemies() nutzen.
+
+     Ihr uebergibt man ein Array mit einem Array mit den gewuenschten Gegnern
+     als und einem zweiten, gleichgrossen Array mit den Zeiten, wie lange
+     diese Gegner aktuell sein sollen, als Eintraege.
+
+     Die Funktion traegt diese Werte als Gegner mit entsprechender
+     Feindeszeit ein.
+
+SIEHE AUCH:
+     InsertEnemy(), StopHuntFor(), SelectEnemy(), PresentEnemies()
+
+10.Feb 2005 Gloinson
diff --git a/doc/lfun/SetGramsPerUnits b/doc/lfun/SetGramsPerUnits
new file mode 100644
index 0000000..fcbf9a4
--- /dev/null
+++ b/doc/lfun/SetGramsPerUnits
@@ -0,0 +1,32 @@
+SetGramsPerUnits()
+
+FUNKTION:
+     void SetGramsPerUnits(int grams, int units);
+
+DEFINIERT IN:
+     /std/unit.c
+
+ARGUMENTE:
+     grams
+          Gewicht in Gramm
+     units
+          Zahl der Einheiten
+
+BESCHREIBUNG:
+     Es wird festgelegt, wieviel eine bestimmte Menge der Einheiten wiegt.
+     Eine einzelne Einheit wiegt grams/units Gramm.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+     Vier Einheiten sollen 3 Gramm wiegen:
+
+     SetGramsPerUnits(3,4);
+
+SIEHE AUCH:
+     SetCoinsPerUnits(), QueryCoinsPerUnits(), QueryGramsPerUnits(),
+     /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:25:09 1996 by Wargon
diff --git a/doc/lfun/SetProp b/doc/lfun/SetProp
new file mode 100644
index 0000000..b2602fb
--- /dev/null
+++ b/doc/lfun/SetProp
@@ -0,0 +1,47 @@
+SetProp()
+FUNKTION:
+     public mixed SetProp(string name, mixed Value);
+
+DEFINIERT IN:
+     /std/thing/properties.c
+     /sys/thing/properties.h (Prototyp)
+
+ARGUMENTE:
+     name	- Property, deren Wert veraendert werden soll.
+     Value	- Wert, auf den der Inhalt der Property gesetzt werden soll
+
+BESCHREIBUNG:
+     Der Datenwert der Property 'name' wird auf den Wert 'Value' gesetzt.
+
+     Existiert eine F_SET_METHOD oder eine _set_'name'()-Methode fuer
+     diese Property, so wird diese aufgerufen und ihr 'Value' uebergeben.
+     Eine F_SET_METHOD hat dabei Vorrang vor _set_'name'(), d.h.
+     _set_'name'() wird nach erfolgreicher F_QUERY_METHOD nicht mehr
+     gerufen.
+
+     (Diese Methoden nutzen dann Set(), um den Datenwert der Property
+      'name' zu aendern. Teilweise werden aber auch interne Variablen so
+      oeffentlich gemacht und sind nicht in der ueber Set/Query verfuegbaren
+      Property 'name' abgelegt.)
+
+RUeCKGABEWERT:
+     Der Wert, der nun in der Property gespeichert ist.
+     In der Regel ist das 'Value'. Wenn die Property ueber eine SET_METHOD
+     oder eine _set_'name'()-Funktion verfuegt und diese 'Value' aendert
+     (zum Beispiel, indem sie 'Value' an einen bestimmten erlaubten
+     Wertebereich anpasst), kann der Rueckgabewert jedoch auch veraendert
+     sein.
+
+     Wenn die Property nicht veraendert werden darf, wird -1 zurueckgegeben.
+
+BEISPIELE:
+     // geben wir dem Zwerg eine Kurzbeschreibung
+     SetProp(P_SHORT, "Ein kleiner Zwerg");
+
+SIEHE AUCH:
+     Aehnliches:	QueryProp(L), Set(L), Query(L)
+     Generell:		SetProperties(L), QueryProperties(L)
+     Konzept:		properties, /std/thing/properties.c
+
+15.Dez 2004 Gloinson
+
diff --git a/doc/lfun/SetProperties b/doc/lfun/SetProperties
new file mode 100644
index 0000000..4a1fa1d
--- /dev/null
+++ b/doc/lfun/SetProperties
@@ -0,0 +1,27 @@
+SetProperties()
+FUNKTION:
+     void SetProperties(mapping props);
+
+DEFINIERT IN:
+     /std/thing/properties.c
+
+ARGUMENTE:
+     props	- Mapping mit den Daten fuer alle Properties
+
+BESCHREIBUNG:
+     Diese Funktion setzt angegebene Properties auf einen Schlag.
+     Mapping muss wie folgt aufgebaut sein:
+	([ name: wert; flags; set_method; query_method,
+	   name2: ... ]);
+
+BEMERKUNGEN:
+     - diese Funktion wird von restore_object() verwendet, um nicht alle
+       restaurierten Properties einzeln setzen zu muessen.
+     - SECURED/PROTECTED/NOSETMETHOD Properties werden beruecksichtigt
+
+SIEHE AUCH:
+     Aehnliches:	SetProp(L), QueryProp(L), Set(L), Query(L)
+     Generell:		QueryProperties(L)
+     Konzept:		properties, /std/thing/properties.c
+
+1.Mai 2004 Gloinson
diff --git a/doc/lfun/SetRealAttribute b/doc/lfun/SetRealAttribute
new file mode 100644
index 0000000..68ea14c
--- /dev/null
+++ b/doc/lfun/SetRealAttribute
@@ -0,0 +1,31 @@
+SetRealAttribute()
+FUNKTION:
+     int SetRealAttribute(string attr, int val)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     attr       - zu setzendes Attribut
+     val        - Wert
+
+BESCHREIBUNG:
+     Setzt den realen Wert des Attributes, d.h. das reine Attribut,
+     wenn moeglich. Lediglich eine Alias-Methode fuer SetAttr().
+     (QueryAttribute() gibt also val + etwaige Offsets/Modifier zurueck)
+
+RUeCKGABEWERT:
+     Den gesetzten Wert.
+
+BEMERKUNGEN:
+     Bitte nicht auf Spieler anwenden!
+
+SIEHE AUCH:

+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+	SetTimedAttrModifier(), QueryTimedAttrModifier(), 

+	DeleteTimedAttrModifier(),

+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,

+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+----------------------------------------------------------------------------

+Last modified: Tue Jul 27 20:00:20 2004 by Muadib

diff --git a/doc/lfun/SetSpellFatigue b/doc/lfun/SetSpellFatigue
new file mode 100644
index 0000000..c34627b
--- /dev/null
+++ b/doc/lfun/SetSpellFatigue
@@ -0,0 +1,75 @@
+SetSpellFatigue
+
+FUNKTION:
+    public varargs int SetSpellFatigue(int duration, string key)
+
+DEFINIERT IN:
+    /std/living/skills.c
+    /std/player/skills.c
+    /sys/living/skills.h
+
+ARGUMENTE:
+    int duration: Wie lang soll die Spruchermuedung andauern?
+    string key  : Eindeutiger Name des Spruches, einer Gruppe von Spruechen
+                  oder 0 fuer die globale Spruchermuedung.
+
+BESCHREIBUNG:
+    Diese Funktion dient zum Verwalten von individuellen Spruchermuedungen
+    (Spellfatigue, Spruchsperren).
+    Hiermit lassen sich unabhaengige Ermuedungen/Sperren fuer einzelne
+    Sprueche oder Gruppen von Spruechen gestalten.
+
+    <duration> ist die Zeit (in Sekunden), welche die Spruchermuedung
+    anhalten soll (nicht die Endzeit).
+
+    Wird <key> nicht angegeben oder ist 0, wird die globale Spruchsperre
+    gesetzt (identisch zu der Property P_NEXT_SPELL_TIME), anderenfalls die
+    unter <key> gespeicherte Spruchermuedung.
+    Setzt man einen Eintrag ohne Angabe von <key> bedeutet dies damit auch,
+    dass der Wert von P_NEXT_SPELL_TIME geaendert wird.
+
+RUeCKGABEWERT:
+    -1    Der Eintrag <key> ist noch nicht abgelaufen, es wurde _keine_
+          neue Spruchermuedung/-Sperre gespeichert.
+
+    >0    Eintrag wurde gespeichert, Rueckgabewert ist die Zeit, zu der die
+          Sperre ablaeuft.
+
+BEISPIELE:
+    Ein Spell gehoert zu einer Gruppe von Spells mit dem Namen 'extrasuess'.
+    Er darf nur ausgefuehrt werden, wenn seit 5s kein anderer Spruch aus der
+    Gruppe ausgefuehrt wurde.
+    if (CalculateSpellSuccess(...) > x) {
+      // Spellfatigue setzen (und Erfolg pruefen!)
+      if (ob->SetSpellFatigue(5, "extrasuess") > -1) {
+        tell_object(ob, "Du fuetterst " + enemy->Name(WEN) + " mit einem "
+          "Stueck suesser Schokotorte.\n");
+        ...
+      }
+      else {
+        // Sauerei! Zu ermuedet fuer diesen Spruch. Fehlermdeldung ...
+      }
+    }
+    Dieses setzt natuerlich voraus, dass alle anderen Sprueche der Gruppe
+    "extrasuess" den gleichen <key> pruefen und setzen.
+    (Will man vor CalculateSpellSuccess() wissen, ob der Spruch ueberhaupt
+     gewirkt werden duerfte, sollte man hierzu dann CheckSpellFatigue()
+     verwenden.)
+
+BEMERKUNGEN:
+    Die genauen Zeitdauern koennen von Spielern beeinflusst werden, sie
+    unterliegen der jeweiligen Einstellung von 'spruchermuedung', d.h. koennen
+    auf volle 2s aufgerundet werden. (Dies ist nicht der Fall bei NPC.)
+    Auch wenn diese Funktion zum Verwalten von beliebigen Zeitsperren genutzt
+    werden koennen, beschraenkt euch bitte auf Spruchermuedungen und benutzt
+    ansonsten check_and_update_timed_key(). Falls ihr diesbzgl. weitere/andere
+    Wuensche habt, sprecht den/die Mudlib-EM an.
+
+SIEHE AUCH:
+    CheckSpellFatigue(L), DeleteSpellFatigue(L)
+    P_NEXT_SPELL_TIME
+    spruchermuedung
+
+----------------------------------------------------------------------------
+27.03.2010, Zesstra
+
diff --git a/doc/lfun/SetStorageRoom b/doc/lfun/SetStorageRoom
new file mode 100644
index 0000000..4655a1e
--- /dev/null
+++ b/doc/lfun/SetStorageRoom
@@ -0,0 +1,74 @@
+SetStorageRoom()
+
+FUNKTION:
+        void SetStorageRoom(string store);
+
+DEFINIERT IN:
+        /std/room/shop.c
+
+ARGUMENTE:
+        store
+          Dateiname des Lagers, in dem die aufgekauften Objekte aufbewahrt
+          werden.
+
+RUeCKGABEWERT:
+        keiner
+
+BESCHREIBUNG:
+        Mit dieser Funktion wird dem Laden bekannt gegeben, welches Objekt
+        als Lager fuer angekaufte Objekte dienen soll. Jeder Laden muss
+        explizit einen eigenen Lagerraum setzen, ansonsten wird ein 
+        Laufzeitfehler ausgeloest und der Laden ist nicht ladbar.
+        
+        Das Speicherobjekt sollte /std/store.c erben, da dort einige
+        Aufraeumfunktionen definiert sind. Entscheidend fuer selbige sind
+        die Properties P_MIN_STOCK und P_STORE_CONSUME.
+
+BEISPIELE:
+        Der Raum 'myladen.c' koennte etwa so aussehen:
+          
+          // myladen.c
+          inherit "/std/shop";
+          #include <properties.h>
+          
+          protected void create() {
+            ::create();
+            SetProp(...); // Beschreibung wie bei normalen Raeumen
+            SetStorageRoom("/d/beispiel/mystore");
+            AddFixedObject("/items/fackel");
+          }
+
+        In diesem Laden wird nun die Standardfackel als mengenmaessig 
+        unbegrenzter Artikel verkauft.
+
+        Der zugehoerige Lagerraum 'mystore.c' kann dann im einfachsten Fall
+        so aussehen:
+          
+          // mystore.c
+          inherit "/std/store";
+          #include <rooms.h>  // Fuer AddItem-Konstanten
+          
+          protected void create() {
+            ::create();
+            // KEINE weiteren Beschreibungen!
+            // 1. erbt der Speicher keine Beschreibungsmodule,
+            // 2. sollen da eh nur Sachen und keine Spieler rein!
+            AddItem("/items/schaufel", REFRESH_REMOVE);
+          }
+        
+        Der Laden verkauft nun auch Schaufeln, jedoch nur eine pro Reset.
+
+HINWEISE:        
+        Fuer standardmaessig verkaufte Waren beachte man den Unterschied 
+        zwischen den Funktionen AddItem() und AddFixedObject().
+        Die erstgenannte Funktion ist im Lager zu verwenden, letztere jedoch
+        im Laden.
+
+SIEHE AUCH:
+        Allgemeines:  laden
+        Funktionen:   AddItem(L), AddFixedObject(L), RemoveFixedObject(L) 
+        Basisobjekte: /std/store.c
+        Properties:   P_MIN_STOCK, P_STORE_CONSUME
+
+----------------------------------------------------------------------------
+Last modified: 19-Jun-2015, Arathorn
diff --git a/doc/lfun/SetTimedAttrModifier b/doc/lfun/SetTimedAttrModifier
new file mode 100644
index 0000000..5804823
--- /dev/null
+++ b/doc/lfun/SetTimedAttrModifier
@@ -0,0 +1,92 @@
+SetTimedAttrModifier()
+FUNKTION:
+     int SetTimedAttrModifier(string key, mapping modifier, 
+                              int outdated, object dependent, mixed notify) 
+DEFINIERT IN:
+     /std/living/attributes.c
+
+ARGUMENTE:
+     key	-	in P_TIMED_ATTR_MOD vorzunehmender oder zu 
+                        aendernder Eintrag

+     modifier   -       Mapping mit den Attributveraenderungen

+     outdated   -       Zeitpunkt zu dem die Attributveraenderungen

+                        ablaufen sollen in Sekunden seit dem

+                        1. Jan 1970, 0.0:0 GMT oder 0

+     dependent  -       Objekt dessen Existenz eine Bedingung fuer die

+                        Attributveraenderung sein soll oder 0

+     notify     -       Objekt oder File das mittels 
+                        NotifyTimedAttrModExpired ueber

+                        den Attributablauf informiert werden soll

+
+BESCHREIBUNG:
+     Der zu key gehoerende Eintrag wird in P_TIMED_ATTR_MOD angelegt oder

+     modifiziert und update_max_sp_and_hp aufgerufen.

+     Es empfiehlt sich auf die Eindeutigkeit des string-Parameters key
+     besonderes Augenmerk zu legen.
+

+     Unter dem Key key wird in P_TIMED_ATTR_MOD ein Eintrag vorgenommen,

+     welcher die Attribute des Livings um die in modifier stehenden Offsets

+     veraendert.

+

+     Diese Veraenderung ist solange aktiv bis entweder die in outdated

+     stehende Zeit ueberschritten ist oder das in dependent uebergebene

+     Objekt nicht mehr existiert.

+     Sind beide Argumente 0 so laeuft die Attributveraenderung nicht ab

+     und kann durch DeleteTimedAttrModifier geloescht werden.

+     Laeuft die Attributveraenderung ab, so wird der in notify angegebene

+     Empfaenger mittels Aufruf NotifyTimedAttrModExpired davon 
+     benachrichtigt.

+     Der Funktion NotifyTimedAttrModExpired wird als Argument der key

+     der abgelaufenen Attributveraenderung uebergeben.

+

+BEISPIELE:

+     Ein NPC kann einen Spieler auf die folgende Weise solange die

+     Attribute um eins herabsetzen bis entweder eine Stunde verstrichen

+     ist oder der NPC nicht mehr existiert zum Beispiel weil er getoetet

+     wurde.

+

+       player->SetTimedAttrModifier( player->query_real_name(),

+                                     ([A_STR:-1,A_INT:-1,A_DEX:-1,A_CON:-1]),

+                                     time()+3600,

+                                     this_object(),

+                                     this_object()

+                                   );

+

+     Will der NPC nun noch darauf reagieren, dass die Attributmodifikation

+     durch Timeout abgelaufen ist, so koennte dies folgendermassen geschehen.

+

+       void NotifyTimedAttrModExpired(string str)

+       {

+           // Die Funktion wird aus dem Lebewesen gerufen, in welchem der Mod
+           // gerade abgelaufen ist. Also Meldungsausgabe an
+           // previous_object().
+           tell_object(previous_object()
+               ,"Da hast Du aber nochmal Glueck gehabt.\n");

+       }

+

+

+RUeCKGABEWERT:

+     TATTR_INVALID_ARGS      -     Im Falle eines fehlenden key-Arguments,

+                                   eines fehlenden modifier-Arguments oder

+                                   eines bereits abgelaufenen

+                                   outdatet-Arguments

+     TATTR_OK                -     Im Erfolgsfall

+

+     Die Rueckgabewerte sind in /sys/living/attributes.h definiert.

+
+SIEHE AUCH:

+     Attribute:  QueryAttribute(), SetAttribute()

+                 SetRealAttribute(), QueryRealAttribute(),

+                 QueryAttributeOffset(),

+                 UpdateAttributes()

+     Methoden:   QueryTimedAttrModifier(), DeleteTimedAttrModifier()

+     Callback:   NotifyTimedAttrModExpired()

+     Properties: P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS

+		 P_X_ATTR_MOD, P_M_ATTR_MOD

+		 P_TIMED_ATTR_MOD

+     Sonstiges:  /std/living/attributes.c

+
+LETZTE Aenderung:
+15.02.2009, Zesstra
+
+
diff --git a/doc/lfun/ShowDoors b/doc/lfun/ShowDoors
new file mode 100644
index 0000000..ecd36b0
--- /dev/null
+++ b/doc/lfun/ShowDoors
@@ -0,0 +1,23 @@
+ShowDoors()
+
+FUNKTION:
+	void ShowDoors()
+
+ARGUMENTE:
+	Keine.
+
+BESCHREIBUNG:
+	Zeigt alle Sehertor an, die der Seher (this_player()) schon kennt.
+	Falls in seiner Umgebung ein Tor steht, so wird dieses eingeklammert.
+
+RUECKGABEWERT:
+	Keiner.
+
+BEMERKUNGEN:
+    Diese Funktion wird von /d/seher/portale/sehertormaster definiert.
+
+BEISPIELE:
+    /d/seher/portale/sehertormaster->ShowDoors()
+
+SIEHE AUCH:
+    DiscoverDoor, DoorIsKnown, Teleport, GetDoorsMapping
diff --git a/doc/lfun/ShowPropList b/doc/lfun/ShowPropList
new file mode 100644
index 0000000..64bc4cb
--- /dev/null
+++ b/doc/lfun/ShowPropList
@@ -0,0 +1,49 @@
+ShowPropList()
+
+FUNKTION:
+     void ShowPropList(string *props);
+
+DEFINIERT IN:
+     /std/thing/util.c
+
+ARGUMENTE:
+     props
+          Array von Strings mit den Namen der Properties, die ausgegeben
+          werden sollen.
+
+BESCHREIBUNG:
+     Gibt die Inhalte der in props angegebenen Properties aus.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+     Sei test.c folgendes Programm:
+
+     inherit "std/thing";
+     inherit "std/thing/util";
+
+     create() {
+       ::create();
+
+       SetProp(P_SHORT, "Kurz");
+       SetProp(P_NAME, ({ "Name", "Namens", "Namen", "Namen" }));
+       SetProp("me", this_object() );
+     }
+
+     Mit xcall test->ShowPropList( ({ P_SHORT, P_NAME, "me" }) ); erhielte
+     man dann folgende Ausgabe:
+
+     *short: "Kurz"
+     *name: ({ "Name", "Namens", "Namen", "Namen" })
+     *me: OBJ(/players/wargon/test#12345)
+
+BEMERKUNGEN:
+     Mit dem Befehl xprops des MGtools lassen sich uebrigens saemtliche
+     Properties eines Objekte auf einen Schlag ausgeben.
+
+SIEHE AUCH:
+     /std/ting/util.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:25:26 1996 by Wargon
diff --git a/doc/lfun/SkillResTransfer b/doc/lfun/SkillResTransfer
new file mode 100644
index 0000000..6983eea
--- /dev/null
+++ b/doc/lfun/SkillResTransfer
@@ -0,0 +1,28 @@
+SkillResTransfer()
+
+FUNKTION:
+     protected void SkillResTransfer(mapping from_M, mapping to_M)
+
+DEFINIERT IN:
+     /std/living/skill_utils
+
+ARGUMENTE:
+     mapping from_M: Mapping mit zu kopierenden Werten
+     mapping to_M:   Zielmapping
+
+BESCHREIBUNG:
+     Interne Methode, die zB (!) waehrend der Ausfuehrung von Attack() durch
+     Skills oder P_TMP_ATTACK_MOD geaenderte Werte selektiert in das
+     Hauptangriffsmapping uebertraegt.
+
+     Derzeit werden folgende Werte kopiert:
+     SI_SKILLDAMAGE, SI_SKILLDAMAGE_MSG, SI_SKILLDAMAGE_MSG2,
+     SI_SKILLDAMAGE_TYPE, SI_SPELL
+
+BEMERKUNGEN:
+     * wird an mehreren Stellen, nicht nur der living/combat verwendet
+
+SIEHE AUCH:
+     P_TMP_ATTACK_MOD, UseSkill (Waffenfaehigkeiten)
+
+18.Jul 2014 Gloinson
diff --git a/doc/lfun/SpellAttack b/doc/lfun/SpellAttack
new file mode 100644
index 0000000..0e24fd9
--- /dev/null
+++ b/doc/lfun/SpellAttack
@@ -0,0 +1,71 @@
+SpellAttack()
+
+FUNKTION:
+        void SpellAttack(object enemy)
+
+ARGUMENTE:
+        enemy: Der Feind.
+
+BESCHREIBUNG:
+        Diese Funktion wird in jedem Heartbeat eines NPCs ausgefuehrt,
+        falls nicht P_DISABLE_ATTACK gesetzt ist (Paralyse).
+        Standardmaessig tut diese Funktion nichts, aber man kann sie
+        ueberschreiben, damit in jedem Heartbeat Angriffe mit Spells
+        ausgefuehrt werden.
+
+        Man sollte hierbei ein random() einbauen, damit der NPC nicht
+        in jedem Heartbeat auch wirklich einen Angriff ausfuehrt.
+        Ausserdem sollte man auch fuer eventuelle Ausgaben sorgen.
+
+RUECKGABEWERT:
+        Keiner.
+
+BEMERKUNG:
+        Die AttackChats, die mittels SetAttackChats gesetzt werden
+        koennen, macht im Grunde nichts anderes, aber Chats sind halt
+        keine Angriffe. :-)
+
+BEISPIELE:
+        Im Grunde ist dieses simple Beispiel eine Nachbildung von
+        Attack-Chats und soll dementsprechend nur der Anschauung dienen.
+
+        void SpellAttack(object enemy) 
+        {
+          // mit 80% Wahrscheinlichkeit wird nichts gemacht.
+          switch(random(5))
+          {
+            case 0: 
+              write("Der Ork tritt Dir in den Hintern.\n");
+              return;
+            case 1: 
+              write("Der Ork bruellt: Lebend kommst Du hier nicht raus!\n");
+              return;
+            case 2:
+              write("Der Ork blutet schon aus mehreren Wunden.\n");
+              return;
+            case 3:
+              write(knirsch(enemy));
+              return;
+            default:
+              return;
+          }
+        }
+
+        string knirsch(object enemy)
+        {
+           if (objectp(enemy))
+             helm = enemy->QueryArmourByType(AT_HELMET);
+           if (objectp(helm))
+           {
+             helm->Damage(1);
+             return "Der Ork beschaedigt Deinen Helm!\n";
+           }
+           else
+             return ""; // keine Meldung
+        }
+
+SIEHE AUCH:
+        "Attack", "SetAttackChats", /std/npc/combat.c
+
+LETZTE AENDERUNG:
+ Don, 27.02.2003, 12:50:00 von Hirudo
diff --git a/doc/lfun/SpellDefend b/doc/lfun/SpellDefend
new file mode 100644
index 0000000..79537d5
--- /dev/null
+++ b/doc/lfun/SpellDefend
@@ -0,0 +1,43 @@
+SpellDefend()
+FUNKTION:
+     public int SpellDefend(object caster,mapping sinfo);
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+ARGUMENTE:
+     object caster	- Gegner
+     mapping sinfo	- Zusatzinformationen zum Spell
+
+BESCHREIBUNG:
+     Ueber den Skill SK_SPELL_DEFEND mit den Aufrufparametern
+       SI_ENEMY    : <caster>
+     und
+       SI_SKILLARG : <sinfo>
+     wird eine Abwehrchance in 0.01%-Schritten fuer einen
+     Spell ermittelt, also 0% - 100% bzw. als Rueckgabewert
+     0 - 10000.
+     
+     Weiterhin wird automatisch P_MAGIC_RESISTANCE_OFFSET und der Skill
+     SK_SPELL_DEFEND beruecksichtigt.
+
+RUeCKGABEWERT:
+     Die Abwehrchance in 0.01%-Schritten.
+     
+     Fuer Spieler wird dieser Rueckgabewert auf 3333 maximal, also 33,33%
+     Abwehrmoeglichkeit beschraenkt.
+
+BEMERKUNGEN:
+     Die Spellbooks muessen selbst auf die Auswertung dieser Funktion
+     achten! Dies geschieht nur im Falle von TryGlobalAttackSpell()
+     und bei Spells fuer NPCs mittels P_SPELLS automatisch!
+
+     Bitte bei NPCs nicht pauschal 100% / 10000 zurueckgeben. Danke.
+
+SIEHE AUCH:
+     Verwandt:     P_MAGIC_RESISTANCE_OFFSET
+     Aehnlich:     P_NOMAGIC
+     Generell:     TryGlobalAttackSpell, /std/spellbook.c
+     Sonstiges:    UseSkill, SK_SPELL_DEFEND
+
+29.Dez 2007 Gloinson
diff --git a/doc/lfun/SpellInform b/doc/lfun/SpellInform
new file mode 100644
index 0000000..369b201
--- /dev/null
+++ b/doc/lfun/SpellInform
@@ -0,0 +1,31 @@
+SpellInform
+
+FUNKTION:
+        void SpellInform(caster,spell,sinfo);
+
+DEFINIERT IN:
+        selber zu definieren
+
+ARGUMENTE:
+        pl
+          Das Lebewesen, das erfolgreich gezaubert hat.
+        spell
+          Der Name des gezauberten Spells
+        sinfo
+          Das komplette Spellmapping des gezauberten Spells
+
+BESCHREIBUNG:
+        Diese Funktion wird vom Spellbuch einer Gilde in der Umgebung
+        (Environment) eines Lebewesens aufgerufen, wenn immer das Lebewesen
+        einen Spell _erfolgreich_ gezaubert hat.
+        Bemerkung: Bitte vermeiden, aufwaendige Sachen in der Funktion zu
+        machen, da sonst u.U. deswegen Gilden anfangen zu buggen. Falls es
+        sein muss, macht dann lieber einen call_out mit 2s Wartezeit.
+
+RUeCKGABEWERT:
+        keiner
+
+SIEHE AUCH:
+        
+----------------------------------------------------------------------------
+16.04.2007, Zesstra
diff --git a/doc/lfun/Start b/doc/lfun/Start
new file mode 100644
index 0000000..89f63ef
--- /dev/null
+++ b/doc/lfun/Start
@@ -0,0 +1,25 @@
+Start()
+
+FUNKTION:
+     varargs void Start(int pos);
+
+DEFINIERT IN:
+     /std/transport.c
+
+ARGUMENTE:
+     pos
+          Fahrplanstation, an der begonnen werden soll.
+
+BESCHREIBUNG:
+     Diese Funktion schickt den Transporter auf die Strecke. Dabei beginnt
+     der Weg an der mit pos bezeichneten Stelle im Fahrplan. Default ist 0,
+     d.h. der Transporter beginnt seinen Weg an der ersten Fahrplanposition.
+
+RUeCKGABEWERT:
+     keiner
+
+SIEHE AUCH:
+     Halt(), /std/transport.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:25:30 1996 by Wargon
diff --git a/doc/lfun/StopHuntFor b/doc/lfun/StopHuntFor
new file mode 100644
index 0000000..738b920
--- /dev/null
+++ b/doc/lfun/StopHuntFor
@@ -0,0 +1,52 @@
+StopHuntFor()
+
+FUNKTION:
+  varargs int StopHuntFor(object arg,int silent);
+
+DEFINIERT IN:
+  /std/living/combat.c
+
+ARGUMENTE:
+  arg
+    Der Gegner, welcher nicht mehr bekaempft werden soll.
+  silent
+    Flag, welches gesetzt anzeigt, dass die beiden Ex-Streithaehne
+    ueber das einseitige Friedensangebot nicht informiert werden
+    sollen.
+
+RUeCKGABEWERT:
+  Flag: Bei 0 war der Gegner nicht auffindbar, bei 1 Erfolg.
+
+BESCHREIBUNG:
+  Mit dieser Funktion kann man ein Lebewesen <arg> als Gegner
+  austragen. Im Normalfall erhalten sowohl das aktuelle Objekt, als
+  auch der Gegner eine Information darueber. Dies kann jedoch mit dem
+  gesetzten Flag <silent> unterbunden werden.
+  Es ist auch moeglich, auf diese Meldung Einfluss zu nehmen, indem
+  man die Funktion StopHuntText() ueberschreibt, welche dafuer
+  verantwortlich ist.
+  Achtung: Um zwischen beiden Streithaehnen Frieden zu schliessen,
+  muss der eine Gegner jeweils bei dem anderen ausgetragen werden. Ein
+  einzelnes StopHuntFor() ist sozusagen nur ein einseitiges
+  Friedensangebot.
+
+BEMERKUNGEN:
+  Soll ein Viech unter bestimmten Umstaenden nicht angreifbar sein, ist in
+  keinem Fall StopHuntFor() im Defend() zu verwenden, sondern P_NO_ATTACK.
+  Grund: Stoppt man unliebsame Kaempfe jeweils am Anfang vom Defend, kann ein
+  Gegner gefahrlos Angriffsspells ausfuehren (und ueben), ohne dass die Gefahr
+  besteht, dass der NPC zurueckschlaegt.
+
+BEISPIELE:
+  Man will aus irgendeinem Grund den Kampf zwischen sich und Gegner enemy
+  einstellen:
+  ...
+  StopHuntFor(enemy); // enemy nicht mehr bekaempfen
+  enemy->StopHuntFor(this_object()); // enemy soll mich nicht bekaempfen.
+  ...
+
+SIEHE AUCH:
+  StopHuntText(), SelectEnemy(), QueryEnemies(), IsEnemy()
+
+----------------------------------------------------------------------------
+16.03.2008, Zesstra 
diff --git a/doc/lfun/StopHuntText b/doc/lfun/StopHuntText
new file mode 100644
index 0000000..1ca8cfb
--- /dev/null
+++ b/doc/lfun/StopHuntText
@@ -0,0 +1,58 @@
+StopHuntText()
+
+FUNKTION:
+	void StopHuntText(object arg);
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	arg
+	  Der Gegner, welcher nicht mehr bekaempft wird.
+
+BESCHREIBUNG:
+	Mit der Funktion StopHuntFor() kann man ein Lebewesen als Gegner
+	austragen. Dabei erhalten sowohl der Gegner, als auch das Lebewesen,
+	welches (einseitig!) Frieden schliesst, jeweils eine Meldung, sofern
+	man dies nicht mittels eines Flags unterbindet.
+	Es ist nun moeglich, auf diese Meldung Einfluss zu nehmen, indem
+	man die Funktion StopHuntText() ueberschreibt, welche dafuer
+	verantwortlich ist.
+
+BEISPIEL:
+	Ein Lebewesen moechte einen Kampf sofort abbrechen, wenn es von
+	einem Frosch angegriffen wird:
+	  int Defend(int dam,mixed dam_type,mixed spell,object enemy)
+	  { if(enemy&&enemy->QueryProp(P_FROG))
+	    { if(StopHuntFor(enemy))
+              { // wenn Frosch angreifen will, der noch kein Gegner war
+                tell_object(arg,
+         this_object()->Name(WER)+" kaempft nicht mit Dir.\n"
+	+"Wahrscheinlich werden Froesche verschont.\n");
+	        tell_object(this_object(),
+	 "Der bloede Frosch wollte Dich doch tatsaechlich angreifen.\n");
+              }
+	      enemy->StopHuntFor(this_object(),1);
+              return 0;
+            }
+	    return::Defend(dam,dam_type,spell,enemy);
+	  }
+	  // wird nur aufgerufen, wenn der Gegner irgendwann Frosch wurde
+	  void StopHuntText(object arg)
+	  { tell_object(arg,
+	 this_object()->Name(WER)+" jagd Dich nicht mehr.\n"
+	+"Wahrscheinlich werden Froesche verschont.\n");
+	    tell_object(this_object(),
+	"Dein Gegner ist doch tatsaechlich ploetzlich Frosch geworden!\n");
+	  }
+	Warum braucht man nun das erste StopHuntFor(), wenn doch Gegner erst
+	in ::Defend() eingetragen werden, welches doch gar nicht ausgefuehrt
+	wird, wenn der Gegner ein Frosch ist? Man beachte hierbei, dass der
+	Gegner ja auch waehrend des Kampfes oder waehrend der Feindschaft
+	irgendwann Frosch werden koennte und dann schon Gegner war.
+
+SIEHE AUCH:
+	StopHuntFor(), SelectEnemy(), QueryEnemies(), IsEnemy()
+
+----------------------------------------------------------------------------
+Last modified: Wed May 26 16:47:51 1999 by Patryn
diff --git a/doc/lfun/SuggestArticle b/doc/lfun/SuggestArticle
new file mode 100644
index 0000000..7a4ba5c
--- /dev/null
+++ b/doc/lfun/SuggestArticle
@@ -0,0 +1,35 @@
+SuggestArticle()
+
+FUNKTION:
+     varargs int SuggestArticle(string name);
+
+DEFINIERT IN:
+     /std/thing/language.c
+
+ARGUMENTE:
+     name
+          Der Name zur Entscheidungshilfe.
+
+BESCHREIBUNG:
+     Diese Funktion versucht herauszufinden, ob der Artikel zu diesem Objekt
+     ein unbestimmter oder besser ein bestimmter Artikel sein sollte. Die
+     Vorgehensweise ist folgende: Gibt es in der Umgebung dieses Objektes
+     ein weiteres Objekt, das den Namen name besitzt, so wird ein
+     unbestimmter Artikel vorgeschlagen, ansonsten ein bestimmter.
+
+RUeCKGABEWERT:
+     0, wenn ein unbestimmter Artikel geeignet ist, ansonsten 1.
+
+BEMERKUNGEN:
+     Der Vergleich erfolgt mittels der Property P_NAME. Um Erfolg zu haben,
+     sollte man diese Funktion daher in der Form
+
+     SuggestArticle(QueryProp(P_NAME))
+
+     aufrufen.
+
+SIEHE AUCH:
+     QueryArticle(), name(), /std/thing/language.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:25:34 1996 by Wargon
diff --git a/doc/lfun/SwapRows b/doc/lfun/SwapRows
new file mode 100644
index 0000000..7d5d928
--- /dev/null
+++ b/doc/lfun/SwapRows
@@ -0,0 +1,40 @@
+
+SwapRows()
+
+
+FUNKTION:
+    int SwapRows( object ob1, object ob2 )
+
+DEFINIERT IN:
+    /std/living/team.c
+
+ARGUMENTE:
+    ob1, ob2 - Spieler, die die Reihen tauschen sollen.
+
+BESCHREIBUNG:
+    Die angegebenen Spieler tauschen die Reihen.
+
+RUECKGABEWERT:
+    1 bei erfolgreichem Tausch, 0 sonst.
+
+BEMERKUNG:
+    Der Tausch wird nur durchgefuehrt, wenn die angegebenen Spieler auch
+    tatsaechlich im Team sind und damit kein NPC vor einen Spieler gestellt
+    wuerde.
+    Moechte man wissen, ob ein Spieler eine Reihe gewechselt hat, muss man
+    sich der Hilfe eines Hooks bedienen: H_HOOK_TEAMROWCHANGE
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_TEAM_LEADER, P_TEAM_ASSOC_MEMBERS,
+                    P_TEAM_NEWMEMBER
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/TakeFlaw b/doc/lfun/TakeFlaw
new file mode 100644
index 0000000..7bfd03a
--- /dev/null
+++ b/doc/lfun/TakeFlaw
@@ -0,0 +1,75 @@
+TakeFlaw()
+
+FUNKTION:
+     varargs void TakeFlaw(object enemy); (Waffen)
+     varargs void TakeFlaw(mixed dam_types,mapping einfos) (Ruestungen)
+
+DEFINIERT IN:
+     /std/armour/combat.c,
+     /std/weapon/combat.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Diese Funktion wird in Waffen und Ruestungen waehrend des Kampfes
+     aufgerufen. In einer Waffe erfolgt der Aufruf bei jedem Schlag mit
+     dieser Waffe, bei Ruestungen wird TakeFlaw() in einer zufaellig
+     ausgewaehlten getragenen Ruestung aufgerufen.
+     Waffen bekommen das Gegnerobjekt uebergeben, Ruestungen die erweiterten
+     DefendInfos (s. dort fuer Details). Aufgrund dieser Informationen kann
+     man den Schaden, den ein Gegenstand nimmt, flexibler gestalten (z.B. bei
+     einer Waffe in Abhaengigkeit von P_BODY des Gegners.)
+
+     Soweit man die Funktion nicht ueberlaedt, bewirkt sie nichts weiter als
+     das Erhoehen eines Zaehlers, der mit QueryFlaw() abgefragt werden kann.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Die Waffen-/ Ruestungsklasse wird nicht automatisch reduziert! Wenn
+     eine Waffe oder Ruestung sich abnutzen soll, muss man TakeFlaw()
+     ueberladen und dort entsprechend handeln, oder (fuer einfache
+     Faelle) die Property P_QUALITY setzen.
+
+BEISPIELE:
+     Eine Waffe, deren Waffenklasse alle 20 Schlaege um 1 abnimmt:
+
+     inherit "std/weapon";
+
+     #include <properties.h>
+     #include <combat.h>
+
+     create()
+     {
+       /* Das Uebliche... */
+     }
+
+     TakeFlaw()
+     {
+       int flaw;
+
+       /* erst mal den Zaehler erhoehen... */
+       ::TakeFlaw();
+
+       /* jetzt den aktuellen Zaehlerstand abfragen */
+       flaw = QueryFlaw()[0];
+
+       /* Abzug nur jeden 20. Schlag */
+       if (!(flaw % 20)) {
+         /* So, jetzt fuer den Schaden sorgen. Hierfuer benutzt */
+         /* man am sichersten die eingebaute Funktion Damage() */
+         Damage(1);
+       }
+     }
+
+     Dieses einfache Beispiel haette natuerlich auch ueber ein
+     SetProp(P_QUALITY,20); im create() realisiert werden koennen.
+
+SIEHE AUCH:
+     QueryFlaw(), Damage(), DefendInfo, P_QUIALITY, /std/armour/combat.c,
+     /std/weapon/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Thu May 22 10:30:10 1997 by Paracelsus
diff --git a/doc/lfun/TeamFlee b/doc/lfun/TeamFlee
new file mode 100644
index 0000000..fb317a0
--- /dev/null
+++ b/doc/lfun/TeamFlee
@@ -0,0 +1,40 @@
+
+TeamFlee()
+
+
+FUNKTION:
+        int TeamFlee()
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        keine
+
+BESCHREIBUNG:
+        Spieler wird zur Flucht in hintere Reihe veranlasst, falls er dies
+        eingestellt hat.
+
+RUECKGABEWERT:
+        1, falls der Spieler in eine hintere Reihe fliehen wollte und nach
+        dem Versuch nicht mehr in der ersten Reihe steht, sonst 0.
+
+BEMERKUNGEN:
+        Beim Teamleiter fuehrt der Fluchtversuch dazu, dass sein Team nicht
+        mehr folgt.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/TeamMembers b/doc/lfun/TeamMembers
new file mode 100644
index 0000000..28ca93b
--- /dev/null
+++ b/doc/lfun/TeamMembers
@@ -0,0 +1,38 @@
+
+TeamMembers()
+
+
+FUNKTION:
+        object *TeamMembers()
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        keine
+
+BESCHREIBUNG:
+        Liefert Teammitglieder des Teams des Spielers.
+
+RUECKGABEWERT:
+        Array mit ALLEN Teammitgliedern.
+
+BEMERKUNGEN:
+        Falls der Spieler in keinem Team ist, enthaelt das Array nur den
+        Spieler.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/TeamPrefix b/doc/lfun/TeamPrefix
new file mode 100644
index 0000000..efbebb7
--- /dev/null
+++ b/doc/lfun/TeamPrefix
@@ -0,0 +1,37 @@
+
+TeamPrefix()
+
+
+FUNKTION:
+        string TeamPrefix()
+
+DEFINIERT IN:
+        /std/living/team.c
+
+ARGUMENTE:
+        keine
+
+BESCHREIBUNG:
+        Ergibt Team-Prefix eines Spielers.
+
+RUECKGABEWERT:
+        "[Team Teamname] ", falls der Spieler in einem Team ist,
+        ""                  sonst.
+
+BEMERKUNGEN:
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/lfun/Teleport b/doc/lfun/Teleport
new file mode 100644
index 0000000..b902d07
--- /dev/null
+++ b/doc/lfun/Teleport
@@ -0,0 +1,28 @@
+Teleport()
+
+FUNKTION:
+    int Teleport(string ziel)
+
+ARGUMENTE:
+    ziel: Nummer des Sehertors, zu dem teleportiert werden soll.
+
+BESCHREIBUNG:
+    Teleportiert den Seher (this_player()) zu dem Tor mit der angegebenen
+    Nummer. Falls keine Nummer angegeben wird, wird mit ShowDoors() die
+    Liste der bekannten Tore angezeigt und auf die Eingabe einer Nummer
+    gewartet.
+
+RUECKGABEWERT:
+    0, falls der Seher nicht neben einem Tor steht, dass er kennt.
+    1  sonst.
+
+BEMERKUNGEN:
+    Der Seher muss in einem Raum stehen, in dem sich ein Sehertor befindet,
+    dass er kennt. Der Seher muss auch das angegebene Ziel kennen.
+    Diese Funktion wird von /d/seher/portale/sehertormaster definiert.
+
+BEISPIELE:
+    /d/seher/portale/sehertormaster->Teleport(1)
+
+SIEHE AUCH:
+    DiscoverDoor, DoorIsKnown, ShowDoors, GetDoorsMapping
diff --git a/doc/lfun/TestIgnore b/doc/lfun/TestIgnore
new file mode 100644
index 0000000..3e664c0
--- /dev/null
+++ b/doc/lfun/TestIgnore
@@ -0,0 +1,66 @@
+TestIgnore()
+
+FUNKTION:
+     public int TestIgnore(string|string* arg)
+
+DEFINIERT IN:
+     /std/player/comm.c
+
+ARGUMENTE:
+     arg
+         String oder Array von Strings, die getestet werden sollen,
+         Format jeweils: [spieler].aktion[.qualifizierer]
+
+RUeCKGABEWERT:
+     0, wenn arg nicht ignoriert wird
+     MSG_IGNORED, wenn (min. ein Element von) arg ignoriert wird
+
+BESCHREIBUNG:
+     Es wird geprueft, ob der Spieler irgendeinen Eintrag auf seiner Liste
+     hat, der dazu fuehrt, dass <arg> ignoriert wird. Hierbei kommen je nach
+     den Angaben in <arg> folgende Regeln zum Tragen:
+     1) spieler
+        Wird der Spieler ignoriert?
+     2) .aktion
+        Ignoriert der Spieler .aktion, d.h. die Aktion komplett (OHNE
+        Qualifizierer)?
+     3) spieler.aktion
+        Ignoriert der Spieler spieler, .aktion oder spieler.aktion?
+     4) spieler.aktion.qualifizierer
+        Ignoriert der Spieler spieler, .aktion, spieler.aktion oder
+        spieler.aktion.qualifizierer?
+     5) .aktion.qualifizierer
+        Ignoriert der Spieler .aktion oder .aktion.qualifizierer?
+
+     Da TestIgnore() damit durchaus etwas aufwendiger sein kann, sollte
+     man dies nicht unnoetig oft aufrufen. (Braucht man das Ergebnis z.B.
+     kurz spaeter nochmal, koennte man das Ergebnis speichern.) Wird der
+     Qualifizierer nicht gebraucht, sollte man ihn weglassen.
+
+BEISPIEL:
+     if (!this_player()->TestIgnore("andy"))
+       tell_object(this_player(), "Andy teilt Dir mit: Hallo!\n");
+
+     // Beispiel fuer eine Ignore-Check fuer Aktion (kratzen) fuer einen
+     // Spieler (this_player()) an einem anderen Spieler (target)
+     if (!target->TestIgnore( ({getuid(this_player()) + ".kratze",
+                                   getuid(this_player()) + ".kratz"}) ))
+     {
+       tell_object(target, this_player()->Name()+" kratzt dich.\n");
+       tell_object(this_player(), "Du kratzt "+target->Name()+".\n");
+     }
+     else
+       tell_object(this_player(), target->Name()+" ignoriert dich.\n");
+
+     // allumfassender Ignorier-Check in einer Gilde (Klerus) auf
+     // eine Aktion (kurieren) fuer einen bestimmten Spieler (den caster)
+     // an einem zu kurierenden Spieler (target)
+     if (target->TestIgnore(getuid(caster)+".kuriere.klerus"))
+       tell_object(caster, break_string(
+         target->Name()+" ignoriert deinen Versuch.", 78));
+
+SIEHE AUCH:
+     P_IGNORE, AddIgnore, RemoveIgnore, TestIgnoreSimple, /std/player/comm.c
+
+26.04.2014 Zesstra
+
diff --git a/doc/lfun/TestIgnoreSimple b/doc/lfun/TestIgnoreSimple
new file mode 100644
index 0000000..542632e
--- /dev/null
+++ b/doc/lfun/TestIgnoreSimple
@@ -0,0 +1,55 @@
+TestIgnoreSimple()
+
+FUNKTION:
+     public int TestIgnoreSimple(string *arg)
+
+DEFINIERT IN:
+     /std/player/comm.c
+
+ARGUMENTE:
+     arg
+         Liste von Strings, die getestet werden sollen
+
+BESCHREIBUNG:
+     TestIgnoreSimple() prueft, ob der Spieler min. einen der uebergebenen
+     Eintraege auf seiner Ignoriereliste hat.
+     Falls man mehrere Eintraege pruefen muss/moechte, ist es schneller, alle
+     Eintraege in einem zu uebergeben anstatt fuer jeden einzeln 
+     TestIgnoreSimple() aufzurufen.
+
+RUeCKGABEWERT:
+     1, falls es mindestens eine Uebereinstimmungen von arg und der
+     Ignoriere-Liste des Spielers gibt.
+     0, sonst.
+
+BEISPIEL:
+     if (!this_player()->TestIgnoreSimple(({"andy"})))
+       tell_object(this_player(), "Andy teilt Dir mit: Hallo!\n");
+
+     // Beispiel fuer eine Ignore-Check fuer Aktion (kratzen) fuer einen
+     // Spieler (this_player()) an einem anderen Spieler (target)
+     if (!target->TestIgnoreSimple(getuid(this_player()),
+                             getuid(this_player())+".kratz",
+                             getuid(this_player())+".kratze",
+                             ".kratz", ".kratze"}))) {
+       tell_object(target, this_player()->Name()+" kratzt dich.\n");
+       tell_object(this_player(), "Du kratzt "+target->Name()+".\n");
+     } else
+       tell_object(this_player(), target->Name()+" ignoriert dich.\n");
+
+     // allumfassender Ignorier-Check in einer Gilde (Klerus) auf
+     // eine Aktion (kurieren) fuer einen bestimmten Spieler (den caster)
+     // an einem zu kurierenden Spieler (target)
+     if (target->TestIgnoreSimple(({getuid(caster),
+                              getuid(caster)+".kuriere",
+                              getuid(caster)+".kuriere.klerus",
+                              ".kuriere",
+                              ".kuriere.klerus"})))
+       tell_object(caster, break_string(
+         target->Name()+" ignoriert deinen Versuch.", 78));
+
+SIEHE AUCH:
+     P_IGNORE, AddIgnore, RemoveIgnore, TestIgnore, /std/player/comm.c
+
+26.04.2014 Zesstra
+
diff --git a/doc/lfun/TestLimitViolation b/doc/lfun/TestLimitViolation
new file mode 100644
index 0000000..9344299
--- /dev/null
+++ b/doc/lfun/TestLimitViolation
@@ -0,0 +1,21 @@
+TestLimitViolation()
+FUNKTION:
+      status TestLimitViolation(mapping check)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+

+PARAMETER:

+     check	- Mapping mit Attributen: ([<attr>:<wert>])

+
+BESCHREIBUNG:
+     Prueft, ob die Summe der in check enthaltenen Modifikatoren die Summe
+     aller Modifikatoren im Spieler ueber den zugelassenen Grenzwert hebt.
+     
+SIEHE AUCH:
+     QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+     SetAttr(), SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+     P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_ATTRIBUTES_MODIFIER,

+     P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+
+13.Jun.2004, Muadib
\ No newline at end of file
diff --git a/doc/lfun/TriggerEvent b/doc/lfun/TriggerEvent
new file mode 100644
index 0000000..7b0089f
--- /dev/null
+++ b/doc/lfun/TriggerEvent
@@ -0,0 +1,59 @@
+
+FUNKTION:
+     varargs int TriggerEvent(string eid, mixed data);
+
+DEFINIERT IN:
+     /p/daemon/eventd.c
+DEKLARIERT IN:
+     /sys/events.h
+
+ARGUMENTE:
+     string eid,
+       Die ID des Events, der ausgeloest werden soll.
+       Da dieser String fuer alle Events jeweils eindeutig sein muss, 
+       empfiehlt es sich, fuer eigene Events z.B. als Praefix den eigenen 
+       Magiernamen zu nehmen, z.B. "zesstra_vulkanausbruch".
+       ACHTUNG: IDs, die mit 'evt_lib_' beginnen, sind AUSSCHLIESSLICH der
+       Mudlib vorbehalten!
+
+     mixed data,
+       Daten, die jeder Lauscher uebergeben bekommt. Kann ein beliebiger
+       Datentyp sein. Ggf. ein Mapping oder Array benutzen.
+
+BESCHREIBUNG:
+     Der Event mit der ID 'eid' wird ausgeloest. Mit kurzer Verzoegerung
+     (meist 0-2s) werden alle fuer 'eid' registrierten Lauscher durch Aufruf
+     einer Funktion in ihnen informiert:
+     listener->fun(eid, triggerob, data);
+     'triggerob' ist hierbei das Objekt, welche TriggerEvent() gerufen hat,
+     'data' das, was das triggernde Objekte als Daten weiterverteilen moechte.
+     Die einzelnen fun() in den lauschenden Objekten muessen wissen, was sie
+     mit 'data' anfangen sollen. ;-)
+
+RUeCKGABEWERT:
+     1 fuer Erfolg, <=0 fuer Misserfolg.
+     1   - Erfolg, Event 'eid' wurde ausgeloest.
+     -1  - falsche Argumente wurden uebergeben
+     -2  - nicht-oeffentlicher Event und das triggernde Objekt wurde nicht
+           fuer diesen Event freigegeben (momentan gibt es noch keine
+           nicht-oeffentlichen Events)
+     -3  - Event 'eid' existiert nicht, d.h. es gibt keine Lauscher.
+     -4  - Es gibt zuviele nicht verarbeitete Events.
+
+BEMERKUNGEN:
+
+
+BEISPIELE:
+     1. Ein Waechter wird angegriffen:
+        EVENTD->TriggerEvent("xand_holzfaellerlager_angriff", 
+                             (["angreifer": enemy,
+                               "ort": environment(this_object()) ]) );
+        Alle anderen angemeldeten Waechter der Lagers werden nun informiert
+        und koennen ihrerseits reagieren (dem ersten Waechter zuhilfe kommen
+        oder auch die Lagertore schliessen).
+
+SIEHE AUCH:
+     events, eventd, UnregisterEvent(), RegisterEvent()
+
+----------------------------------------------------------------------------
+Last modified: 15.08.2007, Zesstra
diff --git a/doc/lfun/UnregisterEvent b/doc/lfun/UnregisterEvent
new file mode 100644
index 0000000..0de361a
--- /dev/null
+++ b/doc/lfun/UnregisterEvent
@@ -0,0 +1,49 @@
+
+FUNKTION:
+     int UnregisterEvent(string eid, object listener);
+
+DEFINIERT IN:
+     /p/daemon/eventd.c
+DEKLARIERT IN:
+     /sys/events.h
+
+ARGUMENTE:
+     string eid,
+       Die ID des Events, vom dem man sich abmelden will.
+     object listener,
+       Das Objekt, das als Lauscher ausgetragen werden soll.
+
+BESCHREIBUNG:
+     Das Objekt 'listener' wird als Lauscher dieses Events ausgetragen. Ab
+     diesem Moment wird es bei Events vom Typ 'eid' nicht mehr informiert.     
+
+     Hat der Event 'eid' im Anschluss keine Lauscher mehr, wird er implizit
+     geloescht.
+
+RUeCKGABEWERT:
+     1 fuer Erfolg, <=0 fuer Misserfolg.
+     1   - Erfolg, 'listener' wurde eingetragen.
+     -1  - falsche Argumente uebergeben
+     -2  - 'listener' ist nicht fuer 'eid' registriert.
+    
+BEMERKUNGEN:
+     Wenn sich ein Objekt vor Zerstoerung nicht abmeldet, wird es ggf. beim
+     naechsten Auftreten von 'eid' automatisch ausgetragen.
+     Falls Blueprints nach Neuladen nicht automatisch angemeldet sein sollen,
+     sollten sie sich im remove() explizit abmelden.
+
+BEISPIELE:
+     1. Ein Objekt moechte nicht mehr ueber Spielertode informiert werden:
+          EVENTD->UnregisterEvent(EVT_LIB_PLAYER_DEATH, this_object());
+
+     2. Ein Objekt moechte sich bei Zerstoerung abmelden:
+       varargs int remove(int silent) {
+           ...
+           EVENTD->UnregisterEvent("zesstra_vulkanausbruch",this_object());
+       }
+
+SIEHE AUCH:
+     events, eventd, UnregisterEvent(), RegisterEvent()
+
+----------------------------------------------------------------------------
+Last modified: 15.08.2007, Zesstra
diff --git a/doc/lfun/UnregisterHelperNPC b/doc/lfun/UnregisterHelperNPC
new file mode 100644
index 0000000..de384fd
--- /dev/null
+++ b/doc/lfun/UnregisterHelperNPC
@@ -0,0 +1,45 @@
+UnregisterHelperNPC()
+FUNKTION:
+     public int UnregisterHelperNPC(object npc);
+
+DEFINIERT IN:
+     /std/player/combat.c
+
+ARGUMENTE:
+     object npc
+       Objekt des helfenden NPC, der abgemeldet werden soll.
+
+BESCHREIBUNG:
+     Mit dieser Funktion wird ein einem Spieler helfender NPC im Spieler
+     wieder abgemeldet, wenn dieser dem Spieler ab jetzt nicht mehr hilft.
+
+     Wenn ein Helfer-NPC zerstoert wird, ist der Aufruf nicht noetig.
+     Bleibt das Objekt des NPC aber existent, bitte auf jeden Fall wieder
+     ordentlich abmelden, da ansonsten ggf. der Spieler unnoetig blockiert
+     wird.
+
+RUeCKGABEWERT:
+     1, wenn die Abmeldung erfolgreich war.
+     0 sonst, z.B. wenn der NPC gar nicht als Helfer registriert war.
+
+BEMERKUNGEN:
+     Diese Funktion setzt bei der Erfolg die Property P_HELPER_NPC in <npc>
+     auf 0.
+
+BEISPIELE:
+     1. Ein NPC, der dem Spieler nicht mehr helfen will und normalerweisen im
+        Raum verbleiben soll:
+     tell_object(spieler, "Ich mag Dich nicht mehr, Du bist doof!\n");
+     if (spieler->UnregisterHelperNPC(this_object()) != 1) {
+       // das ist ja bloed...
+       remove(0);
+     }
+     else {
+       tell_room(environment(),
+           Name()+" dreht " +spieler->Name(WEM) + " schmollend den Ruecken "
+           "zu.\n");
+     }
+
+SIEHE AUCH:
+    UnregisterHelperNPC()
+    P_HELPER_NPC
diff --git a/doc/lfun/UnregisterHelperObject b/doc/lfun/UnregisterHelperObject
new file mode 100644
index 0000000..eefd84e
--- /dev/null
+++ b/doc/lfun/UnregisterHelperObject
@@ -0,0 +1,47 @@
+FUNKTION:
+     int UnregisterHelperObject(object helper, int type);
+
+DEFINIERT IN:
+     /std/living/helpers.c
+
+ARGUMENTE:
+     object helper
+       Das Objekt, das als Hilfsobjekt deregistriert werden soll.
+     int type
+       Helfertyp, einer der in /sys/living/helpers.h definierten Typen:
+       - HELPER_TYPE_AERIAL fuer die Flug-/Segelunterstuetzung
+       - HELPER_TYPE_AQUATIC fuer Tauchunterstuetzung
+
+BESCHREIBUNG:
+     Das als Hilfsobjekt fuer bestimmte Aktivitaeten wie zum Beispiel Tauchen
+     oder Fliegen bei einem Lebewesen registrierte Objekt "helper" meldet
+     sich bei diesem ab.
+     Hinweis: fuer eine temporaer gueltige "Nicht-Zustaendigkeit" kaeme auch
+     in Frage, in dieser Zeit einfach "0" zurueckzugeben, statt sich
+     komplett abzumelden.
+
+RUECKGABEWERTE:
+      1  Objekt wurde erfolgreich ausgetragen (HELPER_SUCCESS)
+     -1  angegebenes Hilfsobjekt existiert nicht (HELPER_NO_CALLBACK_OBJECT)
+     -3  angegebenes Hilfsobjekt war gar nicht angemeldet
+         (HELPER_NOTHING_TO_UNREGISTER)
+
+BEISPIEL:
+     Eine luftgefuellte Blase hatte sich als Tauch-Helfer am Spieler
+     angemeldet, ist jetzt aber verbraucht und meldet sich daher ab:
+
+     // Austragen im Spielerobjekt
+     void BlaseAustragen() {
+       [...]
+       if ( TP->UnregisterHelperObject(ME, HELPER_TYPE_AQUATIC)
+            == HELPER_SUCCESS )
+         remove();
+     }
+
+SIEHE AUCH:
+     Funktionen:  RegisterHelperObject()
+     Properties:  P_HELPER_OBJECTS, P_AERIAL_HELPERS, P_AQUATIC_HELPERS
+     Sonstiges:   /sys/living/helpers.h
+
+19.02.2013 Arathorn
+
diff --git a/doc/lfun/Unwear b/doc/lfun/Unwear
new file mode 100644
index 0000000..624c7fc
--- /dev/null
+++ b/doc/lfun/Unwear
@@ -0,0 +1,38 @@
+Unwear()
+FUNKTION:
+     public int Unwear(object ob) 
+
+DEFINIERT IN:
+     /std/living/clothing.c
+
+ARGUMENTE:
+     object ob
+       Die Ruestung oder Kleidung, die ausgezogen wird.
+
+BESCHREIBUNG:
+     Das Lebewesen, in dem diese Funktion gerufen wird, zieht die Ruestung
+     oder das Kleidungsstueck <ob> aus.
+     ABER: 'Ausziehen' bedeutet in diesem Kontext lediglich, dass die
+     Ruestung/Kleidung aus P_ARMOURS bzw. P_CLOTHING ausgetragen wird. Es
+     finden zur Zeit keine Pruefungen statt, ob das Lebewesen den Gegenstand
+     ueberhaupt ausziehen kann. Genausowenig werden Funktionen wie
+     InformUnwear()/RemoveFunc() gerufen oder etwaige Stat-Boni deaktiviert.
+
+     Die Funktion ist nur dazu gedacht, im Zuge des Ausziehens eines Objekts
+     von diesem im Lebewesen gerufen zu werden.
+
+RUeCKGABEWERT:
+     1, wenn das Ausziehen erfolgreich war.
+     0 sonst.
+
+BEMERKUNGEN:
+     Nicht von Hand aufrufen, es sei denn man weiss genau, was man tut. Und am
+     besten auch dann nicht.
+
+SIEHE AUCH:
+     Wear(), WearArmour(), WearClothing(), UnwearArmour(), UnwearClothing()
+     P_CLOTHING, P_ARMOURS
+     FilterClothing(), FilterArmours()
+
+ZULETZT GEAeNDERT:
+14.03.2009, Zesstra
diff --git a/doc/lfun/UnwearArmour b/doc/lfun/UnwearArmour
new file mode 100644
index 0000000..86b55da
--- /dev/null
+++ b/doc/lfun/UnwearArmour
@@ -0,0 +1,38 @@
+UnwearArmour()
+FUNKTION:
+     public int UnwearArmour(object ob) 
+
+DEFINIERT IN:
+     /std/living/clothing.c
+
+ARGUMENTE:
+     object ob
+       Die Ruestung, die ausgezogen wird.
+
+BESCHREIBUNG:
+     Das Lebewesen, in dem diese Funktion gerufen wird, zieht die Ruestung
+     <ob> aus.
+     ABER: 'Ausziehen' bedeutet in diesem Kontext lediglich, dass die
+     Ruestung/Kleidung aus P_ARMOURS ausgetragen wird. Es finden zur Zeit
+     keine Pruefungen statt, ob das Lebewesen den Gegenstand ueberhaupt
+     ausziehen kann. Genausowenig werden Funktionen wie
+     InformUnwear()/RemoveFunc() gerufen oder etwaige Stat-Boni deaktiviert.
+
+     Die Funktion ist nur dazu gedacht, im Zuge des Ausziehens eines Objekts
+     von diesem im Lebewesen gerufen zu werden.
+
+RUeCKGABEWERT:
+     1, wenn das Ausziehen erfolgreich war.
+     0 sonst.
+
+BEMERKUNGEN:
+     Nicht von Hand aufrufen, es sei denn man weiss genau, was man tut. Und am
+     besten auch dann nicht.
+
+SIEHE AUCH:
+     Wear(), WearArmour(), WearClothing(), Unwear(), UnwearClothing()
+     P_CLOTHING, P_ARMOURS
+     FilterClothing(), FilterArmours()
+
+ZULETZT GEAeNDERT:
+14.03.2009, Zesstra
diff --git a/doc/lfun/UnwearClothing b/doc/lfun/UnwearClothing
new file mode 100644
index 0000000..0556654
--- /dev/null
+++ b/doc/lfun/UnwearClothing
@@ -0,0 +1,38 @@
+UnwearClothing()
+FUNKTION:
+     public int UnwearClothing(object ob) 
+
+DEFINIERT IN:
+     /std/living/clothing.c
+
+ARGUMENTE:
+     object ob
+       Das Kleidungsstuck, das ausgezogen wird.
+
+BESCHREIBUNG:
+     Das Lebewesen, in dem diese Funktion gerufen wird, zieht das
+     Kleidungsstueck <ob> aus.
+     ABER: 'Ausziehen' bedeutet in diesem Kontext lediglich, dass die
+     Ruestung/Kleidung aus P_CLOTHING ausgetragen wird. Es finden zur Zeit
+     keine Pruefungen statt, ob das Lebewesen den Gegenstand ueberhaupt
+     ausziehen kann. Genausowenig werden Funktionen wie
+     InformUnwear()/RemoveFunc() gerufen.
+
+     Die Funktion ist nur dazu gedacht, im Zuge des Ausziehens eines Objekts
+     von diesem im Lebewesen gerufen zu werden.
+
+RUeCKGABEWERT:
+     1, wenn das Ausziehen erfolgreich war.
+     0 sonst.
+
+BEMERKUNGEN:
+     Nicht von Hand aufrufen, es sei denn man weiss genau, was man tut. Und am
+     besten auch dann nicht.
+
+SIEHE AUCH:
+     Wear(), WearArmour(), WearClothing(), Unwear(), UnwearArmour()
+     P_CLOTHING, P_ARMOURS
+     FilterClothing(), FilterArmours()
+
+ZULETZT GEAeNDERT:
+14.03.2009, Zesstra
diff --git a/doc/lfun/UnwieldFunc b/doc/lfun/UnwieldFunc
new file mode 100644
index 0000000..9e4929c
--- /dev/null
+++ b/doc/lfun/UnwieldFunc
@@ -0,0 +1,52 @@
+UnwieldFunc()
+
+FUNKTION:
+     int UnwieldFunc(object weapon, int info, object user);
+
+DEFINIERT IN:
+     eigenen Objekten, fuer /std/weapon/combat.c
+
+ARGUMENTE:
+     weapon (object)
+          Die Waffe, die weggesteckt werden soll.
+     info (int)
+          Bei (info&M_SILENT) wird keine Meldung ueber das Wegstecken
+          ausgegeben.
+          Bei (info&M_NOCHECK) wird die Waffe auch weggesteckt, wenn
+          sie verflucht ist. Die tritt insbesondere dann auf, wenn der
+          Spieler, der die Waffe benutzt, stirbt und die Waffe in
+          die Leiche bewegt wird.
+     user (object)
+          Das Lebewesen, welches die Waffe gerade gezueckt hat und sie nun
+          ausziehen will.
+
+BESCHREIBUNG:
+     Hier koennen zusaetzliche Abfragen vorgenommen werden, ob sich die
+     Waffe <weapon> wegstecken laesst oder nicht.
+
+RUeCKGABEWERT:
+     0, wenn sich die Waffe nicht wegstecken laesst, ansonsten ungleich 0.
+
+BEMERKUNGEN:
+     Verfluchte Waffen, die sich erst nach Entfernung des Fluches wegstecken
+     lassen, sollte man besser mit P_CURSED realisieren.
+     Selbst wenn man einen Wert ungleich Null zurueckgibt, ist das noch
+     keine Garantie, dass sich die Waffe auch wirklich zuecken laesst! Der
+     Spieler koennte zum Beispiel noch eine Waffe gezueckt haben, die sich
+     nicht wegstecken laesst, etc.
+     Wenn ihr sicher sein wollt, dass der Spieler ein Objekt gezueckt hat,
+     benutzt bitte InformWear().
+     Bitte nicht drauf verlassen, dass this_player() das Lebewesen ist,
+     welches die Waffe gezueckt und wegstecken will.
+     Die Reihenfolge der Argumente ist etwas unschoen, aber leider wurde <user>
+     erheblich spaeter hinzugefuegt und es war unmoeglich, einige hundert
+     Objekte zu aendern.
+
+SIEHE AUCH
+     P_WIELD_MSG, P_UNWIELD_MSG, P_WEAR_MSG, P_UNWEAR_MSG
+     DoWield(), DoUnwield(), InformWield(), InformUnwield(), 
+     UnwieldFunc, WieldFunc() 
+     /std/weapon/combat.c
+
+----------------------------------------------------------------------------
+02.02.2009, Zesstra
diff --git a/doc/lfun/UpdateAttributes b/doc/lfun/UpdateAttributes
new file mode 100644
index 0000000..ef5a24f
--- /dev/null
+++ b/doc/lfun/UpdateAttributes
@@ -0,0 +1,32 @@
+UpdateAttributes()
+FUNKTION:
+     void UpdateAttributes()
+
+DEFINIERT IN:
+     /std/living/attributes.c
+
+BESCHREIBUNG:
+     Rechnet damit alle Attributmodifier der im Inventory befindlichen 

+     (P_X_ATTR_MOD, P_X_HEALTH_MOD) und getragenen/gezueckten 

+     (P_M_HEALTH_MOD, P_M_ATTR_MOD) Objekte und aller Attributoffsets 

+     zusammen und speichert sie in einer intern fuer Attribute 

+     verwendete Variablen.
+     Berechnet darauf basierend HP und SP neu.
+     

+     Die Bedingungen fuer die ueber P_TIMED_ATTR_MOD gesetzten 

+     Attributveraenderungen werden im Heartbeat in der Funktion

+     attribute_hb ueberprueft.

+
+BEMERKUNGEN:
+     Sollte nach Einbringen neuer Modifikatorobjekte am Living gerufen
+     werden.
+
+SIEHE AUCH:

+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+	SetTimedAttrModifier(), QueryTimedAttrModifier(), 

+	DeleteTimedAttrModifier(),

+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,

+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+----------------------------------------------------------------------------

+09.05.2007 by Zesstra

diff --git a/doc/lfun/UpdateResistanceStrengths b/doc/lfun/UpdateResistanceStrengths
new file mode 100644
index 0000000..48747b3
--- /dev/null
+++ b/doc/lfun/UpdateResistanceStrengths
@@ -0,0 +1,26 @@
+UpdateResistanceStrengths()
+
+FUNKTION:
+     public void UpdateResistanceStrengths()
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+BESCHREIBUNG:
+     Die Funktion wird intern mehrmals (durch Defend, AddResistanceModifier
+     und RemoveResistanceModifier) aufgerufen. In ihr wird das Resistenz-
+     mapping zusammengerechnet und Eintraege geloescht, deren Eintraege
+     invalid sind oder deren setzende Objekte geloescht wurden.
+
+RUeCKGABEWERT:
+     keiner
+
+SIEHE AUCH:
+     Berechnung:	CheckResistance(), Defend()
+     Modifikatoren:	AddResistanceModifier, RemoveResistanceModifier(),
+			P_RESISTANCE_MODIFIER
+     simple Resistenz:	P_RESISTANCE, P_VULNERABILITY
+     Hauptmapping:	P_RESISTANCE_STRENGTHS
+     anderes:		balance, /std/armour/combat.c, /std/living/combat.c
+
+29.Apr 2002, Gloinson@MG
diff --git a/doc/lfun/UseHands b/doc/lfun/UseHands
new file mode 100644
index 0000000..a4fbc8d
--- /dev/null
+++ b/doc/lfun/UseHands
@@ -0,0 +1,37 @@
+UseHands
+FUNKTION:
+     public varargs int UseHands(object ob, int num)
+
+DEFINIERT IN:
+     /std/living/combat.c
+
+ARGUMENTE:
+     ob  - das Objekt, das die Haende belegen soll
+     num - die Anzahl der zu belegenden Haende    
+
+RUECKGABEWERT:
+     1, fuer Erfolg
+     0, sonst     
+
+BESCHREIBUNG:
+     Belegt, wenn moeglich Haende eines Livings durch ein bestimmtes
+     Objekt. Wenn die Anzahl der freien Haende (P_MAX_HANDS-P_USED_HANDS)
+     kleiner ist als "num", dann schlaegt diese Belegung fehl.
+
+BEISPIELE:
+     > halte seil fest
+     ...
+     this_player()->UseHands(this_object(),2);
+     ...
+
+     > lasse seil los
+     ...
+     this_player()->FreeHands(this_object());
+     ...
+
+SIEHE AUCH:
+     P_HANDS, P_HANDS_USED_BY
+     P_MAX_HANDS, P_USED_HANDS, P_FREE_HANDS
+     FreeHands
+
+1.Feb.2004 Gloinson
diff --git a/doc/lfun/UseSkill b/doc/lfun/UseSkill
new file mode 100644
index 0000000..3b12bd8
--- /dev/null
+++ b/doc/lfun/UseSkill
@@ -0,0 +1,48 @@
+UseSkill()
+FUNKTION:
+    public varargs mixed UseSkill(string skill, mapping args)
+
+DEFINIERT IN:
+    /std/living/skills.c
+
+ARGUMENTE:
+    string skill     Skill-Name
+    mapping args     Argumente (veraenderte Skillmapping-Informationen)
+
+BESCHREIBUNG:
+    Benutzt einen Skill. Dieser Skill sollte (als grossgeschriebener Skill)
+    im Living vorliegen und das Living darf kein Geist sein.
+    
+    Die Argumente 'args' werden temporaer auf das Skillmapping des Living
+    addiert (also nur fuer diesen Aufruf und SI_INHERIT gueltig).
+    
+    Eine ausfuehrbare Skill-Funktion zum Skill wird in folgender
+    Reihenfolge bestimmt:
+    - eine gesetzte SI_CLOSURE nutzen
+    - ein gesetztes SI_SKILLFUNC in der gesetzten Gilde nutzen
+    - im Living die Funktion "StdSkill_"+skill (zB Waffenskills) nutzen
+    - QuerySkillAbility() nutzen
+    Die so bestimmte Skill-Funktion wird dann als SI_CLOSURE im Spieler
+    gesetzt und ist bis zur Zerstoerung der entsprechenden Objekte gueltig.
+    Die Methode wird dann gerufen (der Skill also angewandt).
+    
+    Standardmaessig gibt ein UseSkill() also einfach den SI_SKILLABILITY-Wert
+    eines Skills zurueck, es sei denn, eine Funktion wurde fuer den Skill
+    an einer der oben genannten Stellen implementiert.
+    
+    Ein eventuell uebergeordneter Skill (SI_INHERIT) wird mit dem durch den
+    Aufruf der Skill-Funktion veraenderten Mapping mit UseSkill(skill, args)
+    ebenfalls noch ausgefuehrt, bevor das Resultat zurueckgegeben wird.
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+    Spellbook:      Learn, SpellSuccess, Erfolg, Misserfolg
+
+4. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/UseSpell b/doc/lfun/UseSpell
new file mode 100644
index 0000000..ddf1c4d
--- /dev/null
+++ b/doc/lfun/UseSpell
@@ -0,0 +1,77 @@
+UseSpell()
+FUNKTION:
+    public varargs int UseSpell(string str, string spell)
+
+DEFINIERT IN:
+    /std/living/skills.c
+
+ARGUMENTE:
+    string str       Spell-Optionen
+    string spell     optionaler Spellname
+
+BESCHREIBUNG:
+    Benutzt einen Spell, dessen Spellname 'spell' ggf ueber query_verb()
+    ermittelt wird. Dieser Spell sollte (als kleingeschriebener
+    Skill/Spell) im Living vorliegen.
+    
+    Die Argumente 'str' werden als SI_SKILLARG temporaer in das
+    Skillmapping eingetragen (also nur fuer diesen Aufruf gueltig).
+    
+    Eine ausfuehrbare Spell-Funktion zum Spell wird in folgender
+    Reihenfolge bestimmt:
+    - eine gesetzte SI_CLOSURE nutzen
+    - "UseSpell" an einem gesetzten SI_SPELLBOOK nutzen
+    - "UseSpell" an der gesetzten P_GUILD nutzen
+      - [UseSpell der Gilde sucht iA ebenfalls nur den Spell am Spellbook]
+    - eine Closure mit Rueckgabewert 0 erstellen
+    Die so bestimmte Spell-Funktion wird dann als SI_CLOSURE im Spieler
+    gesetzt und ist bis zur Zerstoerung der entsprechenden Objekte gueltig.
+    Die Methode wird dann gerufen (der Spell also angewandt).
+
+    Standardmaessig gibt ein UseSpell() also 0 zurueck, es sei denn, eine
+    Funktion wurde fuer den Spell an einer der oben genannten Stellen
+    implementiert.
+
+    SI_INHERIT ist fuer Spells beim Aufruf wirkungslos (gilt aber bei
+    LearnSkill normal).
+
+    Ein Durchlauf von UseSpell durch den Spieler sieht in etwa so aus:
+      1) Die Methode wird als Empfaenger fuer Kommandos bekannt gemacht.
+         Das passiert mit der Anweisung
+         'add_action("UseSpell", "", 1);' in den Dateien player/base.c und
+         in living/npc.c.
+
+      2) /std/living/skills::UseSpell wird durch Kommando oder Heartbeat
+         gerufen.
+      
+      3) UseSpell() ermittelt eine SI_CLOSURE oder delegiert diesen Aufruf
+         an die gueltige Gilde/das Spellbook weiter.
+      
+      4) Eine gueltige Closure wird ausgefuehrt. UseSpell() uebergibt dabei
+         die Spell/Skill-Informationen und SI_SKILLARG.
+      
+      4.1.) Im Normalfall einer Gilde/Spellbook landet der Aufruf ueber
+            /std/gilden_ob::UseSpell() in /std/spellbook::UseSpell() und
+            dieses ruft eine Spellfunktion im Spellbook auf.
+            Die Spellfunktion arbeitet mit den Spell-Informationen und
+            gibt ein ERFOLG, MISSERFOLG oder 0 dafuer zurueck, ob das
+            Spellbook Lernen/Fehlermeldung oder nichts machen soll.
+            Dementsprechend werden P_SP, P_ATTACK_BUSY und
+            P_NEXT_SPELL_TIME im Spellbook geaendert.
+
+      5.) Der Aufruf der Closure kehrt zurueck und wird zurueckgegeben.
+          Damit ist der 0-Rueckgabewert der Spellfunktion im Spellbook
+          aequivalent einem nicht ausgefuehrten Kommando.
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+    Spellbook:      UseSpell (spellbook), Learn, SpellSuccess
+
+5. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/Validate b/doc/lfun/Validate
new file mode 100644
index 0000000..10f4791
--- /dev/null
+++ b/doc/lfun/Validate
@@ -0,0 +1,47 @@
+Validate()
+
+FUNKTION:
+   string Validate(string oname);
+
+DEFINIERT IN:
+   /std/virtual/v_compiler.c
+
+ARGUMENTE:
+   oname
+       Objektname, der geprueft werden soll 
+
+RUeCKGABEWERT:
+   
+BESCHREIBUNG:
+   Diese Funktion hat die Aufgabe zu ueberpruefen ob ein Objekt welches
+   geladen werden soll, in dem VC  ueberhaupt erlaubt ist. Dieser 
+   Funktion wird nur der reine Filename uebergeben, ohne Pfad!
+   Diese Funktion macht im Standard-VC in /std/ nichts weiter, als
+   das '.c' am File Namen abzuschneiden.
+   Sollte der Dateiname gueltig sein liefert die Funktion als Rueckgabewert
+   den Filenamen ohne .c und sonst 0.
+
+BEMERKUNGEN:
+   Am besten ruft man in seinem Validate() das ::Validate(), was einem die
+   Arbeit abnimmt, ein .c am Ende zu entfernen.
+
+BEISPIEL:
+   string Validate(string oname) {
+     string raum, spieler;
+     //.c abschneiden
+     oname=::Validate(oname);
+     
+     // folgt der Raum dem Muster "arena|name"? Wenn nein -> ungueltig,
+     // 0 zureckgeben, sonst den Filenamen.
+     if(sscanf(oname,"%s|%s",raum,spieler)<2 || raum!="arena")
+        return 0;
+     return oname;
+   }
+
+SIEHE AUCH:
+     virtual_compiler
+     CustomizeObject(), Validate(), NoParaObjects(), 
+     P_COMPILER_PATH, P_PARA
+     /std/virtual/v_compiler.c
+----------------------------------------------------------------------------
+27.10.2007, Zesstra
diff --git a/doc/lfun/Wear b/doc/lfun/Wear
new file mode 100644
index 0000000..bfc8ad2
--- /dev/null
+++ b/doc/lfun/Wear
@@ -0,0 +1,37 @@
+Wear()
+FUNKTION:
+     public int Wear(object ob) 
+
+DEFINIERT IN:
+     /std/living/clothing.c
+
+ARGUMENTE:
+     object ob
+       Die Ruestung oder Kleidung, die angezogen wird.
+
+BESCHREIBUNG:
+     Das Lebewesen, in dem diese Funktion gerufen wird, zieht die Ruestung
+     oder das Kleidungsstueck <ob> an.
+     ABER: 'Anziehen' bedeutet in diesem Kontext lediglich, dass die
+     Ruestung/Kleidung in P_ARMOURS bzw. P_CLOTHING eingetragen wird. Es
+     finden zur Zeit keine Pruefungen statt, ob das Lebewesen den Gegenstand
+     ueberhaupt anziehen kann. Genausowenig werden Funktionen wie InformWear()
+     gerufen oder etwaige Stat-Boni aktiviert.
+     Die Funktion ist nur dazu gedacht, im Zuge des Anziehens eines Objekts
+     von diesem im Lebewesen gerufen zu werden.
+
+RUeCKGABEWERT:
+     1, wenn das Anziehen erfolgreich war.
+     0 sonst.
+
+BEMERKUNGEN:
+     Nicht von Hand aufrufen, es sei denn man weiss genau, was man tut. Und am
+     besten auch dann nicht.
+
+SIEHE AUCH:
+     WearArmour(), WearClothing(), Unwear(), UnwearArmour(), UnwearClothing()
+     P_CLOTHING, P_ARMOURS
+     FilterClothing(), FilterArmours()
+
+ZULETZT GEAeNDERT:
+14.03.2009, Zesstra
diff --git a/doc/lfun/WearArmour b/doc/lfun/WearArmour
new file mode 100644
index 0000000..9fd8e95
--- /dev/null
+++ b/doc/lfun/WearArmour
@@ -0,0 +1,37 @@
+WearArmour()
+FUNKTION:
+     public int WearArmour(object ob) 
+
+DEFINIERT IN:
+     /std/living/clothing.c
+
+ARGUMENTE:
+     object ob
+       Die Ruestung, die angezogen wird.
+
+BESCHREIBUNG:
+     Das Lebewesen, in dem diese Funktion gerufen wird, zieht die Ruestung
+     <ob> an.
+     ABER: 'Anziehen' bedeutet in diesem Kontext lediglich, dass die
+     Ruestung/Kleidung in P_ARMOURS eingetragen wird. Es finden zur Zeit keine
+     Pruefungen statt, ob das Lebewesen den Gegenstand ueberhaupt anziehen
+     kann. Genausowenig werden Funktionen wie InformWear() gerufen oder
+     etwaige Stat-Boni aktiviert.
+     Die Funktion ist nur dazu gedacht, im Zuge des Anziehens eines Objekts
+     von diesem im Lebewesen gerufen zu werden.
+
+RUeCKGABEWERT:
+     1, wenn das Anziehen erfolgreich war.
+     0 sonst.
+
+BEMERKUNGEN:
+     Nicht von Hand aufrufen, es sei denn man weiss genau, was man tut. Und am
+     besten auch dann nicht.
+
+SIEHE AUCH:
+     Wear(), WearClothing(), Unwear(), UnwearArmour(), UnwearClothing()
+     P_CLOTHING, P_ARMOURS
+     FilterClothing(), FilterArmours()
+
+ZULETZT GEAeNDERT:
+14.03.2009, Zesstra
diff --git a/doc/lfun/WearClothing b/doc/lfun/WearClothing
new file mode 100644
index 0000000..17c0280
--- /dev/null
+++ b/doc/lfun/WearClothing
@@ -0,0 +1,37 @@
+WearClothing()
+FUNKTION:
+     public int WearClothing(object ob) 
+
+DEFINIERT IN:
+     /std/living/clothing.c
+
+ARGUMENTE:
+     object ob
+       Das Kleidungsstuck, das angezogen wird.
+
+BESCHREIBUNG:
+     Das Lebewesen, in dem diese Funktion gerufen wird, zieht das
+     Kleidungsstueck <ob> an.
+     ABER: 'Anziehen' bedeutet in diesem Kontext lediglich, dass die
+     Ruestung/Kleidung in P_CLOTHING eingetragen wird. Es finden zur Zeit
+     keine Pruefungen statt, ob das Lebewesen den Gegenstand ueberhaupt
+     anziehen kann. Genausowenig werden Funktionen wie InformWear() gerufen.
+
+     Die Funktion ist nur dazu gedacht, im Zuge des Anziehens eines Objekts
+     von diesem im Lebewesen gerufen zu werden.
+
+RUeCKGABEWERT:
+     1, wenn das Anziehen erfolgreich war.
+     0 sonst.
+
+BEMERKUNGEN:
+     Nicht von Hand aufrufen, es sei denn man weiss genau, was man tut. Und am
+     besten auch dann nicht.
+
+SIEHE AUCH:
+     Wear(), WearArmour(), Unwear(), UnwearArmour(), UnwearClothing()
+     P_CLOTHING, P_ARMOURS
+     FilterClothing(), FilterArmours()
+
+ZULETZT GEAeNDERT:
+14.03.2009, Zesstra
diff --git a/doc/lfun/WearFunc b/doc/lfun/WearFunc
new file mode 100644
index 0000000..626fd64
--- /dev/null
+++ b/doc/lfun/WearFunc
@@ -0,0 +1,80 @@
+WearFunc()
+
+FUNKTION:
+     int WearFunc(object ruest, int silent, object user);
+
+DEFINIERT IN:
+     eigenen Objekten (fuer /std/clothing/wear)
+
+ARGUMENTE:
+     ruest (object)
+          Die Ruestung/Kleidung, die angezogen werden soll.
+     silent (int)
+          Ob dabei eine Meldung ausgegeben wird.
+     user (object)
+          Das Lebewesen, welches die Ruestung/Kleidung anziehen will.
+
+BESCHREIBUNG:
+     Mit dieser Funktion kann man pruefen, ob sich das Kleidungsstueck bzw.
+     Ruestung <ruest> von this_player() anziehen laesst oder nicht.
+     Kann die Ruestung angezogen werden, so muss ein Wert ungleich 0
+     zurueckgegeben werden.
+
+RUeCKGABEWERT:
+     0, wenn sich die Ruestung nicht anziehen laesst, ansonsten ungleich 0.
+
+BEMERKUNGEN:
+     Bitte nicht darauf verlassen, dass der Spieler das Objekt auch wirklich
+     anzieht, wenn man hier 1 zurueckgibt.
+     Speziell bei Schilden kann das Anziehen trotz eines Rueckgabewertes 
+     != 0 immer noch schief gehen, wenn der Spieler keine Hand mehr frei hat.
+     Wenn ihr sicher sein wollt, dass der Spieler ein Objekt angezogen hat,
+     benutzt bitte InformWear().
+     Bitte nicht drauf verlassen, dass this_player() das ausziehende Lebewesen
+     ist.
+     Die Reihenfolge der Argumente ist etwas unschoen, aber leider wurde <user>
+     erheblich spaeter hinzugefuegt und es war unmoeglich, einige hundert
+     Objekte zu aendern.
+
+BEISPIELE:
+     Ein Helm, der nur von Elfen getragen werden kann:
+
+     inherit "std/armour.c";
+
+     #include <properties.h>
+
+     create()
+     {
+       ::create();
+
+       SetProp(P_ARMOUR_TYPE, AT_HELMET);
+       /* zig weitere SetProp's, um den Helm zu konfigurieren */
+
+       /* WearFunc() ist im Helm selbst zu finden */
+       SetProp(P_WEAR_FUNC, this_object());
+     }
+
+     int WearFunc(object me, int silent, object user)
+     {
+       if (user->QueryProp(P_RACE) == "Elf")
+         return 1;   /* Elfen duerfen den Helm tragen */
+
+       /* Die anderen Rassen sollten zumindest erfahren koennen, wieso
+          sie den Helm nicht tragen koennen... */
+       if (!silent)
+           write( "Der Helm rutscht Dir immer ueber Deine runden "
+                 +"Ohren.\n" );
+       return 0;
+     }
+
+     Gibt jetzt ein Nicht-Elf "trage helm" ein, so bekommt er die Meldung
+     "Der Helm rutscht Dir immer ueber Deine runden Ohren.", Elfen dagegen
+     passt das Teil wie angegossen.
+
+SIEHE AUCH:
+     P_WEAR_MSG, P_UNWEAR_MSG, P_WIELD_MSG, P_UNWIELD_MSG
+     DoWear(), DoUnwear(), InformUnwear(), InformWear()
+     /std/clothing/wear.c
+
+----------------------------------------------------------------------------
+02.02.2009, Zesstra
diff --git a/doc/lfun/WieldFunc b/doc/lfun/WieldFunc
new file mode 100644
index 0000000..23e299f
--- /dev/null
+++ b/doc/lfun/WieldFunc
@@ -0,0 +1,77 @@
+WieldFunc()
+
+FUNKTION:
+     int WieldFunc(object weapon, int silent, object user);
+
+DEFINIERT IN:
+     eigenen Objekten (fuer /std/weapon/combat)
+
+ARGUMENTE:
+     weapon (object)
+          Die Waffe, die gezueckt werden soll.
+     silent (int)
+          Ob dabei eine Meldung ausgegeben werden soll.
+     user (object)
+          Das Lebewesen, welches die Waffe zuecken will.
+
+BESCHREIBUNG:
+     In dieser Funktion kann man zusaetzliche Abfragen vornehmen, ob sich
+     die Waffe <weapon> von <user> zuecken laesst oder nicht.
+
+RUeCKGABEWERT:
+     0, wenn die Waffe nicht gezueckt werden kann, sonst ungleich 0.
+
+BEMERKUNGEN:
+     Selbst wenn man einen Wert ungleich Null zurueckgibt, ist das noch
+     keine Garantie, dass sich die Waffe auch wirklich zuecken laesst! Der
+     Spieler koennte zum Beispiel noch eine Waffe gezueckt haben, die sich
+     nicht wegstecken laesst, etc.
+     Wenn ihr sicher sein wollt, dass der Spieler ein Objekt gezueckt hat,
+     benutzt bitte InformWield().
+     Bitte nicht drauf verlassen, dass this_player() das Lebewesen ist,
+     welches die Waffe zuecke will.
+     Die Reihenfolge der Argumente ist etwas unschoen, aber leider wurde <user>
+     erheblich spaeter hinzugefuegt und es war unmoeglich, einige hundert
+     Objekte zu aendern.
+
+BEISPIELE:
+     Eine Waffe, die sich nicht von Zwergen zuecken laesst:
+
+     inherit "std/weapon";
+
+     #include <properties.h>
+     #include <combat.h>
+
+     create()
+     {
+       ::create();
+
+       ... /* zig SetProp's, um die Waffe zu konfigurieren */
+
+       /* WieldFunc() ist in der Waffe selbst zu finden */
+       SetProp(P_WIELD_FUNC, this_object());
+     }
+
+     int WieldFunc(object weapon, int silent, object user)
+     {
+       /* Nicht-Zwerge duerfen die Waffe zuecken */
+       if (user->QueryProp(P_RACE) != "Zwerg")
+         return 1;
+
+       /* Ansonsten sagen wir evtl., warum das Zuecken nicht klappt... */
+       if (!silent)
+         write( "Deine kleinen Haendchen koennen den Griff nicht "+
+                "umklammern.\n");
+
+       /* ...und brechen das Zuecken ab. */
+       return 0;
+     }
+
+SIEHE AUCH:
+     P_WIELD_MSG, P_UNWIELD_MSG, P_WEAR_MSG, P_UNWEAR_MSG
+     DoWield(), DoUnwield(), InformUnwield(), InformWield() 
+     UnwieldFunc, WieldFunc 
+     /std/weapon/combat.c
+
+---------------------------------------------------------------------------
+02.02.2009, Zesstra
diff --git a/doc/lfun/WithDraw b/doc/lfun/WithDraw
new file mode 100644
index 0000000..d1532a2
--- /dev/null
+++ b/doc/lfun/WithDraw
@@ -0,0 +1,42 @@
+WithDraw()
+FUNKTION:
+     int WithDraw(int amount);
+
+DEFINIERT IN:
+     /p/daemon/zentralbank.c
+
+ARGUMENTE:
+     int amount	- angeforderte Geldmenge
+
+BESCHREIBUNG:
+     Damit wird bei der Zentralbank eine bestimmte Menge Geld angefordert.
+     Der Rueckgabewert haengt vom Kassenstand der Zentralbank ab und ist
+     entweder amount oder amount/3.
+
+RUeCKGABEWERT:
+     Menge des bei der Zentralbank "abgehobenen" Geldes.
+
+BEISPIELE:
+     #include <bank.h>
+     ...
+     if(ZENTRALBANK->WithDraw(50000)<50000)
+      write(break_string(
+       "Leider koennen wir ihnen keinen vollen Zuschuss zu ihrem Hotelbau "
+       "geben!",
+       "Der Beamte sagt: ",78));
+      say(break_string(
+       "Leider koennen wir ihnen keinen vollen Zuschuss zu ihrem Hotelbau "
+       "geben!",
+       "Der Beamte sagt zu "+this_player()->name(WEM)+": ",78));
+      ...
+
+BEMERKUNGEN:
+     Unsere Zentralbank ist korrupt, vor allem dadurch, dass in Laeden und
+     an anderen Stellen Geld erzeugt wird.
+
+SIEHE AUCH:
+     Geldhandling:	AddMoney(L), QueryMoney(L)
+     Zentralbank:	PayIn(L), _query_current_money(L)
+     Sonstiges:		/items/money.c, /sys/bank.h
+
+27. Apr 2004 Gloinson
diff --git a/doc/lfun/__INIT b/doc/lfun/__INIT
new file mode 100644
index 0000000..208b655
--- /dev/null
+++ b/doc/lfun/__INIT
@@ -0,0 +1,12 @@
+SYNOPSIS:
+	__INIT
+
+DESCRIPTION:
+	This function is constructed automagically by the parser at
+	compiler, if the parser was compiled with #define
+	INITIALISATION__INIT. This function is not intended to be
+	defined by the lpc objects, and never to be called from lpc
+	objects. This man page is here just for completeness.
+
+SEE ALSO:
+	initialisation(LPC)
diff --git a/doc/lfun/_query_current_money b/doc/lfun/_query_current_money
new file mode 100644
index 0000000..16b7ee5
--- /dev/null
+++ b/doc/lfun/_query_current_money
@@ -0,0 +1,32 @@
+_query_current_money()
+FUNKTION:
+     int _query_current_money()
+
+DEFINIERT IN:
+     /p/daemon/zentralbank.c
+
+BESCHREIBUNG:
+     Es wird zurueckgegeben, wieviel Geld die Zentralbank besitzt.
+
+BEISPIELE:
+     #include <bank.h>
+     ...
+     if(ZENTRALBANK->_query_current_money()<30000) {
+      write(break_string(
+       "Leider koennen wir ihren Bausparvertrag derzeit nicht einloesen.",
+       "Der Beamte sagt: ",78));
+      say(break_string(
+       "Leider koennen wir ihren Bausparvertrag derzeit nicht einloesen.",
+       "Der Beamte sagt zu "+this_player()->name(WEM)+": ",78));
+     }
+
+BEMERKUNGEN:
+     Unsere Zentralbank ist korrupt, vor allem dadurch, dass in Laeden und
+     an anderen Stellen Geld erzeugt wird.
+
+SIEHE AUCH:
+     Geldhandling:	AddMoney(L), QueryMoney(L)
+     Zentralbank:	WithDraw(L), PayIn(L)
+     Sonstiges:		/items/money.c, /sys/bank.h
+
+27. Apr 2004 Gloinson
diff --git a/doc/lfun/_unparsed_args b/doc/lfun/_unparsed_args
new file mode 100644
index 0000000..4e527b8
--- /dev/null
+++ b/doc/lfun/_unparsed_args
@@ -0,0 +1,29 @@
+_unparsed_args()
+FUNKTION:
+     varargs string _unparsed_args(int level)
+
+DEFINIERT IN:
+     /std/player/command.c:
+
+ARGUMENTE:
+     level
+          Gibt an, wieviel des Textes "weggeparsed" werden soll.
+
+BESCHREIBUNG:
+     Gibt den Text des letzten Befehls des Spielers (ohne das Befehlswort
+     selbst) zurueck. "level" gibt dabei an, wieviel geparsed wird:
+     level = 0 : Gar kein Parsing.
+                 -> entspricht einem query_command()
+     level = 1 : Der Text wird in Kleinbuchstaben umgewandelt, doppelte
+                 Leerzeichen werden entfernt.
+     level = 2 : Semikoli, Kommata und Doppelpunkte werden in Leerzeichen
+		 umgewandelt, doppelte Leerzeichen und Artikel (der, die,
+		 das, ein,...) werden entfernt.
+
+RUeCKGABEWERT:
+     Der geparste Text.
+
+SIEHE AUCH:
+     query_command()
+
+7.Aug 2007 Gloinson
diff --git a/doc/lfun/access_rights b/doc/lfun/access_rights
new file mode 100644
index 0000000..9859761
--- /dev/null
+++ b/doc/lfun/access_rights
@@ -0,0 +1,75 @@
+access_rights()
+
+FUNKTION:
+    int access_rights(string euid, string file);
+
+DEFINIERT IN:
+    access_rights.c (muss man selber schreiben)
+
+PARAMETER:
+    euid
+        Die euid desjenigen, der auf das Verzeichnis schreiben will
+    file
+        Name der Datei, auf die zugegriffen werden soll
+
+BESCHREIBUNG:
+    access_rights() wird immer dann aufgerufen, wenn jemand, der nicht
+    sowieso schon schreibberechtigt ist, in die Datei/das Verzeichnis file
+    schreiben oder loeschen will.
+
+    Anhand von euid kann man dann entscheiden, ob der Schreibzugriff erlaubt
+    wird oder nicht.
+
+RUECKGABEWERT:
+    0, wenn der Zugriff verweigert wird,
+    1, wenn der Zugriff erlaubt wird.
+
+BEISPIELE:
+    /* /d/inseln/wargon/access_rights.c */
+
+    int access_rights(string euid, string file)
+    {
+      string dir, rest;
+
+      // Catweazle darf auf alles zugreifen (*argl* ;^)
+      if (euid == "catweazle")
+        return 1;
+
+      // Rechte auf einzelne Verzeichnisse ermitteln:
+      if (sscanf(file, "%s/%s", dir, rest) != 2)
+        rest = file;
+
+      // Jof und Boing duerfen an Tarko Reub rumpfuschen:
+      if (dir == "tarko" && (euid == "jof" || euid == "boing"))
+        return 1;
+
+      // Anthea darf die Karten von Aurora und der Piratenhoehle bearbeiten:
+      if (dir == "MAPS" && 
+          member( ({"Aurora", "Piratenhoehle" }), rest) >= 0 && 
+          euid == "anthea")
+        return 1;
+
+      // alle anderen duerfen nicht!
+      return 0;
+    }
+
+BEMERKUNGEN:
+    file ist immer relativ zu dem Verzeichnis, in dem das access_rights.c
+    liegt! Will also jemand auf /d/inseln/wargon/tarko/macros.h schreiben,
+    wird file "tarko/macros.h" uebergeben.
+
+    In Verzeichnissen von Magiern mit einem Level >= ELDER_LVL wird das
+    access_rights.c NICHT ausgewertet (da damit andere Magier zB. an
+    Erzmagierrechte gelangen koennten).
+
+    Es wird immer nur EIN access_rights.c ausgewertet, naemlich das in der
+    tiefsten Verzeichnisebene.
+
+    Man kann sowohl in seinen Regionsverzeichnissen als auch in seinen
+    Homeverzeichnissen access_rights.c-Dateien anlegen.
+
+    GANZ WICHTIG!!!
+    Fuer die Dateien, die evtl. von anderen angelegt werden, ist man immer
+    noch selbst verantwortlich! Wenn jemand also ein Gebiet bei Dir an-
+    schliesst, muss es erst von den verantwortlichen Regionsmagiern abgesegnet
+    sein!
diff --git a/doc/lfun/buffer_hp b/doc/lfun/buffer_hp
new file mode 100644
index 0000000..c3e7b1b
--- /dev/null
+++ b/doc/lfun/buffer_hp
@@ -0,0 +1,76 @@
+FUNKTION:
+    int buffer_hp( int val, int rate );
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    val:  Gesamte Heilung.
+    rate: LP-Rate.
+        
+BESCHREIBUNG:
+    Erhoeht die LP eines Spielers automatisch insgesamt um den Wert "val".
+    Pro heart_beat() wird ihm dabei der Wert "rate" zugefuehrt.
+    Sollen neben P_HP noch weitere Props manipuliert werden - bspw. zur
+    P_FOOD - bietet sich die Funktion consume() an.
+
+RUECKGABEWERTE:
+    Der getankte Wert pro heart_beat().
+
+BEMERKUNG:
+    Sollte von jeder tragbaren Heilung genutzt werden, welche den Spieler
+    darauf schliessen lassen kann, auf natuerlichem und nichtmagischem Weg
+    (Essen, Trinken) geheilt worden zu sein.
+
+BEISPIEL:
+    #define TP this_player()
+    ...
+
+    int heilung=1;
+    ...
+
+    create()
+    {
+     ::create();
+     SetProp(P_NAME,"Heilpflanze");
+     ...
+
+     AddCmd("iss","eat");
+    }
+
+    int eat(string str)
+    {
+      notify_fail("WAS willst Du essen?\n");
+      if ( !str || !id(str) )
+       return 0;
+      ...
+
+      if ( !TP->eat_food(25) )
+       return 1;
+
+      TP->buffer_hp(20,5);
+      TP->buffer_sp(80,10);
+      heilung--;
+      write(BS("Du fuehlst langsam, wie Deine Kraefte zurueckkehren."));
+
+      return 1;
+    }
+
+    reset()
+    {
+      heilung=1;
+      ::reset();
+    }
+
+    Es wird durch eat_food getestet, ob der Spieler noch genuegend essen kann.
+    Wenn ja, kriegt unser Held die 25 automatisch oben drauf und ausserdem
+    20 LP in 5-LP-Schritten und 80 KP in 10-LP-Schritten gutgeschrieben.
+
+SIEHE AUCH:
+     Aehnlich:  heal_self, restore_spell_points, restore_hit_points, 
+                buffer_sp
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Props:     P_SP, P_HP,
+     Konzepte:  heilung
+
+9. August 2015 Gloinson
diff --git a/doc/lfun/buffer_sp b/doc/lfun/buffer_sp
new file mode 100644
index 0000000..dc7341c
--- /dev/null
+++ b/doc/lfun/buffer_sp
@@ -0,0 +1,36 @@
+FUNKTION:
+    int buffer_sp( int val, int rate );
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    val:  Gesamte Heilung.
+    rate: KP-Rate.
+        
+BESCHREIBUNG:
+    Erhoeht die KP eines Spielers automatisch insgesamt um den Wert "val".
+    Pro heart_beat() wird ihm dabei der Wert "rate" zugefuehrt.
+    Sollen neben P_SP noch weitere Props manipuliert werden - bspw. zur
+    P_FOOD - bietet sich die Funktion consume() an.
+
+RUECKGABEWERTE:
+    Der getankte Wert pro heart_beat().
+
+BEMERKUNG:
+    Sollte von jeder tragbaren Heilung genutzt werden, welche den Spieler
+    darauf schliessen lassen kann, auf natuerlichem und nichtmagischem Weg
+    (Essen, Trinken) geheilt worden zu sein.
+
+BEISPIEL:
+    s. Bsp. zu "buffer_hp"
+
+SIEHE AUCH:
+     Aehnlich:  heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Props:     P_SP, P_HP,
+     Konzepte:  heilung
+
+9. August 2015 Gloinson
+
diff --git a/doc/lfun/buy_obj b/doc/lfun/buy_obj
new file mode 100644
index 0000000..bf1995b
--- /dev/null
+++ b/doc/lfun/buy_obj
@@ -0,0 +1,42 @@
+buy_obj()
+
+FUNKTION:
+	static string buy_obj(mixed ob, int short);
+
+DEFINIERT IN:
+	/std/shop.c
+
+ARGUMENTE:
+	ob - der Gegenstand bei dem geprueft werden soll, ob der Laden ihn
+	     an this_player() verkauft. Sollte es sich hierbei um ein
+	     FixedObject handeln, wird ein String uebergeben, ansonsten ein
+	     object.
+        short - Bisher noch nicht in Benutzung. Aber fuer die Zukunft
+             vorgesehn, falls man mehrere Objekte auf einmal kauft.
+             Ein auswerten ist keine Pflicht, waere aber praktisch, damit
+             der Scroll dabei nicht zu gross wird.
+
+RUeCKGABEWERT:
+        Ein String was der Haendler sagen soll wieso der Gegenstand nicht
+	verkauft wird. Der String wird dabei wie folgt umgebrochen:
+        break_string(str, 78, Name(WER, 1)+" sagt: ")
+BESCHREIBUNG:
+	Durch ueberschreiben dieser Funktion ist es moeglich bestimmte
+	Objekte (wie z.b. Questobjekte) nur an ausgewaehlte Spieler zu
+	verkaufen). Aber auch abfragen ob der Laden ueberhaupt mit
+	this_player() handelt, sind moeglich.
+
+BEISPIELE:
+	static string buy_obj(mixed ob, int short)
+	{
+	   if (PL->QueryProp(P_RACE)=="Zwerg")
+	      return "Ich verkaufe nichts an Zwerge!";
+	   return ::buy_obj(ob, short);
+	}
+
+SIEHE AUCH:
+	sell_obj(), AddFixedObject(), RemoveFixedObject(), SetStorageRoom(),
+        /std/shop.c
+
+----------------------------------------------------------------------------
+Last modified: Thu Mar 4 15:26:13 1999 by Padreic
diff --git a/doc/lfun/catch_msg b/doc/lfun/catch_msg
new file mode 100644
index 0000000..3bf09c9
--- /dev/null
+++ b/doc/lfun/catch_msg
@@ -0,0 +1,15 @@
+catch_msg()
+
+SYNOPSIS:
+    void catch_msg(mixed *arr, object obj)
+
+DESCRIPTION:
+    When say(), tell_object()  or tell_room() are used with an array 
+    as message, the array will be passed to catch_message() in all living
+    objects that can hear it, instead of writing to the user resp.
+    sending to catch_tell(). This can be used to implement
+    communication protocols between livings. The second denotes
+    the object that has sent the message.
+
+SEE ALSO:
+ say(E), tell_room(E), tell_object(E), catch_tell(L)
diff --git a/doc/lfun/catch_tell b/doc/lfun/catch_tell
new file mode 100644
index 0000000..b64832b
--- /dev/null
+++ b/doc/lfun/catch_tell
@@ -0,0 +1,25 @@
+catch_tell()
+
+SYNOPSIS:
+	void catch_tell(string)
+
+DESCRIPTION:
+	When a message is sent to a noninteractive player, via say(),
+	tell_object, tell_room(), printf() or write(), it will get to the
+	function catch_tell(string). This will enable communications between
+	NPCs and from a player to an NPC.
+
+	Also, if an interactive object is being shadowed and the
+	shadow has catch_tell() defined, it will receive all output
+	that would otherwise be written to the user.
+
+	If a message is sent by an interactive object, catch_tell() is
+	not called in that object, to prevent recursive calls. Thus
+	catch_tell() in interactive objects can be used to filter the
+	output that goes to the users.
+
+	The efun shout() sends to interactive objects only.
+
+SEE ALSO:
+	enable_commands(E), say(E), tell_object(E), tell_room(E),
+	write(E), catch_msg(L) 
diff --git a/doc/lfun/check_and_update_timed_key b/doc/lfun/check_and_update_timed_key
new file mode 100644
index 0000000..513c261
--- /dev/null
+++ b/doc/lfun/check_and_update_timed_key
@@ -0,0 +1,93 @@
+check_and_update_timed_key()
+
+FUNKTION:
+       public int check_and_update_timed_key(int duration, string key)
+       
+DEFINIERT IN:
+       /std/living/life.c    
+
+ARGUMENTE:
+       int duration: In wieviel Sekunden wird <key> wieder freigebeben,
+                     (z.B. wann kann der Spieler an dieser Stelle eine neue 
+                     Heilung bekommen).
+       string key  : Eindeutiger Name, wird zusammen mit <duration>
+                     gespeichert.
+
+BESCHREIBUNG:
+       Diese Funktion hat die Aufgabe, Zeitsperren verschiedenster Art
+       einfach zu ermoeglichen (z.B. die Realisierung charakter-abhaengiger
+       Heilstellen u.ae.).
+
+       <key> muss eindeutig sein, am besten verwendet man den eigenen
+       Magiernamen (und ggf. nen Gebietsnamen) als Teil des Strings.
+
+       Die Funktion ist definiert in /std/living/life.c. Somit funktioniert
+       sie auch bei NPCs. Die Daten werden in P_TIMING_MAP gespeichert, sind
+       also gegen "ende" resistent. (werden allerdings nach Ablauf ggf.
+       'aufgeraeumt')
+
+       Das Mapping P_TIMING_MAP ist NICHT zur Abfrage und / oder Manipulation
+       'per Hand' vorgesehen.
+
+RUeCKGABEWERT:
+       0    Irgendein Fehler im Aufruf, evtl. existiert die Funktion (noch)
+            nicht im jew. Objekt.
+
+      -1    Alles okay. Neuer Zeitpunkt wird automatisch gespeichert. In
+            diesem Fall darf der Spieler geheilt werden.
+
+      >0    Key noch gesperrt, in dem Fall darf also nicht geheilt werden. 
+            Der Rueckgabewert ist der Zeitpunkt, ab dem <key> wieder frei ist,
+            laesst sich daher dazu nutzen, um dem Spieler einen Anhaltspunkt
+            zu geben, wann er die Stelle wieder nutzen kann, etwa:
+
+            "Die Schale ist erst halb voll, Du musst noch etwas warten."
+
+BEISPIELE:
+       Eine Heilstelle soll jedem Spieler alle 5min zur Verfuegung stehen:
+
+       AddCmd(({"trink","trinke"}),"trink_cmd");
+
+       int trink_cmd(string str){
+         ...
+         ...
+         /*
+         Der key sollte natuerlich eine etwas eindeutigere Kennzeichnung
+         wie etwa "tilly_trinken" bekommen, auch wenn er durch einen
+         anderen (gleichnamigen) nicht ueberschrieben werden kann.
+
+         Trifft diese Abfrage hier zu, kann dem Spieler Heilung o.ae. zu-
+         gefuehrt werden. Die neue Zeit (duration) wird automatisch gesetzt.
+         */
+         if(this_player()->check_and_update_timed_key(300,"jof_trinken")==-1){
+           if(this_player()->drink_soft(2)){
+             this_player()->heal_self(50);
+             write("Du fuehlst Dich sichtlich erfrischt.\n");
+             return 1;
+            }
+           else{
+             write("Du hast schon zuviel getrunken.\n");
+             return 1;
+            }
+          }
+         else {
+           write("Du trinkst und denkst . o O (Hmm, nicht schlecht).\n");
+           return 1;
+          }
+         return 0;
+        }
+
+BEMERKUNGEN: 
+       Auch bei dieser Funktion ist darauf zu achten, dass Properties wie
+       P_FOOD, P_DRINK und P_ALCOHOL beruecksichtigt werden.
+       Heilstellen sind dem zustaendigen Magier fuer Heilungs-Balance zu 
+       melden. Wer dies momentan ist, kann dem Mailalias heilungs_balance
+       entnommen werden.
+
+SIEHE AUCH:
+       check_timed_key, eat_food, drink_alcohol, drink_soft, heal_self,
+       restore_spell_points, reduce_hit_point
+
+----------------------------------------------------------------------------
+08.01.2012, Zesstra
+
diff --git a/doc/lfun/check_restrictions b/doc/lfun/check_restrictions
new file mode 100644
index 0000000..2c815cd
--- /dev/null
+++ b/doc/lfun/check_restrictions
@@ -0,0 +1,149 @@
+check_restrictions()
+FUNKTION:
+    string check_restrictions(object pl, mapping restr)
+
+DEFINIERT IN:
+    /std/restriction_checker.c
+
+ARGUMENTE:
+    object pl        geprueftes Lebewesen
+    mapping restr    Mapping mit Restriktionen, s.u.
+
+BESCHREIBUNG:
+    Die Methode wird verwendet, um Restriktionen (zum Beispiel fuer das
+    Casten eines Spells) zu pruefen. Sie wird von Spellbook und
+    Gildenobjekt direkt genutzt.
+
+    Ihr wird dabei ein Spielerobjekt sowie ein Mapping mit den jeweiligen
+    Restriktionen uebergeben. Die aktuell moeglichen Keys des Mappings sind
+    weiter unten gelistet.
+
+BEMERKUNGEN:
+    Es wird bei der Rasse P_REAL_RACE geprueft. Der Tarnhelm funktioniert
+    also nicht.
+
+    Bei Erweiterungsvorschlaegen wendet euch bitte an einen EM oder
+    inheritet im Zweifelsfall nach Absprache.
+    NIEMALS solchen Code einfach KOPIEREN. Spaeter muss nur irgendwer
+    eurem alten Code hinterherraeumen.
+
+Aktuelle Liste der pruefbaren Parameter:
+    P_LEVEL
+      Mindeststufe, die das Lebewesen besitzen muss, um die Aktion
+      auszufuehren.
+    P_GUILD_LEVEL
+      Gildenlevel, das das Lebewesen mindestens erreicht haben muss, um die
+      Aktion auszufuehren.
+    SR_SEER
+      Ist gesetzt, wenn das Lebewesen Seher sein muss.
+      Auswertung nur fuer Interactives, NSC ignorieren das Flag.
+    P_XP
+      Mindestmenge an Erfahrungspunkten, die ein Lebewesen besitzen muss,
+      um die Aktion auszufuehren.
+    P_QP
+      Mindestmenge an Abenteuerpunkten, die das Lebewesen haben muss.
+    P_ALCOHOL
+      Menge an Alkohol, unter der der Alkoholspiegel des Lebewesen liegen
+      muss, um die Aktion noch ausfuehren zu koennen.
+    P_DRINK
+      Menge an Fluessigkeit, unter der der Fluessigkeitsspiegel des
+      Lebewesen liegen muss, um die Aktion noch ausfuehren zu koennen.
+    P_FOOD
+      Beinhaltet die Menge an Nahrung, unter der der Nahrungsspiegel des
+      Spielers liegen muss, um die Aktion noch ausfuehren zu koennen.
+    P_DEAF
+      Ist gesetzt, falls der Spieler nicht taub sein darf.
+    P_FROG
+      Ist gesetzt, falls der Spieler kein Frosch sein darf.
+    P_BLIND
+      Ist gesetzt, falls der Spieler nicht blind sein darf.
+      Achtung: das ist nicht gleichbedeutend mit dem Umstand, dass er evtl.
+      nichts mehr sehen kann. Auch andere Gruende (zum Beispiel Dunkelheit)
+      koennen bewirken, dass ein Spieler nichts mehr sieht.
+    A_INT, A_DEX, A_CON, A_STR
+      Jeweilige Mindesthoehe eines Attribut, um eine Aktion ausfuehren zu
+      koennen.
+    SR_BAD, SR_GOOD
+      Gibt an, wie [minimal] boese bzw. wie [maximal] gut ein Charakter sein
+      darf, um eine Aktion ausfuehren zu koennen.
+    SR_MIN_SIZE, SR_MAX_SIZE
+      Gibt die minimale, bzw. die maximale Groesse an, die ein Charakter
+      maximal haben darf, um eine Aktion ausfuehren zu koennen.
+    SR_FREE_HANDS
+      Gibt an, wieviele freie Haende ein Charakter fuer diese Aktion
+      besitzen muss.
+    SR_EXCLUDE_RACE
+      Mitglieder aller in dieser Liste aufgefuehrten Rassen koennen
+      diese Aktion nicht ausfuehren.
+    SR_INCLUDE_RACE
+      Mitglieder aller NICHT in dieser Liste aufgefuehrten Rassen koennen
+      diese Aktion nicht ausfuehren.
+    SM_RACE
+      Hier kann pro Rasse ein Mapping mit besonderen (nur) fuer diese Rasse
+      geltenden Einschraenkungen vorgenommen werden. Als Keys sind die
+      in dieser Manpage beschriebenen Keys erlaubt, wobei SM_RACE nicht
+      rekursiv ausgewertet wird.
+      Der Rassenname ist gross geschrieben und "*" steht fuer alle Rassen.
+    SR_EXCLUDE_GUILD
+    SR_INCLUDE_GUILD
+      Diese beiden Keys verhalten sich wie SR_*_RACE, nur dass hier Gilden
+      genannt werden.
+    SR_FUN
+      Hier kann eine Funktion in verschiedenen Formen zum Pruefen der
+      Restriktionen angegeben werden, siehe execute_anything().
+      Das kann nuetzlich sein, um andere Restriktionen zu pruefen,
+      wie das Bestehen von Miniquests oder andere Faehigkeiten/Flags.
+      Ist der Test nicht bestanden, gibt die Funktion einen String zurueck.
+    SR_PROP
+      Hier kann ein Mapping mit Properties und zugehoerigen Werten angegeben
+      werden, die jeweils auf Identitaet geprueft werden. Zusaetzlich sollte
+      eine Meldung angegeben werden, die als Fehlermeldung ausgegeben wird,
+      wenn der Spieler die Bedingung nicht erfuellt. Es sollte immer eine
+      passende Meldung fuer den Spieler eingebaut werden. Beispiel:
+      ([ SR_PROP: ([P_AUSGANG_ENTDECKT: 1; "Dein Schwert fluestert "
+          "veraergert: Ich werde Dir erst dann zu Diensten sein, wenn Du "
+          "Dich als wuerdig erwiesen hast!"]) ])
+      Aufgrund der Meldung wird empfohlen, SR_PROP nicht in Restriktionen
+      einzusetzen, die massenweise in Savefiles landen (z.B.
+      Spielersavefiles).
+    SR_QUEST
+      Hier kann ein String-Array mit den Namen (Keys) der Quest(s) angegeben
+      werden, die der Spieler bestanden haben muss, um die Aktion ausfuehren
+      zu koennen.
+    SQ_MINIQUEST
+      Hier kann entweder ein String-Array mit den Ladenamen der vergebenden
+      Objekte oder ein Int-Array mit den Index-Nummern (IDs) der
+      Miniquest(s) (empfohlen!) angegeben werden, die der Spieler bestanden
+      haben muss, um die Aktion ausfuehren zu koennen.
+
+BEISPIELE:
+    // #1 Levelbeschraenkung in der Abenteurergilde
+    AddSpell("feuerball",20,
+             ([SI_SKILLRESTR_LEARN:([P_LEVEL:15]), ...
+
+    // #2 Glaubenstest im Klerus
+    AddSpell("bete",
+             ([SI_SKILLRESTR_LEARN: ([P_GUILD_LEVEL : LVL_NOVIZE,
+                                      SR_FUN : #'glaubensTest ]), ...
+    // mit
+    static string glaubensTest(object pl) {
+      if (pl->QueryProp(K_STRENGTH) < 8000)
+        return ("Deine Glaubensstaerke laesst zu wuenschen uebrig!\n");
+      return 0;
+    }
+
+    // #3 SM_RACE-Modifikation der Restriktionen:
+    //    haertere Restriktionen fuer Zwerge
+    //    - hoeheres Level
+    //    - zusaetzlich A_STR pruefen
+    ([P_LEVEL:15,
+      A_INT:10,
+      SM_RACE: (["Zwerg": ([P_LEVEL:17, A_STR:20])])])
+    // ist identisch zu
+    ([SM_RACE: (["*":     ([P_LEVEL:15, A_INT:10]),
+                 "Zwerg": ([P_LEVEL:17, A_INT:10, A_STR:20])])])
+
+SIEHE AUCH:
+    execute_anything(L), AddSpell (Gilde), P_RESTRICTIONS
+
+03. Januar 2014, Arathorn
diff --git a/doc/lfun/check_timed_key b/doc/lfun/check_timed_key
new file mode 100644
index 0000000..81baff7
--- /dev/null
+++ b/doc/lfun/check_timed_key
@@ -0,0 +1,34 @@
+check_timed_key()
+
+FUNKTION:
+       public int check_timed_key(string key)
+       
+DEFINIERT IN:
+       /std/living/life.c    
+
+ARGUMENTE:
+       string key  : Eindeutiger Name
+
+BESCHREIBUNG:
+       Diese Funktion hat die Aufgabe, mittels check_and_update_timed_key()
+       gespeicherte Zeitsperren zu pruefen, aber dabei nicht zu veraendern.
+
+       Es MUSS bei der eigentlichen Aktion (z.B. Heilung des Spielers) der
+       Rueckgabewert von check_and_update_timed_key() beruecksichtigt werden,
+       sollte dieses nicht -1 geliefert haben, MUSS <key> als gesperrt
+       betrachtet werden, d.h. check_timed_key() hat nur informativen
+       Charakter.
+
+RUeCKGABEWERT:
+       0    Die Zeitsperre <key> ist abgelaufen.
+
+       >0   <key> ist noch gesperrt.
+            Der Rueckgabewert ist der Zeitpunkt, ab dem <key> wieder frei ist,
+
+SIEHE AUCH:
+       check_and_update_timed_key, eat_food, drink_alcohol, drink_soft,
+       heal_self, restore_spell_points, reduce_hit_point
+
+----------------------------------------------------------------------------
+08.01.2012, Zesstra
+
diff --git a/doc/lfun/clean_up b/doc/lfun/clean_up
new file mode 100644
index 0000000..97ddf09
--- /dev/null
+++ b/doc/lfun/clean_up
@@ -0,0 +1,43 @@
+clean_up()
+FUNKTION:
+     int clean_up(int ref);
+
+DEFINIERT IN:
+     /std/room.c
+     man kann die Funktion jedoch auch in beliebigen Objekten selbst
+     definieren.
+
+ARGUMENTE:
+     ref
+             + 0 bei gecloneten Objekten
+             + 1 bei einfachen geladenen Objekten
+             + >1 bei Objekten, die geerbt wurden oder als Blueprint dienen
+             + <0, wenn clean_up() von aussen aufgerufen wurde (das muss man
+               selbst beachten!)
+
+BESCHREIBUNG:
+     Wenn ein Objekt seit langer Zeit nicht mehr benutzt wurde, kann es sich
+     hier selbst zerstoeren. Das sollte das Objekt allerdings nur tun, wenn
+     ref kleiner oder gleich 1 ist.
+
+RUeCKGABEWERT:
+     Der Rueckgabewert hat nur dann eine Bedeutung, wenn sich das Objekt
+     nicht selbst zerstoert hat. Wird 0 zurueckgegeben, so wird clean_up()
+     erst dann wieder aufgerufen, nachdem das Objekt aus- und wieder
+     eingeswappt wurde.
+
+     Ein Rueckgabewert ungleich 0 zeigt an, dass das Objekt sich
+     wahrscheinlich in der naechsten clean_up()-Runde zerstoeren kann, wenn
+     in der Zwischenzeit zB. noch einmal reset() aufgerufen wurde.
+
+BEMERKUNGEN:
+     Standardmaessig definieren nur Raeume clean_up().
+
+     Die Zeiten zwischen zwei Aufrufen von clean_up() betragen momentan
+     einen Tag (86400 Sekunden).
+
+SIEHE AUCH:
+     reset(), P_NEVER_CLEAN
+     memory
+
+21. Maerz 2004 Gloinson
diff --git a/doc/lfun/cmd_shoot b/doc/lfun/cmd_shoot
new file mode 100644
index 0000000..ccd52ce
--- /dev/null
+++ b/doc/lfun/cmd_shoot
@@ -0,0 +1,31 @@
+cmd_shoot()
+
+FUNKTION:
+    static int cmd_shoot(string str)
+
+DEFINIERT IN:
+    /std/ranged_weapon.c
+
+ARGUMENTE:
+    string str    - Schusssyntax
+
+BESCHREIBUNG:
+    Kommandofunktion der Fernwaffe. Enthaelt die Vorbereitung und den Schuss.
+
+BEMERKUNGEN:
+    Ist in der Fernwaffe mit AddCmd( ({"schiess", "schiesse"}), "cmd_shoot");
+    angebunden. Will man eine andere Syntax haben, kann man mit
+    AddCmd/RemoveCmd diese umsetzen.
+
+BEISPIELE:
+    RemoveCmd(({"schiess", "schiesse"})); // entferne Default-Kommando
+    AddCmd(({"schleuder", "schleudere"}), #'cmd_shoot);
+
+SIEHE AUCH:
+    Generell:  P_AMMUNITION, P_SHOOTING_WC, P_STRETCH_TIME
+    Methoden:  shoot_dam(L), cmd_shoot(L)
+    Kommandos: AddCmd(L), RemoveCmd(L)
+    Syntax:    _unparsed_args(L)
+    Sonstiges: fernwaffen
+
+28.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/command_me b/doc/lfun/command_me
new file mode 100644
index 0000000..cdb1ef2
--- /dev/null
+++ b/doc/lfun/command_me
@@ -0,0 +1,81 @@
+command_me()
+FUNKTION:
+    int command_me(string str)
+
+ARGUMENTE:
+    string str - auszufuehrendes Kommando
+
+DEFINIERT IN:
+    /std/npc.c, /std/player/command.c
+
+BESCHREIBUNG:
+    Fuehrt 'str' wie ein Kommando aus, welches direkt vom Living
+    abgegeben wurde.
+
+    Der Rueckgabewert ist >=1 fuer Erfolg und 0 fuer Misserfolg. 
+    Rueckgabewert ist im Erfolgsfall die Hoehe der EvalCost in Ticks. 
+
+    command_me() leitet den Befehl an command()(E) weiter und erlaubt
+    dadurch auch den Aufruf von sonst durch "static", "protected" oder
+    "private" vor externem Aufruf geschuetzten Kommando-Funktionen.
+
+    Kommandos mit oeffentlichen Kommandofunktionen (also damit alle mit
+    AddCmd definierten Kommandos) koennen auch durch command()(E)
+    von aussen ausgeloest werden.
+
+BEMERKUNGEN:    
+    - beruecksichtigt Aliase, d.h. wenn man Aliase eines Spielers
+      ignorieren will, muss man ein \\ (fuer ein \ im Eingabestring)
+      vor den Befehl stellen
+    - fuer objektinterne Kommandos funktioniert also auch command()(E)
+
+BEISPIEL:
+    (Code des Testraum ist in /doc/beispiele/testobjekte/command_me_testraum)
+    // #1: Testraum, zwinge Spieler bei "schleiche heran" zum Furzen
+    //     command_me() ist hier noetig, da das Furzen eine geschuetzte
+    //     Kommandofunktion hat
+    inherit "/std/room";
+
+    void create() {
+      ::create();
+      AddCmd("schleiche&heran|herum", "action_schleichen");
+    }
+    
+    void init() {
+      ::init();
+      add_action("action_kriechen", "kriech", 1);
+    }
+
+    static int action_schleichen(string str) {
+      string tmp = this_player()->QueryProp(P_RACE);
+      // ... 
+      if(tmp[<1]=='e') tmp=tmp[0..<2];
+      write(break_string("Du versuchst leise zu schleichen, dabei passiert "
+        "dir aber ein allzu "+
+        (tmp=="Mensch"?"menschliches":lower_case(tmp)+"isches")+
+        " Missgeschick. Verflucht!", 78));
+      this_player()->command_me("\\furze");
+      return 1;
+    }
+    
+    static int action_kriechen(string str) {
+      write(break_string("Deine Knie tun zu sehr weh dafuer.", 78));
+      tell_room(this_object(), break_string(this_player()->Name(WER)+
+        " knackt mit den Knien.", 78));
+      return 1;
+    }
+    
+    // #2 (in obigem Raum): zwinge Spieler in Raum zu obigem Kommando
+    //    Beide Kommandos gelingen, da Kommando mit AddCmd definiert.
+    find_player("naddl")->command_me("schleiche herum")
+    command("schleiche herum", find_player("naddl")); 
+
+    // #3 (in obigem Raum): zwinge Spieler in Raum zu obigem Kommando
+    find_player("naddl")->command_me("krieche")
+    //    Folgendes Kommando schlaegt fehl, da Kommandofunktion static ist.
+    command("krieche", find_player("naddl"));
+    
+SIEHE AUCH:
+     enable_commands(E), command(E)
+
+06 Sep 2012 Gloinson
diff --git a/doc/lfun/consume b/doc/lfun/consume
new file mode 100644
index 0000000..9979ec4
--- /dev/null
+++ b/doc/lfun/consume
@@ -0,0 +1,85 @@
+public varargs int consume(mapping cinfo, int testonly)
+
+FUNKTION:
+    public varargs int consume(mapping cinfo, int testonly);
+
+    Aenderung der Gesundheit eines Lebewesens durch etwas Konsumierbares.
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    cinfo
+        Mapping mit Informationen ueber die Gesundheitsaenderung
+        Heilung.
+    testonly
+        Gibt an, ob nur die Bedingungen abgetestet werden sollen,
+        oder auch die Wirkung eintreten soll.
+
+RUECKGABEWERT:
+    1 erfolgreich konsumiert
+    0 keine oder falsche Aenderungsdaten in cinfo (nicht benutzbar)
+   <0 Bedingung fuer konsumieren nicht erfuellt, Bitset aus:
+      HC_MAX_FOOD_REACHED    - Kann nichts mehr essen
+      HC_MAX_DRINK_REACHED   - Kann nichts mehr trinken
+      HC_MAX_ALCOHOL_REACHED - Kann nichts mehr saufen
+      HC_HOOK_CANCELLETION   - durch H_HOOK_CONSUME abgebrochen
+
+BESCHREIBUNG:
+    Die Funktion stellt eine Moeglichkeit zur Verfuegung, die Aenderung
+    der Gesundheit eines Lebewesens beim Konsumieren von irgendetwas (z.B in
+    einer Kneipe, durch eine Heilstellte oder tragbare Tanke, ...) zentral zu
+    erledigen. Sie vereint in sich die Pruefung auf Durchfuerbarkeit der
+    Aenderung und Anwendung der Aenderung.
+
+    Der erste Parameter gibt die Eigenschaften der Aenderung an, der zweite ob
+    ausschliesslich die Pruefung auf Anwendbarkeit erfolgen soll.
+
+    Das Mapping cinfo hat folgende Struktur:
+    a) Einfache Angabe der betroffenen Properties. In neuem Code bitte nicht
+       machen, dort ein Mapping wie unter b) beschrieben nutzen!
+
+    b) Strukturiert in Effekte und Bedingungen mit folgenden Schluesseln:
+      H_EFFECTS - Mapping der zu aendernden Properties mit dem Umfang der
+                  Aenderung, erlaubte Properties siehe H_ALLOWED_EFFECTS
+
+      H_CONDITIONS - Mapping der zu pruefenden Properties mit dem Umfang der
+                     Aenderung, erlaubte Properties siehe H_ALLOWED_CONDITIONS
+
+      H_DISTRIBUTION - Verteilung der Aenderung fuer P_SP, P_HP
+                       HD_INSTANT bzw. 0: instante Heilung
+                       1 - 50: angebene Zahl pro Heartbeat
+                       HD_STANDARD: 5 pro Heartbeat
+
+    Aenderungen koennen sowohl positiv als auch negativ sein.
+
+BEMERKUNGEN:
+    Hierbei aber bitte beachten, dass Tanken/Entanken sowie Heilungen ggf. von
+    der (Heilungs-)Balance genehmigt werden muessen!
+
+BEISPIELE:
+    Heilung um 100 KP, 50 LP, aber nur wenn 30 P_FOOD gegessen werden kann:
+
+    consume( ([H_EFFECTS: ([P_HP:50, P_SP:100]),
+               H_CONDITIONS: ([P_FOOD:30]) ]) );
+
+    Heilung um 100 KP und Vergiftung um 2, wenn 15 Alkohol getrunken werden
+    koennen. Die SP werden zeitverzoegert mit 10 pro Heartbeat zugefuehrt.
+
+    consume(([H_EFFECTS: ([P_SP: 100, P_POISON: 2]),
+              H_CONDITIONS: ([P_ALCOHOL: 15]),
+              H_DISTRIBUTION: 10]) )
+
+SIEHE AUCH:
+     Aehnlich:  drink_alcohol, eat_food, drink_soft
+     Heilung:   heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp, buffer_sp
+     Timing:    check_and_update_timed_key
+     Enttanken: defuel_drink, defuel_food
+     Props:     P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+LETZTE AeNDERUNG:
+    29.05.2015, Boing
+
diff --git a/doc/lfun/create b/doc/lfun/create
new file mode 100644
index 0000000..9582609
--- /dev/null
+++ b/doc/lfun/create
@@ -0,0 +1,78 @@
+create()
+
+FUNKTION:
+     protected void create();
+     void create();
+
+DEFINIERT IN:
+     allen Standardobjekten
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Diese Funktion wird aufgerufen, wenn ein Objekt geladen oder geclont
+     wird.
+     In dieser Funktion wird das Objekt initialisiert und konfiguriert.
+     Waehrend des create() kann es einen this_player()/this_interactive()
+     geben, muss aber nicht!
+     Im create() hat das Objekt noch kein environment().
+     create() wird nur gerufen, wenn das Objekte geclont oder explizit geladen
+     wird. Wenn es aufgrund eines inherit in einem anderen Objekt vom Driver
+     geladen wird, wird das create() nicht ausgefuehrt (s. create_super()).
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Erbt man von anderen Objekten, so besteht die erste Aktion innerhalb
+     von create() normalerweise darin, in diesen Objekten create()
+     aufzurufen.
+     Die Funktion kann protected oder static sein (aber nicht private). Es
+     duerfte fuer die meisten Objekte sinnvoll sein, create() protected zu
+     deklarieren.
+
+     Um Speicher zu sparen, kann man bei Blueprints von der Konfigurierung
+     absehen (siehe Beispiel). Dies sollte man allerdings nicht bei Objekten
+     machen, von denen keine Clones erzeugt werden sollen (zB. bei Raeumen). 
+
+     Man sollte bei Abbruch des create() in BP unbedingt set_next_reset(-1);
+     rufen, da sonst die (nicht konfigurierte) BP resetten kann und dann
+     buggt.
+
+BEISPIELE:
+     Ein Gegenstand wuerde wie folgt konfiguriert:
+
+     inherit "std/thing";
+
+     #include <properties.h>
+
+     create()
+     {
+       // Wenn wir die Blueprint sind: NICHT konfigurieren!
+       // Bei normalen Raeumen oder Transportern sind diese beiden
+       // Zeilen wegzulassen!!!
+       if (!clonep(this_object())) {
+           set_next_reset(-1);    // wichtig, damit die BP nicht resettet.
+           return;
+       }
+
+       // Ansonsten die allgemeinen Eigenschaften von /std/thing
+       // konfigurieren...
+       ::create();
+
+       // ...und nun unsere speziellen Eigenschaften:
+       SetProp(P_NAME, "Muell");
+       SetProp(P_SHORT, "Muell");
+       SetProp(P_LONG, "Voellig unnuetzer Muell!\n");
+       SetProp(P_ARTICLE, 0);
+       SetProp(P_VALUE, 0);
+       SetProp(P_GENDER, MALE);
+     }
+
+SIEHE AUCH:
+     create(L), reset(L)
+     hook(C), create(H), create_ob(H), create_super(H, reset(H)
+     create(A), reset(A)
+----------------------------------------------------------------------------
+22.10.2007, Zesstra
diff --git a/doc/lfun/create_default_npc b/doc/lfun/create_default_npc
new file mode 100644
index 0000000..b331c5c
--- /dev/null
+++ b/doc/lfun/create_default_npc
@@ -0,0 +1,55 @@
+create_default_npc()
+FUNKTION:
+     varargs void create_default_npc( int level, int maxhp );
+
+BENUTZUNG:
+     inherit "std/npc";
+
+FUNKTION:
+     Setze die Daten eines Monsters auf einen gewissen Level.
+
+     Der Level sollte zwischen 1 und 20 liegen. Die Stats werden auf diesen
+     Level gesetzt und mehrere andere Werte, so dass das Monster von der
+     Staerke her einem Spieler gleichen Levels entspricht.
+
+     Wird der (optionale) Parameter maxhp weggelassen, wird dieser berechnet
+     nach:
+          maxhp = 42 + 8 * level
+
+     Die genauen Werte sind:
+          P_LEVEL : level
+          P_MAX_HP: maxhp
+          P_MAX_SP: maxhp
+          P_HANDS : 10 * level
+          P_BODY  : (20/3) * level
+          P_XP    : 50 * level * maxhp (== 5 * P_HANDS * max_hp)
+
+          A_STR, A_INT, A_DEX, A_CON : level
+
+BEMERKUNG:
+     Diese Funktion sollte nur im create() eines Monsters benutzt werden.
+     Oben beschriebene Werte, die vor dem Aufruf der Funktion gesetzt
+     wurden, werden durch die neuen Werte ersetzt.
+
+     Ab einem Aufruf mit Level 20 werden P_XP = 202000 gesetzt, also ein
+     Kill-Stup vergeben (siehe P_XP).
+
+BEISPIEL:
+     create_default_npc(17) ergibt:
+
+          P_LEVEL : 17
+          P_MAX_HP: 178
+          P_MAX_SP: 178
+          P_HANDS : 170
+          P_BODY  : 113
+          P_XP    : 151300
+
+          A_STR, A_INT, A_DEX, A_CON : 17
+
+SIEHE AUCH:
+     Funktionen:  AddExp(), GiveKillScore()
+     Properties:  P_XP
+                  P_LEVEL, P_MAX_HP, P_MAX_SP, P_HANDS, P_BODY
+     Sonstiges:   npcs
+
+14.Feb 2007 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/create_super b/doc/lfun/create_super
new file mode 100644
index 0000000..14725a6
--- /dev/null
+++ b/doc/lfun/create_super
@@ -0,0 +1,49 @@
+create_super()
+
+FUNKTION:
+     protected void create_super();
+
+DEFINIERT IN:
+     allen Standardobjekten
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Diese Funktion wird immer dann aufgerufen, wenn ein Objekt implizit durch
+     ein 'inherit' in einem erbenden Objekte geladen wird.
+     Normalweise muss man dieses so geladene Objekte nicht konfigurieren, weil
+     nur das Programm dieses Objektes fuer die erbenden Objekte interessant
+     ist, nicht seine Daten.
+     Was hier aber z.B. sinnvoll ist, ist das Abschalten des Resets, denn ein
+     Objekt, was nur dazu dient, dass es von anderen geerbt wird, braucht
+     keinen Reset, auch wenn es ein reset() definiert (was in erbenden Objekte
+     benutzt wird).
+     Die create_super() in den Standardobjekten tun momentan genau dieses.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Wenn ihr von /std/ erbt, braucht ihr euch in aller Regel um diese
+     Funktion keine Gedanken machen.
+     Ihr koennt diese Funktion aber in Objekten selber definieren, die nur zum
+     Erben gedacht sind. Dies kann sinnvoll ein, wenn ihr nicht von /std/ erbt
+     und ein reset() im Objekt habt oder was machen wollt, was ueber das
+     Abschalten des Resets hinausgeht.
+
+BEISPIELE:
+     Gegeben sei folgende Vererbungskette:
+     /std/room -> /d/inseln/zesstra/stdraum -> /d/inseln/zesstra/raum
+
+     Wird nun 'raum' geladen und 'stdraum' ist noch nicht geladen, wird der
+     Driver implizit von selbst 'stdraum' laden (weil 'raum' das Programm von
+     'stdraum' braucht). Bei diesem Laden wird das create() in 'stdraum' nicht
+     ausgefuehrt, sondern stattdessen create_super().
+    
+SIEHE AUCH:
+     create(L), reset(L)
+     hook(C), create(H), create_ob(H), create_super(H, reset(H)
+     create(A), reset(A)
+----------------------------------------------------------------------------
+22.10.2007, Zesstra
diff --git a/doc/lfun/defuel_drink b/doc/lfun/defuel_drink
new file mode 100644
index 0000000..67e834d
--- /dev/null
+++ b/doc/lfun/defuel_drink
@@ -0,0 +1,59 @@
+FUNKTION:
+    int defuel_drink();
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    Keine.
+        
+BESCHREIBUNG:
+    Enttankt den Spieler automatisch um einen gewissen Fluessigkeits-Wert,
+    sofern der Spieler ueber einer bestimmten Enttank-Grenze liegt und seit
+    seinem letzten Enttanken eine gewisse Zeit vergangen ist.
+    Alle diese Werte sind rassenabhaengig.
+    Ausserdem wird dem Spieler eine gewisse Menge Alkohol entzogen. Er wird
+    also mit jedem fluessigen Enttanken etwas nuechterner.
+
+    Es ist also NICHT moeglich, Einfluss auf die Menge des Enttankens
+    zu nehmen. Das ist hier so gewollt.
+
+    Hat der Spieler mindestens 
+    * P_DEFUEL_LIMIT_DRINK in P_DRINK
+    kann er alle
+    * P_DEFUEL_TIME_DRINK
+    um
+    * (x=P_DRINK*P_DEFUEL_AMOUNT_DRINK/2) + random(x)
+      (also um (50 bis 100 * P_DRINK) Prozent)
+    enttanken.
+
+RUECKGABEWERTE:
+    DEFUEL_TOO_SOON: -2, wenn Enttankintervallzeiten zu kurz.
+    DEFUEL_TOO_LOW:  -1, wenn Enttankgrenze noch nicht erreicht.
+    NO_DEFUEL:        0, wenn Enttanken nicht noetig war (Spieler war leer)
+    >0, wenn Erfolg (enttankte Wert wird zurueckgegeben).
+
+    (Konstanten kommen aus /sys/defuel.h)
+
+BEMERKUNG:
+    Bitte defuel_drink() benutzen und nicht P_DRINK oder P_MAX_DRINK des
+    manipulieren!
+
+    Es gibt keine eigene Methode fuer die Verringerung von P_ALCOHOL.
+
+    Achtung: Nur Toiletten sollten diese Funktion im Spieler aufrufen!
+
+BEISPIEL:
+    s. Bsp. zu defuel_food()
+
+SIEHE AUCH:
+     Aehnlich:  defuel_food
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Heilung:   heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp, buffer_sp
+     Timing:    check_and_update_timed_key
+     Props:     P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/lfun/defuel_food b/doc/lfun/defuel_food
new file mode 100644
index 0000000..1e89110
--- /dev/null
+++ b/doc/lfun/defuel_food
@@ -0,0 +1,85 @@
+FUNKTION:
+    int defuel_food();
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    Keine.
+
+BESCHREIBUNG:
+    Enttankt den Spieler automatisch um einen gewissen Essens-Wert,
+    sofern der Spieler ueber einer bestimmten Enttank-Grenze liegt und seit
+    seinem letzten Enttanken eine gewisse Zeit vergangen ist.
+    Alle diese Werte sind rassenabhaengig.
+
+    Es ist also NICHT moeglich, Einfluss auf die Menge des Enttankens
+    zu nehmen. Das ist hier so gewollt.
+
+    Hat der Spieler mindestens 
+    * P_DEFUEL_LIMIT_FOOD in P_FOOD
+    kann er alle
+    * P_DEFUEL_TIME_FOOD
+    um
+    * (x=P_DRINK*P_DEFUEL_AMOUNT_FOOD/2) + random(x)
+      (also um (50 bis 100 * P_FOOD) Prozent)
+    enttanken.
+
+RUECKGABEWERTE:
+    DEFUEL_TOO_SOON: -2, wenn Enttankintervallzeiten zu kurz.
+    DEFUEL_TOO_LOW:  -1, wenn Enttankgrenze noch nicht erreicht.
+    NO_DEFUEL:        0, wenn Enttanken nicht noetig war (Spieler war leer)
+    >0, wenn Erfolg (enttankte Wert wird zurueckgegeben).
+
+    (Konstanten kommen aus /sys/defuel.h)
+
+BEMERKUNG:
+    Bitte defuel_food() benutzen und nicht P_FOOD oder P_MAX_FOOD des
+    Spielers manipulieren!
+
+    Achtung: Nur Toiletten sollten diese Funktion im Spieler aufrufen!
+
+BEISPIEL:
+    int action_enttanken() {
+      string msg;
+      int val = this_player()->defuel_food();
+
+      switch (val) {
+        case DEFUEL_TOO_SOON:
+          msg = "Du warst doch erst vor kurzem auf Toilette...";
+          break;
+        case DEFUEL_TOO_LOW:
+          msg = "Du versuchst Dich zu entleeren, aber irgendwie will "
+                "das nicht so recht klappen.";
+          break;
+        case NO_DEFUEL:
+          msg = "Du hast seit langem nichts gegessen, wie willst Du dann "
+                "was loswerden koennen?";
+          break;
+        default:
+          string qualifier;
+          int fuzzypercent = (90+random(20)) *
+                             val/this_player()->QueryProp(P_MAX_FOOD);
+          switch(fuzzypercent) {
+            case 0..50:  qualifier = "etwas"; break;
+            case 51..75: qualifier = "enorm"; break;
+            default:     qualifier = "unglaublich"; break;
+          }
+          msg = "Du entleerst Dich "+qualifier"+. Puh, das tat gut!";
+          break;
+      }
+      tell_object(this_player(), break_string(msg, 78));
+      return 1;
+    }
+
+SIEHE AUCH:
+     Aehnlich:  defuel_drink
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Heilung:   heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp, buffer_sp
+     Timing:    check_and_update_timed_key
+     Props:     P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/lfun/deregister_modifier b/doc/lfun/deregister_modifier
new file mode 100644
index 0000000..cbb541e
--- /dev/null
+++ b/doc/lfun/deregister_modifier
@@ -0,0 +1,24 @@
+deregister_modifier()
+FUNKTION:
+     void deregister_modifier(object modifier)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+

+PARAMETER:

+     modifier	- Objekt mit P_X_ATTR_MOD oder P_M_ATTR_MOD

+
+BESCHREIBUNG:
+     Meldet einen Modifier im Spieler ab. Wird durch RemoveSensitiveObject
+     beziehungsweise beim Ausziehen oder Wegstecken gerufen.
+     Muss nicht direkt gerufen werden. Bei Veraenderungen von Modifikatoren
+     sollte stattdessen UpdateAttributes gerufen werden.     
+
+SIEHE AUCH:
+     QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+     SetAttr(), SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+     register_modifier(),P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, 
+     P_ATTRIBUTES_MODIFIER, P_X_ATTR_MOD, P_M_ATTR_MOD, 
+     /std/living/attributes.c

+
+13.Jun.2004, Muadib
\ No newline at end of file
diff --git a/doc/lfun/die b/doc/lfun/die
new file mode 100644
index 0000000..ce055f8
--- /dev/null
+++ b/doc/lfun/die
@@ -0,0 +1,45 @@
+die()
+
+FUNKTION:
+     public varargs void die(int poisondeath,int extern);
+
+DEFINIERT IN:
+     /std/living/life.c
+
+ARGUMENTE:
+     int poisondeath
+	  Dieses Flag sollte bei einem Gifttod (P_POISON) gesetzt sein.
+     int extern
+	  Intern.
+
+BESCHREIBUNG:
+     Das Lebewesen stirbt, meist automatisch von do_damage() ausgeloest, wenn
+     0 HP unterschritten werden. In diesem Fall wird der Kampf beendet, Gift,
+     Alkohol, Trink- und Esswerte, Blindheit, Taubheit u.s.w. auf Null
+     gesetzt oder geloescht.
+
+     Es wird automatisch eine Leiche (siehe auch P_CORPSE, P_NOCORPSE) nebst
+     Todesmeldungen (siehe auch P_DIE_MSG) erzeugt, und fuer Spieler werden
+     Killstupse vergeben, sofern notwendig.
+
+     Ueber den Hook P_TMP_DIE_HOOK kann man jedoch auf den Automatismus
+     Einfluss nehmen, z.B. koennte ein temporaerer Todesbann-Zauber das
+     Sterben fuer kurze Zeit verhindern.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Diese Funktion sollte nur selten direkt verwendet werden. Meist ist der
+     uebliche Weg ueber Defend() -> do_damage() -> die() die logisch bessere
+     und balancetechnisch guenstigere Loesung.
+
+SIEHE AUCH:
+     Todesursachen:	Defend(L), do_damage(L), P_POISON
+     Verwandt:		P_TMP_DIE_HOOK, P_DEADS
+     Todesmeldungen:	P_KILL_NAME, P_KILL_MSG, P_MURDER_MSG, P_DIE_MSG
+			P_ZAP_MSG, P_ENEMY_DEATH_SEQUENCE
+     Sonstiges:		P_CORPSE, P_NOCORPSE, /std/corpse.c
+
+----------------------------------------------------------------------------
+Last modified: Mon May 14 16:20:34 2001 by Patryn
diff --git a/doc/lfun/doUnwearMessage b/doc/lfun/doUnwearMessage
new file mode 100644
index 0000000..e029ea2
--- /dev/null
+++ b/doc/lfun/doUnwearMessage
@@ -0,0 +1,28 @@
+doUnwearMessage()
+
+FUNKTION:
+	void doUnwearMessage(object worn_by, int all);
+
+DEFINIERT IN:
+	/std/armour/combat.c
+
+ARGUMENTE:
+	worn_by
+          Das Lebewesen, dass die Ruestung bisher getragen hat
+        all
+          Wurde "ziehe alles aus"/"ziehe alle ruestungen aus" eingegeben,
+          so ist all gesetzt, ansonsten nicht.
+
+BESCHREIBUNG:
+        Diese Funktion gibt beim Ausziehen einer Ruestung die entspr.
+        Meldung an den Traeger und die Umgebung aus.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        doWearMessage(), doWieldMessage(), doUnwieldMessage()
+
+----------------------------------------------------------------------------
+Last modified: Sat Jun 26 15:41:00 1999 by Paracelsus
+
diff --git a/doc/lfun/doUnwieldMessage b/doc/lfun/doUnwieldMessage
new file mode 100644
index 0000000..dbf07ce
--- /dev/null
+++ b/doc/lfun/doUnwieldMessage
@@ -0,0 +1,25 @@
+doUnwieldMessage()
+
+FUNKTION:
+	void doUnwieldMessage(object wielded_by);
+
+DEFINIERT IN:
+	/std/weapon/combat.c
+
+ARGUMENTE:
+	wielded_by
+          Das Lebewesen, dass die (Parier)Waffe bisher gezueckt hatte.
+
+BESCHREIBUNG:
+        Diese Funktion gibt beim Wegstecken einer Waffe die entspr.
+        Meldung an den Benutzer und die Umgebung aus.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        doWearMessage(), doUnwearMessage(), doWieldMessage()
+
+----------------------------------------------------------------------------
+Last modified: Sat Jun 26 15:32:00 1999 by Paracelsus
+
diff --git a/doc/lfun/doWearMessage b/doc/lfun/doWearMessage
new file mode 100644
index 0000000..1962d5c
--- /dev/null
+++ b/doc/lfun/doWearMessage
@@ -0,0 +1,26 @@
+doWearMessage()
+
+FUNKTION:
+	varargs void doWearMessage(int all);
+
+DEFINIERT IN:
+	/std/armour/combat.c
+
+ARGUMENTE:
+	all
+          Wurde "trage alles"/"trage alle ruestungen" eingegeben, so
+          ist all gesetzt, ansonsten nicht.
+
+BESCHREIBUNG:
+        Diese Funktion gibt beim Anziehen einer Ruestung die entspr.
+        Meldung an den Traeger und die Umgebung aus.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        doUnwearMessage(), doWieldMessage(), doUnwieldMessage()
+
+----------------------------------------------------------------------------
+Last modified: Sat Jun 26 15:30:00 1999 by Paracelsus
+
diff --git a/doc/lfun/doWieldMessage b/doc/lfun/doWieldMessage
new file mode 100644
index 0000000..2315faa
--- /dev/null
+++ b/doc/lfun/doWieldMessage
@@ -0,0 +1,24 @@
+doWieldMessage()
+
+FUNKTION:
+	void doWieldMessage();
+
+DEFINIERT IN:
+	/std/weapon/combat.c
+
+ARGUMENTE:
+	keine
+
+BESCHREIBUNG:
+        Diese Funktion gibt beim Zuecken einer Waffe die entspr.
+        Meldung an den Benutzer und die Umgebung aus.
+
+RUeCKGABEWERT:
+	keiner
+
+SIEHE AUCH:
+        doWearMessage(), doUnwearMessage(), doUnwieldMessage()
+
+----------------------------------------------------------------------------
+Last modified: Sat Jun 26 15:33:00 1999 by Paracelsus
+
diff --git a/doc/lfun/do_damage b/doc/lfun/do_damage
new file mode 100644
index 0000000..2d58839
--- /dev/null
+++ b/doc/lfun/do_damage
@@ -0,0 +1,44 @@
+do_damage(L)
+FUNKTION:
+     int do_damage(int dam,mixed enemy);
+
+DEFINIERT IN:
+     /std/living/life.c
+
+ARGUMENTE:
+     int dam
+	  Die abzuziehenden Lebenspunkte (HP).
+     object enemy
+	  Das Objekt, welches den Schaden zufuegt.
+
+BESCHREIBUNG:
+     Dem Lebewesen werden <dam> HP abgezogen. Falls weniger als 0 HP uebrig
+     bleiben, so stirbt es automatisch mittels die().
+     Ein Lebewesen, welches sich bewegt hat, trifft die ersten Kampfrunden
+     sehr viel schlechter, um Rein-Raus-Attacken zu verhindern. Dieses
+     Vorgehen kann man mittels P_ENABLE_IN_ATTACK_OUT deaktivieren.
+     Lebewesen, welche P_NO_ATTACK gesetzt haben, kann man mit dieser
+     Funktion nicht schaden.
+
+RUeCKGABEWERT:
+     Der tatsaechlich verursachte Schaden.
+
+BEMERKUNGEN:
+     Beim Gegner <enemy>, falls vorhanden, werden XP und ALIGN entsprechend
+     angepasst, im Opfer wird der Gegner in P_KILLER vermerkt, der Kampf wird
+     beendet.
+     Diese Funktion sollte nur selten direkt verwendet werden. Meist ist der
+     uebliche Weg ueber Defend() -> do_damage() -> die() die logisch bessere
+     und balancetechnisch guenstigere Loesung, da Defend() magische
+     Verteidigungen, die der Spieler bei sich hat beruecksichtigt.
+     Es sollte also allein schon aus Fairness gegenueber den Objekten
+     anderer Magier Defend() immer dem direkten reduce_hit_points() oder
+     do_damage() vorgezogen werden. Mittels der Flags in 'spell' kann man
+     sehr viele Parameter beeinflussen.
+
+SIEHE AUCH:
+     Verwandt:	Defend(L), reduce_hit_points(L), die(L)
+     Props:	P_NO_ATTACK, P_ENABLE_IN_ATTACK_OUT, P_KILLER
+		P_XP, P_ALIGN
+
+23.Feb.2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/do_frage b/doc/lfun/do_frage
new file mode 100644
index 0000000..dc08610
--- /dev/null
+++ b/doc/lfun/do_frage
@@ -0,0 +1,21 @@
+do_frage()
+FUNKTION:
+     int do_frage(string text)
+
+DEFINIERT IN:
+     /std/npc/info.c
+
+ARGUMENTE:
+     string str	 - Schluesselwort der Frage
+
+BESCHREIBUNG:
+     Bearbeitet ein Schluesselwort, das mit "frage <wen> nach " uebergeben
+     wurde. Gibt entsprechende Antworten formatiert aus.
+
+BEMERKUNGEN:
+     Recht komplex, besser nicht ueberschreiben wenn man es nicht versteht.
+
+SIEHE AUCH:
+     Verwandt:  GetInfoArr, AddInfo
+
+31.Mar 2007 Gloinson
diff --git a/doc/lfun/do_unwear b/doc/lfun/do_unwear
new file mode 100644
index 0000000..cecfa34
--- /dev/null
+++ b/doc/lfun/do_unwear
@@ -0,0 +1,34 @@
+do_unwear()
+
+FUNKTION:
+     varargs int do_unwear(string str, int silent);
+
+DEFINIERT IN:
+     /std/armour/combat.c
+
+ARGUMENTE:
+     str
+          String der normalerweise dem Parameter des "ziehe"-Kommandos
+          entspricht.
+
+     silent
+          1, wenn das Ausziehen ohne Meldungen durchgefuehrt werden soll.
+
+BESCHREIBUNG:
+     Diese Funktion stellt fest, ob die Ruestung sich durch str
+     identifizieren laesst und angezogen ist und ruft im Erfolgsfall
+     UnWear(silent) auf.
+
+RUeCKGABEWERT:
+     1, wenn alles gut ging, ansonsten 0.
+
+BEMERKUNGEN:
+     Wenn man Ruestungen "von aussen" ausziehen will, sollte man direkt
+     UnWear() verwenden!
+
+SIEHE AUCH:
+     do_wear(), UnWear(), RemoveFunc(), InformUnwear(),
+     /std/armour/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Sun Jun 27 22:29:00 1999 by Paracelsus
diff --git a/doc/lfun/do_wear b/doc/lfun/do_wear
new file mode 100644
index 0000000..fe227d6
--- /dev/null
+++ b/doc/lfun/do_wear
@@ -0,0 +1,27 @@
+do_wear()
+
+FUNKTION:
+     varargs int do_wear(string str, int silent);
+
+DEFINIERT IN:
+     /std/armour/combat.c
+
+ARGUMENTE:
+     str
+          String, der normalerweise dem Parameter des
+          "ziehe/trage"-Kommandos entspricht.
+     silent
+          1, wenn das Anziehen ohne Meldungen durchgefuehrt werden soll.
+
+BESCHREIBUNG:
+     Wenn sich die Ruestung mit "str" identifizieren laesst, wird versucht,
+     sie mittels DoWear() anzuziehen.
+
+RUeCKGABEWERT:
+     1, wenn sich die Ruestung anziehen liess, sonst 0.
+
+SIEHE AUCH:
+     do_unwear(), DoWear(), WearFunc(), InformWear(), /std/armour/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Sun Jun 27 22:31:00 1999 by Paracelsus
diff --git a/doc/lfun/drink_alcohol b/doc/lfun/drink_alcohol
new file mode 100644
index 0000000..28ed1dd
--- /dev/null
+++ b/doc/lfun/drink_alcohol
@@ -0,0 +1,83 @@
+FUNKTION:
+    public varargs int drink_alcohol(int strength, int testonly, string mytext)
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    strength: wird zur aktuellen Saettigung P_ALCOHOL dazu addiert
+    testonly: Ist das Flag gesetzt, wird dem Spieler kein ALCOHOL zugefuehrt.
+              Darf nur zum Testen der Heilstelle verwendet werden und muss
+              im normalen Betrieb auf '0' stehen!
+    mytext: Wer selber einen Text bei Misserfolg ausgeben lassen moechte,
+            darf sich hier was nettes ausdenken.
+            Achtung: Das unterdrueckt nicht die "Nuechtern"-Meldung, die bei
+            negativem strength auftreten kann, wenn P_ALCOHOL wieder 0 ist.
+
+BESCHREIBUNG:
+    Es wird geprueft, ob dem Spieler der angegebene Wert fuer 'strength'
+    auf seine aktuelle P_ALCOHOL addiert werden kann oder nicht. Falls
+    das moeglich ist und testonly = 0, wird P_ALCOHOL entsprechend
+    aktualisiert.
+
+    Sollen neben P_ALCOHOL noch weitere Props manipuliert werden - bspw. zur
+    Heilung eines Lebewesens - bietet sich die Funktion consume() an.
+
+RUECKGABEWERT:
+    0 bei [potentiellem] Misserfolg (strength + P_ALCOHOL > P_MAX_ALCOHOL)
+    1 bei [potentiellem] Erfolg
+    * potentiell bezieht sich hier auf Nutzung mit 'testonly' != 0
+
+BEMERKUNG:
+    drink_alocohol() bitte anstatt eigener Manipulationen von P_ALCOHOL und
+    P_MAX_ALCOHOL verwenden.
+
+    Achtung: Immer erst VOR einer Heilung ausfuehren und bei Erfolg heilen.
+
+    Bei Heilstellen sollte eine evtl. Heilung des Spielers mit der eigens
+    dafuer eingerichteten Funktion check_and_update_timed_key realisiert
+    werden.
+
+BEISPIEL:
+    int heilstelle() {
+      if(this_player()->drink_alcohol(10, 0,
+                                      "Du prustest in den Schnaps. "
+                                      "Der passt nicht mehr rein.\n")) {
+        // Platz fuer 10 "Alkohol" war noch, diese sind jetzt bereits addiert
+        // Nachricht an den Spieler:
+        tell_object(this_player(),
+                    break_string("Du trinkst den Schnaps aus.", 78));
+
+        // Nachricht an andere Livings im Raum
+        object ob = first_inventory(environment(this_player()));
+        do {
+          if(living(ob) && ob!=this_player())
+            ob->ReceiveMsg(this_player()->Name()+" trinkt einen Schnaps aus.",
+                           MT_LOOK|MT_LISTEN,
+                           MA_DRINK);
+          ob = next_inventory(ob);
+        } while(ob);
+
+        // Rassenabhaengige Heilung: Sofort oder in Schritten
+        // Tragbare Heilungen sollten auch eher buffer_hp/_sp benutzen.
+        if(this_player()->QueryProp(P_REAL_RACE)=="Schnapsdrossel")
+          this_player()->heal_self(30);
+        else {
+          this_player()->buffer_hp(30,5);
+          this_player()->buffer_sp(30,5);
+        }
+      }
+
+      return 1;
+     }
+SIEHE AUCH:
+     Aehnlich:  consume, eat_food, drink_soft
+     Heilung:   heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp, buffer_sp
+     Timing:    check_and_update_timed_key
+     Enttanken: defuel_drink, defuel_food
+     Props:     P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/lfun/drink_soft b/doc/lfun/drink_soft
new file mode 100644
index 0000000..4ab6e07
--- /dev/null
+++ b/doc/lfun/drink_soft
@@ -0,0 +1,83 @@
+FUNKTION:
+    public varargs int drink_soft(int strength, int testonly, string mytext)
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    strength: Wird zu dem augenblicklichen Saettigungsgrad (P_DRINK) addiert.
+    testonly: Ist das Flag gesetzt, wird dem Spieler kein DRINK zugefuehrt.
+              Darf nur zum Testen der Heilstelle verwendet werden und muss
+              im normalen Betrieb auf '0' stehen!
+    mytext: Wer selber einen Text bei Misserfolg ausgeben lassen moechte,
+            darf sich hier was nettes ausdenken.
+            Achtung: Das unterdrueckt nicht die "Durst"-Meldung, die bei
+            negativem strength auftritt, wenn P_DRINK wieder 0 ist.
+
+BESCHREIBUNG:
+    Es wird geprueft, ob dem Spieler der angebene Wert "strength" auf
+    aktuelle P_DRINK addiert werden kann oder nicht. Ist dies moeglich,
+    wird es gemacht, es sei denn das testonly != 0.
+
+    Sollen neben P_DRINK noch weitere Props manipuliert werden - bspw. zur
+    Heilung eines Lebewesens - bietet sich die Funktion consume() an.
+
+RUECKGABEWERT:
+     0, wenn strength + P_DRINK > P_MAX_DRINK
+    >0, wenn Erfolg
+
+BEMERKUNG:
+    drink_soft() bitte anstatt eigener Manipulationen von P_DRINK und
+    P_MAX_DRINK verwenden.
+
+    Achtung: Immer erst VOR einer Heilung ausfuehren und bei Erfolg heilen.
+
+    Bei Heilstellen sollte eine evtl. Heilung des Spielers mit der eigens
+    dafuer eingerichteten Funktion check_and_update_timed_key realisiert
+    werden.
+
+BEISPIEL:
+    int heilstelle() {
+      if(this_player()->drink_soft(10, 0, "Du blubberst nicht ueberzeugt "
+                                   "in der Limonade. Das ist zu viel.\n")) {
+        // Platz fuer 10 "Trinken" war noch, diese sind jetzt bereits addiert
+        // Nachricht an den Spieler:
+        tell_object(this_player(), break_string("Du nimmst einen grossen "
+                    "Schluck zuckersuesse Limonade.", 78));
+
+        // alle anderen im Raum bekommen es ggf auch mit:
+        // 1) filter(..., #'living) ergibt die Lebewesen im Raum
+        // 2) filter_objects(..., "ReceiveMsg") ruft ReceiveMsg an jedem
+        // 3) ReceiveMsg(...) bekommt die Folgeparameter
+        filter_objects(filter(all_inventory(environment(this_player())),
+                              #'living) - ({this_player()}),
+                       "ReceiveMsg",
+                       this_player()->Name()+
+                         " trinkt einen Schluck Limonade.",
+                       MT_LOOK|MT_LISTEN,
+                       MA_DRINK);
+
+        // Rassenabhaengige Heilung: Sofort oder in Schritten
+        // Tragbare Heilungen sollten auch eher buffer_hp/_sp benutzen.
+        if(this_player()->QueryProp(P_REAL_RACE)=="Saufziege")
+          this_player()->heal_self(30);
+        else {
+          this_player()->buffer_hp(30,5);
+          this_player()->buffer_sp(30,5);
+        }
+      }
+
+      return 1;
+     }
+
+SIEHE AUCH:
+     Aehnlich:  consume, drink_alcohol, eat_food
+     Heilung:   heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp, buffer_sp
+     Timing:    check_and_update_timed_key
+     Enttanken: defuel_drink, defuel_food
+     Props:     P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/lfun/drop b/doc/lfun/drop
new file mode 100644
index 0000000..ab8dd19
--- /dev/null
+++ b/doc/lfun/drop
@@ -0,0 +1,45 @@
+drop()
+
+FUNKTION:
+    public varargs int drop(object o, mixed msg);
+
+DEFINIERT IN:
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+    object o
+        Das Objekt, das fallengelassen werden soll.
+    mixed msg
+        Eine optionale Meldung, die anstelle von P_DROP_MSG oder der
+        Standardmeldung verwendet wird, oder -1, um die Meldung zu
+        unterdruecken.
+
+BESCHREIBUNG:
+    Der Spieler oder NPC laesst das Objekt fallen. Gibt o->move() keinen
+    positiven Wert zurueck, beispielsweise weil das Objekt verflucht ist,
+    bekommt er eine entsprechende Fehlermeldung.
+
+RUECKGABEWERT:
+    Wenn das Fallenlassen geklappt hat, 1, ansonsten 0.
+
+BEMERKUNG:
+    Diese Funktion ist dann sinnvoll, wenn man den Spieler ein Objekt
+    fallenlassen lassen und sich nicht selbst um die Fehlerbehandlung kuemmern
+    moechte - und da unzaehlige verschiedene Dinge schiefgehen koennen und
+    manche Objekte eigene Fehlermeldungen definieren, eigentlich immer.
+
+    Die Funktion prueft nicht, ob der Spieler/NPC das Objekt ueberhaupt hat,
+    das muss man ggf. selbst ermitteln.
+
+BEISPIEL:
+    if (this_player()->drop(obj, ({
+            "Du wirfst @WEN2 in den Saeureteich.\n",
+            "@WER1 wirft @WENU2 in den Saeureteich.\n" })))
+        obj->remove();
+
+SIEHE AUCH:
+    move(L), P_DROP_MSG, drop_objects(L), P_NOINSERT_MSG, P_NOLEAVE_MSG,
+    P_TOO_MANY_MSG, P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_NODROP
+
+----------------------------------------------------------------------------
+Last modified: Thu Aug 28 22:20:37 2008 by Amynthor
diff --git a/doc/lfun/drop_obj b/doc/lfun/drop_obj
new file mode 100644
index 0000000..2f25e0f
--- /dev/null
+++ b/doc/lfun/drop_obj
@@ -0,0 +1,28 @@
+drop_obj()
+
+FUNKTION
+    int drop_obj(object ob);
+
+DEFINIERT IN:
+
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+
+    ob  Das Objekt, das von dem Lebewesen, in dem diese Funktion aufgerufen
+        wird, fallengelassen werden soll.
+
+BESCHREIBUNG:
+
+    Das Lebewesen, in dem diese Funktion aufgerufen werden soll, laesst
+    den angegebenen Gegenstand fallen, wenn dies moeglich ist.
+
+RUeCKGABEWERT:
+    1, wenn das Objekt fallen gelassen wurde oder dies nicht moeglich war.
+    (in diesem Fall wird auch direkt eine Textausgabe ausgegeben)
+    0 sonst, in diesem Fall wird in notify_fail eine passende Ausgabe
+    plaziert.
+
+SIEHE AUCH:
+
+    find_obs(), give_obj(), pick_obj(), put_obj(), /std/living/put_and_get.c
diff --git a/doc/lfun/drop_objects b/doc/lfun/drop_objects
new file mode 100644
index 0000000..c1045f4
--- /dev/null
+++ b/doc/lfun/drop_objects
@@ -0,0 +1,48 @@
+drop_objects()
+
+FUNKTION:
+    public varargs int drop_objects(string str, mixed msg);
+
+DEFINIERT IN:
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+    string str
+        Was fallengelassen werden soll.
+    mixed msg
+        Eine optionale Meldung, die anstelle von P_DROP_MSG oder der
+        Standardmeldung verwendet wird, oder -1, um die Meldung zu
+        unterdruecken.
+
+BESCHREIBUNG:
+    Der Spieler oder NPC laesst die in <str> benannten Sachen fallen.
+    Kann er ein Objekt nicht fallenlassen, bekommt er eine entsprechende
+    Fehlermeldung. Wenn keine Objekte auf <str> passen, wird per
+    _notify_fail() eine Meldung gesetzt, aber noch nicht ausgegeben.
+
+RUECKGABEWERT:
+    Wenn <str> irgendwelche vorhandenen Sachen sind, 1, sonst 0.
+
+BEMERKUNG:
+    Wenn die Funktion 1 zurueckgibt, heisst das noch nicht, dass der Spieler
+    etwas fallengelassen hat! Er hat es nur versucht, d.h. auf jeden Fall eine
+    Meldung bekommen. Gibt die Funktion 0 zurueck, hat er noch keine bekommen.
+
+BEISPIEL:
+    private int cmd_opfern(string str)
+    {
+        notify_fail("WAS moechtest Du opfern?\n");
+
+        if (!this_player()->drop_objects(str, ({ "Du opferst @WEN2.",
+                                                 "@WER1 opfert @WENU2.\n" })))
+            return 0;
+
+        filter_objects(this_player()->moved_objects(), "remove");
+        return 1;
+    }
+
+SIEHE AUCH:
+    move(L), drop(L), P_DROP_MSG, find_objects(L), moved_objects(L)
+
+----------------------------------------------------------------------------
+Last modified: Fri Jul 25 10:59:37 2008 by Amynthor
diff --git a/doc/lfun/eat_food b/doc/lfun/eat_food
new file mode 100644
index 0000000..ec0102d
--- /dev/null
+++ b/doc/lfun/eat_food
@@ -0,0 +1,86 @@
+FUNKTION:
+    public varargs int eat_food(int food, int testonly, string mytext)
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    food: Wird zu dem augenblicklichen Saettigungsgrad (P_FOOD) addiert.
+    testonly: Ist das Flag gesetzt, wird dem Spieler kein FOOD zugefuehrt.
+              Darf nur zum Testen der Heilstelle verwendet werden und muss
+              im normalen Betrieb auf '0' stehen!
+    mytext: Wer selber einen Text bei Misserfolg ausgeben lassen moechte,
+            darf sich hier was nettes ausdenken.
+            Achtung: Das unterdrueckt nicht die "Hunger"-Meldung, die bei
+            negativem food auftreten kann, wenn P_FOOD wieder 0 ist.
+
+BESCHREIBUNG:
+    Es wird geprueft, ob dem Spieler der angebene Wert "strength" auf seine
+    aktuelle P_FOOD addiert werden kann oder nicht. Ist dies moeglich, wird
+    wird es gemacht, es sei denn das testonly != 0.
+
+    Sollen neben P_FOOD noch weitere Props manipuliert werden - bspw. zur
+    Heilung eines Lebewesens - bietet sich die Funktion consume() an.
+
+RUECKGABEWERT:
+     0, wenn strength + P_FOOD > P_MAX_FOOD.
+    >0, wenn Erfolg.
+
+BEMERKUNG:
+    eat_food() bitte anstatt eigener Manipulationen von P_FOOD und
+    P_MAX_FOOD verwenden.
+
+    Achtung: Immer erst VOR einer Heilung ausfuehren und bei Erfolg heilen.
+
+    Bei Heilstellen sollte eine evtl. Heilung des Spielers mit der eigens
+    dafuer eingerichteten Funktion check_and_update_timed_key realisiert
+    werden.
+
+BEISPIEL:
+    int heilstelle() {
+      // Wenn auf das P_FOOD des Spielers die angegebenen 10 nicht mehr addiert
+      // addiert werden koennen (weil sonst P_MAX_FOOD ueberschritten wird),
+      // wird die Fehlermeldung ausgegeben, dass der Spieler nichts mehr
+      // essen/trinken kann.
+      // Bei gesetztem 'mytext' wird 'mytext' an den Spieler ausgegeben.
+      // Ansonsten wird die Standardmeldung ausgegeben.
+      if (!this_player()->eat_food(10, 0, "Der Keks ist einfach "
+                                          "zuviel fuer Dich.\n") )
+        return 1;
+
+      // Spieler hatte noch ausreichend Spielraum bei P_FOOD. Die 10 sind 
+      // schon addiert worden. Jetzt Nachricht ausgeben:
+      tell_object(this_player(), break_string("Du knabberst ein bisschen an "
+                  "dem Keks herum und fuehlst Dich gleich viel besser.", 78));
+
+      // alle Lebewesen im Raum bekommen das auch mit
+      foreach(object ob:
+              (filter(all_inventory(environment(this_player())), #'living) -
+               ({this_player()})))
+        ob->ReceiveMsg(this_player()->Name()+" knuspert einen Keks weg.",
+                       MT_LOOK|MT_LISTEN,
+                       MA_EAT);
+
+      // Rassenabhaengige Heilung: Sofort oder in Schritten
+      // Tragbare Heilungen sollten auch eher buffer_hp/_sp benutzen.
+      if(this_player()->QueryProp(P_REAL_RACE)=="Kruemelmonster")
+        this_player()->heal_self(30);
+      else {
+        this_player()->buffer_hp(30,5);
+        this_player()->buffer_sp(30,5);
+      }
+
+      return 1;
+    }
+
+SIEHE AUCH:
+     Aehnlich:  consume, drink_alcohol, drink_soft
+     Heilung:   heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp, buffer_sp
+     Timing:    check_and_update_timed_key
+     Enttanken: defuel_drink, defuel_food
+     Props:     P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/lfun/execute_anything b/doc/lfun/execute_anything
new file mode 100644
index 0000000..9c889f0
--- /dev/null
+++ b/doc/lfun/execute_anything
@@ -0,0 +1,42 @@
+execute_anything()
+FUNKTION:
+    protected mixed execute_anything(mixed fun, mixed args, ...)
+
+DEFINIERT IN:
+    /std/util/executer.c
+
+ARGUMENTE:
+    mixed fun        auszufuehrende Funktion/Array/Closure ... anything
+    mixed args       weitere Argumente, werden weiter uebergeben
+
+BESCHREIBUNG:
+    Fuehrt "alles" aus:
+    
+    'fun' kann sein:
+    - eine Closure
+      [funcall(fun, args, ...)]
+    - einen String als Funktion im Objekt
+      [call_other(this_object(), fun, args, ...)]
+    - ein Array mit Objekt/Objektnamen + Funktion als Aufruf der Funktion am
+      Objekt/Objektnamen:
+      [call_other(array[0], array[1], args...)]
+
+    Wird execute_anything() aus dem restriction_checker gerufen, wird als
+    erster Parameter immer das gepruefte Living uebergeben.
+
+BEMERKUNGEN:
+    Es kann sich anbieten, die gerufene Funktion mit varargs-Argumenten zu
+    gestalten, damit ihr mehr Argumente uebergeben werden koennen als in der
+    Funktionsdefinition angegeben sind. 
+
+    Der Restriktionspruefer (/std/restriction_checker) versteht im Falle eines
+    Arrays mit Objekt/Objektnamen + Funktion auch ein Array mit mehr als 2
+    Elementen. Die weiteren Elemente werden dann zu weiteren Argumenten der
+    gerufenen Funktion. Hierbei wird <pl> ggf. aber als erstes Argument vor
+    alle anderen eingefuegt.
+
+SIEHE AUCH:
+    check_restrictions, varargs
+
+31.12.2013, Zesstra
+
diff --git a/doc/lfun/exit b/doc/lfun/exit
new file mode 100644
index 0000000..190db91
--- /dev/null
+++ b/doc/lfun/exit
@@ -0,0 +1,33 @@
+exit()
+
+FUNKTION:
+  varargs void exit(object liv, object dest);
+
+DEFINIERT IN:
+  /std/room/description.c
+
+ARGUMENTE:
+  liv - (object) Das bewegte Lebewesen.
+  dest - (object) Das Environment, in welches bewegt wird.
+
+BESCHREIBUNG:
+  Diese Funktion wird immer dann aufgerufen, wenn ein Lebewesen den
+  Raum verlaesst. Standardmaessig werden hier ggf. die Raummeldungen
+  abgestellt, man kann aber auch eigene Checks einhaengen. In dem Fall MUSS
+  man aber das geerbte exit() auf jeden Fall aufrufen.
+
+RUeCKGABEWERT:
+  keiner
+
+BEMERKUNG:
+  Man beachte, dass this_player() 0 sein kann, wenn z.B. ein netztoter Spieler
+  Spieler den Raum verlaesst.
+  Man beachte ausserdem, dass this_player() nicht unbedingt das bewegte Living
+  sein muss. Wenn z.B. jemand ein Lebewesen bewegt, ist TP der, der die
+  Bewegung durchfuehrt, nicht das Lebewesen.
+
+SIEHE AUCH:
+  init(), this_player(), previous_object(), caller_stack(),
+  NotfiyLeave(), NotifyRemove(), NotifyDestruct()
+----------------------------------------------------------------------------
+Last modified: 25.02.2009, Zesstra
diff --git a/doc/lfun/find_obs b/doc/lfun/find_obs
new file mode 100644
index 0000000..8f44384
--- /dev/null
+++ b/doc/lfun/find_obs
@@ -0,0 +1,38 @@
+find_obs()
+
+FUNKTION
+    object* find_obs(string str, int meth)
+
+DEFINIERT IN:
+
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+
+    str     Der String der geparsed werden soll.
+    meth    Mit Hilfe dieses Parameters koennen bestimmte Bereichs-
+            eingrenzungen vorgenommen werden (definiert in moving.h):
+
+            PUT_GET_NONE - keinerlei Bereichseingrenzung.
+            PUT_GET_TAKE - es handelt sich um ein Nehmen von Gegenstaenden
+                           also wird das inventory ausgenommen.
+            PUT_GET_DROP - es handelt sich um das Entfernen von Gegenstaenden
+                           also wird das environment ausgenommen.           
+                                                                            
+BESCHREIBUNG:                                                               
+                                                                            
+    Der String (str) muss folgendes Format haben damit Objekte gefunden
+    werden.
+
+    <gegenstand> [aus container] [in mir|im raum]
+
+    <gegenstand> kann hierbei sowohl eine Objekt-ID als auch ein
+    Gruppenbezeichner wie z.b. "alles" sein.
+
+RUeCKGABEWERT:
+
+    Ein Array mit allen Objekten die sich angesprochen fuehlen, oder aber 0.
+
+SIEHE AUCH:
+
+    drop_obj(), give_obj(), pick_obj(), put_obj(), /std/living/put_and_get.c
diff --git a/doc/lfun/get_killing_player b/doc/lfun/get_killing_player
new file mode 100644
index 0000000..16685b9
--- /dev/null
+++ b/doc/lfun/get_killing_player
@@ -0,0 +1,39 @@
+get_killing_player()
+
+FUNKTION:
+     protected object get_killing_player()
+
+DEFINIERT IN:
+     /std/living/life.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Liefert im Tod (nach dem toetenden do_damage()) das Spielerobjekt, was
+     den Tod wohl zu verantworten hat, falls es ermittelt werden kann. Es
+     werden registrierte Helfer-NPC und einige schadenverursachende Objekte
+     beruecksichtigt. Hierbei wird QueryUser() in den Objekten abgefragt.
+
+     Es benoetigt ein gueltiges P_KILLER, d.h. falls das Lebewesen vergiftet
+     wurde oder das toetende Objekt aus sonstigen Gruenden nicht in P_KILLER
+     steht, funktioniert es nicht.
+     Auch gibt es bestimmt Objekte, die fuer Spieler toeten koennen, die die
+     diese Funktion nicht kennt.
+     (Dies gilt beides ebenso fuer /p/service/mupfel/getkill.c, ist also kein
+      Grund, jenes statt dieser Funktion zu nutzen.)
+
+RUeCKGABEWERT:
+     Das Objekt des Spielers, falls es ermittelt werden konnte, sonst 0.
+
+BEMERKUNGEN:
+    Der Name des Spieler ist mittel Name() ermittelbar. Will man die Info, 
+    womit ein Spieler den Kill ggf. gemacht hat, kann man P_KILLER
+    auswerten/nutzen.
+
+SIEHE AUCH:
+     QueryUser
+     P_KILLER
+----------------------------------------------------------------------------
+11.11.2013, Zesstra
+
diff --git a/doc/lfun/gilde/AddSkill b/doc/lfun/gilde/AddSkill
new file mode 100644
index 0000000..21db504
--- /dev/null
+++ b/doc/lfun/gilde/AddSkill
@@ -0,0 +1,33 @@
+AddSkill()
+FUNKTION:
+    varargs int AddSkill(string sname, mapping ski)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    string sname       Name des Skills
+    mapping ski        Skill-Mapping
+
+BESCHREIBUNG:
+    Fuegt den Skill zur Liste der in dieser Gilde lernbaren Skills
+    hinzu. Das Mapping enthaelt Informationen, die der Gildenraum
+    bzw. das Gildenobjekt zum Skill herausgeben und die das Lernen
+    des Skills beeinflussen.
+
+RUECKGABWERT:
+    1 fuer Erfolg
+
+BEISPIEL:
+    AddSkill( FIGHT(WT_CLUB), ([ OFFSET(SI_SKILLLEARN) : 1 ]) );
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), QuerySpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/AddSpell b/doc/lfun/gilde/AddSpell
new file mode 100644
index 0000000..c0ca935
--- /dev/null
+++ b/doc/lfun/gilde/AddSpell
@@ -0,0 +1,47 @@
+AddSpell()
+FUNKTION:
+    varargs int AddSpell(string verb, mapping ski)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    string verb        Name des Spells
+    mapping ski        Skill-Mapping
+
+BESCHREIBUNG:
+    Fuegt den Spell zur Liste der in dieser Gilde lernbaren Spells
+    hinzu. Das Mapping enthaelt Informationen, die der Gildenraum
+    bzw. das Gildenobjekt zum Spell herausgeben und die das Lernen
+    des Spells beeinflussen.
+
+RUECKGABWERT:
+    1 fuer Erfolg
+
+BEMERKUNGEN:
+    Siehe das Verhalten von QuerySpell (gilde) zum Zusammenfuegen
+    der AddSpell-Informationen aus Gilde und Spellbook. Relevant
+    zB fuer Lernrestriktionen.
+
+BEISPIEL:
+    AddSpell("entfluche",
+      ([SI_SKILLRESTR_LEARN :
+        ([P_GUILD_LEVEL: LVL_WANDER,
+          SR_FUN:        #'glaubensTest]),
+        SI_DIFFICULTY: 100,
+        SI_SKILLINFO:  "Wanderprediger ab Stufe 7",
+        SI_SKILLINFO_LONG: break_string(
+          "Um jemanden von einem laestigen Sprachfluch zu befreien, "
+          "sollte man diese Anrufung benutzen [...]", 78),
+        SI_GOD:        LEMBOLD]));
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSkill, QuerySpell, QuerySkill, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+3. Okt 2011 Gloinson
diff --git a/doc/lfun/gilde/GuildRating b/doc/lfun/gilde/GuildRating
new file mode 100644
index 0000000..7bfb6b2
--- /dev/null
+++ b/doc/lfun/gilde/GuildRating
@@ -0,0 +1,27 @@
+GuildRating()
+FUNKTION:
+    int GuildRating(object pl)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    object pl          Spieler, der geratet werden soll
+
+BESCHREIBUNG:
+    Gibt das Guild-Rating des Spielers im Bereich 0-MAX_ABILITY zurueck
+    und schreibt sie in P_GUILD_RATING. Wichtig fuer Levelbestimmung!
+    
+    Normalerweise ist das der Mittelwert der Skill-Abilities aller Skills
+    und Spells, das Verhalten kann aber ueberschrieben werden.
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS, P_GUILD_RATING
+    Gildenfkt.:
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+10. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/InitialSkillAbility b/doc/lfun/gilde/InitialSkillAbility
new file mode 100644
index 0000000..28a2689
--- /dev/null
+++ b/doc/lfun/gilde/InitialSkillAbility
@@ -0,0 +1,31 @@
+InitialSkillAbility()
+FUNKTION:
+    static int InitialSkillAbility(mapping ski, object pl)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    mapping ski     Der zu lernende Skill
+    object  pl      Spieler
+
+BESCHREIBUNG:
+    Gibt den initialen Ability-Wert fuer einen neu zu lernenden Skill (Spell)
+    zurueck. Die Standardformel benutzt nur Intelligenz und SI_SKILLLEARN und
+    kann in der Gilde ueberschrieben werden.
+
+BEMERKUNGEN:
+    Der zurueckgegebene Wert wird noch in das Spieler-Skillsystem eingegeben
+    und daher kann der real gelernte Wert abweichen
+
+SIEHE AUCH:
+    Skills:         LimitAbility, ModifySkill
+    GObj Lernen:    LearnSkill, LearnSpell
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/LearnSkill b/doc/lfun/gilde/LearnSkill
new file mode 100644
index 0000000..c381959
--- /dev/null
+++ b/doc/lfun/gilde/LearnSkill
@@ -0,0 +1,35 @@
+LearnSkill()
+FUNKTION:
+    int LearnSkill(string skill)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    string skill     Der zu lernende Skill
+
+BESCHREIBUNG:
+    Diese Funktion ueberprueft den Spieler auf Gildenzugehoerigkeit
+    und ruft, falls kein 'skill' angegeben ist die SkillListe()
+    fuer Skills auf.
+
+    Falls ein Argument angegeben wird, wird bei dem Spieler dieser Skill
+    initialisiert, sofern er die notwendigen Anforderungen erfuellt hat.
+
+RUECKGABEWERT:
+    0 bei Fehler, 1 bei Erfolg.
+
+BEMERKUNGEN:
+    Fuer die Lebewesen-Skills gibt es eine gleichnamige Funktion.
+    Siehe dafuer LearnSkill.
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/LearnSpell b/doc/lfun/gilde/LearnSpell
new file mode 100644
index 0000000..55c5840
--- /dev/null
+++ b/doc/lfun/gilde/LearnSpell
@@ -0,0 +1,32 @@
+LearnSpell()
+FUNKTION:
+    varargs int LearnSpell(string spell, object pl)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    string spell     Der zu lernende Spell
+    object pl        lernender Spieler, wenn 0, wird this_player() genommen
+
+BESCHREIBUNG:
+    Diese Funktion ueberprueft den Spieler auf Gildenzugehoerigkeit
+    und ruft, falls kein 'spell' angegeben ist die SkillListe()
+    fuer Spells auf.
+
+    Falls ein Argument angegeben wird, wird bei dem Spieler dieser Spell
+    initialisiert, sofern er die notwendigen Anforderungen erfuellt hat.
+
+RUECKGABEWERT:
+    0 bei Fehler, 1 bei Erfolg.
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/QuerySkill b/doc/lfun/gilde/QuerySkill
new file mode 100644
index 0000000..59dce12
--- /dev/null
+++ b/doc/lfun/gilde/QuerySkill
@@ -0,0 +1,33 @@
+QuerySkill()
+FUNKTION:
+    mapping QuerySkill(string skill)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    string skill       Name des Skills
+
+BESCHREIBUNG:
+    Liefert fuer diesen Skill die Gildeninformationen in einem
+    Mapping zurueck.
+
+BEISPIEL:
+    // /gilden/klerus->QuerySkill(FIGHT(WT_CLUB)) gibt zB zurueck:
+    ([SI_FUN:                "Fight_club",
+      OFFSET(SI_SKILLLEARN): 1
+      SI_SKILLRESTR_USE:     ([SR_FUN:#'gilden/klerus->spellTest()]),
+      OFFSET(SI_SKILLLEARN): #'gilden/klerus->learnOffset,
+      OFFSET(SI_SPELLCOST):  #'gilden/klerus->costOffset,
+      FACTOR(SI_SPELLCOST):  #'gilden/klerus->costFactor])
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSkill, AddSpell, QuerySpell
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/QuerySpell b/doc/lfun/gilde/QuerySpell
new file mode 100644
index 0000000..22f1965
--- /dev/null
+++ b/doc/lfun/gilde/QuerySpell
@@ -0,0 +1,54 @@
+QuerySpell()
+FUNKTION:
+    mapping QuerySpell(string spell)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    string spell       Name des Spells
+
+BESCHREIBUNG:
+    Liefert fuer diesen Spell die Gilden- und Spellbookinformationen
+    zusammengefasst in ein Mapping zurueck.
+    Die Gildeninformationen haben dabei Vorrang (d.h. eine Lernrestriktion
+    im Spellbook wird benutzt, bei unterschiedlichen Werten fuer das gleiche
+    Attribut geht der Wert in der Gilde vor).
+
+BEISPIEL:
+    // /gilden/klerus->QuerySpell("entfluche") gibt zB zurueck:
+    ([SI_SPELLFATIGUE: 2,
+      SI_SP_LOW_MSG:   "Deine Konzentration reicht nicht aus, das Interesse "
+                       "der Goetter zu "wecken.\n",
+      SI_TIME_MSG:     "So schnell koennen sich die Goetter nicht wieder um "
+                       "Dich kuemmern!\n",
+      SI_SKILLLEARN:   5,
+      OFFSET(SI_SKILLLEARN):15
+      SI_SKILLRESTR_LEARN:
+      ([P_LEVEL:       7,
+        P_GUILD_LEVEL: LVL_WANDER,
+        SR_FUN:        #'gilden/klerus->glaubensTest]),
+      SI_DIFFICULTY:   100,
+      SI_SKILLINFO:    "Wanderprediger ab Stufe 7",
+      SI_SKILLINFO_LONG:
+        "Um jemanden von einem laestigen Sprachfluch zu befreien, "
+        "sollte man diese Anrufung benutzen [...]",
+      SP_NAME:         "entfluche",
+      SI_SKILLRESTR_USE: ([ SR_FREE_HANDS : 0 ]),
+      SI_MAGIC_TYPE:   ({MT_SAKRAL})
+      SI_GOD:          LEMBOLD,
+      SI_SKILLRESTR_USE:     ([SR_FUN:#'gilden/klerus->spellTest()]),
+      OFFSET(SI_SKILLLEARN): #'gilden/klerus->learnOffset,
+      OFFSET(SI_SPELLCOST):  #'gilden/klerus->costOffset,
+      FACTOR(SI_SPELLCOST):  #'gilden/klerus->costFactor])
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSkill, AddSpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+3. Okt 2011 Gloinson
diff --git a/doc/lfun/gilde/SkillListe b/doc/lfun/gilde/SkillListe
new file mode 100644
index 0000000..8cc2b39
--- /dev/null
+++ b/doc/lfun/gilde/SkillListe
@@ -0,0 +1,27 @@
+SkillListe()
+FUNKTION:
+    int SkillListe(int what)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    int what        Rueckgabeoption:
+
+BESCHREIBUNG:
+    Gibt eine Text mit Liste mit lernbaren Skills/Spells zurueck:
+    
+    Fuer 'what': 0 - alle; 1 - Spells; 2 - Skills.
+    
+    Zeigt Eintraege aus SI_SKILLINFO.
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+    Skills:         skill_info_liste
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/UseSpell b/doc/lfun/gilde/UseSpell
new file mode 100644
index 0000000..96823cc
--- /dev/null
+++ b/doc/lfun/gilde/UseSpell
@@ -0,0 +1,32 @@
+UseSpell()
+FUNKTION:
+    varargs int UseSpell(object caster, string spell, mapping sinfo)
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+ARGUMENTE:
+    object caster      Spieler, der Spell nutzt
+    string spell       Spell-Name
+    mapping sinfo      Spell-Informationen
+
+BESCHREIBUNG:
+    Prueft, ob der Spell in der Gilde definiert ist und ruft ihn dann
+    ggf in aus dem Spell-Mapping gelesenen Gilden-SI_SPELLBOOK auf.
+
+    Wird von living/skills::UseSpell gerufen, wenn dieses die SI_CLOSURE,
+    also die Funktion eines Spells sucht, fuer den kein SI_SPELLBOOK
+    explizit angegeben wurde.
+
+RUECKGABWERT:
+    Rueckgabewert des Spells aus dem Spellbook oder 0.
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell, QuerySkill
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:     GuildRating
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/austreten b/doc/lfun/gilde/austreten
new file mode 100644
index 0000000..4770bef
--- /dev/null
+++ b/doc/lfun/gilde/austreten
@@ -0,0 +1,34 @@
+austreten()
+FUNKTION:
+    varargs int austreten(int loss)
+
+ARGUMENTE:
+    int loss       Prozentsatz, um den sich die Gildenskills verschlechtern
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+BESCHREIBUNG:
+    Austrittsfunktion der Gilde. Prueft die Restriktionen der Gilde und
+    laesst this_player() ggf austreten. Das Austreten aus der Standard-
+    gilde ist dabei nicht moeglich.
+
+    Der Gildenmaster loest ggf ein EVT_GUILD_CHANGE aus. Dabei werden
+    E_OBJECT, E_GUILDNAME, E_LAST_GUILDNAME entsprechend gesetzt.
+
+    Der Gildenmaster senkt auch die Skill/Spell-Faehigkeiten um 'loss' bzw.
+    normalerweise mindestens 20%.
+
+    Durch Ueberschreiben koennen hier zB Abschiedsmeldungen gesendet werden.
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:
+    * Ein/Austritt: beitreten, bei_oder_aus_treten
+    * Props dafuer: P_GUILD_RESTRICTIONS
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/bei_oder_aus_treten b/doc/lfun/gilde/bei_oder_aus_treten
new file mode 100644
index 0000000..0a5de78
--- /dev/null
+++ b/doc/lfun/gilde/bei_oder_aus_treten
@@ -0,0 +1,25 @@
+bei_oder_aus_treten()
+FUNKTION:
+    int bei_oder_aus_treten(string str)
+
+ARGUMENTE:
+    string str       Spielerparameter
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+BESCHREIBUNG:
+    Aus- oder Eintrittsfunktion, ruft beitreten() bzw. austreten() auf.
+    Wird im Std-Gildenraum per AddCmd zur Verfuegung gestellt.
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell, QuerySkill
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:
+    * Ein/Austritt: beitreten, austreten
+    * Props dafuer: P_GUILD_RESTRICTIONS
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/gilde/beitreten b/doc/lfun/gilde/beitreten
new file mode 100644
index 0000000..3938f7b
--- /dev/null
+++ b/doc/lfun/gilde/beitreten
@@ -0,0 +1,28 @@
+beitreten()
+FUNKTION:
+    int beitreten()
+
+DEFINIERT IN:
+    /std/gilden_ob.c
+
+BESCHREIBUNG:
+    Beitrittsfunktion der Gilde. Prueft die Gilde selbst im Gildenmaster,
+    dann die Restriktionen der Gilde und laesst this_player() ggf eintreten.
+
+    Der Gildenmaster loest ggf ein EVT_GUILD_CHANGE aus. Dabei werden
+    E_OBJECT, E_GUILDNAME, E_LAST_GUILDNAME entsprechend gesetzt.
+
+    Durch Ueberschreiben koennen hier zB Standard-Skills und Spells den
+    Spieler bei Eintritt gelehrt werden.
+
+SIEHE AUCH:
+    GObj Lernen:    LearnSkill, LearnSpell, InitialSkillAbility
+    * Anzeigen:     SkillListe
+    * Verwalten:    AddSpell (gilde), AddSkill, QuerySpell
+    * Nutzen:       UseSpell (gilde)
+    * Properties:   P_GUILD_SKILLS, P_GLOBAL_SKILLPROPS
+    Gildenfkt.:
+    * Ein/Austritt: bei_oder_aus_treten, austreten
+    * Props dafuer: P_GUILD_RESTRICTIONS
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/give b/doc/lfun/give
new file mode 100644
index 0000000..39a2624
--- /dev/null
+++ b/doc/lfun/give
@@ -0,0 +1,43 @@
+give()
+
+FUNKTION:
+    public varargs int give(object o, object dest, mixed msg);
+
+DEFINIERT IN:
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+    object o
+        Das Objekt, das uebergeben werden soll.
+    object dest
+        Der Spieler oder NPC, der das Objekt bekommen soll.
+    mixed msg
+        Eine optionale Meldung, die anstelle von P_GIVE_MSG oder der
+        Standardmeldung verwendet wird, oder -1, um die Meldung zu
+        unterdruecken.
+
+BESCHREIBUNG:
+    Der Spieler oder NPC uebergibt dem Empfaenger das Objekt. Gibt o->move()
+    keinen positiven Wert zurueck, beispielsweise weil das Objekt verflucht
+    ist oder der Empfaenger es nicht mehr tragen kann, bekommt er eine
+    entsprechende Fehlermeldung.
+
+RUECKGABEWERT:
+    Wenn die Uebergabe geklappt hat, 1, ansonsten 0.
+
+BEMERKUNG:
+    Diese Funktion ist dann sinnvoll, wenn man den Spieler ein Objekt
+    weitergeben lassen und sich nicht selbst um die Fehlerbehandlung kuemmern
+    moechte - und da unzaehlige verschiedene Dinge schiefgehen koennen und
+    manche Objekte eigene Fehlermeldungen definieren, eigentlich immer.
+
+    Die Funktion prueft nicht, ob der Spieler/NPC der Objekt ueberhaupt hat,
+    das muss man ggf. selbst ermitteln.
+
+SIEHE AUCH:
+    move(L), P_GIVE_MSG, give_objects(L), give_notify(L),
+    P_NOINSERT_MSG, P_NOLEAVE_MSG, P_TOO_MANY_MSG,
+    P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_NODROP
+
+----------------------------------------------------------------------------
+Last modified: Thu Aug 28 22:21:19 2008 by Amynthor
diff --git a/doc/lfun/give_notify b/doc/lfun/give_notify
new file mode 100644
index 0000000..010d68e
--- /dev/null
+++ b/doc/lfun/give_notify
@@ -0,0 +1,59 @@
+give_notify()
+FUNKTION:
+     void give_notify(object obj);
+
+DEFINIERT IN:
+     /std/npc/put_and_get.c
+
+ARGUMENTE:
+     obj
+       an den NPC uebergebenes Objekt
+RUeCKGABEWERT:
+     keiner
+
+BESCHREIBUNG:
+     Diese Funktion wird automatisch immer dann aufgerufen, wenn ein
+     Lebewesen (welches kein Spielercharakter ist) ein Objekt uebergeben
+     bekommt. Dies muss jedoch ueber die Funktionalitaet von
+     put_and_get.c geschehen sein, innerhalb von move() wird die Funktion
+     nicht aufgerufen!
+
+BEISPIEL:
+     Oftmals will man in Quests erreichen, dass einem NPC ein bestimmtes
+     Item als Beweis der Erfuellung einer bestimmten Aufgabe ueberbracht
+     wird. Folgendermasse kann dies realisiert werden:
+     void create() {
+       ::create();
+       ...
+       SetProp(P_REJECT,({REJECT_GIVE,
+         Name(WER)+" sagt: Das brauche ich nicht!\n"}));
+       ...
+     }
+
+     void quest_ok(object obj) { ...
+       // Vernichtung des Questobjektes und Questtexte
+       // Questbelohnung und Questanerkennung
+     }
+
+     void give_notify(object obj) {
+       if(obj->id("\nquestitem")) // Questitem bekommen?
+         quest_ok(obj);
+       else
+         ::give_notify(obj);  // P_REJECT soll sonst greifen
+     }
+     Der Aufruf von ::give_notify() stellt sicher, dass ein Objekt
+     zurueckgegeben wird, sofern es nicht das gesuchte ist. Erreicht wird
+     dies ueber P_REJECT (siehe Bemerkungen).
+
+BEMERKUNGEN:
+     Speziell in NPCs ist diese Funktion normalerweise dafuer
+     verantwortlich, dass mittels der Property P_REJECT die Annahme von
+     Objekten verweigert werden kann. Ueberschreibt man sie, so sollte
+     man gegebenenfalls darauf achten, dass diese Standardfunktion
+     ebenfalls aufgerufen wird.
+
+SIEHE AUCH:
+     P_REJECT, show_notify(), 
+     /std/npc/put_and_get.c, /std/living/put_and_get.c
+
+22. Oktober 2013, Arathorn.
diff --git a/doc/lfun/give_obj b/doc/lfun/give_obj
new file mode 100644
index 0000000..59f8c99
--- /dev/null
+++ b/doc/lfun/give_obj
@@ -0,0 +1,27 @@
+give_obj()
+
+FUNKTION
+    int give_obj(object ob, object where)
+
+DEFINIERT IN:
+
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+
+    ob      Das Objekt, das abgegeben werden soll.
+    where   Das Lebewesen, dass das Objekt erhaelt.
+
+BESCHREIBUNG:
+
+    Das Lebewesen, in dem diese Funktion aufgerufen werden soll, gibt
+    den angegebenen Gegenstand (ob) an das angegebene Lebewesen (where).
+
+RUeCKGABEWERT:
+    1, wenn das Objekt uebergeben wurde oder die Uebergabe nicht moeglich war.
+    (in diesem Fall wird auch direkt eine Textausgabe ausgegeben)
+    0 sonst, in diesem Fall wird in notify_fail eine passende Ausgabe plaziert.
+
+SIEHE AUCH:
+
+    pick_obj(), drop_obj(), put_obj(), find_obs(), /std/living/put_and_get.c
diff --git a/doc/lfun/heal_self b/doc/lfun/heal_self
new file mode 100644
index 0000000..5f60547
--- /dev/null
+++ b/doc/lfun/heal_self
@@ -0,0 +1,49 @@
+heal_self()
+
+FUNKTION:
+    void heal_self(int points);
+
+ARGUMENTE:
+    points: Die dem Lebewesen zukommende Heilung.
+
+BESCHREIBUNG:
+    Dem Lebewesen werden points Lebens- und Konzentrationspunkte 
+    gutgeschrieben und auf die aktuellen addiert. Es werden aber nicht
+    die maximalen Werte ueberschritten.
+
+RUECKGABEWERT:
+    Keiner
+
+BEISPIELE:
+    
+    AddCmd("pflueck&beere","pfluecke_cmd","Was moechtest Du pfluecken?");
+
+    int pfluecke_cmd(string str){
+        write("Du pflueckst eine Beere, isst sie und fuehlst Dich gleich "
+             +"viel besser.\n");
+        this_player()->heal_self(30);
+        return 1;
+    }
+
+    Der Spieler bekommt hier pro Beere die er pflueckt und isst je 30 LP/KP
+    zu seinen momentanen.
+
+BEMERKUNGEN: 
+    heal_self wird gerne fuer Heilstellen in Gebieten genommen, in denen ein
+    Spieler diese Heilung auch wirklich braucht. Dennoch ist der Einsatz un-
+    bedingt mit der Heilungsbalance abzusprechen und darauf zu achten, dass
+    pro reset() nur eine bestimmte Anzahl an Heilungen ausgegeben werden.
+
+    Bei Heilstellen sollte eine evtl. Heilung des Spielers mit der eigens
+    dafuer eingerichteten Funktion check_and_update_timed_key realisiert
+    werden.
+
+SIEHE AUCH:
+    Verwandt:   restore_spell_points, restore_hit_points, buffer_hp
+		buffer_sp, check_and_update_timed_key
+    Gegenparts: do_damage, reduce_hit_points, reduce_spell_points
+    Props:      P_HP, P_SP
+    Konzept:    heilung
+
+----------------------------------------------------------------------------
+Last modified: 27.05.2007 by Ennox
diff --git a/doc/lfun/heart_beat b/doc/lfun/heart_beat
new file mode 100644
index 0000000..6a314bd
--- /dev/null
+++ b/doc/lfun/heart_beat
@@ -0,0 +1,42 @@
+heart_beat()
+
+FUNKTION:
+     protected void heart_beat();
+
+DEFINIERT IN:
+     /std/living/life.c
+     /std/living/combat.c
+     und anderen...
+     kann auch in beliebigen Objekten selbst definiert werden.
+
+BESCHREIBUNG:
+     Diese Funktion wird alle zwei Sekunden vom GameDriver aufgerufen. Sie
+     regelt in der MG-MudLib das Heilen von Spielern und Monstern, den
+     Ablauf von Kampfrunden, die Verdauung etc.
+
+     Da heart_beat() ziemlich viele Ressourcen des GameDrivers verbraet,
+     sollte man Objekte mit heart_beat() nur so selten wie moeglich
+     benutzen! Und selbst dann sollte der heart_beat() nicht die ganze Zeit
+     ueber laufen, sondern sich so bald wie moeglich abschalten.
+
+     Das Ein- und Ausschalten des heart_beat()s erfolgt mit
+     set_heart_beat().
+
+BEMERKUNGEN:
+     1. Teuer, teuer, teuer!
+     2. Soll euer Viech pro "echtem" Heartbeat mehrere Kampfrunden haben,
+        benutzt dafuer SA_SPEED und ruft auf gar keinen Fall mehrfach 
+        ::heart_beat() auf. Also _NICHT_
+        void heart_beat() {
+            ::heart_beat();
+            ::heart_beat(); }
+        sondern:
+        SetProp(P_SKILL_ATTRIBUTE_OFFSETS, ([SA_SPEED: 200]) );
+
+SIEHE AUCH:
+     Efuns:     set_heart_beat(), absolute_hb_count(), set_next_reset()
+     Fehler:    make_immortal(L)
+
+----------------------------------------------------------------------------
+22.3.2008, Zesstra
+
diff --git a/doc/lfun/id b/doc/lfun/id
new file mode 100644
index 0000000..7cf5aed
--- /dev/null
+++ b/doc/lfun/id
@@ -0,0 +1,76 @@
+id()
+
+FUNKTION:
+     varargs int id(string str, int lvl);
+
+DEFINIERT IN:
+     /std/thing/description.c
+     /std/player/base.c
+
+ARGUMENTE:
+     string str
+          String, auf den getestet werden soll.
+     int lvl
+          In /std/player/base.c benutzt. Wenn der Spieler unsichtbar ist
+          und lvl kleiner ist als sein Level, wird 0 zurueckgegeben.
+
+BESCHREIBUNG:
+     Es wird geprueft, ob sich das Objekt mit str ansprechen laesst. Dazu
+     wird str mit dem Inhalt der Property P_IDS verglichen. Falls
+     P_ADJECTIVES gesetzt ist, werden auch alle Adjektivkombinationen mit
+     den Bezeichnern geprueft.
+
+     Besondere Bedeutung hat diese Funktion bei Mengenobjekten: Anhand von
+     str wird vermerkt, welche Menge des Objektes angesprochen wird. Es
+     werden dabei mehrere Faelle unterschieden:
+     o str ist einer der mit AddId() angegebener Bezeichner. In diesem
+       Fall ist die angesprochene Menge die Gesamtmenge.
+     o str ist einer der mit AddSingularId() angegebenen Bezeichner. Die
+       angesprochene Menge ist in diesem Fall 1.
+     o str ist einer der mit AddPluralId() angegebenen Bezeichner. Die
+       angesprochene Menge ist in diesem Fall . die Gesamtmenge.
+     o Hat str die Form "<n> <id>", wobei <n>=1 und <id> eine SingularId
+       oder 1 < <n> <= der Gesamtmenge und <id> eine PluralId, so ist die
+       angesprochene Menge = <n>.
+     Wie gesagt, gilt dies einzig und allein bei Mengenobjekten!
+
+RUeCKGABEWERT:
+     1, wenn sich das Objekt von str angesprochen fuehlt, ansonsten 0.
+
+BEISPIELE:
+     Angenommen, ein Objekt habe folgende Bezeichner:
+
+     AddId( "murmel" );
+     AddAdjective( "runde" );
+
+     Dann liefern die angegebenen id()-Aufrufe folgende Ergebnisse:
+
+     id( "murmel" );         => 1
+     id( "runde murmel" );   => 1
+     id( "kleine murmel" );  => 0
+     id( "runder ball" );    => 0
+     id( "runde murmel 2" ); => 1, wenn dies die zweite Murmel in der
+                                   gleichen Umgebung ist, ansonsten 0
+
+     Bei einem Haufen von 100 Muenzen haette man zB.:
+
+     AddId( "geld" );
+     AddSingularId( "muenze" );
+     AddPluralId( "muenzen" );
+
+     Nach fuehlen sich nach den folgenden id()-Aufrufen folgende Anzahlen
+     angesprochen:
+
+     id( "geld" );       => 100 Muenzen
+     id( "muenze" );     => 1 Muenze
+     id( "muenzen" );    => 100 Muenzen
+     id( "1 muenze" );   => 1 Muenze
+     id( "42 muenzen" ); => 42 Muenzen
+
+     id() liefert in all diesen Faellen 1 zurueck.
+
+SIEHE AUCH:
+     AddId(), AddAdjective(), AddSingularId(), AddPluralId(), present(),
+     match_ids(), /std/thing/description.c, /std/unit.c
+
+6. Sep 2012 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/init b/doc/lfun/init
new file mode 100644
index 0000000..f9d0cad
--- /dev/null
+++ b/doc/lfun/init
@@ -0,0 +1,65 @@
+init()
+
+FUNKTION:
+	void init();
+
+DEFINIERT IN:
+	/std/room/description.c
+
+ARGUMENTE:
+	keine
+
+BESCHREIBUNG:
+	init() wird immer dann aufgerufen, wenn ein lebendes Objekt in die
+	Naehe anderer Objekte bewegt wird oder ein nicht lebendiges Objekt
+	in die Naehe von Lebewesen gelangt. init() wird dabei in allen
+	Objekten aufgerufen, bei denen es notwendig ist.
+
+	Der Hauptzweck dieser Funktion besteht darin, den Objekten
+	untereinander ihre jeweiligen Befehle zugaenglich zu machen.
+	Waehrend dies in anderen MudLibs durch eine Reihe von
+	add_action()-Aufrufen im Rumpf von init() geschah, geschieht dies in
+	der MG-MudLib bei Objekten, die /std/thing/commands.c erben
+	 (das sind zB. alle Standardobjekte) quasi automatisch
+	 (dort werden die Befehle dann per AddCmd() im create() angemeldet,
+	  man spart sich die Implementierung von init() und dem Mud somit
+	  Speicher). Der andere Weg ist aber natuerlich immer noch moeglich.
+
+RUeCKGABEWERT:
+	keiner
+
+BEMERKUNGEN:
+	Der Ablauf der init()-Kette ist wie folgt:
+	o Ist das Objekt X, welches ins Zielobjekt D bewegt wurde, ein
+	  Lebewesen, so wird in D init() aufgerufen, wobei this_player() auf
+	  X gesetzt ist.
+	o Dann wird fuer jedes Objekt C in D folgendes ausgefuehrt:
+	  + Ist C ein Lebewesen, dann wird init() in X aufgerufen, wobei
+	    this_player() auf C gesetzt ist.
+	  + Ist X ein Lebewesen, dann wird init() in C aufgerufen, wobei
+	  this_player() auf X gesetzt ist.
+	o Schliesslich wird in dem Fall, dass D lebendig ist, in X init()
+	  aufgerufen, wobei this_player() auf D gesetzt ist.
+
+BEISPIELE:
+	D sei ein Raum, in dem sich das Lebewesen L1 sowie die Gegenstaende
+	N1 und N2 befinden.
+	Betritt ein Spieler X diesen Raum, so werden folgende init()s
+	aufgerufen:
+
+	  D->init();  // this_player() == X
+	  X->init();  // this_player() == L1
+	  L1->init(); // this_player() == X
+	  N1->init(); // this_player() == X
+	  N2->init(); // this_player() == X
+
+	Gelangt dagegen ein nichtlebendiges Objekt nach D, so sieht das Ganze
+	wie folgt aus:
+
+	  X->init();    // this_player() == L1
+
+SIEHE AUCH:
+	exit(), AddCmd(), add_action(),
+  NotifyInsert()
+----------------------------------------------------------------------------
+Last modified: 04.08.2007, Zesstra
diff --git a/doc/lfun/insert_sensitive_inv b/doc/lfun/insert_sensitive_inv
new file mode 100644
index 0000000..5b54df4
--- /dev/null
+++ b/doc/lfun/insert_sensitive_inv
@@ -0,0 +1,21 @@
+insert_sensitive_inv
+FUNKTION:
+     void insert_sensitive_inv(object ob, string key,
+			       int threshold, mixed *opt)
+
+DEFINIERT IN:
+     /std/container/inventory.c
+
+BESCHREIBUNG:
+     Diese Funktion sucht, ob beim Hinzufuegen eines sensitiven Objekts
+     schon ein Objekt da ist, dass dieses ausloest.
+
+SIEHE AUCH:
+     P_SENSITIVE
+     InsertSensitiveObject, RemoveSensitiveObject
+     insert_sensitive_inv_trigger
+     P_SENSITIVE_ATTACK, P_SENSITIVE_INVENTORY,
+     P_SENSITIVE_INVENTORY_TRIGGER
+     CheckSensitiveAttack
+
+28.Jan.2001, Gloinson@MG
diff --git a/doc/lfun/insert_sensitive_inv_trigger b/doc/lfun/insert_sensitive_inv_trigger
new file mode 100644
index 0000000..766f0f5
--- /dev/null
+++ b/doc/lfun/insert_sensitive_inv_trigger
@@ -0,0 +1,21 @@
+insert_sensitive_inv_trigger
+FUNKTION:
+     void insert_sensitive_inv_trigger(object ob, string key,
+				       int threshold, mixed *opt)
+
+DEFINIERT IN:
+     /std/container/inventory.c
+
+BESCHREIBUNG:
+     Diese Funktion sucht, ob ein sensitives Objekt im Inventory ist,
+     das durch dieses (soeben eingefuegte) Objekt ausgeloest wird.
+
+SIEHE AUCH:
+     P_SENSITIVE
+     InsertSensitiveObject, RemoveSensitiveObject
+     insert_sensitive_inv
+     P_SENSITIVE_ATTACK, P_SENSITIVE_INVENTORY,
+     P_SENSITIVE_INVENTORY_TRIGGER
+     CheckSensitiveAttack
+
+28.Jan.2001, Gloinson@MG
diff --git a/doc/lfun/int_long b/doc/lfun/int_long
new file mode 100644
index 0000000..7513e87
--- /dev/null
+++ b/doc/lfun/int_long
@@ -0,0 +1,64 @@
+int_long()
+FUNKTION:
+     varargs string int_long(mixed viewer, mixed viewpoint, int flags)
+
+DEFINIERT IN:
+     /std/room/description.c
+
+ARGUMENTE:
+     mixed viewer	- der Betrachter des Raumes
+     mixed viewpoint	- 0/Objekt/Array der/die Ausgangspunkt(e) des
+			  Betrachtens (und damit nicht sichtbar!)
+     int flags		- Modifikatoren fuer die Anzeige
+			  (siehe "man make_invlist", wird mit 3 verUNDet!)
+
+BESCHREIBUNG:
+     Es wird die Beschreibung des Rauminneren erstellt. Dabei wird die
+     Langbeschreibung des Raumes, die enthaltenen Objekte (exklusive
+     aller viewpoints (normalerweise nur der Betrachter)) und Ausgaenge,
+     wenn vom Viewer eingeschaltet dargestellt.
+     Falls der Raum innerhalb eines anderen Raumes liegt und selbst
+     transparent ist, wie zusaetzlich die Kurzbeschreibung des Aussen-
+     raumes angezeigt.
+
+     Ist Viewer ein Magier mit eingeschaltetem Magiermodus, so wird der
+     Beschreibung der Dateiname des Raumes vorangestellt.
+
+RUeCKGABEWERT:
+     Die Langbeschreibung des Raumes von innen.
+
+BEMERKUNGEN:
+     Die Trennung von viewer und viewpoint hat durchaus ihren Sinn. So ist
+     es zum Beispiel moeglich, einen Raum "mit den Augen eines Anderen" zu
+     betrachten. Dabei saehe man sich selbst, wenn man im Raum waere.
+
+BEISPIELE:
+     // in diesem Raum sieht man keine Mitspieler im "schau" oder beim
+     // Betreten (vielleicht ist es zu neblig)
+     // dazu werden einfach alle Interactives zu den viewpoints addiert
+     string int_long(object viewer, mixed viewpoints, int flags) {
+      if(!pointerp(viewpoints)) viewpoints=({viewpoints});
+      return ::int_long(&viewer,
+			viewpoints+
+			filter(all_inventory(this_object()),
+				     #'interactive),
+			&flags);
+     }
+
+     string int_short(object viewer, mixed viewpoints) {
+      if(!pointerp(viewpoints)) viewpoints=({viewpoints});
+      return ::int_short(&viewer,
+			 viewpoints+
+			 filter(all_inventory(this_object()),
+				      #'interactive));
+     }
+
+SIEHE AUCH:
+     Aehnliches:	int_short()
+     Properties:	P_INT_LONG, P_SHORT
+			P_HIDE_EXITS, P_SHOW_EXITS
+			P_TRANSPARENT
+     Kommandokette:	make_invlist(), short()
+     Sonstiges:		P_REFERENCE_OBJECT, P_WANTS_TO_LEARN
+
+11. Mai 2004 Gloinson
diff --git a/doc/lfun/int_short b/doc/lfun/int_short
new file mode 100644
index 0000000..e4a8d3a
--- /dev/null
+++ b/doc/lfun/int_short
@@ -0,0 +1,58 @@
+int_short()
+FUNKTION:
+     string int_short(mixed viewer, mixed viewpoint);
+
+DEFINIERT IN:
+     /std/room/description.c
+
+ARGUMENTE:
+     mixed viewer	- der Betrachter des Raumes
+     mixed viewpoint	- 0/Objekt/Array der/die Ausgangspunkt(e) des
+			  Betrachtens (und damit nicht sichtbar!)
+
+BESCHREIBUNG:
+     Es wird eine kurze  Beschreibung des Rauminneren erstellt. Dabei wird
+     die Kurzbeschreibung des Raumes, die enthaltenen Objekte (exklusive
+     aller viewpoints (normalerweise nur der Betrachter)) und Ausgaenge,
+     wenn vom Viewer eingeschaltet dargestellt.
+
+     Ist Viewer ein Magier mit eingeschaltetem Magiermodus, so wird der
+     Beschreibung der Dateiname des Raumes vorangestellt.
+
+RUeCKGABEWERT:
+     Die Kurzbeschreibung des Raumes von innen.
+
+BEMERKUNGEN:
+     Die Trennung von viewer und viewpoint hat durchaus ihren Sinn. So ist
+     es zum Beispiel moeglich, einen Raum "mit den Augen eines Anderen" zu
+     betrachten. Dabei saehe man sich selbst, wenn man im Raum waere.
+
+BEISPIELE:
+     // in diesem Raum sieht man keine Mitspieler im "schau" oder beim
+     // Betreten (vielleicht ist es zu neblig)
+     // dazu werden einfach alle Interactives zu den viewpoints addiert
+     string int_long(object viewer, mixed viewpoints, int flags) {
+      if(!pointerp(viewpoints)) viewpoints=({viewpoints});
+      return ::int_long(&viewer,
+			viewpoints+
+			filter(all_inventory(this_object()),
+				     #'interactive),
+			&flags);
+     }
+
+     string int_short(object viewer, mixed viewpoints) {
+      if(!pointerp(viewpoints)) viewpoints=({viewpoints});
+      return ::int_short(&viewer,
+			 viewpoints+
+			 filter(all_inventory(this_object()),
+				      #'interactive));
+     }
+
+SIEHE AUCH:
+     Aehnliches:	int_long()
+     Properties:	P_INT_SHORT, P_SHORT
+			P_HIDE_EXITS, P_SHOW_EXITS
+     Kommandokette:	make_invlist(), short()
+     Sonstiges:		P_REFERENCE_OBJECT, P_WANTS_TO_LEARN
+
+11. Mai 2004 Gloinson
diff --git a/doc/lfun/is_class_member b/doc/lfun/is_class_member
new file mode 100644
index 0000000..7019447
--- /dev/null
+++ b/doc/lfun/is_class_member
@@ -0,0 +1,155 @@
+is_class_member()
+FUNKTION:
+     int is_class_member(string|string* class);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     string/string* class	- String oder Stringarray der Klasse(n)
+
+BESCHREIBUNG:
+     Es wird getestet, ob das Objekt in eine der in class angegebenen
+     Klassen faellt. In diesen Test werden die folgenden Eigenschaften des
+     Objektes einbezogen:
+
+       1. Die Rasse des Objektes (bei Lebewesen),
+       2. die IDs des Objektes und
+       3. die explizit angegebenen Klassen des Objektes.
+       4. einigen impliziten Klassen, die sich aus den Klassen in 3 ergeben.
+
+     Die moeglichen Klassen sind in /sys/class.h definiert. Momentan stehen
+     folgende Klassen zur Verfuegung:
+
+     CL_AMMUNITION
+          Das Objekt eignet sich als Munition.
+     CL_ANIMAL
+          Das Objekt ist ein Tier.
+     CL_ARACHNID
+          Das Objekt in ein Spinnenwesen.
+     CL_BIGBANG
+          Dieses Objekt kann mehreren Lebewesen auf einmal Schaden zufuegen.
+     CL_BIRD
+          Ein Vogel.
+     CL_CRAWLING
+          Dieses Wesen bewegt sich kriechend.
+     CL_CURSE
+          Das Objekt ist ein Fluch (zB. ein Sprachfluch).
+     CL_DEMON
+          Bei dem Objekt handelt es sich um einen Daemon.
+     CL_DISEASE
+          Eine Krankheit.
+     CL_DRAGON
+          Ein Drache.
+     CL_DWARF
+          Fuer unsere kleinen Gaeste...
+     CL_ELF
+          Elfen aller Art.
+     CL_ELEMENTAL
+          Ein Elementar irgendeiner Art. Material setzen waere angebracht.
+     CL_EXPLOSIVE
+          Bei dem Objekt handelt es sich um einen Sprengstoff.
+     CL_FELINE
+          Felinen und andere katzenartigen Lebewesen.
+     CL_FISH
+          Fische - keine Meeressaeuger!
+     CL_FLYING
+          Dieses Wesen bewegt sich fliegend.
+     CL_FROG
+          Froesche - auch gefroschte Spieler.
+     CL_GHOST
+          Geister und geisterhafte Wesen.
+     CL_GHOUL
+          Ein Ghoul. Er faellt automatisch in die Klasse CL_UNDEAD.
+     CL_GIANT
+          Ein riesiges Lebewesen.
+     CL_GNOME
+          Ein Gnom.
+     CL_GOBLIN
+          Ein Goblin.
+     CL_HOBBIT
+          Ein Hobbit.
+     CL_HOBGOBLIN
+          Ein Hobgoblin. Er faellt automatisch auch in die Klasse CL_GOBLIN.
+     CL_HUMAN
+          Ein Mensch.
+     CL_INORGANIC
+          Anorganische Lebewesen wie Metallmonster
+     CL_INSECT
+          Insekten (Nicht mit Spinnen verwechseln)
+     CL_LIVING
+          Lebewesen im allgemeinen.
+     CL_MAMMAL
+          Saeugetiere.
+     CL_MAMMAL_LAND
+          Landsaeugetiere
+     CL_MAMMAL_WATER
+          Meeressaeuger.
+     CL_ORC
+          Ein Ork.
+     CL_PLANT
+          Pflanzen und pflanzenartige Monster.
+     CL_POISON
+          Das Objekt ist selbst ein Gift
+     CL_POISONOUS
+          Das Objekt kann einen Spieler/NPC vergiften.
+     CL_REPTILE
+          Reptilien.
+     CL_SHADOW
+          Schattenwesen.
+     CL_SKELETON
+          Ein Skelett. Es faellt automatisch in die Klasse CL_UNDEAD.
+     CL_SLIME
+          Fuer Einzeller und aehnliches Schleimgetier
+     CL_SNAKE
+          Schlangen.
+     CL_SWIMMING
+          Dieses Wesen bewegt sich schwimmend.
+     CL_TROLL
+          Ein Troll.
+     CL_UNDEAD
+          Ein untotes Lebewesen.
+     CL_WALKING
+          Dieses Wesen bewegt sich gehend.
+     CL_VAMPIRE
+          Ein Vampir. Er faellt automatisch in die Klasse CL_UNDEAD.
+     CL_ZOMBIE
+          Ein Zombie. Er faellt automatisch in die Klasse CL_UNDEAD.
+
+     Implizite Klassen:
+     Bei einigen Klassen wird im AddClass() automatisch eine oder mehrere
+     weiterer Klassen hinzugefuegt und im RemoveClass() die entsprechenden
+     impliziten Klassen auch automatisch entfernt.
+     Wuenscht man diese impliziten Klassen nicht, muss man nach dem AddClass()
+     diese mittels eines entsprechenden RemoveClass() entfernen.
+     Die impliziten Klassen einer Klasse lassen sich mit Hilfe der Funktion
+     QueryImplicitClasses() in CLASSDB herausfinden:
+       CLASSDB->QueryImplicitClasses(...)
+     Momentan sind dies:
+     CL_ZOMBIE:       CL_UNDEAD
+     CL_SKELETON:     CL_UNDEAD
+     CL_GHOUL:        CL_UNDEAD
+     CL_VAMPIRE:      CL_UNDEAD
+     CL_HOBGOBLIN:    CL_GOBLIN
+     CL_MAMMAL_LAND:  CL_MAMMAL, CL_ANIMAL
+     CL_MAMMAL_WATER: CL_MAMMAL, CL_ANIMAL
+     CL_SNAKE:        CL_REPTILE
+     CL_ARACHNID:     CL_ANIMAL
+     CL_BIRD:         CL_ANIMAL
+     CL_FISH:         CL_ANIMAL
+     CL_FROG:         CL_ANIMAL
+     CL_INSECT:       CL_ANIMAL
+     CL_MAMMAL:       CL_ANIMAL
+     CL_REPTILE:      CL_ANIMAL
+     CL_SNAKE:        CL_ANIMAL
+
+RUeCKGABEWERT:
+     1, wenn das Objekt in eine der angegebenen Klassen faellt, ansonsten 0.
+
+SIEHE AUCH:
+     AddClass(), RemoveClass(), /std/thing/description.c
+     P_CLASS
+
+----------------------------------------------------------------------------
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/lfun b/doc/lfun/lfun
new file mode 100644
index 0000000..eadd45a
--- /dev/null
+++ b/doc/lfun/lfun
@@ -0,0 +1,12 @@
+NAME:
+	lfun()
+
+DESCRIPTION:
+	This directory contains descriptions for the lfuns used by
+	Amylaar's version of the LPC parser.
+
+	These are functions that are applied by the parser to the LPC
+	objects on various occasions.
+
+SEE ALSO:
+	efun(E), master(M), concepts(C), lpc(LPC), driver(D)
diff --git a/doc/lfun/locate_objects b/doc/lfun/locate_objects
new file mode 100644
index 0000000..1d56e9a
--- /dev/null
+++ b/doc/lfun/locate_objects
@@ -0,0 +1,54 @@
+locate_objects()
+
+FUNKTION:
+     object *locate_objects(string desc, int info);
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     desc
+          Die Umschreibung des gesuchten Objektes.
+
+     info
+          Ist ungleich 0, wenn diese Funktion von /std/living/put_and_get.c
+          aus aufgerufen wurde.
+
+BESCHREIBUNG:
+     Diese Funktion erweitert die Funktionalitaet von present_objects()
+     insofern, als dass es moeglich ist, auch noch Behaelter innerhalb des
+     Behaelters zu durchsuchen. Das genaue Verhalten haengt von desc ab:
+
+     Ist desc von der Form "<id>", so wird das Ergebnis von
+     present_objects(desc) zurueckgegeben.
+
+     Ist desc von der Form "<gesucht> in <id>", so wird in allen Objekten,
+     die von present_objects("<id>") erfasst wurden,
+     locate_objects("<desc>") aufgerufen. Zurueckgegeben werden alle auf
+     diese Weise gefundenen Objekte.
+
+RUeCKGABEWERT:
+     Array von Objekten, die auf die oben geschilderte Art und Weise
+     ermittelt wurden. Konnte kein Objekt ermittelt werden, wird ein leeres
+     Array zurueckgegeben.
+
+BEMERKUNGEN:
+     Theoretisch sollte es moeglich sein, ueber desc rekursiv mehrere
+     Behaelterebenen erfassen zu koennen (etwa mit "schwert in beutel in
+     beutel in wargon"). In der aktuellen Implementierung klappt das jedoch
+     nicht; nach dem ersten "in" ist Schluss!
+
+BEISPIELE:
+     Was steckt alles dem Beutel, den der Spieler bei sich traegt?
+
+     object *obs;
+     obs = this_player()->locate_objects("alles in beutel");
+
+     Traegt der Spieler keinen Beutel bei sich oder ist dieser leer, so wird
+     ein leeres Array zurueckgegeben.
+
+SIEHE AUCH:
+     present_objects(), /std/container/restrictions.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:20:36 1996 by Wargon
diff --git a/doc/lfun/logon b/doc/lfun/logon
new file mode 100644
index 0000000..700f1e0
--- /dev/null
+++ b/doc/lfun/logon
@@ -0,0 +1,15 @@
+logon()
+
+SYNOPSIS:
+	int logon(void)
+
+DESCRIPTION:
+	When the parser accepts a new connection, it first calls
+	connect() in the master object and then applies logon() to
+	the object that is returned by the master. That will usually be
+	a special login object, that is expected to clone and get going
+	a user shell or player object.
+	Should return 0 on failure, everything else means success.
+
+SEE ALSO:
+	connect(M)
diff --git a/doc/lfun/long b/doc/lfun/long
new file mode 100644
index 0000000..34ac4f9
--- /dev/null
+++ b/doc/lfun/long
@@ -0,0 +1,31 @@
+long()
+FUNKTION:
+     varargs string long(int mode);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     int mode		- Modifikatoren fuer die Anzeige, falls this_object()
+			  ein Container ist
+			  (siehe "man make_invlist")
+
+BESCHREIBUNG:
+     Der Inhalt der Property P_LONG wird ausgewertet und zurueckgegeben.
+     Falls das Objekt ein Container und transparent (offen) ist, wird
+     zudem make_invlist() auf den Inhalt zurueckgegeben.
+
+RUeCKGABEWERT:
+     Die Langbeschreibung des Objektes.
+
+BEMERKUNGEN:
+     Durch Ueberladen von long() lassen sich noch weitere Eigenschaften des
+     Objektes anzeigen. Behaelter koennen zum Beispiel noch ihren Inhalt
+     anzeigen, Lebewesen ihren Gesundheitszustand, o.ae.
+
+SIEHE AUCH:
+     Aehnliches:	short()
+     Properties:	P_LONG, P_INVIS, P_TRANSPARENT
+     Sonstiges:		make_invlist()
+
+11. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/make_immortal b/doc/lfun/make_immortal
new file mode 100644
index 0000000..3ff4900
--- /dev/null
+++ b/doc/lfun/make_immortal
@@ -0,0 +1,27 @@
+make_immortal()

+

+FUNKTION:

+     void make_immortal();

+

+DEFINIERT IN:

+     /std/npc/combat.c

+

+BESCHREIBUNG:

+     Macht den NPC für 5 Minuten unangreifbar und heilt ihn.

+

+     Wird bei Fehlern im Herzschlag des NPCs gerufen um Bugnutzung

+     zu unterbinden.

+

+     Ausschrift:

+     "... versteckt sich hinter einem Fehler im Raum-Zeit-Gefuege und

+      entgeht so voruebergehend allen Angriffen."

+

+BEMERKUNGEN:

+     Nicht missbrauchen.

+

+SIEHE AUCH:

+     Methoden:       heart_beat(), static _check_immortality()

+     Master:         heart_beat_error()

+     Properties:     "time_to_mortality"

+

+1.Juni 2007 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/make_invlist b/doc/lfun/make_invlist
new file mode 100644
index 0000000..effbcca
--- /dev/null
+++ b/doc/lfun/make_invlist
@@ -0,0 +1,38 @@
+make_invlist()
+FUNKTION:
+     varargs mixed make_invlist(object viewer, mixed inv, int flags)
+
+DEFINIERT IN:
+     /std/container/description.c
+
+ARGUMENTE:
+     object viewer	- das Objekt, welches sich den Inhalt ansieht (in
+			  der Regel this_player())
+     mixed inv		- ein Array von Objekten, die in die Liste
+			  aufgenommen werden sollen
+     int flags		- Folgende Werte koennen verODERt werden:
+			  1: das Inv nicht als String, sondern als ein
+			     Array zurueckgeben
+			  2: gleiche Objekte nicht zusammengefassen
+			  4: unterdrueckt die Ausgabe des Dateinamens hinter
+			     jedem trotz eingeschaltetem Magiermodus
+
+BESCHREIBUNG:
+     Die Kurzbeschreibungen der Objekte in inv werden zu einer Liste
+     zusammengefasst (eine Zeile pro Objekt). Unsichtbare Objekte tauchen in
+     dieser Liste nicht auf.
+
+     Ist viewer ein Magier mit eingeschaltetem Magiermodus, so wird hinter
+     die Kurzbeschreibungen noch der Dateiname des jeweiligen Objektes in
+     eckigen Klammern angegeben. Unsichtbare Objekte erscheinen in diesem
+     Fall als Filenamen.
+
+RUeCKGABEWERT:
+     Ein String oder ein Array, die das inv beschreiben.
+
+SIEHE AUCH:
+     Kommandokette:	short()
+     Properties:	P_SHORT, P_INVIS, P_WANTS_TO_LEARN
+     Sonstiges:		P_REFERENCE_OBJECT
+
+Last modified: Tue Oct 15 10:10:00 2002 by Rikus
diff --git a/doc/lfun/master/AddWizardForUID b/doc/lfun/master/AddWizardForUID
new file mode 100644
index 0000000..c58463b
--- /dev/null
+++ b/doc/lfun/master/AddWizardForUID
@@ -0,0 +1,47 @@
+AddWizardForUID()
+
+FUNKTION:
+    string* AddWizardForUID(string uid, string wizard);
+
+DEFINIERT IN:
+    /secure/master/userinfo.c
+
+ARGUMENTE:
+    uid
+      Die UID, fuer die man einen (weiteren) verantwortlichen Magier
+      explizit eintragen moechte.
+    wizard
+      Der Magier, den man eintragen moechte.
+
+BESCHREIBUNG:
+    Die Funktion traegt einen Magier 'wizard' explizit als verantwortlichen
+    Magier fuer die UID 'uid' ein. Hierbei kann 'uid' sogar der Name eines
+		anderen Magiers sein, dessen UIDs 'wizard' sozusagen "adoptiert".
+
+		Berechtigt zum Eintragen von Magiern fuer bestimmte UIDs sind alle Magier,
+    die (implizit oder explizit) verantwortlich fuer die jeweilige UID sind.
+    Z.B. kann Zesstra ohne weiteres jemand weiteren als verantwortlich fuer
+    d.inseln.zesstra eintragen.
+
+RUeCKGABEWERT:
+    Zurueckgeliefert wird ein Array von Strings, jedes Element ist eine UID,
+    fuer die dier Magier jetzt explizit eingetragen ist.
+
+BEMERKUNGEN:
+    Es ist nicht noetig, z.B. Zesstra als verantwortlich fuer d.inseln.zesstra
+    einzutragen, da sie ohnehin schon implizit dafuer zustaendig ist. Auch
+    fuer RMs bzw. GMs muss ihre Region bzw. Gilde nicht explizit eingetragen 
+    werden.
+
+BEISPIELE:
+    master()->AddWizardForUID("p.waterluh","zook");
+		
+		string *uids = master()->AddWizardForUID("jof","zook");
+    printf("Zook ist nun explizit zustaendig fuer: %s\n",CountUp(uids));
+
+SIEHE AUCH:
+    QueryWizardsForUID(), QueryUIDsForWizard,
+		RemoveWizardFromUID()
+
+20.02.2007, Zesstra
+
diff --git a/doc/lfun/master/QueryUIDAlias b/doc/lfun/master/QueryUIDAlias
new file mode 100644
index 0000000..0ea844c
--- /dev/null
+++ b/doc/lfun/master/QueryUIDAlias
@@ -0,0 +1,43 @@
+QueryUIDAlias()
+
+FUNKTION:
+    varargs string* QueryUIDsForWizard(string uidalias, int recursive);
+
+DEFINIERT IN:
+    /secure/master/userinfo.c
+
+ARGUMENTE:
+    uidalias
+      UID, die expandiert werden soll.
+    recursive (optional)
+      Gibt an, ob QueryUIDAlias() (indirekt) rekursiv aufgerufen wurde.
+      Sollte normalerweise nicht per Hand gesetzt werden.
+
+BESCHREIBUNG:
+    Die Funktion ermittelt aus einer "Alias-UID" die UID, fuer die sie steht.
+    Hierbei werden folgende UID-Aliase beruecksichtigt:
+    "region":    d.region.* + region + d.region
+    "gilde":     GUILD.gilde, GUILD.gildenspellbook, p.gilde
+    "p":         p.* (ohne p.service)
+    "p.service": p.service.*
+    "magierid":  QueryUIDsForWizard()
+
+    Das Ergebnis dieser Funktion wird laengere Zeit gecachet (bis zu 24h).
+
+RUeCKGABEWERT:
+    Zurueckgeliefert wird ein Array von Strings, jedes Element ist eine UID.
+    Sollte uidaliase keines der o.g. sein, wird ein ({uidalias}) geliefert.
+
+BEISPIELE:
+    string *uids = master()->QueryUIDAlias("schattenwelt");
+    // uids enthaelt nun:
+    // ({"d.anfaenger","anfaenger","d.anfaenger.ark","d.anfaenger.ennox",
+    //   "d.anfaenger.humni","d.anfaenger.kiria","d.anfaenger.konzepte",
+    //   "d.anfaenger.miril"})
+
+SIEHE AUCH:
+    QueryWizardsForUID(), 
+		AddWizardForUID(), RemoveWizardFromUID()
+
+16.12.2007, Zesstra
+
diff --git a/doc/lfun/master/QueryUIDsForWizard b/doc/lfun/master/QueryUIDsForWizard
new file mode 100644
index 0000000..a4028c1
--- /dev/null
+++ b/doc/lfun/master/QueryUIDsForWizard
@@ -0,0 +1,42 @@
+QueryUIDsForWizard()
+
+FUNKTION:
+    varargs string* QueryUIDsForWizard(string wizname, int recursive);
+
+DEFINIERT IN:
+    /secure/master/userinfo.c
+
+ARGUMENTE:
+    wizname
+      Der Magier, fuer den man die UIDs ermitteln will, fuer die er
+      zustaendig ist.
+    recursive (optional)
+      Gibt an, ob QueryUIDsForWizard() (indirekt) rekursiv aufgerufen wurde.
+      Sollte normalerweise nicht per Hand gesetzt werden.
+
+BESCHREIBUNG:
+    Die Funktion ermittelt die UIDs, fuer die dieser Magier zustaendig ist.
+    Dabei wird impliziert beruecksichtigt, wenn der Magier RM einer Region
+    oder Gildenmagier einer Gilde ist, ebenso wie Verzeichnisse in den
+    Regionen oder in /p/service.
+    Ausserdem wird nachgeschaut, fuer welche UIDs dieser Magier explizit
+    eingetragen worden ist.
+    Wenn z.B. Magier A auch fuer alle UIDs von Magier B zustaendig sein
+    sollte, liefert die Funktion auch die UIDs von B zurueck.
+
+RUeCKGABEWERT:
+    Zurueckgeliefert wird ein Array von Strings, jedes Element ist eine UID.
+    Sollte fuer einen Namen keine UID ermittelbar sein, ist das Arrays leer.
+
+BEISPIELE:
+    string *uids = master()->QueryUIDsForWizard("ennox");
+    // uids enthaelt nun:
+    // ({"ennox","d.anfaenger.ennox","d.schattenwelt.ennox",
+    //   "p.service.ennox","GUILD.chaos","p.chaos"})
+
+SIEHE AUCH:
+    QueryWizardsForUID(), 
+		AddWizardForUID(), RemoveWizardFromUID()
+
+16.12.2007, Zesstra
+
diff --git a/doc/lfun/master/QueryWizardsForUID b/doc/lfun/master/QueryWizardsForUID
new file mode 100644
index 0000000..93095b6
--- /dev/null
+++ b/doc/lfun/master/QueryWizardsForUID
@@ -0,0 +1,46 @@
+QueryWizardsForUID()
+
+FUNKTION:
+    varargs string* QueryWizardsForUID(string uid, int recursive);
+
+DEFINIERT IN:
+    /secure/master/userinfo.c
+
+ARGUMENTE:
+    uid
+      Die UID, fuer die man die Magier ermitteln will, die fuer sie
+      zustaendig sind.
+    recursive (optional)
+      gibt an, ob das QueryWizardsForUID() (indirekt) aus einem 
+      QueryWizardsForUID() heraus gerufen wurde. Sollte nicht manuell gesetzt
+      werden.
+
+BESCHREIBUNG:
+    Die Funktion ermittelt die Magier, die fuer diese UID zustaendig sind.
+
+RUeCKGABEWERT:
+    Zurueckgeliefert wird ein Array von Strings, jedes Element ist ein Magier.
+    Sollte fuer eine UID kein Magier ermittelbar sein, ist das Array leer.
+    Wenn z.B. fuer die UID der Magier "Atamur" gefunden wird, aber fuer alle 
+    UIDs von "Atamur" auch der Magier "Rumata" zustaendig sein sollte, wird 
+    "Rumata" ueber eine rekursive Suche gefunden.
+
+BEMERKUNGEN:
+    Wenn die UID den Magier nicht implizit enthaelt (z.B. GUILD.gilde, im 
+    Gegensatz zu d.region.magier), findet diese Funktion nur Magier, fuer die 
+    seit Laden des Master bereits einmal get_userinfo() oder 
+    QueryUIDsForWizard() im Master gerufen wurde, was z.B. Einloggen passiert.
+    Magier, die lang nicht einloggten, werden also manchmal nicht gefunden,
+    was in der Regel nicht schlimm sein sollte, da sie ja ohnehin den
+    entsprechenden Code gerade nicht warten...
+
+BEISPIELE:
+    string *wiz = master()->QueryWizards("GUILD.klerus");
+    // wiz enthaelt nun: ({"morgoth","magdalena"})
+
+SIEHE AUCH:
+    QueryUIDsForWizard(), 
+		AddWizardForUID(), RemoveWizardFromUID()
+
+16.12.2007, Zesstra
+
diff --git a/doc/lfun/master/RemoveWizardFromUID b/doc/lfun/master/RemoveWizardFromUID
new file mode 100644
index 0000000..da97132
--- /dev/null
+++ b/doc/lfun/master/RemoveWizardFromUID
@@ -0,0 +1,38 @@
+RemoveWizardFromUID()
+
+FUNKTION:
+    string* RemoveWizardFromUID(string uid, string wizard);
+
+DEFINIERT IN:
+    /secure/master/userinfo.c
+
+ARGUMENTE:
+    uid
+      Die UID, fuer die man einen zustaendigen Magier austragen will.
+    wizard
+      Der Magier, den man austragen moechte.
+
+BESCHREIBUNG:
+    Die Funktion loescht die UID 'uid' aus der Liste der UIDs, fuer die
+    'wizard' explizit zustaendig ist.
+
+    Berechtigt zum Austragen von Magiern fuer bestimmte UIDs sind alle Magier,
+    die (implizit oder explizit) verantwortlich fuer die jeweilige UID sind.
+    Man kann sich auch selber austragen. ;-)
+
+RUeCKGABEWERT:
+    Zurueckgeliefert wird ein Array von Strings, jedes Element ist eine UID,
+    fuer die dier Magier jetzt explizit eingetragen ist.
+
+BEISPIELE:
+    master()->RemoveWizardFromUID("p.waterluh","zook");
+		
+    string *uids = master()->RemoveWizardFromUID("jof","zook");
+    printf("Zook ist nun explizit zustaendig fuer: %s\n",CountUp(uids));
+
+SIEHE AUCH:
+    QueryWizardsForUID(), QueryUIDsForWizard()
+		AddWizardForUID()
+
+20.02.2007, Zesstra
+
diff --git a/doc/lfun/match_ids b/doc/lfun/match_ids
new file mode 100644
index 0000000..d2c985b
--- /dev/null
+++ b/doc/lfun/match_ids
@@ -0,0 +1,47 @@
+match_ids()
+
+FUNKTION:
+     int match_ids(string *list);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     *list	String-Array mit zu testenden IDs
+
+BESCHREIBUNG:
+     Die Liste der uebergebenen IDs wird mit den IDs des Objektes
+     UND-Verknuepft. Die Groesse des resultierenden Arrays wird
+     zurueckgegeben.
+     Diese Funktion erlaubt also das gleichzeitige Pruefen auf
+     mehrere IDs. Allerdings werden - im Gegensatz zu id() -
+     Adjektive und Ausdruecke der Art "<ID> <nummer>" nicht
+     beruecksichtigt.
+     Ebenso werden Spezialitaeten wie Unitobjekte und Objekte mit
+     ueberschriebenem id() nicht beruecksichtigt! Im Zweifelsfall ist daher
+     doch die Nutzung von id() zu empfehlen.
+
+RUeCKGABEWERT:
+     Anzahl der zutreffenden IDs.
+
+BEISPIELE:
+     Angenommen, ein Objekt habe folgende Bezeichner:
+
+     AddId( ({"murmel","kugel","glasmurmel","glaskugel"}) );
+     AddAdjective( "rund" );
+
+     Dann liefern die angegebenen match_ids()-Aufrufe folgende Ergebnisse:
+
+     match_ids( ({"murmel","stein"}) );         => 1
+     match_ids( ({"murmel","kugel"}) );         => 2
+     match_ids( ({"runde murmel"}) );           => 0
+     match_ids( ({"murmel 2"}) );               => 0, auch wenn dies die 
+                                               zweite Murmel in der
+                                               gleichen Umgebung ist
+
+SIEHE AUCH:
+     AddId(), AddAdjective(), AddSingularId(), AddPluralId(), present(),
+     id(), /std/thing/description.c, /std/unit.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Mar 15 21:40:00 2000 by Paracelsus
diff --git a/doc/lfun/move b/doc/lfun/move
new file mode 100644
index 0000000..b323c34
--- /dev/null
+++ b/doc/lfun/move
@@ -0,0 +1,212 @@
+move()
+
+FUNKTION: 
+     Fuer unbelebte Gegenstaende (/std/thing):
+       varargs int move(object|string dest, int method);
+
+     Fuer Lebewesen (/std/living, /std/npc, usw.):
+       varargs int move(object|string dest, int method, string dir, 
+                        string textout, string textin);
+
+DEFINIERT IN:
+     /std/thing/moving.c
+     /std/living/moving.c
+
+ARGUMENTE:
+     dest
+          Das Zielobjekt (entweder der Dateiname oder das Objekt selbst).
+
+     method
+          Die Art der Bewegung (eine der unten aufgefuehrten Arten; es
+          koennen auch mehrere zusammenge-ODER-t werden).
+
+     dir
+          Die Richtung, in die ein Lebewesen geht. Normalerweise ist das die
+          eingeschlagene Laufrichtung (zB. "nach Norden").
+
+     textout
+          Verlaesst ein Lebewesen einen Raum, so wird diese Meldung in den
+          Raum geschickt. Ist bei dir ein String angegeben, so wird dieser
+          noch an textout angehaengt. Der Name des Lebewesens wird der
+          Meldung in jedem Fall vorangestellt.
+
+     textin
+          Dieser Text wird im Zielraum ausgegeben, wenn ein Lebewesen ihn
+          betritt. Bei normaler Fortbewegung ist das "kommt an". Dem Text
+          wird noch der Name des Spielers vorangestellt.
+
+BESCHREIBUNG:
+     Es wird versucht, das Objekt in das Zielobjekt dest zu bewegen.
+     Abhaengig vom momentanen Aufenthaltsort und dem Zielobjekt ist die
+     Bewegungsmethode method zu waehlen.
+
+     In <moving.h> sind folgende Konstanten fuer die Art der Bewegung
+     definiert:
+     M_NOCHECK
+          Es werden keine Abfragen durchgefuehrt, ob das Objekt ueberhaupt
+          in das Zielobjekt hineinpasst (was zB. aus Gewichtsgruenden der
+          Fall sein koennte).
+
+     M_GO
+          Ein Lebewesen bewegt sich gehend von einem Raum in den naechsten.
+          Bei normalem Gehen wird diese Methode benutzt; man sollte sie auch
+          benutzen, wenn man Spieler ueber einen SpecialExit in einen
+          benachbarten Raum bewegt.
+
+     M_TPORT
+          Ein Lebewesen wird von einem Raum in einen anderen teleportiert.
+          Im Gegensatz zu M_GO kann ein Raum verhindern, dass man ihn
+          mittels M_TPORT verlaesst oder betritt.
+
+     M_NO_SHOW
+          Beim Bewegen von Lebewesen bekommen diese die Beschreibung des
+          Zielraumes nicht ausgegeben.
+
+     M_NO_ATTACK
+          Beim Bewegen von Lebewesen bekommen diese keinen
+          Begruessungsschlag, wenn ein Feind im Zielraum steht.
+
+     M_SILENT
+          Es werden beim Bewegen keine Meldungen ausgegeben. Dieser
+          Parameter wirkt sich nur auf das Bewegen von Lebenwesen aus.
+
+     M_GET
+          Das Objekt wird von einem unbelebten Objekt (zB. einem Raum, einer
+          Leiche, einem Beutel) in ein lebendes Objekt (Spieler oder NPC)
+          bewegt.
+
+     M_PUT
+          Das Objekt wird von einem lebenden Objekt in ein unbelebtes Objekt
+          bewegt.
+
+     M_GIVE
+          Das Objekt wird von einem Lebewesen an ein anderes Lebewesen
+          weitergereicht.
+
+     M_MOVE_ALL (Nur fuer Objekte, die /std/unit.c erben)
+          Es wird die gesamte Menge bewegt, nicht nur ein Teil.
+
+     Soll das Objekt auf jeden Fall und ohne jede Abfrage bewegt werden, so
+     reicht es, als method M_NOCHECK zu uebergeben.
+
+     Waffen und Ruestungen werden, soweit sie gezueckt bzw. angezogen sind,
+     beim Bewegen auf jeden Fall weggesteckt bzw. ausgezogen. Ist in method
+     M_SILENT enthalten, so geschieht dies ohne Meldungen.
+
+     Die erste Art des Funktionsaufrufs ist sowohl beim Bewegen von
+     Lebewesen als auch von unbelebten Objekten moeglich. Die zweite Art
+     laesst sich nur bei Lebewesen anwenden.
+
+ANMERKUNG:
+     Diese Funktion sollte nicht (mehr) ueberschrieben werden. Stattdessen
+     greift bitte auf PreventMove() und NotifyMove() zurueck. RMs sind
+     aufgerufen, Objekt mit ueberschriebenen move() nur noch dann
+     anzuschliessen, wenn der Zweck sonst nicht erreicht werden kann. Solltet
+     ihr move() ueberschreiben: Seid euch sehr genau im klaren, was move()
+     genau macht. ;-)
+     
+     Wenn Livings bewegt werden, sorgt move() automatisch in Abhaengigkeit
+     von P_PARA dafuer, dass das Lebewesen in der korrekten (Parallel-)Welt
+     landet.
+
+     Bei Gegenstaenden wird ebenfalls versucht, die richtige Zielwelt
+     auszuwaehlen (damit z.B. in der Parallelwelt geworfene Bumerangs auch nur
+     innerhalb der Parallelwelt fliegen). Um Rechenzeit zu sparen, wird das
+     allerdings nur versucht, wenn 'dest' ein Filename ist und kein Objekt.
+
+     Grund: bei Zielobjekten handelt es sich meist um Bewegungen in das Inv
+     oder Env eines Spielers - und die sind uninteressant. Raumwechsel dagegen
+     erfolgen fast immer unter Angabe eines Filenamens anstatt eines Objektes.
+
+RUeCKGABEWERT:
+     Alle Rueckgabewerte sind als symbolische Konstanten in <moving.h>
+     definiert. (MOVE_OK ist 1, alle anderen sind <0 und symbolisieren Fehler.
+     Traditionell erfolgt die Pruefung auf erfolgreiches Move mit == 1, in
+     Zukunft wird == MOVE_OK empfohlen.)
+     
+     MOVE_OK
+          Die Bewegung wurde erfolgreich abgeschlossen.
+
+     ME_PLAYER
+          Lebewesen lassen sich nicht ohne weiteres bewegen. Es muss
+          mindestens eine der Methoden M_NOCHECK, M_GO oder M_TPORT
+          angegeben werden.
+
+     ME_TOO_HEAVY
+          Das Zielobjekt kann dieses Objekt aus Gewichtsgruenden nicht mehr
+          aufnehmen.
+
+     ME_CANT_TPORT_IN
+          Das Zielobjekt verbietet das Teleportieren in sich hinein (nur bei
+          M_TPORT ohne M_NOCHECK).
+
+     ME_CANT_TPORT_OUT
+          Der Raum, in dem sich das Lebewesen befindet, verbietet das
+          Teleportieren aus sich hinaus (nur bei M_TPORT ohne M_NOCHECK).
+
+     ME_CANT_BE_DROPPED
+          Das Objekt kann nicht fallen gelassen werden (zB. weil P_NODROP
+          gesetzt ist).
+
+     ME_CANT_BE_TAKEN
+          Das Objekt kann nicht genommen werden (zB. weil P_NOGET gesetzt
+          ist).
+
+     ME_CANT_BE_INSERTED
+          Das Zielobjekt verhindert das Einfuegen aus bestimmten Gruenden.
+
+     ME_CANT_LEAVE_ENV
+          Der Container verhindert ein verlassen des Objektes
+
+     ME_TOO_HEAVY_FOR_ENV
+          Ein Objekt kann einen Behaelter nicht verlassen, da es dem 
+          Lebewesen sonst zu schwer wuerde.
+
+     TOO_MANY_OBJECTS
+          Das Zielobjekt kann soviele Objekte nicht mehr aufnehmen.
+
+     ME_NOT_ALLOWED
+          Raeume mit gesetzter Property P_NO_PLAYERS koennen nur von
+          Testspielern und Magiern betreten werden. Bei Spielern oder
+          Gildentesties gibt es diese Fehlermeldung.
+     ME_WAS_DESTRUCTED
+          Das Objekt hat sich entweder im Verlaufe der Bewegung selbst
+          zerstoert oder wurde zerstoert, sodass move() nicht erfolgreich
+          beendet werden konnte. (Bsp: sensitive Objekte)
+
+     ME_DONT_WANT_TO_BE_MOVED
+          Das Objekt moechte nicht bewegt werden.
+
+BEISPIELE:
+        o Ein Objekt "gibt sich" dem Spieler:
+
+          move(this_player(), M_GET);
+
+        o Ein Lebewesen wird in die Abenteurergilde teleportiert:
+
+          lv->move("/gilden/abenteurer", M_TPORT);
+
+        o Ein Spieler "wird in die Gilde gegangen":
+
+          this_player()->move("/gilden/abenteurer", M_GO, "in die Gilde");
+
+          Spieler, die mit ihm im gleichen Raum stehen, sehen folgende
+          Meldung:
+          "<name> geht in die Gilde."
+
+        o Ein Spieler schwimmt durchs Meer:
+
+          this_player()->move("meer_xy", M_GO, "nach Norden", "schwimmt",
+                              "schwimmt herein");
+
+          Spieler in seinem Startraum sehen "<name> schwimmt nach Norden.",
+          Spieler in seinem Zielraum sehen "<name> schwimmt herein."
+
+SIEHE AUCH:
+     move_object(), remove(), setmin, setmmin, setmout, setmmout, review,
+     PreventInsert(), PreventLeave(), PreventInsertLiving(),
+     PreventLeaveLiving(), PreventMove(), NotifyInsert(), NotifyLeave(),
+     NotifyMove(), NotifyRemove(), init(), exit(),
+     P_NO_PLAYERS, P_PARA, /std/thing/moving.c, /std/living/moving.c
+     -----------------------------------------------------------------------
+2015-Jan-19, Arathorn
diff --git a/doc/lfun/moved_objects b/doc/lfun/moved_objects
new file mode 100644
index 0000000..edcbd6e
--- /dev/null
+++ b/doc/lfun/moved_objects
@@ -0,0 +1,30 @@
+moved_objects()
+
+FUNKTION:
+    public object *moved_objects(void);
+
+DEFINIERT IN:
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+    keine
+
+BESCHREIBUNG:
+    Mit dieser Funktion lassen sich die Objekte ermitteln, die das Lebewesen
+    beim letzten Aufruf von drop_objects(L) oder einer aehnlichen Funktion
+    bewegt hat.
+
+RUECKGABEWERT:
+    Array mit den zuletzt bewegten Objekten, oder ein leeres Array, falls
+    keine Objekte auf die Beschreibung des letzten drop_objects() / 
+    pick_objects() / put_objects() / give_objects() passten.
+
+BEISPIELE:
+    siehe drop_objects() und give_objects()
+
+SIEHE AUCH:
+    drop_objects(L), give_objects(L), pick_objects(L), put_objects(L),
+    show_objects(L), NotifyMove(L)
+
+----------------------------------------------------------------------------
+Last modified: Thu Aug 28 22:19:26 2008 by Amynthor
diff --git a/doc/lfun/moved_where b/doc/lfun/moved_where
new file mode 100644
index 0000000..8bb7e9c
--- /dev/null
+++ b/doc/lfun/moved_where
@@ -0,0 +1,28 @@
+moved_where()
+
+FUNKTION:
+    public object moved_where(void);
+
+DEFINIERT IN:
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+    keine
+
+BESCHREIBUNG:
+    Mit dieser Funktion laesst sich ermitteln, wohin das Lebewesen zuletzt
+    mittels put_objects(L) oder give_objects(L) etwas bewegt oder wem es mit
+    show_objects(L) etwas gezeigt hat.
+
+RUECKGABEWERT:
+    Der Container oder das Lebewesen, wohin die Gegenstaende bewegt wurden.
+
+BEISPIEL:
+    siehe give_objects()
+
+SIEHE AUCH:
+    put_objects(L), give_objects(L), show_objects(L), NotifyInsert(L),
+    P_LAST_CONTENT_CHANGE
+
+----------------------------------------------------------------------------
+Last modified: Thu Aug 28 22:16:15 2008 by Amynthor
diff --git a/doc/lfun/muster b/doc/lfun/muster
new file mode 100644
index 0000000..d519f69
--- /dev/null
+++ b/doc/lfun/muster
@@ -0,0 +1,16 @@
+muster()
+
+FUNKTION:
+	type muster(...)
+	
+ARGUMENTE:
+	
+BESCHREIBUNG:
+
+RUECKGABEWERT:
+	
+BEMERKUNG:
+	
+BEISPIEL:
+
+SIEHE AUCH:
diff --git a/doc/lfun/name b/doc/lfun/name
new file mode 100644
index 0000000..26e50fa
--- /dev/null
+++ b/doc/lfun/name
@@ -0,0 +1,50 @@
+name()
+
+FUNKTION:
+     varargs string name(int casus, int demon);
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     casus
+          Der Fall, in dem der Name dekliniert werden soll.
+     demon
+          Gibt an, ob der Name mit bestimmtem oder unbestimmtem Artikel
+          versehen werden soll:
+             + demon = 0: Unbestimmter Artikel.
+             + demon = 1: Bestimmter Artikel.
+             + demon = 2: Finde selbst heraus, ob ein bestimmter oder ein
+               unbestimmter Artikel verwendet werden soll.
+
+BESCHREIBUNG:
+     Diese Funktion ermittelt den Namen des Objektes im gewuenschten Fall
+     und mit dem angegebenen Artikel. Moegliche Werte fuer casus sind in
+     <thing/language.h> definiert. Weiterhin werden auch (falls angegeben)
+     die Namensadjektive dekliniert und in den Namen eingebaut.
+
+RUeCKGABEWERT:
+     String mit dem Namen des Objektes.
+
+BEMERKUNGEN:
+     Falls P_ARTICLE gesetzt ist, werden weder Artikel noch Namensadjektive
+     in den Namen eingebaut.
+
+     Wenn man als casus RAW angibt, wird der Name im Nominativ ohne Artikel
+     und Namensadjektive zurueckgegeben.
+
+BEISPIELE:
+     Wenn das Objekt ein Ball mit P_NAME="Ball" und P_NAME_ADJ="klein" ist,
+     so liefern die folgenden Aufrufe die angegebenen Ergebnisse:
+
+     name(WER,0);    => "ein kleiner Ball"
+     name(WESSEN,1); => "des kleinen Balls"
+     name(RAW);      => "Ball"
+     name(WEM,2);    => "einem kleinen Ball" oder "dem kleinen Ball",
+                        abhaengig davon, wieviele Baelle gerade da sind.
+
+SIEHE AUCH:
+     /std/thing/description.c, Name()
+
+----------------------------------------------------------------------------
+Last modified: Sat Aug  3 11:28:55 2002 by Vanion
diff --git a/doc/lfun/notify_player_change b/doc/lfun/notify_player_change
new file mode 100644
index 0000000..1765af6
--- /dev/null
+++ b/doc/lfun/notify_player_change
@@ -0,0 +1,56 @@
+void notify_player_change(string/object who, int rein [, int invis])
+
+FUNKTION:
+    void /notify_player_change(object who, int rein)
+    void /std/player/base::notify_player_change(string who, int rein,
+                                                int invis)
+  
+GERUFEN VON:
+    /std/player/base.c (d.h. alle Spielershells/-Objekte)
+
+ARGUMENTE:
+    string who
+      getuid() eines Spielers
+    object who
+      Spieler-Objekt
+    int rein
+      0 fuer das MUD verlassende, 1 fuer hereinkommende Spieler
+    int invis
+      1 fuer unsichtbare Spieler (Magier)
+
+BESCHREIBUNG:
+    Diese Funktion wird von Lebewesen fuer hereinkommende und das Spiel
+    verlassende Spieler an verschiedenen Stellen aufgerufen:
+    
+    * in anderen Spielern mit notify_player_change() mit drei Parametern
+      - dies dient fuer die "erwarte"-Funktionalitaet
+    * in der Gilde des Spielern mit zwei Parameter
+      - damit koennen Gilden notwendige Anpassungen vornehmen
+
+    Diese Funktionen werden auch gerufen, wenn Magier "invis -e" bzw.
+    "vis e" benutzen.
+
+BEISPIELE:
+    // in einer Gilde:
+    void notify_player_change(object pl, int rein) {
+      if (rein && objectp(pl)) {
+        // Checks, ob Spielerskills in Ordnung sind
+        mapping bete = pl->QuerySkill("bete");
+        
+        if (!mappingp(bete)) {
+          if (IS_LEARNER(pl) || pl->QueryProp(P_TESTPLAYER)) {
+            tell_object(pl, break_string(
+              "Du bist ein kaputter Test-Kleriker ...", 78,
+              "Arkshat teilt dir mit: "));
+            // notduerftige Reparaturen
+          } else
+            raise_error("Klerus: Kaputter oder gesetzer Kleriker!\n");
+        }
+      }
+    }
+
+SIEHE AUCH:
+    RegisterEvent mit (EVT_LIB_LOGIN, EVT_LIB_LOGOUT)
+    erwarte
+
+1. Sep 2011 Gloinson
diff --git a/doc/lfun/obsolete/AddHpHook b/doc/lfun/obsolete/AddHpHook
new file mode 100644
index 0000000..e227951
--- /dev/null
+++ b/doc/lfun/obsolete/AddHpHook
@@ -0,0 +1,29 @@
+********************* OBSOLETE LFUN ***********************************
+* Diese Efun bitte nicht mehr benutzen, sondern stattdessen die       *
+* Hooks (s. /doc/std/hooks).                                          *
+***********************************************************************
+AddHpHook()
+FUNKTION:
+     int AddHpHook(object ob)
+
+DEFINIERT IN:
+     /std/player/life.c
+
+ARGUMENTE:
+     ob - das Objekt, das sich eintragen moechte.
+
+BESCHREIBUNG:
+     Traegt ein Objekt in P_HP_HOOKS ein, wenn es nicht schon darin steht.
+
+     Aendern sich beim Spieler dann HP oder KP (nicht durch Set()), wird
+     an allen eingetragenen Objekten NotifyHpChange() gerufen.
+
+RUECKGABEWERT:
+     1, wenn Erfolg, 0 sonst
+
+SIEHE AUCH:
+     Gegenpart:	RemoveHpHook()
+     Props:	P_HP_HOOKS, P_HP
+     Verwandt:	reduce_hit_points(), do_damage(), buffer_hp()
+
+23.Feb.2004 Gloinson
diff --git a/doc/lfun/obsolete/AddInsertHook b/doc/lfun/obsolete/AddInsertHook
new file mode 100644
index 0000000..5e80272
--- /dev/null
+++ b/doc/lfun/obsolete/AddInsertHook
@@ -0,0 +1,59 @@
+********************* OBSOLETE LFUN ***********************************
+* Diese Efun bitte nicht mehr benutzen, sondern stattdessen die       *
+* Hooks (s. /doc/std/hooks).                                          *
+***********************************************************************
+AddInsertHook()
+
+FUNKTION:
+     void AddInsertHook(object ob);
+
+DEFINIERT IN:
+     /std/player/restrictions.c
+
+ARGUMENTE:
+     ob - Das Objekt, das informiert werden soll, wenn ein Objekt dem
+          Spielerinventar hinzugefuegt wurde.
+
+BESCHREIBUNG:
+     (Diese Funktionalitaet wurde ersetzt durch den allgemeinen Hook
+      H_HOOK_INSERT und ist nur noch aus Gruenden der Kompatibilitaet
+      vorhanden.)
+
+     Diese Funktion wird im Spielerobjekt aufgerufen, um das Objekt ob als
+     Hook-Listener anzumelden. Auf diese Weise eingetragene Listener
+     werden informiert, wenn ein Objekt ins Spielerinventar bewegt wurde.
+     Technisch wird die Bewegung ueber NotifyInsert() im Spielerobjekt
+     detektiert, und im Listener-Objekt wird die Funktion InsertNotify()
+     gerufen, die als Parameter das neu ins Spielerinventar bewegte Objekt
+     uebergeben bekommt.
+
+RUeCKGABEWERT:
+     keiner
+
+BEMERKUNGEN:
+     Das Listener-Objekt muss sich ebenfalls im Spielerinventar befinden,
+     ansonsten wird der eingetragene Hook wieder geloescht.
+
+BEISPIEL:
+     
+     a) Objekt "ob" wird im Spieler als Listener angemeldet:
+        this_player()->AddInsertHook(ob);
+
+     b) Objekt "new" wird ins Spielerinventar bewegt, das Spielerobjekt
+        informiert "ob" darueber:
+        ob->InsertNotify(new);
+
+     c) Das Listener-Objekt "ob" reagiert darauf, z.B. indem es die Fackel
+        loescht, sofern sie vorher brannte:
+        void InsertNotify(object new) {
+          if ( objectp(new) && new->id("\nfackel") && 
+               new->QueryProp(P_LIGHTED) )
+            new->unlight();
+          return;
+        }
+
+SIEHE AUCH:
+    NotifyInsert(), RemoveInsertHook(), QueryInsertHooks()
+
+----------------------------------------------------------------------------
+Last modified: 14.04.2010, Arathorn
diff --git a/doc/lfun/obsolete/ModifySkillAttributeOld b/doc/lfun/obsolete/ModifySkillAttributeOld
new file mode 100644
index 0000000..65d9afc
--- /dev/null
+++ b/doc/lfun/obsolete/ModifySkillAttributeOld
@@ -0,0 +1,90 @@
+ModifySkillAttributeOld()
+
+FUNKTION:
+    varargs int ModifySkillAttributeOld(object caster, string atrname, 
+                                        int value, int duration, mixed fun)
+
+DEFINIERT IN:
+    /std/living/skill_attributes.c
+
+ARGUMENTE:
+    <caster>    IGNORIERT
+                frueher Objekt, das die Modifikation vornimmt, heute ist
+                dieses Argument ohne Bedeutung und wird ignoriert.
+
+    <atrname>   STRING
+                Name des zu veraendernden Attributes
+                (Definiert in /sys/living/skill_attributes.h)
+
+    <value>     INT
+                Neuer Wert des Attributs (Standard: 100)
+
+    <duration>  INT
+                Dauer in Sekunden
+
+    <fun>       NICHT MEHR UNTERSTUETZT - ModifySkillAttribute() nutzen!!
+
+BESCHREIBUNG:
+    Diese Funktion existiert nur aus Kompatibilitaetsgruenden. Bitte in neuen
+    Objekten NICHT mehr verwenden und in alten nach Moeglichkeit ausbauen!
+
+    Aendert ein Skill-Attribut eines Living.
+    
+    Fuer <value> ist folgendes zu beachten:
+    Frueher handelte es sich um einen multiplikativen Faktor. 100 hatte die
+    Bedeutung von 1 und veraenderte nichts. Heute sind die Modifikatoren
+    additiv. Diese Funktion macht eine einfache Umrechnung, indem sie vom hier
+    uebergeben Wert 100 abzieht. (In der Annahme, dass frueher meist eh nur 
+    ein Modifikator zur gleichen Zeit aktiv war.)
+    Gibt man hier also hier eine 100 an, wird ein Modifikator von 0 einge-
+    tragen, der nichts aendert, bei 200 wird ein Modifikator von 100 einge-
+    tragen, bei 50 einer von -50, welcher das Skillattribute folglich 
+    reduziert.
+
+    Es sind momentan max. 5 gleichzeitige Skillattribute-Modifikatoren pro SA
+    zulaessig.
+
+RUECKGABEWERT:
+     0  wenn der Wert ungueltig ist oder aus sonstigem Grunde nicht gesetzt
+        werden konnte (fuer bessere Diagnostik -> ModifySkillAttribute()).
+    >0  wenn alles okay war
+
+BEMERKUNGEN:
+    Frueher musste ein setzendes Objekt ein groesseres P_LEVEL haben als das
+    Objekt, welches einen vorherigen Modifikator gesetzt hat, um diesen zu
+    ueberschreiben. Dies ist inzwischen ohne Bedeutung.
+
+BEISPIELE:
+    Ein NPC:
+
+    void
+    create() {
+    .
+    .
+    .
+    AddSpell(1, 1,
+      "Der fuerchterliche NPC haut Dir auf den Kopf.\n",
+      "Der fuerchterliche NPC haut @WEN auf den Kopf.\n",
+      DT_MAGIC, "schwaechen");
+    .
+    .
+    }
+
+    schwaechen(object enemy, int damage, mixed *dam_type) {
+      int ergebnis;
+      ergebnis = enemy->ModifySkillAttributeOld(this_object(), SA_QUALITY, 50, 5);
+      if (ergebnis > 0)
+          tell_object(enenmy, "Du fuehlst Dich ganz schwach.\n");
+    }
+    
+    Der NPC schwaecht seinen Gegner erheblich! Alles wird fuer 5 Sekunden um
+    50, d.h. 0.5 Skillattribute reduziert (50 - 100 => -50 als Modifikator).
+
+SIEHE AUCH:
+    P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS,
+    ModifySkillAttribute, QuerySkillAttribute(),
+    RemoveSkillAttributeModifer(), QuerySkillAttributeModifier()
+
+-----------------------------------------------------------------------------
+07.08.2008 Zesstra
+
diff --git a/doc/lfun/obsolete/NotifyGiveQuest b/doc/lfun/obsolete/NotifyGiveQuest
new file mode 100644
index 0000000..7e29798
--- /dev/null
+++ b/doc/lfun/obsolete/NotifyGiveQuest
@@ -0,0 +1,37 @@
+********************* OBSOLETE LFUN ***********************************
+* Diese Efun bitte nicht mehr benutzen, sondern stattdessen die       *
+* Events (siehe "man events").                                        *
+***********************************************************************
+
+NotifyGiveQuest()
+
+FUNKTION:
+     void NotifyGiveQuest(object pl, string key);
+     
+DEFINIERT IN:
+     /std/gilden_ob.c
+     
+ARGUMENTE:
+     pl     Der Spieler, der eine Quest geloest hat.
+     key    Name der geloesten Quest.
+     
+BESCHREIBUNG:
+     Die Funktion wird in der Gilde des Spielers aufgerufen, wenn der 
+     Spieler eine gueltige Quest besteht - und zwar unabhaengig davon,
+     ob er sie bereits geloest hat, oder nicht.
+     
+RUECKGABEWERT:
+     keiner
+     
+BEMERKUNGEN:
+     Die Funktion ist dafuer gedacht, von Gildenprogrammierern ueberschrieben
+     zu werden, wenn beispielsweise bestimmte Quests als Aufstiegsbedingung
+     verlangt werden, diese aber in der entsprechenden Gilde geloest sein
+     muessen (z.B. Obergladiator als Level-5-Zauberer).
+     
+SIEHE AUCH:
+     /std/gilden_ob.c
+     /std/player/quests.c
+
+----------------------------------------------------------------------------
+Last modified: Fri Oct 4 10:17:00 1996 by Silvana
diff --git a/doc/lfun/obsolete/NotifyHpChange b/doc/lfun/obsolete/NotifyHpChange
new file mode 100644
index 0000000..6f82b03
--- /dev/null
+++ b/doc/lfun/obsolete/NotifyHpChange
@@ -0,0 +1,47 @@
+********************* OBSOLETE LFUN ***********************************
+* Diese Efun bitte nicht mehr benutzen, sondern stattdessen die       *
+* Hooks (s. /doc/std/hooks).                                          *
+***********************************************************************
+NotifyHpChange()
+
+FUNKTION:
+	void NotifyHpChange();
+
+DEFINIERT IN:
+	/std/player/life.c
+
+ARGUMENTE:
+	keine
+
+BESCHREIBUNG:
+	Wenn sich die Lebenspunkte eines Spielers aendern, so werden davon
+	auch andere Objekte unterrichtet, sofern diese mittels der Funktion
+	AddHpHook() bei eben diesem Spieler angemeldet wurden.
+	Fortan wird dann die Funktion NotifyHpChange() in diesen
+	angemeldeten Objekten aufgerufen, wenn sich die Property P_HP des
+	Spielers aendert. Es werden hierbei keine Argumente an
+	NotifyHpChange() uebergeben, die aktuellen Lebenspunkte kann man ja
+	auch ohne weiteres ueber die Property P_HP in Erfahrung bringen und
+	aeltere Werte muss man sich gesondert merken. Zu beachten ist, dass
+	die Property P_HP bei Aufruf der Funktion NotifyHpChange() bereits
+	den neuen Wert enthaelt.
+	Bei dem Spieler angemeldete Objekte, die von Lebenspunkteaenderungen
+	informiert werden sollen, werden automatisch aus der Liste entfernt,
+	wenn sie zerstoert wurden. Diese Liste ist in der Property
+	P_HP_HOOKS zu finden. Per Hand kann man sie auch explizit mittels
+	der Funktion RemoveHpHook() entfernen.
+	Stirbt ein Spieler, so wird die Funktion NotifyPlayerDeath()
+	aufgerufen und nicht NotifyHpChange()!
+
+RUeCKGABEWERT:
+	keiner
+
+BEISPIELE:
+	ist in Arbeit
+
+SIEHE AUCH:
+	P_HP, P_HP_HOOKS, AddHpHook(), RemoveHpHook(),
+	Defend(), do_damage(), NotifyPlayerDeath()
+
+----------------------------------------------------------------------------
+Last modified: Thu Nov 19 13:54:33 1998 by Patryn
diff --git a/doc/lfun/obsolete/QueryEnemy b/doc/lfun/obsolete/QueryEnemy
new file mode 100644
index 0000000..bf0b583
--- /dev/null
+++ b/doc/lfun/obsolete/QueryEnemy
@@ -0,0 +1,24 @@
+********************* OBSOLETE LFUN ***********************************
+FUNKTION:
+	object QueryEnemy();
+
+DEFINIERT IN:
+	/std/living/combat.c
+
+ARGUMENTE:
+	keine
+
+RUeCKGABEWERT:
+	gefundener Gegner
+
+BESCHREIBUNG:
+	Diese Funktion liefert zufaellig einen der anwesenden Gegner
+	zurueck, sofern keine Gegner bevorzugt ausgewaehlt werden.
+
+BEMERKUNGEN:
+  Diese Lfun existiert nicht mehr. Bitte SelectEnemy() benutzen.
+
+SIEHE AUCH:
+	SelectEnemy(), QueryPreferedEnemy(), P_PREFERED_ENEMY
+----------------------------------------------------------------------------
+07.02.2009, Zesstra
diff --git a/doc/lfun/obsolete/QueryInsertHooks b/doc/lfun/obsolete/QueryInsertHooks
new file mode 100644
index 0000000..c43d036
--- /dev/null
+++ b/doc/lfun/obsolete/QueryInsertHooks
@@ -0,0 +1,31 @@
+********************* OBSOLETE LFUN ***********************************
+* Diese Efun bitte nicht mehr benutzen, sondern stattdessen die       *
+* Hooks (s. /doc/std/hooks).                                          *
+***********************************************************************
+QueryInsertHooks()
+
+FUNKTION:
+     object *QueryInsertHooks();
+
+DEFINIERT IN:
+     /std/player/restrictions.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     (Diese Funktionalitaet wurde ersetzt durch den allgemeinen Hook
+      H_HOOK_INSERT und ist nur noch aus Gruenden der Kompatibilitaet
+      vorhanden.)
+
+     Diese Funktion gibt die aktuell beim Spielerobjekt angemeldeten
+     Listener-Objekte zurueck.
+
+RUeCKGABEWERT:
+     Array aus Objektpointern oder leeres Array
+
+SIEHE AUCH:
+    NotifyInsert(), AddInsertHook(), RemoveInsertHook()
+
+----------------------------------------------------------------------------
+Last modified: 14.04.2010, Arathorn
diff --git a/doc/lfun/obsolete/QueryOptQP b/doc/lfun/obsolete/QueryOptQP
new file mode 100644
index 0000000..f6f72c5
--- /dev/null
+++ b/doc/lfun/obsolete/QueryOptQP
@@ -0,0 +1,25 @@
+QueryOptQP()
+
+FUNKTION:
+    int QueryOptQP()
+
+DEFINIERT IN:
+    /secure/questmaster.c
+
+ARGUMENTE:
+    keine
+
+RUECKGABEWERT:
+    Abenteuerpunkte der optionalen Quests
+
+BESCHREIBUNG:
+    Diese Funktion liefert die Abenteuerpunkte der optionalen
+    Abenteuer zurueck. 
+
+SIEHE AUCH:
+    GiveQuest, QueryQuest, /secure/questmaster.h, QueryGroupedKeys,
+    QueryMaxQP, QueryTotalQP
+
+----------------------------------------------------------------------------
+Zuletzt geaendert: Sam, 25. Nov 2000, 14:04:28 von Zook.
+
diff --git a/doc/lfun/obsolete/RemoveHpHook b/doc/lfun/obsolete/RemoveHpHook
new file mode 100644
index 0000000..d3177f1
--- /dev/null
+++ b/doc/lfun/obsolete/RemoveHpHook
@@ -0,0 +1,25 @@
+********************* OBSOLETE LFUN ***********************************
+* Diese Efun bitte nicht mehr benutzen, sondern stattdessen die       *
+* Hooks (s. /doc/std/hooks).                                          *
+***********************************************************************
+RemoveHpHook()
+FUNKTION:
+     int RemoveHpHook(object ob)
+
+DEFINIERT IN:
+     /std/player/life.c
+
+ARGUMENTE:
+     ob - das Objekt, das sich austragen moechte.
+
+BESCHREIBUNG:
+     Entfernt den Eintrag fuer dieses Objekt in P_HP_HOOKS.
+
+RUECKGABEWERT:
+     1, wenn Erfolg, 0 sonst
+
+SIEHE AUCH:
+     Gegenpart:	AddHpHook()
+     Props:	P_HP_HOOKS, P_HP
+
+23.Feb.2004 Gloinson
diff --git a/doc/lfun/obsolete/RemoveInsertHook b/doc/lfun/obsolete/RemoveInsertHook
new file mode 100644
index 0000000..f232eed
--- /dev/null
+++ b/doc/lfun/obsolete/RemoveInsertHook
@@ -0,0 +1,31 @@
+********************* OBSOLETE LFUN ***********************************
+* Diese Efun bitte nicht mehr benutzen, sondern stattdessen die       *
+* Hooks (s. /doc/std/hooks).                                          *
+***********************************************************************
+RemoveInsertHook()
+
+FUNKTION:
+     void RemoveInsertHook(object ob);
+
+DEFINIERT IN:
+     /std/player/restrictions.c
+
+ARGUMENTE:
+     ob - Das Objekt, das als Listener aus der Liste ausgetragen werden soll
+
+BESCHREIBUNG:
+     (Diese Funktionalitaet wurde ersetzt durch den allgemeinen Hook
+      H_HOOK_INSERT und ist nur noch aus Gruenden der Kompatibilitaet
+      vorhanden.)
+
+     Diese Funktion wird im Spielerobjekt aufgerufen, um ein als Listener
+     eingetragenes Hook-Objekt ob wieder auszutragen.
+
+RUeCKGABEWERT:
+     keiner
+
+SIEHE AUCH:
+    NotifyInsert(), AddInsertHook(), QueryInsertHooks()
+
+----------------------------------------------------------------------------
+Last modified: 14.04.2010, Arathorn
diff --git a/doc/lfun/obsolete/TestAttributeLock b/doc/lfun/obsolete/TestAttributeLock
new file mode 100644
index 0000000..126e931
--- /dev/null
+++ b/doc/lfun/obsolete/TestAttributeLock
@@ -0,0 +1,25 @@
+********************* OBSOLETE LFUN ***********************************
+TestAttributeLock()
+FUNKTION:
+     string TestAttributeLock(mapping check)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+

+PARAMETER:

+     check	- Mapping mit Attributen: ([<attr>:<wert>])

+
+BESCHREIBUNG:
+     Prueft, ob eines der im Mapping enthaltenen Attribute blockiert

+     ist (bereits durch einen anderen Modifier belegt wurde).
+     
+     Da Modifier nicht mehr direkt blockieren ist diese Funktion obsolet
+     und in Livings inzwischen nicht mehr existent.
+
+SIEHE AUCH:
+     QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+     SetAttr(), SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+     P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_ATTRIBUTES_MODIFIER,

+     P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c

+
+11.05.2007, Zesstra
diff --git a/doc/lfun/obsolete/extra_look b/doc/lfun/obsolete/extra_look
new file mode 100644
index 0000000..753a8ed
--- /dev/null
+++ b/doc/lfun/obsolete/extra_look
@@ -0,0 +1,19 @@
+********************* VERALTETE LFUN ******************************
+* Diese LFUN ist veraltet. Bitte benutzt sie NICHT mehr, sondern  *
+* stattdessden AddExtraLook().                                    *
+*******************************************************************
+
+extra_look()
+
+FUNKTION:
+    string extra_look();
+
+BESCHREIBUNG:
+    Kann in Objekt definiert sein. Wenn ein Living (std/living/description)
+    das Objekt enthaelt, wird zu dessen long() der zurueckgegebene String
+    hinzugefuegt.
+
+SIEHE AUCH:
+    AddExtraLook()
+
+25.Jan 2015 Gloinson
diff --git a/doc/lfun/obsolete/paramove b/doc/lfun/obsolete/paramove
new file mode 100644
index 0000000..96686a2
--- /dev/null
+++ b/doc/lfun/obsolete/paramove
@@ -0,0 +1,45 @@
+****************************************************************************
+************************* VERALTETE LFUN ***********************************
+************************* DO NOT USE!    ***********************************
+****************************************************************************
+paramove()
+
+FUNKTION:
+     int paramove();
+
+DEFINIERT IN:
+     /std/room/para.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Bewegt den Spieler ggf. in eine Paralleldimension.
+
+RUeCKGABEWERT:
+     1, wenn der Spieler die Dimension gewechselt hat.
+
+BEISPIEL:
+     init(){
+       if(!paramove()) ::init();
+      }
+
+BEMERKUNGEN:
+     DIESE FUNKTION NICHT MEHR BENUTZEN!
+
+     Diese Funktion sollte nur aus einem init() aufgerufen werden!
+
+     Fuer die Entscheidung, in welchem Raum ein Spieler in Abhaengigkeit 
+     von P_PARA landet, ist die Funktion move() zustaendig. Als Magier 
+     muss man sich darum nicht gesondert kuemmern. Das heisst aber auch, 
+     dass beim Anschluss eines Normalweltraumes automatisch alle in dem 
+     Verzeichnis mit gleichem Namen vorhandenen Parallelweltraeume mit 
+     angeschlossen werden.
+
+     Deswegen ist paramove() veraltet und sollte nicht mehr genutzt werden.
+
+SIEHE AUCH:
+     /std/room/para.c, P_PARA, P_NO_PLAYERS, move
+
+----------------------------------------------------------------------------
+Last modified: 05.08.2007, Zesstra
diff --git a/doc/lfun/pick b/doc/lfun/pick
new file mode 100644
index 0000000..59bf51f
--- /dev/null
+++ b/doc/lfun/pick
@@ -0,0 +1,48 @@
+pick()
+
+FUNKTION:
+    public varargs int pick(object o, mixed msg);
+
+DEFINIERT IN:
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+    object o
+        Das Objekt, das aufgehoben werden soll.
+    mixed msg
+        Eine optionale Meldung, die anstelle von P_PICK_MSG oder der
+        Standardmeldung verwendet wird, oder -1, um die Meldung zu
+        unterdruecken.
+
+BESCHREIBUNG:
+    Der Spieler oder NPC nimmt das Objekt auf. Gibt o->move() keinen positiven
+    Wert zurueck, beispielsweise weil das Objekt zu schwer ist oder nicht
+    genommen werden darf, bekommt er eine entsprechende Fehlermeldung.
+
+RUECKGABEWERT:
+    Wenn das Aufnehmen geklappt hat, 1, ansonsten 0.
+
+BEMERKUNG:
+    Diese Funktion ist dann sinnvoll, wenn man den Spieler ein Objekt
+    aufnehmen lassen und sich nicht selbst um die Fehlerbehandlung kuemmern
+    moechte - und da unzaehlige verschiedene Dinge schiefgehen koennen und
+    manche Objekte eigene Fehlermeldungen definieren, eigentlich immer.
+
+    Die Funktion prueft nicht, ob sich das Objekt ueberhaupt in der Reichweite
+    des Spielers/NPC befindet, das muss man ggf. selbst ermitteln.
+
+BEISPIEL:
+    ob = clone_object(WEINGUMMI);
+
+    if (this_player()->pick(ob, ({ "Du nimmst @WENU2 aus dem Regal.",
+                                   "@WER1 nimmt @WENU2 aus dem Regal." })))
+        weingummi--;
+    else
+        ob->remove();
+
+SIEHE AUCH:
+    move(L), P_PICK_MSG, pick_objects(L), P_NOINSERT_MSG, P_NOLEAVE_MSG,
+    P_TOO_MANY_MSG, P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_NOGET
+
+----------------------------------------------------------------------------
+Last modified: Thu Aug 28 22:21:41 2008 by Amynthor
diff --git a/doc/lfun/pick_obj b/doc/lfun/pick_obj
new file mode 100644
index 0000000..a4c7c17
--- /dev/null
+++ b/doc/lfun/pick_obj
@@ -0,0 +1,27 @@
+pick_obj()
+
+FUNKTION
+    int pick_obj(object ob)
+
+DEFINIERT IN:
+
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+
+    ob      Das Objekt, das genommen werden soll.
+
+BESCHREIBUNG:
+
+    Das Lebewesen, in dem diese Funktion aufgerufen werden soll, hebt
+    den angegebenen Gegenstand (ob) auf, falls es ihm moeglich ist.
+
+RUeCKGABEWERT:
+    1, wenn das Objekt genommen wurde oder dies nicht moeglich war. (in diesem
+    Fall wird auch direkt eine Textausgabe ausgegeben)
+    0 sonst, in diesem Fall wird in notify_fail eine passende Ausgabe
+    plaziert
+
+SIEHE AUCH:
+
+    drop_obj(), find_obs(), give_obj(), put_obj(), /std/living/put_and_get.c
diff --git a/doc/lfun/pick_objects b/doc/lfun/pick_objects
new file mode 100644
index 0000000..92c083d
--- /dev/null
+++ b/doc/lfun/pick_objects
@@ -0,0 +1,39 @@
+pick_objects()
+
+FUNKTION:
+    public varargs int pick_objects(string str, int flag, mixed msg);
+
+DEFINIERT IN:
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+    string str
+        Was aufgehoben werden soll.
+    int flag
+        Muss das Objekt irgendwo drinstecken (flag = 1), oder darf es einfach
+        so herumliegen (flag = 0)? Dieses Argument ist hauptsaechlich fuer das
+        Kommando "hole" gedacht, in der Regel braucht man es nicht anzugeben.
+    mixed msg
+        Eine optionale Meldung, die anstelle von P_PICK_MSG oder der
+        Standardmeldung verwendet wird, oder -1, um die Meldung zu
+        unterdruecken.
+
+BESCHREIBUNG:
+    Der Spieler oder NPC nimmt die in <str> benannten Sachen. Kann er ein
+    Objekt nicht nehmen, bekommt er eine entsprechende Fehlermeldung. Wenn
+    keine Objekte auf <str> passen, wird per _notify_fail() eine Meldung
+    gesetzt, aber noch nicht ausgegeben.
+
+RUECKGABEWERT:
+    Wenn <str> irgendwelche vorhandenen Sachen sind, 1, sonst 0.
+
+BEMERKUNG:
+    Wenn die Funktion 1 zurueckgibt, heisst das noch nicht, dass der Spieler
+    etwas genommen hat! Er hat es nur versucht, d.h. auf jeden Fall eine
+    Meldung bekommen. Gibt die Funktion 0 zurueck, hat er noch keine bekommen.
+
+SIEHE AUCH:
+    move(L), pick(L), P_PICK_MSG, find_objects(L), moved_objects(L)
+
+----------------------------------------------------------------------------
+Last modified: Fri Jul 25 10:58:43 2008 by Amynthor
diff --git a/doc/lfun/present_objects b/doc/lfun/present_objects
new file mode 100644
index 0000000..15cf4be
--- /dev/null
+++ b/doc/lfun/present_objects
@@ -0,0 +1,32 @@
+present_objects()
+
+FUNKTION:
+     object *present_objects(string desc);
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     desc
+          Umschreibung des gesuchten Objektes oder "alles" oder "alle".
+
+BESCHREIBUNG:
+     Diese Funktion gibt die Objekte im Inneren des Behaelters zurueck, die
+     sich mit desc ansprechen lassen. In dem Fall, dass "alle(s)"
+     angefordert wird, sind das alle sichtbaren Objekte, ansonsten das erste
+     Objekt, das sich mit desc ansprechen laesst.
+     Objekte, die P_INVIS gesetzt haben, zaehlen als nicht ansprechbar, im
+     Gegensatz zu solchen Objekten, die keine P_SHORT haben.
+
+RUeCKGABEWERT:
+     Ein Array von Objekten mit den geforderten Eigenschaften.
+
+     Befindet sich kein Objekt im Behaelter, das sich durch desc ansprechen
+     laesst, so wird ein leeres Array zurueckgegeben.
+
+SIEHE AUCH:
+     locate_objects(), /std/container/restrictions.c
+
+----------------------------------------------------------------------------
+03.03.2013, Zesstra
+
diff --git a/doc/lfun/put b/doc/lfun/put
new file mode 100644
index 0000000..33e7eaf
--- /dev/null
+++ b/doc/lfun/put
@@ -0,0 +1,43 @@
+put()
+
+FUNKTION:
+    public varargs int put(object o, object dest, mixed msg);
+
+DEFINIERT IN:
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+    object o
+        Das Objekt, das irgendwo hingesteckt werden soll.
+    object dest
+        Der Behaelter, in den das Objekt gesteckt werden soll.
+    mixed msg
+        Eine optionale Meldung, die anstelle von P_PUT_MSG oder der
+        Standardmeldung verwendet wird, oder -1, um die Meldung zu
+        unterdruecken.
+
+BESCHREIBUNG:
+    Der Spieler oder NPC steckt das Objekt in einen Behaelter. Gibt o->move()
+    keinen positiven Wert zurueck, beispielsweise weil er das Objekt nicht
+    weggeben darf oder der Behaelter schon voll ist, bekommt er eine
+    entsprechende Fehlermeldung.
+
+RUECKGABEWERT:
+    Wenn das Bewegen geklappt hat, 1, ansonsten 0.
+
+BEMERKUNG:
+    Diese Funktion ist dann sinnvoll, wenn man den Spieler ein Objekt irgendwo
+    hinstecken lassen und sich nicht selbst um die Fehlerbehandlung kuemmern
+    moechte - und da unzaehlige verschiedene Dinge schiefgehen koennen und
+    manche Objekte eigene Fehlermeldungen definieren, eigentlich immer.
+
+    Die Funktion prueft nicht, ob sich das Objekt und der Behaelter ueberhaupt
+    in der Reichweite des Spielers/NPC befinden, das muss man ggf. selbst
+    ermitteln.
+
+SIEHE AUCH:
+    move(L), P_PUT_MSG, put_objects(L), P_NOINSERT_MSG, P_NOLEAVE_MSG,
+    P_TOO_MANY_MSG, P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_NOGET, P_NODROP
+
+----------------------------------------------------------------------------
+Last modified: Thu Aug 28 22:21:58 2008 by Amynthor
diff --git a/doc/lfun/put_obj b/doc/lfun/put_obj
new file mode 100644
index 0000000..1f1b299
--- /dev/null
+++ b/doc/lfun/put_obj
@@ -0,0 +1,30 @@
+put_obj()
+
+FUNKTION
+    int put_obj(object ob, object where)
+
+DEFINIERT IN:
+
+    /std/living/put_and_get.c
+
+ARGUMENTE:
+
+    ob      Das Objekt, das irgendwo hineingelegt werden soll.
+    where   Das (tote) Objekt, in das etwas hineingelegt werden soll.
+
+BESCHREIBUNG:
+
+    Das Lebewesen, in dem diese Funktion aufgerufen werden soll, legt
+    den angegebenen Gegenstand (ob) in das angegebene Zielobjekt (where).
+    Dabei sollte es sich bei where um einen Container/Raum handeln.
+    Ist where ein Lebewesen, verwendet man besser give_obj().
+
+RUeCKGABEWERT:
+    1, wenn das Objekt weggelegt wurde oder dies nicht moeglich war. (in diesem
+    Fall wird auch direkt eine Textausgabe ausgegeben)
+    0 sonst, in diesem Fall wird in notify_fail eine passende Ausgabe
+    plaziert
+
+SIEHE AUCH:
+
+    drop_obj(), find_obs(), give_obj(), pick_obj(), /std/living/put_and_get.c
diff --git a/doc/lfun/query_prevent_shadow b/doc/lfun/query_prevent_shadow
new file mode 100644
index 0000000..80b0c7d
--- /dev/null
+++ b/doc/lfun/query_prevent_shadow
@@ -0,0 +1,34 @@
+query_prevent_shadow(L)
+FUNKTION:
+     varargs int query_prevent_shadow(object shadower)
+
+PARAMETER:
+     object shadower	- da Objekt, das eine Beschattung beantragt
+
+BESCHREIBUNG:
+     Diese Methode kann in Objekten definiert werden, die nicht beschattet
+     werden wollen oder anhand des Objektes shadower entscheiden wollen ob
+     sie beschattet werden wollen.
+
+     Gibt die Funktion 0 zurueck, wird ein Shadow auf das Objekt erlaubt,
+     sonst schlaegt es fehl.
+
+BEISPIEL:
+     // generell keine Beschattung
+     int query_prevent_shadow(object who) {
+      return 1;
+     }
+
+     // Beschattung durch offizielle Objekte erlaubt
+     int query_prevent_shadow(object who) {
+      if(who && !strstr(object_name(who),"/std/player"))
+       return 0;
+      return 1;
+     }
+
+SIEHE AUCH:
+     Rechte:	     query_allow_shadow(M)
+     Generell:	     shadow(E), unshadow(E)
+     Informationen:  query_shadowing(E)
+
+20. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/query_real_name b/doc/lfun/query_real_name
new file mode 100644
index 0000000..d7633de
--- /dev/null
+++ b/doc/lfun/query_real_name
@@ -0,0 +1,15 @@
+query_real_name()
+
+SYNOPSIS:
+	string query_real_name(void)
+
+DESCRIPTION:
+	The result of this_player()->query_real_name() is used as
+	default argument for the efun wizlist().
+
+	If LOG_SHOUT was #defined in the parser at compile time, the
+	efun shout will use query_real_name() to log the shouter's
+	name.
+
+SEE ALSO:
+	shout(E), wizlist(E)
diff --git a/doc/lfun/query_weight_contents b/doc/lfun/query_weight_contents
new file mode 100644
index 0000000..13980f8
--- /dev/null
+++ b/doc/lfun/query_weight_contents
@@ -0,0 +1,20 @@
+query_weight_contents()
+
+FUNKTION:
+     int query_weight_contents()
+
+DEFINIERT IN:
+     /std/container/restrictions.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Gibt das Gewicht des Inhaltes des Behaelters zurueck (ohne
+     Beruecksichtigung von P_WEIGHT_PERCENT!)
+
+RUeCKGABEWERT:
+     Das Gewicht des Behaelterinhaltes.
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:23:32 1996 by Wargon
diff --git a/doc/lfun/reduce_hit_points b/doc/lfun/reduce_hit_points
new file mode 100644
index 0000000..39b3368
--- /dev/null
+++ b/doc/lfun/reduce_hit_points
@@ -0,0 +1,43 @@
+reduce_hit_points()
+FUNKTION:
+    int reduce_hit_points(int damage)
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    int damage	- der zugefuegte Schaden
+
+BESCHREIBUNG:
+    Dem Lebewesen werden damage Lebenspunkte abgezogen, aber der
+    Wert wird hinterher nicht kleiner als 1 sein und das Lebewesen
+    wird dadurch nicht sterben.
+
+RUECKGABEWERT:
+    Die verbleibenden Lebenspunkte.
+
+BEISPIELE:
+    write("Ploetzlich schiesst eine scheussliche Kreatur aus der Pfuetze "+
+          "heraus und\nbeisst Dich ins Bein, sie verschwindet so schnell, "+
+          "wie sie gekommen ist.\n");
+    this_player()->reduce_hit_points(50);
+    (Auszug aus /players/boing/friedhof/room/cat1x9)
+
+BEMERKUNGEN:
+    damage kann auch ein negativer Wert sein, dann werden dem Lebewesen
+    diese Lebenspunkte gutgeschrieben und auf die aktuellen Lebenspunkte
+    addiert. Da dies eine Form der Heilung ist, nur nach Ruecksprache mit
+    dem Regionsmagier verwenden.
+
+    Bei Heilstellen sollte eine evtl. Heilung des Spielers mit der eigens
+    dafuer eingerichteten Funktion check_and_update_timed_key realisiert
+    werden.
+
+SIEHE AUCH:
+    Gegenpart:	restore_hit_points()
+    Verwandt:	do_damage(), Defend(), reduce_spell_points()
+    Props:	P_HP
+    Konzept:	heilung
+
+----------------------------------------------------------------------------
+Last modified: Sat Dec 13 01:00:47 1999 by Tilly
diff --git a/doc/lfun/reduce_spell_points b/doc/lfun/reduce_spell_points
new file mode 100644
index 0000000..13c0630
--- /dev/null
+++ b/doc/lfun/reduce_spell_points
@@ -0,0 +1,27 @@
+reduce_spell_points()
+FUNKTION:
+    void reduce_spell_points(int points)
+
+DEFINIERT IN:
+    /std/living/life.c
+
+ARGUMENTE:
+    points: Anzahl der Konzentrationspunkte die abgezogen werden sollen.
+
+BESCHREIBUNG:
+    Dem Lebewesen werden points Konzentrationspunkte abgezogen. Falls
+    das Lebewesen weniger Konzentrationspunkte hat, als abgezogen werden
+    sollen, werden sie auf 0 gesetzt.
+
+BEISPIELE:
+    write("Das boese boese Monster schaut Dich grimmig an und labt sich an "
+         +"Deiner Konzentration.\n");
+    this_player()->reduce_spell_points(50);
+
+SIEHE AUCH:
+    Gegenpart:	restore_spell_points(L)
+    Verwandt:	reduce_hit_points(L), buffer_sp(L)
+    Props:	P_SP
+    Konzept:	heilung
+
+23.Feb.2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/register_modifier b/doc/lfun/register_modifier
new file mode 100644
index 0000000..359a050
--- /dev/null
+++ b/doc/lfun/register_modifier
@@ -0,0 +1,24 @@
+register_modifier()
+FUNKTION:
+     void register_modifier(object modifier)
+
+DEFINIERT IN:
+     /std/living/attributes.c
+

+PARAMETER:

+     modifier	- Objekt mit P_X_ATTR_MOD oder P_M_ATTR_MOD

+
+BESCHREIBUNG:
+     Registriert einen Modifier im Spieler. Wird durch InsertSensitiveObject
+     beziehungsweise beim Anziehen oder Zuecken gerufen.
+     Muss nicht direkt gerufen werden. Bei Veraenderungen von Modifikatoren
+     sollte stattdessen UpdateAttributes gerufen werden.     
+
+SIEHE AUCH:
+     QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),

+     SetAttr(), SetAttribute(), SetRealAttribute(), UpdateAttributes(),

+     deregister_modifier(), P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, 
+     P_ATTRIBUTES_MODIFIER,P_X_ATTR_MOD, P_M_ATTR_MOD, 
+     /std/living/attributes.c

+
+13.Jun.2004, Muadib
\ No newline at end of file
diff --git a/doc/lfun/remove b/doc/lfun/remove
new file mode 100644
index 0000000..21fc59a
--- /dev/null
+++ b/doc/lfun/remove
@@ -0,0 +1,34 @@
+remove()
+
+FUNKTION:
+     varargs int remove(int silent);
+
+DEFINIERT IN:
+     /std/thing/moving.c
+     /std/living/moving.c
+     /std/room/moving.c
+
+ARGUMENTE:
+     silent
+          Falls ungleich 0, so werden beim Zerstoeren keine Meldungen
+          ausgegeben.
+
+BESCHREIBUNG:
+     Beim Aufruf dieser Funktion entfernt sich das Objekt selbst. Durch
+     Ueberladen dieser Funktion kann man diesen Vorgang noch durch die
+     Ausgabe von Meldungen kommentieren, oder irgendwelche Daten
+     abspeichern, oder das Zerstoeren ganz verhindern (auf diesem Weg... Mit
+     destruct() kann das Objekt immer noch direkt zerstoert werden!)
+
+RUeCKGABEWERT:
+     1, wenn sich das Objekt erfolgreich selbst zerstoert hat, sonst 0.
+
+BEMERKUNGEN:
+     Nach einem erfolgreichen ::remove() gelten die selben Einschraenkungen
+     wie nach einem destruct()!
+
+SIEHE AUCH:
+     destruct()
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:23:40 1996 by Wargon
diff --git a/doc/lfun/remove_multiple b/doc/lfun/remove_multiple
new file mode 100644
index 0000000..6340fd1
--- /dev/null
+++ b/doc/lfun/remove_multiple
@@ -0,0 +1,58 @@
+remove_multiple()
+FUNKTION:
+     public varargs int remove_multiple(int limit, mixed fun);
+
+DEFINIERT IN:
+     /std/container/items.c
+
+ARGUMENTE:
+     limit: Anzahl gleicher Objekte, die verbleiben sollen.
+     fun:   Funktionsname (string) oder Closure.
+
+BESCHREIBUNG:
+     Wird diese Funktion aufgerufen, werden alle gleichen Objekte
+     (standardmaessig definiert als gleicher Ladename, gleiche
+      Kurzbeschreibung und gleiche Langbeschreibung), deren Anzahl <limit>
+     ueberschreitet, entfernt.
+     
+     Ausnahmen: Lebewesen und per AddItem() hinzugefuegte Objekte.
+
+     Mit dem Argument <fun> lassen sich die Kriterien fuer die "Gleichheit"
+     aendern.
+     Ist <fun> ein Funktionsname, wird diese Funktion an allen in Frage
+     kommenenden Objekten im Container gerufen.
+     Ist <fun> eine Closure, werden sie fuer jedes in Frage kommende Objekt
+     einmal gerufen und ihr das Objekt uebergeben.
+     Als 'gleich' werden alle Objekte betrachtet, fuer die <fun> den gleichen
+     Wert zurueckliefert.
+     Objekte, fuer die <fun> 0 zurueckliefert, werden ignoriert.
+
+BEMERKUNGEN:
+     1) Raeume rufen remove_multiple(3) standardmaessig im reset(), jedoch
+        nur, wenn kein Spieler anwesend ist und mehr als 10 Objekte im Raum
+        sind.
+     2) remove_multipe(0) entfernt alle entfernbaren Objekte (s. Ausnahmen).
+
+BEISPIELE:
+     Ein Container enthaelt 5 Fackeln. Im reset() ruft man nun
+     remove_multiple(3) auf. Anschliessend sind noch 3 Fackeln uebrig.
+     
+     Alle verbleibenden Objekte im Container sollen unterschiedliche Namen
+     haben:
+     remove_multiple(1, "name");
+
+     Ein Container soll nur ein Objekt behalten, welches groesser als 70 cm
+     ist:
+     int groessen_filter(object ob) {
+       if (ob->QueryProp(P_SIZE > 70)) return 1;
+       return 0; // damit das Objekt ignoriert wird.
+       // Alternativ koennte man statt 0 auch object_name(ob) zurueckliefern,
+       // dann sind diese Objekte alle unterschiedlich.
+     }
+     ...
+     remove_multiple(1, #'groessen_filter);
+
+SIEHE AUCH:
+     reset()
+
+31.01.2009, Zesstra
diff --git a/doc/lfun/reset b/doc/lfun/reset
new file mode 100644
index 0000000..07a22ee
--- /dev/null
+++ b/doc/lfun/reset
@@ -0,0 +1,88 @@
+reset()
+FUNKTION:
+     void reset();
+     protected void reset();
+
+BESCHREIBUNG:
+     reset() wird vom GameDriver in jedem Objekt aufgerufen, um dem Objekt
+     die Gelegenheit zu geben, sich wieder in einen definierten Zustand zu
+     versetzen: Raeume und Monster erzeugen per AddItem() eingefuegte und
+     zwischenzeitlich entfernte Objekte neu, Tueren schliessen sich ...
+
+     Solange das Objekt "benutzt" wird, wird reset() regelmaessig alle
+     45 Minuten (+/-15 Minuten) mit einer Aufloesung von 2s aufgerufen
+     (d.h. der Driver prueft und ruft nur alle 2 Sekunden reset() auf
+     allen Objekten).
+
+     Wird eine Objekt nicht mehr "benutzt", d.h. wird an einem Objekt nicht
+     von aussen (durch call_other etc.) _nach_ einem reset() eine Methode
+     bzw. LFun gerufen, so bekommt dieses Objekt keinen weiteren reset().
+
+     Ein Funktionsaufruf am Objekt schaltet den reset() wieder ein.
+     Bei einem Objekt in einem Container waere das zB das Benutzen des
+     Containers (Hineinlegen/Herausnehmen/Hineinsehen). Das kann
+     sehr lange dauern.
+
+     Die Abschaltung kann man verhindern, indem man im reset() per call_out()
+     eine Funktion im Objekt ruft. Dies aber bitte _nur_ machen, wenn das
+     Objekt _unbedingt_ auf einen staendigen Reset angewiesen ist, auch wenn
+     es nicht "benutzt" wird.
+
+     Aendern laesst sich die Zeit zwischen den Aufrufen von reset() mit
+     set_next_reset(). Die Aufloesung von 2s kann man nicht aendern.
+
+BEMERKUNGEN:
+     - man kann reset() nutzen, um Ereignisse auszuloesen:
+       - es ist billiger als lange call_out()
+       - siehe Warnung bezueglich Abschalten des reset
+     - man kann reset() als protected oder static definieren, wenn man nicht
+       moechte, dass die Funktion von aussen gerufen werden kann. Dies
+       verhindert Einflussnahme von aussen, kann aber auch Debugmassnahmen
+       erschweren. Es ist aber dennoch fuer einige Objekte sinnvoll.
+     - der Driver ruft reset() unabhaengig von zusaetzlichen, "manuellen"
+       Rufen von reset()
+       - keine Rufe von reset() mit call_out() aus reset() (Callout-Ketten-
+         bildung droht), fuer solche Faelle ist set_next_reset(E) da!
+     - bei Blueprints sollte der reset() in der Regel abgeschaltet werden,
+       sofern er nicht auf wichtige Aufgaben in der BP zu tun hat:
+       protected void create() {
+         if(!clonep(ME)) {
+             set_next_reset(-1);
+             return;
+         }
+         ::create();
+         ...
+       }
+
+BEISPIELE:
+     // ein NPC, der bei jedem reset() schaut, ob um ihn herum bessere
+     // Ausruestung liegt als die, die er selbst gerade traegt:
+
+     ...
+     void reset() {
+       ::reset();
+
+       if(clonep(this_object()) && environment()) {
+         object o;
+         o=first_inventory(environment());
+         while(o) {
+             look_for_good_weapons_and_use_them_if_better(o);
+             o=next_inventory(o);
+         }
+       }
+     }
+
+     // ein reset fuer einen Gegenstand, der vielleicht in
+     // in einem Container landet und dann weiter einen reset
+     // bekommen muss/soll
+
+     void reset() {
+       // irgend ein Code hier
+       call_other(this_object(), "???"); // einfach nur was aufrufen
+     }
+
+SIEHE AUCH:
+     clean_up(), set_next_reset(E), query_next_reset(E)
+     memory
+
+letzte Aenderung: 2009-01-14 Rumata
diff --git a/doc/lfun/restore_hit_points b/doc/lfun/restore_hit_points
new file mode 100644
index 0000000..7ae3457
--- /dev/null
+++ b/doc/lfun/restore_hit_points
@@ -0,0 +1,33 @@
+restore_hit_points()
+FUNKTION:
+    int restore_hit_points(int heal)
+
+ARGUMENTE:
+    int heal	- der zu heilende Betrag
+
+BESCHREIBUNG:
+    Dem Lebewesen werden heal Lebenspunkte aufgeschlagen. Die HP
+    steigen nicht ueber P_MAX_HP.
+
+RUECKGABEWERT:
+    Die verbleibenden Lebenspunkte.
+
+BEISPIELE:
+    write("Ploetzlich schiesst eine scheussliche Kreatur aus der Pfuetze "+
+          "heraus und\nschleimt dich heilend voll, sie verschwindet so, "+
+          "wie sie gekommen ist.\n");
+    this_player()->restore_hit_points(50);
+
+BEMERKUNGEN:
+    Bei Heilstellen sollte eine evtl. Heilung des Spielers mit der eigens
+    dafuer eingerichteten Funktion check_and_update_timed_key realisiert
+    werden.
+    Ansonsten bitte buffer_hp() benutzen und die Konzeptseite lesen!
+
+SIEHE AUCH:
+    Gegenpart:	reduce_hit_points()
+    Verwandt:	buffer_hp(), heal_self(), restore_spell_points()
+    Props:	P_HP
+    Konzept:	heilung
+
+23.Feb.2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/restore_spell_points b/doc/lfun/restore_spell_points
new file mode 100644
index 0000000..87c2a6c
--- /dev/null
+++ b/doc/lfun/restore_spell_points
@@ -0,0 +1,37 @@
+restore_spell_points()
+FUNKTION:
+    void restore_spell_points(int points)
+
+ARGUMENTE:
+    points: Anzahl der Konzentrationspunkte die gutgeschrieben werden sollen.
+
+BESCHREIBUNG:
+    Dem Lebewesen werden points Konzentrationspunkte gutgeschrieben. Falls
+    Punkte abgezogen werden sollen und das Lebewesen nicht ueber <points>
+    Konzentrationspunkte verfuegt, werden sie auf 0 gesetzt.
+
+RUECKGABEWERT:
+    Keiner
+
+BEISPIELE:
+    write("Das boese boese Monster schaut Dich suess an und gibt dir mehr "
+         +"Konzentration.\n");
+    this_player()->restore_spell_points(50);
+
+BEMERKUNGEN:
+    Da das Benutzen der Funktion eine Heilung bedeutet, sollte man bei
+    Verwendung auf jeden Fall Ruecksprache mit seinem RM nehmen, bzw
+    die Heilstelle bei der Heilungsbalance genehmigen lassen.
+
+    Bei Heilstellen sollte eine evtl. Heilung des Spielers mit der eigens
+    dafuer eingerichteten Funktion check_and_update_timed_key realisiert
+    werden.
+    Ansonsten bitte buffer_sp() benutzen und die Konzeptseite lesen!
+
+SIEHE AUCH:
+    Gegenpart:	reduce_spell_points(L)
+    Verwandt:	buffer_sp(L), restore_hit_points(L)
+    Props:	P_SP
+    Konzept:	heilung
+
+23.Feb.2004 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/save_me b/doc/lfun/save_me
new file mode 100644
index 0000000..d7f9e0a
--- /dev/null
+++ b/doc/lfun/save_me
@@ -0,0 +1,21 @@
+save_me(L)
+FUNKTION:
+    void save_me(mixed value_items)
+
+DEFINIERT IN:
+    /std/player/base.c
+
+ARGUMENTE:
+    value_items
+       Ungleich 0, wenn Wert der Gegenstaende berechnet werden soll.
+
+BESCHREIBUNG:
+    Speichert einen Spieler, seine Autoloader, bestimmt sein GuildRating
+    und berechnet/speichert auf Anforderung den Wert der getragenen
+    Gegenstaende.
+
+SIEHE AUCH:
+    Props:       P_CARRIED_VALUE, P_AUTOLOADOBJ, P_LAST_LOGOUT
+    Kommandos:   save, ende
+
+1.September 2008 Gloinson
diff --git a/doc/lfun/second_life b/doc/lfun/second_life
new file mode 100644
index 0000000..b5abfd5
--- /dev/null
+++ b/doc/lfun/second_life
@@ -0,0 +1,30 @@
+second_life()
+
+FUNKTION:
+	varargs int second_life(object obj);
+
+DEFINIERT IN:
+	/std/player/life.c
+
+ARGUMENTE:
+	obj
+	  Leiche des Lebewesens.
+
+BESCHREIBUNG:
+        Diese Funktion wird im die() des Lebewesens aufgerufen, wenn sicher
+        ist, dass es stirbt. Ueblicherweise ist diese Funktion nur im Spieler
+        definiert und regelt EP-Verlust und dergleichen. Ein Shadow wuerde
+        diese Funktion ueberlagern, um zu verhindern, dass ein Spieler stirbt.
+
+RUeCKGABEWERT:
+        1, wenn das Lebewesen nicht stirbt, sonst 0
+
+BEMERKUNG:
+        Bei NPCs sollte man direkt die() ueberschreiben, wenn man nicht
+        moechte, dass sie sterben.
+
+SIEHE AUCH:
+        die()
+
+----------------------------------------------------------------------------
+Last modified: 2015-Jan-19, Arathorn 
diff --git a/doc/lfun/sell_obj b/doc/lfun/sell_obj
new file mode 100644
index 0000000..8c362f1
--- /dev/null
+++ b/doc/lfun/sell_obj
@@ -0,0 +1,52 @@
+sell_obj()

+

+Funktion:

+    static string sell_obj(object ob, int short)

+

+Definiert in:

+    /std/room/shop

+

+Argumente:

+    ob:

+      Das anzukaufende Objekt

+    short:

+      Gibt an, ob der Verkaeufer nur ein Objekt (0) oder mehrere (1) 

+      verkauft. (Verkaufe alles etc.)

+

+Beschreibung:

+    Ermittelt ob der Laden bereit ist, <ob> anzukaufen.

+

+Rueckgabewert:

+    Meldung die ausgegeben wird, wenn ein Objekt abgelehnt wird oder 0.

+

+Bemerkung:

+    Man sollte im normalfall _niemals_ einfach 0 zurueckgeben, sondern das 

+    geerbte sell_obj() aus /std/room/shop, damit beispielsweise P_NOBUY 

+    beachtet wird.

+

+Beispiel:

+    Ein Schmied, der nur Waffen ankauft:

+    

+    protected void create()

+    {

+      ...

+    }

+    

+    static string sell_obj(object ob, int short)

+    {

+      if(!ob->QueryProp(P_WEAPON_TYPE))

+      {

+        return "Ich bin nur an Waffen interessiert.";

+      }

+      return ::sell_obj(ob,short);

+    }

+

+Siehe auch:

+    Funktionen:

+      AddFixedObject(), RemoveFixedObject(), SetStorageRoom(), 

+      QueryStorageRoom(), QueryBuyValue(), QueryBuyFact(), buy_obj()

+    Properties:

+      P_KEEPER, P_MIN_STOCK, P_STORE_CONSUME

+

+------------------------------------------------------------------------------

+Letzte Aenderung: 21.05.2014, Bugfix

diff --git a/doc/lfun/set_object_next_reset b/doc/lfun/set_object_next_reset
new file mode 100644
index 0000000..68dfa2f
--- /dev/null
+++ b/doc/lfun/set_object_next_reset
@@ -0,0 +1,25 @@
+set_object_next_reset()
+
+FUNKTION:
+	int set_object_next_reset(object ob, int zeit );
+
+DEFINIERT IN: /secure/debug.c
+
+ARGUMENTE:
+	ob: Das Objekt, dess Reset gesetzt werden soll.
+  zeit: Zeit bis zum naechsten Reset von ob.
+
+FUNKTION:
+  Die Funktion ruft letztendlich set_next_reset() in <ob> auf und setzt daher
+  dessen Resetzeit auf einen neuen Wert. Dies ist zu Debugzwecken gedacht.
+
+  Die Benutzung ist nur fuer EM+ moeglich.
+
+RUECKGABEWERT:
+	Gibt den Rueckgabewert des set_next_reset()-Aufrufs in <ob> zurueck.
+
+SIEHE AUCH:
+	set_next_reset(E)
+
+10.10.2007, Zesstra
+
diff --git a/doc/lfun/shoot_dam b/doc/lfun/shoot_dam
new file mode 100644
index 0000000..5d82d02
--- /dev/null
+++ b/doc/lfun/shoot_dam
@@ -0,0 +1,40 @@
+shoot_dam()
+
+FUNKTION:
+    static int shoot_dam(mapping shoot)
+
+DEFINIERT IN:
+    /std/ranged_weapon.c
+
+ARGUMENTE:
+    mapping shoot - Schussdaten
+
+BESCHREIBUNG:
+    Erhaelt von /std/ranged_weapon::cmd_shoot() die Schussdaten und berechnet
+    den Schaden der Waffe, basierend auf den P_SHOOTING_WC von Waffe und
+    Munition sowie der Geschicklichkeit des Schuetzen. HitFuncs der Munition
+    und Skills werden hier ebenfalls beruecksichtigt.
+
+RUECKGABEWERT:
+    Schaden. Ebenfalls in 'shoot' unter SI_SKILLDAMAGE aktualisiert.
+
+BEMERKUNGEN:
+    'shoot' enthaelt normalerweise folgende Eintraege:
+    * Key P_WEAPON:       die Schusswaffe
+    * Key P_WEAPON_TYPE:  P_AMMUNITION, also die Munitions-ID
+    * Key P_STRETCH_TIME: P_STRETCH_TIME der Waffe
+    * Key P_WC:           P_SHOOTING_WC der Waffe
+    * Key P_SHOOTING_WC:  P_SHOOTING_WC der Munition
+    * Key P_AMMUNITION:   Munitionsobjekt (eventuell Unit)
+    * Key SI_ENEMY:       gueltigen Gegner
+    * Key SI_SKILLDAMAGE_TYPE:  Schaden (aus P_DAM_TYPE der Munition)
+    * Key SI_SKILLDAMAGE_MSG/2: Munitionsname
+
+SIEHE AUCH:
+    Generell:  P_AMMUNITION, P_SHOOTING_WC, P_STRETCH_TIME
+    Methoden:  FindRangedTarget(L), cmd_shoot(L)
+    Skills:    UseSkill(L), SkillResTransfer(L)
+    Attribute: QueryAttribute
+    Sonstiges: fernwaffen, HitFunc
+
+28.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/short b/doc/lfun/short
new file mode 100644
index 0000000..a9734c2
--- /dev/null
+++ b/doc/lfun/short
@@ -0,0 +1,31 @@
+short()
+FUNKTION:
+     public varargs string short();
+
+DEFINIERT IN:
+     /std/thing/description.c
+
+ARGUMENTE:
+     keine
+
+BESCHREIBUNG:
+     Der Inhalt der Property P_SHORT wird ausgewertet, mit ".\n"
+     abgeschlossen und zurueckgegeben.
+
+RUeCKGABEWERT:
+     Die Kurzbeschreibung als String oder 0, falls das Objekt unsichtbar
+     ist.
+
+BEMERKUNGEN:
+     Durch Ueberladen von short() lassen sich noch weitere Eigenschaften des
+     Objektes zeigen. Fackeln zeigen zum Beispiel an, ob sie brennen,
+     Ruestungen, ob sie angezogen sind und Waffen, ob sie gezueckt sind.
+
+SIEHE AUCH:
+     Aehnliches:	long()
+     Properties:	P_SHORT, P_INVIS
+     Sonstiges:		make_invlist()
+
+----------------------------------------------------------------------------
+20.01.2015, Zesstra
+
diff --git a/doc/lfun/show_notify b/doc/lfun/show_notify
new file mode 100644
index 0000000..ae09adc
--- /dev/null
+++ b/doc/lfun/show_notify
@@ -0,0 +1,44 @@
+give_notify()
+FUNKTION:
+     void show_notify(object obj)
+
+DEFINIERT IN:
+     /std/living/put_and_get.c
+
+ARGUMENTE:
+     obj - dem Lebewesen gezeigtes Objekt
+
+RUeCKGABEWERT:
+     keiner
+
+BESCHREIBUNG:
+     Diese Funktion wird automatisch immer dann aufgerufen, wenn einem
+     Lebewesen (welches kein Spielercharakter ist) ein Objekt gezeigt wird.
+     Dies funktioniert nur dann, wenn der Standardbefehl der Spielershell
+     verwendet wird ("zeige <name> <gegenstand>"). Selbstgebautes "zeige"
+     funktioniert nicht.
+
+BEISPIEL:
+     Oftmals will man in Quests erreichen, dass einem NPC ein bestimmtes
+     Item als Beweis der Erfuellung einer bestimmten Aufgabe vorgezeigt
+     wird. Folgendermassen kann dies realisiert werden:
+
+     void quest_ok(object obj) { ...
+       // z.B. Vernichtung des Questobjektes und Questtexte
+       // Questbelohnung und Questanerkennung, etc.
+     }
+
+     void show_notify(object obj) {
+       if(obj->id("\nquestitem")) // Ist das das geforderte Questobjekt?
+         quest_ok(obj);
+     }
+
+BEMERKUNGEN:
+     Da es nur um das Vorzeigen von Gegenstaenden geht, die nicht den 
+     Besitzer wechseln, sind Mechanismen wie P_REJECT in diesem Fall 
+     nicht erforderlich.
+
+SIEHE AUCH:
+     give_notify(), /std/npc/put_and_get.c, /std/living/put_and_get.c
+
+22. Oktober 2013 Arathorn
diff --git a/doc/lfun/spellbook/AddSpell b/doc/lfun/spellbook/AddSpell
new file mode 100644
index 0000000..78686d1
--- /dev/null
+++ b/doc/lfun/spellbook/AddSpell
@@ -0,0 +1,54 @@
+AddSpell()
+FUNKTION:
+    varargs int AddSpell(string verb, int kosten, mixed ski) 
+
+DEFINIERT IN:
+    /std/spellbook.c
+
+ARGUMENTE:
+    string verb     Name des Spells
+    int kosten      normale Kosten (Grundkosten)
+    mixed ski       Skillmapping mit allen Eintraegen zum Spell
+
+BESCHREIBUNG:
+    Addiert einen Eintrag fuer den Spell im Spellbook. Wenn dieser
+    Spell direkt vom Spieler (SI_SPELLBOOK) oder (normalerweise)
+    ueber ein Gildenobjekt aufgerufen wird, wird das Mapping auf
+    die Skillinformationen aus Spieler und Gilde addiert und
+    beeinflusst damit den Aufruf der letztlichen Spellfunktion.
+
+BEMERKUNGEN:
+    Siehe das Verhalten von QuerySpell (gilde) zum Zusammenfuegen
+    der AddSpell-Informationen aus Gilde und Spellbook. Relevant
+    zB fuer Lernrestriktionen.
+
+BEISPIEL:
+    AddSpell("kampfschrei", 30,
+         ([SI_SKILLRESTR_LEARN:([P_LEVEL:13]),
+           SI_MAGIC_TYPE: ({MT_PSYCHO}),
+           SI_SPELL:      ([
+             SP_NAME: "Kampfschrei",
+             SP_SHOW_DAMAGE:
+               ({({ -1, "Dir geschieht jedoch nichts.",
+                   "@WEM1 geschieht jedoch nichts.",
+                   "@WEM1 geschieht jedoch nichts." }),
+                 ({  0, "Du kannst darueber aber nur lachen.",
+                   "@WER1 kann darueber aber nur lachen.",
+                   "@WER1 kann darueber aber nur lachen." }),
+                 ({ 10, "Dir droehnen die Ohren.",
+                   "@WEM1 droehnen die Ohren.",
+                   "@WEM1 droehnen die Ohren." })
+               })])
+         ]));
+
+SIEHE AUCH:
+    Spellbook Lernen: Learn, SpellSuccess, Erfolg, Misserfolg
+    * Verwalten:      QuerySpell
+    * Angriff:        TryAttackSpell, TryDefaultAttackSpell,
+                      TryGlobalAttackSpell
+    * Properties:     P_GLOBAL_SKILLPROPS, P_SB_SPELLS
+    Skills Lernen:    LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:        UseSpell, UseSkill
+    * sonstig:        spruchermuedung, skill_info_liste
+
+5. Okt 2011 Gloinson
diff --git a/doc/lfun/spellbook/Erfolg b/doc/lfun/spellbook/Erfolg
new file mode 100644
index 0000000..625bf4f
--- /dev/null
+++ b/doc/lfun/spellbook/Erfolg
@@ -0,0 +1,28 @@
+Erfolg()
+FUNKTION:
+    void Erfolg(object caster, string spell, mapping sinfo)
+
+DEFINIERT IN:
+    /std/spellbook.c
+
+ARGUMENTE:
+    object caster    Spell sprechender Spieler
+    string spell     Spellname
+    mapping sinfo    Spell-Info-Mapping mit allen Informationen
+
+BESCHREIBUNG:
+    Wird bei Erfolg eines Spells gerufen. Ruft SpellInform() am
+    Environment.
+
+SIEHE AUCH:
+    Sonstiges:        SpellInform
+    Spellbook Lernen: Learn, SpellSuccess, Misserfolg
+    * Verwalten:      AddSpell, QuerySpell
+    * Angriff:        TryAttackSpell, TryDefaultAttackSpell,
+                      TryGlobalAttackSpell
+    * Properties:     P_GLOBAL_SKILLPROPS, P_SB_SPELLS
+    Skills Lernen:    LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:        UseSpell, UseSkill
+    * sonstig:        spruchermuedung, skill_info_liste
+
+5. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/spellbook/Learn b/doc/lfun/spellbook/Learn
new file mode 100644
index 0000000..4e2431a
--- /dev/null
+++ b/doc/lfun/spellbook/Learn
@@ -0,0 +1,33 @@
+Learn()
+FUNKTION:
+    void Learn(object caster, string spell, mapping sinfo)
+
+DEFINIERT IN:
+    /std/spellbook.c
+
+ARGUMENTE:
+    object caster   Derjenige, der den Spruch spricht.
+    string spell    Der gesprochene Spell
+    mapping sinfo   Mapping mit allen moeglichen Informationen zum Spell
+
+BESCHREIBUNG:
+    Diese Funktion wird von der Funktion "Misserfolg" aus dem 
+    Spellbook aufgerufen. Hier lernt der Spieler den Spruch, der 
+    nicht geglueckt ist.
+
+BEMERKUNGEN:
+    Kann auch ueberschrieben werden, wenn man komplexe Lern-Aenderungen
+    vornehmen will. Andere Attribute sind ueber SI_LEARN_ATTRIBUTE
+    setzbar.
+
+SIEHE AUCH:
+    Spellbook Lernen: SpellSuccess, Erfolg, Misserfolg
+    * Verwalten:      AddSpell, QuerySpell
+    * Angriff:        TryAttackSpell, TryDefaultAttackSpell,
+                      TryGlobalAttackSpell
+    * Properties:     P_GLOBAL_SKILLPROPS, P_SB_SPELLS
+    Skills Lernen:    LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:        UseSpell, UseSkill
+    * sonstig:        spruchermuedung, skill_info_liste
+
+5. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/spellbook/Misserfolg b/doc/lfun/spellbook/Misserfolg
new file mode 100644
index 0000000..7ad530b
--- /dev/null
+++ b/doc/lfun/spellbook/Misserfolg
@@ -0,0 +1,53 @@
+Misserfolg()
+FUNKTION:
+    void Misserfolg(object caster, string spell, mapping sinfo) 
+
+DEFINIERT IN:
+    /std/spellbook.c
+
+ARGUMENTE:
+    object caster    Spell sprechender Spieler
+    string spell     Spellname
+    mapping sinfo    Spell-Info-Mapping mit allen Informationen
+
+BESCHREIBUNG:
+    Wird bei Misserfolg eines Spells im Spellbook aufgerufen und
+    ruft die Lernfunktion Learn() nach einer Fehlermeldung.
+    
+    Kann ueberschrieben werden, um die Meldungen anzupassen.
+
+BEISPIEL:
+    // Misserfolge im Klerus mit angepassten Meldungen
+    void Misserfolg(object caster, string spell, mapping sinfo) {
+      switch(spell) {
+        case "begrabe":
+          tell_object(caster, BS(
+            "Du begraebst Deine Hoffnungen, dass Du diese Anrufung jemals "
+            "perfekt beherrschen wirst."));
+          tell_room(environment(caster),
+            caster->Name(WER)+" tritt die Leiche lustlos.\n", ({caster}));
+          break;
+        case "blitz":
+        [...]
+      }
+        
+      int old_abil = sinfo[SI_SKILLABILITY];
+      Learn(caster, spell, sinfo);
+      int new_abil = caster->QuerySkillAbility(spell);
+      if (old_abil < new_abil)
+        tell_object(caster, "Die Goetter schenken Dir eine Erleuchtung.\n");
+      else
+        tell_object(caster, "Leider lernst Du nicht aus Deinem Fehler.\n"); 
+    }
+
+SIEHE AUCH:
+    Spellbook Lernen: Learn, SpellSuccess, Erfolg
+    * Verwalten:      AddSpell, QuerySpell
+    * Angriff:        TryAttackSpell, TryDefaultAttackSpell,
+                      TryGlobalAttackSpell
+    * Properties:     P_GLOBAL_SKILLPROPS, P_SB_SPELLS
+    Skills Lernen:    LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:        UseSpell, UseSkill
+    * sonstig:        spruchermuedung, skill_info_liste
+
+5. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/spellbook/QuerySpell b/doc/lfun/spellbook/QuerySpell
new file mode 100644
index 0000000..0cadec2
--- /dev/null
+++ b/doc/lfun/spellbook/QuerySpell
@@ -0,0 +1,26 @@
+QuerySpell()
+FUNKTION:
+    mapping QuerySpell(string spell)
+
+DEFINIERT IN:
+    /std/spellbook.c
+
+ARGUMENTE:
+    string spell    Name des Spells
+
+BESCHREIBUNG:
+    Gibt das Spellmapping aus P_SB_SPELLS fuer diesen Spell zurueck.
+    
+    Hier enthaelt QuerySpell nur die Spellbook-Informationen.
+
+SIEHE AUCH:
+    Spellbook Lernen: Learn, SpellSuccess, Erfolg, Misserfolg
+    * Verwalten:      AddSpell
+    * Angriff:        TryAttackSpell, TryDefaultAttackSpell,
+                      TryGlobalAttackSpell
+    * Properties:     P_GLOBAL_SKILLPROPS, P_SB_SPELLS
+    Skills Lernen:    LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:        UseSpell, UseSkill
+    * sonstig:        spruchermuedung, skill_info_liste
+
+5. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/spellbook/SpellSuccess b/doc/lfun/spellbook/SpellSuccess
new file mode 100644
index 0000000..ec44884
--- /dev/null
+++ b/doc/lfun/spellbook/SpellSuccess
@@ -0,0 +1,31 @@
+SpellSuccess()
+FUNKTION:
+    int SpellSuccess(object caster, mapping sinfo)
+
+DEFINIERT IN:
+    /std/spellbook.c
+
+ARGUMENTE:
+    object caster    Spell sprechender Spieler
+    mapping sinfo    Spell-Info-Mapping mit allen Informationen
+
+BESCHREIBUNG:
+    Berechnet den Erfolg der Anwendung eines Spells aus seiner
+    SI_SKILLABILITY und dem Skill SK_CASTING im Spieler. Laesst
+    den Spieler bei besonders gutem Gelingen SK_CASTING lernen.
+
+BEMERKUNGEN:
+    SK_CASTING muss fuer die SK_CASTING-Boni beherrscht werden.
+    Das ist zB im Klerus ab bestimmtem Level der Fall.
+
+SIEHE AUCH:
+    Spellbook Lernen: Learn, Erfolg, Misserfolg
+    * Verwalten:      AddSpell, QuerySpell
+    * Angriff:        TryAttackSpell, TryDefaultAttackSpell,
+                      TryGlobalAttackSpell
+    * Properties:     P_GLOBAL_SKILLPROPS, P_SB_SPELLS
+    Skills Lernen:    LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:        UseSpell, UseSkill
+    * sonstig:        spruchermuedung, skill_info_liste
+
+5. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/lfun/spellbook/TryAttackSpell b/doc/lfun/spellbook/TryAttackSpell
new file mode 100644
index 0000000..76d75b8
--- /dev/null
+++ b/doc/lfun/spellbook/TryAttackSpell
@@ -0,0 +1,48 @@
+** gilden-doku
+ o TryAttackSpell(opfer,schaden,typen,is_spell,caster,info)
+   Versucht den Angriffs-Spruch auf den Gegner anzuwenden. Die
+   mittleren 4 Werte sind die, die auch bei Defend uebergeben werden.
+   Dabei wird die Abwehrfaehigkeit des Gegners gegen Magie und das
+   Skill-Attribut SA_DAMAGE automatisch beruecksichtigt. 
+
+FUNKTION:
+
+int TryAttackSpell(object victim, int damage, mixed dtypes,
+                   mixed is_spell, object caster, mapping sinfo)
+
+
+ARGUMENTE:
+
+        victim   : Das arme Opfer.
+        damage   : Der Schaden.
+        dtypes   : Die Schadensarten.
+	      is_spell : Ist es ein Spell? Werden noch Spezielle Parameter 
+	           uebergeben (als mapping) ?
+        caster   : Derjenige, der den Spruch spricht.
+        sinfo    : Mapping mit allen moeglichen Informationen zum Spell
+
+
+BESCHREIBUNG:
+
+	Diese Funktion wird vom Spellbook aufgerufen, wenn der Spieler
+	einen Angriffsspell gemacht hat und damit Schaden anrichten will.
+
+
+RUECKGABEWERT:
+
+	Der Wert, der vom Defend() des Gegners zurueckgeliefert wird.
+
+
+BEMERKUNGEN:
+
+	Zu erst wird ueberprueft, ob das Ziel ueberhaupt angreifbar ist. Dies
+	verhindert das ueben von Spells an unangreifbaren NPCs.
+	Als naechstes wird die Faehigkeit, Spells abzuwehren ueberprueft.
+	Falls beide Abfragen ok sind, wird Defend aufgerufen.
+
+
+Siehe auch:
+
+TryDefaultAttackSpell (to be written)
+------------------------------------------------------------------------------
+07.10.2007, Zesstra
diff --git a/doc/lfun/trigger_sensitive_attack b/doc/lfun/trigger_sensitive_attack
new file mode 100644
index 0000000..129b38c
--- /dev/null
+++ b/doc/lfun/trigger_sensitive_attack
@@ -0,0 +1,75 @@
+trigger_sensitive_attack()
+
+FUNKTION:
+     varargs void trigger_sensitive_attack(object enemy, string key, int
+     dam, mixed spell, mixed *options);
+
+DEFINIERT IN:
+     eigenen sensitiven Objekten, wird aufgerufen von
+     /std/living/inventory.c
+
+ARGUMENTE:
+     enemy
+          Der Gegner, der die Aktion ausgeloest hat.
+     key
+          Der ausloesende Schadenstyp.
+     dam
+          Der angerichtete Schaden.
+     spell
+          Wie bei Defend().
+     options
+          Array mit den in P_SENSITIVE angegebenen Optionen fuer diese
+          Aktion.
+
+BESCHREIBUNG:
+     Wenn der bei einem Angriff zugefuegte Schaden den in P_SENSITIVE
+     angegebenen Grenzwert uebersteigt sowie der als Schluessel angegebene
+     Schadenstyp in den Schaedenstypen des Angriffes vorkommt, wird diese
+     Funktion aufgerufen und kann entsprechend reagieren.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+     Eine Fackel, die sich bei Feuerattacken selbst entzuendet und bei
+     Wasserattacken verloescht, koennte man wie folgt implementieren:
+
+     inherit "/std/lightsource.c"
+
+     #include <properties.h>
+     #include <sensitive.h>
+     #include <combat.h>
+
+     create()
+     {
+       ::create();
+
+       SetProp(...); // die ueblichen Eigenschaften definieren
+
+       SetProp(P_SENSITIVE,
+           //  Ereignis          Key       Grenze (keine Optionen)
+         ({ ({ SENSITIVE_ATTACK, DT_FIRE,  100 }),
+            ({ SENSITIVE_ATTACK, DT_WATER, 100 }) }) );
+     }
+
+     varargs void
+     trigger_sensitive_attack(object enemy, string key,
+                              int dam, mixed spell)
+     {
+       // Es soll nicht verschwiegen werden, dass das Entzuenden und
+       // Loeschen einer Lichtquelle so leider nicht funktioniert...
+       if (key == DT_FIRE && !QueryProp(P_LIGHTED)) {
+         SetProp(P_LIGHTED, 1);
+         tell_object(environment(), "Die Fackel faengt Feuer.\n");
+       }
+       else if (key == DT_WATER && QueryProp(P_LIGHTED)) {
+         SetProp(P_LIGHTED, 0);
+         tell_object(environment(), "Die Fackel verlischt.\n");
+       }
+     }
+
+SIEHE AUCH:
+     trigger_sensitive_inv(), sensitive Objekte
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 15:56:25 1996 by Wargon
diff --git a/doc/lfun/trigger_sensitive_inv b/doc/lfun/trigger_sensitive_inv
new file mode 100644
index 0000000..a417ebe
--- /dev/null
+++ b/doc/lfun/trigger_sensitive_inv
@@ -0,0 +1,40 @@
+trigger_sensitive_inv()
+
+FUNKTION:
+     varargs void trigger_sensitive_inv(object ob, string key, int wert,
+     mixed *optionen1, mixed *optionen2);
+
+DEFINIERT IN:
+     eigenen Objekten, wird aufgerufen von /std/container/inventory.c
+
+ARGUMENTE:
+     ob
+          Das ausloesende Objekt
+     key
+          Der Schluessel, der die Aktion ausloeste.
+     wert
+          Der Grenzwert des ausloesenden Objektes.
+     optionen1
+          Die Optionen des ausloesenden Objektes.
+     optionen2
+          Die Optionen des reagierenden Objektes.
+
+BESCHREIBUNG:
+     Diese Funktion wird in Objekten des sensitiven Typs SENSITIVE_INVENTORY
+     aufgerufen, wenn sie in Kontakt mit Objekten des Typs
+     SENSITIVE_INVENTORY_TRIGGER treten, die den gleichen Schluessel
+     aufweisen und einen hoeheren Grenzwert haben.
+
+     Anhand der Parameter koennen dann die noetigen Aktionen ausgeloest
+     werden.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+
+SIEHE AUCH:
+     trigger_sensitive_attack(), sensitive Objekte
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:26:10 1996 by Wargon
diff --git a/doc/lfun/wield_me b/doc/lfun/wield_me
new file mode 100644
index 0000000..427504e
--- /dev/null
+++ b/doc/lfun/wield_me
@@ -0,0 +1,10 @@
+wield_me()
+
+BEMERKUNGEN:
+     wield_me wurde durch DoWield ersetzt.
+
+SIEHE AUCH:
+     DoWieldFunc(), /std/weapon.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Apr 08 10:25:00 2004 by Muadib
diff --git a/doc/libhooks/H_HOOK_EXIT_USE b/doc/libhooks/H_HOOK_EXIT_USE
new file mode 100644
index 0000000..e4e4e53
--- /dev/null
+++ b/doc/libhooks/H_HOOK_EXIT_USE
@@ -0,0 +1,30 @@
+HOOK: 
+   H_HOOK_EXIT_USE
+
+DEFINIERT IN:
+   /sys/hook.h
+
+GERUFEN VON:
+   /std/room/exits.c
+
+BESCHREIBUNG:
+   Wird ausgeloest, wenn ein Lebewesen einen Raumausgang benutzt.
+
+EVENT-DATEN:
+   Es wird ein Array uebergeben:
+   ({ <verb>, <destroom>, <message> })
+      <verb>     : eingegebenes Kommandoverb
+      <destroom> : Zielraum (string) oder closure
+      <message>  : Bewegungsmeldung (ggf. 0)
+
+RUeCKGABEWERTE:
+   ({ <status>, <daten> })
+      <status>  : H_NO_MOD, H_CANCELLED, H_ALTERED
+      <daten>   : wie uebergebenes Datenarray
+
+SIEHE AUCH:
+   HRegisterToHook(), HUnregisterFromHook(), HookFlow()
+
+-----------------------------------------------------------------------------
+7.2.2016, Zesstra
+
diff --git a/doc/libhooks/H_HOOK_HP b/doc/libhooks/H_HOOK_HP
new file mode 100644
index 0000000..e80791f
--- /dev/null
+++ b/doc/libhooks/H_HOOK_HP
@@ -0,0 +1,28 @@
+HOOK:
+   H_HOOK_HP
+
+DEFINIERT IN:
+   /sys/hook.h
+
+AUSGELOeST VON:
+   /std/living/life.c
+
+BESCHREIBUNG:
+   Wird ausgeloest, wenn sich die P_HP eines Spielers aendern.
+   Dieser Hook laeuft nach der Aenderung der Lebenspunkte. Es ist nicht
+   moeglich, diesen Hook abzubrechen oder die Lebenspunkte zu aendern.
+
+EVENT-DATEN:
+   Es werden die neuen Lebenspunkte des Spielers uebergebe.
+
+RUeCKGABEWERTE:
+   ({ <status>, <daten> })
+      <status>  : H_NO_MOD
+      <daten>   : Lebenspunkte
+
+SIEHE AUCH:
+   HRegisterToHook(), HUnregisterFromHook(), HookFlow()
+
+-----------------------------------------------------------------------------
+7.2.2016, Zesstra
+
diff --git a/doc/libhooks/H_HOOK_SP b/doc/libhooks/H_HOOK_SP
new file mode 100644
index 0000000..c64f98e
--- /dev/null
+++ b/doc/libhooks/H_HOOK_SP
@@ -0,0 +1,27 @@
+HOOK:
+   H_HOOK_SP
+
+DEFINIERT IN:
+   /sys/hook.h
+
+AUSGELOeST VON:
+   /std/living/life.c
+
+BESCHREIBUNG:
+   Wird ausgeloest, wenn sich die P_SP eines Spielers aendern.
+   Dieser Hook laeuft nach der Aenderung der Konzentrationspunkte. Es ist
+   nicht moeglich, diesen Hook abzubrechen oder die Lebenspunkte zu aendern.
+
+EVENT-DATEN:
+   Es werden die neuen Konzentrationspunkte des Spielers uebergeben.
+
+RUeCKGABEWERTE:
+   ({ <status>, <daten> })
+      <status>  : H_NO_MOD
+      <daten>   : Konzentrationspunkte
+
+SIEHE AUCH:
+   HRegisterToHook(), HUnregisterFromHook(), HookFlow()
+
+-----------------------------------------------------------------------------
+7.2.2016, Zesstra
diff --git a/doc/master/compile_object b/doc/master/compile_object
new file mode 100644
index 0000000..1b55658
--- /dev/null
+++ b/doc/master/compile_object
@@ -0,0 +1,11 @@
+SYNOPSIS
+	object compile_object(string filename)
+
+DESCRIPTION
+	This function is caled if the interpreter cannot find the
+	file for an object to be loaded. The master object has now
+	the opportunity to return an object that will then serve as if
+	compiled from the given filename.
+
+	If 0 is returned, the usual ``Could not load descr for'' error
+	will occur.
diff --git a/doc/master/connect b/doc/master/connect
new file mode 100644
index 0000000..a1c7315
--- /dev/null
+++ b/doc/master/connect
@@ -0,0 +1,13 @@
+SYNOPSIS
+	object connect(void)
+
+DESCRIPTION
+	Return a login object that the requested connection should be
+	bound to. Note that the connection is not bound yet.
+
+	The lfun logon() will be applied to the login object after
+	binding the connection to it. That lfun has to return != 0 to
+	indicate success.
+
+SEE ALSO
+	logon(A), disconnect(M), interactive(E), exec(E)
diff --git a/doc/master/dangling_lfun_closure b/doc/master/dangling_lfun_closure
new file mode 100644
index 0000000..6bfaeb5
--- /dev/null
+++ b/doc/master/dangling_lfun_closure
@@ -0,0 +1,26 @@
+SYNOPSIS
+	void dangling_lfun_closure()
+
+DESCRIPTION
+	Handle a dangling lfun-closure.
+
+	This is called when the gamedriver executes a closure using a
+	vanished lfun. A proper handling is to raise a runtime error.
+
+	Technical:
+	  Upon replacing programs (see efun replace_program()), any
+	  existing lambda closures of the object are adjusted to the
+	  new environment. If a closure uses a lfun which vanished in
+	  the replacement process, the reference to this lfun is
+	  replaced by a reference to this function. The error will
+	  then occur when the execution of the adjusted lambda reaches
+	  the point of the lfun reference. There are two reasons for
+	  the delayed handling. First is that the program replacement
+	  and with it the closure adjustment happens at the end of a
+	  backend cycle, outside of any execution thread: noone would
+	  see the error at this time.  Second, smart closures might
+	  know/recognize the program replacement  and skip the call to
+	  the vanished lfun.
+
+SEE ALSO
+	closures(LPC)
diff --git a/doc/master/disconnect b/doc/master/disconnect
new file mode 100644
index 0000000..f7a9f3d
--- /dev/null
+++ b/doc/master/disconnect
@@ -0,0 +1,13 @@
+SYNOPSIS
+	void disconnect(object ob)
+
+DESCRIPTION
+	Handle the loss of the IP connection for the (formerly)
+	interactive object ob. The connection can be lost because the
+	the underlying transport connection was lost (``netdead''), or
+	because of a call to exec() or remove_interactive(). The
+	connection will be unbound upon return from this call.
+
+SEE ALSO
+	connect(M), remove_player(M), remove_interactive(E), exec(E),
+	interactive(E)
diff --git a/doc/master/epilog b/doc/master/epilog
new file mode 100644
index 0000000..eb51d75
--- /dev/null
+++ b/doc/master/epilog
@@ -0,0 +1,24 @@
+SYNOPSIS
+	void epilog(void)		/* compat in 3.2 */
+	string *epilog(int eflag)	/* !compat or 3.2.1 */
+
+DESCRIPTION
+	Perform final actions before opening the system to users.
+	The semantics of this function differ for compat and !compat
+	mode, and between 3.2 and 3.2.1.
+
+	Compat in 3.2: the objects from the INIT_FILE (#defined to
+	"room/init_file" at compile time in the parser) are already
+	loaded at this time. Normally there is nothing left to do for
+	this function.
+
+	!Compat and 3.2.1: the argument is the number of -e options that were
+	given to the parser on the commandline. Normally it is just 0
+	or 1. The function should return an array of strings, which
+	traditionally denote the objects to be preloaded with
+	master->preload(). Any other return value is interpreted as
+	``no object to preload''. The resulting strings will be passed
+	one at a time as arguments to preload().
+
+SEE ALSO	
+	preload(M), master(M)
diff --git a/doc/master/external_master_reload b/doc/master/external_master_reload
new file mode 100644
index 0000000..57913f0
--- /dev/null
+++ b/doc/master/external_master_reload
@@ -0,0 +1,10 @@
+SYNOPSIS
+	void external_master_reload()
+
+DESCRIPTION
+	Master was reloaded on external request by SIGUSR1.
+	It will be called after inaugurate_master() of course.
+	If you plan to do additional magic here, you're welcome.
+
+SEE ALSO
+	inaugurate_master(M)
diff --git a/doc/master/flag b/doc/master/flag
new file mode 100644
index 0000000..e04e91d
--- /dev/null
+++ b/doc/master/flag
@@ -0,0 +1,41 @@
+SYNOPSIS
+	void flag(string arg)
+
+DESCRIPTION
+	Evaluate an argument given as option '-f' to the driver.
+	If several '-f' options are given, this function will be
+	called sequentially with all given arguments.
+	This function can be used to pass the master commands via
+	arguments to the driver. This is useful when building a new
+	mudlib from scratch. It is called only when the system is
+	started.
+
+EXAMPLE
+	// The code given implements these commands:
+	//  '-fcall <ob> <fun> <arg>': call function <fun> in object <ob> with
+	//				argument <arg>.
+	//  '-fshutdown': shutdown the system immediately.
+	// Thus, starting the driver as
+	//	 'parse "-fcall foo bar Yow!" -fshutdown' would
+	// first do foo->bar("Yow!") and then shut down the system.
+
+	{
+	  string obj, fun, rest;
+
+	  if (arg == "shutdown")
+	  {
+	    shutdown();
+	    return;
+	  }
+	  if (sscanf(arg, "call %s %s %s", obj, fun, rest) >= 2)
+	  {
+	    write(obj+"->"+fun+"(\""+rest+"\") = ");
+	    write(call_other(obj, fun, rest));
+	    write("\n");
+	    return;
+	  }
+	  write("master: Unknown flag "+arg+"\n");
+	}
+
+SEE ALSO
+	master(M)
diff --git a/doc/master/get_bb_uid b/doc/master/get_bb_uid
new file mode 100644
index 0000000..5a4dc8b
--- /dev/null
+++ b/doc/master/get_bb_uid
@@ -0,0 +1,18 @@
+SYNOPSIS
+	string get_bb_uid(void)
+
+DESCRIPTION
+	Is called to get the ``backbone id''. Objects whose creator is
+	the backbone id are ``trusted'', and will automagically get
+	the uid and euid of the object that caused to load or clone
+	them.
+
+	The backbone id is also temporary given to objects while being
+	called via process_string().
+
+HISTORY
+	Since 3.2.1, get_bb_uid() is needed just for process_string()
+	if no this_object() is present.
+
+SEE ALSO
+	uids(C), creator_file(M), creator(E), get_root_id(M)
diff --git a/doc/master/get_ed_buffer_save_file_name b/doc/master/get_ed_buffer_save_file_name
new file mode 100644
index 0000000..50a23c3
--- /dev/null
+++ b/doc/master/get_ed_buffer_save_file_name
@@ -0,0 +1,22 @@
+SYNOPSIS
+	string get_ed_buffer_save_object_name(string edited_file)
+
+DESCRIPTION
+	This function is called when an interactive user object is
+	destructed or looses connection through remove_interactive()
+	while editing with ed() the file edite_file (emergency save).
+	this_player() is set to the object that loosing connection.
+	The function should return a file name for the emergency save
+	file.
+
+EXAMPLE
+	string get_ed_buffer_save_object_name(string file) {
+	  return "/players/"+getuid(this_player())+"/.dead_ed_files/"
+		 + explode(file, "/")[<1];
+	}
+
+	This breaks up file into its components and stores it in the
+	user's emergency save directory under the file's basename.
+
+SEE ALSO
+	ed(E), destruct(E), remove_interactive(E), valid_write(M)
diff --git a/doc/master/get_master_uid b/doc/master/get_master_uid
new file mode 100644
index 0000000..a0c6737
--- /dev/null
+++ b/doc/master/get_master_uid
@@ -0,0 +1,12 @@
+SYNOPSIS
+	string get_master_uid(void)
+
+DESCRIPTION
+	Return the string to be used as root-uid.
+	Under !native, the function is expendable.
+
+HISTORY
+	Introduced in 3.2.1@40 replacing get_root_uid().
+
+SEE ALSO
+	get_bb_uid(M), get_master_uid(M), uids(C), creator_file(M), creator(E)
diff --git a/doc/master/get_simul_efun b/doc/master/get_simul_efun
new file mode 100644
index 0000000..88adba0
--- /dev/null
+++ b/doc/master/get_simul_efun
@@ -0,0 +1,24 @@
+SYNOPSIS
+	mixed get_     simul_efun(void)      // 3.2
+	string|string* get_simul_efun(void)  // 3.2.1
+
+DESCRIPTION
+	Load the simul_efun object(s) and return one or more paths of it.
+// Note that the object(s) must be loaded by this function!
+//
+// When you return an array of strings, the first string is taken as path
+// to the simul_efun object, and all other paths are used for backup
+// simul_efun objects to call simul_efuns that are not present in the
+// main simul_efun object. This allows to remove simul_efuns at runtime 
+// without getting errors from old compiled programs that still use the 
+// obsolete simul_efuns. A side use of this mechanism is to provide 
+// a 'spare' simul_efun object in case the normal one fails to load.
+//
+	Should return either the object_name of the simul_efun object as
+	a string, or an array containing as first element a string
+	with the file name of the simul_efun object and the following
+	elements strings with file names of alternate simul_efun
+	objects that will be used if the first one cannot be loaded.
+
+SEE ALSO
+	simul_efun(C)
diff --git a/doc/master/get_wiz_name b/doc/master/get_wiz_name
new file mode 100644
index 0000000..6056965
--- /dev/null
+++ b/doc/master/get_wiz_name
@@ -0,0 +1,13 @@
+SYNOPSIS
+	string get_wiz_name(string file)
+
+DESCRIPTION
+	Argument is a file name, which we want to get the owner of.
+	This used for the wizlist, to determine who gets the score for
+	the file being used.
+
+	For 3.2.1, it is used only to score errors to the right wizard.
+
+SEE ALSO
+	wizlist(E), get_wiz_info(E), query_real_name(A),
+	query_creator(M), getuid(E)
diff --git a/doc/master/handle_external_signal b/doc/master/handle_external_signal
new file mode 100644
index 0000000..6fe81ef
--- /dev/null
+++ b/doc/master/handle_external_signal
@@ -0,0 +1,26 @@
+SYNOPSIS
+        #include <signals.h>
+
+        int handle_external_signal(int signal)
+
+DESCRIPTION
+        If the driver receives a signal from the OS it forwards it to the
+        mudlib master by calling this function. The signal received by the
+        driver is given in <signal> and may be one of the following:
+        SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2.
+
+        If this function returns != 0, the driver will assume the signal has
+        been dealt with and take NO further action.
+        The exception is SIGTERM, which can't be handled. The driver will
+        perform a graceful shutdown of the game after this function returns.
+
+        If the master does not handle the signal (returns 0 or this function
+        doe not exit), the driver will perform the following default actions:
+
+        SIGHUP:  begin a graceful shutdown
+        SIGINT:  send itself an unhandled SIGINT. This usually causes an
+                 immediate and non-graceful shutdown.
+        SIGUSR1: the driver will reload the master object
+        SIGUSR2: the driver will re-open its debug log file
+                 (this will happen the next time the driver writes to it)
+
diff --git a/doc/master/heart_beat_error b/doc/master/heart_beat_error
new file mode 100644
index 0000000..d4d15f2
--- /dev/null
+++ b/doc/master/heart_beat_error
@@ -0,0 +1,24 @@
+SYNOPSIS
+	mixed heart_beat_error(object culprit, string err, string prg,
+			       string curobj, int line)
+
+DESCRIPTION
+	This function is called when a runtime error occurs while
+	executing the heart_beat() function of the object culprit. prg
+	is program where the actual error happened, in object curobj
+	at the given line.
+
+	At time of call, the heart_beat has been turned off.
+	Return anything != 0 to restart the heart_beat in culprit.
+
+	If culprit is a user, it should at least get the message ``You
+	have no heartbeat''. A more advanced handling would destruct
+	the offending object curobj and and allow the heartbeat to
+	restart.
+
+	Note that prg denotes the program actually executed (which
+	might be an inherited one) whereas curobj is just the
+	offending object.
+
+SEE ALSO
+	set_heart_beat(E), heart_beat(A), runtime_error(M)
diff --git a/doc/master/inaugurate_master b/doc/master/inaugurate_master
new file mode 100644
index 0000000..85c9526
--- /dev/null
+++ b/doc/master/inaugurate_master
@@ -0,0 +1,30 @@
+SYNOPSIS
+	void inaugurate_master(int arg)
+
+DESCRIPTION
+	This function is called in the master object after it has been
+	created and is fully functional. Note that the create()
+	function is of little use in the master object, because at the
+	time it is called there is no simul_efun object yet, and the
+	interpreter does not know anything about the user-ids and
+	access permissions.
+
+	The argument <arg> denotes why this function is called:
+	  arg = 0: the mud just started, this is the first master of all.
+	      = 1: the master was destructed and then reactivated
+	           (because a new one couldn't be loaded).
+	      = 2: the master was destructed and then reactivated, but
+	           additionally lost all variable contents.
+	      = 3: this is a reloaded master.
+
+	This function has at least to set up the driverhooks to use
+	(in 3.2.1). Also, any mudwho or wizlist handling has to be
+	initialized here.
+
+	Besides that, do whatever you feel you need to do, 
+	e.g. set_auto_include_string(), or give the master a decent euid.
+
+SEE ALSO
+	initialisation(M), create(M), simul_efun(C), get_bb_id(M),
+	get_root_id(M), get_master_uid(M), flag(M),
+	reactivate_destructed_master(M)
diff --git a/doc/master/include_file b/doc/master/include_file
new file mode 100644
index 0000000..68568ee
--- /dev/null
+++ b/doc/master/include_file
@@ -0,0 +1,32 @@
+SYNOPSIS
+        mixed include_file (string file, string compiled_file, int sys_include)
+
+DESCRIPTION
+        Generate the pathname of an included file.
+
+        Arguments:
+          previous_object(): The object causing the compile.
+          file             : The name given in the #include directive.
+          compiled_file    : The object file which is just compiled.
+                             (compat: name given without leading "/")
+          sys_include      : TRUE for #include <> directives.
+
+        Result:
+          0: use the normal include filename generation (""-includes are
+             used as they are, <>-includes are handled according to
+             H_INCLUDE_DIRS).
+
+          <path>: the full absolute pathname of the file to include,
+                  without parentdir parts ("/../"). Leading slashes ("/")
+                  may be omitted.
+
+          else: The include directive is not legal.
+
+        If the function does not generate a valid pathname, the driver
+        will next try to resolve the include using the H_INCLUDE_DIRS hook.
+
+HISTORY
+        Introduced in LDMud 3.2.8.
+
+SEE ALSO
+        hooks(C), inherit_file(M), include_dirs(H)
diff --git a/doc/master/inherit_file b/doc/master/inherit_file
new file mode 100644
index 0000000..7914fac
--- /dev/null
+++ b/doc/master/inherit_file
@@ -0,0 +1,26 @@
+SYNOPSIS
+        mixed inherit_file (string file, string compiled_file)
+
+DESCRIPTION
+        Generate the pathname of an inherited object.
+
+        Arguments:
+          previous_object(): The object causing the compile.
+          file             : The name given in the inherit directive.
+          compiled_file    : The object file which is just compiled.
+                             (compat: name given without leading "/")
+
+        Result:
+          0: use the given filename as it is.
+
+          <path>: the full absolute pathname of the file to inherit,
+                  without parentdir parts ("/../"). Leading slashes ("/")
+                  are ignored.
+
+          else: The inherit directive is not legal.
+
+HISTORY
+        Introduced in LDMud 3.2.8.
+
+SEE ALSO
+        hooks(C), include_file(M)
diff --git a/doc/master/initialisation b/doc/master/initialisation
new file mode 100644
index 0000000..e08d34a
--- /dev/null
+++ b/doc/master/initialisation
@@ -0,0 +1,16 @@
+SYNOPSIS
+	Initialization of the master object (since 3.2.1).
+
+	As since 3.2.1 the lfuns which are called to initialize
+	objects after a load are defined through driver hooks, and
+	these hooks are cleared prior to a master (re)load, the first
+	function called is inaugurate_master(). Anyway it's not very
+	sensible to do anything earlier as the master is not
+	recognized as such at that time, and so a number of
+	(important) things would not work.
+	Which lfun is called during runtime to reset the master is also
+	depending on the driverhook settings. Arbitrary actions may be done
+	on a reset.
+
+SEE ALSO
+	inaugurate_master(M)
diff --git a/doc/master/log_error b/doc/master/log_error
new file mode 100644
index 0000000..afc3385
--- /dev/null
+++ b/doc/master/log_error
@@ -0,0 +1,11 @@
+SYNOPSIS
+	void log_error(string file, string err)
+
+DESCRIPTION
+	Announce a compiler-time error in the named file. Whenever the
+	LPC compiler detects an error, this function is called. It
+	should at least log the error in a file, and also announce it
+	to the active user.
+
+SEE ALSO
+	runtime_error(M)
diff --git a/doc/master/make_path_absolute b/doc/master/make_path_absolute
new file mode 100644
index 0000000..e0a0019
--- /dev/null
+++ b/doc/master/make_path_absolute
@@ -0,0 +1,10 @@
+SYNOPSIS
+	string make_path_absolute(string str)
+
+DESCRIPTION
+	Absolutize a relative filename str given to the editor. Should
+	return the full pathname of the file to use. Any non-string
+	result will act as ``bad file name''.
+
+SEE ALSO
+	ed(E), valid_write(M)
diff --git a/doc/master/master b/doc/master/master
new file mode 100644
index 0000000..7d88855
--- /dev/null
+++ b/doc/master/master
@@ -0,0 +1,30 @@
+NAME
+	master
+
+DESCRIPTION
+	This directory contains descriptions for the functions that
+	Amylaar's version of the LPC parser, expects to find in the
+	master object (similar to lfuns, but for the master object
+	only). The name of the master object is hardcoded in the
+	parser (to "secure/master").
+
+	The master is the gateway between the interpreter and the
+	mudlib to perform actions with mudlib specific effects. Calls
+	to the master by the interpreter have an automatic catch() in
+	effect.
+
+	Note that the master is loaded first of all objects. Thus you
+	shouldn't inherit an other object, nor is the compiler able to
+	search include files (read: they must be specified with full
+	path).
+
+	Amylaar says: actually, you can inherit, but the file will be
+	loaded then before the master, which isn't good for most
+	files.
+
+	Refer to 'master-3.2' and 'master-3.2.1' for the surveys of
+	the masters internals. 
+
+SEE ALSO
+	master-3.2(M), master-3.2.1(M)
+	efun(E), applied(A), concepts(C), driver(D), lpc(LPC)
diff --git a/doc/master/master-3.2 b/doc/master/master-3.2
new file mode 100644
index 0000000..b55a931
--- /dev/null
+++ b/doc/master/master-3.2
@@ -0,0 +1,248 @@
+NAME
+	master for LPMud 3.2
+
+DESCRIPTION
+	This directory contains descriptions for the functions that
+	Amylaar's version of the LPC parser, expects to find in the
+	master object (similar to lfuns, but for the master object
+	only). The name of the master object is hardcoded in the
+	parser (to "secure/master").
+
+	The master is the gateway between the interpreter and the
+	mudlib to perform actions with mudlib specific effects. Calls
+	to the master by the interpreter have an automatic catch() in
+	effect.
+
+	Note that the master is loaded first of all objects. Thus you
+	shouldn't inherit an other object, nor is the compiler able to
+	search include files (read: they must be specified with full
+	path).
+
+	Amylaar says: actually, you can inherit, but the file will be
+	loaded then before the master, which isn't good for most
+	files.
+
+	A short survey of the things that happen at system startup
+	time:
+
+	The Initialisation functions are called after (re)loading the
+	master to establish the most basic operation parameters.
+
+	The initialisation of LPMud on startup follows this schedule:
+	  - The interpreter evaluates the commandline options and
+	    initializes itself.
+	  - The master is loaded, and thus it's create() (!compat only) and
+	    its reset() is called, though it's not much use, since
+	    most of the important things won't work already.
+	  - get_root_uid() is called. If the result is valid, it
+	    becomes the masters uid and euid.
+	  - get_bb_uid() is called.
+	  - inaugurate_master() is called.
+	  - flag() is called for each given '-f' commandline option.
+	  - get_simul_efun() is called.
+	  - define_include_dirs() is called.
+	  - Preloading is done:
+	      compat : The filenames of the objects are read from
+		       INIT_FILE and the objects are loaded. Then
+		       epilog() is called.
+	      !compat: epilog() is called. If it returns an array of
+		       strings, it is considered holding the filenames
+		       of the objects to preload. They are then given
+		       one at a time as argument to preload() which
+		       does the actual preloading.
+	  - The interpreter sets up the IP communication and enters
+	    the backend loop.
+
+	If the master is reloaded during system operation, this
+	actions are taken:
+	  - The master is loaded, and thus it's create() (!compat only) and
+	    its reset() is called.
+	  - Any auto-include string is cleared.
+	  - get_root_uid() is called. If the result is valid, it becomes the
+	    masters uid and euid.
+	  - inaugurate_master() is called.
+
+	If the master was destructed, but couldn't be reloaded, the old
+	master object could be reactivated. In that case:
+	  - reactivate_destructed_master() is called.
+	  - inaugurate_master() is called.
+
+
+	Security hint: most of this functions are not useful to be
+	called directly from other objects and can be made private or
+	static. Unlike create(), these functions that are applied to
+	the master object are found by the interpreter even if not
+	publicly accessible.
+
+
+
+	A short reference to all expected master functions...
+	----------------------------------------------------------------
+	    Initialisation
+
+	void create ()	// !compat
+	  Initialize the object. Not very useful, though.
+
+	void reset (int flag)  // !native
+	void reset ()	       // native
+	  Initialize (compat only) or reset the object.
+
+	void inaugurate_master ()
+	  Perform mudlib specific setup of the master.
+
+	void flag (string arg)
+	  Evaluate an argument given as option '-f' to the driver.
+
+	string *define_include_dirs ()
+	  Define where the include files are searched.
+
+	void	epilog ()	    // compat
+	string *epilog (int eflag)  // !compat
+	  Perform final actions before opening the system to users.
+	  The semantics of this function differ for compat and !compat mode.
+
+	void preload (string file)  // !compat
+	  Preload a given object.
+
+	void external_master_reload ()
+	  Called after a reload of the master on external request.
+
+	void reactivate_destructed_master (int removed)
+	  Reactivate a formerly destructed master.
+
+	string|string * get_simul_efun ()
+	  Load the simul_efun object and return one or more paths of it.
+
+	----------------------------------------------------------------
+	    Handling of user connections
+
+	object connect ()
+	  Handle the request for a new connection.
+
+	void disconnect (object obj)
+	  Handle the loss of an IP connection.
+
+	void remove_player (object user)
+	  Remove a user object from the system.
+
+	-----------------------------------------------------------------
+	    Runtime Support
+
+	object compile_object (string filename)
+	  Compile an virtual object.
+
+	string get_wiz_name (string file)
+	  Return the author of a file.
+
+	string object_name (object obj)
+	  Return a printable name for an object.
+
+	mixed prepare_destruct (object obj)
+	  Prepare the destruction of the given object.
+
+	void quota_demon (void)
+	  Handle quotas in times of memory shortage.
+
+	void receive_udp (string host, string msg)
+	  Handle a received IMP message.
+
+	void slow_shut_down (int minutes)
+	  Schedule a shutdown for the near future.
+
+	void notify_shutdown ()
+	  Notify the master about an immediate shutdown.
+
+	-----------------------------------------------------------------
+	    Error Handling
+
+	void dangling_lfun_closure ()
+	  Handle a dangling lfun-closure.
+
+	void log_error (string file, string err)
+	  Announce a compiler-time error.
+
+	mixed heart_beat_error (object culprit, string err,
+				string prg, string curobj, int line)
+	  Announce an error in the heart_beat() function.
+
+	void runtime_error (string err, string prg, string curobj, int line)
+	  Announce a runtime error.
+
+	-----------------------------------------------------------------
+	    Security and Permissions
+
+	int privilege_violation (string op, mixed who, mixed arg3, mixed arg4)
+	  Validate the execution of a privileged operation.
+
+	int query_allow_shadow (object victim)
+	  Validate a shadowing.
+
+	int query_player_level (string what)
+	  Check if the user is of high enough level for several things.
+
+	int valid_exec (string name)
+	  Validate the rebinding of an IP connection by usage of efun
+	  exec().
+
+	int valid_query_snoop (object obj)
+	  Validate if the snoopers of an object may be revealed by
+	  usage of the efun query_snoop().
+
+	int valid_snoop (object snoopee, object snooper)
+	  Validate the start/stop of a snoop.
+
+	------------------------------------------------------------------
+	    Userids and depending Security
+
+	string creator_file (mixed obj)
+	  Return the name of the creator of an object.
+	  This is called in every mode!
+
+	string get_root_uid ()	// !compat
+	  Return the string to be used as root-uid.
+
+	string get_bb_uid()  // !compat
+	  Return the string to be used as root-uid.
+
+	int valid_seteuid (object obj, string neweuid)	// !compat
+	  Validate the change of an objects euid by efun seteuid().
+
+	int|string valid_read (string path, string euid, string fun, object caller)
+	int|string valid_write (string path, string euid, string fun, object caller)
+	  Validate a reading/writing file operation.
+
+	-----------------------------------------------------------------
+	    ed() Support
+
+	string make_path_absolute (string str)
+	  Absolutize a relative filename given to the editor.
+
+	int save_ed_setup (object who, int code)
+	  Save individual settings of ed for a wizard.
+
+	int retrieve_ed_setup (object who)
+	  Retrieve individual settings of ed for a wizard.
+
+	string get_ed_buffer_save_object_name (string file)
+	  Return a filename for the ed buffer to be saved into.
+
+	----------------------------------------------------------------
+	    parse_command() Support  (!compat)
+
+	string *parse_command_id_list ()
+	  Return generic singular ids.
+
+	string *parse_command_plural_id_list ()
+	  Return generic plural ids.
+
+	string *parse_command_adjectiv_id_list ()
+	  Return generic adjective ids.
+
+	string *parse_command_prepos_list ()
+	  Return common prepositions.
+
+	string parse_command_all_word()
+	  Return the one(!) 'all' word.
+
+SEE ALSO
+	master(M), efun(E), applied(A), concepts(C), driver(D), lpc(LPC)
diff --git a/doc/master/master-3.2.1 b/doc/master/master-3.2.1
new file mode 100644
index 0000000..03e4339
--- /dev/null
+++ b/doc/master/master-3.2.1
@@ -0,0 +1,231 @@
+NAME
+	master for LPMud 3.2.1
+
+DESCRIPTION
+	This directory contains descriptions for the functions that
+	Amylaar's version of the LPC parser, expects to find in the
+	master object (similar to lfuns, but for the master object
+	only). The name of the master object is hardcoded in the
+	parser (to "secure/master").
+
+	The master is the gateway between the interpreter and the
+	mudlib to perform actions with mudlib specific effects. Calls
+	to the master by the interpreter have an automatic catch() in
+	effect.
+
+	Note that the master is loaded first of all objects. Thus you
+	shouldn't inherit an other object, nor is the compiler able to
+	search include files (read: they must be specified with full
+	path).
+
+	Amylaar says: actually, you can inherit, but the file will be
+	loaded then before the master, which isn't good for most
+	files.
+
+	A short survey of the things that happen at system startup
+	time:
+
+	The Initialisation functions are called after (re)loading the
+	master to establish the most basic operation parameters.
+
+	The initialisation of LPMud on startup follows this schedule:
+	  - The interpreter evaluates the commandline options and
+	    initializes itself.
+	  - The master is loaded, but since the driverhooks are not set yet,
+	    no standard initialisation lfun is called.
+	  - get_master_uid() is called. If the result is valid, it becomes the
+	  - inaugurate_master() is called.
+	  - flag() is called for each given '-f' commandline option.
+	  - get_simul_efun() is called.
+	  - the WIZLIST is read in.
+	  - epilog() is called. If it returns an array of strings,
+	    they are given one at a time as argument to preload().
+	    Traditionally, these strings are the filenames of the objects to
+	    preload, which preload() then does.
+	  - The interpreter sets up the IP communication and enters
+	    the backend loop.
+
+	If the master is reloaded during system operation, this
+	actions are taken:
+	  - The master is loaded, and its initialisation lfun is
+	    called according to the settings of the driverhooks (if set).
+	  - Any auto-include string and all driverhooks are cleared.
+	  - get_master_uid() is called. If the result is valid, it becomes the
+	    masters uid and euid.
+	  - inaugurate_master() is called.
+
+	If the master was destructed, but couldn't be reloaded, the old
+	master object could be reactivated. In that case:
+	  - reactivate_destructed_master() is called.
+	  - inaugurate_master() is called.
+
+
+	Security hint: most of this functions are not useful to be
+	called directly from other objects and can be made private or
+	static. Unlike create(), these functions that are applied to
+	the master object are found by the interpreter even if not
+	publicly accessible.
+
+
+
+	A short reference to all expected master functions...
+	----------------------------------------------------------------
+	    Initialisation
+
+	void inaugurate_master ()
+	  Perform mudlib specific setup of the master.
+
+	string get_master_uid ()
+	  Return the string to be used as uid (and -euid) of a
+	  (re)loaded master. 
+
+	void flag (string arg)
+	  Evaluate an argument given as option '-f' to the driver.
+
+	string *define_include_dirs ()
+	  Define where the include files are searched.
+
+	string *epilog (int eflag)
+	  Perform final actions before opening the system to users.
+
+	void preload (string file)
+	  Preload a given object.
+
+	void external_master_reload ()
+	  Called after a reload of the master on external request.
+
+	void reactivate_destructed_master (int removed)
+	  Reactivate a formerly destructed master.
+
+	string|string * get_simul_efun ()
+	  Load the simul_efun object and return one or more paths of it.
+
+	----------------------------------------------------------------
+	    Handling of user connections
+
+	object connect ()
+	  Handle the request for a new connection.
+
+	void disconnect (object obj)
+	  Handle the loss of an IP connection.
+
+	void remove_player (object user)
+	  Remove a user object from the system.
+
+	void stale_erq (closure callback)
+	  Notify the loss of the erq demon.
+
+	-----------------------------------------------------------------
+	    Runtime Support
+
+	object compile_object (string filename)
+	  Compile an virtual object.
+
+	string get_wiz_name (string file)
+	  Return the author of a file.
+
+	string object_name (object obj)
+	  Return a printable name for an object.
+
+	mixed prepare_destruct (object obj)
+	  Prepare the destruction of the given object.
+
+	void quota_demon (void)
+	  Handle quotas in times of memory shortage.
+
+	void receive_udp (string host, string msg, int port)
+	  Handle a received IMP message.
+
+	void slow_shut_down (int minutes)
+	  Schedule a shutdown for the near future.
+
+	void notify_shutdown ()
+	  Notify the master about an immediate shutdown.
+
+	-----------------------------------------------------------------
+	    Error Handling
+
+	void dangling_lfun_closure ()
+	  Handle a dangling lfun-closure.
+
+	void log_error (string file, string err)
+	  Announce a compiler-time error.
+
+	mixed heart_beat_error (object culprit, string err,
+				string prg, string curobj, int line)
+	  Announce an error in the heart_beat() function.
+
+	void runtime_error (string err, string prg, string curobj, int line)
+	  Announce a runtime error.
+
+	-----------------------------------------------------------------
+	    Security and Permissions
+
+	int privilege_violation (string op, mixed who, mixed arg3, mixed arg4)
+	  Validate the execution of a privileged operation.
+
+	int query_allow_shadow (object victim)
+	  Validate a shadowing.
+
+	int query_player_level (string what)
+	  Check if the user is of high enough level for several things.
+
+	int valid_exec (string name)
+	  Validate the rebinding of an IP connection by usage of efun
+	  exec().
+
+	int valid_query_snoop (object obj)
+	  Validate if the snoopers of an object may be revealed by
+	  usage of the efun query_snoop().
+
+	int valid_snoop (object snoopee, object snooper)
+	  Validate the start/stop of a snoop.
+
+	------------------------------------------------------------------
+	    Userids and depending Security
+
+	string get_bb_uid()  // euids
+	  Return the string to be used as root-uid.
+
+	int valid_seteuid (object obj, string neweuid)	// euids
+	  Validate the change of an objects euid by efun seteuid().
+
+	int|string valid_read (string path, string euid, string fun, object caller)
+	int|string valid_write (string path, string euid, string fun, object caller)
+	  Validate a reading/writing file operation.
+
+	-----------------------------------------------------------------
+	    ed() Support
+
+	string make_path_absolute (string str)
+	  Absolutize a relative filename given to the editor.
+
+	int save_ed_setup (object who, int code)
+	  Save individual settings of ed for a wizard.
+
+	int retrieve_ed_setup (object who)
+	  Retrieve individual settings of ed for a wizard.
+
+	string get_ed_buffer_save_object_name (string file)
+	  Return a filename for the ed buffer to be saved into.
+
+	----------------------------------------------------------------
+	    parse_command() Support  (!compat, SUPPLY_PARSE_COMMAND defined)
+
+	string *parse_command_id_list ()
+	  Return generic singular ids.
+
+	string *parse_command_plural_id_list ()
+	  Return generic plural ids.
+
+	string *parse_command_adjectiv_id_list ()
+	  Return generic adjective ids.
+
+	string *parse_command_prepos_list ()
+	  Return common prepositions.
+
+	string parse_command_all_word()
+	  Return the one(!) 'all' word.
+
+SEE ALSO
+	master(M), efun(E), applied(A), concepts(C), driver(D), lpc(LPC)
diff --git a/doc/master/notify_shutdown b/doc/master/notify_shutdown
new file mode 100644
index 0000000..d23cd98
--- /dev/null
+++ b/doc/master/notify_shutdown
@@ -0,0 +1,29 @@
+SYNOPSIS
+        varargs void notify_shutdown (string crash_reason)
+
+DESCRIPTION
+        Notify the master about an immediate shutdown. If <crash_reason> is 0,
+        it is a normal shutdown, otherwise it is a crash and <crash_reason>
+        gives a hint at the reason.
+
+        The function has the opportunity to perform any cleanup operation,
+        like informing the mudwho server that the mud is down. This can not be
+        done when remove_player() is called because the udp connectivity is
+        already gone then.
+
+        If the gamedriver shuts down normally , this is the last function
+        called before the mud shuts down the udp connections and the accepting
+        socket for new players.
+
+        If the gamedriver crashes, this is the last function called before the
+        mud attempts to dump core and exit. WARNING: Since the driver is in an
+        unstable state, this function may not be able to run to completion!
+        The following crash reasons are defined:
+          "Fatal Error": an internal sanity check failed.
+
+HISTORY
+        LDMud 3.2.9 added the <crash_reason> argument and that the function
+        is called for a crash at all.
+
+SEE ALSO
+        slow_shut_down(M), remove_player(M),
diff --git a/doc/master/object_name b/doc/master/object_name
new file mode 100644
index 0000000..2990b6d
--- /dev/null
+++ b/doc/master/object_name
@@ -0,0 +1,10 @@
+SYNOPSIS
+	string object_name(object ob)
+
+DESCRIPTION
+	Return a printable name for an object. This function is called
+	by sprintf() to print a meaningful name in addition to the
+	normal object_name().
+
+SEE ALSO
+	sprintf(E), object_name(E)
diff --git a/doc/master/parse_command_all_word b/doc/master/parse_command_all_word
new file mode 100644
index 0000000..b57ab05
--- /dev/null
+++ b/doc/master/parse_command_all_word
@@ -0,0 +1,9 @@
+SYNOPSIS
+	string *parse_command_all_word(void)
+
+DESCRIPTION
+	Used by parse_command(). Return the word for ``all'' in the
+	installations native language.
+
+SEE ALSO
+	parse_command(E)
diff --git a/doc/master/parse_command_prepos_list b/doc/master/parse_command_prepos_list
new file mode 100644
index 0000000..24706ce
--- /dev/null
+++ b/doc/master/parse_command_prepos_list
@@ -0,0 +1,9 @@
+SYNOPSIS
+	string *parse_command_prepos_list(void)
+
+DESCRIPTION
+	Used by parse_command(). Return an array of common
+	prepositions in the installations native language.
+
+SEE ALSO
+	parse_command(E)
diff --git a/doc/master/preload b/doc/master/preload
new file mode 100644
index 0000000..95f27d7
--- /dev/null
+++ b/doc/master/preload
@@ -0,0 +1,18 @@
+SYNOPSIS
+	void preload(string file)
+
+DESCRIPTION
+	Load the object with the given file name, that was returned by
+	epilog(). It is task of the epilog()/preload() pair to ensure
+	the validity of the given strings (e.g. filtering out comments
+	and blank lines). For preload itself a call_other(file, "???")
+	s sufficient, but it should be guarded by a catch() to avoid
+	premature blockings. Also it is wise to change the master's
+	euid from root_uid to something less privileged for the time
+	of the preload.
+
+	You can of course do anything else with the passed strings -
+	preloading is just the traditional task.
+
+SEE ALSO
+	epilog(M), master(M)
diff --git a/doc/master/prepare_destruct b/doc/master/prepare_destruct
new file mode 100644
index 0000000..3121b88
--- /dev/null
+++ b/doc/master/prepare_destruct
@@ -0,0 +1,22 @@
+SYNOPSIS
+	mixed prepare_destruct(object obj)
+
+DESCRIPTION
+	Prepare the destruction of the object obj. Return 0 if the
+	object is ready for destruction, any other value will abort
+	the attempt. If a string is returned, an error with the string
+	as message will be issued.
+
+	The interpreter calls this function whenever an object shall
+	be destructed. It expects, that this function cleans the
+	inventory of the object, or the destruct will fail.
+	Furthermore, the function could notify the former inventory
+	objects that their holder is under destruction (useful to move
+	users out of rooms which re updated); and it could announce
+	systemwide the destruction(quitting) of users.
+
+	Strange things will happen if the mastor object does not
+	provide this function.
+
+SEE ALSO
+	remove_player(M), destruct(E)
diff --git a/doc/master/privilege_violation b/doc/master/privilege_violation
new file mode 100644
index 0000000..957a4b9
--- /dev/null
+++ b/doc/master/privilege_violation
@@ -0,0 +1,63 @@
+SYNOPSIS
+	int privilege_violation(string op, mixed who, mixed arg3, mixed arg4)
+
+DESCRIPTION
+	Validate the execution of a privileged operation.
+	op denotes the requested operation, who is the object
+	requesting the operation (object_name or object pointer), arg3
+	and arg4 are additional arguments, depending on the operation.
+
+	The function should return >0 to grant the privilege, 0 to
+	indicate that the caller was probably misleaded and the error
+	might be fixed, and anything else to indicate a real
+	violation, that will be handled as run time error.
+
+	The privileged operations are:
+	attach_erq_demon  Attach the erq demon to object <arg> with
+	                  flag <args>. 
+	bind_lambda	  Bind a lambda-closure to object arg3.
+	call_out_info	  Return an array with all call_out
+			  informations.
+	nomask simul_efun Attempt to get an efun <arg> via efun:: when
+	                  it is shadowed by a nomask type simul_efun.
+	rename_object	  The object who tries to rename the object
+			  arg3 to the name arg4.
+	send_udp	  Send UDP-data to host arg3.
+	set_auto_include_string Set the string automatically included
+			  by the compiler into every object.
+	get_extra_wizinfo Get the additional wiz-list info for user
+			  arg3.
+	set_extra_wizinfo Set the additional wiz-list info for user
+			  arg3.
+	set_extra_wizinfo_size Set the size of the additional user
+			  info in the wiz-list to arg3.
+	set_driver_hook   : Set hook <arg> to <arg2>.
+	set_this_object	  Set this_object() to arg3.
+	shadow_add_action Add an action to function arg4 that is
+			  shadowed by the object arg3.
+	symbol_variable	  Attempt to make a symbol from a hidden
+			  inherited variable. arg3 is the object in
+			  question, arg4 the number of the variable in
+			  the variable table.
+	wizlist_info	  Return an array with all wiz-list
+			  information.
+
+	call_out_info() can return the arguments to functions and
+	lambda closures to be called by call_out(); you should
+	consider that read access to closures, mappings and arrays
+	means write access and/or other privileges. 
+	wizlist_info() will return an array which holds, among others,
+	the extra wizlist field. While a toplevel array, if found,
+	will be copied, this does not apply to nested arrays or to any
+	mappings. You might also have some sensitive closures there.
+	send_udp() should be watched as it could be abused to mess up
+	the IMP.
+	The xxx_extra_wizinfo operations are necessary for a proper
+	wizlist and should therefore be restricted to admins.
+	All other operations are potential sources for direct security
+	breaches - any use of them should be scrutinized closely.
+
+SEE ALSO	
+	simul_efun(C), call_out_info(E), shadow(E), add_action(E),
+	wizlist(E), set_this_object(E), rename_object(E),
+	bind_lambda(E), send_udp(E), set_auto_include_string(E)
diff --git a/doc/master/query_allow_shadow b/doc/master/query_allow_shadow
new file mode 100644
index 0000000..47d2e95
--- /dev/null
+++ b/doc/master/query_allow_shadow
@@ -0,0 +1,23 @@
+query_allow_shadow(M)
+FUNKTION:
+     int query_allow_shadow(object victim)
+
+DEFINITION:
+     /secure/master.c
+
+BESCHREIBUNG:
+     Gibt 1 zurueck, wenn das Objekt victim von previous_object() beschattet 
+     werden darf, 0 sonst.
+
+     Die Funktion prueft, ob das Objekt victim ein Root-Objekt ist, oder
+     ob es beim Aufruf von query_prevent_shadow() 1 zurueckgibt.
+
+BEMERKUNGEN:
+     Wird automatisch bei shadow() ausgefuehrt.
+
+SIEHE AUCH:
+     Rechte:	     query_prevent_shadow(L)
+     Generell:	     shadow(E), unshadow(E)
+     Informationen:  query_shadowing(E)
+
+20. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/master/query_player_level b/doc/master/query_player_level
new file mode 100644
index 0000000..484e18e
--- /dev/null
+++ b/doc/master/query_player_level
@@ -0,0 +1,15 @@
+SYNOPSIS
+	int query_player_level(string what)
+
+DESCRIPTION
+	Check if the user is of high enough level for several things.
+
+	The argument denotes the action for which permission is to be
+	checked:
+
+	"trace"		Is the user allowed to use tracing?
+	"inspect memory" Is the user allowed to issue the
+			special command "showsmallnewmalloced"? 
+
+SEE ALSO
+	trace(E), showsmallnewmalloced(D), malloc(D), status(D), memory(C)
diff --git a/doc/master/quota_demon b/doc/master/quota_demon
new file mode 100644
index 0000000..f7f8d95
--- /dev/null
+++ b/doc/master/quota_demon
@@ -0,0 +1,18 @@
+SYNOPSIS
+	void quota_demon(void)
+
+DESCRIPTION
+	Handle quotas in times of memory shortage.
+
+	This function is called during the final phase of a garbage
+	collection if the reserved user area couldn't be reallocated.
+	This function (or a called demon) has now the opportunity to
+	remove some (still active) objects from the system. If this does
+	not free enough memory to reallocate the user reserve,
+	slow_shut_down() will be called to start Armageddon.
+
+	Up to now, the wizlist lacks various informations needed to
+	detect the memory-hungriest users.
+
+SEE ALSO
+	slow_shut_down(M), wizlist(E)
diff --git a/doc/master/reactivate_destructed_master b/doc/master/reactivate_destructed_master
new file mode 100644
index 0000000..e90d2a1
--- /dev/null
+++ b/doc/master/reactivate_destructed_master
@@ -0,0 +1,15 @@
+SYNOPSIS
+	void reactivate_destructed_master(int flag)
+
+DESCRIPTION
+	This function is called in an already destructed master object
+	if no new master object could be loaded. flag will be 1 if the
+	old master object could be reclaimed form the list of objects
+	that were marked for destruction but not yet terminated. If
+	flag is 0, all variables of the object have been set to 0 and
+	must be re-initialized.
+
+	After this function, inaugurate_master() will be applied again.
+
+SEE ALSO
+	destruct(E), inaugurate_master(M), master(M)
diff --git a/doc/master/receive_udp b/doc/master/receive_udp
new file mode 100644
index 0000000..a1b58c5
--- /dev/null
+++ b/doc/master/receive_udp
@@ -0,0 +1,17 @@
+SYNOPSIS
+	void receive_udp(string host, string msg, int hostport)
+
+DESCRIPTION
+	Handle a received IMP message.
+
+	This function is called for every message received on the IMP
+	port. Usually it is passed on to some object that handles
+	inter mud communications.
+
+HISTORY
+	The 'hostport' argument was added in 3.2.1.
+
+SEE ALSO
+	send_udp(E), query_udp_port(E)
+
+29.10.2006 Zesstra
diff --git a/doc/master/remove_player b/doc/master/remove_player
new file mode 100644
index 0000000..b70a1fb
--- /dev/null
+++ b/doc/master/remove_player
@@ -0,0 +1,14 @@
+SYNOPSIS
+	void remove_player(object ob)
+
+DESCRIPTION
+	Remove an interactive user object ob from the system. This
+	function is called by the interpreter to expell remaining
+	users from the system on shutdown in a polite way. If this
+	functions fails to quit/destruct the user, he will be
+	destructed the hard way by the interpreter.
+
+	This function must not cause runtime errors.
+
+SEE ALSO
+	remove_interactive(E), slow_shut_down(M)
diff --git a/doc/master/retrieve_ed_setup b/doc/master/retrieve_ed_setup
new file mode 100644
index 0000000..4d92ef0
--- /dev/null
+++ b/doc/master/retrieve_ed_setup
@@ -0,0 +1,9 @@
+SYNOPSIS
+	int retrieve_ed_setup(object command_giver)
+
+DESCRIPTION
+	Should return an integer that gives the ed setup flags for the
+	user that is denoted by command_giver.
+
+SEE ALSO
+	save_ed_setup(M)
diff --git a/doc/master/runtime_error b/doc/master/runtime_error
new file mode 100644
index 0000000..d109df8
--- /dev/null
+++ b/doc/master/runtime_error
@@ -0,0 +1,16 @@
+SYNOPSIS
+	void runtime_error(string err, string prg, string curobj, int line)
+
+DESCRIPTION
+	This function has to announce a runtime error to the active
+	user. If the user has enough privileges, it might give him the
+	full error message together with the source line. Else it
+	should issue a decent message ("Your sensitive mind notices a
+	wrongness in the fabric of space").
+
+	Note that prg denotes the program actually executed (which
+	might be an inherited one) whereas curobj is just the
+	offending object.
+
+SEE ALSO
+	log_error(M), heart_beat_error(M), raise_error(E)
diff --git a/doc/master/runtime_warning b/doc/master/runtime_warning
new file mode 100644
index 0000000..80864ab
--- /dev/null
+++ b/doc/master/runtime_warning
@@ -0,0 +1,27 @@
+SYNOPSIS
+        void runtime_warning( string msg, string curobj, string prog, int line
+                            , int inside_catch)
+
+DESCRIPTION
+        This function is called to let the mudlib handle a runtime warning,
+        e.g. by logging it into a database.
+
+        <msg> is the warning message.
+        <curobj> is the name of the current object which caused the message
+              (the object itself might already be destructed), or 0 if there
+              is none.
+        <prog>, <line> determine the name of the program and the line where
+              the error occured if the current object exists, otherwise
+              they are 0.
+        <inside_catch> : != 0 if the warning occurs inside a catch().
+
+        The driver is limited to three nested warnings, to prevent
+        an endless recursion in case runtime_warning() itself causes
+        warnings.
+
+HISTORY
+        Introduced in LDMud 3.3.551.
+        LDMud 3.3.705 added the <inside_catch> argument.
+
+SEE ALSO
+        runtime_error(M)
diff --git a/doc/master/save_ed_setup b/doc/master/save_ed_setup
new file mode 100644
index 0000000..feaaf71
--- /dev/null
+++ b/doc/master/save_ed_setup
@@ -0,0 +1,33 @@
+SYNOPSIS
+	int save_ed_setup(object who, int code)
+
+DESCRIPTION
+	Save individual option settings of the builtin ed, encoded
+	into code, for the user denoted by who. These functions are
+	located in the master object so that the local gods can decide
+	what strategy they want to use. suggestions:
+	A setup file for every user.
+		advantages:	transparent to the user
+				independent of user count
+		disadvantage:	extra file access at ed invocation
+	An array in the master object, users are searched by member_array
+		advantage:	easy to implement
+		disadvantage:	performance degradation with high user counts
+	An AVL-tree to access users by name
+		advantage:	can fit any need
+		disadvantage:	hard to implement, will need more
+				overhead on small and medium
+				installations than it can ever make
+				good by lg(usercount) complexity
+	Dedicated flags in every user object.
+		advantages:	easy to implement
+				independent of user count
+				Will also work for nusers w/o file
+				access privileges.
+		disadvantage:	care has to be taken to avoid
+				collision with other uses of the flags
+				in the user object
+
+SEE ALSO
+	ed(E), retrieve_ed_setup(M), valid_write(M),
+	get_ed_buffer_save_object_name(M)
diff --git a/doc/master/slow_shut_down b/doc/master/slow_shut_down
new file mode 100644
index 0000000..9a7fe8d
--- /dev/null
+++ b/doc/master/slow_shut_down
@@ -0,0 +1,40 @@
+SYNOPSIS
+	void slow_shut_down(int minutes)
+
+DESCRIPTION
+	Schedule a shutdown for the near future. minutes is the
+	desired time in minutes till the shutdown:
+	 six, if just the user reserve has been put into use.
+	 one, if the (smaller) master reserve has been put into use as
+	      well.
+
+	The interpreter calls this function when it runs low on
+	memory. At this time, it has freed its reserve, but since it
+	won't last long, the interpreter needs to be shut down. The
+	delay is to give the users the opportunity to finish their
+	current tasks, but don't take the 'minutes' for granted, just
+	deduce the urgency from it. 
+	It is possible that the driver may reallocate some memory
+	after the function has been called, and then run again into a
+	low memory situation, calling this function again.
+	This function might load an 'Armageddon' object and tell it
+	what to do. It is the Armageddon object then which performs
+	the shutdown.
+
+	Technical: The memory handling of the interpreter includes
+	three reserved areas: user, system and master. All three are
+	there to insure that the system shuts down gracefully when the
+	memory runs out: the user area to give the users time to
+	quit normally, the others to enable emergency-logouts when the
+	user reserve is used up as well.
+	The areas are allocated at start of the interpreter, and
+	released when no more memory could be obtained from the host.
+	In such a case, one of the remaining areas is freed (so the
+	operation can continue a short while) and a garbage collection
+	is initiated. If the garbage collection recycles enough memory
+	(either true garbage or by the aid of the quota_demon) to
+	reallocate the areas, all is fine, else the system shut down
+	is invoked by a call to this function. 
+
+SEE ALSO
+	quota_demon(M), notify_shutdown(M), shutdown(E), malloc(D), memory(C)
diff --git a/doc/master/stale_erq b/doc/master/stale_erq
new file mode 100644
index 0000000..a05ca31
--- /dev/null
+++ b/doc/master/stale_erq
@@ -0,0 +1,17 @@
+SYNOPSIS
+	void stale_erq (closure callback)
+
+DESCRIPTION
+	Notify the loss of the erq demon.
+	Argument is the callback closure set for an erq request.
+
+	If the erq connection dies prematurely, the driver will call
+	this lfun for every pending request with set callback. This
+	function should notify the originating object that the answer
+	will never arrive. 
+
+HISTORY
+	Introduced in 3.2.1@61.
+
+SEE ALSO
+	erq(C)
diff --git a/doc/master/valid_exec b/doc/master/valid_exec
new file mode 100644
index 0000000..2c0b67b
--- /dev/null
+++ b/doc/master/valid_exec
@@ -0,0 +1,15 @@
+SYNOPSIS
+	int valid_exec(string name, object ob, object obfrom)
+
+DESCRIPTION
+	Validate the rebinding of an IP connection by usage of efun
+	exec(). Arguments are the <name> of the _program_ attempting
+	to rebind the connection, the object <ob> to receive the
+	connection, and the object <obfrom> giving the connection.
+	Note that the program name is not the object_name() of the
+	object, and has no leading slash.
+
+	Return 0 to disallow the action, any other value to allow it.
+
+SEE ALSO
+	exec(E)
diff --git a/doc/master/valid_query_snoop b/doc/master/valid_query_snoop
new file mode 100644
index 0000000..e92378a
--- /dev/null
+++ b/doc/master/valid_query_snoop
@@ -0,0 +1,12 @@
+SYNOPSIS
+	valid_query_snoop(object ob)
+
+DESCRIPTION
+	Should return 1 if previous_object() (the one that called the
+	efun query_snoop()) is allowed to query wether ob is being
+	snooped, 0 if not.
+
+	The master object is always allowed to use query_snoop().
+
+SEE ALSO
+	valid_snoop(M), query_snoop(E), snoop(E)
diff --git a/doc/master/valid_read b/doc/master/valid_read
new file mode 100644
index 0000000..2dafbae
--- /dev/null
+++ b/doc/master/valid_read
@@ -0,0 +1,32 @@
+SYNOPSIS
+	string valid_read(string path, string uid, string func, object ob)
+
+DESCRIPTION
+	This function is called to check if the object ob with the
+	user-id uid has read permissions for the file given by path
+	for the operation named by func. It should return 0 if
+	permission is denied, or the normalized path if permission is
+	granted. You can also return 1 to indicate that the path can
+	be used unchanged.
+
+	The returned pathname must not contain ``..'', a leading /
+	will be stripped by the interpreter.
+
+	Func denotes the efun call or other operation that caused
+	valid_read() to be called:
+	ed_start (check if the file to be edited is readable),
+	file_size,
+	get_dir,
+	print_file (efun cat()),
+	read_bytes,
+	read_file,
+	restore_object,
+	tail.
+
+	Note that this function is called in compat mode as well. If
+	you need to be compatible with the old 2.4.5-mudlib, redirect
+	these calls to the valid_read/valid_write in the user
+	object.
+
+SEE ALSO
+	valid_write(M), make_path_absolute(M)
diff --git a/doc/master/valid_seteuid b/doc/master/valid_seteuid
new file mode 100644
index 0000000..3afc0d2
--- /dev/null
+++ b/doc/master/valid_seteuid
@@ -0,0 +1,9 @@
+SYNOPSIS
+	int valid_seteuid(object ob, string newid)
+
+DESCRIPTION
+	Should return 1 if ob is allowed to set its euid to newid.
+	Objects are always allowed to set their euid to 0.
+
+SEE ALSO
+	seteuid(E), uids(C)
diff --git a/doc/master/valid_snoop b/doc/master/valid_snoop
new file mode 100644
index 0000000..5bff987
--- /dev/null
+++ b/doc/master/valid_snoop
@@ -0,0 +1,8 @@
+SYNOPSIS
+	int valid_snoop(object me, object you)
+
+DESCRIPTION
+	Should return 1 if me is allowed to snoop you, 0 if not.
+
+SEE ALSO
+	snoop(E), query_snoop(E), valid_query_snoop(M)
diff --git a/doc/master/valid_write b/doc/master/valid_write
new file mode 100644
index 0000000..31fe43b
--- /dev/null
+++ b/doc/master/valid_write
@@ -0,0 +1,33 @@
+SYNOPSIS
+	string valid_write(string path, string uid, string func, object ob)
+
+DESCRIPTION
+	This function is called to check if the object ob with the
+	user-id uid has write permissions to the file given by path
+	for the operation named by func. It should return 0 if
+	permission is denied, or the normalized path if permission is
+	granted. You can also return 1 to indicate that the path can
+	be used unchanged.
+
+	The returned pathname must not contain ``..'', a leading /
+	will be stripped by the interpreter.
+
+	Func denotes the efun call or other operation that caused
+	valid_write() to be called:
+	cindent,
+	do_rename (efun rename(), for the old and then for the new name),
+	ed_start (whenever the builtin ed tries to write to a file),
+	mkdir,
+	remove_file (efun rm()),
+	rmdir,
+	save_object,
+	write_bytes,
+	write_file.
+
+	Note that this function is called in compat mode as well. If
+	you need to be compatible with the old 2.4.5-mudlib, redirect
+	these calls to the valid_read/valid_write in the user
+	object.
+
+SEE ALSO
+	valid_read(M), make_path_absolute(M)
diff --git a/doc/materials/MatDB b/doc/materials/MatDB
new file mode 100644
index 0000000..6536585
--- /dev/null
+++ b/doc/materials/MatDB
@@ -0,0 +1,42 @@
+Der Master hat (erstmal) kein AddMaterial mehr. Neue Materialien werden jetzt
+ganz einfach durch eine neue Datei im Verzeichnis mit den Materialien und den
+Aufruf der Update()-Funktion in der Datenbank erzeugt. Das gleiche gilt fuer
+neue Materialgruppen.
+Nach einem Update sollte man den Materialheader und die Doku neu generieren
+und einspielen, damit alles schoen konsistent bleibt (anders als bisher).
+Das Format der Materialdateien schaut man sich am besten am Beispiel an.
+
+Die alten Funktionen des Masters existieren weiterhin. Es gibt ein paar neue,
+um abhaengige Files zu erzeugen und die Datenbank neu aufzubauen:
+
+----------------------------------------
+
+void Update()
+
+Erneutes Einlesen der Materialdaten. Das Einlesen passiert asynchron, falls es
+zu lange dauert. Nach Abschluss des Einlesens werden die neuen Daten aktiv.
+
+----------------------------------------
+
+vargargs void GenMatList(string filename)
+
+Generiert Datei mit registrierten Materialien fuer die Dokumentation. Falls
+kein Dateiname angegeben wird, wird "materialliste" verwendet.
+
+----------------------------------------
+
+vargargs void GenMatGroupList(string filename)
+
+Generiert Datei mit registrierten Materialgruppen fuer die
+Dokumentation. Falls kein Dateiname angegeben wird, wird "materialgruppen"
+verwendet.
+
+----------------------------------------
+
+vargargs void GenHeaderFile(string filename)
+
+Generiert Datei mit Definitionen der moeglichen Materialien und Gruppen. Der
+Inhalt entspricht der bisherigen /sys/thing/material.h.  Wenn kein Dateiname
+angegeben wird, wird "material.h" verwendet.
+
+----------------------------------------
\ No newline at end of file
diff --git a/doc/materials/groups/MATGROUP_ACIDIC b/doc/materials/groups/MATGROUP_ACIDIC
new file mode 100644
index 0000000..bcfb8e7
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_ACIDIC
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_ACIDIC
+
+Name:
+Saeuren
diff --git a/doc/materials/groups/MATGROUP_BASIC b/doc/materials/groups/MATGROUP_BASIC
new file mode 100644
index 0000000..5d5b208
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_BASIC
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_BASIC
+
+Name:
+Laugen
diff --git a/doc/materials/groups/MATGROUP_BIO b/doc/materials/groups/MATGROUP_BIO
new file mode 100644
index 0000000..b4ff899
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_BIO
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_BIO
+
+Name:
+biologische Materialien
diff --git a/doc/materials/groups/MATGROUP_CLOTH b/doc/materials/groups/MATGROUP_CLOTH
new file mode 100644
index 0000000..be4ed49
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_CLOTH
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_CLOTH
+
+Name:
+Stoffe
diff --git a/doc/materials/groups/MATGROUP_CONIFER_WOOD b/doc/materials/groups/MATGROUP_CONIFER_WOOD
new file mode 100644
index 0000000..75ff5b3
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_CONIFER_WOOD
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_CONIFER_WOOD
+
+Name:
+Nadelhoelzer
diff --git a/doc/materials/groups/MATGROUP_DEAD b/doc/materials/groups/MATGROUP_DEAD
new file mode 100644
index 0000000..89e33a7
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_DEAD
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_DEAD
+
+Name:
+Ueberreste von Lebewesen
diff --git a/doc/materials/groups/MATGROUP_DECIDUOUS_WOOD b/doc/materials/groups/MATGROUP_DECIDUOUS_WOOD
new file mode 100644
index 0000000..579c4dc
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_DECIDUOUS_WOOD
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_DECIDUOUS_WOOD
+
+Name:
+Laubhoelzer
diff --git a/doc/materials/groups/MATGROUP_DRUG b/doc/materials/groups/MATGROUP_DRUG
new file mode 100644
index 0000000..a59b232
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_DRUG
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_DRUG
+
+Name:
+Drogen und Heiltraenke
diff --git a/doc/materials/groups/MATGROUP_EATABLE b/doc/materials/groups/MATGROUP_EATABLE
new file mode 100644
index 0000000..354edd6
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_EATABLE
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_EATABLE
+
+Name:
+Essbares
diff --git a/doc/materials/groups/MATGROUP_ELECTRICAL b/doc/materials/groups/MATGROUP_ELECTRICAL
new file mode 100644
index 0000000..04d3bb6
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_ELECTRICAL
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_ELECTRICAL
+
+Name:
+geladene Materialien
diff --git a/doc/materials/groups/MATGROUP_ELEMENTAL b/doc/materials/groups/MATGROUP_ELEMENTAL
new file mode 100644
index 0000000..d923437
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_ELEMENTAL
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_ELEMENTAL
+
+Name:
+(altertuemliche) Elemente
diff --git a/doc/materials/groups/MATGROUP_EXPLOSIVE b/doc/materials/groups/MATGROUP_EXPLOSIVE
new file mode 100644
index 0000000..3f4d208
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_EXPLOSIVE
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_EXPLOSIVE
+
+Name:
+Sprengstoffe
diff --git a/doc/materials/groups/MATGROUP_FLEXIBLE b/doc/materials/groups/MATGROUP_FLEXIBLE
new file mode 100644
index 0000000..b91143d
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_FLEXIBLE
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_FLEXIBLE
+
+Name:
+biegsame Materialien
diff --git a/doc/materials/groups/MATGROUP_FLUID b/doc/materials/groups/MATGROUP_FLUID
new file mode 100644
index 0000000..13f74f6
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_FLUID
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_FLUID
+
+Name:
+Fluessigkeiten
diff --git a/doc/materials/groups/MATGROUP_GAS b/doc/materials/groups/MATGROUP_GAS
new file mode 100644
index 0000000..f1d2436
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_GAS
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_GAS
+
+Name:
+Gase
diff --git a/doc/materials/groups/MATGROUP_HERBAL b/doc/materials/groups/MATGROUP_HERBAL
new file mode 100644
index 0000000..047b408
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_HERBAL
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_HERBAL
+
+Name:
+pflanzliche Materialien
diff --git a/doc/materials/groups/MATGROUP_HOLY b/doc/materials/groups/MATGROUP_HOLY
new file mode 100644
index 0000000..8609c2c
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_HOLY
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_HOLY
+
+Name:
+heilige Materialien
diff --git a/doc/materials/groups/MATGROUP_INFLAMMABLE b/doc/materials/groups/MATGROUP_INFLAMMABLE
new file mode 100644
index 0000000..3e87537
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_INFLAMMABLE
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_INFLAMMABLE
+
+Name:
+entflammbare Materialien
diff --git a/doc/materials/groups/MATGROUP_INVIS b/doc/materials/groups/MATGROUP_INVIS
new file mode 100644
index 0000000..741baef
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_INVIS
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_INVIS
+
+Name:
+unsichtbare Materialien
diff --git a/doc/materials/groups/MATGROUP_JEWEL b/doc/materials/groups/MATGROUP_JEWEL
new file mode 100644
index 0000000..7aab392
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_JEWEL
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_JEWEL
+
+Name:
+Edelsteine
diff --git a/doc/materials/groups/MATGROUP_LIVING b/doc/materials/groups/MATGROUP_LIVING
new file mode 100644
index 0000000..6c02462
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_LIVING
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_LIVING
+
+Name:
+Lebewesen
diff --git a/doc/materials/groups/MATGROUP_MAGIC b/doc/materials/groups/MATGROUP_MAGIC
new file mode 100644
index 0000000..20b8287
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_MAGIC
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_MAGIC
+
+Name:
+Magisches
diff --git a/doc/materials/groups/MATGROUP_MAGNETIC b/doc/materials/groups/MATGROUP_MAGNETIC
new file mode 100644
index 0000000..d43c3b3
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_MAGNETIC
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_MAGNETIC
+
+Name:
+anziehende Materialien
diff --git a/doc/materials/groups/MATGROUP_METAL b/doc/materials/groups/MATGROUP_METAL
new file mode 100644
index 0000000..f3979af
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_METAL
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_METAL
+
+Name:
+Metalle
diff --git a/doc/materials/groups/MATGROUP_MINERAL b/doc/materials/groups/MATGROUP_MINERAL
new file mode 100644
index 0000000..31eda4c
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_MINERAL
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_MINERAL
+
+Name:
+Mineralien
diff --git a/doc/materials/groups/MATGROUP_MISC b/doc/materials/groups/MATGROUP_MISC
new file mode 100644
index 0000000..b19c7d9
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_MISC
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_MISC
+
+Name:
+verschiedene Materialien, die nicht naeher zugeordnet sind (als fest, fluessig, gasfoermig)
diff --git a/doc/materials/groups/MATGROUP_PAPER b/doc/materials/groups/MATGROUP_PAPER
new file mode 100644
index 0000000..f8ed507
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_PAPER
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_PAPER
+
+Name:
+Papieraehliches
diff --git a/doc/materials/groups/MATGROUP_POISONOUS b/doc/materials/groups/MATGROUP_POISONOUS
new file mode 100644
index 0000000..1f2e26c
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_POISONOUS
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_POISONOUS
+
+Name:
+Gifte
diff --git a/doc/materials/groups/MATGROUP_PRECIOUS_METAL b/doc/materials/groups/MATGROUP_PRECIOUS_METAL
new file mode 100644
index 0000000..3d0fb1a
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_PRECIOUS_METAL
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_PRECIOUS_METAL
+
+Name:
+Edelmetalle
diff --git a/doc/materials/groups/MATGROUP_RADIOACTIVE b/doc/materials/groups/MATGROUP_RADIOACTIVE
new file mode 100644
index 0000000..1f2be19
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_RADIOACTIVE
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_RADIOACTIVE
+
+Name:
+Unbeschreibliches
diff --git a/doc/materials/groups/MATGROUP_SOLID b/doc/materials/groups/MATGROUP_SOLID
new file mode 100644
index 0000000..3c01ddb
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_SOLID
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_SOLID
+
+Name:
+feste Materialien
diff --git a/doc/materials/groups/MATGROUP_STONE b/doc/materials/groups/MATGROUP_STONE
new file mode 100644
index 0000000..7a76e5c
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_STONE
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_STONE
+
+Name:
+Steine
diff --git a/doc/materials/groups/MATGROUP_TROPICAL_WOOD b/doc/materials/groups/MATGROUP_TROPICAL_WOOD
new file mode 100644
index 0000000..02fa072
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_TROPICAL_WOOD
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_TROPICAL_WOOD
+
+Name:
+Tropenhoelzer
diff --git a/doc/materials/groups/MATGROUP_UNHOLY b/doc/materials/groups/MATGROUP_UNHOLY
new file mode 100644
index 0000000..44d961b
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_UNHOLY
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_UNHOLY
+
+Name:
+daemonische Materialien
diff --git a/doc/materials/groups/MATGROUP_WOOD b/doc/materials/groups/MATGROUP_WOOD
new file mode 100644
index 0000000..5466d1d
--- /dev/null
+++ b/doc/materials/groups/MATGROUP_WOOD
@@ -0,0 +1,5 @@
+Gruppenid:
+MATGROUP_WOOD
+
+Name:
+Hoelzer
diff --git a/doc/materials/materials/MAT_ADAMANT b/doc/materials/materials/MAT_ADAMANT
new file mode 100644
index 0000000..ebb435c
--- /dev/null
+++ b/doc/materials/materials/MAT_ADAMANT
@@ -0,0 +1,20 @@
+Materialid:
+MAT_ADAMANT              "adamant"
+
+Name:
+"Adamant" "Adamants" "Adamant" "Adamant"
+
+Geschlecht:
+N
+
+Beschreibung:
+hartes Elfenmetall
+
+Erkennbarkeit:
+MAT_MISC_METAL:10
+MAT_ADAMANT
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_PRECIOUS_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_AGATE b/doc/materials/materials/MAT_AGATE
new file mode 100644
index 0000000..e5456c6
--- /dev/null
+++ b/doc/materials/materials/MAT_AGATE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_AGATE                "agate"
+
+Name:
+"Achat" "Achats" "Achat" "Achat"
+
+Geschlecht:
+M
+
+Beschreibung:
+Farbspiel
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:0
+MAT_QUARTZ:20
+MAT_AGATE
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_AIR b/doc/materials/materials/MAT_AIR
new file mode 100644
index 0000000..a9d4a80
--- /dev/null
+++ b/doc/materials/materials/MAT_AIR
@@ -0,0 +1,19 @@
+Materialid:
+MAT_AIR                  "air"
+
+Name:
+"Luft" "Luft" "Luft" "Luft"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_GAS:100
+MATGROUP_INVIS:100
+MATGROUP_ELEMENTAL:100
diff --git a/doc/materials/materials/MAT_ALCOHOL b/doc/materials/materials/MAT_ALCOHOL
new file mode 100644
index 0000000..4ef80d4
--- /dev/null
+++ b/doc/materials/materials/MAT_ALCOHOL
@@ -0,0 +1,18 @@
+Materialid:
+MAT_ALCOHOL              "alcohol"
+
+Name:
+"Alkohol" "Alkohols" "Alkohol" "Alkohol"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_ALUMINIUM b/doc/materials/materials/MAT_ALUMINIUM
new file mode 100644
index 0000000..ecb282d
--- /dev/null
+++ b/doc/materials/materials/MAT_ALUMINIUM
@@ -0,0 +1,20 @@
+Materialid:
+MAT_ALUMINIUM            "Al"
+
+Name:
+"Aluminium" "Aluminiums" "Aluminium" "Aluminium"
+
+Geschlecht:
+N
+
+Beschreibung:
+weich behandelt hart
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:15
+MAT_ALUMINIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_AMBER b/doc/materials/materials/MAT_AMBER
new file mode 100644
index 0000000..eca9ee0
--- /dev/null
+++ b/doc/materials/materials/MAT_AMBER
@@ -0,0 +1,22 @@
+Materialid:
+MAT_AMBER                "amber"
+
+Name:
+"Bernstein" "Bernsteins" "Bernstein" "Bernstein"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_JEWEL:100
+MATGROUP_BIO:100
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_AMETHYST b/doc/materials/materials/MAT_AMETHYST
new file mode 100644
index 0000000..86cdd53
--- /dev/null
+++ b/doc/materials/materials/MAT_AMETHYST
@@ -0,0 +1,21 @@
+Materialid:
+MAT_AMETHYST             "amethyst"
+
+Name:
+"Amethyst" "Amethysts" "Amethyst" "Amethyst"
+
+Geschlecht:
+M
+
+Beschreibung:
+violett (Quarz)
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:25
+MAT_AMETHYST
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_ANTIMON b/doc/materials/materials/MAT_ANTIMON
new file mode 100644
index 0000000..12311f7
--- /dev/null
+++ b/doc/materials/materials/MAT_ANTIMON
@@ -0,0 +1,20 @@
+Materialid:
+MAT_ANTIMON              "antimon"
+
+Name:
+"Antimon" "Antimons" "Antimon" "Antimon"
+
+Geschlecht:
+N
+
+Beschreibung:
+weich, sproede, silberweiss
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:15
+MAT_ANTIMON
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_AQUAMARINE b/doc/materials/materials/MAT_AQUAMARINE
new file mode 100644
index 0000000..e401412
--- /dev/null
+++ b/doc/materials/materials/MAT_AQUAMARINE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_AQUAMARINE           "aquamarine"
+
+Name:
+"Aquamarin" "Aquamarins" "Aquamarin" "Aquamarin"
+
+Geschlecht:
+M
+
+Beschreibung:
+blau
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:25
+MAT_AQUAMARINE
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_ARSENIC b/doc/materials/materials/MAT_ARSENIC
new file mode 100644
index 0000000..ef12eb7
--- /dev/null
+++ b/doc/materials/materials/MAT_ARSENIC
@@ -0,0 +1,21 @@
+Materialid:
+MAT_ARSENIC              "arsenic"
+
+Name:
+"Arsen" "Arsens" "Arsen" "Arsen"
+
+Geschlecht:
+N
+
+Beschreibung:
+giftiges Halbmetall
+
+Erkennbarkeit:
+MAT_SALT:50
+MAT_MISC_METAL:66
+MAT_ARSENIC
+
+Gruppenzugehoerigkeit:
+MATGROUP_POISONOUS:100
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_ASBESTOS b/doc/materials/materials/MAT_ASBESTOS
new file mode 100644
index 0000000..215b546
--- /dev/null
+++ b/doc/materials/materials/MAT_ASBESTOS
@@ -0,0 +1,20 @@
+Materialid:
+MAT_ASBESTOS             "asbestos"
+
+Name:
+"Asbest" "Asbests" "Asbest" "Asbest"
+
+Geschlecht:
+M
+
+Beschreibung:
+grauweiss
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_POISONOUS:100
+MATGROUP_MINERAL:100
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_ASH_WOOD b/doc/materials/materials/MAT_ASH_WOOD
new file mode 100644
index 0000000..531c1df
--- /dev/null
+++ b/doc/materials/materials/MAT_ASH_WOOD
@@ -0,0 +1,26 @@
+Materialid:
+MAT_ASH_WOOD             "ash_wood"
+
+Name:
+"Eschenholz" "Eschenholzes" "Eschenholz" "Eschenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+flexibel, magisch
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:15
+MAT_ASH_WOOD
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_MAGIC:100
+MATGROUP_BIO:100
+MATGROUP_HERBAL:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_ASPHALT b/doc/materials/materials/MAT_ASPHALT
new file mode 100644
index 0000000..8b03e4f
--- /dev/null
+++ b/doc/materials/materials/MAT_ASPHALT
@@ -0,0 +1,18 @@
+Materialid:
+MAT_ASPHALT              "asphalt"
+
+Name:
+"Asphalt" "Asphalts" "Asphalt" "Asphalt"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_ASPIRIN b/doc/materials/materials/MAT_ASPIRIN
new file mode 100644
index 0000000..5a7a6cc
--- /dev/null
+++ b/doc/materials/materials/MAT_ASPIRIN
@@ -0,0 +1,19 @@
+Materialid:
+MAT_ASPIRIN              "aspirin"
+
+Name:
+"Aspirin" "Aspirins" "Aspirin" "Aspirin"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_SALT:50
+MAT_ASPIRIN
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
+MATGROUP_DRUG:100
diff --git a/doc/materials/materials/MAT_BALSA b/doc/materials/materials/MAT_BALSA
new file mode 100644
index 0000000..963af4a
--- /dev/null
+++ b/doc/materials/materials/MAT_BALSA
@@ -0,0 +1,23 @@
+Materialid:
+MAT_BALSA                "balsa"
+
+Name:
+"Balsaholz" "Balsaholzes" "Balsaholz" "Balsaholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+weicher/leichter als Kork
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_HERBAL:100
+MATGROUP_TROPICAL_WOOD:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_BARYT b/doc/materials/materials/MAT_BARYT
new file mode 100644
index 0000000..516ffa2
--- /dev/null
+++ b/doc/materials/materials/MAT_BARYT
@@ -0,0 +1,21 @@
+Materialid:
+MAT_BARYT                "baryt"
+
+Name:
+"Schwerspat" "Schwerspates" "Schwerspat" "Schwerspat"
+
+Geschlecht:
+M
+
+Beschreibung:
+weiss, hohe Dichte
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:33
+MAT_ORTHOKLAS:50
+MAT_BARYT
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_BASALT b/doc/materials/materials/MAT_BASALT
new file mode 100644
index 0000000..c858830
--- /dev/null
+++ b/doc/materials/materials/MAT_BASALT
@@ -0,0 +1,18 @@
+Materialid:
+MAT_BASALT               "basalt"
+
+Name:
+"Basalt" "Basalts" "Basalt" "Basalt"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_BEECH b/doc/materials/materials/MAT_BEECH
new file mode 100644
index 0000000..1eaf815
--- /dev/null
+++ b/doc/materials/materials/MAT_BEECH
@@ -0,0 +1,24 @@
+Materialid:
+MAT_BEECH                "beech"
+
+Name:
+"Buchenholz" "Buchenholzes" "Buchenholz" "Buchenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+hart, roetlich
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:5
+MAT_BEECH
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_BIRCH b/doc/materials/materials/MAT_BIRCH
new file mode 100644
index 0000000..7b950c7
--- /dev/null
+++ b/doc/materials/materials/MAT_BIRCH
@@ -0,0 +1,24 @@
+Materialid:
+MAT_BIRCH                "birch"
+
+Name:
+"Birkenholz" "Birkenholzes" "Birkenholz" "Birkenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+magisch, zaeh, suess
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:5
+MAT_BIRCH
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_BLOOD b/doc/materials/materials/MAT_BLOOD
new file mode 100644
index 0000000..3f4b2b1
--- /dev/null
+++ b/doc/materials/materials/MAT_BLOOD
@@ -0,0 +1,19 @@
+Materialid:
+MAT_BLOOD                "blood"
+
+Name:
+"Blut" "Bluts" "Blut" "Blut"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_FLUID:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_BONE b/doc/materials/materials/MAT_BONE
new file mode 100644
index 0000000..3800823
--- /dev/null
+++ b/doc/materials/materials/MAT_BONE
@@ -0,0 +1,19 @@
+Materialid:
+MAT_BONE                 "bone"
+
+Name:
+"Knochen" "Knochens" "Knochen" "Knochen"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_BRASS b/doc/materials/materials/MAT_BRASS
new file mode 100644
index 0000000..de2f4d7
--- /dev/null
+++ b/doc/materials/materials/MAT_BRASS
@@ -0,0 +1,20 @@
+Materialid:
+MAT_BRASS                "brass"
+
+Name:
+"Messing" "Messings" "Messing" "Messing"
+
+Geschlecht:
+N
+
+Beschreibung:
+bis 80% Kupfer, Rest Zink
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_GOLD:15
+MAT_BRASS
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_BRONCE b/doc/materials/materials/MAT_BRONCE
new file mode 100644
index 0000000..657d24e
--- /dev/null
+++ b/doc/materials/materials/MAT_BRONCE
@@ -0,0 +1,18 @@
+Materialid:
+MAT_BRONCE               "bronce"
+
+Name:
+"Bronze" "Bronze" "Bronze" "Bronze"
+
+Geschlecht:
+F
+
+Beschreibung:
+Kupferlegierung (mit Zinn)
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_BRUYERE b/doc/materials/materials/MAT_BRUYERE
new file mode 100644
index 0000000..479500a
--- /dev/null
+++ b/doc/materials/materials/MAT_BRUYERE
@@ -0,0 +1,24 @@
+Materialid:
+MAT_BRUYERE              "bruyere"
+
+Name:
+"Bruyereholz" "Bruyereholzes" "Bruyereholz" "Bruyereholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+sehr hart und zaeh, fuer Pfeifen
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:5
+MAT_BRUYERE
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_CANNABIS b/doc/materials/materials/MAT_CANNABIS
new file mode 100644
index 0000000..a81cd39
--- /dev/null
+++ b/doc/materials/materials/MAT_CANNABIS
@@ -0,0 +1,21 @@
+Materialid:
+MAT_CANNABIS             "cannabis"
+
+Name:
+"Hanf" "Hanfs" "Hanf" "Hanf"
+
+Geschlecht:
+M
+
+Beschreibung:
+auch THC
+
+Erkennbarkeit:
+MAT_MISC_HERBAL:33
+MAT_CANNABIS
+
+Gruppenzugehoerigkeit:
+MATGROUP_HERBAL:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
+MATGROUP_DRUG:100
diff --git a/doc/materials/materials/MAT_CARBON b/doc/materials/materials/MAT_CARBON
new file mode 100644
index 0000000..05a05a2
--- /dev/null
+++ b/doc/materials/materials/MAT_CARBON
@@ -0,0 +1,18 @@
+Materialid:
+MAT_CARBON               "C"
+
+Name:
+"Kohlenstoff" "Kohlenstoffs" "Kohlenstoff" "Kohlenstoff"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CARTON b/doc/materials/materials/MAT_CARTON
new file mode 100644
index 0000000..68c836c
--- /dev/null
+++ b/doc/materials/materials/MAT_CARTON
@@ -0,0 +1,20 @@
+Materialid:
+MAT_CARTON               "carton"
+
+Name:
+"Pappe" "Pappe" "Pappe" "Pappe"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_PAPER:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CEDAR b/doc/materials/materials/MAT_CEDAR
new file mode 100644
index 0000000..cc6ee93
--- /dev/null
+++ b/doc/materials/materials/MAT_CEDAR
@@ -0,0 +1,25 @@
+Materialid:
+MAT_CEDAR                "cedar"
+
+Name:
+"Zedernholz" "Zedernholzes" "Zedernholz" "Zedernholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+magisch und weich
+
+Erkennbarkeit:
+MAT_MISC_CONIFER_WOOD:5
+MAT_CEDAR
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_MAGIC:100
+MATGROUP_BIO:100
+MATGROUP_HERBAL:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
+MATGROUP_DEAD:100
+MATGROUP_CONIFER_WOOD:100
diff --git a/doc/materials/materials/MAT_CERAMIC b/doc/materials/materials/MAT_CERAMIC
new file mode 100644
index 0000000..4f71b1c
--- /dev/null
+++ b/doc/materials/materials/MAT_CERAMIC
@@ -0,0 +1,17 @@
+Materialid:
+MAT_CERAMIC              "ceramic"
+
+Name:
+"Keramik" "Keramik" "Keramik" "Keramik"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CHALK b/doc/materials/materials/MAT_CHALK
new file mode 100644
index 0000000..5775e91
--- /dev/null
+++ b/doc/materials/materials/MAT_CHALK
@@ -0,0 +1,17 @@
+Materialid:
+MAT_CHALK                "chalk"
+
+Name:
+"Kreide" "Kreide" "Kreide" "Kreide"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CHEESE b/doc/materials/materials/MAT_CHEESE
new file mode 100644
index 0000000..143d544
--- /dev/null
+++ b/doc/materials/materials/MAT_CHEESE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_CHEESE             "cheese"
+
+Name:
+"Kaese" "Kaeses" "Kaese" "Kaese"
+
+Geschlecht:
+M
+
+Beschreibung:
+weich, essbar
+
+Erkennbarkeit:
+MATGROUP_EATABLE:0
+MATGROUP_BIO:0
+MAT_CHEESE
+
+Gruppenzugehoerigkeit:
+MATGROUP_EATABLE:100
+MATGROUP_SOLID:100
+MATGROUP_BIO:100
diff --git a/doc/materials/materials/MAT_CHIFFON b/doc/materials/materials/MAT_CHIFFON
new file mode 100644
index 0000000..2995a4a
--- /dev/null
+++ b/doc/materials/materials/MAT_CHIFFON
@@ -0,0 +1,21 @@
+Materialid:
+MAT_CHIFFON              "chiffon"
+
+Name:
+"Chiffon" "Chiffons" "Chiffon" "Chiffon"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
+MATGROUP_CLOTH:100
diff --git a/doc/materials/materials/MAT_CHITIN b/doc/materials/materials/MAT_CHITIN
new file mode 100644
index 0000000..081e65d
--- /dev/null
+++ b/doc/materials/materials/MAT_CHITIN
@@ -0,0 +1,19 @@
+Materialid:
+MAT_CHITIN               "chitin"
+
+Name:
+"Chitin" "Chitins" "Chitin" "Chitin"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_DEAD:100
diff --git a/doc/materials/materials/MAT_CHLOR b/doc/materials/materials/MAT_CHLOR
new file mode 100644
index 0000000..f32ea88
--- /dev/null
+++ b/doc/materials/materials/MAT_CHLOR
@@ -0,0 +1,20 @@
+Materialid:
+MAT_CHLOR                "chlor"
+
+Name:
+"Chlorgas" "Chlorgases" "Chlorgas" "Chlorgas"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_GAS:20
+MAT_CHLOR
+
+Gruppenzugehoerigkeit:
+MATGROUP_POISONOUS:100
+MATGROUP_GAS:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_CHROMIUM b/doc/materials/materials/MAT_CHROMIUM
new file mode 100644
index 0000000..aa1d15f
--- /dev/null
+++ b/doc/materials/materials/MAT_CHROMIUM
@@ -0,0 +1,20 @@
+Materialid:
+MAT_CHROMIUM             "chromium"
+
+Name:
+"Chrom" "Chroms" "Chrom" "Chrom"
+
+Geschlecht:
+N
+
+Beschreibung:
+silberweiss, weich, zaeh
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:15
+MAT_CHROMIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CINNABAR b/doc/materials/materials/MAT_CINNABAR
new file mode 100644
index 0000000..2a519ea
--- /dev/null
+++ b/doc/materials/materials/MAT_CINNABAR
@@ -0,0 +1,20 @@
+Materialid:
+MAT_CINNABAR             "cinnabar"
+
+Name:
+"Zinnober" "Zinnobers" "Zinnober" "Zinnober"
+
+Geschlecht:
+N
+
+Beschreibung:
+bleigrau bis scharlachrot
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:20
+MAT_CINNABAR
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_CLAY b/doc/materials/materials/MAT_CLAY
new file mode 100644
index 0000000..ea9795d
--- /dev/null
+++ b/doc/materials/materials/MAT_CLAY
@@ -0,0 +1,17 @@
+Materialid:
+MAT_CLAY                 "clay"
+
+Name:
+"Ton" "Tons" "Ton" "Ton"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CLOTH b/doc/materials/materials/MAT_CLOTH
new file mode 100644
index 0000000..83a4d15
--- /dev/null
+++ b/doc/materials/materials/MAT_CLOTH
@@ -0,0 +1,21 @@
+Materialid:
+MAT_CLOTH                "cloth"
+
+Name:
+"Stoff" "Stoffes" "Stoff" "Stoff"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_COBALT b/doc/materials/materials/MAT_COBALT
new file mode 100644
index 0000000..513b32a
--- /dev/null
+++ b/doc/materials/materials/MAT_COBALT
@@ -0,0 +1,20 @@
+Materialid:
+MAT_COBALT               "Co"
+
+Name:
+"Cobalt" "Cobalts" "Cobalt" "Cobalt"
+
+Geschlecht:
+N
+
+Beschreibung:
+hartes, sproedes Legierungmet.
+
+Erkennbarkeit:
+MAT_MISC_METAL:25
+MAT_COBALT
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_MAGNETIC:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_COCAINE b/doc/materials/materials/MAT_COCAINE
new file mode 100644
index 0000000..d69d413
--- /dev/null
+++ b/doc/materials/materials/MAT_COCAINE
@@ -0,0 +1,19 @@
+Materialid:
+MAT_COCAINE              "cocaine"
+
+Name:
+"Kokain" "Kokains" "Kokain" "Kokain"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_CHALK:50
+MAT_COCAINE
+
+Gruppenzugehoerigkeit:
+MATGROUP_DRUG:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CONCRETE b/doc/materials/materials/MAT_CONCRETE
new file mode 100644
index 0000000..bb711cc
--- /dev/null
+++ b/doc/materials/materials/MAT_CONCRETE
@@ -0,0 +1,18 @@
+Materialid:
+MAT_CONCRETE             "concrete"
+
+Name:
+"Beton" "Betons" "Beton" "Beton"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_COPPER b/doc/materials/materials/MAT_COPPER
new file mode 100644
index 0000000..7c351a6
--- /dev/null
+++ b/doc/materials/materials/MAT_COPPER
@@ -0,0 +1,19 @@
+Materialid:
+MAT_COPPER               "Cu"
+
+Name:
+"Kupfer" "Kupfers" "Kupfer" "Kupfer"
+
+Geschlecht:
+N
+
+Beschreibung:
+weich, rot
+
+Erkennbarkeit:
+MAT_MISC_METAL:5
+MAT_COPPER
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CORK b/doc/materials/materials/MAT_CORK
new file mode 100644
index 0000000..a4fc3c6
--- /dev/null
+++ b/doc/materials/materials/MAT_CORK
@@ -0,0 +1,22 @@
+Materialid:
+MAT_CORK                 "cork"
+
+Name:
+"Kork" "Korks" "Kork" "Kork"
+
+Geschlecht:
+M
+
+Beschreibung:
+weich
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_COTTON b/doc/materials/materials/MAT_COTTON
new file mode 100644
index 0000000..a2d94ca
--- /dev/null
+++ b/doc/materials/materials/MAT_COTTON
@@ -0,0 +1,21 @@
+Materialid:
+MAT_COTTON               "cotton"
+
+Name:
+"Baumwolle" "Baumwolle" "Baumwolle" "Baumwolle"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_CRYSTAL b/doc/materials/materials/MAT_CRYSTAL
new file mode 100644
index 0000000..aab2eb5
--- /dev/null
+++ b/doc/materials/materials/MAT_CRYSTAL
@@ -0,0 +1,19 @@
+Materialid:
+MAT_CRYSTAL              "crystal"
+
+Name:
+"Kristall" "Kristalls" "Kristall" "Kristall"
+
+Geschlecht:
+M
+
+Beschreibung:
+klar bis weiss
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_DETONATING_GAS b/doc/materials/materials/MAT_DETONATING_GAS
new file mode 100644
index 0000000..80a88e5
--- /dev/null
+++ b/doc/materials/materials/MAT_DETONATING_GAS
@@ -0,0 +1,21 @@
+Materialid:
+MAT_DETONATING_GAS       "oxyhydrogen"
+
+Name:
+"Knallgas" "Knallgases" "Knallgas" "Knallgas"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_GAS:20
+MAT_DETONATING_GAS
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_GAS:100
+MATGROUP_EXPLOSIVE:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_DIAMOND b/doc/materials/materials/MAT_DIAMOND
new file mode 100644
index 0000000..b9f9fc0
--- /dev/null
+++ b/doc/materials/materials/MAT_DIAMOND
@@ -0,0 +1,22 @@
+Materialid:
+MAT_DIAMOND              "diamond"
+
+Name:
+"Diamant" "Diamants" "Diamant" "Diamant"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:0
+MAT_CRYSTAL:25
+MAT_DIAMOND
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_DUST b/doc/materials/materials/MAT_DUST
new file mode 100644
index 0000000..d5a5c49
--- /dev/null
+++ b/doc/materials/materials/MAT_DUST
@@ -0,0 +1,17 @@
+Materialid:
+MAT_DUST                 "dust"
+
+Name:
+"Staub" "Staubs" "Staub" "Staub"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_EARTH b/doc/materials/materials/MAT_EARTH
new file mode 100644
index 0000000..8ff28e0
--- /dev/null
+++ b/doc/materials/materials/MAT_EARTH
@@ -0,0 +1,18 @@
+Materialid:
+MAT_EARTH                "earth"
+
+Name:
+"Erde" "Erde" "Erde" "Erde"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_ELEMENTAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_EBONY b/doc/materials/materials/MAT_EBONY
new file mode 100644
index 0000000..933ce66
--- /dev/null
+++ b/doc/materials/materials/MAT_EBONY
@@ -0,0 +1,24 @@
+Materialid:
+MAT_EBONY                "ebony"
+
+Name:
+"Ebenholz" "Ebenholzes" "Ebenholz" "Ebenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+schwarz
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:15
+MAT_EBONY
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_ELEKTRON b/doc/materials/materials/MAT_ELEKTRON
new file mode 100644
index 0000000..11d64f9
--- /dev/null
+++ b/doc/materials/materials/MAT_ELEKTRON
@@ -0,0 +1,20 @@
+Materialid:
+MAT_ELEKTRON             "elektron"
+
+Name:
+"Elektron" "Elektrons" "Elektron" "Elektron"
+
+Geschlecht:
+N
+
+Beschreibung:
+bis 75% Gold, Rest Silber
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_GOLD:66
+MAT_ELEKTRON
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_EMERALD b/doc/materials/materials/MAT_EMERALD
new file mode 100644
index 0000000..daad2c0
--- /dev/null
+++ b/doc/materials/materials/MAT_EMERALD
@@ -0,0 +1,21 @@
+Materialid:
+MAT_EMERALD              "emerald"
+
+Name:
+"Smaragd" "Smaragds" "Smaragd" "Smaragd"
+
+Geschlecht:
+M
+
+Beschreibung:
+gruen
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:25
+MAT_EMERALD
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_FAT b/doc/materials/materials/MAT_FAT
new file mode 100644
index 0000000..98e2a03
--- /dev/null
+++ b/doc/materials/materials/MAT_FAT
@@ -0,0 +1,22 @@
+Materialid:
+MAT_FAT                  "fat"
+
+Name:
+"Fett" "Fetts" "Fett" "Fett"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_FOOD:-50
+MAT_FAT
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_EATABLE:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_FEATHER b/doc/materials/materials/MAT_FEATHER
new file mode 100644
index 0000000..1f51ecc
--- /dev/null
+++ b/doc/materials/materials/MAT_FEATHER
@@ -0,0 +1,21 @@
+Materialid:
+MAT_FEATHER              "feather"
+
+Name:
+"Federn" "Federn" "Federn" "Federn"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_FELT b/doc/materials/materials/MAT_FELT
new file mode 100644
index 0000000..ead7d49
--- /dev/null
+++ b/doc/materials/materials/MAT_FELT
@@ -0,0 +1,21 @@
+Materialid:
+MAT_FELT                 "felt"
+
+Name:
+"Filz" "Filzes" "Filz" "Filz"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_FIR b/doc/materials/materials/MAT_FIR
new file mode 100644
index 0000000..0fd017e
--- /dev/null
+++ b/doc/materials/materials/MAT_FIR
@@ -0,0 +1,24 @@
+Materialid:
+MAT_FIR                  "fir"
+
+Name:
+"Tannenholz" "Tannenholzes" "Tannenholz" "Tannenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+trocken (Douglasie)
+
+Erkennbarkeit:
+MAT_MISC_CONIFER_WOOD:15
+MAT_FIR
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_CONIFER_WOOD:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_FIRE b/doc/materials/materials/MAT_FIRE
new file mode 100644
index 0000000..81b94aa
--- /dev/null
+++ b/doc/materials/materials/MAT_FIRE
@@ -0,0 +1,19 @@
+Materialid:
+MAT_FIRE                 "fire"
+
+Name:
+"Feuer" "Feuers" "Feuer" "Feuer"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_GAS:100
+MATGROUP_INVIS:100
+MATGROUP_ELEMENTAL:100
diff --git a/doc/materials/materials/MAT_FLESH b/doc/materials/materials/MAT_FLESH
new file mode 100644
index 0000000..3f61e56
--- /dev/null
+++ b/doc/materials/materials/MAT_FLESH
@@ -0,0 +1,21 @@
+Materialid:
+MAT_FLESH                "flesh"
+
+Name:
+"Fleisch" "Fleisches" "Fleisch" "Fleisch"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_FOOD:-50
+MAT_FLESH
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_BIO:100
+MATGROUP_EATABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_FLINT b/doc/materials/materials/MAT_FLINT
new file mode 100644
index 0000000..4ea5ca9
--- /dev/null
+++ b/doc/materials/materials/MAT_FLINT
@@ -0,0 +1,18 @@
+Materialid:
+MAT_FLINT                "flint"
+
+Name:
+"Feuerstein" "Feuersteins" "Feuerstein" "Feuerstein"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_FLUORITE b/doc/materials/materials/MAT_FLUORITE
new file mode 100644
index 0000000..4052ad4
--- /dev/null
+++ b/doc/materials/materials/MAT_FLUORITE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_FLUORITE             "fluorite"
+
+Name:
+"Flussspat" "Flussspates" "Flussspat" "Flussspat"
+
+Geschlecht:
+M
+
+Beschreibung:
+oft fluoreszierend
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:33
+MAT_ORTHOKLAS:50
+MAT_FLUORITE
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_FUNGUS b/doc/materials/materials/MAT_FUNGUS
new file mode 100644
index 0000000..1f845a3
--- /dev/null
+++ b/doc/materials/materials/MAT_FUNGUS
@@ -0,0 +1,19 @@
+Materialid:
+MAT_FUNGUS               "fungus"
+
+Name:
+"Pilz" "Pilzs" "Pilz" "Pilz"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_LIVING:100
diff --git a/doc/materials/materials/MAT_GARNET b/doc/materials/materials/MAT_GARNET
new file mode 100644
index 0000000..17a4f83
--- /dev/null
+++ b/doc/materials/materials/MAT_GARNET
@@ -0,0 +1,20 @@
+Materialid:
+MAT_GARNET               "garnet"
+
+Name:
+"Granat" "Granats" "Granat" "Granat"
+
+Geschlecht:
+M
+
+Beschreibung:
+rot, Edelstein: Karfunkel
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
+MATGROUP_JEWEL:100
diff --git a/doc/materials/materials/MAT_GHOST b/doc/materials/materials/MAT_GHOST
new file mode 100644
index 0000000..bbdd8fc
--- /dev/null
+++ b/doc/materials/materials/MAT_GHOST
@@ -0,0 +1,20 @@
+Materialid:
+MAT_GHOST                "ghost"
+
+Name:
+"Geist" "Geists" "Geist" "Geist"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_GAS:100
+MATGROUP_DEAD:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_GLASS b/doc/materials/materials/MAT_GLASS
new file mode 100644
index 0000000..5da7e13
--- /dev/null
+++ b/doc/materials/materials/MAT_GLASS
@@ -0,0 +1,17 @@
+Materialid:
+MAT_GLASS                "glass"
+
+Name:
+"Glas" "Glasses" "Glas" "Glas"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_GNEISS b/doc/materials/materials/MAT_GNEISS
new file mode 100644
index 0000000..a03eeea
--- /dev/null
+++ b/doc/materials/materials/MAT_GNEISS
@@ -0,0 +1,19 @@
+Materialid:
+MAT_GNEISS               "gneiss"
+
+Name:
+"Gneiss" "Gneisss" "Gneiss" "Gneiss"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_STONE:35
+MAT_GNEISS
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_GOLD b/doc/materials/materials/MAT_GOLD
new file mode 100644
index 0000000..2dc051b
--- /dev/null
+++ b/doc/materials/materials/MAT_GOLD
@@ -0,0 +1,19 @@
+Materialid:
+MAT_GOLD                 "Au"
+
+Name:
+"Gold" "Goldes" "Gold" "Gold"
+
+Geschlecht:
+N
+
+Beschreibung:
+weiss bis gelb/rot
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
+MATGROUP_PRECIOUS_METAL:100
diff --git a/doc/materials/materials/MAT_GRANITE b/doc/materials/materials/MAT_GRANITE
new file mode 100644
index 0000000..7e4da7a
--- /dev/null
+++ b/doc/materials/materials/MAT_GRANITE
@@ -0,0 +1,18 @@
+Materialid:
+MAT_GRANITE              "granite"
+
+Name:
+"Granit" "Granits" "Granit" "Granit"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_GRAPHITE b/doc/materials/materials/MAT_GRAPHITE
new file mode 100644
index 0000000..49d7f44
--- /dev/null
+++ b/doc/materials/materials/MAT_GRAPHITE
@@ -0,0 +1,23 @@
+Materialid:
+MAT_GRAPHITE             "graphite"
+
+Name:
+"Graphit" "Graphits" "Graphit" "Graphit"
+
+Geschlecht:
+N
+
+Beschreibung:
+metallisch grau
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:20
+MAT_LEAD:40
+MAT_CARBON:60
+MAT_GRAPHITE
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_GUNPOWDER b/doc/materials/materials/MAT_GUNPOWDER
new file mode 100644
index 0000000..3eec675
--- /dev/null
+++ b/doc/materials/materials/MAT_GUNPOWDER
@@ -0,0 +1,19 @@
+Materialid:
+MAT_GUNPOWDER            "gunpowder"
+
+Name:
+"Schwarzpulver" "Schwarzpulvers" "Schwarzpulver" "Schwarzpulver"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_EXPLOSIVE:100
diff --git a/doc/materials/materials/MAT_HAIR b/doc/materials/materials/MAT_HAIR
new file mode 100644
index 0000000..3ffd5c3
--- /dev/null
+++ b/doc/materials/materials/MAT_HAIR
@@ -0,0 +1,21 @@
+Materialid:
+MAT_HAIR                 "hair"
+
+Name:
+"Haare" "Haare" "Haaren" "Haaren"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_HELIUM b/doc/materials/materials/MAT_HELIUM
new file mode 100644
index 0000000..b4504c0
--- /dev/null
+++ b/doc/materials/materials/MAT_HELIUM
@@ -0,0 +1,19 @@
+Materialid:
+MAT_HELIUM               "He"
+
+Name:
+"Helium" "Heliums" "Helium" "Helium"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_GAS:20
+MAT_HELIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_GAS:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_HORN b/doc/materials/materials/MAT_HORN
new file mode 100644
index 0000000..dad2359
--- /dev/null
+++ b/doc/materials/materials/MAT_HORN
@@ -0,0 +1,19 @@
+Materialid:
+MAT_HORN                 "horn"
+
+Name:
+"Horn" "Horns" "Horn" "Horn"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_HOWALGO b/doc/materials/materials/MAT_HOWALGO
new file mode 100644
index 0000000..aaeab73
--- /dev/null
+++ b/doc/materials/materials/MAT_HOWALGO
@@ -0,0 +1,22 @@
+Materialid:
+MAT_HOWALGO              "howalgo"
+
+Name:
+"Howalgoerz" "Howalgoerzes" "Howalgoerz" "Howalgoerz"
+
+Geschlecht:
+N
+
+Beschreibung:
+Zwergenwaffenstahl
+
+Erkennbarkeit:
+MAT_MISC_METAL:10
+MAT_STEEL:65
+MAT_HOWALGO
+
+Gruppenzugehoerigkeit:
+MATGROUP_MAGNETIC:100
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
+MATGROUP_PRECIOUS_METAL:100
diff --git a/doc/materials/materials/MAT_ICE b/doc/materials/materials/MAT_ICE
new file mode 100644
index 0000000..e8b04d3
--- /dev/null
+++ b/doc/materials/materials/MAT_ICE
@@ -0,0 +1,17 @@
+Materialid:
+MAT_ICE                  "ice"
+
+Name:
+"Eis" "Eises" "Eis" "Eis"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_INK b/doc/materials/materials/MAT_INK
new file mode 100644
index 0000000..ed43d5e
--- /dev/null
+++ b/doc/materials/materials/MAT_INK
@@ -0,0 +1,17 @@
+Materialid:
+MAT_INK                  "ink"
+
+Name:
+"Tinte" "Tinte" "Tinte" "Tinte"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_IRIDIUM b/doc/materials/materials/MAT_IRIDIUM
new file mode 100644
index 0000000..e122588
--- /dev/null
+++ b/doc/materials/materials/MAT_IRIDIUM
@@ -0,0 +1,23 @@
+Materialid:
+MAT_IRIDIUM              "Ir"
+
+Name:
+"Iridium" "Iridiums" "Iridium" "Iridium"
+
+Geschlecht:
+N
+
+Beschreibung:
+schwer, giftig
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:5
+MAT_PLATINUM:25
+MAT_IRIDIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_POISONOUS:100
+MATGROUP_SOLID:100
+MATGROUP_PRECIOUS_METAL:100
diff --git a/doc/materials/materials/MAT_IRON b/doc/materials/materials/MAT_IRON
new file mode 100644
index 0000000..7015cb0
--- /dev/null
+++ b/doc/materials/materials/MAT_IRON
@@ -0,0 +1,19 @@
+Materialid:
+MAT_IRON                 "Fe"
+
+Name:
+"Eisen" "Eisens" "Eisen" "Eisen"
+
+Geschlecht:
+N
+
+Beschreibung:
+weich
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_MAGNETIC:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_IRON_WOOD b/doc/materials/materials/MAT_IRON_WOOD
new file mode 100644
index 0000000..77890f6
--- /dev/null
+++ b/doc/materials/materials/MAT_IRON_WOOD
@@ -0,0 +1,24 @@
+Materialid:
+MAT_IRON_WOOD            "iron_wood"
+
+Name:
+"Eisenholz" "Eisenholzes" "Eisenholz" "Eisenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+extrem hart (tropisch)
+
+Erkennbarkeit:
+MAT_OAK:25
+MAT_IRON_WOOD
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_TROPICAL_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_IVORY b/doc/materials/materials/MAT_IVORY
new file mode 100644
index 0000000..e6ad852
--- /dev/null
+++ b/doc/materials/materials/MAT_IVORY
@@ -0,0 +1,19 @@
+Materialid:
+MAT_IVORY                "ivory"
+
+Name:
+"Elfenbein" "Elfenbeins" "Elfenbein" "Elfenbein"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_JADE b/doc/materials/materials/MAT_JADE
new file mode 100644
index 0000000..b0d1950
--- /dev/null
+++ b/doc/materials/materials/MAT_JADE
@@ -0,0 +1,20 @@
+Materialid:
+MAT_JADE                 "jade"
+
+Name:
+"Jade" "Jade" "Jade" "Jade"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_JOFIUM b/doc/materials/materials/MAT_JOFIUM
new file mode 100644
index 0000000..9c2cbc1
--- /dev/null
+++ b/doc/materials/materials/MAT_JOFIUM
@@ -0,0 +1,19 @@
+Materialid:
+MAT_JOFIUM               "jofium"
+
+Name:
+"Jofium" "Jofiums" "Jofium" "Jofium"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
+MATGROUP_PRECIOUS_METAL:100
diff --git a/doc/materials/materials/MAT_LACE b/doc/materials/materials/MAT_LACE
new file mode 100644
index 0000000..36db45f
--- /dev/null
+++ b/doc/materials/materials/MAT_LACE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_LACE                 "lace"
+
+Name:
+"Spitze" "Spitze" "Spitze" "Spitze"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_LARIX b/doc/materials/materials/MAT_LARIX
new file mode 100644
index 0000000..9eda4cd
--- /dev/null
+++ b/doc/materials/materials/MAT_LARIX
@@ -0,0 +1,25 @@
+Materialid:
+MAT_LARIX                "larix"
+
+Name:
+"Laerchenholz" "Laerchenholzes" "Laerchenholz" "Laerchenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+sehr harzig, biegsam
+
+Erkennbarkeit:
+MAT_MISC_CONIFER_WOOD:5
+MAT_LARIX
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_CONIFER_WOOD:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_LATEX b/doc/materials/materials/MAT_LATEX
new file mode 100644
index 0000000..78876a2
--- /dev/null
+++ b/doc/materials/materials/MAT_LATEX
@@ -0,0 +1,19 @@
+Materialid:
+MAT_LATEX                "latex"
+
+Name:
+"Gummi" "Gummis" "Gummi" "Gummi"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLEXIBLE:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_LAUGHING_GAS b/doc/materials/materials/MAT_LAUGHING_GAS
new file mode 100644
index 0000000..91da6e3
--- /dev/null
+++ b/doc/materials/materials/MAT_LAUGHING_GAS
@@ -0,0 +1,20 @@
+Materialid:
+MAT_LAUGHING_GAS         "laughing_gas"
+
+Name:
+"Lachgas" "Lachgases" "Lachgas" "Lachgas"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_GAS:100
+MATGROUP_EXPLOSIVE:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_LAZURITE b/doc/materials/materials/MAT_LAZURITE
new file mode 100644
index 0000000..6ed358a
--- /dev/null
+++ b/doc/materials/materials/MAT_LAZURITE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_LAZURITE             "lazurite"
+
+Name:
+"Lapislazuli" "Lapislazulis" "Lapislazuli" "Lapislazuli"
+
+Geschlecht:
+M
+
+Beschreibung:
+tiefblau (ultramarin)
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:20
+MAT_LAZURITE
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
+MATGROUP_JEWEL:100
diff --git a/doc/materials/materials/MAT_LEAD b/doc/materials/materials/MAT_LEAD
new file mode 100644
index 0000000..2bfafc9
--- /dev/null
+++ b/doc/materials/materials/MAT_LEAD
@@ -0,0 +1,20 @@
+Materialid:
+MAT_LEAD                 "Pb"
+
+Name:
+"Blei" "Bleis" "Blei" "Blei"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLEXIBLE:100
+MATGROUP_METAL:100
+MATGROUP_POISONOUS:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_LEATHER b/doc/materials/materials/MAT_LEATHER
new file mode 100644
index 0000000..34c8e75
--- /dev/null
+++ b/doc/materials/materials/MAT_LEATHER
@@ -0,0 +1,21 @@
+Materialid:
+MAT_LEATHER              "leather"
+
+Name:
+"Leder" "Leders" "Leder" "Leder"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_LIGHTNING b/doc/materials/materials/MAT_LIGHTNING
new file mode 100644
index 0000000..20d55ca
--- /dev/null
+++ b/doc/materials/materials/MAT_LIGHTNING
@@ -0,0 +1,19 @@
+Materialid:
+MAT_LIGHTNING            "lightning"
+
+Name:
+"Blitz" "Blitzes" "Blitz" "Blitz"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_ELECTRICAL:100
+MATGROUP_GAS:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_LIME b/doc/materials/materials/MAT_LIME
new file mode 100644
index 0000000..ed61dea
--- /dev/null
+++ b/doc/materials/materials/MAT_LIME
@@ -0,0 +1,24 @@
+Materialid:
+MAT_LIME                 "lime"
+
+Name:
+"Lindenholz" "Lindenholzes" "Lindenholz" "Lindenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+weich
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:15
+MAT_LIME
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_LIMESTONE b/doc/materials/materials/MAT_LIMESTONE
new file mode 100644
index 0000000..01ea90a
--- /dev/null
+++ b/doc/materials/materials/MAT_LIMESTONE
@@ -0,0 +1,18 @@
+Materialid:
+MAT_LIMESTONE            "limestone"
+
+Name:
+"Kalkstein" "Kalksteins" "Kalkstein" "Kalkstein"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_LINEN b/doc/materials/materials/MAT_LINEN
new file mode 100644
index 0000000..fa4deb0
--- /dev/null
+++ b/doc/materials/materials/MAT_LINEN
@@ -0,0 +1,21 @@
+Materialid:
+MAT_LINEN                "linen"
+
+Name:
+"Leinen" "Leinen" "Leinen" "Leinen"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MAGNESIUM b/doc/materials/materials/MAT_MAGNESIUM
new file mode 100644
index 0000000..dd5cbbb
--- /dev/null
+++ b/doc/materials/materials/MAT_MAGNESIUM
@@ -0,0 +1,21 @@
+Materialid:
+MAT_MAGNESIUM            "Mg"
+
+Name:
+"Magnesium" "Magnesiums" "Magnesium" "Magnesium"
+
+Geschlecht:
+N
+
+Beschreibung:
+brennbar
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_ALUMINIUM:30
+MAT_MAGNESIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MAHAGONI b/doc/materials/materials/MAT_MAHAGONI
new file mode 100644
index 0000000..0d8929c
--- /dev/null
+++ b/doc/materials/materials/MAT_MAHAGONI
@@ -0,0 +1,24 @@
+Materialid:
+MAT_MAHAGONI             "mahagoni"
+
+Name:
+"Mahagoni" "Mahagonis" "Mahagoni" "Mahagoni"
+
+Geschlecht:
+N
+
+Beschreibung:
+rot bis dunkelrot
+
+Erkennbarkeit:
+MAT_MISC_TROPICAL_WOOD:-5
+MAT_MAHAGONI
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_TROPICAL_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_MALACHITE b/doc/materials/materials/MAT_MALACHITE
new file mode 100644
index 0000000..7771010
--- /dev/null
+++ b/doc/materials/materials/MAT_MALACHITE
@@ -0,0 +1,20 @@
+Materialid:
+MAT_MALACHITE            "malachite"
+
+Name:
+"Malachit" "Malachits" "Malachit" "Malachit"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:20
+MAT_MALACHITE
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_MAPLE b/doc/materials/materials/MAT_MAPLE
new file mode 100644
index 0000000..9ebbd98
--- /dev/null
+++ b/doc/materials/materials/MAT_MAPLE
@@ -0,0 +1,24 @@
+Materialid:
+MAT_MAPLE                "maple"
+
+Name:
+"Ahornholz" "Ahornholzes" "Ahornholz" "Ahornholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:25
+MAT_MAPLE
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_MARBLE b/doc/materials/materials/MAT_MARBLE
new file mode 100644
index 0000000..a48942f
--- /dev/null
+++ b/doc/materials/materials/MAT_MARBLE
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MARBLE               "marble"
+
+Name:
+"Marmor" "Marmors" "Marmor" "Marmor"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MERCURY b/doc/materials/materials/MAT_MERCURY
new file mode 100644
index 0000000..cf3fd88
--- /dev/null
+++ b/doc/materials/materials/MAT_MERCURY
@@ -0,0 +1,19 @@
+Materialid:
+MAT_MERCURY              "Hg"
+
+Name:
+"Quecksilber" "Quecksilbers" "Quecksilber" "Quecksilber"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_POISONOUS:100
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_METHANE b/doc/materials/materials/MAT_METHANE
new file mode 100644
index 0000000..d93c576
--- /dev/null
+++ b/doc/materials/materials/MAT_METHANE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_METHANE              "methane"
+
+Name:
+"Methan" "Methans" "Methan" "Methan"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_GAS:20
+MAT_METHANE
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_GAS:100
+MATGROUP_EXPLOSIVE:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_MILK b/doc/materials/materials/MAT_MILK
new file mode 100644
index 0000000..7aea040
--- /dev/null
+++ b/doc/materials/materials/MAT_MILK
@@ -0,0 +1,17 @@
+Materialid:
+MAT_MILK                 "milk"
+
+Name:
+"Milch" "Milch" "Milch" "Milch"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_MISC b/doc/materials/materials/MAT_MISC
new file mode 100644
index 0000000..d9aa554
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC
@@ -0,0 +1,17 @@
+Materialid:
+MAT_MISC                 "misc"
+
+Name:
+"verschiedenes Material" "verschiedenen Materials" "verschiedenem Material" "verschiedenen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+allg. Material (default)
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MISC:100
diff --git a/doc/materials/materials/MAT_MISC_ACID b/doc/materials/materials/MAT_MISC_ACID
new file mode 100644
index 0000000..ac8d15f
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_ACID
@@ -0,0 +1,19 @@
+Materialid:
+MAT_MISC_ACID            "misc_acid"
+
+Name:
+"Saeure" "Saeure" "Saeure" "Saeure"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_ACIDIC:100
+MATGROUP_FLUID:100
+MATGROUP_POISONOUS:100
diff --git a/doc/materials/materials/MAT_MISC_BASE b/doc/materials/materials/MAT_MISC_BASE
new file mode 100644
index 0000000..cd2cfd1
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_BASE
@@ -0,0 +1,19 @@
+Materialid:
+MAT_MISC_BASE            "misc_base"
+
+Name:
+"Lauge" "Lauge" "Lauge" "Lauge"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLUID:100
+MATGROUP_BASIC:100
+MATGROUP_POISONOUS:100
diff --git a/doc/materials/materials/MAT_MISC_CONIFER_WOOD b/doc/materials/materials/MAT_MISC_CONIFER_WOOD
new file mode 100644
index 0000000..1089538
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_CONIFER_WOOD
@@ -0,0 +1,23 @@
+Materialid:
+MAT_MISC_CONIFER_WOOD    "misc_conifer_wood"
+
+Name:
+"Nadelholz" "Nadelholzes" "Nadelholz" "Nadelholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_CONIFER_WOOD:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_MISC_DEAD b/doc/materials/materials/MAT_MISC_DEAD
new file mode 100644
index 0000000..7a4437a
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_DEAD
@@ -0,0 +1,19 @@
+Materialid:
+MAT_MISC_DEAD            "misc_dead"
+
+Name:
+"sterbliche Ueberreste" "sterbliche Ueberrestes" "sterbliche Ueberreste" "sterbliche Ueberreste"
+
+Geschlecht:
+M
+
+Beschreibung:
+allg. totes Material
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_DECIDUOUS_WOOD b/doc/materials/materials/MAT_MISC_DECIDUOUS_WOOD
new file mode 100644
index 0000000..733456e
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_DECIDUOUS_WOOD
@@ -0,0 +1,23 @@
+Materialid:
+MAT_MISC_DECIDUOUS_WOOD  "misc_deciduous_wood"
+
+Name:
+"Laubholz" "Laubholzes" "Laubholz" "Laubholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_MISC_DRUG b/doc/materials/materials/MAT_MISC_DRUG
new file mode 100644
index 0000000..be59196
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_DRUG
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_DRUG            "misc_drug"
+
+Name:
+"Droge" "Droge" "Droge" "Droge"
+
+Geschlecht:
+F
+
+Beschreibung:
+allg. Drogen
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DRUG:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_EXPLOSIVE b/doc/materials/materials/MAT_MISC_EXPLOSIVE
new file mode 100644
index 0000000..3446878
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_EXPLOSIVE
@@ -0,0 +1,19 @@
+Materialid:
+MAT_MISC_EXPLOSIVE       "misc_explosive"
+
+Name:
+"explosives Material" "explosiven Materials" "explosivem Material" "explosiven Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+allg. Sprengstoffe
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MISC:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_EXPLOSIVE:100
diff --git a/doc/materials/materials/MAT_MISC_FLEXIBLE b/doc/materials/materials/MAT_MISC_FLEXIBLE
new file mode 100644
index 0000000..978d37c
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_FLEXIBLE
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_FLEXIBLE        "misc_flexible"
+
+Name:
+"biegsames Material" "biegsamen Materials" "biegsamem Material" "biegsamen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_FLUID b/doc/materials/materials/MAT_MISC_FLUID
new file mode 100644
index 0000000..fca926d
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_FLUID
@@ -0,0 +1,17 @@
+Materialid:
+MAT_MISC_FLUID           "misc_fluid"
+
+Name:
+"Fluessigkeit" "Fluessigkeits" "Fluessigkeit" "Fluessigkeit"
+
+Geschlecht:
+F
+
+Beschreibung:
+allg. Fluessigkeit
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_MISC_FOOD b/doc/materials/materials/MAT_MISC_FOOD
new file mode 100644
index 0000000..244c440
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_FOOD
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_FOOD            "misc_food"
+
+Name:
+"Essen" "Essens" "Essen" "Essen"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_EATABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_GAS b/doc/materials/materials/MAT_MISC_GAS
new file mode 100644
index 0000000..b8f90bb
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_GAS
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_GAS             "misc_gas"
+
+Name:
+"Gas" "Gases" "Gas" "Gas"
+
+Geschlecht:
+N
+
+Beschreibung:
+allg. Gas
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_GAS:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_MISC_HERBAL b/doc/materials/materials/MAT_MISC_HERBAL
new file mode 100644
index 0000000..645c8f3
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_HERBAL
@@ -0,0 +1,21 @@
+Materialid:
+MAT_MISC_HERBAL          "misc_herbal"
+
+Name:
+"Kraeuter" "Kraeuter" "Kraeuter" "Kraeuter"
+
+Geschlecht:
+F
+
+Beschreibung:
+allg. Kraeuter
+
+Erkennbarkeit:
+MAT_MISC_PLANT:15
+MAT_MISC_HERBAL
+
+Gruppenzugehoerigkeit:
+MATGROUP_HERBAL:100
+MATGROUP_BIO:100
+MATGROUP_LIVING:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_HOLY b/doc/materials/materials/MAT_MISC_HOLY
new file mode 100644
index 0000000..8d265aa
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_HOLY
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_HOLY            "misc_holy"
+
+Name:
+"heiliges Material" "heiligen Materials" "heiligem Material" "heiligen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_HOLY:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_INVIS b/doc/materials/materials/MAT_MISC_INVIS
new file mode 100644
index 0000000..e17ffde
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_INVIS
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_INVIS           "misc_invis"
+
+Name:
+"" "" "" ""
+
+Geschlecht:
+F
+
+Beschreibung:
+allg. unsichtbares Material
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MISC:100
+MATGROUP_INVIS:100
diff --git a/doc/materials/materials/MAT_MISC_JEWEL b/doc/materials/materials/MAT_MISC_JEWEL
new file mode 100644
index 0000000..6d1327f
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_JEWEL
@@ -0,0 +1,20 @@
+Materialid:
+MAT_MISC_JEWEL           "misc_jewel"
+
+Name:
+"Edelstein" "Edelsteins" "Edelstein" "Edelstein"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_MISC_LIVING b/doc/materials/materials/MAT_MISC_LIVING
new file mode 100644
index 0000000..581a01f
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_LIVING
@@ -0,0 +1,19 @@
+Materialid:
+MAT_MISC_LIVING          "misc_living"
+
+Name:
+"Lebewesen" "Lebewesens" "Lebewesen" "Lebewesen"
+
+Geschlecht:
+N
+
+Beschreibung:
+allg. lebendes Material
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_LIVING:100
diff --git a/doc/materials/materials/MAT_MISC_MAGIC b/doc/materials/materials/MAT_MISC_MAGIC
new file mode 100644
index 0000000..0886b59
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_MAGIC
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_MAGIC           "misc_magic"
+
+Name:
+"Magie" "Magie" "Magie" "Magie"
+
+Geschlecht:
+F
+
+Beschreibung:
+allg. magisches Material, das sich nicht naeher bestimmen laesst (wie Oktarin, Birnbaumholz)
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MISC:100
+MATGROUP_MAGIC:100
diff --git a/doc/materials/materials/MAT_MISC_MAGNETIC b/doc/materials/materials/MAT_MISC_MAGNETIC
new file mode 100644
index 0000000..2d48539
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_MAGNETIC
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_MAGNETIC        "misc_magnetic"
+
+Name:
+"magnetisches Material" "magnetischen Materials" "magnetischem Material" "magnetischen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MAGNETIC:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_METAL b/doc/materials/materials/MAT_MISC_METAL
new file mode 100644
index 0000000..61b871c
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_METAL
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_METAL           "misc_metal"
+
+Name:
+"Metall" "Metalls" "Metall" "Metall"
+
+Geschlecht:
+N
+
+Beschreibung:
+allg. Metall
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_MINERAL b/doc/materials/materials/MAT_MISC_MINERAL
new file mode 100644
index 0000000..91da98d
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_MINERAL
@@ -0,0 +1,19 @@
+Materialid:
+MAT_MISC_MINERAL         "misc_mineral"
+
+Name:
+"Mineral" "Minerals" "Mineral" "Mineral"
+
+Geschlecht:
+N
+
+Beschreibung:
+allg. Mineralien
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_MISC_PLANT b/doc/materials/materials/MAT_MISC_PLANT
new file mode 100644
index 0000000..ff805bc
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_PLANT
@@ -0,0 +1,20 @@
+Materialid:
+MAT_MISC_PLANT           "misc_plant"
+
+Name:
+"pflanzliches Material" "pflanzlichen Materials" "pflanzlichem Material" "pflanzlichen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+allg. planzliches Material ohne Holzanteil
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_HERBAL:100
+MATGROUP_BIO:100
+MATGROUP_LIVING:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_POISON b/doc/materials/materials/MAT_MISC_POISON
new file mode 100644
index 0000000..82754f1
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_POISON
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_POISON          "misc_poison"
+
+Name:
+"giftiges Material" "giftigen Materials" "giftigem Material" "giftigen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MISC:100
+MATGROUP_POISONOUS:100
diff --git a/doc/materials/materials/MAT_MISC_SOLID b/doc/materials/materials/MAT_MISC_SOLID
new file mode 100644
index 0000000..3b75ce8
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_SOLID
@@ -0,0 +1,17 @@
+Materialid:
+MAT_MISC_SOLID           "misc_solid"
+
+Name:
+"verschiedenes Material" "verschiedenen Materials" "verschiedenem Material" "verschiedenen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+allg. Feststoffe
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_STONE b/doc/materials/materials/MAT_MISC_STONE
new file mode 100644
index 0000000..6375be7
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_STONE
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_STONE           "misc_stone"
+
+Name:
+"Stein" "Steines" "Stein" "Stein"
+
+Geschlecht:
+M
+
+Beschreibung:
+allg. Gestein
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_TROPICAL_WOOD b/doc/materials/materials/MAT_MISC_TROPICAL_WOOD
new file mode 100644
index 0000000..0376c5b
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_TROPICAL_WOOD
@@ -0,0 +1,23 @@
+Materialid:
+MAT_MISC_TROPICAL_WOOD   "misc_tropical_wood"
+
+Name:
+"Tropenholz" "Tropenholzes" "Tropenholz" "Tropenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_TROPICAL_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_MISC_UNHOLY b/doc/materials/materials/MAT_MISC_UNHOLY
new file mode 100644
index 0000000..364206a
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_UNHOLY
@@ -0,0 +1,18 @@
+Materialid:
+MAT_MISC_UNHOLY          "misc_unholy"
+
+Name:
+"unheiliges Material" "unheiligen Materials" "unheiligem Material" "unheiligen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_UNHOLY:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_MISC_WOOD b/doc/materials/materials/MAT_MISC_WOOD
new file mode 100644
index 0000000..3937e91
--- /dev/null
+++ b/doc/materials/materials/MAT_MISC_WOOD
@@ -0,0 +1,22 @@
+Materialid:
+MAT_MISC_WOOD            "misc_wood"
+
+Name:
+"Holz" "Holzes" "Holz" "Holz"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_MITHRIL b/doc/materials/materials/MAT_MITHRIL
new file mode 100644
index 0000000..90fe713
--- /dev/null
+++ b/doc/materials/materials/MAT_MITHRIL
@@ -0,0 +1,19 @@
+Materialid:
+MAT_MITHRIL              "mithril"
+
+Name:
+"Mithril" "Mithrils" "Mithril" "Mithril"
+
+Geschlecht:
+N
+
+Beschreibung:
+Zwergenruestungsmetall
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
+MATGROUP_PRECIOUS_METAL:100
diff --git a/doc/materials/materials/MAT_MOONSTONE b/doc/materials/materials/MAT_MOONSTONE
new file mode 100644
index 0000000..083beda
--- /dev/null
+++ b/doc/materials/materials/MAT_MOONSTONE
@@ -0,0 +1,20 @@
+Materialid:
+MAT_MOONSTONE            "moonstone"
+
+Name:
+"Mondstein" "Mondsteines" "Mondstein" "Mondstein"
+
+Geschlecht:
+M
+
+Beschreibung:
+gelb, blaeulich, fahl
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:25
+MAT_MOONSTONE
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_MORPHIUM b/doc/materials/materials/MAT_MORPHIUM
new file mode 100644
index 0000000..f3d383a
--- /dev/null
+++ b/doc/materials/materials/MAT_MORPHIUM
@@ -0,0 +1,20 @@
+Materialid:
+MAT_MORPHIUM             "morphium"
+
+Name:
+"Morphium" "Morphiums" "Morphium" "Morphium"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_SALT:50
+MAT_MORPHIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_HERBAL:100
+MATGROUP_DRUG:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_NEUTRONIUM b/doc/materials/materials/MAT_NEUTRONIUM
new file mode 100644
index 0000000..b64c289
--- /dev/null
+++ b/doc/materials/materials/MAT_NEUTRONIUM
@@ -0,0 +1,19 @@
+Materialid:
+MAT_NEUTRONIUM           "Neutr"
+
+Name:
+"Neutronium" "Neutroniums" "Neutronium" "Neutronium"
+
+Geschlecht:
+N
+
+Beschreibung:
+ultraschwer, unzerstoerbar
+
+Erkennbarkeit:
+MAT_MISC_METAL:-25
+MAT_NEUTRONIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_NICKEL b/doc/materials/materials/MAT_NICKEL
new file mode 100644
index 0000000..3bf0935
--- /dev/null
+++ b/doc/materials/materials/MAT_NICKEL
@@ -0,0 +1,20 @@
+Materialid:
+MAT_NICKEL               "nickel"
+
+Name:
+"Nickel" "Nickels" "Nickel" "Nickel"
+
+Geschlecht:
+N
+
+Beschreibung:
+zaeh, fest, silberweiss
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:15
+MAT_NICKEL
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_NITROGLYCERINE b/doc/materials/materials/MAT_NITROGLYCERINE
new file mode 100644
index 0000000..fffa06e
--- /dev/null
+++ b/doc/materials/materials/MAT_NITROGLYCERINE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_NITROGLYCERINE       "nitroglycerine"
+
+Name:
+"Nitroglycerin" "Nitroglycerins" "Nitroglycerin" "Nitroglycerin"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_OIL:25
+MAT_MISC_EXPLOSIVE:50
+MAT_NITROGLYCERINE
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_EXPLOSIVE:100
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_NUTTREE b/doc/materials/materials/MAT_NUTTREE
new file mode 100644
index 0000000..7dd88ff
--- /dev/null
+++ b/doc/materials/materials/MAT_NUTTREE
@@ -0,0 +1,24 @@
+Materialid:
+MAT_NUTTREE              "nuttree"
+
+Name:
+"Nussbaumholz" "Nussbaumholzes" "Nussbaumholz" "Nussbaumholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+hell, polierfaehig
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:15
+MAT_NUTTREE
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_OAK b/doc/materials/materials/MAT_OAK
new file mode 100644
index 0000000..ca256da
--- /dev/null
+++ b/doc/materials/materials/MAT_OAK
@@ -0,0 +1,24 @@
+Materialid:
+MAT_OAK                  "oak"
+
+Name:
+"Eichenholz" "Eichenholzes" "Eichenholz" "Eichenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+hart
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:5
+MAT_OAK
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_OBSIDIAN b/doc/materials/materials/MAT_OBSIDIAN
new file mode 100644
index 0000000..865203b
--- /dev/null
+++ b/doc/materials/materials/MAT_OBSIDIAN
@@ -0,0 +1,20 @@
+Materialid:
+MAT_OBSIDIAN             "obsidian"
+
+Name:
+"Obsidian" "Obsidians" "Obsidian" "Obsidian"
+
+Geschlecht:
+N
+
+Beschreibung:
+schwarz
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:10
+MAT_OBSIDIAN
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_OCTARINE b/doc/materials/materials/MAT_OCTARINE
new file mode 100644
index 0000000..4ef0d29
--- /dev/null
+++ b/doc/materials/materials/MAT_OCTARINE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_OCTARINE             "octarine"
+
+Name:
+"Oktarin" "Oktarins" "Oktarin" "Oktarin"
+
+Geschlecht:
+M
+
+Beschreibung:
+magischer Muell :)
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MAGIC:100
+MATGROUP_STONE:100
+MATGROUP_JEWEL:100
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_OIL b/doc/materials/materials/MAT_OIL
new file mode 100644
index 0000000..7de5102
--- /dev/null
+++ b/doc/materials/materials/MAT_OIL
@@ -0,0 +1,18 @@
+Materialid:
+MAT_OIL                  "oil"
+
+Name:
+"Oel" "Oels" "Oel" "Oel"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_OLIVIN b/doc/materials/materials/MAT_OLIVIN
new file mode 100644
index 0000000..89a1e3b
--- /dev/null
+++ b/doc/materials/materials/MAT_OLIVIN
@@ -0,0 +1,20 @@
+Materialid:
+MAT_OLIVIN               "olivin"
+
+Name:
+"Olivin" "Olivins" "Olivin" "Olivin"
+
+Geschlecht:
+N
+
+Beschreibung:
+gruen bis braun
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:20
+MAT_OLIVIN
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_ONYX b/doc/materials/materials/MAT_ONYX
new file mode 100644
index 0000000..cb5363a
--- /dev/null
+++ b/doc/materials/materials/MAT_ONYX
@@ -0,0 +1,22 @@
+Materialid:
+MAT_ONYX                 "onyx"
+
+Name:
+"Onyx" "Onyxes" "Onyx" "Onyx"
+
+Geschlecht:
+M
+
+Beschreibung:
+Unterart Achat, schwarz
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:0
+MAT_QUARTZ:20
+MAT_AGATE:75
+MAT_ONYX
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_OPAL b/doc/materials/materials/MAT_OPAL
new file mode 100644
index 0000000..89e9707
--- /dev/null
+++ b/doc/materials/materials/MAT_OPAL
@@ -0,0 +1,21 @@
+Materialid:
+MAT_OPAL                 "opal"
+
+Name:
+"Opal" "Opals" "Opal" "Opal"
+
+Geschlecht:
+M
+
+Beschreibung:
+weiss, rot, blau, bunt
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:25
+MAT_OPAL
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_OPIUM b/doc/materials/materials/MAT_OPIUM
new file mode 100644
index 0000000..e680829
--- /dev/null
+++ b/doc/materials/materials/MAT_OPIUM
@@ -0,0 +1,20 @@
+Materialid:
+MAT_OPIUM                "opium"
+
+Name:
+"Opium" "Opiums" "Opium" "Opium"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_HERBAL:50
+MAT_OPIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_HERBAL:100
+MATGROUP_DRUG:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_ORTHOKLAS b/doc/materials/materials/MAT_ORTHOKLAS
new file mode 100644
index 0000000..de100b6
--- /dev/null
+++ b/doc/materials/materials/MAT_ORTHOKLAS
@@ -0,0 +1,20 @@
+Materialid:
+MAT_ORTHOKLAS            "orthoklas"
+
+Name:
+"Feldspat" "Feldspates" "Feldspat" "Feldspat"
+
+Geschlecht:
+M
+
+Beschreibung:
+weiss bis grau, gruenlich
+
+Erkennbarkeit:
+MAT_MISC_MINERAL:33
+MAT_ORTHOKLAS
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_OSMIUM b/doc/materials/materials/MAT_OSMIUM
new file mode 100644
index 0000000..7ab21a0
--- /dev/null
+++ b/doc/materials/materials/MAT_OSMIUM
@@ -0,0 +1,22 @@
+Materialid:
+MAT_OSMIUM               "Os"
+
+Name:
+"Osmium" "Osmiums" "Osmium" "Osmium"
+
+Geschlecht:
+N
+
+Beschreibung:
+schwerstes Metall
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:5
+MAT_PLATINUM:25
+MAT_OSMIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
+MATGROUP_PRECIOUS_METAL:100
diff --git a/doc/materials/materials/MAT_PAPER b/doc/materials/materials/MAT_PAPER
new file mode 100644
index 0000000..4a7820d
--- /dev/null
+++ b/doc/materials/materials/MAT_PAPER
@@ -0,0 +1,21 @@
+Materialid:
+MAT_PAPER                "paper"
+
+Name:
+"Papier" "Papiers" "Papier" "Papier"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_PAPER:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PAPYRUS b/doc/materials/materials/MAT_PAPYRUS
new file mode 100644
index 0000000..e5ee8c1
--- /dev/null
+++ b/doc/materials/materials/MAT_PAPYRUS
@@ -0,0 +1,21 @@
+Materialid:
+MAT_PAPYRUS              "papyrus"
+
+Name:
+"Papyrus" "Papyruss" "Papyrus" "Papyrus"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_PAPER:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PARFUM b/doc/materials/materials/MAT_PARFUM
new file mode 100644
index 0000000..a704fd9
--- /dev/null
+++ b/doc/materials/materials/MAT_PARFUM
@@ -0,0 +1,17 @@
+Materialid:
+MAT_PARFUM               "parfum"
+
+Name:
+"Parfuem" "Parfuems" "Parfuem" "Parfuem"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_PATENT_LEATHER b/doc/materials/materials/MAT_PATENT_LEATHER
new file mode 100644
index 0000000..c4fc177
--- /dev/null
+++ b/doc/materials/materials/MAT_PATENT_LEATHER
@@ -0,0 +1,20 @@
+Materialid:
+MAT_PATENT_LEATHER       "patent_leather"
+
+Name:
+"Lackleder" "Lackleders" "Lackleder" "Lackleder"
+
+Geschlecht:
+N
+
+Beschreibung:
+Kunstleder
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLEXIBLE:100
+MATGROUP_BIO:100
+MATGROUP_CLOTH:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PEARL b/doc/materials/materials/MAT_PEARL
new file mode 100644
index 0000000..eb56f10
--- /dev/null
+++ b/doc/materials/materials/MAT_PEARL
@@ -0,0 +1,20 @@
+Materialid:
+MAT_PEARL                "pearl"
+
+Name:
+"Perle" "Perle" "Perle" "Perle"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_DEAD:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
diff --git a/doc/materials/materials/MAT_PEARLMOTHER b/doc/materials/materials/MAT_PEARLMOTHER
new file mode 100644
index 0000000..f058dbc
--- /dev/null
+++ b/doc/materials/materials/MAT_PEARLMOTHER
@@ -0,0 +1,19 @@
+Materialid:
+MAT_PEARLMOTHER          "pearlmother"
+
+Name:
+"Perlmutt" "Perlmutts" "Perlmutt" "Perlmutt"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PEAR_WOOD b/doc/materials/materials/MAT_PEAR_WOOD
new file mode 100644
index 0000000..d31ffb5
--- /dev/null
+++ b/doc/materials/materials/MAT_PEAR_WOOD
@@ -0,0 +1,25 @@
+Materialid:
+MAT_PEAR_WOOD            "pear_wood"
+
+Name:
+"Birnbaumholz" "Birnbaumholzes" "Birnbaumholz" "Birnbaumholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+zaeh, trocken, magisch
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:35
+MAT_PEAR_WOOD
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_MAGIC:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_PELT b/doc/materials/materials/MAT_PELT
new file mode 100644
index 0000000..e15566d
--- /dev/null
+++ b/doc/materials/materials/MAT_PELT
@@ -0,0 +1,21 @@
+Materialid:
+MAT_PELT                 "pelt"
+
+Name:
+"Fell" "Felles" "Fell" "Fell"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PENICILLIN b/doc/materials/materials/MAT_PENICILLIN
new file mode 100644
index 0000000..7d79344
--- /dev/null
+++ b/doc/materials/materials/MAT_PENICILLIN
@@ -0,0 +1,21 @@
+Materialid:
+MAT_PENICILLIN           "penicillin"
+
+Name:
+"Penicillin" "Penicillins" "Penicillin" "Penicillin"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_CHALK:50
+MAT_PENICILLIN
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_DEAD:100
+MATGROUP_DRUG:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PERGAMENT b/doc/materials/materials/MAT_PERGAMENT
new file mode 100644
index 0000000..7941178
--- /dev/null
+++ b/doc/materials/materials/MAT_PERGAMENT
@@ -0,0 +1,22 @@
+Materialid:
+MAT_PERGAMENT            "pergament"
+
+Name:
+"Pergament" "Pergaments" "Pergament" "Pergament"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_PAPER:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PHOSPHORUS b/doc/materials/materials/MAT_PHOSPHORUS
new file mode 100644
index 0000000..c5a0fbb
--- /dev/null
+++ b/doc/materials/materials/MAT_PHOSPHORUS
@@ -0,0 +1,18 @@
+Materialid:
+MAT_PHOSPHORUS           "P"
+
+Name:
+"Phosphor" "Phosphors" "Phosphor" "Phosphor"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_POISONOUS:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PINE b/doc/materials/materials/MAT_PINE
new file mode 100644
index 0000000..64e1cdc
--- /dev/null
+++ b/doc/materials/materials/MAT_PINE
@@ -0,0 +1,24 @@
+Materialid:
+MAT_PINE                 "pine"
+
+Name:
+"Kieferholz" "Kiefernholzes" "Kieferholz" "Kieferholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+harzig (Pinie, Kienspan)
+
+Erkennbarkeit:
+MAT_MISC_CONIFER_WOOD:15
+MAT_PINE
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_CONIFER_WOOD:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_PLASTIC b/doc/materials/materials/MAT_PLASTIC
new file mode 100644
index 0000000..6c55327
--- /dev/null
+++ b/doc/materials/materials/MAT_PLASTIC
@@ -0,0 +1,18 @@
+Materialid:
+MAT_PLASTIC              "plastic"
+
+Name:
+"kuenstliches Material" "kuenstlichen Materials" "kuenstlichem Material" "kuenstlichen Material"
+
+Geschlecht:
+N
+
+Beschreibung:
+Kunststoff
+
+Erkennbarkeit:
+MAT_MISC_SOLID:35
+MAT_PLASTIC
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_PLATINUM b/doc/materials/materials/MAT_PLATINUM
new file mode 100644
index 0000000..c1671b5
--- /dev/null
+++ b/doc/materials/materials/MAT_PLATINUM
@@ -0,0 +1,21 @@
+Materialid:
+MAT_PLATINUM             "Pt"
+
+Name:
+"Platin" "Platins" "Platin" "Platin"
+
+Geschlecht:
+N
+
+Beschreibung:
+grauweiss
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:5
+MAT_PLATINUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
+MATGROUP_PRECIOUS_METAL:100
diff --git a/doc/materials/materials/MAT_PLUTONIUM b/doc/materials/materials/MAT_PLUTONIUM
new file mode 100644
index 0000000..e5a2857
--- /dev/null
+++ b/doc/materials/materials/MAT_PLUTONIUM
@@ -0,0 +1,20 @@
+Materialid:
+MAT_PLUTONIUM            "Pu"
+
+Name:
+"Plutonium" "Plutoniums" "Plutonium" "Plutonium"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_DUST:65
+MAT_PLUTONIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_RADIOACTIVE:100
+MATGROUP_POISONOUS:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_POPLAR b/doc/materials/materials/MAT_POPLAR
new file mode 100644
index 0000000..8cf6eed
--- /dev/null
+++ b/doc/materials/materials/MAT_POPLAR
@@ -0,0 +1,24 @@
+Materialid:
+MAT_POPLAR               "poplar"
+
+Name:
+"Pappelholz" "Pappelholzes" "Pappelholz" "Pappelholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+sehr weich, faserig
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:25
+MAT_POPLAR
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_QUARTZ b/doc/materials/materials/MAT_QUARTZ
new file mode 100644
index 0000000..da78786
--- /dev/null
+++ b/doc/materials/materials/MAT_QUARTZ
@@ -0,0 +1,19 @@
+Materialid:
+MAT_QUARTZ               "quartz"
+
+Name:
+"Quarz" "Quarzes" "Quarz" "Quarz"
+
+Geschlecht:
+M
+
+Beschreibung:
+klar bis grau, auch gelb
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_ROBINIA b/doc/materials/materials/MAT_ROBINIA
new file mode 100644
index 0000000..3c169a7
--- /dev/null
+++ b/doc/materials/materials/MAT_ROBINIA
@@ -0,0 +1,24 @@
+Materialid:
+MAT_ROBINIA              "robinia"
+
+Name:
+"Robinienholz" "Robinienholzes" "Robinienholz" "Robinienholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+sehr hart
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:5
+MAT_ROBINIA
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_ROSEWOOD b/doc/materials/materials/MAT_ROSEWOOD
new file mode 100644
index 0000000..b9ff362
--- /dev/null
+++ b/doc/materials/materials/MAT_ROSEWOOD
@@ -0,0 +1,24 @@
+Materialid:
+MAT_ROSEWOOD             "rosewood"
+
+Name:
+"Palisander" "Palisanders" "Palisander" "Palisander"
+
+Geschlecht:
+M
+
+Beschreibung:
+schokoladenbraun
+
+Erkennbarkeit:
+MAT_MISC_TROPICAL_WOOD:-5
+MAT_ROSEWOOD
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_TROPICAL_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_RUBY b/doc/materials/materials/MAT_RUBY
new file mode 100644
index 0000000..2f03c75
--- /dev/null
+++ b/doc/materials/materials/MAT_RUBY
@@ -0,0 +1,21 @@
+Materialid:
+MAT_RUBY                 "ruby"
+
+Name:
+"Rubin" "Rubins" "Rubin" "Rubin"
+
+Geschlecht:
+M
+
+Beschreibung:
+rot
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:25
+MAT_RUBY
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_SALPETER b/doc/materials/materials/MAT_SALPETER
new file mode 100644
index 0000000..aaca1be
--- /dev/null
+++ b/doc/materials/materials/MAT_SALPETER
@@ -0,0 +1,17 @@
+Materialid:
+MAT_SALPETER             "salpeter"
+
+Name:
+"Salpeter" "Salpeters" "Salpeter" "Salpeter"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SALT b/doc/materials/materials/MAT_SALT
new file mode 100644
index 0000000..1d54a9e
--- /dev/null
+++ b/doc/materials/materials/MAT_SALT
@@ -0,0 +1,18 @@
+Materialid:
+MAT_SALT                 "natriumchloride"
+
+Name:
+"Salz" "Salzes" "Salz" "Salz"
+
+Geschlecht:
+N
+
+Beschreibung:
+Kochsalz
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_EATABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SAND b/doc/materials/materials/MAT_SAND
new file mode 100644
index 0000000..af33552
--- /dev/null
+++ b/doc/materials/materials/MAT_SAND
@@ -0,0 +1,17 @@
+Materialid:
+MAT_SAND                 "sand"
+
+Name:
+"Sand" "Sands" "Sand" "Sand"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SANDAL b/doc/materials/materials/MAT_SANDAL
new file mode 100644
index 0000000..f76590d
--- /dev/null
+++ b/doc/materials/materials/MAT_SANDAL
@@ -0,0 +1,24 @@
+Materialid:
+MAT_SANDAL               "sandal"
+
+Name:
+"Sandelholz" "Sandelholzes" "Sandelholz" "Sandelholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+gut riechend, kostbar, hart
+
+Erkennbarkeit:
+MAT_MISC_TROPICAL_WOOD:-5
+MAT_SANDAL
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_TROPICAL_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_SAPPHIRE b/doc/materials/materials/MAT_SAPPHIRE
new file mode 100644
index 0000000..436800c
--- /dev/null
+++ b/doc/materials/materials/MAT_SAPPHIRE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_SAPPHIRE             "sapphire"
+
+Name:
+"Saphir" "Saphirs" "Saphir" "Saphir"
+
+Geschlecht:
+M
+
+Beschreibung:
+blau
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:25
+MAT_SAPPHIRE
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_SATIN b/doc/materials/materials/MAT_SATIN
new file mode 100644
index 0000000..f2a6e3b
--- /dev/null
+++ b/doc/materials/materials/MAT_SATIN
@@ -0,0 +1,21 @@
+Materialid:
+MAT_SATIN                "satin"
+
+Name:
+"Satin" "Satins" "Satin" "Satin"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SHADOW b/doc/materials/materials/MAT_SHADOW
new file mode 100644
index 0000000..5de459b
--- /dev/null
+++ b/doc/materials/materials/MAT_SHADOW
@@ -0,0 +1,17 @@
+Materialid:
+MAT_SHADOW               "shadow"
+
+Name:
+"Schatten" "Schattens" "Schatten" "Schatten"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_MISC:100
diff --git a/doc/materials/materials/MAT_SHIT b/doc/materials/materials/MAT_SHIT
new file mode 100644
index 0000000..12d05d4
--- /dev/null
+++ b/doc/materials/materials/MAT_SHIT
@@ -0,0 +1,17 @@
+Materialid:
+MAT_SHIT                 "shit"
+
+Name:
+"Scheisse" "Scheisse" "Scheisse" "Scheisse"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SILK b/doc/materials/materials/MAT_SILK
new file mode 100644
index 0000000..eabdec8
--- /dev/null
+++ b/doc/materials/materials/MAT_SILK
@@ -0,0 +1,22 @@
+Materialid:
+MAT_SILK                 "silk"
+
+Name:
+"Seide" "Seide" "Seide" "Seide"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SILVER b/doc/materials/materials/MAT_SILVER
new file mode 100644
index 0000000..e4447e5
--- /dev/null
+++ b/doc/materials/materials/MAT_SILVER
@@ -0,0 +1,19 @@
+Materialid:
+MAT_SILVER               "Ag"
+
+Name:
+"Silber" "Silbers" "Silber" "Silber"
+
+Geschlecht:
+N
+
+Beschreibung:
+weiss
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
+MATGROUP_PRECIOUS_METAL:100
diff --git a/doc/materials/materials/MAT_SKIN b/doc/materials/materials/MAT_SKIN
new file mode 100644
index 0000000..231c8f0
--- /dev/null
+++ b/doc/materials/materials/MAT_SKIN
@@ -0,0 +1,20 @@
+Materialid:
+MAT_SKIN                 "skin"
+
+Name:
+"Haut" "Haut" "Haut" "Haut"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLEXIBLE:100
+MATGROUP_DEAD:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SLATE b/doc/materials/materials/MAT_SLATE
new file mode 100644
index 0000000..87fd40c
--- /dev/null
+++ b/doc/materials/materials/MAT_SLATE
@@ -0,0 +1,18 @@
+Materialid:
+MAT_SLATE                "slate"
+
+Name:
+"Schiefer" "Schiefers" "Schiefer" "Schiefer"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_STONE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SLIME b/doc/materials/materials/MAT_SLIME
new file mode 100644
index 0000000..49c08a9
--- /dev/null
+++ b/doc/materials/materials/MAT_SLIME
@@ -0,0 +1,17 @@
+Materialid:
+MAT_SLIME                "slime"
+
+Name:
+"Schleim" "Schleims" "Schleim" "Schleim"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_SOAP b/doc/materials/materials/MAT_SOAP
new file mode 100644
index 0000000..b791da9
--- /dev/null
+++ b/doc/materials/materials/MAT_SOAP
@@ -0,0 +1,18 @@
+Materialid:
+MAT_SOAP                 "soap"
+
+Name:
+"Seife" "Seifes" "Seife" "Seife"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLUID:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SODIUM b/doc/materials/materials/MAT_SODIUM
new file mode 100644
index 0000000..30c8db4
--- /dev/null
+++ b/doc/materials/materials/MAT_SODIUM
@@ -0,0 +1,21 @@
+Materialid:
+MAT_SODIUM               "Na"
+
+Name:
+"Natrium" "Natriums" "Natrium" "Natrium"
+
+Geschlecht:
+N
+
+Beschreibung:
+Wasser-Vorsicht
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_ALUMINIUM:30
+MAT_SODIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SPRUCE b/doc/materials/materials/MAT_SPRUCE
new file mode 100644
index 0000000..699f4f9
--- /dev/null
+++ b/doc/materials/materials/MAT_SPRUCE
@@ -0,0 +1,24 @@
+Materialid:
+MAT_SPRUCE               "spruce"
+
+Name:
+"Fichtenholz" "Fichtenholzes" "Fichtenholz" "Fichtenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+trocken, bruechig
+
+Erkennbarkeit:
+MAT_MISC_CONIFER_WOOD:15
+MAT_SPRUCE
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_CONIFER_WOOD:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_STEEL b/doc/materials/materials/MAT_STEEL
new file mode 100644
index 0000000..fdc6cad
--- /dev/null
+++ b/doc/materials/materials/MAT_STEEL
@@ -0,0 +1,19 @@
+Materialid:
+MAT_STEEL                "steel"
+
+Name:
+"Stahl" "Stahls" "Stahl" "Stahl"
+
+Geschlecht:
+N
+
+Beschreibung:
+hart, flexibel
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_MAGNETIC:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_STRAW b/doc/materials/materials/MAT_STRAW
new file mode 100644
index 0000000..0882c0c
--- /dev/null
+++ b/doc/materials/materials/MAT_STRAW
@@ -0,0 +1,20 @@
+Materialid:
+MAT_STRAW                "straw"
+
+Name:
+"Stroh" "Strohs" "Stroh" "Stroh"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_HERBAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_SULFUR b/doc/materials/materials/MAT_SULFUR
new file mode 100644
index 0000000..caf8a5b
--- /dev/null
+++ b/doc/materials/materials/MAT_SULFUR
@@ -0,0 +1,20 @@
+Materialid:
+MAT_SULFUR               "S"
+
+Name:
+"Schwefel" "Schwefels" "Schwefel" "Schwefel"
+
+Geschlecht:
+M
+
+Beschreibung:
+gelb
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_TALLOW b/doc/materials/materials/MAT_TALLOW
new file mode 100644
index 0000000..72ebf0b
--- /dev/null
+++ b/doc/materials/materials/MAT_TALLOW
@@ -0,0 +1,20 @@
+Materialid:
+MAT_TALLOW               "tallow"
+
+Name:
+"Talg" "Talgs" "Talg" "Talg"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_DEAD:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_TAR b/doc/materials/materials/MAT_TAR
new file mode 100644
index 0000000..edad3ca
--- /dev/null
+++ b/doc/materials/materials/MAT_TAR
@@ -0,0 +1,17 @@
+Materialid:
+MAT_TAR                  "tar"
+
+Name:
+"Teer" "Teers" "Teer" "Teer"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_TEAK b/doc/materials/materials/MAT_TEAK
new file mode 100644
index 0000000..3a2d767
--- /dev/null
+++ b/doc/materials/materials/MAT_TEAK
@@ -0,0 +1,24 @@
+Materialid:
+MAT_TEAK                 "teak"
+
+Name:
+"Teakholz" "Teakholzes" "Teakholz" "Teakholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_TROPICAL_WOOD:25
+MAT_TEAK
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_TROPICAL_WOOD:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_THALLIUM b/doc/materials/materials/MAT_THALLIUM
new file mode 100644
index 0000000..45ce091
--- /dev/null
+++ b/doc/materials/materials/MAT_THALLIUM
@@ -0,0 +1,22 @@
+Materialid:
+MAT_THALLIUM             "thallium"
+
+Name:
+"Thallium" "Thalliums" "Thallium" "Thallium"
+
+Geschlecht:
+N
+
+Beschreibung:
+giftig, schwer, weich
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_LEAD:50
+MAT_THALLIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_FLEXIBLE:100
+MATGROUP_METAL:100
+MATGROUP_POISONOUS:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_TIN b/doc/materials/materials/MAT_TIN
new file mode 100644
index 0000000..8f29454
--- /dev/null
+++ b/doc/materials/materials/MAT_TIN
@@ -0,0 +1,22 @@
+Materialid:
+MAT_TIN                  "Sn"
+
+Name:
+"Zinn" "Zinns" "Zinn" "Zinn"
+
+Geschlecht:
+N
+
+Beschreibung:
+sehr weich, weiss
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:15
+MAT_LEAD:30
+MAT_TIN
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_TITANIUM b/doc/materials/materials/MAT_TITANIUM
new file mode 100644
index 0000000..7c54374
--- /dev/null
+++ b/doc/materials/materials/MAT_TITANIUM
@@ -0,0 +1,20 @@
+Materialid:
+MAT_TITANIUM             "Ti"
+
+Name:
+"Titan" "Titans" "Titan" "Titan"
+
+Geschlecht:
+N
+
+Beschreibung:
+aeusserst hart
+
+Erkennbarkeit:
+MAT_MISC_METAL:10
+MAT_STEEL:20
+MAT_TITANIUM
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_TNT b/doc/materials/materials/MAT_TNT
new file mode 100644
index 0000000..b9af3ec
--- /dev/null
+++ b/doc/materials/materials/MAT_TNT
@@ -0,0 +1,19 @@
+Materialid:
+MAT_TNT                  "tnt"
+
+Name:
+"TNT" "TNT" "TNT" "TNT"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_EXPLOSIVE:100
diff --git a/doc/materials/materials/MAT_TOOTH b/doc/materials/materials/MAT_TOOTH
new file mode 100644
index 0000000..e4588a5
--- /dev/null
+++ b/doc/materials/materials/MAT_TOOTH
@@ -0,0 +1,20 @@
+Materialid:
+MAT_TOOTH                "tooth"
+
+Name:
+"Zahn" "Zahns" "Zahn" "Zahn"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_BIO:100
+MATGROUP_DEAD:100
+MATGROUP_SOLID:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_TOPAZ b/doc/materials/materials/MAT_TOPAZ
new file mode 100644
index 0000000..d39d5e1
--- /dev/null
+++ b/doc/materials/materials/MAT_TOPAZ
@@ -0,0 +1,21 @@
+Materialid:
+MAT_TOPAZ                "topaz"
+
+Name:
+"Topas" "Topas" "Topas" "Topas"
+
+Geschlecht:
+M
+
+Beschreibung:
+gelb
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:25
+MAT_TOPAZ
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_TUNGSTEN b/doc/materials/materials/MAT_TUNGSTEN
new file mode 100644
index 0000000..7a7c643
--- /dev/null
+++ b/doc/materials/materials/MAT_TUNGSTEN
@@ -0,0 +1,19 @@
+Materialid:
+MAT_TUNGSTEN             "W"
+
+Name:
+"Wolfram" "Wolframs" "Wolfram" "Wolfram"
+
+Geschlecht:
+N
+
+Beschreibung:
+sehr hart, hitzebestaendig
+
+Erkennbarkeit:
+MAT_MISC_METAL:25
+MAT_TUNGSTEN
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_TURQUOISE b/doc/materials/materials/MAT_TURQUOISE
new file mode 100644
index 0000000..dfe30f9
--- /dev/null
+++ b/doc/materials/materials/MAT_TURQUOISE
@@ -0,0 +1,21 @@
+Materialid:
+MAT_TURQUOISE            "turquoise"
+
+Name:
+"Tuerkis" "Tuerkis" "Tuerkis" "Tuerkis"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+MAT_MISC_JEWEL:25
+MAT_TURQUOISE
+
+Gruppenzugehoerigkeit:
+MATGROUP_MINERAL:100
+MATGROUP_SOLID:100
+MATGROUP_JEWEL:100
+MATGROUP_STONE:100
diff --git a/doc/materials/materials/MAT_VELVET b/doc/materials/materials/MAT_VELVET
new file mode 100644
index 0000000..e2a5634
--- /dev/null
+++ b/doc/materials/materials/MAT_VELVET
@@ -0,0 +1,21 @@
+Materialid:
+MAT_VELVET               "velvet"
+
+Name:
+"Samt" "Samts" "Samt" "Samt"
+
+Geschlecht:
+M
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_CLOTH:100
+MATGROUP_BIO:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_WATER b/doc/materials/materials/MAT_WATER
new file mode 100644
index 0000000..900498f
--- /dev/null
+++ b/doc/materials/materials/MAT_WATER
@@ -0,0 +1,18 @@
+Materialid:
+MAT_WATER                "water"
+
+Name:
+"Wasser" "Wassers" "Wasser" "Wasser"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_ELEMENTAL:100
+MATGROUP_FLUID:100
diff --git a/doc/materials/materials/MAT_WAX b/doc/materials/materials/MAT_WAX
new file mode 100644
index 0000000..baa163c
--- /dev/null
+++ b/doc/materials/materials/MAT_WAX
@@ -0,0 +1,17 @@
+Materialid:
+MAT_WAX                  "wax"
+
+Name:
+"Wachs" "Wachses" "Wachs" "Wachs"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_WECKAMIN b/doc/materials/materials/MAT_WECKAMIN
new file mode 100644
index 0000000..d22becb
--- /dev/null
+++ b/doc/materials/materials/MAT_WECKAMIN
@@ -0,0 +1,18 @@
+Materialid:
+MAT_WECKAMIN             "weckamine"
+
+Name:
+"Aufputschmittel" "Aufputschmittels" "Aufputschmittel" "Aufputschmittel"
+
+Geschlecht:
+N
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DRUG:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_WILLOW b/doc/materials/materials/MAT_WILLOW
new file mode 100644
index 0000000..0e5f0ef
--- /dev/null
+++ b/doc/materials/materials/MAT_WILLOW
@@ -0,0 +1,25 @@
+Materialid:
+MAT_WILLOW               "willow"
+
+Name:
+"Weidenholz" "Weidenholzes" "Weidenholz" "Weidenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+weich und flexibel
+
+Erkennbarkeit:
+MAT_MISC_DECIDUOUS_WOOD:5
+MAT_WILLOW
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_HERBAL:100
+MATGROUP_DECIDUOUS_WOOD:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
diff --git a/doc/materials/materials/MAT_WOODEN_PLANT b/doc/materials/materials/MAT_WOODEN_PLANT
new file mode 100644
index 0000000..0c9c795
--- /dev/null
+++ b/doc/materials/materials/MAT_WOODEN_PLANT
@@ -0,0 +1,22 @@
+Materialid:
+MAT_WOODEN_PLANT         "wooden_plant"
+
+Name:
+"Baum" "Baumes" "Baum" "Baum"
+
+Geschlecht:
+M
+
+Beschreibung:
+Pflanzen mit Holzanteil (Baeume, Gebuesche)
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_HERBAL:100
+MATGROUP_BIO:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_SOLID:100
+MATGROUP_WOOD:100
+MATGROUP_LIVING:100
diff --git a/doc/materials/materials/MAT_WOOL b/doc/materials/materials/MAT_WOOL
new file mode 100644
index 0000000..8e2ae07
--- /dev/null
+++ b/doc/materials/materials/MAT_WOOL
@@ -0,0 +1,22 @@
+Materialid:
+MAT_WOOL                 "wool"
+
+Name:
+"Wolle" "Wolle" "Wolle" "Wolle"
+
+Geschlecht:
+F
+
+Beschreibung:
+- nicht vorhanden -
+
+Erkennbarkeit:
+- keine Einschraenkung -
+
+Gruppenzugehoerigkeit:
+MATGROUP_DEAD:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_CLOTH:100
+MATGROUP_SOLID:100
diff --git a/doc/materials/materials/MAT_YEW b/doc/materials/materials/MAT_YEW
new file mode 100644
index 0000000..cef8f66
--- /dev/null
+++ b/doc/materials/materials/MAT_YEW
@@ -0,0 +1,26 @@
+Materialid:
+MAT_YEW                  "yew"
+
+Name:
+"Eibenholz" "Eibenholzes" "Eibenholz" "Eibenholz"
+
+Geschlecht:
+N
+
+Beschreibung:
+zaeh, biegsam
+
+Erkennbarkeit:
+MAT_MISC_CONIFER_WOOD:5
+MAT_YEW
+
+Gruppenzugehoerigkeit:
+MATGROUP_INFLAMMABLE:100
+MATGROUP_BIO:100
+MATGROUP_SOLID:100
+MATGROUP_POISONOUS:100
+MATGROUP_WOOD:100
+MATGROUP_HERBAL:100
+MATGROUP_CONIFER_WOOD:100
+MATGROUP_DEAD:100
+MATGROUP_FLEXIBLE:100
diff --git a/doc/materials/materials/MAT_ZINC b/doc/materials/materials/MAT_ZINC
new file mode 100644
index 0000000..4970e17
--- /dev/null
+++ b/doc/materials/materials/MAT_ZINC
@@ -0,0 +1,22 @@
+Materialid:
+MAT_ZINC                 "zinc"
+
+Name:
+"Zink" "Zinks" "Zink" "Zink"
+
+Geschlecht:
+N
+
+Beschreibung:
+weich, bestaendig
+
+Erkennbarkeit:
+MAT_MISC_METAL:0
+MAT_SILVER:15
+MAT_LEAD:30
+MAT_ZINC
+
+Gruppenzugehoerigkeit:
+MATGROUP_METAL:100
+MATGROUP_FLEXIBLE:100
+MATGROUP_SOLID:100
diff --git a/doc/mcmd/.readme b/doc/mcmd/.readme
new file mode 100644
index 0000000..017db98
--- /dev/null
+++ b/doc/mcmd/.readme
@@ -0,0 +1,3 @@
+Hier findest Du Hilfeseiten zu den Befehlen, die die Magiershell zur
+Verfuegung stellt.
+
diff --git a/doc/mcmd/.synonym b/doc/mcmd/.synonym
new file mode 100644
index 0000000..1f6138a
--- /dev/null
+++ b/doc/mcmd/.synonym
@@ -0,0 +1,3 @@
+heal heile
+peace frieden
++ goto
diff --git a/doc/mcmd/addguildmaster b/doc/mcmd/addguildmaster
new file mode 100644
index 0000000..3bab6dd
--- /dev/null
+++ b/doc/mcmd/addguildmaster
@@ -0,0 +1,25 @@
+
+addguildmaster
+--------------
+
+ ERZMAGIERKOMMANDO:
+    addguildmaster <name> <gilde>
+
+ ARGUMENTE:
+
+     <name>
+        Name des Magiers
+     <gilde>
+        Name einer Gilde
+
+ BESCHREIBUNG:
+    Der Magier <name> wird zum Gildenmagier fuer die Gilde <gilde> 
+    ernannt.
+
+    Dieser Befehl steht nur Goettern zur Verfuegung.
+
+ SIEHE AUCH:
+    removeguildmaster, gilden
+
+ LETZTE AeNDERUNG:
+    2003-12-10, Zook
diff --git a/doc/mcmd/addmaster b/doc/mcmd/addmaster
new file mode 100644
index 0000000..20689e6
--- /dev/null
+++ b/doc/mcmd/addmaster
@@ -0,0 +1,24 @@
+
+addmaster
+---------
+
+ ERZMAGIERKOMMANDO:
+    addmaster <name> <region>
+
+ ARGUMENTE:
+
+     <name>
+        Name des Magiers
+     <region>
+        Eine Region
+
+ BESCHREIBUNG:
+    Der Magier <name> wird in der Region <region> zum Regionsmagier ernannt.
+
+    Dieser Befehl steht nur Erzmagiern und Goettern zur Verfuegung.
+
+ SIEHE AUCH:
+    removemaster, regionen
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/at b/doc/mcmd/at
new file mode 100644
index 0000000..0315b73
--- /dev/null
+++ b/doc/mcmd/at
@@ -0,0 +1,33 @@
+
+at
+--
+
+ MAGIERKOMMANDO:
+    at <name> <kommando>
+
+ ARGUMENTE:
+
+     <raum>
+        Name eines Lebewesens
+     <kommando>
+        das auzufuehrende Kommando
+
+ BESCHREIBUNG:
+    Du wirst, unsichtbar fuer die Anwesenden, in den Raum transportiert, in
+    dem sich das Lebewesen <name> befindet. Dort fuehrst Du das Kommando
+    <kommando> aus und gelangst automatisch wieder in den Raum zurueck, in dem
+    Du vorher warst.
+
+ BEISPIELE:
+    Catweazle macht mal wieder Faxen?
+
+    > at catweazle wuerge catweazle
+
+    Die Umstehenden sehen dann zwar die Meldungen des Kommandos, aber man
+    selbst befindet sich sofort wieder in Sicherheit :)
+
+ SIEHE AUCH:
+    in, goto
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/banish b/doc/mcmd/banish
new file mode 100644
index 0000000..07104ef
--- /dev/null
+++ b/doc/mcmd/banish
@@ -0,0 +1,38 @@
+
+banish
+------
+
+ MAGIERKOMMANDO:
+    banish [-f] <name> [<grund>]
+
+ ARGUMENTE:
+
+    -f (optional)
+        Sperrung erzwingen
+     <name>
+        Der zu sperrende Name
+     <grund> (optional)
+        Der Grund der Sperre
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kann man bestimmte Namen sperren, so dass sich keine
+    Spieler mit gleichem Namen einloggen koennen. Sinnvoll ist dies z.B. bei
+    Namen von NPCs oder Oertlichkeiten, wo es ggf. zu Verwirrungen kommen
+    koennte.
+
+    Als gute Praxis sollte man in den Grund auch angeben, fuer welchen 
+    Magier der Name gesperrt wurde. 
+
+    Mit der Option -f kann man auch Namen von existenten Spielern banishen.
+    Diese koennen sich weiterhin noch einloggen, aber sobald der Spieler sich
+    loescht, ist der Name gesperrt.
+
+    Mit dem Grund 'loeschen' koennen gesperrte Namen wieder freigegeben werden.
+
+    Dieser Befehl kann nur von Regions- und hoeheren Magiern ausgefuehrt werden.
+
+ SIEHE AUCH:
+    mbanish, tbanish, sbanish
+
+ LETZTE AeNDERUNG:
+    Don,  2. Mai 2013, 11:45:08 von Zook
diff --git a/doc/mcmd/cat b/doc/mcmd/cat
new file mode 100644
index 0000000..64ab02b
--- /dev/null
+++ b/doc/mcmd/cat
@@ -0,0 +1,23 @@
+
+cat
+---
+
+ MAGIERKOMMANDO:
+    cat <datei>
+
+ ARGUMENTE:
+
+     <datei>
+        Die auszugebende Datei
+
+ BESCHREIBUNG:
+    Bis zu 40 Zeilen der Datei <datei> werden ausgegeben. Beim Abbruch
+    erscheint die Meldung
+
+    *****TRUNCATED****
+
+ SIEHE AUCH:
+    head, tail, more
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/cd b/doc/mcmd/cd
new file mode 100644
index 0000000..8d774b6
--- /dev/null
+++ b/doc/mcmd/cd
@@ -0,0 +1,37 @@
+
+cd
+--
+
+ MAGIERKOMMANDO:
+    cd [ - ] [ -l ] [ -s ] [ <Verzeichnis> ]
+
+ ARGUMENTE:
+
+     <Verzeichnis>  neuer Pfad, der gesetzt werden soll
+
+ BESCHREIBUNG:
+    Das aktuelle Verzeichnis wird auf <Verzeichnis> gesetzt.
+
+    Laesst man <Verzeichnis> weg, wird das aktuelle Verzeichnis auf das
+    Heimatverzeichnis gesetzt. Bei einem Magier mit Magierlevel 15 ist dies
+    das Verzeichnis `/doc', ab Magierlevel 20 das Verzeichnis
+    `/players/<Magiername>'.
+
+    Bei Eindeutigkeit koennen Platzhalter verwendet werden. Die Befehle 
+    cd /std/player/shadows und cd /*/pl*/sh* bewirken dasselbe.
+
+    Mit der Option - wird direkt ins letzte Verzeichnis gewechselt.
+
+    Mit den Optionen -l und -s kann man die Behandlung von `.readme'-Dateien
+    im Zielverzeichnis einstellen. Mit der Option -s wird die Ausgabe der
+    `.readme'-Dateien verhindert, mit -l dagegen erlaubt.
+
+    Ueber die Variable 'CD_SHORT' kann eingestellt werden, ob `.readme'-
+    Dateien grundsaetzlich unterdrueckt werden sollen. Dazu einfach 
+    'set CD_SHORT 1' eingeben
+
+ SIEHE AUCH:
+    prompt, pwd, ls, set
+
+ LETZTE AENDERUNG:
+    03.06.2015, Bugfix
diff --git a/doc/mcmd/clone b/doc/mcmd/clone
new file mode 100644
index 0000000..04f4627
--- /dev/null
+++ b/doc/mcmd/clone
@@ -0,0 +1,36 @@
+
+clone
+-----
+
+ MAGIERKOMMANDO:
+    clone [-f] <objektname>
+
+ ARGUMENTE:
+
+     <objektname> Dateiname des Objektes, das erzeugt werden soll
+
+ OPTIONEN:
+
+     -f:  Erzwingt den Versuch des Clonens ohne Ueberpruefung, ob eine
+          Datei existiert. Diese Option sollte nur in Ausnahmefaellen
+          verwendet werden, da Fehlschlaege sofort als Fehlermeldung im
+          Driverlog auftauchen.
+
+ BESCHREIBUNG:
+    Eine Kopie von einem Objekt, das im File <objektname> beschrieben ist,
+    wird erzeugt. Das Objekt befindet sich danach im Inventar des Magiers
+    oder (wenn in dem Objekt P_NOGET gesetzt ist) im gleichen Raum wie der
+    Magier.
+
+    Die Blueprint wird zu nichts anderem gebraucht, als Kopien zu erzeugen.
+
+    Wenn ein Objekt noch nicht geladen ist, wird es neu geladen.
+
+    Raeume sollten niemals geclont werden, da sie immer nur einmal existieren
+    sollten und nicht in mehrern Kopien.
+
+ SIEHE AUCH:
+    load, destruct, upd, setcmsg
+
+ LETZTE AENDERUNG:
+    Mit, 05.06.2003, 18:00:00 von Mandragon
diff --git a/doc/mcmd/cp b/doc/mcmd/cp
new file mode 100644
index 0000000..b5cf5b5
--- /dev/null
+++ b/doc/mcmd/cp
@@ -0,0 +1,45 @@
+
+cp
+--
+
+ MAGIERKOMMANDO:
+    cp [ -irfv ] <von> <nach>
+    cp [ -irfv ] <von_1> [ ... <von_n> ] <verz>
+    cp [ -irfvm ] <von_1> [ ... <von_n> ] <verz> <maske>
+ 
+ ARGUMENTE:
+
+     <von>   Name der Quelldatei
+     <von_x> Name von Quelldateien oder -verzeichnissen
+     <nach>  Name der Zieldatei
+     <verz>  Name des Zielverzeichnisses
+     <maske> Dateimaske
+
+ BESCHREIBUNG:
+    Die Datei <von> wird nach Datei <nach> kopiert, bzw. die Datei(en) <von_1>
+    (- <von_n>) in das Verzeichnis <verz>.
+
+    Die Dateinamen koennen auch Muster wie * oder ? enthalten.
+
+    Zusaetzlich koennen folgende Flags angegeben werden:
+
+     -i  Vor jedem kopieren wird gefragt, ob kopiert werden soll
+     -r  Unterverzeichnisse werden rekursiv kopiert
+     -f  Vor dem Ueberschreiben einer existierenden Datei wird nicht gefragt
+     -v  Es wird jeder Arbeitsschritt auf dem Bildschirm ausgegeben
+     -m  Es werden nur Dateien kopiert, die der Maske <maske> entsprechen.
+         Letzere wird im glob-Format angegeben. (z.B. *.c, save*.o)
+    
+ BEISPIELE:
+
+    > cp datei1 datei2
+    > cp *.c temp
+    > cp /doc/s* .
+    > cp -irm /doc ~/KURS *.c 
+    > cp -rf ~mandragon/meloran /d/inseln/mandragon
+
+ SIEHE AUCH:
+    mv, rm, mkdir, rmdir
+
+ LETZTE AENDERUNG:
+    Mit, 02.10.2002, 02:00:00 von Mandragon
diff --git a/doc/mcmd/destruct b/doc/mcmd/destruct
new file mode 100644
index 0000000..e85ed4c
--- /dev/null
+++ b/doc/mcmd/destruct
@@ -0,0 +1,30 @@
+
+destruct
+--------
+
+ MAGIERKOMMANDO:
+    destruct <objekt>
+
+ ARGUMENTE:
+
+     <objekt>   ID eines Objektes
+
+ BESCHREIBUNG:
+    Wenn es ein Objekt in der Umgebung (Inventory, Raum) gibt, das auf
+    <objekt> anspricht, wird dieses Objekt zerstoert.
+
+    In dem Objekt wird remove() aufgerufen, um es zu zerstoeren. Falls dies
+    nicht zur Zerstoerung des Objektes fuehrt (weil das Objekt gar kein
+    remove() definiert oder die remove()-Funktion das Zerstoeren verhindert),
+    bleibt das Objekt erhalten.
+
+ BEMERKUNGEN:
+    Spieler duerfen niemals zerstoert werden!
+
+ SIEHE AUCH:
+    load, clone, upd, setdmsg,
+    remove(L), destruct(E)
+
+ LETZTE AENDERUNG:
+    11.06.2014, Zesstra
+
diff --git a/doc/mcmd/do b/doc/mcmd/do
new file mode 100644
index 0000000..180f453
--- /dev/null
+++ b/doc/mcmd/do
@@ -0,0 +1,30 @@
+
+do
+--
+
+ MAGIERKOMMANDO:
+    do <cmds>
+
+ ARGUMENTE:
+
+     <cmds>
+        Liste von Befehlen (mit `;' getrennt)
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kann man mehrere andere Befehle nacheinander ausfuehren.
+    Dies laesst sich zum Beispiel im Zusammenhang mit Aliasen ausnutzen.
+
+    Die einzelnen Befehle werden durch Semikolons (`;') getrennt; in den
+    Befehlen selbst duerfen keine Semikolons vorkommen.
+
+ BEISPIELE:
+    Wenn man sein Erscheinen in der Abenteurergilde mit einem freundlichen
+    Gruss verbinden moechte, koennte man folgendermassen vorgehen:
+
+    > do goto /gilden/abenteurer; sag Hallo!
+
+ SIEHE AUCH:
+    alias
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/echoall b/doc/mcmd/echoall
new file mode 100644
index 0000000..3abefd3
--- /dev/null
+++ b/doc/mcmd/echoall
@@ -0,0 +1,24 @@
+
+echoall
+-------
+
+ MAGIERKOMMANDO:
+    echoall <text>
+
+ ARGUMENTE:
+
+     <text>
+        ein beliebiger Text
+
+ BESCHREIBUNG:
+    Der Text <text> wird an alle Spieler im MUD geschickt.
+
+    Der Befehl sollte mit groesster Sorgfalt behandelt werden. In diesem
+    Zusammenhang sei auch nochmal darauf hingewiesen, dass Echos in fremdem
+    Namen nicht erlaubt sind.
+
+ SIEHE AUCH:
+    vertrag, emote, echo, echoto, mecho, teile (mit)
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 16:54:18 von Wargon
diff --git a/doc/mcmd/echoto b/doc/mcmd/echoto
new file mode 100644
index 0000000..5528312
--- /dev/null
+++ b/doc/mcmd/echoto
@@ -0,0 +1,26 @@
+
+echoto
+------
+
+ MAGIERKOMMANDO:
+    echoto <name> <text>
+
+ ARGUMENTE:
+
+     <name>
+        Name eines (eingeloggten) Spielers oder NPCs
+     <text>
+        ein beliebiger Text
+
+ BESCHREIBUNG:
+    Der Text <text> wird an das Lebewesen <name> geschickt.
+
+    Der Befehl sollte mit Sorgfalt behandelt werden. In diesem Zusammenhang
+    sei auch nochmal darauf hingewiesen, dass Echos in fremdem Namen nicht
+    erlaubt sind.
+
+ SIEHE AUCH:
+    vertrag, emote, echo, echoall, mecho, teile (mit)
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 16:54:38 von Wargon
diff --git a/doc/mcmd/ed b/doc/mcmd/ed
new file mode 100644
index 0000000..8fc5be1
--- /dev/null
+++ b/doc/mcmd/ed
@@ -0,0 +1,47 @@
+
+ed
+--
+
+ MAGIERKOMMANDO:
+    ed <datei> [...]
+
+ ARGUMENTE:
+
+     <datei> [...]
+        Name(n) der zu bearbeitenden Datei(en)
+
+ BESCHREIBUNG:
+    Startet den Editor nacheinander mit jeder angegebenen Datei.
+
+    Die Dateinamen koennen auch Muster wie * oder ? enthalten.
+
+    Der Editor ist im grossen und ganzen kompatibel zum UNIX Editor ed. Er ist
+    zeilenorientiert und funktioniert nach einem einfachen Prinzip.
+
+    Es gibt zwei Modi: Kommandomodus und Eingabemodus
+
+     Kommandomodus:
+
+         * Hat das Prompt `:'
+         * Akzeptiert Befehle der Art [<addresse>]<befehl>
+           Hierbei besteht <adresse> aus einer Zeilennummer oder aus einer
+           Angabe die mehrere Zeilen adressiert: zeile1,zeile2
+           Die Befehle koennen mit dem Befehl `h' abgerufen werden.
+
+     Eingabemodus:
+
+         * Hat keinen Prompt.
+         * Akzeptiert Eingaben, bis auf einer einzelnen Zeile ein `.'
+           eingegeben wird, das wechselt wieder in den Kommandomodus.
+
+ BEISPIELE:
+
+    > ed test.c
+    > ed *.c
+
+ SIEHE AUCH:
+    more, head, tail, load, clone
+    ed0(LPC), ed1(LPC), ed2(LPC), ed3(LPC), ed4(LPC), ed5(LPC)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/exec b/doc/mcmd/exec
new file mode 100644
index 0000000..6390f0f
--- /dev/null
+++ b/doc/mcmd/exec
@@ -0,0 +1,29 @@
+
+exec
+----
+
+ MAGIERKOMMANDO:
+    exec <datei>
+
+ ARGUMENTE:
+
+     <datei>
+        Dateiname des Zielobjektes
+
+ BESCHREIBUNG:
+    Es wird versucht, einen Clone von <datei> zu erschaffen und Deine
+    Verbindung zum MUD an diesen Clone weiterzugeben. Das Objekt sollte dazu
+    moeglichst eine Rassenshell, zumindest aber `/std/player/base.c' geerbt
+    haben.
+
+    Das Objekt muss die gleiche UID besitzen wie Du (sprich: es muss sich in
+    einem Deiner Verzeichnisse befinden).
+
+    Dieser Befehl kann nur von Regions- und hoeheren Magiern ausgefuehrt
+    werden.
+
+ SIEHE AUCH:
+    exec(E)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/frieden b/doc/mcmd/frieden
new file mode 100644
index 0000000..5f8f10f
--- /dev/null
+++ b/doc/mcmd/frieden
@@ -0,0 +1,24 @@
+
+frieden
+-------
+
+ MAGIERKOMMANDO:
+    frieden [<name>]
+
+ ARGUMENTE:
+
+     <name> (optional)
+        Name eines Lebewesens
+
+ BESCHREIBUNG:
+    Ohne Argument werden alle Kaempfe in dem Raum, in dem Du Dich gerade
+    befindest abgebrochen.
+
+    Mit Argument bricht das Lebewesen <name> den Kampf ab (d.h. es selbst
+    schlaegt nicht mehr zu, und auch seine Feinde greifen es nicht mehr an).
+
+ SIEHE AUCH:
+    stop
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/goto b/doc/mcmd/goto
new file mode 100644
index 0000000..587dda0
--- /dev/null
+++ b/doc/mcmd/goto
@@ -0,0 +1,52 @@
+
+goto
+----
+
+ MAGIERKOMMANDO:
+    goto <ziel>
+    +<magier>
+
+ ARGUMENTE:
+
+     <ziel>
+        Pfadname oder Name eines Lebewesens
+     <magier>
+        Name eines Magiers (mindestens Magierlevel 20)
+
+ BESCHREIBUNG:
+    Mit diesen Befehlen gelangst Du an die gewuenschten Orte im MorgenGrauen.
+
+    Ist <ziel> ein Pfadname, so gelangst Du direkt in den angegebenen Raum.
+
+    Ist <ziel> dagegen der Name eines (eingeloggten) Spielers oder eines NPCs,
+    so wirst Du in den Raum teleportiert, in dem sich das entsprechende
+    Lebewesen aufhaelt.
+    
+    Wenn mehere NPCs des Namens existieren, kann man mit 'goto name nr' den
+    gewuenschten auswaehlen.
+
+    Eine schnelle Art, in den Arbeitsraum des Magiers <magier> zu gelangen,
+    ist das Kommando +<magier>.
+
+    Wenn Du Dich im Verfolgemodus befindet, wird dieser durch den Befehl
+    abgeschaltet.
+
+ BEISPIELE:
+    In Wargons Arbeitsraum steht immer ein NPC namens Errol. Deshalb kann man
+    auf folgende drei Arten in Wargons Arbeitsraum gelangen:
+
+    > goto ~wargon/workroom
+    > goto errol
+    > +wargon
+    
+    Es gibt im Morgengrauen zahlreiche Rehe. Zu den einzelnen gelangt man mit
+    > goto reh 1
+    > goto reh 2
+    > goto reh 3
+    > ...
+
+ SIEHE AUCH:
+    trans, in, at, setmmin, setmmout
+
+ LETZTE AeNDERUNG:
+    Sat, 29.07.2000, 18:00:00 von Silvana
diff --git a/doc/mcmd/grep b/doc/mcmd/grep
new file mode 100644
index 0000000..5b5a72f
--- /dev/null
+++ b/doc/mcmd/grep
@@ -0,0 +1,55 @@
+
+grep
+----
+
+ MAGIERKOMMANDO:
+    grep [ -chilnvrf ] <regexp> <name> [...]
+    grep [ -chilnvrmf ] <regexp> <name> [...] [<maske>]
+
+ ARGUMENTE:
+
+     <regexp>       regulaerer Suchausdruck
+     <name> [...]   Die zu durchsuchende(n) Datei(en) (oder Verzeichnisse)
+     <maske>        Maske, der eine Datei entsprechen muss (glob)
+
+ BESCHREIBUNG:
+    In den angegebenen Dateien wird nach dem regulaeren Ausdruck <regexp>
+    gesucht.
+
+    Die Dateinamen koennen auch Muster wie * oder ? enthalten.
+
+    Zusaetzlich koennen folgende Flags angegeben werden:
+
+     -c  Es wird nur die Zahl der gefundenen Zeilen pro Datei ausgegeben.
+     -h  Die Dateinamen werden nicht mit ausgegeben.
+     -i  Gross- und Kleinschreibung werden ignoriert.
+     -l  Die Dateinamen werden immer mit ausgegeben.
+     -n  Die Zeilennummern der gefundenen Zeilen werden ausgegeben.
+     -v  Es werden die Zeilen ausgegeben, in denen <regexp> *nicht* gefunden
+         wurde.
+     -r  Handelt es sich bei <name> um ein Verzeichnis, werden rekursiv
+         alle darin befindlichen Dateien durchsucht.
+     -m  Es werden nur Dateien durchsucht, die auf die Dateimaske <maske>
+         passen. Letztere wird in glob-Form angegeben.
+     -f  Alle Ausgaben von grep werden in die Datei grep.out im Verzeichnis
+         des Magiers (/players/magiername) ausgegeben.
+
+ BEMERKUNGEN:
+    Das Durchsuchen sehr langer Dateien oder von Verzeichnissen mit sehr
+    vielen Dateien sollte man moeglichst vermeiden, da dies sehr lagintensiv
+    ist.
+
+ BEISPIELE:
+
+    > grep P_N /sys/*.h
+    > grep -n ".*[ab]*" datei.c
+    > grep -rm "P_BLABLUBB" /std *.c -> sucht alle Dateien in /std, die
+                                        auf .c enden und P_BLABLUBB
+                                        enthalten 
+
+ SIEHE AUCH:
+    regexp(E), more, cat, head, tail
+
+ LETZTE AENDERUNG:
+    Mit, 02.10.2002, 02:00:00 von Mandragon
+ 
\ No newline at end of file
diff --git a/doc/mcmd/head b/doc/mcmd/head
new file mode 100644
index 0000000..c16ad5b
--- /dev/null
+++ b/doc/mcmd/head
@@ -0,0 +1,20 @@
+
+head
+----
+
+ MAGIERKOMMANDO:
+    head <datei>
+
+ ARGUMENTE:
+
+     <datei>
+        Die auszugebende Datei
+
+ BESCHREIBUNG:
+    Die ersten zehn Zeilen der Datei <datei> werden ausgegeben.
+
+ SIEHE AUCH:
+    cat, tail, more
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/heile b/doc/mcmd/heile
new file mode 100644
index 0000000..226982e
--- /dev/null
+++ b/doc/mcmd/heile
@@ -0,0 +1,27 @@
+
+heile
+-----
+
+ MAGIERKOMMANDO:
+    heile <ziel>
+
+ ARGUMENTE:
+
+     <ziel>
+        Das zu heilende Lebewesen
+
+ BESCHREIBUNG:
+    Das angegebene Lebewesen wird vollstaendig geheilt.
+
+    Der Befehl darf nur fuer Tests benutzt werden. Man sollte darauf achten,
+    dass man keine Spieler damit beeinflusst, und zwar weder im Guten (indem
+    man den Spieler heilt) noch im Boesen (indem man das Monster heilt, gegen
+    das der Spieler gerade kaempft).
+
+    Magier-Lehrlingen steht dieser Befehl noch nicht zur Verfuegung.
+
+ SIEHE AUCH:
+    vertrag
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 16:54:45 von Wargon
diff --git a/doc/mcmd/home b/doc/mcmd/home
new file mode 100644
index 0000000..48fc907
--- /dev/null
+++ b/doc/mcmd/home
@@ -0,0 +1,23 @@
+
+home
+----
+
+ MAGIERKOMMANDO:
+    home
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Du wirst in Deinen Workroom transportiert.
+
+    Magier-Lehrlingen steht dieser Befehl noch nicht zur Verfuegung, da sie
+    auch noch keinen Workroom haben.
+    Wenn Du Dich im Verfolgemodus befindet, wird dieser durch den Befehl
+    abgeschaltet.
+
+ SIEHE AUCH:
+    goto
+
+ LETZTE AeNDERUNG:
+    Sat, 29.07.2000, 18:00:00 von Silvana
diff --git a/doc/mcmd/ignoriere b/doc/mcmd/ignoriere
new file mode 100644
index 0000000..43aabf4
--- /dev/null
+++ b/doc/mcmd/ignoriere
@@ -0,0 +1,30 @@
+
+ignoriere
+---------
+
+ MAGIERKOMMANDO:
+    ignoriere <magier>.debug
+
+ ARGUMENTE:
+
+     <magier>
+        Name des Magiers, dessen Bugmeldungen ignoriert werden sollen.
+
+ BESCHREIBUNG:
+    Mit Hilfe dieses Befehls kann man gezielt die Bugs eines bestimmten 
+    Magiers ignorieren.
+    
+    Es werden die Bug-Meldungen auf den Kanaelen 'debug' und auf 
+    'entwicklung' ignoriert. 
+
+    Beim Durchsehen der Kanal-History (-deb*20) werden die Bugs allerdings 
+    nicht ignoriert.
+
+    '-deb backtrace' liefert ein Backtrace zu dem letzten aufgetretenen Bug,
+    voellig unabhaengig, ob der Aufrufende den Bug ignoriert.
+
+ SIEHE AUCH:
+    ignoriere (Spielerkommando)
+
+ LETZTE AENDERUNG:
+    Don, 01.08.2002, 17:15:00 von Vanion
diff --git a/doc/mcmd/in b/doc/mcmd/in
new file mode 100644
index 0000000..eb9609f
--- /dev/null
+++ b/doc/mcmd/in
@@ -0,0 +1,29 @@
+
+in
+--
+
+ MAGIERKOMMANDO:
+    in <raum> <kommando>
+
+ ARGUMENTE:
+
+     <raum>
+        Dateiname eines Raumes
+     <kommando>
+        das auzufuehrende Kommando
+
+ BESCHREIBUNG:
+    Du wirst, unsichtbar fuer die Anwesenden, in den Raum <raum>
+    transportiert, fuehrst das Kommando <kommando> aus und gelangst
+    automatisch wieder in den Raum zurueck, in dem Du vorher warst.
+
+ BEISPIELE:
+    Ein Blick auf die aktuelle Liste der Abenteuer:
+
+    > in /gilden/abenteurer liste
+
+ SIEHE AUCH:
+    at, goto
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/invis b/doc/mcmd/invis
new file mode 100644
index 0000000..face1a0
--- /dev/null
+++ b/doc/mcmd/invis
@@ -0,0 +1,26 @@
+
+invis
+-----
+
+ MAGIERKOMMANDO:
+    invis [e]
+
+ ARGUMENTE:
+    Wird der Paramater ´e` angegeben, erhalten die Mitspieler die
+    Erwartemeldungen wie beim Ausloggen.
+
+ BESCHREIBUNG:
+    Du wirst unsichtbar. Kein Spieler kann Dich jetzt mehr sehen.
+
+    Jeder Magier sollte sich ueberlegen, wann es sinnvoll ist, unsichtbar zu
+    sein, und wann er besser sichtbar ist.
+
+    Es besteht ausserdem die Moeglichkeit, sich direkt unsichtbar einzuloggen
+    (auch wenn man beim letzten Ausloggen sichtbar war). Dazu muss man bei der
+    Passwortabfrage als ersten Buchstaben ein - eingeben.
+
+ SIEHE AUCH:
+    vis
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/load b/doc/mcmd/load
new file mode 100644
index 0000000..4ff4db4
--- /dev/null
+++ b/doc/mcmd/load
@@ -0,0 +1,23 @@
+
+load
+----
+
+ MAGIERKOMMANDO:
+    load <datei> [...]
+
+ ARGUMENTE:
+
+     <datei> [...]  Ein oder mehrere Dateinamen
+
+ BESCHREIBUNG:
+    Das Objekt, welches in <datei> definiert ist, wird geladen. Wenn es bereits
+    geladen ist, passiert nichts.
+
+    Raeume koennen auch geladen werden, indem man sie betritt. Die Blueprint
+    eines Objektes kann auch durch Clonen des Objektes geladen werden.
+
+ SIEHE AUCH:
+    clone, destruct, upd
+
+ LETZTE AENDERUNG:
+    Mit, 02.10.2002, 02:00:00 von Mandragon
\ No newline at end of file
diff --git a/doc/mcmd/localcmd b/doc/mcmd/localcmd
new file mode 100644
index 0000000..1a7cb3d
--- /dev/null
+++ b/doc/mcmd/localcmd
@@ -0,0 +1,27 @@
+
+localcmd
+--------
+
+ MAGIERKOMMANDO:
+    localcmd
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Eigentlich sollte dieses Kommando alle Befehle anzeigen, die Du aufgrund
+    des Raumes, in dem Du gerade stehst, aufgrund der der Dinge in dem Raum
+    und in Deinem Inventar sowie aufgrund Deiner eigenen Stellung ausfuehren
+    kannst.
+
+    Aus technischen Gruenden werden allerdings nur die Befehle angezeigt, die
+    ueber add_action() in die Befehlsliste eingefuegt werden; das MorgenGrauen
+    verfuegt jedoch ueber einen anderen Mechanismus, um in Objekten Kommandos
+    zu definieren.
+
+ SIEHE AUCH:
+    man, hilfe,
+    AddCmd(L), add_action(E)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/ls b/doc/mcmd/ls
new file mode 100644
index 0000000..3469941
--- /dev/null
+++ b/doc/mcmd/ls
@@ -0,0 +1,90 @@
+
+ls
+--
+
+ MAGIERKOMMANDO:
+    ls [ -alrtsug ] [ <name> ... ]
+
+ ARGUMENTE:
+
+     <name>  Datei- oder Verzeichnisname (es koennen auch mehrere sein)
+
+ BESCHREIBUNG:
+    Die angegeben Dateien und Verzeichnisse werden aufgelistet. Laesst man
+    <name> weg, wird der Inhalt des aktuellen Verzeichnisses aufgelistet.
+
+    Die Flags haben folgende Bedeutung:
+
+     -a  Auch unsichtbare Dateien (deren Namen mit . beginnen) werden
+         angezeigt.
+     -l  Eine ausfuehrliche Liste, in der auch Laenge und Datum der Datei
+         angegeben werden.
+     -u  In Verbindung mit -l wird auch die UID der Dateien ausgegeben.
+     -g  In Verbindung mit -l wird auch die GID der Dateien ausgegeben.
+     -r  Die Sortierreihenfolge wird umgekehrt.
+     -t  Die Liste wird nach dem Erstellungsdatum sortiert.
+     -s  Die Liste wird nach der Groesse der Dateien geordnet.
+
+ EINSTELLUNGEN:
+    Verzeichnisse und geladene Objekte werden, abhaengig von der aktuellen
+    Einstellung des Terminaltyps, besonders angezeigt.
+
+    Diese Einstellungen lassen sich ueber zwei Umgebungsvariablen aendern,
+    wenn man als Terminaltyp `vt100' oder `ansi' eingestellt hat. Bei der
+    Einstellung `dumb' wird bei Verzeichnissen ein / angehaengt und bei
+    geladenen Objekten ein *.
+
+     LS_DIR  Hier kann man die Darstellung von Verzeichnissen konfigurieren.
+             Der Default ist bei `vt100'-Terminals Fettschrift und bei
+             `ansi'-Terminals blaue Fettschrift.
+     LS_OBJ  Diese Variable beinhaltet die Einstellung fuer geladene Objekte.
+             Der Default ist bei `vt100'-Terminals inverse Darstellung und bei
+             `ansi'-Terminals rote Schrift.
+     LS_VC   Diese Variable beinhaltet die Einstellung fuer Objekte, die von
+             einem Virtual Compiler erzeugt wurden. Default ist wie bei LS_OBJ.
+
+    Die Variablen koennen die nachfolgend aufgefuehrten Werte annehmen. Um
+    mehrere Effekte zu kombinieren, muss man sie mit einem + trennen.
+
+    `vt100' und `ansi':
+
+     none    Keine Hervorhebungen
+     bold    Fettschrift
+     blink   blinkende Schrift
+     invers  Schrift- und Hintergrundfarbe werden vertauscht
+
+    Nur `ansi':
+
+     black     Textfarbe schwarz
+     red       Textfarbe rot
+     green     Textfarbe gruen
+     yellow    Textfarbe gelb
+     blue      Textfarbe blau
+     purple    Textfarbe purpur
+     cyan      Textfarbe cyan
+     white     Textfarbe weiss
+     bblack    Hintergrundfarbe schwarz
+     bred      Hintergrundfarbe rot
+     bgreen    Hintergrundfarbe gruen
+     byellow   Hintergrundfarbe gelb
+     bblue     Hintergrundfarbe blau
+     bpurple   Hintergrundfarbe purpur
+     bcyan     Hintergrundfarbe cyan
+     bwhite    Hintergrundfarbe weiss
+
+ BEISPIELE:
+
+    > ls -l
+    > ls -a /doc
+
+    Verzeichnisse in Fettschrift anzeigen, geladene Dateien rot auf gelbem
+    Hintergrund:
+
+    > set LS_DIR bold
+    > set LS_OBJ red+byellow
+
+ SIEHE AUCH:
+    cd, pwd, set, stty
+
+ LETZTE AENDERUNG:
+    Mit, 02.10.2002, 02:00:00 von Mandragon
\ No newline at end of file
diff --git a/doc/mcmd/man b/doc/mcmd/man
new file mode 100644
index 0000000..3130ad5
--- /dev/null
+++ b/doc/mcmd/man
@@ -0,0 +1,61 @@
+
+man
+---
+
+ MAGIERKOMMANDO:
+    man [-i] <name/nummer>
+    man [-i] <name> [nummer]
+    man [-mi] <maske>
+    man [-ri] <maske>
+
+ ARGUMENTE:
+
+     <name> [...]   Name der gewuenschten Hilfeseite
+     <maske>        Wortteil einer Hilfeseite (kann * und ? enthalten)
+     <[nummer]>	    Nummer einer von mehreren Hilfsseiten
+
+ BESCHREIBUNG:
+    Im Hilfeverzeichnis (`/doc') wird nach der entsprechenden Hilfeseite
+    gesucht und diese dann angezeigt.
+
+    Wenn der Parameter -m verwendet wurde, dann werden alle Hilfeseiten
+    aufgelistet, deren Name die Maske enthaelt.
+
+    Der Parameter -r ermoeglicht es, einen Ausdruck im Regexp-Format
+    anzugeben.
+
+    Mit Hilfe der Nummer kann man sich das genaue Ausschreiben einer
+    bestimmten Hilfsseite bei der Anzeige mehrere sparen.
+
+    Die Option -i (interaktiver HTML-Modus) ist zur Zeit nicht aktiviert.
+
+ ACHTUNG:
+
+    Nach dem Einspielen von neuen MAN-Seiten muss der betreffende Magier
+    per 'xcall /p/daemon/mand->update_cache()' den Cache aktualisieren.
+    Dieser wird automatisch nur woechentlich aktualisiert.
+
+ BEISPIELE:
+    Eine einfache Hilfeseite (naemlich diese):
+
+    > man man
+
+    Welche Hilfeseiten haben etwas mit Haenden zu tun?
+
+    > man -m *hands*
+
+    Welche Hilfesseiten sagen uns etwas ueber Waffen?
+
+    > man waffen
+      Es wurden folgende potentiell passenden Seiten gefunden:
+      --------------------------------------------------------
+      1: help/waffenfertigkeiten 2: std/weapon 3: wiz/waffen
+      --------------------------------------------------------
+    > man 3 ODER	> man wiz/waffen ODER	> man waffen 3
+      [Anzeige von /wiz/waffen]
+
+ SIEHE AUCH:
+    hilfe rman
+
+ LETZTE AENDERUNG:
+    20. Maerz 2004 Gloinson
diff --git a/doc/mcmd/mbanish b/doc/mcmd/mbanish
new file mode 100644
index 0000000..c1f5754
--- /dev/null
+++ b/doc/mcmd/mbanish
@@ -0,0 +1,31 @@
+
+mbanish
+-------
+
+ ERZMAGIERKOMMANDO:
+    mbanish <name> [<grund>]
+
+ ARGUMENTE:
+
+     <name>
+        Name des Opfers
+     <grund> (optional)
+        Der Grund der Sperre
+
+ BESCHREIBUNG:
+    Mit diesem Befehl laesst sich verhindern, dass der Spieler <name> von
+    beliebigen Magiern gesponsort (d.h. zum Magier gemacht) werden kann (aus
+    welchem <grund> auch immer).
+
+    Nur ein Erzmagier oder Gott kann in diesem Fall ein Sponsoring vornehmen.
+
+    Mit dem Grund 'loeschen' koennen gesperrte Namen wieder freigegeben werden.
+    Ohne Parameter wird die Liste aller gesperrten Namen ausgegeben.
+
+    Dieser Befehl kann nur von Erzmagiern und Goettern ausgefuehrt werden.
+
+ SIEHE AUCH:
+    banish, tbanish, sbanish
+
+ LETZTE AeNDERUNG:
+    Mon, 20.12.1999, 23:30:00 von Tiamak
diff --git a/doc/mcmd/mecho b/doc/mcmd/mecho
new file mode 100644
index 0000000..569d780
--- /dev/null
+++ b/doc/mcmd/mecho
@@ -0,0 +1,22 @@
+
+mecho
+-----
+
+ MAGIERKOMMANDO:
+    mecho <text>
+
+ ARGUMENTE:
+
+     <text>
+        ein beliebiger Text
+
+ BESCHREIBUNG:
+    Der Text <text> wird an alle Magier im MUD geschickt.
+
+    Der Befehl sollte mit groesster Sorgfalt behandelt werden.
+
+ SIEHE AUCH:
+    vertrag, emote, echo, echoall, echoto, teile (mit)
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 16:54:57 von Wargon
diff --git a/doc/mcmd/mkdir b/doc/mcmd/mkdir
new file mode 100644
index 0000000..f0615dc
--- /dev/null
+++ b/doc/mcmd/mkdir
@@ -0,0 +1,43 @@
+
+mkdir
+-----
+
+ MAGIERKOMMANDO:
+    mkdir [-vr] <verz> [...]
+
+ ARGUMENTE:
+
+     <verz> [...]
+        Name des neuen Verzeichnisses (es koennen auch mehrere sein)
+
+ BESCHREIBUNG:
+    Die angegebenen Verzeichnisse werden neu angelegt.
+
+    Die Flags haben folgende Bedeutung:
+
+    -v  Genau ausgeben, was gemacht wird
+    -r  Rekursiv die OBERverzeichnisse von <verz> mitanlegen, wenn sie nicht
+        schon existieren.
+    -p  Das gleiche wie -r (alias eingefuehrt, weil -p einfach viel
+        verbreiteter ist).
+ 
+ BEISPIELE:
+
+    > mkdir new
+
+    Soll jetzt in `new/' noch das Verzeichnis `foo/bar/' angelegt werden, so
+    darf man nicht folgenden Aufruf verwenden
+
+    > mkdir new/foo/bar      ; So nicht!
+
+    sondern koennte z.B folgendermassen vorgehen:
+
+    > mkdir new/foo new/foo/bar           oder
+    > mkdir -r /new/foo/bar
+
+ SIEHE AUCH:
+    rmdir
+
+ LETZTE AENDERUNG:
+    26.01.2013, Zesstra
+
diff --git a/doc/mcmd/more b/doc/mcmd/more
new file mode 100644
index 0000000..1ec675b
--- /dev/null
+++ b/doc/mcmd/more
@@ -0,0 +1,42 @@
+
+more
+----
+
+ MAGIERKOMMANDO:
+    more <datei> [...]
+
+ ARGUMENTE:
+
+     <datei> [...]
+        Dateiname(n)
+
+ BESCHREIBUNG:
+    Die Datei(en) <datei> wird/werden stueckchenweise angezeigt. Nach jeder
+    ausgegebenen Seite wird gestoppt und es koennen verschiedene Aktionen
+    durchgefuehrt werden:
+
+     <RETURN>, f, F
+               Eine Seite vorwaerts
+     d, D      Eine halbe Seite vorwaerts
+     u, U      Eine halbe Seite zurueck
+     b, B      Eine Seite zurueck
+     <zeile>   Springe zu Zeile <zeile>
+     ?         Hilfetext ausgeben
+     q, x      Anzeige der aktuellen Datei abbrechen
+     /<regexp>
+               regulaeren Ausdruck <regexp> suchen
+
+    Die Dateinamen koennen auch Muster wie * oder ? enthalten.
+
+    Die Laenge einer Seite kann man mit dem Befehl `zeilen' einstellen.
+
+ BEISPIELE:
+
+    > more /std/npc.c
+    > more *.h
+
+ SIEHE AUCH:
+    cat, head, tail, zeilen
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/mschau b/doc/mcmd/mschau
new file mode 100644
index 0000000..5dd26a1
--- /dev/null
+++ b/doc/mcmd/mschau
@@ -0,0 +1,40 @@
+
+mschau
+------
+
+ MAGIERKOMMANDO:
+    mschau <schalter>
+
+ ARGUMENTE:
+
+     <schalter>
+        'an', 'ein' oder 'ja' schaltet den Magiermodus ein
+        'aus' oder 'nein' schaltet den Magiermodus aus
+        '+debug' schaltet Debugmeldungen ein
+        '-debug' schaltet Debugmeldungen aus
+
+ BESCHREIBUNG:
+    Manchmal moechte man etwas ausprobieren, was nur Spielern moeglich ist,
+    zum Beispiel beim Testen von Abenteuern o.ae. Dazu dient dieser Befehl,
+    mit dem man die meisten Faehigkeiten eines Magiers deaktivieren kann.
+
+    Nach einem `mschau aus' sieht man keine Dateinamen mehr von Raeumen und
+    Objekten. Die meisten Magierbefehle sind abgeschaltet und man kann auch
+    wieder sterben wie ein normaler Spieler.
+
+    Mit `mschau an' kehrt man wieder in den Magiermodus zurueck.
+
+    Zusaetzlich kann dieses Kommando noch umschalten, ob Magier Debugmeldungen
+    (das sind Meldungen, die mit dem Typ MT_DEBUG an ReceiveMsg() uebergeben
+     werden) wahrnehmen moechten oder nicht.
+
+ BEMERKUNGEN:
+    Auch mit ausgeschaltetem Magiermodus unterliegt man noch den Bedingungen
+    des Magiervertrags!
+
+ SIEHE AUCH:
+    vertrag, schau (an), i (=inventur)
+
+ LETZTE AeNDERUNG:
+    1.5.2014, Zesstra
+
diff --git a/doc/mcmd/mv b/doc/mcmd/mv
new file mode 100644
index 0000000..32c5368
--- /dev/null
+++ b/doc/mcmd/mv
@@ -0,0 +1,51 @@
+
+mv
+--
+
+ MAGIERKOMMANDO:
+    mv [ -irfv ]  <alt> <neu>
+    mv [ -irfv ]  <von_1> [ ... <von_n> ] <nach>
+    mv [ -irfvm ] <von_1> [ ... <von_n> ] <nach> <maske>
+
+ ARGUMENTE:
+
+     <alt>    Alter Datei- oder Verzeichnisname
+     <neu>    Neuer Datei- oder Verzeichnisname
+     <von_1>
+     <von_n>  Name der Quelldateien und -verzeichnisse
+     <nach>   Das Zielverzeichnis
+     <maske>  Dateimaske fuer Datei- oder Verzeichnisnamen
+
+ BESCHREIBUNG:
+    Mit dem ersten Aufruf wird die Datei bzw. das Verzeichnis <alt> in <neu>
+    umbenannt.
+
+    Mit dem zweiten Aufruf werden die Quelldateien <von_1> bis <von_n> in das
+    Zielverzeichnis <verz> verschoben.
+
+    In der zweiten Variante koennen die Dateinamen auch Muster wie * oder ?
+    enthalten.
+
+    Die Optionen haben folgende Bedeutung:
+
+     -i  Vor dem Ueberschreiben einer existierenden Datei wird eine
+         Sicherheitsabfrage durchgefuehrt.
+     -r  Es werden rekursiv Unterverzeichnisse verschoben, falls das
+         Zielverzeichnis schon existiert
+     -f  Evtl. auftretende Probleme, die sonst einen Abbruch bewirken wuerden,
+         werden ignoriert. Auch `-i' wird ausser Kraft gesetzt.
+     -v  Es wird detailliert ausgegeben, was gemacht wird
+     -m  Es werden nur Dateien verschoben, die dem Muster <maske> entsprechen
+
+ BEISPIELE:
+
+    > mv datei1 datei2
+    > mv * temp
+    > mv /players/hate/*.c ../test
+    > mv -ifrm ~mandragon/meloran /d/inseln/mandragon/meloran *.c
+
+ SIEHE AUCH:
+    cp, rm
+
+ LETZTE AENDERUNG:
+    Don, 03.10.2002, 18:00:00 von Mandragon
diff --git a/doc/mcmd/oropax b/doc/mcmd/oropax
new file mode 100644
index 0000000..66bc1b2
--- /dev/null
+++ b/doc/mcmd/oropax
@@ -0,0 +1,30 @@
+
+oropax
+------
+
+ MAGIERKOMMANDO:
+    oropax [<stufe>]
+
+ ARGUMENTE:
+
+     <stufe> (optional)
+        Magierlevel, ab dem Rufe durchgelassen werden
+
+ BESCHREIBUNG:
+    Du steckst Dir Oropax in die Ohren. Nun kannst Du nichts mehr hoeren, was
+    gerufen, gesagt oder Dir mitgeteilt wird. Das gilt allerdings nur fuer
+    Leute mit einem Magierlevel, der kleiner ist als <stufe>.
+
+    Die hoechstmoegliche Stufe ist Dein eigener Magierlevel.
+
+    Rufst Du den Befehl ohne Argument auf, wird das Oropax wieder entfernt.
+
+    Auf die Kommunikation ueber die Ebenen wirkt das Oropax nicht, da diese
+    Art der Kommunikation auf geistiger Ebene verlaeuft und nicht ueber den
+    Gehoergang.
+
+ SIEHE AUCH:
+    ignoriere
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/people b/doc/mcmd/people
new file mode 100644
index 0000000..b5adeed
--- /dev/null
+++ b/doc/mcmd/people
@@ -0,0 +1,30 @@
+
+people
+------
+
+ MAGIERKOMMANDO:
+    people
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Dieses Kommando listet Informationen ueber alle eingeloggten Spieler und
+    Magier auf:
+
+     * von welcher Internetnummer sie kommen
+     * den aktuellen Namen.
+     * den Magierlevel
+     * das Alter
+     * Idle flag `I', wenn der Spieler laenger als 5 Minuten nichts mehr
+       gemacht hat
+     * wo er ist
+
+    Ausserdem wird die Anzahl der aktiven Spieler, die Anzahl der Kommandos
+    pro Sekunde und die Anzahl der kompilierten Zeilen pro Sekunde angezeigt.
+
+ SIEHE AUCH:
+    wer, pwho
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/ping b/doc/mcmd/ping
new file mode 100644
index 0000000..9daf7b3
--- /dev/null
+++ b/doc/mcmd/ping
@@ -0,0 +1,19 @@
+
+ping
+----
+
+ MAGIERKOMMANDO:
+    ping <spieler>
+
+ ARGUMENTE:
+
+     <spieler>
+        ein (eingeloggter) Spieler
+
+ BESCHREIBUNG:
+    Der Spieler <spieler> wird angepiept. Dabei wird bei dem Spieler eine
+    Meldung und, falls sein Rechner dies unterstuetzt, ein Signalton
+    ausgegeben.
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/prompt b/doc/mcmd/prompt
new file mode 100644
index 0000000..eb9b0de
--- /dev/null
+++ b/doc/mcmd/prompt
@@ -0,0 +1,43 @@
+
+prompt
+------
+
+ MAGIERKOMMANDO:
+    prompt [<text>]
+
+ ARGUMENTE:
+
+     <text> (optional)
+        ein beliebiger Text
+
+ BESCHREIBUNG:
+    Die Eingabeaufforderung ("prompt") wird auf die angegebene Meldung <text>
+    gesetzt.
+
+    Ohne Argumente wird das Defaultprompt (`> ') eingestellt.
+
+    Um Leerzeichen an Anfang und Ende des Prompts zu ermoeglichen, kann <text>
+    in Anfuehrungszeichen gesetzt werden. Ausserdem gibt es noch folgende
+    besondere Zeichenfolgen:
+
+     \h  wird durch den Namen des Muds ersetzt
+     \u  wird durch Deinen Namen ersetzt
+     \w  wird durch das aktuelle Verzeichnis ersetzt
+     \t  wird durch die aktuelle Zeit ersetzt
+     \n  an dieser Stelle wird ein Zeilenumbruch eingefuegt
+
+ BEISPIELE:
+
+    > prompt "\h:\u:\w> "
+
+    ergibt bei Wargon, wenn er sich in seinem Homeverzeichns befindet:
+
+    MorgenGrauen:Wargon:/players/wargon> _
+
+    (der Unterstrich soll den Cursor anzeigen)
+
+ SIEHE AUCH:
+    pwd
+
+ LETZTE AeNDERUNG:
+    Mon, 08.02.1999, 22:15:00 von Tiamak
diff --git a/doc/mcmd/protect b/doc/mcmd/protect
new file mode 100644
index 0000000..592876a
--- /dev/null
+++ b/doc/mcmd/protect
@@ -0,0 +1,32 @@
+
+protect
+-------
+
+ MAGIERKOMMANDO:
+    protect <prop>
+
+ ARGUMENTE:
+
+     <prop>
+        Name der zu schuetzenden Property
+
+ BESCHREIBUNG:
+    Das Zustand des PROTECTED-Flags der Property <prop> wird umgeschaltet.
+
+    Man muss dabei allerdings beachten, dass man nicht den Namen der Property
+    aus `/sys/properties.h' verwenden darf, sondern den String nehmen muss,
+    der sich hinter dem P_XYZ verbirgt.
+
+    Magier-Lehrlingen steht dieser Befehl noch nicht zur Verfuegung.
+
+ BEISPIELE:
+    Wenn Du verhindern willst, dass jemand anderes Deinen Titel (P_TITLE =
+    "title") aendern kann:
+
+    > protect title
+
+ SIEHE AUCH:
+    `/std/thing/properties.c'
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/pwd b/doc/mcmd/pwd
new file mode 100644
index 0000000..b8d5f42
--- /dev/null
+++ b/doc/mcmd/pwd
@@ -0,0 +1,18 @@
+
+pwd
+---
+
+ MAGIERKOMMANDO:
+    pwd
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Der aktuelle Pfad wird angezeigt.
+
+ SIEHE AUCH:
+    cd, prompt, ls
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/pwho b/doc/mcmd/pwho
new file mode 100644
index 0000000..79cd382
--- /dev/null
+++ b/doc/mcmd/pwho
@@ -0,0 +1,35 @@
+
+pwho
+----
+
+ MAGIERKOMMANDO:
+    pwho
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Dieses Kommando gibt die wichtigsten Charakterwerte aller eingeloggten
+    Spieler und Seher aus.
+
+    Als Infomation erhaelt man
+
+     * den Level
+     * den Namen
+     * die Erfahrungspunkte
+     * die Abenteuerpunkte
+     * Intelligenz
+     * Kraft
+     * Geschicklichkeit
+     * Ausdauer
+     * Angriffsstaerke
+     * Abwehrstaerke
+     * Angriffsstaerke mit blossen Haenden
+     * momentane Lebenspunkte
+     * maximale Lebenspunkte
+
+ SIEHE AUCH:
+    wer, people
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/removeguildmaster b/doc/mcmd/removeguildmaster
new file mode 100644
index 0000000..74ce300
--- /dev/null
+++ b/doc/mcmd/removeguildmaster
@@ -0,0 +1,24 @@
+
+removeguildmaster
+-----------------
+
+ ERZMAGIERKOMMANDO:
+    removeguildmaster <name> <gilde>
+
+ ARGUMENTE:
+
+     <name>
+        Name des Magiers
+     <gilde>
+        Name der Gilde
+
+ BESCHREIBUNG:
+    Der Magier <name> ist fortan nicht mehr Gildenmagier der Gilde <gilde>.
+
+    Dieser Befehl steht nur Goettern zur Verfuegung.
+
+ SIEHE AUCH:
+    addguildmaster, gilden
+
+ LETZTE AeNDERUNG:
+    2003-12-10, Zook.
diff --git a/doc/mcmd/removemaster b/doc/mcmd/removemaster
new file mode 100644
index 0000000..b7f5d23
--- /dev/null
+++ b/doc/mcmd/removemaster
@@ -0,0 +1,25 @@
+
+removemaster
+------------
+
+ ERZMAGIERKOMMANDO:
+    removemaster <name> <region>
+
+ ARGUMENTE:
+
+     <name>
+        Name des Magiers
+     <region>
+        Eine Region
+
+ BESCHREIBUNG:
+    Der Magier <name> wird von der Liste der Regionsmagier der Region <region>
+    gestrichen.
+
+    Dieser Befehl steht nur Erzmagiern und Goettern zur Verfuegung.
+
+ SIEHE AUCH:
+    addmaster, regionen
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/rm b/doc/mcmd/rm
new file mode 100644
index 0000000..8378a02
--- /dev/null
+++ b/doc/mcmd/rm
@@ -0,0 +1,35 @@
+
+rm
+--
+
+ MAGIERKOMMANDO:
+    rm [ -irv ] <dateiname> [...]
+    rm [ -irmv ] <dateiname> [...] [<maske>]
+
+ ARGUMENTE:
+
+     <dateiname> Name einer Datei oder eines Verzeichnisses
+                 (es koennen auch mehrere sein)
+
+ BESCHREIBUNG:
+    Die angegebenen Dateien oder Verzeichnisse werden geloescht.
+    Die Dateinamen koennen auch Muster wie * oder ? enthalten.
+
+    Die Optionen haben folgende Bedeutung:
+
+     -r  Unterverzeichnisse werden rekursiv geloescht.
+     -i  Bei jeder Datei wird nachgefragt, ob sie geloescht werden soll.
+     -m  Es sind nur Dateien betroffen, die der Maske <maske> entsprechen
+     -v  Es wird jeder Arbeitsschritt ausgegeben
+
+ BEISPIELE:
+
+    > rm test1.c
+    > rm *.bak
+    > rm -rm / *~     
+
+ SIEHE AUCH:
+    cp, mv
+
+ LETZTE AeNDERUNG:
+    Thu, 17.10.2002, 16:30:00 von Mandragon
diff --git a/doc/mcmd/rman b/doc/mcmd/rman
new file mode 100644
index 0000000..95f4d5a
--- /dev/null
+++ b/doc/mcmd/rman
@@ -0,0 +1,28 @@
+
+rman
+---
+
+ MAGIERKOMMANDO:
+    rman <hilfsseite> <mudname>
+
+ ARGUMENTE:
+
+     <hilfsseite>   Name der gewuenschten Hilfeseite
+     <mudname>      Name eines bekannten Muds
+
+ BESCHREIBUNG:
+    An das Mud <mudname> wird eine Anfrage geschickt, ob es eine Hilfe-
+    Seite zum Thema <hilfsseite> bereitstellen kann. Die Antwort ist
+    vom Mud abhaengig.
+
+ BEISPIELE:
+   
+    Im Pk-Mud die Hilfeseite zu PKs anfordern:
+
+    > rman pk pk-mud
+
+ SIEHE AUCH:
+    hilfe man udpq
+
+ LETZTE AENDERUNG:
+    Die, 06.06.2003, 18:00:00 von Mandragon
diff --git a/doc/mcmd/rmdir b/doc/mcmd/rmdir
new file mode 100644
index 0000000..02b4182
--- /dev/null
+++ b/doc/mcmd/rmdir
@@ -0,0 +1,24 @@
+
+rmdir
+-----
+
+ MAGIERKOMMANDO:
+    rmdir [-v] <verz> [...]
+
+ ARGUMENTE:
+
+     <verz>  Das zu loeschende Verzeichnis (es koennen auch mehrere sein)
+
+ BESCHREIBUNG:
+    Die angegebenen Verzeichnisse werden geloescht. Die Verzeichnisse muessen
+    dazu leer sein.
+
+    Das Flag -v sorgt dafuer, das detaillierte Informationen ueber den Fort-
+    schritt ausgegeben werden.
+
+
+ SIEHE AUCH:
+    mkdir, rm
+
+ LETZTE AENDERUNG:
+    Mit, 02.10.2002, 02:00:00 von Mandragon
diff --git a/doc/mcmd/sallow b/doc/mcmd/sallow
new file mode 100644
index 0000000..18750d2
--- /dev/null
+++ b/doc/mcmd/sallow
@@ -0,0 +1,23 @@
+
+sallow
+------
+
+ MAGIERKOMMANDO:
+    sallow <name>
+
+ ARGUMENTE:
+
+     <name>
+        Name eines Magiers
+
+ BESCHREIBUNG:
+    Du erlaubst dem Magier <name> Dich zu snoopen.
+
+    Dies ist nur noetig, wenn ein Magier von gleichem oder geringerem Level
+    Dich snoopen soll.
+
+ SIEHE AUCH:
+    snoop
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/sbanish b/doc/mcmd/sbanish
new file mode 100644
index 0000000..a7c847f
--- /dev/null
+++ b/doc/mcmd/sbanish
@@ -0,0 +1,55 @@
+
+sbanish
+-------
+
+ MAGIERKOMMANDO:
+    sbanish <adresse> <tage>
+
+ ARGUMENTE:
+
+     <adresse>
+        IP-Adresse des Opfers
+     <tage>
+        Die Dauer der Sperrung
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kann man verhindern, dass sich von bestimmten Adressen
+    aus Gaeste einloggen oder neue Spieler angelegt werden..
+    
+    Die Dauer wird in Tagen angegeben. Eine Angabe von -1 setzt eine 
+    unbefristete Sperre; mit einer Dauer von 0 Tagen loescht man eine gesetzte 
+    Sperre.
+
+    Die Angabe von 'sbanish' ohne Parameter gibt eine Liste aller gesperrten
+    Adressen aus.
+
+    Die zu sperrende IP-Adresse kann in den folgenden Formen angegeben werden:
+      - 'n.n.n.n': einzelne Adresse
+      - 'n.n.n.n/x': Subnetzwerk in CIDR-Notation mit Subnetzmaske x.
+                     2^(32-x) Adressen
+      - 'n.n.n.n/m.m.m.m': Subnetzwerk in CIDR-Notation mit Subnetzmaske 
+                           m.m.m.m
+      - 'n.n.n': Class-C-Netz n.n.n (255 Adressen)
+      - 'n.n': Class-B-Netz n.n (65536 Adressen)
+
+    Dieser Befehl steht eingeschraenkt ab Level 26 zur Verfuegung:
+
+      - ab Level 26 kann man bis zu zehn einzelne IPs fuer einen Tag sperren
+        und eigene Sperrungen wieder aufheben
+      - ab Level 40 kann man bis zu zehn IPs und/oder Subnetze mit bis zu 255
+        Adressen fuer einen Tag sperren und eigene Sperrungen wieder aufheben
+      - Hilfssheriffs und Erzmagier koennen beliebig viele IPs bzw. Subnetze
+        beliebiger Groesse fuer beliebige Zeitraeume sperren sowie fremde
+        Sperrungen wieder aufheben
+
+ BEMERKUNGEN:
+    Ein sbanish fuehrt ausdruecklich _nicht_ dazu, dass sich von den
+    entsprechenden Adressen keine bestehenden Spieler mehr einloggen
+    koennen.
+
+ SIEHE AUCH:
+    banish, mbanish, tbanish
+
+ LETZTE AeNDERUNG:
+ 20.01.2013, Zesstra
+
diff --git a/doc/mcmd/set b/doc/mcmd/set
new file mode 100644
index 0000000..6d73fda
--- /dev/null
+++ b/doc/mcmd/set
@@ -0,0 +1,49 @@
+
+set
+---
+
+ MAGIERKOMMANDO:
+    set [<var> [<wert>]]
+
+ ARGUMENTE:
+
+     <var>
+        eine beliebige Zeichenkette
+     <wert>
+        der dazugehoerige Wert
+
+ BESCHREIBUNG:
+    Die Variable <var> wird auf den Wert <wert> gestezt.
+
+    Laesst man <wert> weg, wird die Variable <var> geloescht.
+
+    Ganz ohne Argumente werden die momentan definierten Variablen ausgegeben.
+
+    Die Variablen wirken sich bei den meisten Dateikommandos aus. Man kann sie
+    verwenden, um sich Abkuerzungen zu oft benutzten Dateien oder
+    Verzeichnissen zu legen.
+
+ BESONDERE VARIABLEN
+    Einige Umgebungsvariablen haben eine feste Bedeutung:
+
+     LS_OBJ   Diese Variablen sind im Zusammenhang mit dem ls-Befehl von
+     LS_DIR   Bedeutung und steuern die farbliche Darstellung der Ausgabe 
+     LS_VC    
+
+     CD_SHORT Wenn auf 1 gesetzt, wird bei 'cd' eine .readme-Datei nicht mit
+              ausgegeben.
+
+ BEISPIELE:
+    Eine Abkuerzung fuer einen Pfad:
+
+    > set ls /d/inseln/wargon/luftschloss
+
+    Nun kann man mit einem einfachen `cd $ls' in das Verzeichnis gelangen.
+    Ein cd $ls/mon fuehrt nach /d/inseln/wargon/luftschloss/mon.
+
+ SIEHE AUCH:
+    cd, ls, rm, mv, cat, head, tail, more
+
+ LETZTE AENDERUNG:
+    Mit, 02.10.2002, 02:00:00 von Mandragon
+ 
\ No newline at end of file
diff --git a/doc/mcmd/setcmsg b/doc/mcmd/setcmsg
new file mode 100644
index 0000000..9944937
--- /dev/null
+++ b/doc/mcmd/setcmsg
@@ -0,0 +1,33 @@
+
+setcmsg
+-------
+
+ MAGIERKOMMANDO:
+    setcmsg [<text>]
+
+ ARGUMENTE:
+
+     <text> (optional)
+        Die neue Meldung
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kannst Du die Meldung festlegen, die andere Leute im
+    gleichen Raum sehen, wenn Du einen Gegenstand clonst. Vor den Text wird
+    noch Dein Name gestellt.
+
+    Ohne Argument wird die Defaultmeldung eingestellt.
+
+ BEISPIELE:
+    Angenommen, Wargon stellt folgende Clone-Meldung ein:
+
+    > setcmsg holt etwas aus den tiefen Taschen seines Mantels
+
+    Clont Wargon nun irgend etwas, sehen die Spieler im gleichen Raum:
+
+    Wargon holt etwas aus den tiefen Taschen seines Mantels.
+
+ SIEHE AUCH:
+    setdmsg, review, clone
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/setdmsg b/doc/mcmd/setdmsg
new file mode 100644
index 0000000..611c7e5
--- /dev/null
+++ b/doc/mcmd/setdmsg
@@ -0,0 +1,33 @@
+
+setdmsg
+-------
+
+ MAGIERKOMMANDO:
+    setdmsg [<text>]
+
+ ARGUMENTE:
+
+     <text> (optional)
+        Die neue Meldung
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kannst Du die Meldung festlegen, die andere Leute im
+    gleichen Raum sehen, wenn Du einen Gegenstand zerstoerst. Vor den Text
+    wird noch der Name des Gegenstandes gestellt.
+
+    Ohne Argument wird die Defaultmeldung eingestellt.
+
+ BEISPIELE:
+    Angenommen, Wargon stellt folgende Destruct-Meldung ein:
+
+    > setdmsg wird von Wargon annihiliert
+
+    Zerstoert Wargon nun z.B. eine Fackel, sehen die Spieler im gleichen Raum:
+
+    Eine Fackel wird von Wargon annihiliert.
+
+ SIEHE AUCH:
+    setcmsg, review, destruct
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/shell b/doc/mcmd/shell
new file mode 100644
index 0000000..46cd3ca
--- /dev/null
+++ b/doc/mcmd/shell
@@ -0,0 +1,47 @@
+
+   ----------------------MAGIER_HILFS_SEITE------------------------
+
+Als Magier hat man neben den Spieler- und Seherbefehlen einige weitere
+Befehle zur Verfuegung. Eine Erlaeuterung zu den folgenden Themen und
+Kommandos kann man mit "hilfe <kommando>" erhalten. Wobei hier nicht
+zwischen den Stufen der Magier unterschieden wird. Dies wird aber jeweils
+bei der Erlaeuterung erwaehnt.
+
+ALLGEMEINE THEMEN:
+    balance, forscherpunkte, testspieler, zweitspieler
+
+KOMMUNIKATION:
+    echoall, echoto, echo, mecho, mrufe, oropax, remote
+
+BEWEGUNG:
+    goto, trans, home, verfolge, setmin, setmout, setmmin, setmmout,
+    at, in, +
+
+KAMPF:
+    zap, frieden, sethands
+
+DATEISYSTEM:
+    cd, pwd, ls, cat, head, tail, more, grep, cp, mv, rm, mkdir,
+    rmdir, set, prompt, ed
+
+OBJEKTE:
+    clone, destruct, upd(ate), load, setcmsg, setdmsg
+
+INFO:
+    mschau, people, pwho, localcmd, man, snoop, sallow, spieler, rman
+
+ANDERES:
+    heile, zwinge, title, extralook, traenke, invis, vis, protect, do,
+    showpresay, ping, todo
+
+REGIONSMAGIERBEFEHLE UND -THEMEN:
+    regionsmagier banish, exec
+
+ERZMAGIERBEFEHLE:
+    addmaster, removemaster, mbanish, shutdown
+
+In den Verzeichnissen unter /doc/* findest Du viele weitere Dokumentationen.
+Unter anderem findest Du einen Programmierkurs in LPC/MorgenGrauen unter
+  /doc/KURS/*
+Ausserdem sollten unbedingt die Dokumentationen unter /doc/MG/* beachtet werden.
+
diff --git a/doc/mcmd/showpresay b/doc/mcmd/showpresay
new file mode 100644
index 0000000..1b3e786
--- /dev/null
+++ b/doc/mcmd/showpresay
@@ -0,0 +1,23 @@
+
+showpresay
+----------
+
+ MAGIERKOMMANDO:
+    showpresay [ein|an|aus]
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Normalerweise wird das Presay bei den Kommunikationsbefehlen nicht mit
+    ausgegeben. Moechte man das dennoch, so kann die Ausgabe mit diesem Befehl
+    aktiviert und deaktiviert werden.
+
+    Man sollte das Presay nur mit ausgeben lassen, wenn es kurz ist (nicht
+    laenger als 10 Zeichen).
+
+ SIEHE AUCH:
+    presay
+
+ LETZTE AeNDERUNG:
+    Tue, 17.12.2002, 12:00:00 von Mandragon
diff --git a/doc/mcmd/shutdown b/doc/mcmd/shutdown
new file mode 100644
index 0000000..8fce2bb
--- /dev/null
+++ b/doc/mcmd/shutdown
@@ -0,0 +1,26 @@
+
+shutdown
+--------
+
+ ERZMAGIERKOMMANDO:
+    shutdown <grund>
+
+ ARGUMENTE:
+
+     <grund>
+        Der Grund fuer den Neustart
+
+ BESCHREIBUNG:
+    Mit diesem Befehl wird das Spiel SOFORT heruntergefahren. Man sollte
+    diesen Befehl nur benutzen, wenn es wirklich dringend notwendig ist; fuer
+    einen Neustart mit Verzoegerung steht Armageddon immer gern zur
+    Verfuegung. Er sollte eigentlich immer gewaehlt werden, da die Spieler
+    dann auch Zeit haben, sich auf den Neustart einzustellen.
+
+    Dieser Befehl steht nur Erzmagiern und Goettern zur Verfuegung.
+
+ SIEHE AUCH:
+    `/obj/shut' (Armageddon)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/snoop b/doc/mcmd/snoop
new file mode 100644
index 0000000..f8d8ddc
--- /dev/null
+++ b/doc/mcmd/snoop
@@ -0,0 +1,45 @@
+
+snoop
+-----
+
+ MAGIERKOMMANDO:
+    snoop <name> [<flags>]
+    snoop
+
+ ARGUMENTE:
+
+     <name>
+        Name eines Spielers
+     <flags> (optional)
+        'l' und/oder 'f'
+
+ BESCHREIBUNG:
+    Du siehst und hoerst alles aus der Sicht des Spielers <name>. Das kann
+    auch ein Magier sein, wenn er einen kleineren Level hat als Du.
+
+    Die Flags haben folgende Bedeutung:
+
+     f (force)
+        Falls der Spieler schon von einem Magier mit niedrigerem Level
+        gesnooped wird, wird diesem der Snoop weggenommen (ein Spieler kann
+        immer nur von *einem* Magier gleichzeitig gesnooped werden).
+
+        Ohne das Flag wird nur eine Mitteilung ausgegeben, dass der Spieler
+        schon gesnooped wird.
+
+     l (locked)
+        Gibt man dieses Flag an, so koennen Magier mit kleinerem Level den
+        Spieler nicht snoopen, waehrend man selbst es gerade tut.
+
+        Laesst man das Flag weg, und ein Magier mit kleinerem Level will den
+        gleichen Spieler snoopen, so wird er gewissermassen dazwischen
+        geklinkt: Der Spieler wird nun von diesem Magier gesnooped, und der
+        Magier wiederum von Dir.
+
+    Mit der zweiten Form (ohne Argumente) wird das Snoopen wieder beendet.
+
+ SIEHE AUCH:
+    sallow, vertrag, snoop()
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 16:55:04 von Wargon
diff --git a/doc/mcmd/spieler b/doc/mcmd/spieler
new file mode 100644
index 0000000..15a5c22
--- /dev/null
+++ b/doc/mcmd/spieler
@@ -0,0 +1,26 @@
+
+spieler
+-------
+
+ MAGIERKOMMANDO:
+    spieler aus ip <ip-adresse>
+    spieler aus ip von <spieler-name>
+
+ ARGUMENTE:
+     <ip-adresse>   IP-Adresse im Format x.x.x.x
+     <spieler-name> Name eines eingeloggten Spielers
+
+ BESCHREIBUNG:
+    Dieser Befehl zeigt alle Spieler an, die ueber die IP-Adresse
+    <ip-adresse> oder dieselbe IP-Adresse eingeloggt sind wie der
+    Spieler <spieler-name>.
+ 
+    Es werden zudem Informationen wie Einlogdatum, Idlezeit und
+    Zweitieeigenschaft angezeigt.	
+
+ SIEHE AUCH:
+    people, pwho, query_ip_number(E)
+
+
+ LETZTE AENDERUNG:
+    Fre, 04.10.2002, 13:00:00 von Mandragon
diff --git a/doc/mcmd/suender b/doc/mcmd/suender
new file mode 100644
index 0000000..f838b62
--- /dev/null
+++ b/doc/mcmd/suender
@@ -0,0 +1,57 @@
+
+suender
+-------
+
+ ERZMAGIER- UND DEPUTY-KOMMANDO:
+
+    suender ?                    Gibt eine Liste aller eingetragenen 
+                                 "Suender" aus.
+
+    suender <name>               Listet die "Suenden" des Spielers/Magiers
+                                 <name> auf.
+
+    suender +<name> <text>       Fuegt einen "Suendeneintrag" fuer den
+    suender +<name> -f <text>    Spieler/Magier <name> hinzu. Durch Angabe
+                                 der Option -f koennen Eintraege fuer
+                                 bereits geloeschte Spieler/Magier
+                                 nachgetragen werden.
+
+    suender -<name> <nr>         Loescht den "Suendeneintrag" <nr> des
+                                 Spielers/Magiers <name>. Dieses Kommando
+                                 ist Erzmagiern vorbehalten.
+
+    suender !                    Erzeugt ein Dump-File mit allen Eintraegen
+
+    suender *                    Zeigt ALLE Eintraege an (per More() ;)
+
+ ARGUMENTE:
+
+     <name>
+        Name des Spielers/Magiers
+
+     <text>
+        Infotext. Sollte enthalten: 
+          a) ob es eine Verwarnung, eine Bestrafung oder Loeschung ist
+          b) den Grund.
+          c) Bei Nachtraeglichen Eintraegen einen entspr. Hinweis.
+        Der Text wird automatisch um das Datum und den Namen des
+        Eintragenden ergaenzt. 
+
+     <nr>
+        Die Nummer des Eintrags. Nach jeder Loeschung werden die Eintraege
+        neu durchnummeriert!
+
+ BESCHREIBUNG:
+
+    Verwaltung der vom Sheriff und seinem Deputy durchgefuehrten Massnahmen,
+    damit andere Erzmagier/Goetter schneller nachschlagen koennen, ob sie
+    z.B. eine Strafe aufheben duerfen.
+
+    Dieser Befehl steht nur Erzmagiern und Deputies zur Verfuegung.
+
+ SIEHE AUCH:
+
+    sheriff
+
+ LETZTE AeNDERUNG:
+    Die, 15.08.2000, 11:00:00 von Paracelsus
diff --git a/doc/mcmd/tail b/doc/mcmd/tail
new file mode 100644
index 0000000..e4adb59
--- /dev/null
+++ b/doc/mcmd/tail
@@ -0,0 +1,21 @@
+
+tail
+----
+
+ MAGIERKOMMANDO:
+    tail <datei>
+
+ ARGUMENTE:
+
+     <datei>
+        Die auszugebende Datei
+
+ BESCHREIBUNG:
+    Die letzten Zeilen der Datei <datei> werden ausgegeben. Dabei wird ein
+    Maximum von 1000 Byte nicht ueberschritten.
+
+ SIEHE AUCH:
+    cat, head, more
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/tbanish b/doc/mcmd/tbanish
new file mode 100644
index 0000000..227a228
--- /dev/null
+++ b/doc/mcmd/tbanish
@@ -0,0 +1,26 @@
+
+tbanish
+-------
+
+ ERZMAGIERKOMMANDO:
+    tbanish <name> <tage>
+
+ ARGUMENTE:
+
+     <name>
+        Name des Opfers
+     <tage>
+        Die Dauer der Spielpause
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kann man Spielern eine Spielpause auferlegen. Die Dauer
+    wird in Tagen angegeben. Eine Angabe von -1 setzt eine unbefristete
+    Spielpause; mit einer Dauer von 0 Tagen loescht man eine gesetzte Sperre.
+
+    Dieser Befehl kann nur von Erzmagiern und Goettern ausgefuehrt werden.
+
+ SIEHE AUCH:
+    banish, mbanish, sbanish
+
+ LETZTE AeNDERUNG:
+    Mon, 20.12.1999, 23:30:00 von Tiamak
diff --git a/doc/mcmd/todo b/doc/mcmd/todo
new file mode 100644
index 0000000..6373b14
--- /dev/null
+++ b/doc/mcmd/todo
@@ -0,0 +1,35 @@
+
+todo
+----
+
+ MAGIERKOMMANDO:
+    todo neu
+    todo anzeigen [<nummer1>] [bis <nummer2>]
+    todo loeschen <nummer1>
+    todo verschieben [<nummer1>] [nach <ziel>]
+
+ ARGUMENTE:
+
+     <nummer1>
+     <nummer2> Nummer eines Eintrags in der Todo-Liste
+     <ziel>    Nummer eines Eintrags in der Todo-Liste oder 'oben' oder 'unten'
+
+ BESCHREIBUNG:
+    Mit dem Befehl 'todo' kann ein Magier seine Todo-Liste verwalten. Vier
+    grundsaetzliche Optionen stehen hier zur Verfuegung:
+
+    'todo neu' legt einen neuen Eintrag an.
+    'todo loeschen' loescht den Eintrag <nummer1>
+    'todo anzeigen' zeigt entweder alle Eintraege an, einen einzelnen Eintrag
+                    oder einen Ausschnitt aus der Todo-Liste. Falls <nummer2>
+                    kleiner ist, als <nummer1> erfolgt die Ausgabe rueckwaerts.
+    'todo verschieben' verschiebt einen Eintrag an eine bestimmte Stelle oder
+                    einen Schritt nach oben oder unten.
+
+    Negative Nummern bei 'todo anzeigen' werden vom Ende der Todo-Liste aus
+    gezaehlt.
+
+ SIEHE AUCH:
+
+ LETZTE AENDERUNG:
+    Mit, 02.10.2002, 02:00:00 von Mandragon
\ No newline at end of file
diff --git a/doc/mcmd/traenke b/doc/mcmd/traenke
new file mode 100644
index 0000000..1e4d305
--- /dev/null
+++ b/doc/mcmd/traenke
@@ -0,0 +1,28 @@
+
+traenke
+-------
+
+ MAGIERKOMMANDO:
+    traenke
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kann man bestimmen, ob man ueberall, wo ein
+    Zaubertrank versteckt ist, auch einen Trank finden kann.
+
+    Ansonsten findet man nur die Traenke, die man in seiner Liste stehen hat.
+
+    Der Befehl wirkt als Umschalter: Kann man Traenke finden, so wird das
+    Verhalten nun ausgeschaltet, und umgekehrt.
+
+ HINWEIS:
+    Wenn man mit eingeschaltetem "traenke" Zaubertraenke findet, werden
+    diese NICHT aus der ZT-Liste ausgetragen.
+
+ SIEHE AUCH:
+    attribute, zaubertraenke
+
+ LETZTE AeNDERUNG:
+   13.08.2015, Arathorn 
diff --git a/doc/mcmd/trans b/doc/mcmd/trans
new file mode 100644
index 0000000..0c57be4
--- /dev/null
+++ b/doc/mcmd/trans
@@ -0,0 +1,24 @@
+
+trans
+-----
+
+ MAGIERKOMMANDO:
+    trans <name>
+
+ ARGUMENTE:
+
+     <name>
+        Name eines Lebewesens
+
+ BESCHREIBUNG:
+    Das Lebewesen <name> wird zu Dir transportiert.
+
+    Spieler duerfen dadurch nicht im Spiel beeinflusst werden!
+
+    Magier-Lehrlingen steht dieser Befehl noch nicht zur Verfuegung.
+
+ SIEHE AUCH:
+    vertrag, goto
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 16:55:14 von Wargon
diff --git a/doc/mcmd/udpq b/doc/mcmd/udpq
new file mode 100644
index 0000000..4fff71e
--- /dev/null
+++ b/doc/mcmd/udpq
@@ -0,0 +1,47 @@
+
+udpq
+----
+
+ MAGIERKOMMANDO:
+    udpq <mud> <type>
+
+ ARGUMENTE:
+
+     <mud>
+        ein MUD aus der `muds'-Liste
+     <type>
+        Art der gewuenschten Information
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kann man Informationen ueber den UDP-Service und den
+    INETD von anderen MUDs aus der `muds'-Liste abfragen.
+
+    Folgende Informationen (<type>) koennen abgefragt werden:
+
+     commands
+        UDP-Kommandos, die das MUD versteht
+     email
+        EMail-Adresse, mit der das MUD bzw. seine Administratoren zu erreichen
+        sind
+     hosts
+        Die Liste der Hosts, mit denen das MUD in Verbindung steht (im selben
+        Format wie `/etc/INETD_HOSTS'
+     inetd
+        Die Versionsnummer des verwendeten INETD
+     list
+        Die Liste der Informationen, die man mit dem `udpq'-Befehl von dem MUD
+        erhalten kann (das koennen mehr oder weniger Punkte sein, als in
+        dieser Liste hier vorhanden sind, je nach Version des INETD auf der
+        anderen Seite)
+     mud_port
+        Der Port, unter dem das MUD laeuft
+     time
+        Die Systemzeit des MUDs
+     version
+        Die Versionsnummer des verwendeten GameDrivers
+
+ SIEHE AUCH:
+    muds
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/upd b/doc/mcmd/upd
new file mode 100644
index 0000000..d66236a
--- /dev/null
+++ b/doc/mcmd/upd
@@ -0,0 +1,79 @@
+
+upd
+---
+
+ MAGIERKOMMANDO:
+    upd [ -abcdhfilmrv ] <datei> [...]
+
+ ARGUMENTE:
+
+     <datei> [...]
+        die zu bearbeitende(n) Datei(en)
+
+ BESCHREIBUNG:
+    Dieses spezielle Kommando stellt ein dateibasiertes Update dar. Es
+    zerstoert und/oder laedt geladene Objekte (Blueprints).
+
+    Die Dateinamen koennen auch Muster wie * oder ? enthalten.
+
+    Wird ein Objekt nicht nur zerstoert, sondern auch neu erzeugt, so wird
+    Configure() benutzt, sofern es eines hat, d.h. die Objektdaten werden
+    vor der Zerstoerung mittels Configure() abgerufen und im neuen Objekt mit
+    Configure() wieder gesetzt.
+
+    Zusaetzlich koennen folgende Flags angegeben werden:
+
+     -a  Alle Instanzen (Clones) der Datei werden zerstoert. Da dazu die
+         gesamte Objektliste durchsucht werden muss und diese Funktion
+         entsprechend zeitaufwendig ist, sollte man dieses nur mit Bedacht
+         benutzen.
+     -b  Falls es beim Update einen Fehler gab, wird versucht, ein Backtrace
+         aus `/<rechner>.debug.log' zu lesen.
+     -C  Die Nutzung von Configure() wird erzwungen, d.h. Objekte, die kein
+         oeffentliches Configure() haben, werden nicht zerstoert/ersetzt.
+         (im Zusammenspiel mit -l oder -r, inkompatibel mit -c)
+     -c  Die Properties des Originalobjektes werden kopiert. In diesem Fall
+         wird Configure() _nicht_ benutzt (im Zusammenspiel mit -l und -r,
+         inkompatibel mit -C)
+     -d  Beim Zerstoeren der Instanzen werden auch evtl. in ihnen vorhandene
+         Objekte zerstoert. Nuetzlich, um z.B. NPCs samt ihrer Ausruestung zu
+         entsorgen.
+     -f  Alle Instanzen (Clones) der Datei werden gesucht.
+     -h  Es wird kein remove versucht, sondern sofort destruct verwendet.
+         Bitte nur in Ausnahmefaellen verwenden.
+     -i  Nicht nur die Datei selbst wird zerstoert, sondern auch alle geerbten
+         Klassen (soweit sie geladen sind).
+     -l  Die Datei wird geladen (aehnlich wie beim Befehl load, allerdings
+         wird das alte Objekt zerstoert, falls es schon geladen ist).
+     -m  MAKE - wie -i, aber es werden nur Objekte zerstoert, die aelter sind
+         als die Datei
+     -r  Wenn ein Objekt zerstoert wurde, wird versucht, es neu zu laden.
+     -s  Alle Erfolgsmeldungen untergeordneter Prozesse unterdruecken.
+     -v  Der volle Abhaengigkeitsbaum wird ausgegeben (im Zusammenspiel mit
+         -m)
+
+    Es koennen auch Objekte angegeben werden, die nicht als Datei existieren,
+    d.h. man kann auch Instanzen mit dem # im Namen zerstoeren. Ausserdem
+    koennen nur Objekte, die man selbst schreiben darf, zerstoert/geladen
+    werden.
+
+    `upd' merkt sich das zuletzt geladene oder geclonte Objekt! Dies wirkt
+    sich vor allem dann aus, wenn man ein Objekt zum testen immer wieder
+    zerstoeren, updaten, laden und clonen muss. Diese Reihe von Kommandos wird
+    durch `upd -mr' ohne Argument auf das zuletzt geladene oder gelonte Objekt
+    vollzogen.
+
+ BEISPIELE:
+
+    > upd *.c
+    > upd -r *
+    > upd -mv test.c
+    > upd -r test#12345
+    > upd -ar /d/inseln/mandragon/meloran/obj/alle/meloran_obj
+
+ SIEHE AUCH:
+    destruct, load
+    Configure()
+
+ LETZTE AENDERUNG:
+    Tue, Oct 10 18:50:00 2000 von Mandragon
diff --git a/doc/mcmd/verfolge b/doc/mcmd/verfolge
new file mode 100644
index 0000000..8cff48c
--- /dev/null
+++ b/doc/mcmd/verfolge
@@ -0,0 +1,40 @@
+
+verfolge
+--------
+
+ MAGIERKOMMANDO:
+    verfolge [<name>]
+
+ ARGUMENTE:
+
+    <name> (optional)
+       Name eines eingeloggten Spielers oder eines NPCs. Der angegebene
+       Name muss eindeutig sein, jedoch reichen die Anfangsbuchstaben aus.
+       Wenn das der Fall ist, wird zuerst nach einem Spieler dieses Namens
+       gesucht, danach nach einem NPC im selben Raum wie der Magier, 
+       anschliessend nach einem NPC irgendwo sonst im Mud. Falls sich das 
+       Zielobjekt nicht im selben Raum wie der Magier befindet, wird er
+       hinbewegt.
+
+       Der Magier kann sich nicht selbst verfolgen.
+
+       Es werden nur Lebewesen gefunden, die ein Environment haben, denn
+       nur diese koennen sinnvoll verfolgt werden.
+
+ BESCHREIBUNG:
+    Du verfolgst den Spieler oder den NPC <name> durch das ganze MUD.
+
+    'verfolge' ohne Parameter bricht eine aktive Verfolgung ab.
+
+ BEISPIEL:
+    'verfolge hum' beginnt die Verfolgung einer Hummel. Wenn jedoch Humni
+    eingeloggt sein sollte, ist die Eingabe nicht eindeutig und es wird
+    eine Fehlermeldung ausgegeben. In diesem Fall koennte man die Angabe 
+    durch Hinzufuegen eines Zeichens praezisieren, beispielsweise 
+    'verfolge humm'.
+
+ SIEHE AUCH:
+    goto, snoop
+
+ LETZTE AeNDERUNG:
+    Thu, 21.04.2016 von Arathorn
diff --git a/doc/mcmd/vis b/doc/mcmd/vis
new file mode 100644
index 0000000..f9f3b92
--- /dev/null
+++ b/doc/mcmd/vis
@@ -0,0 +1,19 @@
+
+vis
+---
+
+ MAGIERKOMMANDO:
+    vis [e]
+
+ ARGUMENTE:
+    Wird der Paramater ´e` angegeben, erhalten die Mitspieler die
+    Erwartemeldungen wie beim Einloggen.
+
+ BESCHREIBUNG:
+    Falls Du unsichtbar warst, wirst Du nun wieder sichtbar.
+
+ SIEHE AUCH:
+    invis
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/mcmd/zap b/doc/mcmd/zap
new file mode 100644
index 0000000..b0bf515
--- /dev/null
+++ b/doc/mcmd/zap
@@ -0,0 +1,25 @@
+
+zap
+---
+
+ MAGIERKOMMANDO:
+    zap <name>
+
+ ARGUMENTE:
+
+     <name>
+        Name eines Lebewesens
+
+ BESCHREIBUNG:
+    Das Lebewesen <name> wird mit einem Schlag getoetet. Dabei werden die
+    Meldungen aus der Property P_ZAP_MSG ausgegeben.
+
+    Spieler duerfen mit diesem Befehl nicht beeinflusst werden!
+
+    Magier-Lehrlingen steht dieser Befehl noch nicht zur Verfuegung.
+
+ SIEHE AUCH:
+    vertrag, toete
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 16:55:20 von Wargon
diff --git a/doc/mcmd/zwinge b/doc/mcmd/zwinge
new file mode 100644
index 0000000..5f57f73
--- /dev/null
+++ b/doc/mcmd/zwinge
@@ -0,0 +1,27 @@
+
+zwinge
+------
+
+ MAGIERKOMMANDO:
+    zwinge <name> [zu] <kommando>
+
+ ARGUMENTE:
+
+     <name>
+        Name eines Lebewesens
+     <kommando>
+        Die auzufuehrende Aktion
+
+ BESCHREIBUNG:
+    Das angegebene Lebewesen wird dazu gezwungen, die angegebene Aktion
+    auszufuehren. Allerdings beherrschen insbesondere NPCs nicht alle Befehle.
+
+    Spieler duerfen mit diesem Befehl nicht beeinflusst werden!
+
+    Magier-Lehrlingen steht dieser Befehl noch nicht zur Verfuegung.
+
+ SIEHE AUCH:
+    vertrag
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 16:55:24 von Wargon
diff --git a/doc/missing b/doc/missing
new file mode 100644
index 0000000..ea65a92
--- /dev/null
+++ b/doc/missing
@@ -0,0 +1,8 @@
+Fehlende Manpages, die mal geschrieben werden muessten:
+======================================================
+
+* P_MAGIC_RESISTANCE_OFFSET
+* P_DEFUEL_LIMIT_FOOD, P_DEFUEL_LIMIT_DRINK
+* P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+* P_DEFUEL_AMOUNT_FOOD, P_DEFUEL_AMOUNT_DRINK
+* 
diff --git a/doc/obj/doormaster b/doc/obj/doormaster
new file mode 100644
index 0000000..c3df97b
--- /dev/null
+++ b/doc/obj/doormaster
@@ -0,0 +1,26 @@
+Der doormaster.c dient als zentrale Verwaltungsstelle fuer die Tueren im
+MorgenGrauen. In der Regel kommt man mit diesem Objekt nicht in Beruehrung,
+da die Kommunikation ueber /std/room/doors.c laeuft.
+
+Folgende Funktionen stehen zur Erzeugung, Abfrage und Manipulation von Tueren
+bereit:
+
+ * NewDoor()
+     Tuer einbauen. Wird im ueblicherweise im create() eines Raums benutzt.
+
+ * QueryDoorStatus()
+     Status einer Tuer abfragen.
+
+ * SetDoorStatus()
+     Status einer Tuer setzen.
+
+ * QueryAllDoors()
+     Gibt ein Mapping mit allen Tueren im MG und deren Zustaenden zurueck.
+
+
+SIEHE AUCH:
+    NewDoor(), QueryDoorKey(), QueryDoorStatus(), SetDoorStatus(),
+    /std/room/doors.c, GetPhiolenInfos(), QueryAllDoors(), P_DOOR_INFOS
+
+-----------------------------------------------------------------------------
+Letzte Aenderung: Don, 08.05.2014, Gabylon
diff --git a/doc/obsolete/add_verb b/doc/obsolete/add_verb
new file mode 100644
index 0000000..ca71933
--- /dev/null
+++ b/doc/obsolete/add_verb
@@ -0,0 +1,27 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+        void add_verb(string str)
+
+DESCRIPTION:
+        This function is connected to the add_action() function. It
+        will set up the command str to trigger a call to the function
+	set up by the previous call to add_action().
+        
+        This function is now obsolete as the verb can be given directly
+	with add_action(). add_verb() remains for compatibility.
+
+	[marion Sun Jan 19 1992 Don't use it. This file is retained
+	because of somewhat nostalgic reasons.]
+
+HISTORY
+  Removed in LDMud 3.3 and LP "03.02.1@150",
+  obsoleted by add_action().
+
+SEE ALSO:
+        add_action(E), query_verb(E), add_xverb(E), remove_action(E)
+
+29.10.2006 Zesstra
\ No newline at end of file
diff --git a/doc/obsolete/add_xverb b/doc/obsolete/add_xverb
new file mode 100644
index 0000000..bc81dbb
--- /dev/null
+++ b/doc/obsolete/add_xverb
@@ -0,0 +1,28 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS
+	void add_xverb(string str)
+
+DESCRIPTION
+	This function is connected to the add_action() function. It
+	will set up the command str to trigger a call to the function
+	set up by the previous call to add_action().
+	
+	add_xverb() differs from add_verb() in that only leading
+	characters of the input line must match with str. It basically
+	is the same as setting flag in add_action().
+
+	[marion Sun Jan 19 1992 Don't use it. This file is retained
+	because of somewhat nostalgic reasons.]
+
+HISTORY
+  Removed in LDMud 3.3 and LP "03.02.1@150",
+  obsoleted by add_action().
+
+SEE ALSO
+	add_action(E), query_verb(E), add_verb(E)
+
+29.10.2006 Zesstra
\ No newline at end of file
diff --git a/doc/obsolete/allocate_mapping b/doc/obsolete/allocate_mapping
new file mode 100644
index 0000000..22e1252
--- /dev/null
+++ b/doc/obsolete/allocate_mapping
@@ -0,0 +1,33 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+	mapping m_allocate(int size, int width)
+
+DESCRIPTION:
+	Reserve memory for a mapping.
+
+	size is the number of entries (i.e. keys) to reserve, width is
+	the number of data items per entry. If the optional width is
+	omitted, 1 is used as default.
+
+	This is useful only when you are going to construct a mapping
+	whose approximate size you know beforehand, to save on malloc
+	overhead. If you don't fill in data for all the allocated
+	elements, any leftovers will be freed after the current
+	function execution ended. It is also useful if you want the
+	mapping to have a certain width even if you don't provide
+	all the data items for the keys yet.
+
+HISTORY
+  Renamed to 'm_allocate()' in LDMud 3.2.6 and LP "03.02.1@150".
+  Since LDMud 3.2.9, not available if driver is compiled without
+    USE_DEPRECATED.
+  Removed in LDMud 3.3 and LP "03.02.1@150"
+
+SEE ALSO:
+	mappings(LPC), walk_mapping(E), get_type_info(E)
+
+29.10.2006 Zesstra
\ No newline at end of file
diff --git a/doc/obsolete/assoc b/doc/obsolete/assoc
new file mode 100644
index 0000000..bd5a945
--- /dev/null
+++ b/doc/obsolete/assoc
@@ -0,0 +1,31 @@
+OPTIONAL, VERALTET
+SYNOPSIS
+        int   assoc(mixed key, mixed *keys);
+        mixed assoc(mixed key, mixed *alist [, mixed fail]);
+        mixed assoc(mixed key, mixed *keys, mixed *data [, mixed fail]);
+
+BESCHREIBUNG
+        Alle drei Aufrufe suchen nach einem <key> in einem <alist> (einem
+        Array von zwei Arrays gleicher Groesse) oder in einem geordneten
+        Array <keys>. Der Versuch, in einem anderen Konstrukt zu suchen,
+        fuehrt zu einem unvorhersehbaren Ergebnis.
+
+        Komplexitaet: O( lg(n) ), wobei <n> die Anzahl Keys ist.
+
+        1.  Form: Key-Suche
+            <key> wird im Array <keys> gesucht. Das Resultat ist der Index,
+            in dem <key> gefunden wurde. Wird <key> nicht gefunden, liefert
+            assoc() -1.
+
+        2.  Form: Suche in Alist.
+            <key> wird in der <alist> gesucht, das Resultat sind die Werte,
+            die zu <key> gehoeren, wenn <key> gefunden wird. Wenn <key> nicht
+            gefunden wird, wird 0 zurueck geliefert oder <fail>, falls
+            angegeben.
+
+        Damit das Sinn macht, muss <data> so geordnet sein, dass es zu <key>
+        passt. Diese Form der Suche ist deshalb vorwiegend fuer
+        multidimensionale Alists geeignet.
+
+SIEHE AUCH
+        alists(LPC), insert_alist(E), order_alist(E)
diff --git a/doc/obsolete/copy_mapping b/doc/obsolete/copy_mapping
new file mode 100644
index 0000000..ea25eab
--- /dev/null
+++ b/doc/obsolete/copy_mapping
@@ -0,0 +1,36 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+	mapping copy(mapping)
+
+DESCRIPTION:
+        Create a shallow copy of <arg> and return it. For arrays and mappings
+        this means that a new array or mapping is created with copies of the
+        original content. Embedded arrays and mappings are copied by reference!
+
+EXAMPLE
+        mixed *a, *b;
+
+        a = ({ 1, ({ 21, 22 }) });
+        b = copy(a);
+        a[0] = -1; a[1][0] = -21;
+         --> a is now ({ -1, ({ -21, 22 }) })
+             b is now ({  1, ({ -21, 22 }) })
+
+WARNING
+	Keep in mind, that a copy of a mapping, that contains arrays/mappings,
+	contains references to these Mappings/Arrays, not real copies. If you
+	don't take care, you can a) change the original mappings while working
+	on the copy and b) create recursive mappings, that leak memory.
+
+HISTORY
+  Superseeded by the copy() efun.
+  Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO:
+	mappings(LPC)
+
+26. September 2006, Zesstra
\ No newline at end of file
diff --git a/doc/obsolete/creator b/doc/obsolete/creator
new file mode 100644
index 0000000..44c320e
--- /dev/null
+++ b/doc/obsolete/creator
@@ -0,0 +1,22 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS
+        string creator(object ob)
+
+DESCRIPTION
+        This functions is not available in native mode, which uses
+        user-ids instead.
+        Returns the creator (i.e. the name of the wizard or domain) of
+        the object. Default for ob is this_object().
+
+HISTORY
+        Since 3.2.1@47, this efun is an alias for getuid().
+
+SEE ALSO
+        getuid(E), native(C), uids(C)
+
+Zesstra, 04.02.2007
+
diff --git a/doc/obsolete/creator_file b/doc/obsolete/creator_file
new file mode 100644
index 0000000..c4fe6ef
--- /dev/null
+++ b/doc/obsolete/creator_file
@@ -0,0 +1,32 @@
+
+   *****************************************************************
+   * ACHTUNG: WIRD VOM DRIVER NICHT MEHR GERUFEN! NICHT VERWENDEN! *
+   *****************************************************************
+
+SYNOPSIS
+	string creator_file(mixed ob)
+
+DESCRIPTION
+	Return the name of the creator of a newly created object, i.e.
+	the name of the user that is responsible for the LPC source
+	file the object was loaded from. If the function returns 0,
+	the object can't be loaded and is destructed again
+	immediately.
+
+	In !compat mode, the returned string serves as the initial uid
+	(``cuid'') of the object. Objects whose cuid is the
+	backbone-id will then get the uid of the currently active user
+	as their userid instead.
+
+	Under compat mode this function is called as well.
+
+	If this function is not provided by the master object, no
+	other object can be loaded.
+
+HISTORY
+	Dropped in 3.2.1, replaced by the _UID driver hooks.
+
+SEE ALSO
+	uids(C), creator(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/define_include_dirs b/doc/obsolete/define_include_dirs
new file mode 100644
index 0000000..4436308
--- /dev/null
+++ b/doc/obsolete/define_include_dirs
@@ -0,0 +1,24 @@
+
+   *****************************************************************
+   * ACHTUNG: WIRD VOM DRIVER NICHT MEHR GERUFEN! NICHT VERWENDEN! *
+   *****************************************************************
+
+SYNOPSIS
+	string *define_include_dirs(void)
+
+DESCRIPTION
+	Return an array of string patterns giving the absolut paths
+	where to search an include file. The patterns have to have a
+	%s at the place where the name given in the #include statement
+	has to be inserted.
+
+EXAMPLE
+	define_include_dirs() { return ({ "sys/%s", "lib/%s" }); }
+
+HISTORY
+	Dropped in 3.2.1, replaced by H_INCLUDE_DIRS hook.
+
+SEE ALSO
+	master(M)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/efun308 b/doc/obsolete/efun308
new file mode 100644
index 0000000..9ebb42d
--- /dev/null
+++ b/doc/obsolete/efun308
@@ -0,0 +1,27 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS
+	void efun308(object item, object env)
+
+DESCRIPTION
+	The item is moved into its new environment env, which may be 0.
+	This efun is to be used in the move_object() hook, as it does
+	nothing else than moving the item - no calls to init() or such.
+
+	Don't use it in your own objects!
+
+HISTORY
+	Introduced in 3.2.1@1
+  renamed to 'set_environment()' in LDMud 3.2.6 and LP "03.02.1@150".
+  Since LDMud 3.2.9, not available if driver is compiled without
+    USE_DEPRECATED.
+  Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO
+	remove(A), init(A), move_object(E), transfer(E), hooks(C),
+	native(C)
+
+29.10.2006 Zesstra
\ No newline at end of file
diff --git a/doc/obsolete/exclude_array b/doc/obsolete/exclude_array
new file mode 100644
index 0000000..9457e03
--- /dev/null
+++ b/doc/obsolete/exclude_array
@@ -0,0 +1,27 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+	mixed *exclude_array(mixed *arr, int from, int to)
+
+DESCRIPTION:
+  Deletes an section from an array.
+
+  Please use the slicing operator:
+  arr = arr[0..from-1]+arr[to+1..<1]
+  or even better:
+  arr[from..to] = ({});
+
+  This efun is temporarily a simulated efun until is finally
+  droppped.
+
+HISTORY
+        Removed in LDMud 3.3.
+
+SEE ALSO
+        [](E)
+
+16.12.2008 Zesstra
+
diff --git a/doc/obsolete/extract b/doc/obsolete/extract
new file mode 100644
index 0000000..de40e00
--- /dev/null
+++ b/doc/obsolete/extract
@@ -0,0 +1,26 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS
+        string extract(string str, int from, int to)
+        string extract(string str, int from)
+
+DESCRIPTION
+	DO NOT USE THIS EFUN ANYMORE! IT HAS BEEN REMOVED FROM THE DRIVER.
+
+        Extract a substring from a string.
+        This is the old notation for str[from..to] and supported
+        only for hysterical raisins.
+        
+        In LDMud this efun is temporarily a simulated efun until is finally
+        droppped.
+
+HISTORY
+        Removed in LDMud 3.3.
+
+SEE ALSO
+        [](E)
+
+11.11.2006 Zesstra
diff --git a/doc/obsolete/file_name b/doc/obsolete/file_name
new file mode 100644
index 0000000..81f42dc
--- /dev/null
+++ b/doc/obsolete/file_name
@@ -0,0 +1,36 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+  string object_name()
+  string object_name(object ob)
+
+DESCRIPTION:
+  Get the file name of an object or if no argument is given of the current
+  object. If the object is a cloned object, then it will not have a
+  corresponding file name, but rather a new name based on the original
+  file name.
+  The returned name always begins with '/' (absolute path),
+	except when the parser runs in COMPAT (-o) mode.
+
+EXAMPLES:
+  find_object(object_name(ob)) == ob
+  This is guaranteed to be true for all objects ob that are not
+  destructed.
+  
+  sizeof(explode(object_name(ob), "#")) == 1
+  This is always true if ob is a blue print.
+
+HISTORY
+  In LDMud 3.2.6 renamed to object_name(), this old name is
+  available as alias.
+  Since LDMud 3.2.9, not available if driver is compiled without
+  USE_DEPRECATED.
+  Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO:
+   find_object(E)
+
+29.10.2006 Zesstra
\ No newline at end of file
diff --git a/doc/obsolete/filter_array b/doc/obsolete/filter_array
new file mode 100644
index 0000000..772cb03
--- /dev/null
+++ b/doc/obsolete/filter_array
@@ -0,0 +1,151 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+filter_array(E)
+
+FUNKTION:
+     mixed *filter_array(mixed *arr, string fun, string|object ob
+                         [, mixed extra, ...])
+     mixed *filter_array(mixed *arr, closure cl [, mixed extra, ...])
+     mixed *filter_array(mixed *arr, mapping map)
+
+PARAMETER:
+     arr	- zu filterndes Array
+     fun/cl	- zu rufende Methode/Closure
+     map	- filterndes Mapping
+     ob		- Objekt/Dateiname, an dem Methode gerufen werden soll
+     extra	- weitere Parameter fuer Methode/Closure
+
+BESCHREIBUNG:
+     Filtert die Elemente aus 'arr' durch die Methode 'fun', die Closure 'cl'
+     oder das Mapping 'map' in ein neues Array.
+     Fuer jedes Element aus 'arr' wird 'fun' oder 'cl' mit dem Element als
+     erstem Parameter [und folgend den optionalen Extra-Parametern] gerufen
+     bzw. 'map' mit dem Element indiziert.
+
+     Wenn der Aufruf
+	ob->fun(element [, extra1, extra2, ...]) bzw.
+	funcall(cl, element [, extra1, extra2, ...])
+     als Rueckgabewert !=0 zurueckgibt oder das Element als Schluessel im
+     Mapping enthalten ist:
+	member(map, element) == 1
+     dann wird das Element in das neue Array aufgenommen, sonst nicht.
+
+
+     Verwendung von Methoden:
+	Wenn bei der Angabe von 'fun' kein Objekt 'ob' in Form eines Strings
+	oder Objekts angegeben wird, wird this_object() angenommen.
+
+     Verwendung von Closures:
+	Es koennen sowohl Lfun-Closures als auch Lambda-Closures verwendet
+	werden. Lfun-Closures koennen, wenn im selben Objekt vorhanden auch
+	'private' oder/und 'static' deklariert sein, muessen aber zu dem
+	Zeitpunkt der Verwendung bekannt sein (Funktionsprototypen benutzen).
+
+RUeCKGABEWERT:
+     Gefiltertes Array mit Filterbedingung erfuellenden Elementen.
+
+BEMERKUNGEN:
+     (1) Achtung, die Elemente in 'arr' werden nicht tief kopiert, sind sie
+     also selbst Arrays oder Mappings, so fuehrt eine spaetere Aenderung im
+     Rueckgabe-Arrays zur Aenderung im Ursprungsarray:
+
+     int *i, *j;
+     i=({({1,2,3}),({4,5,6})});
+     j=filter_array(i, #'sizeof);	// filtert leere Arrays heraus
+     j[0][0]=8;
+
+     fuehrt zu: i==j==({({8,2,3}),({4,5,6})});
+
+     (2) Das Kopieren in das Rueckgabemapping erfolgt fuer jedes Element nach
+     Ausfuehrung der Filtermethode. Aenderungen der Werte im Array in dieser
+     Methode (globale Variable/Uebergabe als Referenz an filter_array)
+     schlagen sich also im Rueckgabearray nieder.
+
+BEISPIEL:
+     ### Filtere alle Lebewesen in einem Raum in ein Array ###
+     filter_array(all_inventory(this_object()),#'living);
+
+
+     ### Filtere alle tauben Spieler im Raum in ein Array ###
+     static int filter_isdeaf(object who) {
+       return(living(who) && who->QueryProp(P_DEAF));
+     }
+     ...
+     filter_array(all_inventory(this_object()), #'filter_isdeaf);
+
+
+     ### Filtern von Idlern (>=1 Sekunde idle) ###
+     // Folgend identische Resultate, aber andere Ansaetze:
+
+     #1: nutzt die Efun query_idle() als Lfun-Closure (ideal hier)
+     idle_usr = filter_array(users(), #'query_idle );
+
+     #2,3: mit Filtermethode
+     int check_if_idle(object user) {
+      return query_idle(user);
+     }
+      #2: filtert mittels der Lfun im selben Objekt die Idler in das
+          Rueckgabearrays
+      idle_usr = filter_array(users(), "check_if_idle");
+      idle_usr = filter_array(users(), "check_if_idle", this_object());
+
+      #3: ruft die Lfun check_if_idle() als Lfun-Closure (Funktionspointer)
+      idle_usr = filter_array(users(), #'check_if_idle );
+
+     #4: nutzt eine Lambda-Closure (langsamer, nicht fuer alle leserlich)
+     idle_usr = filter_array(users(), lambda(({'u}), ({#'query_idle, 'u})));
+
+
+     ### Filtern von Idlern (>=20 Sekunden idle) mit Extraparameter ###
+     // Folgend identische Resultate, aber andere Ansaetze:
+
+     #1: die Efun koennen wir nicht mehr direkt nutzen, weil sie
+         diesen Parameter nicht unterstuetzt
+     // idle_usr = filter_array(users(), #'query_idle );
+
+     #2,3: mit Filtermethode ... mit neuem Parameter
+     int check_if_idle(object user, int length) {
+      return query_idle(user)>length;
+     }
+      #2: filtert mittels der Lfun im selben Objekt die Idler in das
+          Rueckgabearrays ... mit drittem Parameter!
+      idle_usr = filter_array(users(), "check_if_idle", this_object(), 20);
+
+      #3: ruft die Lfun check_if_idle() als Lfun-Closure (Funktionspointer)
+      idle_usr = filter_array(users(), #'check_if_idle, 20);
+
+     #4: nutzt eine Lambda-Closure (langsamer, nicht fuer alle leserlich)
+     idle_usr =
+       filter_array(users(),
+         lambda(({'u, 'l}), ({#'>,({#'query_idle, 'u}),'l})),
+         20);
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i;
+     mixed *ret; mixed *input;
+
+     ret=allocate(0);
+     i=sizeof(input);
+     while(i--)
+       if(ob->fun(input[i] [, extra1, extra2, ...]))
+       // if(funcall(cl, input[i] [, extra1, extra2, ...]))
+       // if(member(map, input[i]))
+         ret+=({input[i]});
+HISTORY
+    Since LDMud 3.2.6 obsoleted by efun filter().
+    Since LDMud 3.2.9, not available if driver is compiled without
+      USE_DEPRECATED.
+    Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SIEHE AUCH:
+     Arrays:		fmap_array(E)
+     Objektarrays:	filter_objects(E), map_objects(E)
+     Mappings:		filter(E), map(E)
+
+     Sonstiges:		sort_array(E), unique_array()
+			alist, transpose_array(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/filter_array.eng b/doc/obsolete/filter_array.eng
new file mode 100644
index 0000000..6737929
--- /dev/null
+++ b/doc/obsolete/filter_array.eng
@@ -0,0 +1,60 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+filter_array(E)
+SYNOPSIS
+     mixed *filter_array(mixed *arr, string fun, string|object ob
+                         [, mixed extra, ...])
+     mixed *filter_array(mixed *arr, closure cl [, mixed extra, ...])
+     mixed *filter_array(mixed *arr, mapping map [, mixed extra, ...])
+
+DESCRIPTION
+        Returns an array holding the items of arr filtered through
+        ob->fun(element, extra, ...), the closure cl, or the mapping map.
+        The function 'fun' in 'ob' resp. the closure 'cl' is called
+        for each element in arr with that element as parameter. The
+        extra and following parameters are in each call if given.
+        The mapping 'map' is likewise indexed by each element.
+        If ob->fun(arr[index], extra) returns != 0 resp.
+        map[arr[index]] exists, the element is included in the
+        returned array.
+
+        If arr is not an array, an error occurs.
+
+        The extra argument(s) are optional and must not be protected
+        references like &(i[0]).
+        If <ob> is omitted, or neither a string nor an object, it
+        defaults to this_object().
+
+        Since 3.2.1@36, the second arg can also be a mapping. Then
+        only the elements of the array which belong to the map (as
+        keys) will be returned (i.e. map[arr[index]] != 0).
+
+EXAMPLE
+        int check_if_idle(object user) { return query_idle(user); }
+
+        ...
+
+        object *idle_users;
+
+        idle_users = filter_array(users(), "check_if_idle");
+        /* equivalent but smaller and faster */
+        idle_users = filter_array(users(), #'query_idle );
+
+        Now idle_users contains all users that have been idle for more
+        than 1 second.
+
+HISTORY
+    Since LDMud 3.2.6 obsoleted by efun filter().
+    Since LDMud 3.2.9, not available if driver is compiled without
+      USE_DEPRECATED.
+    Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO:
+        Similar filter:	filter_array(E), filter_object(E), filter(E)
+        Mapping:	map(E), map_objects(E), map(E)
+        Related:	sort_aray(E), unique_array(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/filter_mapping b/doc/obsolete/filter_mapping
new file mode 100644
index 0000000..a70c724
--- /dev/null
+++ b/doc/obsolete/filter_mapping
@@ -0,0 +1,126 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+filter_mapping(E)
+
+FUNKTION:
+     mapping filter(mapping map, string fun, string|object ob
+                            [, mixed extra, ...])
+     mapping filter(mapping map, closure cl [, mixed extra, ...])
+
+PARAMETER:
+     map	- zu filterndes Mapping
+     fun/cl	- zu rufende Methode/Closure
+     ob		- Objekt/Dateiname, an dem Methode gerufen werden soll
+     extra	- weitere Parameter fuer Methode/Closure
+
+BESCHREIBUNG:
+     Filtert die Elemente (jeweils Schluessel) aus 'map' durch die
+     Methode 'fun' oder die Closure 'cl' in ein neues Mapping.
+     Fuer jedes Element aus 'map' wird 'fun' oder 'cl' mit dem Schluessel als
+     erstem Parameter [und folgend den optionalen Extra-Parametern] gerufen.
+
+     Wenn der Aufruf
+	ob->fun(element [, extra1, extra2, ...]) bzw.
+	funcall(cl, element [, extra1, extra2, ...])
+     als Rueckgabewert !=0 zurueckgibt dann wird der Schluessel+Werte in das
+     neue Array aufgenommen, sonst nicht.
+
+     Wenn auf die Werte zugegriffen werden muss, kann das Mapping 'map'
+     zusaetzlich als 'extra'-Parameter uebergeben werden. Alternativ kann man
+     walk_mapping() benutzen und das Rueckgabemapping selbst erstellen.
+
+
+     Verwendung von Methoden:
+	Wenn bei der Angabe von 'fun' kein Objekt 'ob' in Form eines Strings
+	oder Objekts angegeben wird, wird this_object() angenommen.
+
+     Verwendung von Closures:
+	Es koennen sowohl Lfun-Closures als auch Lambda-Closures verwendet
+	werden. Lfun-Closures koennen, wenn im selben Objekt vorhanden auch
+	'private' oder/und 'static' deklariert sein, muessen aber zu dem
+	Zeitpunkt der Verwendung bekannt sein (Funktionsprototypen benutzen).
+
+RUeCKGABEWERT:
+     Gefiltertes Mapping mit Filterbedingung erfuellenden Elementen.
+
+BEMERKUNGEN:
+     (1) Achtung, die Elemente in 'map' werden nicht tief kopiert, sind sie
+     also selbst Arrays oder Mappings, so fuehrt eine spaetere Aenderung im
+     Rueckgabe-Mapping zur Aenderung im Ursprungsmapping:
+
+     mapping m,n;
+     m=([1:({1,2}),0:({2,3,4})]);
+     n=filter(m, #'!);		// filtert alle Keys !=0 heraus
+     n[0][0]=8;
+
+     fuehrt zu: n=([0:({8,3,4})])
+		m=([0:({8,3,4}),1:({1,2})])
+
+     (2) Das Kopieren in das Rueckgabemapping erfolgt fuer jedes Element nach
+     Ausfuehrung der Filtermethode. Aenderungen der Werte im Mapping in dieser
+     Methode (globale Variable/Uebergabe als Referenz an filter)
+     schlagen sich also im Rueckgabemapping nieder.
+
+BEISPIELE:
+     ### erfundene Liste mit Spielern saeubern ... ###
+     mapping x=([ [/human:liafar]:  20,
+		  [/dwarf:mesirii]: 50,
+		  [/elf:zarniya]:   40,
+		  [/feline:turbo]:  30]);
+
+     int is_badguy(object who) {
+      if(who->InFight()) return 1;
+      return 0;
+     }
+
+     mapping result=filter(x, #'is_badguy);
+     // 'result' enthaelt nur noch kaempfende Spieler
+
+     ### erfundene Liste ueber ihre Werte saeubern ###
+     int is_badguy(object who, mapping m) {
+      if(m[x]<30) return 1;
+      return 0;
+     }
+
+     mapping result=filter(x, #'is_badguy, &x); // Referenz
+     // 'result' enthaelt nur Spieler mit Werten >= 30
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i, width;
+     mapping ret; mapping input;
+     mixed *index;
+
+     width=get_type_info(input)[1];
+     ret=m_allocate(0, width);
+     index=m_indices(input);
+     i=sizeof(index);
+     while(i--)
+       if(ob->fun(index[i] [, extra1, extra2, ...]))
+       // if(funcall(cl, index[i] [, extra1, extra2, ...]))
+       {
+         int j;
+         j=width;
+
+         while(j--)
+           ret[index[i],j]=input[index[i],j];
+       }
+
+HISTORY
+    Since LDMud 3.2.6 obsoleted by efun filter_indices().
+    Since LDMud 3.2.9, not available if driver is compiled without
+      USE_DEPRECATED.
+    Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SIEHE AUCH:
+     Arrays:		filter_array(E), map(E)
+     Objektarrays:	filter_objects(E), map_objects(E)
+     Mappings:		map(E)
+
+     Sonstiges:		walk_mapping(E), m_contains(E)
+			member()
+			m_indices(E), m_values(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/get_root_uid b/doc/obsolete/get_root_uid
new file mode 100644
index 0000000..c1de324
--- /dev/null
+++ b/doc/obsolete/get_root_uid
@@ -0,0 +1,20 @@
+
+   **********************************************************
+  * ACHTUNG: WIRD VOM DRIVER NICHT MEHR GERUFEN! NICHT VERWENDEN! *
+   **********************************************************
+
+SYNOPSIS
+	string get_root_uid(void)
+
+DESCRIPTION
+	Return the string to be used as root-uid.
+	Under !native, the function is expendable.
+
+HISTORY
+	In 3.2.1@40, get_root_uid() was renamed to get_master_uid()
+	and got a new semantic.
+
+SEE ALSO
+	get_bb_uid(M), get_master_uid(M), uids(C), creator_file(M), creator(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/initialisation b/doc/obsolete/initialisation
new file mode 100644
index 0000000..e270376
--- /dev/null
+++ b/doc/obsolete/initialisation
@@ -0,0 +1,48 @@
+OBSOLETE
+CONCEPT
+	initialisation
+
+DESCRIPTION
+	There are two different flavours of initialisations,
+	selectable in config.h at driver compile time:
+
+	i)  #undef INITIALIZATION_BY___INIT
+	------------------------------------
+
+	Initialisation is done at compile time. This is fast and costs
+	no extra code in the program.  Allowed expressions currently
+	include integer literals, string literals, integer operators,
+	string addition, bracketing, array constructors, the empty
+	mapping and order_alist() .
+	When an object with initialised variables is cloned or
+	inherited, all initialised variables are copied from the
+	blueprint.  A special application of this feature is to have
+	an initialised non-empty array or a mapping; it will be shared
+	by all clones or inheriting objects unless an assignment to
+	the variable - as opposed to an assignment to an element of
+	the array/mapping - is done in all clones etc.  To prevent
+	unauthorised chenges in initialised arrays/mappings, you can
+	declare the variables as ``private static'' or use a nomask
+	reset/create that checks for undesired inheritance.
+
+	ii) #define INITIALIZATION_BY___INIT
+	-------------------------------------
+
+	Creates a function named __INIT() for all variable
+	initialisations and for calls to __INIT() in all inherited
+	objects, and runs this function at object creation time.
+	Any efun can be used in the expressions for variable
+	initialisations, even ones with severe side effects, like
+	destruct() or shutdown() . The code created for __INIT() is a
+	little worse than a medium-skilled lpc-programmer would
+	generate, because it is scattered all over the program.
+	It is possible (though discouraged) to overload __INIT() with
+	selfwritten functions.
+
+HISTORY
+  Since LDMud 3.3, order_alist() is no longer accepted without
+    INITIALIZATION_BY___INIT.
+  LDMud 3.3.378 replaced this static choice of initialisation
+    methods by compile-time pragmas.
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/intersect_alist b/doc/obsolete/intersect_alist
new file mode 100644
index 0000000..4bbbccb
--- /dev/null
+++ b/doc/obsolete/intersect_alist
@@ -0,0 +1,14 @@
+OPTIONAL
+SYNOPSIS
+        mixed * intersect_alist (mixed * list1, mixed * list2)
+
+DESCRIPTION
+        Does a fast set intersection on alist key vectors (NOT on full alists!).
+        The operator '&' does set intersection on arrays in general.
+
+EXAMPLE
+        new_list = intersect_alist(list1, list2);
+
+SEE ALSO
+        filter(E), assoc(E), insert_alist(E), map(E),
+        member_array(E), order_alist(E), sort_array(E), unique_array(E)
diff --git a/doc/obsolete/is_clone b/doc/obsolete/is_clone
new file mode 100644
index 0000000..d25b9d4
--- /dev/null
+++ b/doc/obsolete/is_clone
@@ -0,0 +1,41 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+FUNKTION:
+	is_clone(mixed ob)
+
+ARGUMENTE:
+	ob - Das zu pruefende Objekt
+
+BESCHREIBUNG:
+	is_clone stellt fest, ob ob ein geclontes Objekt ist oder nicht.
+
+RUECKGABEWERT:
+	1, wenn ob ein geclontes Objekt ist, ansonsten 0.
+
+HINWEIS:
+  Dies ist eine Simul Efun, die inzwischen ueberflussig ist und nur aus
+  Kompatibilitaetsgruenden noch existiert. Bitte die Efun 'clonep' verwenden!
+
+BEISPIELE:
+	inherit "std/thing";
+
+	#include <properties.h>
+
+	create()
+        {
+          if (!is_clone(this_object())) {
+              set_next_reset(-1);
+              return;
+          }
+
+          :: create();
+          ...
+        }
+
+siehe auch: clonep
+
+Zesstra, 04.02.2007
+
diff --git a/doc/obsolete/m_sizeof b/doc/obsolete/m_sizeof
new file mode 100644
index 0000000..2326b47
--- /dev/null
+++ b/doc/obsolete/m_sizeof
@@ -0,0 +1,21 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+	int sizeof(mapping map)
+
+DESCRIPTION:
+	Return the number of indices in mapping 'map'.
+
+HISTORY
+  Since LDMud 3.2.9, not available if driver is compiled without
+    USE_DEPRECATED.
+  Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO:
+	mappingp(E), mkmapping(E), m_indices,(E) m_values(E),
+	m_delete(E), widthof(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/m_width b/doc/obsolete/m_width
new file mode 100644
index 0000000..a6fc7a6
--- /dev/null
+++ b/doc/obsolete/m_width
@@ -0,0 +1,15 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+	int widthof(mapping map)
+
+DESCRIPTION:
+	Return the number of values per index in mapping 'map'. It means
+	the width of the mapping 'map'.
+
+SEE ALSO:
+	mappingp(E), mkmapping(E), m_indices,(E) m_values(E),
+	m_delete(E), sizeof(E)
diff --git a/doc/obsolete/map_array b/doc/obsolete/map_array
new file mode 100644
index 0000000..41329db
--- /dev/null
+++ b/doc/obsolete/map_array
@@ -0,0 +1,90 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+map_array(E)
+
+FUNKTION:
+     mixed *map(mixed *arr, string fun, object ob [, mixed extra])
+     mixed *map(mixed *arr, closure cl [, mixed extra])
+
+PARAMETER:
+     arr	- zu mappendes Array
+     fun/cl	- zu rufende Methode/Closure
+     ob		- Objekt/Dateiname, an dem Methode gerufen werden soll
+     extra	- weitere Parameter fuer Methode/Closure
+
+BESCHREIBUNG:
+     Mapped die Elemente aus 'arr' durch die Methode 'fun' oder die Closure 'cl'
+     in ein neues Array.
+     Fuer jedes Element aus 'arr' wird 'fun' oder 'cl' mit dem Element als
+     erstem Parameter [und folgend den optionalen Extra-Parametern] gerufen
+     bzw. 'map' mit dem Element indiziert.
+
+     Der Rueckgabewert der Methode/Closure wird in an der Indexposition des
+     Elementes in das neue Array eingetragen.
+
+     Verwendung von Methoden:
+	Wenn bei der Angabe von 'fun' kein Objekt 'ob' in Form eines Strings
+	oder Objekts angegeben wird, wird this_object() angenommen.
+
+     Verwendung von Closures:
+	Es koennen sowohl Lfun-Closures als auch Lambda-Closures verwendet
+	werden. Lfun-Closures koennen, wenn im selben Objekt vorhanden auch
+	'private' oder/und 'static' deklariert sein, muessen aber zu dem
+	Zeitpunkt der Verwendung bekannt sein (Funktionsprototypen benutzen).
+
+RUeCKGABEWERT:
+     Array mit Rueckgabewerten der Methode/Closure.
+
+BEISPIELE:
+     ### ersetze Strings durch ihre Grosschreibung ###
+     map(({"abc","cde"}), #'capitalize); == ({"Abc","Cde"})
+
+
+     ### ersetze in einem Spielerobjektarray die Objekte durch ihre UID ###
+     // Folgend identische Resultate, aber andere Ansaetze:
+
+     #1: mit der Efun etuid direkt (ideal hier)
+     map(users(), #'getuid);
+
+     #2,3: mit Mapmethode
+     string make_uid(object o) {
+      return getuid(o);
+     }
+      #2: als LFun-Aufruf der Mapmethode
+      map(users(), "make_uid");
+      map(users(), "make_uid", this_object());
+
+      #3: als Lfun-Closure-Aufruf der Mapmethode
+      map(users(), #'make_uid);
+
+     #4: mit Lambda-Closure (langsamer, nicht fuer alle leserlich)
+     map(users(), lambda(({'x}), ({#'getuid, 'x})));
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i;
+     mixed *ret; mixed *input;
+
+     i=sizeof(input);
+     ret=allocate(i);
+     while(i--)
+       ret[i]=ob->fun(input[i] [, extra1, extra2, ...]));
+       // ret[i]=funcall(cl, input[i] [, extra1, extra2, ...]);
+
+HISTORY
+    Since LDMud 3.2.6 obsoleted by map().
+    Since LDMud 3.2.9, not available if driver is compiled without
+      USE_DEPRECATED.
+    Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SIEHE AUCH:
+     Arrays:		filter_array(E)
+     Objektarrays:	filter_objects(E), map_objects(E)
+     Mappings:		filter(E), map(E)
+
+     Sonstiges:		sort_array(E), unique_array()
+			alist, transpose_array(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/map_mapping b/doc/obsolete/map_mapping
new file mode 100644
index 0000000..22c84c0
--- /dev/null
+++ b/doc/obsolete/map_mapping
@@ -0,0 +1,86 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+map_mapping(E)
+
+FUNKTION:
+     mapping map(mapping m, string fun, object ob [, mixed extra])
+     mapping map(mapping m, closure cl [, mixed extra])
+
+PARAMETER:
+     arr	- zu mappendes Array
+     fun/cl	- zu rufende Methode/Closure
+     ob		- Objekt/Dateiname, an dem Methode gerufen werden soll
+     extra	- weitere Parameter fuer Methode/Closure
+
+BESCHREIBUNG:
+     Mapped die Elemente (jeweils Schluessel) aus 'map' durch die Methode
+     'fun' oder die Closure 'cl' in ein neues Mapping.
+     Fuer jedes Element aus 'map' wird 'fun' oder 'cl' mit dem Schluessel als
+     erstem Parameter [und folgend den optionalen Extra-Parametern] gerufen.
+
+     Der Rueckgabewert der Methode/Closure wird in fuer den Schluessel als
+     Datenwert in das neue Mapping eingetragen.
+
+     ACHTUNG: Alle anderen Daten bei Mapping mit Breite>1 verfallen!
+
+     Verwendung von Methoden:
+	Wenn bei der Angabe von 'fun' kein Objekt 'ob' in Form eines Strings
+	oder Objekts angegeben wird, wird this_object() angenommen.
+
+     Verwendung von Closures:
+	Es koennen sowohl Lfun-Closures als auch Lambda-Closures verwendet
+	werden. Lfun-Closures koennen, wenn im selben Objekt vorhanden auch
+	'private' oder/und 'static' deklariert sein, muessen aber zu dem
+	Zeitpunkt der Verwendung bekannt sein (Funktionsprototypen benutzen).
+
+RUeCKGABEWERT:
+     Mapping mit Schluessel:Rueckgabewerten der Methode/Closure.
+
+BEISPIELE:
+     // ersetze in einem Mapping die Datenwerte durch das Doppelte,
+     // nutze dabei die Datenwerte des Altmappings durch Uebergabe als
+     // extra-Parameter
+
+     // Anmerkung: Das geht mit walk_mapping() eleganter!
+
+     int do_double(string key, mapping m, int mult) {
+      return m[key]*mult;
+     }
+
+     mapping x, y;
+     x=(["a":2, "b":3]);
+     y=map((["a":2, "b":3]), #'do_double, &x, 3);
+
+     y == (["a":6,"b":9])
+
+AeQUIVALENZCODE (nicht empfohlen, nur zum Verstaendnis!):
+     int i;
+     mapping ret; mapping input;
+     mixed *index;
+
+     ret=m_allocate(0, 1);
+     index=m_indices(input);
+     i=sizeof(index);
+     while(i--)
+       ret[index[i]]=ob->fun(index[i] [, extra1, extra2, ...]))
+       // ret[index[i]]=funcall(cl, index[i] [, extra1, extra2, ...]);
+
+HISTORY
+    Since LDMud 3.2.6 obsoleted by map_indices().
+    Since LDMud 3.2.9, not available if driver is compiled without
+      USE_DEPRECATED.
+    Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SIEHE AUCH:
+     Arrays:		filter_array(E), map(E)
+     Objektarrays:	filter_objects(E), map_objects(E)
+     Mappings:		filter(E)
+
+     Sonstiges:		walk_mapping(E), m_contains(E)
+			member()
+			m_indices(E), m_values(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/mapping_contains b/doc/obsolete/mapping_contains
new file mode 100644
index 0000000..88df897
--- /dev/null
+++ b/doc/obsolete/mapping_contains
@@ -0,0 +1,24 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+	int m_contains(mixed &data1, ..., &dataN, map, key)
+
+DESCRIPTION:
+	If the mapping contains the key map, the corresponding values
+	are assigned to the data arguments, which massed be passed by
+	reference, and 1 is returned. If key is not in map, 0 is
+	returned and the data args are left unchanged.
+
+HISTORY
+  Renamed to 'm_contains()' in LDMud 3.2.6.
+  Since LDMud 3.2.9, not available if driver is compiled without
+    USE_DEPRECATED.
+  Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO:
+	mappings(LPC), member(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/member_array b/doc/obsolete/member_array
new file mode 100644
index 0000000..1b948e6
--- /dev/null
+++ b/doc/obsolete/member_array
@@ -0,0 +1,30 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+    int member_array(mixed item, mixed *arr)
+    int member_array(mixed item, string arr)
+
+DESCRIPTION:
+    DO NOT USE THIS EFUN - IT HAS BEEN REMOVED FROM THE DRIVER!
+    Returns the index of the first occurence of item in array arr,
+  	or occurence of a character in a string. If not found, then -1
+  	is returned.
+        
+    If you want to search through an alist, use assoc() because
+    member_array() is good for unsorted but assoc() is faster for
+    sorted arrays.
+        
+    In LDMud this efun is temporarily a simulated efun until is finally
+    droppped.
+
+HISTORY
+    Superseeded by member().
+    Removed in LDMud 3.3.
+
+SEE ALSO:
+        alists(LPC), mappings(LPC), assoc(E), slice_array(E)
+
+11.11.2006 Zesstra
diff --git a/doc/obsolete/obsolete b/doc/obsolete/obsolete
new file mode 100644
index 0000000..f6e805e
--- /dev/null
+++ b/doc/obsolete/obsolete
@@ -0,0 +1,12 @@
+NAME
+    obsolete
+
+DESCRIPTION
+    This directory contains descriptions for features removed from
+    the game driver, since they can come in handy when reworking
+    old LPC code.
+
+SEE ALSO
+    applied(A), efun(E), master(M), concepts(C), lpc(LPC), driver(D)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/order_alist b/doc/obsolete/order_alist
new file mode 100644
index 0000000..32b1c20
--- /dev/null
+++ b/doc/obsolete/order_alist
@@ -0,0 +1,36 @@
+VERALTET
+SYNOPSIS
+        mixed *order_alist(mixed *keys, mixed *data, ...);
+        mixed *order_alist(mixed *list);
+
+BESCHREIBUNG
+        Diese Funktion erzeugt eine Alist.
+
+        Gibt man zwei oder mehr Argumente an, muss das erste Argument
+        ein Array von Keys enthalten, die nachfolgenden Argumente
+        sind Arrays von Datenelementen. Alle <data> Argumente muessen
+        die gleiche Groesse (also die gleiche Anzahl Elemente) wie <keys>
+        haben.
+
+        Gibt man nur ein Argument <list> an, so muss es sich dabei um ein
+        Array handeln, das als erste Element ein Array von Keys und als
+        weitere Elemente Arrays mit Datenelementen enthaelt. Alle Elemente
+        von <list> muessen die gleiche Groesse haben.
+
+        order_alist() liefert ein Array zurueck, das das sortierte <keys>
+        Array und die gleich sortierten <data> Arrays enthaelt. Auf die
+        <data> Arrays wird die gleiche Permutation wie auf das <key> Array
+        angewendet.
+
+        Die Komplexitaet ist O(n*lg(n)+n*m), wobei n die Anzahl Elemente im
+        <keys> Array darstellt, m die Anzahl <data> Arrays + 1.
+
+        Die Dimensionen der Arrays werden gegenueber LISP genau umgekehrt
+        verwendet, um ein schnelleres Suchen zu ermoeglichen.
+
+        Keys muessen vom Typ Integer, String oder Object sein. Die Typen
+        koennen auch gemischt sein.
+
+SIEHE AUCH
+        alists(LPC), mappings(LPC), insert_alist(E), assoc(E),
+        transpose_array(E)
diff --git a/doc/obsolete/parse_command b/doc/obsolete/parse_command
new file mode 100644
index 0000000..2039161
--- /dev/null
+++ b/doc/obsolete/parse_command
@@ -0,0 +1,72 @@
+int parse_command(string str, mixed source, string pattern, var1, var2 ...);
+
+Parses commands given in "str" against the pattern in "pattern" and
+returns 1 if it matches. "source" is either an object or an array of objects.
+This is essentially a 'hotted' sscanf and it has a similar syntax, although
+parse_command works on word basis where sscanf works on character basis.
+
+.ip str
+Given command
+.ip source
+Either an array holding the accessible objects, or
+an object from which to recurse and create
+the list of accessible objects, normally
+ob = environment(this_player()) .
+
+.ip pattern
+Parse pattern as list of words and formats:
+.nf
+		Syntax:
+			'word' 		obligatory text (One word)
+			[word]		optional text (One word)
+			/		Alternative marker
+			%o		Single item, object
+			%l		Single living object
+			%s		Any text (multiple words)
+			%w              Any word
+			%p		Preposition
+			%i		Any items
+			%d              Number 0- or tx(0-99)
+.fi
+Example string: " 'get' / 'take' %i " .
+Items as in %o and %i can on many forms, some examples:
+.nf
+			apple, two apples, twentyfirst apple
+			apples, all apples, all green apples, all green ones
+.fi
+
+.ip varN
+This is the list of result variables as in sscanf.
+One variable is needed for each %_.
+The return types of different %_ is:
+.nf
+	%o	Returns an object
+	%l	Returns an object
+	%s	Returns a string of words
+	%w      Returns a string of one word
+	%p	Can on entry hold a list of word in array
+		or an empty variable
+		Returns:
+		   if empty variable: a string
+		   if array: array[0]=matched word
+	%i	Returns a special array on the form:
+		[0] = (int) given numeric prefix
+		       =0: all or a pluralform given
+		       >0: numeral given: two, three, four...
+		       <0: order given: second, third ...
+		[1..n] (object) Objectpointers
+		       A list of the POSSIBLE objects that can match
+		       the given %i. No choosing of third or such.
+	%d      Returns a number
+.fi
+.lp
+Example:
+
+a=parse_command("take apple",environment(this_player()),
+	 " 'get' / 'take' %i ",items);
+
+HISTORY
+  LDMud 3.3.258 and LP "03.02.1@150" removed the compat-mode 
+  parse_command().
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/query_imp_port b/doc/obsolete/query_imp_port
new file mode 100644
index 0000000..b6a7c3d
--- /dev/null
+++ b/doc/obsolete/query_imp_port
@@ -0,0 +1,21 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+	int query_udp_port(void)
+
+DESCRIPTION:
+	Returns the port number that is used for the inter mud
+	protocol.
+
+HISTORY
+  LDMud 3.2.9 renamed this efun to query_udp_port(). This version
+  is available if the driver is compiled with USE_DEPRECATED.
+  Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO:
+	send_udp(E), receive_udp(M)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/receive_imp b/doc/obsolete/receive_imp
new file mode 100644
index 0000000..b42e78f
--- /dev/null
+++ b/doc/obsolete/receive_imp
@@ -0,0 +1,25 @@
+
+   **********************************************************
+  * ACHTUNG: WIRD VOM DRIVER NICHT MEHR GERUFEN! NICHT VERWENDEN! *
+   **********************************************************
+
+SYNOPSIS
+	void receive_udp(string host, string msg, int hostport)
+
+DESCRIPTION
+	Handle a received IMP message.
+
+	This function is called for every message received on the IMP
+	port. Usually it is passed on to some object that handles
+	inter mud communications.
+
+HISTORY
+	The 'hostport' argument was added in 3.2.1.
+  LDMud 3.2.9 renamed this method to receive_udp(); this old version
+  is supported if the driver is compiled with USE_DEPRECATED.
+  Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO
+	send_udp(E), query_udp_port(E)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/send_imp b/doc/obsolete/send_imp
new file mode 100644
index 0000000..c0f8e40
--- /dev/null
+++ b/doc/obsolete/send_imp
@@ -0,0 +1,23 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS:
+	int send_udp(string host, int port, string message)
+
+DESCRIPTION:
+	Sends The message in an UDP packet to the given host and port
+	number. Causes a privilege violation.
+	Returns 1 on success, 0 on failure.
+
+HISTORY
+  LDMud 3.2.9 renamed this efun to send_udp(), and also changed the
+  privilege violation string and the apply names. This old version
+  is available if the driver is compiled with USE_DEPRECATED.
+  Removed in LDMud 3.3 and LP "03.02.1@150".
+
+SEE ALSO:
+	receive_udp(M)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/set_auto_include_string b/doc/obsolete/set_auto_include_string
new file mode 100644
index 0000000..5a3823d
--- /dev/null
+++ b/doc/obsolete/set_auto_include_string
@@ -0,0 +1,28 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS
+        void set_auto_include_string (string arg)
+
+DESCRIPTION
+
+        The arg will be automatically included into every compiled LPC
+        object. This is useful to enforce global definitions, e.g.
+        ``#pragma combine_strings'' or ``#pragma strict_types''.  The
+        calling object needs to be privileged by the master object.
+
+        Note that the auto-include-string is cleared when the master
+        object is reloaded.
+
+HISTORY
+        LDMud 3.2.9 replaced this efun with driver hook H_AUTO_INCLUDE.
+          This old version is available if the driver is compiled
+          with USE_DEPRECATED.
+        Removed in LDMud 3.3.
+
+SEE ALSO
+        set_driver_hook(E), privilege_violation(M), pragma(LPC), master(M)
+
+29.10.2006 Zesstra
diff --git a/doc/obsolete/slice_array b/doc/obsolete/slice_array
new file mode 100644
index 0000000..620bdc9
--- /dev/null
+++ b/doc/obsolete/slice_array
@@ -0,0 +1,27 @@
+
+     **********************************************************
+     *  ACHTUNG: EFUN EXISTIERT NICHT MEHR! NICHT VERWENDEN!  *
+     **********************************************************
+
+SYNOPSIS
+        mixed *slice_array(mixed *array, int from, int to)
+
+DESCRIPTION
+	DO NOT USE THIS EFUN ANYMORE. IT HAS BEEN REMOVED FROM THE DRIVER.
+
+        Returns an array that is a slice of the array <arr> from the
+        index <from> to the index <to>.
+
+        This is the old notation for arr[from..to] and supported
+        only for hysterical raisins.
+
+        In LDMud this efun is temporarily a simulated efun until is finally
+        droppped.
+
+HISTORY
+        Removed in LDMud 3.3.
+
+SEE ALSO
+        [](E)
+
+11.11.2006 Zesstra
diff --git a/doc/pcmd/.readme b/doc/pcmd/.readme
new file mode 100644
index 0000000..8891327
--- /dev/null
+++ b/doc/pcmd/.readme
@@ -0,0 +1,4 @@
+Hier liegen Hilfen zu den Befehlen, ueber die man schon als normaler
+Spieler verfuegt.
+Seher- und Magierbefehle sind andernorts dokumentiert.
+
diff --git a/doc/pcmd/.synonym b/doc/pcmd/.synonym
new file mode 100644
index 0000000..0d25025
--- /dev/null
+++ b/doc/pcmd/.synonym
@@ -0,0 +1,67 @@
+ali alias
+ansi stty
+aus ausgaenge
+ausgang ausgaenge
+betrachte schau
+betr schau
+blind grafik
+blindheit grafik
+disconnect schlafe
+durchsuche suche
+ebene ebenen
+- ebenen
+; emote
+: emote
+erzaehle teile
+erzaehl teile
+farben stty
+farbe stty
+fluester fluestere
+frag frage
+gemote emote
+hist history
+histlen history
+histmin history
+^ history
+& history
+ignorier ignoriere
+i inventur
+inv inventur
+kanaele ebenen
+kanal ebenen
+keepalive telnet
+kkwho kkwer
+kletter klettere
+kwho kwer
+lass wirf
+lese lies
+md detail
+mruf mrufe
+passwd passwort
+password passwort
+punkte info
+quit ende
+rfluester rfluestere
+riech rieche
+rknuddel rknuddle
+ruf rufe
+rwink rwinke
+sag sage
+save speichern
+schlaf schlafe
+schnuppere rieche
+schnupper rieche
+score info
+steck stecke
+such suche
+terminal stty
+tm teile
+unali unalias
+untersuche schau
+unt schau
+vt100 stty
+werfe wirf
+werf wirf
+who wer
+zieh ziehe
+zueck zuecke
diff --git a/doc/pcmd/adverb b/doc/pcmd/adverb
new file mode 100644
index 0000000..2db3008
--- /dev/null
+++ b/doc/pcmd/adverb
@@ -0,0 +1,64 @@
+
+adverb
+------
+
+ KOMMANDO:
+    adverb <abk> <text>
+    adverb [ # | $ ]
+    adverb ? <abk>
+    adverb <abk>
+
+ ARGUMENTE:
+
+     <abk>
+        Eine Abkuerzung fuer ein Adverb
+     <text>
+        Der Text des Adverbs
+
+ BESCHREIBUNG:
+
+    Mit Adverbien koennen einige Verben genauer beschrieben werden. So
+    kann man einfach nur laecheln (laechel), gluecklich laecheln (laechel 
+    glue) oder scrollen (laechel stra und glue und stol und vers). Mit
+    einem / kann man an das Verb noch etwas eigenes einfuegen (jammere 
+    laut und /wie es nur Zauberer koennen).
+
+    Mit dem Kommando adverb kann man die definierten Adverbien anzeigen
+    lassen oder auch eigene Adverbien definieren. Die einzelnen Aufrufe
+    haben folgende Funktion:
+
+    1. Es wird ein neues Adverb mit der Abkuerzung <abk> zu dem Text <text>
+       definiert. Die Abkuerzung kann einen bis sechs Buchstaben lang sein.
+
+    2. Ohne weitere Parameter wird die komplette Adverbienliste angezeigt.
+       `adverb #' zeigt nur die selbstdefinierten Adverbien an, waehrend
+       `adverb $' nur die Standardadverbien anzeigt.
+
+    3. Es wird geprueft, ob es schon ein Adverb zu der Abkuerzung <abk> gibt.
+
+    4. Das Adverb mit der Abkuerzung <abk> wird aus der Liste geloescht. Dies
+       geht jedoch nur mit selbstdefiinierten Adverbien, nicht mit den
+       Standardadverbien!
+
+ BEISPIELE:
+    Ein Adverb `ratlos' mit der Abkuerzung `rat' wird geschaffen:
+
+    > adverb rat ratlos
+    OK, neues Adverb "ratlos" mit der Abkuerzung "rat".
+
+    Wir sehen nach, wie `rat' definiert ist:
+
+    > adverb ? rat
+    Die Abkuerzung rat gehoert zum Adverb:
+    ratlos
+
+    Wir loeschen es wieder:
+
+    > adverb rat
+    OK, Adverb "ratlos" geloescht.
+
+ SIEHE AUCH:
+    verben, adverbien
+
+ LETZTE AeNDERUNG:
+    Thu, 29.03.2008, 12:00:00 von Vanion
diff --git a/doc/pcmd/alias b/doc/pcmd/alias
new file mode 100644
index 0000000..7426f5c
--- /dev/null
+++ b/doc/pcmd/alias
@@ -0,0 +1,100 @@
+
+alias
+-----
+
+ KOMMANDO:
+    alias <alias> <befehl>
+    alias [ -a ] [ <alias> | <abk>* ]
+
+ ARGUMENTE:
+
+     <alias>
+        Der Name des Alias
+     <befehl>
+        Der Text, durch den das Alias ersetzt wird
+     <abk>
+        Die Abkuerzung eines Alias
+     -a
+        Option, um Aliase so auszugeben, wie man sie definiert
+
+ BESCHREIBUNG:
+    (Statt `alias' kann man auch `ali' verwenden!)
+
+    Mit diesem Kommando kann man sich Abkuerzungen fuer oft benutzte Befehle
+    erstellen sowie die schon definierten Aliase ansehen.
+
+    Definiert wird ein Alias mit dem ersten der obigen Kommandos. <alias> darf
+    dabei nur ein Wort umfassen, waehrend <befehl> beliebig lang sein darf.
+
+    Wenn Du von nun an das Alias eingibst, so fuehrst Du den ausgeschriebenen
+    Befehl wortwoertlich aus. Die folgenden Worte im ausgeschriebenen Befehl
+    haben jedoch eine besondere Bedeutung:
+
+     $*      Steht fuer alles, was auf das Alias folgt.
+     $<n>    Steht fuer das <n>te Wort nach dem Alias.
+     $<n>*   Steht fuer alle Worte ab dem <n>ten (einschliesslich).
+
+    Mit dem zweiten der obigen Kommandos kannst Du Dir die Aliase anzeigen
+    lassen. Ohne Parameter werden dabei saemtliche Aliase angezeigt, mit
+    `alias <alias>' wird die Definition von <alias> angezeigt, und mit `alias
+    <abk>*' werden alle Aliase gezeigt, die mit <abk> beginnen.
+
+    Nimmt man die Option -a hinzu (nur sinnvoll, wenn man sich Aliase anzeigen
+    laesst), so werden die Aliase so angezeigt, dass der Text cut-and-paste-
+    faehig ist, d.h. man kann den Text so als Befehl eingeben, wie er aus-
+    gegeben wird (z.B. um einem Zweitcharakter aliases des Erstcharakters zu
+    geben).
+
+    Soll das Zeichen "$" oder das Zeichen "&" im Alias vorkommen ("&" ist aus
+    historischen Gruenden genau wie "$" benutzbar), so muss es mit einem \
+    "gequoted" werden. Soll ein \ vorkommen, muss auch dieser gequoted werden
+    (\\).
+
+    Beginnt eine Befehlszeile mit einem "\", so werden die Aliase nicht
+    ersetzt. Wenn man als Aliasnamen einen auch sonst gueltigen Befehl
+    verwendet, kann man auf diese Weise auf den eigentlichen Befehl zugreifen.
+
+ BEISPIELE:
+    Erst mal ein paar (mehr oder weniger nuetzliche) Aliase anlegen:
+
+    > alias ul untersuche leiche
+    > alias tmh teile highlander mit $*
+    > alias tmz teile zook mit $*
+    > alias weg teile $1 mit Ich bin jetzt weg, \$ verdienen!
+
+    Wenn man sich die Aliase ansehen will:
+
+    > alias
+     tmh    = teile highlander mit $*
+     ul     = untersuche leiche
+     weg    = teile $1 mit Ich bin jetzt weg, \$ verdienen!
+
+    > alias weg
+     weg    = teile $1 mit Ich bin jetzt weg, \$ verdienen!
+
+    > alias tm*
+     tmh    = teile highlander mit $*
+     tmz    = teile zook mit $*
+
+    Und folgendermassen lassen sich die Aliase benutzen:
+
+    > tmh Hi Sheriff!
+    Du teilst Highlander mit: Hi Sheriff!
+
+    > tmz Oh mein Gott! :-)
+    Du teilst Zook mit: Oh mein Gott!
+
+    > weg boing
+    Du teilst Boing mit: Ich bin jetzt weg, $ verdienen!
+
+    > \weg Arbeiten...
+    Du bist jetzt als abwesend gekennzeichnet.
+
+    Das letzte Beispiel zeigt, wie man an einen Befehl kommt, der von einem
+    Alias "ueberladen" wurde.
+
+ SIEHE AUCH:
+    unalias, ersetzungsanzeige
+
+ LETZTE AeNDERUNG:
+    Thu, 11.03.1999, 15:30:00 von Highlander
diff --git a/doc/pcmd/angriffsmeldung b/doc/pcmd/angriffsmeldung
new file mode 100644
index 0000000..5f7ca54
--- /dev/null
+++ b/doc/pcmd/angriffsmeldung
@@ -0,0 +1,54 @@
+
+angriffsmeldung
+---------------
+
+ KOMMANDO:
+    angriffsmeldung an/ein | aus
+
+ BESCHREIBUNG:
+    Schaltet die Anzeige der Angriffsmeldung:
+    > Du greifst XYZ mit ABC an.
+    fuer jede Kampfrunde ein oder aus.
+    
+    Ist "angriffsmeldung" ausgeschaltet, bekommt man nur neue
+    Angriffsmeldungen (zB bei Waffenwechseln) von sich angezeigt.
+
+    Ist sie eingeschaltet, bekommt man in jeder Kampfrunde auch
+    die eigene Angriffsmeldung angezeigt.
+
+ BEISPIEL:
+    > angriffsmeldung an
+    Du siehst saemtliche Angriffsmeldungen von Dir.
+    > toete grille
+    Ok.
+    Du greifst die Grille mit blossen Haenden an.   <--
+    Du triffst eine Grille hart.
+    Die Grille greift Dich an.
+    Eine Grille kitzelt Dich am Bauch.
+    Du greifst die Grille mit blossen Haenden an.   <--
+    Du triffst eine Grille hart.
+    Die Grille greift Dich an.
+    Eine Grille verfehlt Dich.
+    Du greifst die Grille mit blossen Haenden an.   <--
+    Du triffst eine Grille sehr hart.
+
+    > angriffsmeldung aus
+    Du siehst nur neue Angriffsmeldungen von Dir.
+    > toete grille
+    Ok.
+    Du greifst die Grille mit blossen Haenden an.   <--
+    Du triffst eine Grille hart.
+    Die Grille greift Dich an.
+    Eine Grille verfehlt Dich.
+    Du triffst eine Grille hart.
+    Eine Grille verfehlt Dich.
+    Du triffst eine Grille hart.
+    Eine Grille verfehlt Dich.
+    Du triffst eine Grille hart.
+    > zueck dolch
+    Du zueckst den Trolldolch.
+    Du greifst die Grille mit dem Trolldolch an.    <--
+    Du kratzt eine Grille.
+
+ LETZTE AeNDERUNG:
+    1.September 2008 Gloinson
diff --git a/doc/pcmd/antworte b/doc/pcmd/antworte
new file mode 100644
index 0000000..d08dc15
--- /dev/null
+++ b/doc/pcmd/antworte
@@ -0,0 +1,22 @@
+
+antworte
+--------
+
+ KOMMANDO:
+    antworte [<wem>] <was>
+
+ ARGUMENTE:
+
+     <wem> (optional)
+        Das Lebewesen, dem Du antworten willst
+     <was>
+        Die Antwort
+
+ BESCHREIBUNG:
+    Man beantwortet eine Frage.
+
+ SIEHE AUCH:
+    frage, sage, gespraech
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/ausgaenge b/doc/pcmd/ausgaenge
new file mode 100644
index 0000000..ed55734
--- /dev/null
+++ b/doc/pcmd/ausgaenge
@@ -0,0 +1,28 @@
+
+ausgaenge
+---------
+
+ KOMMANDO:
+    ausgaenge [auto]
+    ausgang [auto]
+    aus [auto]
+
+ ARGUMENTE:
+
+     auto (optional)
+        Schaltet automatische Ausgangsanzeige aus/ein
+
+ BESCHREIBUNG:
+    Mit `ausgaenge' werden alle unmittelbar sichtbaren Ausgaenge aus dem Raum,
+    in dem man sich gerade befindet, ausgegeben. Dieser Befehl ist von Nutzen,
+    wenn man sich die Raumbeschreibung nicht durchlesen will. Mit `ausgang
+    auto' werden die unmittelbar sichtbaren Ausgaenge automatisch ausgegeben,
+    ein weiteres `ausgang auto' schaltet die automatische Anzeige wieder ab.
+
+    *Aber*: Es gibt Raeume, die versteckte Ausgaenge haben!
+
+ SIEHE AUCH:
+    schau (an), kurz, bewegung
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/ausruestung b/doc/pcmd/ausruestung
new file mode 100644
index 0000000..6c620d2
--- /dev/null
+++ b/doc/pcmd/ausruestung
@@ -0,0 +1,23 @@
+
+ausruestung
+--------
+
+ KOMMANDO:
+    ausruestung [-k] [farben]
+
+ ARGUMENTE:
+    farben  -  startet die Farbkonfiguration.
+    -k      -  gibt eine Kurzvariante ohne ASCII-Grafik aus.
+
+ BESCHREIBUNG:
+    Zeigt eine graphische Ausgabe der getragenen Ausruestung an.
+    Mittels des Arguments -k wird unabhaengig von 'grafik ein/aus' eine
+    kuerzere Version ohne ASCII-Grafik angezeigt.
+    Die Farbkonfiguration erlaubt, die Darstellung fuer ungewoehnlich
+    eingestellte terminals anzupassen.
+    
+ SIEHE AUCH:
+    behalte, inventur
+
+ LETZTE AeNDERUNG:
+    14.08.2009, Zesstra
diff --git a/doc/pcmd/avatar b/doc/pcmd/avatar
new file mode 100644
index 0000000..49b0d1f
--- /dev/null
+++ b/doc/pcmd/avatar
@@ -0,0 +1,45 @@
+
+avatar
+---------
+
+ KOMMANDO:
+    avatar [<uri>]
+
+ ARGUMENTE:
+
+     <uri> (optional)
+        Die neue URI zum Avatar
+
+ BESCHREIBUNG:
+    Spieler koennen sich mit diesem Kommando einen graphischen Avatar (d.h.
+    ein Bild) geben, welchen manche Clients anzeigen koennen.
+    Hierzu setzt der Spieler hier eine URI, welche auf ein Bild im Netz
+    verweist, welches ggf. vom Client anderer Spieler heruntergeladen wird.
+    Spieler koennen diese Avatar-URI mit dem Befehl 'avatar' anzeigen,
+    aendern und loeschen.
+    Ist das Argument dieses Befehls 'keine', so wird die Avatar-URI
+    geloescht.
+
+    Avatar-URIs anderer Spieler lassen sich mit 'finger -a' ausgeben.
+
+    Wird ein Charakter auf der MG-Homepage gefingert, wird das Bildchen ggf.
+    ebenfalls mit angezeigt. Hierzu muss allerdings eine URL angegeben werden,
+    welche mit http:// oder https:// beginnt.
+ 
+ BEMERKUNGEN:
+    Auf der MG-Homepage werden die Bilder immer auf eine Hoehe von 150 Pixeln
+    skaliert (Breite entsprechend proportional).
+    Um anderen Spielern nicht unnoetige Wartezeiten zu beschweren, sollte die
+    Groesse des Bildes nicht zu riesig sein. Bilder im Bereich von 20-200kB
+    sollten voellig ausreichen.
+
+ BEISPIELE:
+    avatar http://mg.mud.de/avatars/zesstra.png
+    avatar keine
+
+ SIEHE AUCH:
+    Persoenliche Details: email, url, icq, ort
+    Sonstiges:            finger
+
+ LETZTE AENDERUNG:
+    25.08.2011, Zesstra
diff --git a/doc/pcmd/behalte b/doc/pcmd/behalte
new file mode 100644
index 0000000..2264c19
--- /dev/null
+++ b/doc/pcmd/behalte
@@ -0,0 +1,29 @@
+
+behalte
+-------
+
+ KOMMANDO:
+    behalte [[<objekt>] [alles] [nichts]]
+
+ ARGUMENTE:
+
+     <objekt>
+        ein Objekt in Deinem Inventar
+
+     alles/nichts
+        wie es der Parameter schon sagt
+
+ BESCHREIBUNG:
+    Man kann mit diesem Befehl Gegenstaende markieren, so dass sie bei
+    `verkaufe alles' nicht mehr automatisch verkauft werden. Ist der
+    betreffende Gegenstand bereits markiert, wird die Markierung aufgehoben.
+    Saemtliche Sachen lassen sich mit `behalte alles' markieren, mit
+    `behalte nichts' kann man saemtliche Markierungen aufheben.
+
+    Ohne Argument aufgerufen zeigt der Befehl alle markierten Gegenstaende an.
+
+    Angezogene Ruestungen und gezueckte Waffen werden uebrigens automatisch
+    behalten.
+
+ LETZTE AeNDERUNG:
+    Tue, 27.10.1998, 16:00:00 von Rikus
diff --git a/doc/pcmd/bug b/doc/pcmd/bug
new file mode 100644
index 0000000..f440a91
--- /dev/null
+++ b/doc/pcmd/bug
@@ -0,0 +1,61 @@
+
+fehler
+------
+
+KOMMANDO:
+    bug <text>
+    bug <objekt>:<text>
+   
+ARGUMENTE:
+
+    <text>
+        Eine Mitteilung
+    <objekt>
+        Ein Referenzobjekt, das neben Dir liegt oder in Deinem Inventar ist
+
+BESCHREIBUNG:
+    Nobody's perfect. Dies gilt besonders fuer unsere Magier :)
+
+    Wer viel programmiert, kann auch viele Fehler machen. Die meisten Fehler
+    werden zwar schon in der Testphase gefunden und ausgemerzt, aber einige
+    Fehler bleiben bis zum Anschluss eines neuen Gebietes oder Objekts
+    unentdeckt.
+
+    Wenn Du einen solchen Fehler gefunden hast, sei es, weil ein 'Fehler im
+    Raum-Zeit-Gefuege' aufgetreten ist, sei es, weil irgendwelche seltsamen
+    Zeichen in der Beschreibung eines Objektes auftauchen, so kannst Du den
+    Verantwortlichen mit diesem Befehl davon unterrichten.
+    (Anmerkung: FiRZG werden auch automatisch protokolliert und zustaendigen
+     Magiern zur Verfuegung gestellt.)
+
+    Nicht zoegern, wenn Du einen Fehler findest, Fehlermitteilungen sind
+    *sehr* willkommen!
+    Solltest Du Dir einmal nicht sicher sein, ob es sich bei einem bestimmten
+    Verhalten um einen Fehler handelt oder nicht, zoegere nicht, bei dem
+    zustaedigen Magier oder auch bei Spielern und anderen eingeloggten Magiern
+    zu fragen.
+
+    Wenn Du einen Typo an einem bestimmten Objekt oder NPC entdeckst, kannst
+    Du dieses/diesen hinter einem Doppelpunkt angeben, damit der fuer das
+    Objekt verantwortliche Magier die Meldung bekommt.
+    Wenn das Objekt nicht zu finden ist, wird die ganze Eingabe als
+    Meldung aufgefasst.
+
+    Ein Hinweis auf die Regeln hier noch: Das Verschweigen und Ausnutzen von
+    Fehlern ist anderen Spielern gegenueber unfair. Bitte unterlasst das,
+    sondern berichtet die Fehler. Bugausnutzung zu eigenem Vorteil oder
+    anderer Nachteil ist ansonsten durchaus ein Fall fuer Sheriff. ;-)
+
+BEMERKUNG:
+    Der Befehl 'bug' bezieht sich bei Nichtangabe eines Bezugsobjektes
+    auf das letzte betrachtete Objekt. Hast Du also ein Objekt untersucht,
+    dann wird die Meldung fuer diese Objekt abgegeben. Hast Du aber den
+    Raum untersucht oder 'schau' eingegeben, wird die Meldung fuer Deinen
+    momentanen Raum abgesetzt.
+
+SIEHE AUCH:
+    typo, idee, detail, regeln, bezugsobjekt
+
+LETZTE AeNDERUNG:
+    12. Okt 2011 Gloinson
+
diff --git a/doc/pcmd/cicerone b/doc/pcmd/cicerone
new file mode 100644
index 0000000..922ebdf
--- /dev/null
+++ b/doc/pcmd/cicerone
@@ -0,0 +1,49 @@
+
+cicerone
+--------
+
+ KOMMANDO:
+    cicerone [<zustand>]
+
+
+ ARGUMENTE:
+
+    <zustand>
+      'ein', 'aus', 'status' oder 'zahl'
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kannst Du Dich selbst zu einem Cicerone, einem
+    Pfadfinder, Fremdenfuehrer oder Neulingsgehilfen ernennen oder
+    Dich wieder als solcher abmelden. Du weist damit dann explizit
+    darauf hin, dass Du bereit bist, Neulingen hier im MG zu helfen.
+
+    'zahl' macht Dich zum Cicerone, allerdings wirst Du neuen Spielern und bei
+    "kwer cicerone" nur dann angezeigt, wenn Du weniger als 'zahl' Minuten
+    idle bist. So muss man nicht dran denken, den Ciceronestatus
+    explizit auszuschalten, wenn man oefter laengerere Zeit idle ist.
+    'zahl' muss min. 1 und max. 1440 (1 Tag) sein.
+
+    'cicerone' ohne Parameter oder mit dem Parameter 'status' zeigt
+    Dir die aktuelle Einstellung an.
+
+    Bevor Du Dich allerdings darauf einlaesst solltest Du die
+    Hilfeseite zu cicerones lesen, dort werden die Aufgaben der
+    Cicerones naeher spezifiziert.
+
+    Cicerone kannst Du ab einem Spielerlevel von 20 werden.
+
+BEISPIELE:
+    cicerone ein -> Du bist permanent Cicerone (bis Ende/Reboot)
+    cicerone aus -> Du bist kein Cicerone
+    cicerone 5   -> Du bist Cicerone und wirst nur angezeigt, wenn Du weniger
+                    als 5min idle bist.
+
+BEMERKUNGEN:
+    Bitte benutzt die Zeitangabe, wenn ihr beim Idlen doch eher nicht auf den
+    Monitor schaut/erreichbar seid. Idle Cicerones sind wenig hilfreich.
+
+SIEHE AUCH:
+    einfuehrung, cicerones
+
+LETZTE AeNDERUNG:
+    11. Sep 2013 Gloinson
diff --git a/doc/pcmd/detail b/doc/pcmd/detail
new file mode 100644
index 0000000..f684d0b
--- /dev/null
+++ b/doc/pcmd/detail
@@ -0,0 +1,52 @@
+detail
+------
+
+KOMMANDO:
+    detail <text>
+    detail <objekt>:<text>
+    md <text>
+    md <objekt>:<text>
+   
+ARGUMENTE:
+
+    <text>
+        Eine Mitteilung
+    <objekt>
+        Ein Referenzobjekt, das neben Dir liegt oder in Deinem Inventar ist
+
+BESCHREIBUNG:
+    Es soll tatsaechlich immer noch passieren, das der ein oder andere
+    gewissenhafte Forscher, einen Raum oder ein Objekt, etc untersucht
+    und dabei so gruendlich vorgeht, das ihm doch wirklich ein Detail
+    ins Auge springt, welches NICHT beschrieben ist.
+
+    Die Zeiten, das Magier mit so einer offenkundigen Vergesslichkeit 
+    und Nachlaessigkeit ungeschoren davonkommen, sind aber entgueltig 
+    vorbei! Denn DIR ist ein Instrument in die Hand gelegt, mit dem Du
+    diese Magier 'erinnern' kannst.
+
+    <detail text> setzt eine Meldung ueber ein fehlendes Detail in 
+    das entsprechende Log-File des zustaendigen Magiers.
+
+    Bei <text> sollte es sich um einen kurzen, knappen Hinweis handeln,
+    der es dem Magier ermoeglicht, ueber die Notwendigkeit, das fehlende
+    Detail zu ergaenzen schnell entscheiden zu koennen.
+
+    Wenn Du ein Detail an bestimmten Objekt oder NPC vermisst, kannst Du
+    dieses/diesen hinter einem Doppelpunkt angeben, damit der fuer das
+    Objekt verantwortliche Magier die Meldung bekommt.
+    Wenn das Objekt nicht zu finden ist, wird die ganze Eingabe als
+    Meldung aufgefasst.
+
+BEMERKUNG:
+    Der Befehl 'detail' bezieht sich bei Nichtangabe eines Bezugsobjektes
+    auf das letzte betrachtete Objekt. Hast Du also ein Objekt untersucht,
+    dann wird die Meldung fuer diese Objekt abgegeben. Hast Du aber den
+    Raum untersucht oder 'schau' eingegeben, wird die Meldung fuer Deinen
+    momentanen Raum abgesetzt.
+
+SIEHE AUCH:
+    typo, idee, bug, bezugsobjekt
+
+LETZTE AeNDERUNG:
+    12. Okt 2011 Gloinson
diff --git a/doc/pcmd/ebenen b/doc/pcmd/ebenen
new file mode 100644
index 0000000..e77f966
--- /dev/null
+++ b/doc/pcmd/ebenen
@@ -0,0 +1,81 @@
+
+Die Ebenen
+==========
+    Die Ebenen sind eine Kommunikationsform, welche es einem ermoeglicht,
+    eine Unterhaltung ueber weite Strecken hinweg mit mehreren Personen zu
+    fuehren. Diese Form der Unterhaltung ist dem Rufen vorzuziehen, da es
+    fuer Personen, welche sich nicht auf der Ebene befinden, geraeuschlos
+    ist.
+
+    Betreten und Verlassen:
+     -<name>+
+        Ebene <name> einschalten.
+     -<name>-
+        Ebene <name> ausschalten.
+     ebenen neu <Name> <Text>
+        Erzeugt eine neue Ebene <Name> mit der Bezeichung <Text>. Dieses
+        Kommando ist erst ab Stufe 5 moeglich!
+     ebenen an
+        Schaltet die vorher ausgeschalteten Ebenen an.
+        Ist vorher kein `ebene aus' erfolgt, so werden alle nicht
+        eingeschalteten Ebenen eingeschaltet.
+     ebenen aus
+        Schaltet die Ebenen aus.
+
+    Reden auf einer Ebene:
+     -<name>'<Text>
+     -<name> <Text>
+        Sendet die Meldung <Text> auf die Ebene
+     -<name>:<Text>
+        Sendet das `emote' <Text> auf die Ebene
+     -<name>;<Text>
+        Erzeugt ein Genitiv-`emote'
+
+    Ebenennamen:
+     Man kann eine Ebene mit dem vollen Namen ansprechen:
+        "-anfaenger Hallo!"   oder   "-abenteuer Hilfe!"
+     es reicht aber auch schon ein eindeutig von anderen Ebenen abgrenzender
+     Teil des Namens:
+        "-an Hallo!"          oder   "-ab Hilfe!"
+
+     Gueltige Namen setzen sich zusammen aus den Buchstaben a-z, A-Z sowie
+     #$%&@<>-. Das # hat dabei eine Sonderaufgabe: Damit wird der
+     gleichnamige IRC-Channel erzeugt bzw. betreten.
+
+    Informationen und Ebenengeschichte:
+     -<name>?
+        Alle Teilnehmer der Ebene <name> anzeigen.
+     -<name>*<Laenge>
+        Die letzten <Laenge> Meldungen der Ebene <name> anzeigen. Wird die
+        Laenge weggelassen, ist Standard und Maximum 200.
+     -?
+        Alle verfuegbaren Ebenen anzeigen.
+     -!
+        Alle eingeschalteten Ebenen anzeigen.
+     ebenen beschreibung <name> <Text>
+        Veraendert die Beschreibung der Ebene <name>. Dies funktioniert nur,
+        wenn man der Meister der Ebene ist.
+
+    Abkuerzungen/Alias fuer Ebenennamen:
+     Es gibt einige vordefinierte Aliase fuer Ebenen (wie -a fuer -allgemein
+     oder -b fuer -abenteuer). Weitere kann man sich selbst definieren, wenn
+     Ebenennamen zu lang oder mit Sonderzeichen versehen sind:
+
+     ebenen a[bkuerzung]
+        Zeigt alle eingestellten Abkuerzungen an.
+     ebenen a[bkuerzung] s[tandard]
+        Stellt die Standardabkuerzungen ein und zeigt diese an.
+     ebenen <xx>=<Name>
+        Stellt die Abkuerzung <xx> fuer die Ebene <Name> ein. Leerzeichen
+	sind *nicht* zulaessig vor oder hinter dem Gleichheitszeichen '='!
+     ebenen <xx>=
+        Loescht die Abkuerzung <xx>
+     ebenen standard <Name>
+        Setzt die Ebene <Name> als Standard.
+	Damit wird automatisch bei "- <Text>" auf dieser Ebene geredet.
+
+ SIEHE AUCH:
+    irc, senderwiederholung
+
+ LETZTE AeNDERUNG:
+    1. Juli 2006 Ennox
diff --git a/doc/pcmd/email b/doc/pcmd/email
new file mode 100644
index 0000000..4ecb1d9
--- /dev/null
+++ b/doc/pcmd/email
@@ -0,0 +1,28 @@
+
+email
+-----
+
+ KOMMANDO:
+    email [<adresse>]
+
+ ARGUMENTE:
+
+     <adresse> (optional)
+        Die neue Adresse
+
+ BESCHREIBUNG:
+    Ohne Argumente gibt `email' die aktuelle EMail-Adresse aus. Mit Argument
+    wird sie auf die neue Adresse gesetzt.
+
+    Hinweis: eine gueltige EMail-Adresse erleichtert es _erheblich_ im
+    Bedarfsfall ein neues Passwort fuer den Charakter zu setzen. In vielen
+    Faellen ist dies ohne EMail-Adresse nicht moeglich.
+
+SIEHE AUCH:
+    Einstellungen:        emailanzeige
+    Persoenliche Details: email, url, icq, messenger, ort
+    Sonstiges:            finger, wer, kwer
+
+LETZTE AeNDERUNG:
+    12.09.2011, Zesstra
+
diff --git a/doc/pcmd/emailanzeige b/doc/pcmd/emailanzeige
new file mode 100644
index 0000000..02f52b2
--- /dev/null
+++ b/doc/pcmd/emailanzeige
@@ -0,0 +1,22 @@
+KOMMANDO:
+	emailanzeige [Personenkreis]
+
+ARGUMENTE:
+	[Personenkreis]
+	  Die Personen, die beim finger-Befehl Deine Email angezeigt
+	  bekommen.
+
+BESCHREIBUNG:
+	Mit diesem Befehl kann man festlegen, welche Personen beim
+	finger-Befehl die EMail-Adresse angezeigt bekommen, die Du mit
+	den Befehl "email" oder beim ersten Login angegeben hast.
+	Als Optionen stehen zur Verfuegung: alle, freunde, niemand.
+	Achtung: Magier bekommen die Email-Adresse immer angezeigt,
+	auch dann, wenn man "emailanzeige niemand" eingibt.
+
+SIEHE AUCH:
+        Persoenliche Details: email, url, icq, messenger, ort
+        Sonstiges:            finger
+
+----------------------------------------------------------------------------
+Last modified: Mon Okt 16 20:32:44 2000 by Silvana
diff --git a/doc/pcmd/emote b/doc/pcmd/emote
new file mode 100644
index 0000000..e1df4ed
--- /dev/null
+++ b/doc/pcmd/emote
@@ -0,0 +1,64 @@
+
+emote
+-----
+
+ KOMMANDO:
+    emote <text1>[#<name>#<text2>[#<text3>]]
+    :<text1>[#<name>#<text2>[#<text3>]]
+    ;<text1>[#<name>#<text2>[#<text3>]]
+
+ ARGUMENTE:
+
+     <text1>, <text2>, <text3>
+        Zeichenketten
+     <name>
+        Name eines Lebewesens im gleichen Raum wie Du
+
+ BESCHREIBUNG:
+    Gibt den Text <text1> an alle im Raum aus. Dein Name wird dem Text
+    vorangestellt. Verwendet man die `;'-Form, wird Dein Name im Genitiv
+    gewaehlt.
+
+    Werden ein Name und weiterere Texte angegeben, so wird an <name> statt des
+    ersten Textes <text2> ausgegeben (ebenfalls mit Deinem Namen
+    vorangestellt) und an Dich <text3> (ohne Namen).
+
+    Das `emote'-Kommando beherrscht man uebrigens erst, nachdem man die
+    Amaryllis-Quest geloest hat.
+
+    Ist man nur einfacher Spieler (also weder Seher noch Magier), so wird auch
+    noch ein `> ' vor Namen und Text gesetzt.
+
+ BEISPIELE:
+    Angenommen, Wargon und Saphis stehen mit einigen anderen Leuten zusammen
+    in einem Raum.
+
+    Hier ein paar Eingaben von Wargon mit den entsprechenden Ausgaben bei den
+    Anwesenden:
+
+    > :niest.
+
+    |Wargon:| Wargon niest.
+    |Saphis:| Wargon niest.
+    |andere:| Wargon niest.
+
+    > :aergert Saphis.#saphis#aergert Dich.
+
+    |Wargon:| Wargon aergert Saphis.
+    |Saphis:| Wargon aergert Dich.
+    |andere:| Wargon aergert Saphis.
+
+    > :aergert Saphis.#saphis#aergert Dich.#Du aergerst Saphis.
+
+    |Wargon:| Du aergerst Saphis.
+    |Saphis:| Wargon aergert Dich.
+    |andere:| Wargon aergert Saphis.
+
+    Wie man sieht, lassen sich mit der letzten Form und dem alias-Befehl
+    eigene Befehle herstellen (allerdings muss man auf Adverbien verzichten).
+
+ SIEHE AUCH:
+    verben, (ab hier nur fuer Seher) remote, echo
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/ende b/doc/pcmd/ende
new file mode 100644
index 0000000..03dcc99
--- /dev/null
+++ b/doc/pcmd/ende
@@ -0,0 +1,28 @@
+
+ende
+----
+
+ KOMMANDO:
+    ende
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Man verlaesst das Spiel sofort und auf der Stelle (siehe aber auch unter
+    BEMERKUNGEN). Alle Gegenstaende werden fallen gelassen, nur autoladene
+    Gegenstaende (z.B. Geld) behaeltst Du ueber das Spielende hinaus. Wenn Du
+    Dich wieder einloggst, startest Du an Deinem lokalen Startpunkt.
+
+    Der aktuelle Spielstand wird vor dem Verlassen automatisch abgespeichert.
+
+ BEMERKUNGEN:
+    Da einige Leute diesen Befehl gebrauchten, um sich im Kampf Vorteile zu
+    verschaffen, funktioniert der `ende'-Befehl erst zwei Minuten nach der
+    letzten Kampfhandlung.
+
+ SIEHE AUCH:
+    speichern, schlafe (ein)
+
+ LETZTE AeNDERUNG:
+    Tue, 02.09.1997, 15:05:00 von Wargon
diff --git a/doc/pcmd/entgifte b/doc/pcmd/entgifte
new file mode 100644
index 0000000..f3edf65
--- /dev/null
+++ b/doc/pcmd/entgifte
@@ -0,0 +1,25 @@
+
+entgifte
+--------
+
+ KOMMANDO:
+    entgifte [<ziel>]
+
+ ARGUMENTE:
+
+     <ziel> (optional)
+        Das zu entgiftende Lebewesen.
+
+ BESCHREIBUNG:
+    Eigentlich ist dies eine Anrufung des Heiligen Ordens. Allerdings koennen
+    auch Angehoerige anderer Gilden diese Anrufung lernen, nachdem sie das
+    Abenteuer "Verhaengnis des Duesterwalds" geloest haben.
+
+    Falls das <ziel> vergiftet ist, so wird seine Vergiftung gelindert oder
+    gar geheilt (je nach Guete der Anrufung). Ohne Angabe von <ziel> wird
+    die eigene Vergiftung gelindert oder geheilt.
+
+    Die Anwendung der Anrufung kostet 30 Magiepunkte.
+
+ LETZTE AENDERUNG:
+    Fre, 26.11.1999, 15:16:00 von Tilly
diff --git a/doc/pcmd/ersetzungsanzeige b/doc/pcmd/ersetzungsanzeige
new file mode 100644
index 0000000..c2131e2
--- /dev/null
+++ b/doc/pcmd/ersetzungsanzeige
@@ -0,0 +1,30 @@
+
+ersetzungsanzeige
+-----------------
+
+ KOMMANDO:
+    ersetzungsanzeige <stufe>
+
+ ARGUMENTE:
+
+     <stufe>
+        0, 1 oder 2
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kann man sich die Ersetzungen bei der Benutzung von
+    Befehlsgeschichte und Aliasen anzeigen lassen.
+
+    `ersetzungsanzeige 1' zeigt dabei die Ersetzungen der History an und
+    `ersetzungsanzeige 2' die Ersetzungen von History und Aliasen.
+
+    Mit `ersetzungsanzeige 0' schaltet man die Anzeige wieder ab.
+
+    Dieser Befehl ist hauptsaechlich dann nuetzlich, wenn man sich davon
+    ueberzeugen will, ob eine anscheinend richtige Syntax z.B. von einem
+    laengst vergessenen Alias verhunzt wird.
+
+ SIEHE AUCH:
+    alias, history
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/erwarte b/doc/pcmd/erwarte
new file mode 100644
index 0000000..7a65b96
--- /dev/null
+++ b/doc/pcmd/erwarte
@@ -0,0 +1,52 @@
+KOMMANDO:
+     erwarte [-u|<Spieler>]
+     erwarte [<Spieler>] wegen [<Grund>]
+     erwarte [an|ein|aus]
+
+ARGUMENTE:
+     <Spieler>
+       Hier wird angegeben, welchen Spieler man erwartet.
+     <Grund>
+       (1) Textmeldung, welche beim Einloggen des erwarteten Spielers kommt.
+       (2) Bei Angabe von 'nichts' oder 'loeschen' wird <Grund> geloescht.
+     -u
+       Unter Verwendung dieser Option werden die erwarteten Spielernamen
+       in der chronologischen Reihenfolge ihres Eintrags in der
+       Erwarte-Liste ausgegeben. Ohne diese Option wird die Liste
+       alphabetisch geordnet praesentiert.
+
+BESCHREIBUNG:
+     Die Ankunft und das Weggehen der Spieler, die mit `Erwarte <Name>'
+     markiert wurden, werden mit einer Meldung und einem Piepton
+     bestaetigt.
+     `erwarte' ohne Argument zeigt die Liste der zur Zeit erwarteten
+     Spieler in alphabetischer Reihenfolge an. Die Option '-u' kann die
+     Liste auch in der chronologischen Reihenfolge ihrer Eintraege
+     anzeigen.
+     Ein erneuter Aufruf von `erwarte <Spieler>' entfernt <Spieler>
+     wieder aus der Liste.
+
+     Erwartet man einen Spieler aus einem ganz bestimmten Grund, und
+     moechte man bei dessen Einloggen auch daran erinnert werden, was man
+     von ihm wollte, so ist `erwarte <Spieler> wegen <Grund>' nuetzlich.
+     Beim Einloggen des Spielers <Name> erscheint eine Textmeldung mit
+     Inhalt <Grund>.
+     Mit `erwarte wegen' ist diese spezielle Erwarteliste abfragbar und
+     mit `erwarte <Spieler> wegen', ob und aus welchen Grund man Spieler
+     <Spieler> erwartet. Wird als <Grund> `nichts' oder `loeschen'
+     angegeben, entfernt man den Eintrag wieder.
+     Spieler koennen 10 Textmeldungen setzen, Seher 20, Magier 40 und
+     Erzmagier 80.
+     Mit 'erwarte aus' kann man Erwarte-Meldungen voruebergehend
+     deaktivieren. 'erwarte ein' bzw. 'erwarte an' aktiviert es dann
+     wieder, ohne dass die Liste der Erwarteten verloren geht.
+
+BEMERKUNGEN:
+     Der von 'erwarte' erzeugte Piepton kann sich in gewissen
+     RL-Umgebungen recht stoerend auswirken. Dagegen kann man sich jedoch
+     mittels des Kommandos 'ton AUS' wehren.
+
+SIEHE AUCH:
+     ton, inform
+
+6.Feb 2016 Gloinson
diff --git a/doc/pcmd/erwidere b/doc/pcmd/erwidere
new file mode 100644
index 0000000..14cae37
--- /dev/null
+++ b/doc/pcmd/erwidere
@@ -0,0 +1,28 @@
+
+erwidere
+--------
+
+ KOMMANDO:
+    erwidere <text>
+
+ ARGUMENTE:
+
+     <text>
+        Der zu erwidernde Text
+
+ BESCHREIBUNG:
+    Wenn Dir jemand etwas mitteilt, kannst Du mit diesem Kommando direkt
+    darauf antworten, ohne den Namen des Absenders eingeben zu muessen.
+
+    Aber aufgepasst: Du erwiderst wirklich nur die *letzte* Mitteilung! Wenn
+    Du also den zu erwidernden Text schreibst, und jemand anderes teilt Dir in
+    der Zwischenzeit auch noch etwas mit, so bekommt *er* die Antwort
+    zugeschickt!
+    
+    Der gleiche Effekt kann mit "teile , mit <text>" erzielt werden.
+
+ SIEHE AUCH:
+    teile (mit)
+
+ LETZTE AeNDERUNG:
+    Thu, 08.02.2007, 18:23:00 von Muadib
diff --git a/doc/pcmd/fehler b/doc/pcmd/fehler
new file mode 100644
index 0000000..98a6675
--- /dev/null
+++ b/doc/pcmd/fehler
@@ -0,0 +1,30 @@
+fehler
+------
+
+KOMMANDO:
+    fehler
+
+BESCHREIBUNG:
+    Wer viel programmiert, kann auch viele Fehler machen. Die meisten
+    Probleme werden zwar schon vor dem Anschluss des neuen Gebietes oder
+    Objektes entdeckt, aber einiges bleibt bis zum Anschluss unentdeckt.
+    Manche Idee ist dem Magier auch nicht so klar, wie dem Spieler, der
+    spaeter einmal durchlaeuft.
+
+    Zum Melden dieser Fehler gibt es vier Kommandos, die durch das Kommando
+    'fehler' gelistet werden:
+    * 'bug'    - Meldung eines Fehlers / einer Fehlfunktion
+    * 'typo'   - Meldung eines Tippfehler
+    * 'detail' - Vorschlaege, ein fehlendes Detail zu ergaenzen
+    * 'idee'   - Vorschlaege mit Ideen zur Erweiterung
+
+BEMERKUNG:
+    Frueher hatte dieses Kommando die gleiche Funktionalitaet wie 'bug',
+    zu viele Spieler haben aber all die verschiedenen Fehlerarten nur als
+    'fehler' abgesetzt, daher wurde das geaendert.
+
+SIEHE AUCH:
+    bug, typo, idee, detail
+
+LETZTE AeNDERUNG:
+    12. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/pcmd/finger b/doc/pcmd/finger
new file mode 100644
index 0000000..b5ce936
--- /dev/null
+++ b/doc/pcmd/finger
@@ -0,0 +1,55 @@
+
+finger
+------
+
+ KOMMANDO:
+    finger [-n] [-p] [-s] [-v] [-a] <name> | <name>@<mud>
+
+ ARGUMENTE:
+
+     <name>
+        Name eines Spielers
+     <mud>
+        Name eines MUDs aus der `muds'-Liste
+
+ BESCHREIBUNG:
+    Gibt ein paar zusaetzliche Informationen ueber den Spieler <name> aus.
+    Hierbei ist einerlei, ob der Spieler eingeloggt, netztot oder ausgeloggt
+    ist.
+
+    Seher und Magier koennen sich eine .plan-Datei anlegen, deren Inhalt unter
+    den Spielerinformationen ausgegeben wird. Manchmal moechte man diese
+    jedoch gar nicht sehen. In diesem Fall kann man die Ausgabe des .plan mit
+    `-n' unterdruecken.
+
+    Moechte man die .plan-Datei defaultmaessig unterdruecken, kann man sich
+    ein Alias der Form
+
+    'alias finger finger -n $*'
+
+    erstellen.
+
+    Moechte man dann trotzdem einmal einen .plan sehen, kann man dies mit der
+    Option `-p' bewerkstelligen.
+
+    Mit dem Schalter '-a' kann man sich zusaetzlich zu den anderen Angaben
+    auch die Avatar-URI des Spielers anzeigen lassen (natuerlich nur, sofern
+    er auch eine gesetzt hat).
+
+    Gibt man den Schalter `-s' an, so wird das Verwandtschaftsverhaeltnis des
+    Magiers ausgegeben.
+
+    Im Gegensatz zu Spielern sehen Magier auch, wenn ein Magier zuletzt
+    unsichtbar anwesend war. Um dieses Verhalten zu unterdruecken, ist die
+    Option `-v' vorhanden.
+
+    Ist der Spieler als abwesend gekennzeichnet, zeigt 'finger' die
+    Wegmeldung des Spielers an.
+    Will man nur wissen, ob ein Spieler als abwesend gekennzeichnet ist, 
+    kann man den Befehl 'wegmeldung' benutzen.
+
+ SIEHE AUCH:
+    avatar, email, url, messenger, icq, ort, weg, (wegmeldung)
+
+ LETZTE AeNDERUNG:
+    27.05.2015, Boing
diff --git a/doc/pcmd/fluestere b/doc/pcmd/fluestere
new file mode 100644
index 0000000..7e73e4a
--- /dev/null
+++ b/doc/pcmd/fluestere
@@ -0,0 +1,25 @@
+
+fluestere
+---------
+
+ KOMMANDO:
+    fluestere <wem> zu <text>
+
+ ARGUMENTE:
+
+     <wem>
+        Das Lebwesen, dem Du etwas zufluestern willst
+     <text>
+        Der zu fluesternde Text
+
+ BESCHREIBUNG:
+    Gibt eine Mitteilung an das angegebene Lebewesen (meistens ein Spieler),
+    die niemand anderes hoeren kann. Das Lebewesen muss sich im selben Raum
+    befinden.
+
+ SIEHE AUCH:
+    sage, frage, antworte, teile (mit), gespraech, rufe, ebenen, weg,
+    ignoriere, kobold
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/frage b/doc/pcmd/frage
new file mode 100644
index 0000000..da9681b
--- /dev/null
+++ b/doc/pcmd/frage
@@ -0,0 +1,31 @@
+
+frage
+-----
+
+ KOMMANDO:
+    frage <npc> nach <was>
+    frage <spieler> <was>
+
+ ARGUMENTE:
+
+     <npc>
+        Ein NPC, von dem man etwas wissen will
+     <spieler>
+        Ein Spieler, von dem man etwas wissen will
+     <was>
+        Die Frage an sich
+
+ BESCHREIBUNG:
+    Man befragt ein Monster oder einen Spieler ueber irgendetwas. Nicht alle
+    Monster haben auch Antworten einprogrammiert und bei Spielern kann man
+    erst recht nicht wissen, ob sie antworten.
+
+    Wenn ein NPC auf eine Deiner Meinung nach sinnvolle Frage keine sinnvolle
+    Antwort weiss, kannst Du seinem Programmierer mit dem idee-Befehl einen
+    kleinen Denkanstoss geben.
+
+ SIEHE AUCH:
+    antworte
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/gespraech b/doc/pcmd/gespraech
new file mode 100644
index 0000000..fc877c8
--- /dev/null
+++ b/doc/pcmd/gespraech
@@ -0,0 +1,25 @@
+
+gespraech
+---------
+
+ KOMMANDO:
+    gespraech 
+
+ ARGUMENTE:
+    <-s> (optional, auch: -still, -silent geht)
+
+ BESCHREIBUNG:
+    Alle weiteren Eingaben werden genauso unmittelbar an alle Spieler im
+    selben Raum weitergegeben, als wenn man den sage-Befehl benutzt haette.
+
+    Wird als Argument '-s' (fuer still/silent) angegeben, werden Deine Eingaben
+    nicht in Form von "Du sagst: ..." Dir selber angezeigt.
+
+    Nach Eingabe von "**" koennen wieder beliebige Befehle eingegeben werden.
+
+ SIEHE AUCH:
+    sage, frage, antworte, fluestere, teile (mit), rufe, ebenen, weg,
+    ignoriere, kobold
+
+ LETZTE AeNDERUNG:
+    10.08.2009, Zesstra
diff --git a/doc/pcmd/gib b/doc/pcmd/gib
new file mode 100644
index 0000000..ff8e3f9
--- /dev/null
+++ b/doc/pcmd/gib
@@ -0,0 +1,23 @@
+gib
+---
+
+ KOMMANDO:
+    gib <ziel> <objekt>
+
+ ARGUMENTE:
+
+    <objekt>
+        Der wegzugebende Gegenstand
+    <ziel>
+        Ein Spieler oder NPC im gleichen Raum
+
+ BESCHREIBUNG:
+    Du gibst den Gegenstand <objekt> an den Spieler oder NPC <ziel>. Man
+    sollte sich genau ueberlegen, wem man was gibt, gerade NPCs geben ungern
+    Sachen einfach zurueck.
+
+ SIEHE AUCH:
+    nimm [aus], hole (aus)
+
+ LETZTE AeNDERUNG:
+    14. Okt 2011 Gloinson
diff --git a/doc/pcmd/grafik b/doc/pcmd/grafik
new file mode 100644
index 0000000..305860d
--- /dev/null
+++ b/doc/pcmd/grafik
@@ -0,0 +1,24 @@
+
+grafik
+------
+
+ KOMMANDO:
+     grafik [ein|aus]
+
+ BESCHREIBUNG:
+     Mit "grafik aus" kannst du die Anzeige von ASCII-Grafiken fuer
+     Dich unterdruecken. Nach dem Befehl "grafik ein" werden Dir solche
+     Grafiken wieder angezeigt.
+     Rufst Du den Befehl ohne Parameter auf, dann wird Dir angezeigt,
+     ob Du Grafiken sehen moechtest oder nicht.
+
+     *** ACHTUNG ***
+     Dieser Befehl wurde am 18. Oktober 2005 eingefuehrt. Daher
+     ist davon auszugehen, dass die Einstellung erst nach und nach
+     an den jeweiligen Stellen im MorgenGrauen beruecksichtigt wird.
+     Wenn Dir eine solche Stelle auffaellt, wo es noch nicht 
+     beruecksichtigt wird, dann schreibe doch bitte eine E-Mail an
+     Zook, Ennox oder Bugfix
+     
+ LETZE AENDERUNG:
+     2009-09-10 von Zook
diff --git a/doc/pcmd/hilfe b/doc/pcmd/hilfe
new file mode 100644
index 0000000..fffbffb
--- /dev/null
+++ b/doc/pcmd/hilfe
@@ -0,0 +1,79 @@
+
+hilfe
+-----
+
+ KOMMANDO:
+    hilfe [[gilde <gildenname>] <thema>]
+
+ ARGUMENTE:
+
+     <thema>
+        Das Thema oder Kommando, zu dem Du eine Hilfe haben moechtest
+     <gildenname>
+        Name einer Gilde (fuer gildenspezifische Seiten)
+
+ BESCHREIBUNG:
+    Gibt Hilfsseiten ueber die Befehle und einige allgemeine Themen aus. Ohne
+    <thema> wird eine Seite mit den Themen gezeigt, zu denen es Hilfsseiten
+    gibt.
+
+    Bei Hilfen zu Zauberspruechen gibt es eine Besonderheit zu beachten:
+    Einige Gilden haben Zaubersprueche mit gleichen Namen, aber etwas
+    unterschiedlicher Wirkung, unterschiedlichen Kosten oder Lernbedingungen.
+    Deshalb kann man noch angeben, von welcher Gilde man die entsprechende
+    Hilfeseite haben moechte. Standardmaessig lassen sich nur die Seiten der
+    Gilde erreichen, in der man gerade Mitglied ist.
+
+    Es gibt (noch?) nicht von allen Gilden Hilfeseiten zu den einzelnen
+    Spruechen und Faehigkeiten. Momentan sind dies nur die Abenteurer,
+    Bierschuettler, Karateka und Kleriker. Es wird jedoch auch auf den
+    jeweiligen Gildenhilfeseiten noch darauf hingewiesen.
+
+ SCHREIBWEISEN:
+    Viele Kommandos verstehen mehrere unterschiedliche Aufrufe. Ausserdem sind
+    manche Bestandteile der Eingabezeile fest vorgegeben, andere dagegen
+    variabel. Um nicht jeden moeglichen Aufruf in eine eigene Zeile packen zu
+    muessen, gibt es folgende Konventionen in der Schreibweise der
+    KOMMANDO-Zeile:
+
+     fest
+        Feste Bestandteile, die auch genau so eingegeben werden.
+     <variabel>
+        Variable Bestandteile. Sie geben an, was genau der Befehl bewirken
+        soll.
+     [ Optionen ]
+        Teile in eckigen Klammern sind optional.
+     Alter | Nativen
+        Alternative Formulierungen werden durch einen senkrechten Strich
+        voneinander getrennt.
+
+    Als Beispiel mag die Kommandozeile der `hilfe'-Befehls selbst herhalten:
+    hilfe [[gilde <gildenname>] <thema>]
+
+    Aufgedroeselt wuerde das so aussehen:
+
+     hilfe
+     hilfe <thema>
+     hilfe gilde <gildenname> <thema>
+
+    Die aeusseren eckigen Klammern zeigen an, dass saemtliche Parameter
+    optional sind und weggelassen werden koennen. Dies entspricht dem oberen
+    Aufruf.
+
+    Die inneren eckigen Klammern zeigen an, dass auch der Gildenteil
+    weggelassen werden kann. Man erhaelt dann eine Hilfe zu allgemeinen Themen
+    (der mittlere Aufruf). Das <thema> selbst ist dabei variabel.
+
+    Die dritte Zeile schliesslich besteht aus dem festen Bestandteil "gilde"
+    sowie den Variablen <gildenname> und <thema>.
+
+    Anstelle der doppelten eckigen Klammern haette man das Ganze auch als
+    Alternative formulieren koennen:
+
+    hilfe [<thema> | gilde <gildenname> <thema>]
+
+ SIEHE AUCH:
+    gilden
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/history b/doc/pcmd/history
new file mode 100644
index 0000000..7574363
--- /dev/null
+++ b/doc/pcmd/history
@@ -0,0 +1,75 @@
+
+history
+-------
+
+ KOMMANDO:
+    history (oder: hist)
+    &<nr>
+    &<text>
+    histlen <n>
+    histmin <n>
+    ^<falsch>^<richtig>^
+
+ ARGUMENTE:
+
+     <nr>
+        Die Nummer eines Befehls in der History
+     <text>
+        Der Anfang eines Befehls in der History
+     <n>
+        Eine Zahl
+     <falsch>
+        Fehlerhafter Text
+     <richtig>
+        Korrigierter Text
+
+ BESCHREIBUNG:
+    Die letzten Befehle, die Du eingegeben hast, werden gespeichert. Auf diese
+    gespeicherten Befehle kannst Du zugreifen, ohne sie komplett neu eingeben
+    zu muessen:
+
+    `&<nr>' fuehrt den Befehl mit Nummer <nr> aus, soweit er sich noch in der
+    Befehlsgeschichte befindet. Man kann jedoch auch negative Nummern
+    verwenden: `&-0' fuehrt den letzten Befehl nochmal aus, `&-1' den
+    vorletzten, und so weiter.
+
+    `&<text>' fuehrt den letzten Befehl aus, der mit <text> anfaengt (sofern
+    vorhanden).
+
+    Wird eine identische Befehlszeile mehrfach hintereinander angegeben, so
+    erscheint sie nur nur ein einziges Mal in der Befehlsgeschichte (auch,
+    wenn die Wiederholungen ueber `&-0' erfolgten).
+
+    Die komplette Befehlsgeschichte kannst Du Dir mit `history' (oder
+    abgekuerzt `hist') anzeigen lassen. Der `history'-Befehl selbst erscheint
+    jedoch nicht in der Geschichte.
+
+    Die Laenge der Befehlsgeschichte betraegt standardmaessig 40 Befehle, dies
+    kann man aber mit dem Befehl `histlen <n>' aendern. Die voreingestellten
+    40 Befehle bilden allerdings das Maximum, welches nicht ueberschritten
+    werden kann.
+
+    Normalerweise landet *jeder* Befehl in der Befehlsgeschichte. Will man
+    aber z.B. die Bewegungsbefehle nicht in der History haben, so kann man mit
+    `histmin <n>' festlegen, ab welcher Laenge die Befehle aufgenommen werden.
+    Mit `histmin 4' werden also nur Befehlszeilen mit mindestens vier
+    Buchstaben Laenge aufgenommen. Dies stellt uebrigens eine sinnvolle
+    Groesse dar, da bei kuerzeren Zeilen die Eingabe des &-Kommandos mehr
+    Aufwand darstellt als die Neueingabe des Befehls.
+
+    Tippfehler im letzten eingegebenen Befehl lassen sich wie folgt
+    korrigieren: `^<falsch>^<richtig>^'. Das letzte ^ kann man auch weglassen.
+    Zum Beispiel:
+
+    > tm jpf Hi!
+    Kein solcher Spieler!
+    > ^jpf^jof
+    Du teilst Jof mit: Hi!
+
+    Hier haette uebrigens auch `^p^o' genuegt.
+
+ SIEHE AUCH:
+    ersetzungsanzeige, alias
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/hole b/doc/pcmd/hole
new file mode 100644
index 0000000..5b55e5d
--- /dev/null
+++ b/doc/pcmd/hole
@@ -0,0 +1,23 @@
+
+hole (aus)
+----------
+
+ KOMMANDO:
+    hole <objekt> aus <behaelter>
+
+ ARGUMENTE:
+
+     <objekt>
+        Der gewuenschte Gegenstand
+     <behaelter>
+        Ein Behaelter
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kannst Du Gegenstaende aus Behaeltern nehmen.
+    Allerdings muss der Behaelter dazu geoeffnet sein.
+
+ SIEHE AUCH:
+    stecke, nimm [aus]
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/icq b/doc/pcmd/icq
new file mode 100644
index 0000000..f28b0e4
--- /dev/null
+++ b/doc/pcmd/icq
@@ -0,0 +1,21 @@
+
+icq
+---
+
+ KOMMANDO:
+    icq [<nummer>]
+
+ ARGUMENTE:
+
+     <nummer> (optional)
+        Die neue Nummer
+
+ BESCHREIBUNG:
+    Wenn Du eine ICQ-Nummer hast kannst Du sie mit diesem
+    Kommando eintragen.
+    Ohne <nummer> wird die aktuelle Nummer angezeigt, ist sie 'keine',
+    so wird die Nummer geloescht.
+
+ SIEHE AUCH:
+    Persoenliche Details: email, url, messenger, ort
+    Sonstiges:            finger
diff --git a/doc/pcmd/idee b/doc/pcmd/idee
new file mode 100644
index 0000000..41342c6
--- /dev/null
+++ b/doc/pcmd/idee
@@ -0,0 +1,45 @@
+idee
+----
+
+KOMMANDO:
+    idee <text>
+    idee <objekt>:<text>
+
+ARGUMENTE:
+
+    <text>
+        Eine Mitteilung
+    <objekt>
+        Ein Referenzobjekt, das neben Dir liegt oder in Deinem Inventar ist
+
+BESCHREIBUNG:
+    Speichert eine Mitteilung ueber eine Idee, wie man das Spiel verbessern
+    oder verschoenern kann. Beispiele waeren weitere Details in Raeumen oder
+    an Objekten; Vorschlaege zur Verbesserung der Syntax an bestimmten
+    Stellen; Ideen, wie man das Ambiente eines Raumes noch verbessern kann.
+    Die Magier werden versuchen, alle Mitteilungen in die Tat umzusetzen,
+    soweit sie ihnen sinnvoll erscheinen :)
+
+    Wenn Du einen Tippfehler gefunden hast, so kannst Du den Verantwortlichen
+    mit diesem Befehl davon unterrichten.
+    Alle Vorschlaege sind *herzlich willkommen*; zoegere also nicht, wenn Du
+    eine gute Idee hast!
+
+    Wenn Du eine Idee fuer ein bestimmten Objekt oder NPC hast, kannst Du
+    dieses/diesen hinter einem Doppelpunkt angeben, damit der fuer das Objekt
+    verantwortliche Magier die Meldung bekommt.
+    Wenn das Objekt nicht zu finden ist, wird die ganze Eingabe als
+    Meldung aufgefasst.
+
+BEMERKUNG:
+    Der Befehl 'idee' bezieht sich bei Nichtangabe eines Bezugsobjektes
+    auf das letzte betrachtete Objekt. Hast Du also ein Objekt untersucht,
+    dann wird die Meldung fuer diese Objekt abgegeben. Hast Du aber den
+    Raum untersucht oder 'schau' eingegeben, wird die Meldung fuer Deinen
+    momentanen Raum abgesetzt.
+
+SIEHE AUCH:
+    bug, typo, detail, bezugsobjekt
+
+LETZTE AeNDERUNG:
+    12. Okt 2011 Gloinson
diff --git a/doc/pcmd/idlezeit b/doc/pcmd/idlezeit
new file mode 100644
index 0000000..9a459ec
--- /dev/null
+++ b/doc/pcmd/idlezeit
@@ -0,0 +1,19 @@
+
+idlezeit
+--------
+
+ KOMMANDO:
+    idlezeit <name>
+
+ ARGUMENTE:
+
+     <name>
+        Name eines Spielers
+
+ BESCHREIBUNG:
+    Dieser Befehl gibt die Zeit aus, die ein Spieler passiv ist.
+    Dann muss man nicht jedes mal den Spieler fingern, wenn man wissen
+    will, ob er gerade ansprechbar ist oder nicht.
+
+ LETZTE AeNDERUNG:
+    Mit, 25. Feb 2004, 12:46:00 von Rikus
diff --git a/doc/pcmd/ignoriere b/doc/pcmd/ignoriere
new file mode 100644
index 0000000..87e9b27
--- /dev/null
+++ b/doc/pcmd/ignoriere
@@ -0,0 +1,134 @@
+
+ignoriere
+---------
+
+ KOMMANDO:
+    ignoriere <spieler> | <spieler>.<aktion> | .<aktion>
+    ignoriere <spieler>@<mud> | <spieler>@ | @<mud>
+    ignoriere <spieler>.<aktion>.<einschraenkung>
+    ignoriere
+
+ ARGUMENTE:
+
+     <aktion>
+        Die zu ignorierende Aktion (Kommando)
+     <spieler>
+        Name des zu ignorierenden Spielers
+     <mud>
+        Name eines MUDs
+     <einschraenkung>
+        Dies kann die ignorierte Aktion nochmal einschraenken (s.u.)
+
+ BESCHREIBUNG:
+    Wenn Dir jemand maechtig auf die Nerven geht oder Dir einige Aktionen
+    nicht in den Kram passen, kannst Du Dich mit diesem Kommando vor den
+    Auswirkungen schuetzen.
+
+    Folgende Moeglichkeiten bestehen:
+
+     'ignoriere <spieler>'
+        Saemtliche Meldungen, die der Spieler <spieler> erzeugt, werden
+        unterdrueckt. Dies ist eine sehr drastische Massnahme!
+
+     'ignoriere .<aktion>'
+        Alle Meldungen, die <aktion> erzeugt, werden unterdrueckt. Es wird
+        meistens jedoch auf die genaue Schreibweise geachtet (Ausnahmen s.u.);
+        wenn man also niemals geweckt werden will, muss man sowohl `.wecke'
+        als auch `.weck' ignorieren!
+
+     'ignoriere <spieler>.<aktion>'
+        Eine Kombination der obigen Moeglichkeiten: Die Aktion <aktion>
+        wird nur dann ignoriert, wenn sie vom Spieler <spieler> kommt. Andere
+        Meldungen von <spieler> werden jedoch weiterhin akzeptiert.
+
+     'ignoriere <spieler>.ebenen.<ebene>'
+     'ignoriere <spieler>.ebenen'
+        So kann man die Aeusserungen eines Spielers auf einer bestimmten Ebene
+        oder auf allen Ebenen ignorieren, ohne ihn gleich komplett zu
+        ignorieren.
+        Ein Beispiel waere 'ignoriere tilly.ebenen.allgemein'. Damit bekommt
+        man nur die Aeusserungen auf der Ebene <Allgemein> nicht mit, alle
+        anderen schon.
+        BTW: das funktioniert zur Zeit nicht fuer Spieler aus anderen Muds.
+     
+     'ignoriere <spieler>.mail'
+        Ignoriert Post (mudinterne Mail), die von <spieler> abgesandt wurde.
+
+     'ignoriere <spieler>.news'
+        Ignoriert MPA-Artikel von <spieler> bei nn. (Nicht bei gezieltem Lesen
+        von Artikeln.)
+
+     'ignoriere <spieler>@<mud>'
+        Alle Mitteilungen des Spielers <spieler> aus dem Mud <mud> werden
+        abgeblockt.
+
+     'ignoriere <spieler>@'
+        Die Mitteilungen von allen Spielern namens <spieler> in anderen Muds
+        werden abgeblockt. Dies ist eine sehr drastische Massnahme, die man
+        sich gut ueberlegen sollte. Schliesslich koennen sich hinter dem
+        gleichen Namen in unterschiedlichen Muds auch unterschiedliche Leute
+        verbergen!
+
+     'ignoriere @<mud>'
+        Es werden saemtliche Mitteilungen aus dem Mud <mud> ignoriert. Auch
+        dies ist eine recht drastische Massnahme!
+
+     'ignoriere'
+        Die Liste der ignorierten Aktionen und Spieler wird angezeigt.
+
+    Folgende Aktionen gibt es, welche auch andere Schreibweisen umfassen:
+      sage (sage, sag, '), emote (emotes, remotes), rufe (rufe, ruf),
+      teilemit (teile-mits), ... (Liste noch unvollstaendig)
+
+    Will man einen Eintrag wieder entfernen, muss man einfach noch einmal das
+    entsprechende `ignoriere'-Kommando eingeben.
+
+    Neben Kommunikationskommandos von Spieler zu Spieler lassen sich auch noch
+    folgende Dinge abwehren (allen diesen Faellen laesst sich ein Spielername
+    voranstellen, wenn man das nur bei einem bestimmten Spieler ignorieren
+    will):
+
+     Spendieren in der Kneipe
+
+         * .spendiere
+         * .spendiere.getraenke
+         * .spendiere.alkohol
+         * .spendiere.essen
+
+     Gefunden werden durch andere Spieler
+     
+         Hiermit wird verhindert, dass fremde Spieler den eigenen
+         Aufenthaltsort ermitteln koennen (noch nicht vollstaendig
+         implementiert).
+         * .finde (schliesst alle nachfolgenden ein)
+         * .finde.glaswuerfel
+         * .finde.feldstecher
+
+     Verschiedenes
+
+         * .shout
+           Die Aktion 'shout' ist nicht das gleiche wie 'rufe', sondern
+           umfasst Meldungen aus den Regionen, wie die Ankunft der Hydra oder
+           das Loesen bestimmter Quests.
+         * .maus.<verb>
+         * .knuddelmaus.<verb>
+           Diese beiden ignorieren die Diddlmaus.
+
+     Meldungen aus den Arenen
+
+         * .arena (alle u.g.)
+         * .arena.seherwettbewerb (Seherwettbewerb Wuestenarena)
+         * .arena.gladiator (Herausforderung Gladiatoren)
+         * .arena.duell (Duellaufforderungen der Wuestenarena)
+         * .arena.fegefeuer (Duellankuendigungen Fegefeuer)
+         * .arena.fegefeuerscroll (Kampfscroll Fefefeuer)
+         * .arena.fegefeuerduell (Duellaufforderungen Fegefeuer)
+         * .arena.schlachtfeld (Schlachtfeld im verl. Land)
+
+ SIEHE AUCH:
+    sage, frage, antworte, fluestere, teile (mit), gespraech, rufe, ebenen,
+    weg, kobold
+
+ LETZTE AENDERUNG:
+    02.10.2013, Zesstra
+
diff --git a/doc/pcmd/info b/doc/pcmd/info
new file mode 100644
index 0000000..c65ac6b
--- /dev/null
+++ b/doc/pcmd/info
@@ -0,0 +1,33 @@
+
+info
+----
+
+ KOMMANDO:
+    info
+    punkte
+
+ BESCHREIBUNG:
+    Diese Kommandos geben die wichtigsten Daten ueber Deinen Charakter aus.
+    Dazu gehoeren:
+
+     * Dein voller Name mit Presay und Titel,
+     * Deine Rasse,
+     * Deine Charaktereinstellung,
+     * koerperliche Attribute wie Geschlecht, Groesse und Gewicht,
+     * Deine Spielerstufe,
+     * die Gilde, der Du angehoerst, und die Stufe dort,
+     * Erfahrungs- und Abenteuerpunkte,
+     * Deine Attribute,
+     * Deine koerperliche und geistige Verfassung,
+     * ggf. Vorsichtsmodus und Fluchtrichtung,
+     * der Grad Deiner Kenntnis des MorgenGrauen,
+     * ggf. Vergiftungsgrad, Abwesenheit und Feinde sowie
+     * Dein Alter.
+
+    `info' zeigt alle diese Daten an, waehrend `punkte' nur die wichtigsten
+    Daten anzeigt.
+
+ SIEHE AUCH:
+    kurzinfo
+
+12. Mar 2006 Gloinson
diff --git a/doc/pcmd/inform b/doc/pcmd/inform
new file mode 100644
index 0000000..b7c08d0
--- /dev/null
+++ b/doc/pcmd/inform
@@ -0,0 +1,29 @@
+
+inform
+------
+
+ KOMMANDO:
+    inform [<zustand>]
+
+ ARGUMENTE:
+
+     <zustand>
+        `ein' oder `aus'
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kannst Du den Informationsmodus ein- oder ausschalten.
+    Hast Du den Informationsmodus eingeschaltet, so wirst Du immer ueber das
+    Ein- und Ausloggen von Spielern informiert.
+
+    `inform' ohne Parameter zeigt Dir den aktuellen Zustand des
+    Informationsmodus an.
+
+ BEMERKUNGEN:
+    Wenn Du nur ueber das Ein- und Ausloggen bestimmter Spieler informiert
+    werden willst, solltest Du den `erwarte'-Befehl benutzen.
+
+ SIEHE AUCH:
+    erwarte
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/inventur b/doc/pcmd/inventur
new file mode 100644
index 0000000..d91138d
--- /dev/null
+++ b/doc/pcmd/inventur
@@ -0,0 +1,49 @@
+
+inventur
+--------
+
+ KOMMANDO:
+    i [<flags>]
+    inv [<flags>]
+    inventur [<flags>]
+
+ ARGUMENTE:
+
+     <flags>
+        Flags, um die Anzeige zu konfigurieren
+
+ BESCHREIBUNG:
+    Es wird eine kurze Beschreibung aller Objekte ausgegeben, die Du bei Dir
+    traegst. Normalerweise werden alle Objekte angezeigt und nach Waffen,
+    Ruestungen und Verschiedenes sortiert. Dies kann man allerdings mit den
+    <flags> aendern:
+
+     -1  Einspaltige Ausgabe
+     +a  Nur Autoloader anzeigen
+     -a  Keine Autoloader anzeigen
+     +b  Nur Objekte zeigen, die man bei "verkaufe alles" behaelt
+     -b  Kein Objekt zeigen, das man bei "verkaufe alles" behaelt
+     -f  Inventar nicht unterteilen oder gleiche Objekte zusammenfassen
+     +r  Nur Ruestungen anzeigen
+     -r  Keine Ruestungen anzeigen
+     -s  Ausgabe alphabetisch sortieren
+     +v  Alles zeigen, was nicht Ruestung oder Waffe ist
+     -v  Alles zeigen, was Ruestung oder Waffe ist
+     +w  Nur Waffen anzeigen
+     -w  Keine Waffen anzeigen
+
+    Die Argumente sind auch kombinierbar.
+
+    Bei den Flags +/-a und +/-b ist folgendes zu beachten: Kombiniert man sie
+    mit den anderen Flags, so findet eine logische UND-Verkuepfung statt. Mit
+
+    inv +r +a
+
+    werden also nicht alle Ruestungen sowie alle Autoloader angezeigt, sondern
+    nur alle Autoload-Ruestungen.
+
+ SIEHE AUCH:
+    behalte, ausruestung
+
+ LETZTE AeNDERUNG:
+    Tue, 27.02.2001, 17:25:00 von Tiamak
diff --git a/doc/pcmd/kkwer b/doc/pcmd/kkwer
new file mode 100644
index 0000000..23bbd70
--- /dev/null
+++ b/doc/pcmd/kkwer
@@ -0,0 +1,19 @@
+
+kkwer
+-----
+
+ KOMMANDO:
+    kkwer
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Es wird eine alphabetisch sortierte Liste mit den Namen aller momentan im
+    MorgenGrauen eingeloggten Spieler ausgegeben.
+
+ SIEHE AUCH:
+    wer, kwer
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/klettere b/doc/pcmd/klettere
new file mode 100644
index 0000000..67d06a5
--- /dev/null
+++ b/doc/pcmd/klettere
@@ -0,0 +1,29 @@
+
+klettere
+--------
+
+ KOMMANDO:
+    klettere hoch | runter
+    klettere aus | auf | ueber | in | aus <objekt>
+
+ ARGUMENTE:
+
+     <objekt>
+        Ein Gegenstand
+
+ BESCHREIBUNG:
+    Das ist der Standardbefehl, um ein Hindernis zu ueberwinden. Manchmal
+    reichen aber auch die normalen Richtungsbefehle aus. Manche Hindernisse
+    stellen ein Raetsel dar, das mit raffinierteren Methoden ueberwunden
+    werden will.
+
+ BEMERKUNG:
+    Wenn irgendwo noch der Befehl `klettere' in anderer Syntax benoetigt wird,
+    bitte eine `fehler'-Meldung hinterlassen, damit die Magier es etwas
+    leichter haben, die Befehle zu vereinheitlichen.
+
+ SIEHE AUCH:
+    bewegung, fehler
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/klingelton b/doc/pcmd/klingelton
new file mode 100644
index 0000000..f855d2e
--- /dev/null
+++ b/doc/pcmd/klingelton
@@ -0,0 +1,23 @@
+KOMMANDO:
+	klingelton aus
+        klingelton 1..3600 
+
+ARGUMENTE:
+                  : aktuellen Status anzeigen  
+	  1..3600 : Klingelton maximal aller n Sekunden 
+	  AUS     : Klingelton ausschalten.
+
+BESCHREIBUNG:
+        Um Mitteilungen im Scroll nicht zu verpassen, wird bei eingeschaltetem
+        Klingelton in den voreingestellten Zeitintervallen ein Tonsignal vom
+        Mud erzeugt. Das ist besonders fuer blinde Spieler von Vorteil, denen
+        sonst Mitteilungen schnell mal verloren gehen.
+        Der Ton wird nur produziert, wenn man mit 'ton ein' die Tonausgabe
+        des Muds aktiviert hat.
+        Mitteilungen sind in diesem Zusammenhang 'sag' und 'teile mit'.
+ 
+SIEHE AUCH:
+	teile mit, sag, klingelton, grafik aus, ton, keepalive
+
+LETZTE AENDERUNG:
+   16. Mai 2007  Ennox
diff --git a/doc/pcmd/kobold b/doc/pcmd/kobold
new file mode 100644
index 0000000..0971658
--- /dev/null
+++ b/doc/pcmd/kobold
@@ -0,0 +1,51 @@
+
+kobold
+------
+
+ KOMMANDO:
+    kobold [<schalter>]
+
+ ARGUMENTE:
+
+     <schalter> (optional)
+        `ein' oder `aus'
+
+ BESCHREIBUNG:
+    Der Kobold hat mehrere Funktionen, die mit dem Speichern von Mitteilungen
+    beim Bearbeiten oder Lesen eines Textes oder anderere Aktionen in
+    Zusammenhang stehen.
+
+    Mit `kobold ein' schaltet man den Kobold so ein, dass er sich jede
+    Mitteilung merkt, die waehrend einer der oben genannten Aktionen an einen
+    gesendet wurde. Wenn man damit fertig ist, kann dann mittels `kobold',
+    ohne Argumente, abgerufen werden, was er sich gemerkt hat. Das sollte aber
+    im Normalfall nicht noetig sein, da sich der Kobold automatisch meldet.
+
+    Jeder gespeicherten Meldung ist die Uhrzeit des Empfangs angehaengt.
+
+    Wuenscht man keine solche Ruhemassnahme, kann man den Kobold mit `kobold
+    aus' wieder abschalten und jede Mitteilung, Rufe und andere Meldungen
+    werden immer sofort weitergeleitet.
+
+    Standardmaessig ist der Kobold ausgeschaltet.
+
+    Der Kobold kann sich max. 255 Mitteilungen merken, sind diese
+    ueberschritten, gehen neuere Mitteilungen verloren!
+
+    Abgeblockt werden folgende Meldungen:
+    mrufe, Ebenen, Mitteilungen (erzaehle, teile mit)
+
+    Nicht abgeblockt werden folgende Meldungen:
+    sage, jegliche lokalen Emotionen sowie sonstige lokale (also im selben
+    Raum) erzeugte Meldungen, rufe, ...
+
+    *Merke*: Der Kobold funktioniert nur, wenn man einen Text liest und more
+    benutzt wird oder wenn man einen Text editiert (z.B. beim Postschreiben,
+    Artikelschreiben).
+
+ SIEHE AUCH:
+    rufe, teile (mit), weg, ebenen
+
+ LETZTE AeNDERUNG:
+    05.10.2013, Zesstra
+
diff --git a/doc/pcmd/kurz b/doc/pcmd/kurz
new file mode 100644
index 0000000..be1d907
--- /dev/null
+++ b/doc/pcmd/kurz
@@ -0,0 +1,20 @@
+
+kurz
+----
+
+ KOMMANDO:
+    kurz
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Schaltet auf den "Kurz"-Modus um. Wenn Du Dich im Kurzmodus befindest,
+    siehst Du nur eine kurze Beschreibung aller Raeume. Fuer eine laengere
+    Beschreibung kannst Du das Kommando `schau' benutzen.
+
+ SIEHE AUCH:
+    lang, ultrakurz, schau, ausgaenge
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/kurzinfo b/doc/pcmd/kurzinfo
new file mode 100644
index 0000000..af1fe68
--- /dev/null
+++ b/doc/pcmd/kurzinfo
@@ -0,0 +1,17 @@
+
+kurzinfo
+--------
+
+ KOMMANDO:
+    kurzinfo
+    kurzinfo -k
+
+ BESCHREIBUNG:
+    Dieses Kommando gibt Deine aktuellen Lebens- und Konzentrationspunkte aus.
+    'kurzinfo -k' gibt eine verkuerzte Angabe ohne ASCII-Graphik aus, genauso 
+    als haettest Du deren Ausgabe mit 'grafik aus' abgeschaltet.
+
+ SIEHE AUCH:
+    info 		
+
+ 09.08.2009, Zesstra
diff --git a/doc/pcmd/kwer b/doc/pcmd/kwer
new file mode 100644
index 0000000..7af9e0b
--- /dev/null
+++ b/doc/pcmd/kwer
@@ -0,0 +1,90 @@
+
+kwer
+----
+
+ KOMMANDO:
+    kwer [[alle] [in <stadt>] [region <region>] [bei <spieler>] [spieler]
+         [seher] [magier] [erzmagier] [goetter] [mensch] [zwerg] [elf]
+         [feline] [hobbit] [regionsmitarbeiter|mitarbeiter <region>]
+         [regionsmagier <region>] [testies] [zweities] [magierzweities]
+         [erwartete] [gilde <gilde>] [gildenmagier <gilde>]
+	 [frosch] [idle] [idlezeit <min>] [icq] [cicerone]
+         [www|url] [ssl|stunnel] [und|oder|ausser] ...]
+
+ ARGUMENTE:
+
+     <stadt>
+        Name der gewuenschten Stadt (Herkunft des Login)
+     <region>
+        Name der gewuenschten Region (in Morgengrauen)
+     <spieler>
+        Name eines Spielers
+     <gilde>
+        Name einer Gilde
+
+ BESCHREIBUNG:
+    Es wird eine kurze Liste aller in MorgenGrauen anwesenden Spieler
+    ausgegeben, dabei werden erwartete Spieler mit einem vorgestellten
+    "*" markiert.
+    Bei aktiviertem ANSI sind Magier unterstrichen, erwartete Spieler
+    in rot und Froesche in gruen angezeigt.
+    
+
+    Die Buchstaben am Ende bedeuten:
+
+     [s]   Spieler
+     [S]   Seher
+
+     [z]   Zweitspieler
+     [Z]   Zweitspieler mit Seherlevel
+     [n]   unsichtbar markierter Zweitspieler
+     [N]   unsichtbar markierter Zweitspieler mit Seherlevel
+
+     [t]   Testspieler
+     [T]   Testspieler mit Seherlevel
+
+     [L]   Magierlehrling
+     [m]   Vollmagier, ohne Region
+     [M]   Vollmagier, mit Region
+     [H]   Hilfsmagier
+     [R]   Regionschef
+     [W]   Weiser
+     [E]   Erzmagier
+     [G]   Gott
+
+    Die Informationen [n] und [N] sowie die Liste der SSL-Nutzer bekommen 
+    nur Magier. Die direkte Abfrage der Magierzweities steht nur 
+    Erzmagiern zur Verfuegung.
+
+    Die Idle-Zeit ist an einem Buchstaben vor dem Level zu erkennen:
+   
+     [i]   > 2 Minuten
+     [I]   > 10 Minuten
+     [j]   > 30 Minuten
+     [J]   > 120 Minuten
+   
+    "Idle" bedeutet, laenger keine Taste zu betaetigen.
+
+     [w]   Der Spieler hat eine WEG-Meldung gesetzt.
+
+    Direkt vor der Idlezeit ist zu erkennen, ob der Spieler den
+    Hardcoremodus spielt:
+     [c]   Der Spieler spielt Hardcore und ist noch am Leben.
+     [+]   Der Spieler spielt Hardcore und ist bereits verstorben.
+
+    Man kann die Ausgabe auf gewisse Gruppen einschraenken, diese Gruppen
+    koennen mit `und', `oder' und `ausser' verknuepft werden. Dies geschieht
+    mit Linksklammerung (also `a oder b und c' wird als `(a oder b) und c'
+    interpretiert).
+
+ BEISPIELE:
+
+    > kwer alle ausser goetter
+    > kwer in muenster oder in koeln und seher
+
+ SIEHE AUCH:
+    wer, kkwer, ort
+
+ LETZTE AeNDERUNG:
+    2015-12-02, Arathorn
+
diff --git a/doc/pcmd/lang b/doc/pcmd/lang
new file mode 100644
index 0000000..b75deba
--- /dev/null
+++ b/doc/pcmd/lang
@@ -0,0 +1,19 @@
+
+lang
+----
+
+ KOMMANDO:
+    lang
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Schaltet auf den "Lang"-Modus um. Im Langmodus siehst Du die komplette
+    Beschreibung der Raeume, die Du betrittst.
+
+ SIEHE AUCH:
+    kurz, ultrakurz, schau, ausgaenge
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/lausche b/doc/pcmd/lausche
new file mode 100644
index 0000000..dcde75e
--- /dev/null
+++ b/doc/pcmd/lausche
@@ -0,0 +1,32 @@
+
+lausch(e) (an)
+--------------
+
+KOMMANDO
+	lausch(e)
+	lausch(e) <was> [an <objekt> | am <objekt>] [in mir | im raum]
+
+ARGUMENTE
+	<objekt>
+	  Ein Gegenstand bzw. Lebewesen, an dem lauschen will.
+
+BESCHREIBUNG
+	`lausch' bzw. `lausche' ist das allgemeine Kommando, um Geraeusche
+	an Gegenstaenden, Lebewesen oder in Raeumen wahrzunehmen. Hierbei
+	laesst `lausch(e)' ohne Argumente den Spieler die Hauptgeraeusche in
+	dem Raum wahrnehmen, in dem er sich derzeit befindet. An allen
+	anderen Gegenstaenden bzw. Lebewesen im selben Raum oder im eigenen
+	Inventar kann man mit `lausch(e) (an)' ebenfalls Geraeusche
+	wahrnehmen. Nicht immer kann man jedoch etwas Besonderes hoeren.
+
+	Da bei Objekten mit gleichen Geraeuscharten zuerst an im Raum
+	liegenden Objekt gelauscht wird, kann man an Sachen, die man bei
+	sich traegt, auf alle Faelle mit dem Zusatz `in mir' lauschen.
+
+SIEHE AUCH:
+  bezugspunkt
+  schau, rieche, taste, lies
+
+LETZTE AENDERUNGEN:
+  18.01.2013, Zesstra
+
diff --git a/doc/pcmd/lies b/doc/pcmd/lies
new file mode 100644
index 0000000..9045beb
--- /dev/null
+++ b/doc/pcmd/lies
@@ -0,0 +1,51 @@
+
+lies
+----
+
+KOMMANDO
+	lies <was> [an <objekt> | am <objekt>] [in mir | im raum]
+
+ARGUMENTE
+  <was>
+    Name eines Gegenstandes, Lebewesens oder Detail, welches man lesen will.
+	<objekt>
+	  Ein Gegenstand oder ein Lebewesen, an dem man lesen will.
+
+BESCHREIBUNG
+  'lies' ist das allgemeine Kommando, um lesbare Details an Gegenstaenden,
+  Lebewesen oder in Raeumen (z.B. ein Schild an einem Rucksack) oder an sich
+  lesbare Gegenstaende (z.B. eine Schriftrolle) wahrzunehmen.
+
+  Da bei Objekten mit gleichen lesbaren Details zuerst die im Raum liegenden
+  Objekte gelesen werden, kann man an Sachen, die man bei sich traegt, auf
+  alle Faelle mit dem Zusatz `in mir' riechen.
+
+  Das Kommando benutzt ggf. das aus dem Kommando 'schau' bzw. 'untersuche'
+  bekannte Bezugsobjekt.
+
+BEISPIELE:
+  > lies tafel
+
+  > lies tafel in raum
+
+  > lies widmung an buchstuetzen in mir
+  
+  > lies schild an biene in raum
+
+  > lies buch in paket
+
+  > unt paket
+  > lies index an buch
+  (Liegt ein Buch mit lesbarem Detail "index" im Paket, liest man diesen mit
+   dem zweiten Kommando.)
+
+  > lies index an buch in paket in raum
+  (Liest den Index eines Buches in einem Paket im Raum.)
+
+SIEHE AUCH:
+  bezugspunkt
+  schau, rieche, lausche, taste
+
+LETZTE AENDERUNGEN:
+  18.01.2013, Zesstra
+
diff --git a/doc/pcmd/messenger b/doc/pcmd/messenger
new file mode 100644
index 0000000..79138ef
--- /dev/null
+++ b/doc/pcmd/messenger
@@ -0,0 +1,37 @@
+
+messenger
+---------
+
+ KOMMANDO:
+    messenger [<id>]
+
+ ARGUMENTE:
+
+     <id> (optional)
+        Die neue Messenger-ID
+
+ BESCHREIBUNG:
+    Wenn Du einen Messenger-Dienst benutzt, so kannst Du dort
+    Deine ID eintragen. Es wird einfach der Text gespeichert, den
+    Du uebergibst und dann beim finger-Befehl angezeigt. Du solltest
+    also mit hinzuschreiben, um welchen Dienst es sich handelt. 
+
+    Wird kein Parameter uebergeben, so wird der aktuelle Eintrag
+    angezeigt. Gibst Du "keine" oder "loeschen" an, wird der
+    Eintrag geloescht.
+
+    Hinweis zum Zusammenspiel mit dem Befehl ICQ. Hast Du zugleich
+    auch eine ICQ-Nummer gesetzt, so wird diese automatisch im
+    Finger-Befehl mit angegeben. 
+
+ BEISPIELE:
+
+    messenger ICQ: 1234   
+    messenger MSN: foo@bar.com
+
+ SIEHE AUCH:
+    Persoenliche Details: email, url, icq, ort
+    Sonstiges:            finger
+
+ LETZTE AENDERUNG:
+    2006-01-05 von Zook.
diff --git a/doc/pcmd/mrufe b/doc/pcmd/mrufe
new file mode 100644
index 0000000..3b164ce
--- /dev/null
+++ b/doc/pcmd/mrufe
@@ -0,0 +1,37 @@
+
+mrufe
+-----
+
+ KOMMANDO:
+    mrufe <text>
+
+ ARGUMENTE:
+
+     <text>
+        Der Text, der an die Magier gerufen wird
+
+ BESCHREIBUNG:
+    Die Meldung <text> wird an alle eingeloggten Magier ausgegeben.
+
+    Dieser Befehl darf nur in NOTFAELLEN verwendet werden!!!
+
+    Notfaelle sind z.B. fehlerhafte Raeume, aus denen man nicht mehr
+    herauskommt, o.ae. (*aber*: nicht jeder Raum ohne sichtbare Ausgaenge ist
+    fehlerhaft!) Man sollte sich erst vergewissern, ob man wirklich
+    feststeckt.
+
+    Kein Notfall ist z.B. ein mrufe, wenn man einen Brief an einen Magier
+    zustellen will.
+    Missbraeuchliche Benutzung dieses Befehls sorgt dafuer, dass sich die
+    Magier auch in wirklichen Notlagen nicht mehr um das ge`mrufe' kuemmern,
+    sondern sich koestlich ueber die Spieler amuesieren. Es liegt also bei
+    euch, wie ernst ihr genommen werden moechtet.
+
+    Magier sollten lieber die Magierebene verwenden (-Magier+).
+
+ SIEHE AUCH:
+    teile (mit), ebenen
+
+ LETZTE AeNDERUNG:
+ 16.09.2008, Zesstra
+
diff --git a/doc/pcmd/muds b/doc/pcmd/muds
new file mode 100644
index 0000000..f9aa67e
--- /dev/null
+++ b/doc/pcmd/muds
@@ -0,0 +1,20 @@
+
+muds
+----
+
+ KOMMANDO:
+    muds
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Gibt eine Liste der MUDs aus, mit denen Du von hier aus Kontakt aufnehmen
+    kannst. Dazu gehoeren z.B. die Abfrage der Anwesenheitsliste, das
+    Versenden von Mitteilungen oder die Information ueber Spieler.
+
+ SIEHE AUCH:
+    wer, teile (mit), finger
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/nimm b/doc/pcmd/nimm
new file mode 100644
index 0000000..039f0a5
--- /dev/null
+++ b/doc/pcmd/nimm
@@ -0,0 +1,34 @@
+
+nimm [aus]
+----------
+
+ KOMMANDO:
+    nimm <objekt> [aus <behaelter>]
+    nimm alles [aus <behaelter>]
+
+ ARGUMENTE:
+
+     <objekt>
+        Der zu nehmende Gegenstand
+     <behaelter> (optional)
+        Der Behaelter, in dem sich das Objekt der Begierde befindet
+
+ BESCHREIBUNG:
+    Man nimmt den Gegenstand <objekt> vom Boden auf oder aus einem <behaelter>
+    heraus.
+
+    Waehlt man als <objekt> `alles', so nimmt man alles, was sich nehmen
+    laesst (soweit man es noch tragen kann).
+
+    Mit 'nimm behaltenes' kann man alle Gegenstaende, die man frueher
+    einmal "behalten" (s. 'behalte') hat, aus dem aktuellen Raum aufnehmen.
+    Steht man in einem Raum, wo man gestorben ist und liegt dort der eigene
+    Kram in Form eines "Haufen Krempels", kann man mittels 'nimm eigenes'
+    alles aus diesem (und nur diesem) Haufen aufnehmen. Dieses schliesst
+    uebrigens 'nimm behaltenes' ein.
+
+ SIEHE AUCH:
+    stecke (in), hole (aus), wirf (weg), behalte
+
+ LETZTE AeNDERUNG:
+    24.05.2007, Zesstra
diff --git a/doc/pcmd/ort b/doc/pcmd/ort
new file mode 100644
index 0000000..472003b
--- /dev/null
+++ b/doc/pcmd/ort
@@ -0,0 +1,27 @@
+
+ort
+---
+
+ KOMMANDO:
+    ort [<name>|loeschen]
+
+ ARGUMENTE:
+
+     <name> (optional)
+        Der neue Ortsname
+     loeschen (optional)
+        Loescht den gesetzten Ortsnamen wieder
+
+ BESCHREIBUNG:
+     Wenn Du aus einem Ort kommst, der nicht automatisch erkannt
+     werden kann, kannst Du mit diesem Befehl eintragen, von
+     woher Du WIRKLICH kommst.
+     Die Angabe wird lediglich als zusaetzliche Information beim
+     "finger"-Befehl angezeigt sowie wahlweise bei "wer".
+     Falls Du z.B. aus Frankfurt eingeloggt bist und als Ort Muenchen
+     angibst, wirst Du sowohl bei "kwer in frankfurt" als auch bei
+     "kwer in muenchen" gefunden.
+     
+ SIEHE AUCH:
+    Persoenliche Details: email, url, icq, messenger
+    Sonstiges:            finger, wer, kwer
diff --git a/doc/pcmd/passwort b/doc/pcmd/passwort
new file mode 100644
index 0000000..191b5b2
--- /dev/null
+++ b/doc/pcmd/passwort
@@ -0,0 +1,20 @@
+
+passwort
+--------
+
+ KOMMANDO:
+    passwort
+    password
+    passwd
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Aendert das Passwort. Zur Sicherheit muss zuerst das alte Passwort
+    eingegeben werden. Daraufhin wird das neue Passwort zweimal erfragt. Das
+    Passwort wird nur dann geaendert, wenn die beiden Eingaben des neues
+    Passwortes uebereinstimmen.
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/reise b/doc/pcmd/reise
new file mode 100644
index 0000000..6e461a3
--- /dev/null
+++ b/doc/pcmd/reise
@@ -0,0 +1,103 @@
+KOMMANDO:
+        reise
+        reise route
+        reise [mit transportmittel] nach|zu|zum|zur|ins|ans (zielort)
+        reise aus|nicht
+
+ARGUMENTE:
+        <transportmittel>       Ein Transportmittel Deiner Wahl
+        <zielort>               Dein Reiseziel
+
+FUNKTION:
+       Wenn Du Dein Reiseziel (oder das Verkehrsmittel) bereits
+       kennst, kannst Du mit diesem Befehl Deine Reise einfacher
+       gestalten.
+       
+       Benutzt Du den reise-Befehl, so wirst Du automatisch ein
+       Transportmittel betreten (falls dies moeglich ist) und es
+       am Zielort (falls angegeben) auch wieder verlassen.
+
+       Folgende Argumente / Funktionen werden unterstuetzt:
+
+reise 
+       Deine aktuelle Reiseroute wird ausgegeben. Du kannst sie mit
+       o.g. Argumenten immer wieder aendern.
+
+reise route:
+       Damit kannst Du feststellen, welche Verkehrsmittel verkehren 
+       und welche Routen sie anbieten.
+
+reise mit <xxx> nach|zu|zum|zur|ins|ans <zzz>:
+       Die wohl genaueste Moeglichkeit, eine Reiseroute festzulegen.
+
+       xxx steht hier fuer eine eindeutige Kennzeichnung des Transport-
+       mittels (z.B. 'piratenschiff' statt 'schiff').
+
+       zzz benennt den genauen Zielort (z.B. 'sonneninsel' statt 'insel').
+
+       Passen mehrere Transporter (oder Zielorte) auf die von Dir 
+       angebenen Namen, so wird der naechstmoegliche Transporter und
+       das naechstgelegene Ziel ausgewaehlt.
+
+       Die Bezeichnung fuer <zzz> reagiert teilweise nicht auf unter-
+       schiedliche Schreibweisen. Am besten, Du nimmst immer die, die 
+       auch bei 'reise route' angegeben wird.
+
+reise mit <xxx>:
+       Hier legst Du nur fest, WOMIT Du fahren willst. Du faehrst solange
+       mit xxx, bis Du den Transporter eigenhaendig verlaesst, oder einen 
+       Zielort mittels 'reise nach zzz' angibst.
+
+reise nach <zzz>:
+       Hier legst Du nur fest, WOHIN Du fahren willst. Das Transportmittel
+       wird automatisch ermittelt, wobei anwesende Transporter natuerlich
+       bevorzugt werden.
+
+       Da <zzz> nicht immer auf unterschiedliche Schreibweisen reagiert, 
+       nimmst Du am besten die Bezeichnung, die auch bei 'reise route'
+       angegeben wird.
+
+reise aus|nicht:
+       Mit diesem Befehl loeschst Du Deine Reiseroute. Du musst das
+       gewuenschte Transportmittel dann wieder per Hand betreten und 
+       verlassen.
+
+BEMERKUNGEN:
+       Eine festgelegte Reiseroute ist nur dort wirksam, wo Du sie 
+       festgelegt hast. Nach erfolgreicher Reise wird sie automatisch 
+       geloescht, ansonsten bleibt sie bis zum expliziten Loeschen 
+       bestehen.
+
+       Nicht jedes Transportmittel / Ziel kann mittels 'reise' ausge-
+       waehlt werden. Es besteht keinerlei Anspruch darauf, das 'reise'
+       ueberall zu funktionieren hat.
+
+BEISPIELE:
+       reise ins verlorene land
+       
+       reise ans ende der welt
+       reise zum ende der welt
+       
+       reise nach port vain
+  
+       Einige Zielorte sind auch per Kuerzel zu erreichen:
+       - Verlorenes Land: vland
+       - Werwolfinsel: wwi
+       - Port Vain: pv
+       - Akhar Nth'tar: ti
+       - Insel am Ende der Welt: edw, iaedw, weltende
+       - Feuerinsel: fi
+       - Magieinsel: minsel
+       - Insel der Toten: idt, toteninsel
+
+       Generell sollten die Namen als Reiseziele verwendet werden, die
+       auch bei 'reise route' angezeigt werden. Gleiches gilt natuerlich
+       auch fuer die Namen der Transporter. So ist eine zielgenaue und 
+       perfekte Reise schon vorprogrammiert.
+
+       Mit ein bisschen Geduld und Testen wirst Du sicher schnell raus-
+       bekommen, wie Du welchem Befehl einsetzen musst um an Dein Ziel 
+       zu gelangen.
+     
+LETZTE AENDERUNG:
+       2015-Jan-18, Arathorn 
diff --git a/doc/pcmd/report b/doc/pcmd/report
new file mode 100644
index 0000000..240ddc0
--- /dev/null
+++ b/doc/pcmd/report
@@ -0,0 +1,77 @@
+KOMMANDO:
+        report [ein|aus|vorsicht]
+
+ARGUMENTE:
+        (nichts)      : aktuelle Einstellung anzeigen
+        aus           : alle eingeschalteten Report-Modi ausschalten
+        ein           : Report von LP/KP/Gift einschalten
+        vorsicht      : Vorsicht-Report zusaetzlich einschalten
+                        (nur Seher: Fluchtrichtung wird auch gemeldet)
+        senden        : Report jetzt sofort mit aktuellen Einstellungen
+                        senden
+
+BESCHREIBUNG:
+        Wenn der Report eingeschaltet wird, wird bei Aenderungen an den LP
+        des Spielers eine Meldung an diesen ausgegeben, die den neuen LP-Wert
+        beinhaltet. Falls freigeschaltet (s.u.), gilt das gleiche fuer 
+        Aenderungen an den KP und am Giftstatus. Jede Aenderung an einem 
+        dieser Werte loest die Ausgabe aller drei Werte gemeinsam aus.
+        Ausschalten laesst sich der Report nur komplett mit "report aus".
+
+        Wenn der Vorsicht-Report eingeschaltet ist, wird in einer separaten
+        Zeile zusaetzlich die Vorsicht sowie bei Sehern die Fluchtrichtung
+        gemeldet. Die Ausgabe ist unabhaengig von dem LP/KP/Gift-Report
+        und findet wie bei diesem nur dann statt, wenn eine Aenderung an
+        Vorsicht oder Fluchtrichtung eingetreten ist, dann aber werden beide
+        Werte gemeinsam ausgegeben.
+
+        "report senden" kann zum Testen verwendet werden oder wenn der
+        Client nach dem Verbinden alle Daten einmal braucht. (Nutzt man
+        GMCP, werden die Daten per GMCP gesendet.) 
+
+HINWEISE:
+        - Die Anzeige der LP ist sofort nach Charaktererstellung verfuegbar.
+        - Die Anzeige der KP ist erst nach Abschluss der Quest "Hilf den 
+          Gnarfen" verfuegbar. Solange dies nicht der Fall ist, werden
+          nicht die KP, sondern die Zeichen ### angezeigt.
+        - Die Anzeige des Giftstatus ist erst nach Abschluss der Quest
+          "Katzenjammer" verfuegbar. Solange dies nicht der Fall ist,
+          wird der Giftstatus als "(nicht verfuegbar)" gemeldet.
+        - Die Anzeige der Vorsicht ist erst nach Abschluss der Quest 
+          "Schrat kann nicht einschlafen" verfuegbar. Mit Erreichen des
+          Seher-Status zeigt diese Option zusaetzlich die eingestellte
+          Fluchtrichtung an. Sehern, die diese Quest nicht abgeschlossen
+          haben, steht keines von beiden zur Verfuegung. Spielercharakteren
+          wird die Fluchtrichtung bis zum Erreichen des Seherstatus als
+          "(nicht verfuegbar)" gemeldet.
+        - Nach dem Bestehen einer der genannten Quests muss ein bereits
+          eingeschalteter Report einmal aus- und wieder eingeschaltet
+          werden, um die Aenderung zu aktivieren.
+        - Der Vorsicht-Report laesst sich auch alleine benutzen, jedoch 
+          muessen zuvor alle Reportfunktionen mit "report aus" abgeschaltet
+          werden, um danach den Vorsicht-Report separat einzuschalten.
+
+BEISPIELE:
+        Angenommen, ein Spieler, der zunaechst mit "report ein" den LP-/KP-
+        und Gift-Report eingeschaltet hat und gerade gegen eine gefaehrliche
+        Spinne kaempft, habe bereits einige Treffer erlitten und auch einige
+        KP fuer Zaubersprueche ausgegeben und daher aktuell nur noch
+        154 LP, 187 KP und sei nicht vergiftet. Wird er nun von der Spinne
+        gebissen und vergiftet, wird diese Reportmeldung ausgegeben:
+            LP: 154, KP: 187, Gift: leicht.
+        Wenn die Spinne bei diesem Biss aber gleich auch Schaden verursacht,
+        und der Spieler 6 LP verliert, wuerde sofort ein weiterer Report
+        ausgeloest:
+            LP: 148, KP: 187, Gift: leicht.
+        Wenn der Spieler jedoch nicht gerne questet und ihm daher nur der
+        LP-Report zur Verfuegung steht, wuerde nur eine der beiden Aenderungen
+        gemeldet, naemlich die LP-Aenderung, und somit folgender Report
+        ausgegeben:
+            LP: 148, KP: ###, Gift: (nicht verfuegbar).
+
+SIEHE AUCH:
+        vorsicht, fluchtrichtung, leben, heilung, kampf
+
+LETZTE AENDERUNG:
+   09.01.2015, Zesstra
+
diff --git a/doc/pcmd/rfluestere b/doc/pcmd/rfluestere
new file mode 100644
index 0000000..e8247a8
--- /dev/null
+++ b/doc/pcmd/rfluestere
@@ -0,0 +1,27 @@
+
+rfluestere
+---------
+
+ KOMMANDO:
+    rfluestere <wem> zu <text>
+
+ ARGUMENTE:
+
+     <wem>
+        Das Lebwesen, dem Du aus der Ferne etwas zufluestern willst
+     <text>
+        Der zu fluesternde Text
+
+ BESCHREIBUNG:
+    Gibt eine Mitteilung an das angegebene Lebewesen aus, die niemand anderes
+    hoeren kann. Das Lebewesen muss sich in einem anderen Raum befinden.
+    Dieser Befehl ist fast aehnlich zum 'teile (mit)'-Befehl, allerdings kann
+    letzterer in einer TM-History beim Sender und/oder Empfaenger gespeichert
+    werden, waehrend dies bei 'rfluestere' nicht passieren kann.
+
+ SIEHE AUCH:
+    sage, frage, antworte, teile (mit), gespraech, rufe, ebenen, weg,
+    ignoriere, kobold, tmhist
+
+ LETZTE AeNDERUNG:
+    10.08.2008, Zesstra
diff --git a/doc/pcmd/rieche b/doc/pcmd/rieche
new file mode 100644
index 0000000..60c4a82
--- /dev/null
+++ b/doc/pcmd/rieche
@@ -0,0 +1,32 @@
+
+riech(e) (an)
+--------------
+
+KOMMANDO
+	riech(e)
+	riech(e) <was> [an <objekt> | am <objekt>] [in mir | im raum]
+
+ARGUMENTE
+	<objekt>
+	  Ein Gegenstand bzw. Lebewesen, an dem riechen will.
+
+BESCHREIBUNG
+	`riech' bzw. `rieche' ist das allgemeine Kommando, um Gerueche
+	an Gegenstaenden, Lebewesen oder in Raeumen wahrzunehmen. Hierbei
+	laesst `riech(e)' ohne Argumente den Spieler die Hauptgerueche in
+	dem Raum wahrnehmen, in dem er sich derzeit befindet. An allen
+	anderen Gegenstaenden bzw. Lebewesen im selben Raum oder im eigenen
+	Inventar kann man mit `riech(e) (an)' ebenfalls Gerueche
+	wahrnehmen. Nicht immer kann man jedoch etwas Besonderes riechen.
+
+	Da bei Objekten mit gleichen Geruchsarten zuerst an im Raum
+	liegenden Objekt gerochen wird, kann man an Sachen, die man bei
+	sich traegt, auf alle Faelle mit dem Zusatz `in mir' riechen.
+
+SIEHE AUCH:
+  bezugspunkt
+  schau, lausche, taste, lies
+
+LETZTE AENDERUNGEN:
+  18.01.2013, Zesstra
+
diff --git a/doc/pcmd/rknuddle b/doc/pcmd/rknuddle
new file mode 100644
index 0000000..046aee8
--- /dev/null
+++ b/doc/pcmd/rknuddle
@@ -0,0 +1,21 @@
+
+rknuddle
+--------
+
+ KOMMANDO:
+    rknuddle <name>
+
+ ARGUMENTE:
+
+     <name>
+        Ein Spieler, der nicht im gleichen Raum ist
+
+ BESCHREIBUNG:
+    Du knuddelst einen [bestimmten] Spieler, der sich nicht im gleichen Raum
+    befindet, in dem Du Dich aufhaeltst.
+
+ SIEHE AUCH:
+    verben, rwinke
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/rufe b/doc/pcmd/rufe
new file mode 100644
index 0000000..a5c1217
--- /dev/null
+++ b/doc/pcmd/rufe
@@ -0,0 +1,27 @@
+
+rufe
+----
+
+ KOMMANDO:
+    rufe <text>
+
+ ARGUMENTE:
+
+     <text>
+        Der zu rufende Text
+
+ BESCHREIBUNG:
+    Du rufst so laut <text>, dass man Dich im ganzen MorgenGrauen hoeren kann.
+    Da das MorgenGrauen allerdings ziemlich gross ist, verbraucht ein Ruf ein
+    gewisses Mass an geistiger Energie (sprich: Magiepunkten).
+
+    Rufe werden im allgemeinen als stoerend empfunden; man sollte lieber die
+    Ebenen benutzen. Diese sind nach Themen eingeteilt, und ihre Nutzung ist
+    kostenlos.
+
+ SIEHE AUCH:
+    sage, frage, antworte, fluestere, teile (mit), gespraech, ebenen, mrufe,
+    weg, ignoriere, kobold
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/rwinke b/doc/pcmd/rwinke
new file mode 100644
index 0000000..ea9bf33
--- /dev/null
+++ b/doc/pcmd/rwinke
@@ -0,0 +1,21 @@
+
+rwinke
+------
+
+ KOMMANDO:
+    rwinke <name>
+
+ ARGUMENTE:
+
+     <name>
+        Ein Spieler, der nicht im gleichen Raum ist
+
+ BESCHREIBUNG:
+    Du winkst einem [bestimmten] Spieler zu, der sich nicht im gleichen Raum
+    befindet, in dem Du Dich aufhaeltst.
+
+ SIEHE AUCH:
+    verben, rknuddle
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/sage b/doc/pcmd/sage
new file mode 100644
index 0000000..e81779e
--- /dev/null
+++ b/doc/pcmd/sage
@@ -0,0 +1,23 @@
+
+sage
+----
+
+ KOMMANDO:
+    sage <text>
+
+ ARGUMENTE:
+
+     <text>
+        Was man so zu sagen hat
+
+ BESCHREIBUNG:
+    Der Text <text> wird an alle Spieler im selben Raum ausgegeben. Ueberlange
+    Zeilen werden umgebrochen, und vor jede Zeile wird noch
+    `<Dein_Name> sagt: ' gesetzt.
+
+ SIEHE AUCH:
+    frage, antworte, fluestere, teile (mit), gespraech, rufe, ebenen, weg,
+    ignoriere, kobold, klingelton, senderwiederholung
+
+ LETZTE AeNDERUNG:
+    01.07.2007 von Ennox
diff --git a/doc/pcmd/schau b/doc/pcmd/schau
new file mode 100644
index 0000000..a7a6f6d
--- /dev/null
+++ b/doc/pcmd/schau
@@ -0,0 +1,72 @@
+
+schau (an)
+----------
+
+ KOMMANDO:
+    schau
+    schau -f | genau
+    schau -k | kurz
+    schau [-f|genau] <was> [an <objekt> | am <objekt>] [in mir | im raum] an
+    untersuche <was> [an <objekt> | am <objekt>] [in mir | im raum]
+
+ ARGUMENTE:
+
+     <was>
+        Ein Gegenstand oder Detail
+     <objekt>
+        Ein weiterer Gegenstand (kein Detail)
+
+ BESCHREIBUNG:
+    (Statt `untersuche' kann man auch `unt', `betrachte' oder `betr'
+    verwenden.)
+
+    `schau' ist das allgemeine Kommando, um Gegenstaende und Raeume zu
+    untersuchen. `schau' ohne Argumente gibt eine Beschreibung des Raumes, in
+    dem der Spieler sich befindet. Alle anderen Gegenstaende, Monster und
+    Spieler im selben Raum oder im eigenen Inventar koennen mit `schau (an)'
+    untersucht werden.
+
+    `schau' muss aber nicht unbedingt alle Geheimnisse des Gegenstandes
+    verraten.
+
+    `unt[ersuche]' bzw. `betr[achte]' macht genau dasselbe, ist aber manchen
+    vielleicht lieber.
+
+    Da bei Objekten mit gleicher Benennung zuerst das im Raum Liegende
+    untersucht wird, kann man Sachen, die man bei sich traegt, auf alle Faelle
+    mit dem Zusatz `in mir' untersuchen.
+
+    Betrachtet man ein <objekt> im Raum, so wird es als neuer Bezugspunkt fuer
+    weitere Betrachtungen genommen. D.h. man kann als naechstes ein Detail an
+    dem Objekt betrachten, ohne eingeben zu muessen `unt <detail> an
+    <objekt>', sondern es reicht dann `unt <detail>'. Wird das Detail an dem
+    eben betrachteten Objekt nicht gefunden, so wird der Bezugspunkt wieder
+    auf die Umgebung und die Objekte im Spieler gesetzt.
+    
+    Die Option '-f' bzw. 'genau' sorgt dafuer, dass gleichartige Objekte
+    bei der Langbeschreibung des Raumes oder der Betrachtung eines Behaelters
+    nicht zusammengefasst werden. 
+    Das kann nuetzlich sein, wenn verschiedene Objekte mit gleicher
+    Bezeichnung (beispielsweise verschiedene Schwerter) im Raum liegen
+    und man wissen will, welches davon man mit 'nimm schwert 2' nun
+    wirklich nimmt.
+    
+    'schau -k' oder 'schau kurz' geben die Kurzbeschreibung der aktuellen
+    Umgebung aus, wie sie auch bei Bewegungen im Kurz-Modus erscheint.
+
+    'schau' ohne ein Argument loescht das sog. Bezugsobjekt.
+
+ ACHTUNG:
+    Manche Raeume definieren ihr eigenes Verb: `untersuche'. Hier koennen
+    `unt' und `untersuche' zu *verschiedenen* Ergebnissen fuehren. Sollte euch
+    das auffallen, setzt bitte mit "fehler" einen Fehler in diesem Raum / an
+    dem Objekt ab.
+
+ SIEHE AUCH:
+    bezugspunkt
+    rieche, lausche, taste, lies
+    kurz, ausgaenge
+
+ LETZTE AeNDERUNG:
+   20.02.2013, Zesstra
+
diff --git a/doc/pcmd/schlafe b/doc/pcmd/schlafe
new file mode 100644
index 0000000..c55c63c
--- /dev/null
+++ b/doc/pcmd/schlafe
@@ -0,0 +1,37 @@
+
+schlafe ein
+-----------
+
+ KOMMANDO:
+    schlafe ein
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Unterbricht die Verbindung zum Spiel. Alle Gegenstaende, die man bei der
+    Eingabe des Kommandos bei sich hat, behaelt man. Beim Neu-Einloggen kommt
+    man normalerweise an der gleichen Stelle heraus, an der man das Spiel
+    verlassen hat. Von dieser Regel kann es aber auch Ausnahmen geben, von
+    denen die wichtigste die Seherhaeuser sind: schlaeft man in einem
+    Seherhaus ein, wacht man vor dem Haus wieder auf (Ausnahme von der
+    Ausnahme: der Hausbesitzer selbst ist davon nicht betroffen).
+    Grund fuer diese Massnahme ist, dass Spieler so nicht beabsichtigt
+    oder unbeabsichtigt im Seherhaus eingeschlossen werden koennen.
+
+    ACHTUNG: Falls das Spiel abstuerzt oder neu gestartet wird, verliert man
+    alle seine Gegenstaende und startet beim Einloggen wieder an seinem
+    lokalen Startpunkt!
+    (In der Regel gibt es dann aber eine (kleine) Entschaedigung fuer die
+    verlorenen Gegenstaende (ohne Gewaehr). )
+
+    ACHTUNG: Abenteuer koennen unter Umstaenden nach dem Wiederaufwachen nicht
+    mehr weitergespielt werden.
+
+                           BENUTZUNG AUF EIGENE GEFAHR!
+
+ SIEHE AUCH:
+    speichern, ende, keepalive
+
+ LETZTE AeNDERUNG:
+    Sat, 04.01.2003, 14:45:00 von Wargon
diff --git a/doc/pcmd/selbstloeschung b/doc/pcmd/selbstloeschung
new file mode 100644
index 0000000..6832023
--- /dev/null
+++ b/doc/pcmd/selbstloeschung
@@ -0,0 +1,25 @@
+KOMMANDO:
+	Selbstloeschung
+
+ARGUMENTE:
+	keine
+
+BESCHREIBUNG:
+	Der Charakter wird unwiderruflich aus dem Spiel entfernt. Auch evtl.
+	noch vorhandene Briefe werden entfernt.
+	Wenn man Seher oder Magier ist, wird der Name des Charakters
+	zusaetzlich gebanisht, damit sich nicht aus Versehen ein Neuling mit
+	einem beruehmten oder aber auch beruechtigten Namen einloggt, was
+	sicher zu einiger Verwirrung fuehren wuerde.
+	Will man nur auf absehbare (oder auch unabsehbare) Zeit nicht mehr 
+	spielen, so sollte man besser den Befehl 'Spielpause' benutzen.
+
+	Als letzten Vorschlag: Wenn Du Dich zu diesem Schritt entschlossen hast,
+	ueberlege Dir, ob Du den Mitspielern, die Du kennst, nicht noch eine
+	Mitteilung schicken magst, sie koennten sich sonst Sorgen machen. 
+
+SIEHE AUCH:
+	spieldauer, spielpause, loeschskript
+
+----------------------------------------------------------------------------
+Letzte Aenderung: 14.02.2007 von Zesstra
diff --git a/doc/pcmd/senderwiederholung b/doc/pcmd/senderwiederholung
new file mode 100644
index 0000000..0addfa9
--- /dev/null
+++ b/doc/pcmd/senderwiederholung
@@ -0,0 +1,32 @@
+KOMMANDO:
+	senderwiederholung [<Status>]
+
+ARGUMENTE:
+	<Status>
+             : aktuellen Status anzeigen  
+	  EIN: Senderwiederholung einschalten.
+	  AUS: Senderwiederholung ausschalten.
+
+BESCHREIBUNG:
+        Bei der Kommunikation per teile mit und sag wird der Sender vor dem
+        mitgeteilten Text dargestellt. Bisher erfolgte das vor jeder Zeile.
+        Mit 'senderwiederholung aus' wird der Sender nur noch einmal darge-
+        stellt. Entweder am Anfang der Zeile, wenn es nur eine Zeile ins-
+        gesamt ist. Oder vor dem Text, wenn es mehrere Zeilen sind.
+
+BEISPIEL:
+         'senderwiederholung ein' (standard)
+         Ennox teilt Dir mit: das ist ein
+         Ennox teilt Dir mit: laengerer Beispieltext
+         Ennox teilt Dir mit: fuer 'senderwiederholung'
+
+         'senderwiederholung aus'
+         Ennox teilt Dir mit: 
+          das ist ein laengerer Beispieltext 
+          fuer 'senderwiederholung'
+
+SIEHE AUCH:
+	teile mit, sage, klingelton, grafik aus, ebenen
+
+LETZTE AENDERUNG:
+   16. Mai 2007  Ennox
diff --git a/doc/pcmd/sonnenfehler b/doc/pcmd/sonnenfehler
new file mode 100644
index 0000000..ddd4cba
--- /dev/null
+++ b/doc/pcmd/sonnenfehler
@@ -0,0 +1,25 @@
+sonnenfehler
+------------
+
+KOMMANDO:
+     sonnenfehler <text>
+   
+ARGUMENTE:
+     <text>
+        Eine Mitteilung
+
+BESCHREIBUNG:
+     Wenn du als Dunkelelf meinst, dass die Sonne in dem (Innen)raum,
+     in dem du dich gerade befindest nicht angebracht ist, dann setz
+     doch bitte eine kurze Meldung ab.
+
+     Diese Fehler werden ausserhalb der Region gesammelt und bearbeitet,
+     eine sehr lange Abwesenheit des RMs sollte dich also nicht hindern
+     den Fehler zu melden.
+
+SIEHE AUCH:
+     typo, idee, detail, fehler
+
+LETZTE AeNDERUNG:
+     26. Sep 2010, Gloinson
+
diff --git a/doc/pcmd/speichern b/doc/pcmd/speichern
new file mode 100644
index 0000000..e131bfe
--- /dev/null
+++ b/doc/pcmd/speichern
@@ -0,0 +1,23 @@
+
+speichern
+---------
+
+ KOMMANDO:
+    speichern
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Sichere alle Daten, die Deinen Charakter betreffen. Dieses Kommando wird
+    beim Ausloggen und regelmaessig automatisch durchgefuehrt. Eigentlich ist
+    dieses Kommando nur fuer besonders aengstliche Spieler, allerdings kann es
+    bei einem Absturz des Spiels auch sehr sinnvoll sein.
+
+    Eine Restaurierung findet nur statt, wenn Du Dich ins Spiel einloggst.
+
+ SIEHE AUCH:
+    ende, schlafe (ein)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/spieldauer b/doc/pcmd/spieldauer
new file mode 100644
index 0000000..026875b
--- /dev/null
+++ b/doc/pcmd/spieldauer
@@ -0,0 +1,32 @@
+KOMMANDO:
+	Spieldauer <Dauer> Minute[n] fuer <Anzahl> Tag[e]
+	Spieldauer <Dauer> Stunde[n] fuer <Anzahl> Tag[e]
+
+ARGUMENTE:
+	<Dauer>
+	  Dauer der Spielzeit pro Tag in Minuten oder Stunden
+	<Anzahl>
+	  Dauer der Spielzeitbeschraenkung in Tagen
+
+BESCHREIBUNG:
+	Wenn man unbedingt einmal eine Mudpause einlegen muesste, weil man
+	sich um RL-Dinge wie Klausuren, Diplomarbeiten und aehnliche
+	Nebensaechlichkeiten zu kuemmern hat, und wenn man genau weiss, dass
+	man sich aus eigenem Willen nicht vom Einloggen fernhalten kann, so
+	kann man sich mit 'Spielpause' eine Zwangspause genehmigen.
+	Weniger drastisch wirkt der Befehl 'spieldauer'. Hiermit schraenkt
+	man die pro Tag zur Verfuegung stehende Zeit im MUD ein. Somit kann
+	man jeden Tag noch schnell seine Mails lesen oder kurz Freunde
+	begruessen. Ist die angegebene Zeit um, so wird man automatisch aus
+	dem MUD geworfen und kann sich erst am naechsten Tag wieder
+	einloggen. Gibt man als Anzahl der Tage 0 ein, so wird die
+	Beschraenkung abgeschaltet. Da man damit die Beschraenkung jederzeit
+	wieder aufheben kann, gehoert also trotzdem viel Disziplin dazu,
+	diese einzuhalten. Der anfangs erwaehnte Befehl 'Spielpause' ist
+	also deutlich wirkungsvoller.
+
+SIEHE AUCH:
+	Spielpause, Selbstloeschung
+
+----------------------------------------------------------------------------
+15.11.2015, Zesstra
diff --git a/doc/pcmd/spielpause b/doc/pcmd/spielpause
new file mode 100644
index 0000000..7a3f1aa
--- /dev/null
+++ b/doc/pcmd/spielpause
@@ -0,0 +1,34 @@
+KOMMANDO:
+	Spielpause <Anzahl> Tag[e]
+	Spielpause bis <Datum>
+
+ARGUMENTE:
+	<Anzahl>
+	  Dauer der Spielpause in Tagen
+	<Datum>
+	  Datum, bis zu dem die Spielpause gelten soll.
+	  Im Format tt.mm.[jj]
+
+BESCHREIBUNG:
+	Wenn man unbedingt einmal eine Mudpause einlegen muesste, weil man
+	sich um RL-Dinge wie Klausuren, Diplomarbeiten und aehnliche
+	Nebensaechlichkeiten zu kuemmern hat, und wenn man genau weiss, dass
+	man sich aus eigenem Willen nicht vom Einloggen fernhalten kann, so
+	kann man sich mit diesem Befehl eine Zwangspause genehmigen.
+	Der Tag, an dem man sich zur Spielpause entschliesst, wird in die
+	Laenge der Pause mit eingeschlossen. Mit `Spielpause 1 Tag' kann man
+	sich also am naechsten Tag wieder einloggen.
+	Wenn man nicht weiss, wie lang die Spielpause sein soll, kann man
+	als Anzahl -1 angeben. Um sich wieder einloggen zu koennen, muss man
+	dann allerdings einem Gott oder Erzmagier Bescheid sagen (mit Hilfe
+	eines Gastes. ;)
+	Die Spielpause tritt mit dem naechsten Ausloggen in Kraft. Dabei ist
+	es egal, ob man sich mit 'Ende' oder 'Schlafe ein' ausloggt.
+	Entscheidet man sich, doch keine Pause antreten zu wollen, so kann
+	man die Aktion mit 'Spielpause 0 Tage' wieder rueckgaengig machen.
+
+SIEHE AUCH:
+	spieldauer, selbstloeschung, loeschskript
+
+----------------------------------------------------------------------------
+Last modified: Mon Okt 16 20:32:44 2000 by Silvana
diff --git a/doc/pcmd/spotte b/doc/pcmd/spotte
new file mode 100644
index 0000000..e70a1cd
--- /dev/null
+++ b/doc/pcmd/spotte
@@ -0,0 +1,20 @@
+spotte
+------
+
+ KOMMANDO:
+    spotte <text>
+    spotte :<emote>
+
+ ARGUMENTE:
+    <text>
+        Was man so ueber seine Opfer laestern moechte.
+
+ BESCHREIBUNG:
+    Mit dem Kommando "spotte" kann man auf dem Moerder-Kanal seine Gefuehle
+    zum gerade erlegten Monster ausdruecken. Das klappt natuerlich nur bei
+    selbst erlegten Monstern und auch nur als direkte Antwort auf die letzten
+    Worte des NPCs.
+
+ SIEHE AUCH:
+    ebenen, toete
+
diff --git a/doc/pcmd/spruchermuedung b/doc/pcmd/spruchermuedung
new file mode 100644
index 0000000..004def3
--- /dev/null
+++ b/doc/pcmd/spruchermuedung
@@ -0,0 +1,44 @@
+
+spruchermuedung
+--------
+
+KOMMANDO:
+    spruchermuedung <alt | neu | normal>
+
+ARGUMENT:
+    alt:    schaltet die ungenauere alte Spruchermuedung ein
+
+    neu:
+    normal: schaltet die neue (normale) Spruchermuedung ein
+
+BESCHREIBUNG:
+    Zaubersprueche (im weitesten Sinne, also auch z.B. wunder bei Klerikern
+    und Sonderangriffe bei Kaempfern erzwingen in der Regel eine kurze
+    (Ermuedungs-)Pause, bis man den naechsten Spruch sprechen kann.
+    Diese Pausen waren auch technischen Gruenden frueher immer Vielfache von
+    2s und kuerzere Pausen gab es nicht. Ausserdem begannen diese Pausen immer
+    zum Beginn einer Kampfrunde.
+    Seit einiger Zeit sind diese Pausen grundsaetzlich sekundengenau. Einige
+    Spieler finden dies jedoch zu ungewohnt. Diese koennen mit diesem Befehl
+    einen alternativen Modus fuer die Spruchermuedung einschalten, welcher das
+    alte Verhalten weitgehend wiederherstellt.
+
+    Aber: benutzt man die alte Spruchermuedung, werden alle Ermuedungspausen
+          auf Vielfache von 2s aufgerundet, d.h. sie werden ggf. laenger. Dies
+          gilt auch fuer etwaige Mali (z.B. wird aus einem Malus von 1s u.U.
+          ein Malus von 2s) und etwaige Boni sind oft unwirksam, weil sie auf
+          Vielfache von 2s abgerundet werden (z.B. -1s auf 0).
+          Ausserdem sind Sprueche auf Grundlage der sekundengenauen
+          Ermuedungspausen berechnet/balanciert.
+
+BEMERKUNGEN:
+    Kann nicht im Kampf oder vor Ablauf von 3min nach einem Kampf geaendert
+    werden.
+
+BEISPIELE:
+    spruchermuedung alt -> Ermuedungspausen werden 2s aufgerundet
+    spruchermuedung neu -> sekundengenaue Ermuedungspausen
+
+LETZTE AeNDERUNG:
+2010-03-02, Zesstra
+
diff --git a/doc/pcmd/stecke b/doc/pcmd/stecke
new file mode 100644
index 0000000..d2a0ca1
--- /dev/null
+++ b/doc/pcmd/stecke
@@ -0,0 +1,31 @@
+
+stecke
+------
+
+ KOMMANDO:
+    stecke <objekt> in <behaelter>
+    stecke <waffe> weg/zurueck
+
+ ARGUMENTE:
+
+     <objekt>
+        Ein beliebiges Objekt in Deiner Reichweite
+     <behaelter>
+        Ein Behaelter
+     <waffe>
+        Die Waffe, die Du gezueckt hast
+
+ BESCHREIBUNG:
+    `stecke (in)' ist das allgemeine Kommando, um Gegenstaende in einem
+    Behaelter zu deponieren. Behaelter koennen nicht alles aufnehmen, aber
+    meist ist es leichter, schwere Gegenstaende in einem Behaelter zu
+    transportieren.
+
+    `stecke (weg)' ist das allgemeine Kommando, um zum Kampf gezueckte Waffen
+    wieder abzulegen.
+
+ SIEHE AUCH:
+    nimm, zuecke
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/stop b/doc/pcmd/stop
new file mode 100644
index 0000000..89b68cd
--- /dev/null
+++ b/doc/pcmd/stop
@@ -0,0 +1,22 @@
+
+stop
+----
+
+ KOMMANDO:
+    stop [<gegner>]
+
+ ARGUMENTE:
+
+     <gegner> (optional)
+        Einer Deiner Gegner
+
+ BESCHREIBUNG:
+    Du hoerst auf, Deine Gegner (oder nur den Gegner <gegner>) zu verfolgen.
+    Allerdings kann man nicht aufhoeren, verfolgt zu werden.
+
+ SIEHE AUCH:
+     Verwandt: toete
+     Anderes:  kaempfen, heilung, leben, tod 
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/stty b/doc/pcmd/stty
new file mode 100644
index 0000000..6d5d0c4
--- /dev/null
+++ b/doc/pcmd/stty
@@ -0,0 +1,44 @@
+
+stty
+----
+
+ KOMMANDO:
+    stty [<typ>]
+    stty reset
+
+ ARGUMENTE:
+
+     <typ>
+        Terminaltyp: `dumb', `vt100' oder `ansi'
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kannst Du einstellen, an was fuer einem Terminal Du
+    sitzt. Folgende Typen werden momentan unterstuetzt:
+
+     `ansi'    das Terminal versteht Farbcodes und Hervorhebungen wie
+               Fettschrift
+     `vt100'   das Terminal ist einfarbig, kennt aber Fettschrift u.ae.
+     `dumb'    das Terminal versteht keine Hervorhebungen
+
+    Der Terminaltyp wird u.a. bei Kommandos wie "wer" benutzt um bestimmte
+    Woerter oder Phrasen hervorzuheben.
+
+    Nach dem Einstellen des Terminaltyp sollte bei `vt100' und `ansi' eine
+    Ausgabe erfolgen, welche die moeglichen Textattribute oder Farben
+    darstellt. Bei ANSI wird das Ganze von einem lesbaren Text gefolgt. Sollte
+    also der folgende Satz
+
+    Sollte dieser Text hier nicht richtig lesbar sein, benutze
+    das Kommando stty reset!
+
+    nicht erscheinen oder nur schwer lesbar sein, sollte man mit stty reset
+    die Farben wiederherstellen oder ein anderes Terminal einstellen.
+
+ ACHTUNG:
+    Manche Terminals sind u.U. nicht ganz ANSI kompatibel, was dazu fuehrt,
+    dass die Farbe nicht ausgeschaltet wird. Sollte soetwas passieren bitte
+    das Kommando stty reset benutzen, welches einen weissen Hintergrund und
+    schwarzen Vordergrund einstellt.
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/suche b/doc/pcmd/suche
new file mode 100644
index 0000000..e436c44
--- /dev/null
+++ b/doc/pcmd/suche
@@ -0,0 +1,43 @@
+
+suche
+----------
+
+ KOMMANDO:
+    suche <was>
+    such  <was>
+    durchsuche <was>
+
+ ARGUMENTE:
+
+     <was>
+        Ein Gegenstand oder Detail
+
+ BESCHREIBUNG:
+    Nicht alle Geheimnisse dieser Welt offenbaren sich auf den ersten Blick.
+    Bei einigen muss mein ein zweites mal hinschauen. Manche Dinge verbergen 
+    sich aber auch diesem genaueren Blick. Genau Dann ist dieser Befehl 
+    sinnvoll.
+
+    Sicher bist Du schonmal auf einem Weg oder in einem Wald ueber einen 
+    Laubhaufen gestolpert und hast Dich gefragt, welche Schaetze er wohl 
+    birgt. Ein gezieltes 'suche laub' oder 'durchsuche laub' bringt da so
+    manch nuetzliches zum Vorschein.
+
+ ACHTUNG:
+    Leider ist das Verhalten von 'such', 'suche' und 'untersuche' jeweis 
+    abhaengig von der Kreativitaet des programmierenden Magiers. Auch wenn 
+    die drei Befehle aehnlich klingen, heisst das nicht, dass sie auch das 
+    gleiche machen. 
+
+    Manchmal findet man etwas, wenn man 'durchsuche laub' macht, waehrend 
+    'suche laub' nur ein lahmes 'Du suchst, findest aber nichts.' zum 
+    Vorschein bringt.
+
+    Oft findet man aber in der Raumbeschreibung Hinweise, welcher Begriff 
+    hier passend ist.
+
+ SIEHE AUCH:
+    rieche, lausche, schau, untersuche
+
+ LETZTE AeNDERUNG:
+    Mon, 01.08.2002, 14:00:00 von Vanion
diff --git a/doc/pcmd/syntaxsammlung b/doc/pcmd/syntaxsammlung
new file mode 100644
index 0000000..ed5bd97
--- /dev/null
+++ b/doc/pcmd/syntaxsammlung
@@ -0,0 +1,45 @@
+
+syntaxsammlung
+-------------
+
+ KOMMANDO:
+    syntaxsammlung [ja | nein]
+
+ ARGUMENTE:
+    nichts, ja oder nein
+
+ BESCHREIBUNG:
+    Um Befehle im MG flexibler zu machen und Spieler und Magier zu entlasten,
+    indem das Spiel besser die Absicht des Spielers bei einem Befehl erkennt,
+    sammeln wir (anonyme) Statistiken ueber Befehle, welche von Spielern
+    benutzt werden, sofern Spieler damit einverstanden sind.
+    Mit diesem Befehl kannst Du also mithelfen, Syntaxen im MG zu verbessern.
+
+    Wenn Du einverstanden bist, speichern wir anonym (d.h. ohne Deinen
+    Charnamen), welche Deiner Befehle erfolgreich und nicht erfolgreich waren.
+    Uebliche Kommunikationsbefehle (z.B. sage, teile-mit, rfluester, ebenen,
+    teamrufe, mrufe, rufe) werden dabei nicht gespeichert.
+    
+    Mit 'syntaxsammlung ja' kannst Du die Speicherung einschalten, mit
+    'syntaxsammlung nein' kannst Du sie ausschalten.
+
+    Die gesammelten Daten koennen nur von Erzmagiern oder Goettern eingesehen
+    werden. Allerdings kann es sein, dass diese anderen Magiern Beispiele aus
+    der Sammlung zeigen, sofern das Beispiel keinen Rueckschluss auf einen
+    Spieler zulaesst.
+
+    Uebrigens sind vor allem Kommandos beim Forschen interessant, weniger
+    beim Metzeln, Ideln, Chatten etc. (Kommunikation s.o.)
+    Daher werden zur Zeit nur Befehle erfasst, welche mehr als 2 Woerter
+    enthalten.
+
+    Ein Beispiel, was gespeichert wird:
+    Befehl                   |Gegend|Erfolg|Anzahl|FP
+    unt jeden zweiten vorhang|ebene |0     |1     |0
+
+    Erfolg ist alles, was kein Notifyfail ausloest, Anzahl, wie oft diese Syntax
+    schonmal benutzt wurde und FP, ob diese Syntax (irgendwo) einen FP gegeben
+    hat.
+
+ LETZTE AeNDERUNG:
+    18.06.2016, Zesstra
diff --git a/doc/pcmd/taste b/doc/pcmd/taste
new file mode 100644
index 0000000..2d173f8
--- /dev/null
+++ b/doc/pcmd/taste
@@ -0,0 +1,47 @@
+
+taste (ab)
+beruehre
+--------------
+
+KOMMANDO
+    taste
+    taste <was> [an <objekt> | am <objekt>] [in mir | im raum] [ab]
+    beruehre <was> [an <objekt> | am <objekt>] [in mir | im raum]
+
+ARGUMENTE
+    <objekt>
+      Ein Gegenstand bzw. Lebewesen, das man abtasten will.
+
+BESCHREIBUNG
+    "taste" ist das allgemeine Kommando, um (ab)tastbare Details an
+    Gegenstaenden, Lebewesen oder in Raeumen wahrzunehmen. Hierbei
+    laesst "taste" ohne Argumente den Spieler ungezielt im Raum rumtasten, in
+    dem er sich derzeit befindets. Ob man hierbei ueberhaupt irgendwas
+    wahrnimmt, haengt vom Magier des Raumes ab.
+    An allen anderen Gegenstaenden bzw. Lebewesen im selben Raum oder im
+    eigenen Inventar kann man mit "taste (an)" ebenfalls tasten. Nicht immer
+    kann man jedoch etwas (er)tasten.
+
+    Da bei Objekten mit gleichen tastbaren/fuehlbaren Details zuerst an im
+    Raum liegende Objekte abgetastet werden, kann man an Sachen, die man bei
+    sich traegt, auf alle Faelle mit dem Zusatz "in mir" abtasten.
+
+    Ertastbare Details wurden im Morgengrauen erst 2010 standardisiert.
+    Erwartet nicht, dass es in allen Raeumen / an allen Gegenstaenden tastbare
+    Details gibt - sie sind eher selten.
+
+BEISPIELE
+    taste boden ab
+    taste boden (identisch zu "taste boden ab")
+
+    taste rucksack in mir ab
+    taste baumstumpf im raum ab
+    taste schnalle an rucksack in mir ab
+
+SIEHE AUCH:
+    bezugspunkt
+    schau, rieche, lausche, lies
+
+LETZTE AENDERUNGEN:
+    13.03.2016, Zesstra
+
diff --git a/doc/pcmd/teile b/doc/pcmd/teile
new file mode 100644
index 0000000..b5a0c36
--- /dev/null
+++ b/doc/pcmd/teile
@@ -0,0 +1,57 @@
+
+teile (mit)
+-----------
+
+ KOMMANDO:
+    teile <wem> mit <text>
+    teile .[<nr>] mit <text>
+    teile <wem>@<mud> mit <text>
+    (Abkuerzung: tm <wem> <text>)
+    
+    erzaehle <wem> <text>
+    erzaehle .[<nr>] <text>
+    erzaehle <wem>@<mud> <text>
+
+ ARGUMENTE:
+
+     <wem>
+        Name des Spielers, dem Du etwas erzaehlen willst
+     <nr>
+        Eine Nummer in der Mitteilungsgeschichte
+     <mud>
+        Name eines MUDs aus der `muds'-Liste
+     <text>
+        Die Mitteilung selbst
+
+ BESCHREIBUNG:
+    Sendet dem angegebenen Spieler eine Nachricht. Es spielt keine Rolle, wo
+    er sich im Spiel befindet. Mitteilen verbraucht *keine* Magiepunkte.
+
+    Mit `teile <wem>@<mud> mit <text>' kann man auch Spielern in anderen MUDs
+    etwas mitteilen. <mud> muss nicht der komplette Mudname sein; es genuegt
+    auch eine eindeutige Abkuerzung.
+
+    Das Kommando merkt sich, wem Du alles etwas mitteilst. Mit `tmhist' kannst
+    Du Dir ansehen, wem Du schon alles etwas mitgeteilt hast. Fuer weitere
+    Mitteilungen kannst Du anstelle des Namens auch die Nummer angeben, *aber
+    Achtung!* Die Liste wird danach wieder neu sortiert!
+
+    Bearbeitet der Spieler einen Text oder liest er irgendetwas, so werden
+    Mitteilungen u.U. gespeichert (dies wird mitgeteilt). Die gespeicherten
+    Mitteilungen erfaehrt der andere Spieler, wenn er mit dem Lesen oder
+    Bearbeiten fertig ist.
+
+    Sofern Du Deine Teile-mit-History (s. tmhist) eingeschaltet hast, werden
+    aus- und eingehende TMs gespeichert. Hat Dein Gespraechspartner seine
+    History eingeschaltet, wird ein TM, was Du ihm schickst, bei ihm
+    gespeichert. Moechtest Du dies nicht, kannst Du den Befehl 'rfluester'
+    verwenden, bei welchem in keinem Fall der Inhalt eines Gespraechs
+    gespeichert wird.
+
+ SIEHE AUCH:
+    erwidere, sage, frage, antworte, fluestere, gespraech, rufe, ebenen, weg,
+    ignoriere, kobold, muds, senderwiederholung, klingelton, tmhist,
+    rfluestere
+
+ LETZTE AeNDERUNG:
+    09.08.2008, Zesstra
diff --git a/doc/pcmd/telnegs b/doc/pcmd/telnegs
new file mode 100644
index 0000000..5dfcc57
--- /dev/null
+++ b/doc/pcmd/telnegs
@@ -0,0 +1,22 @@
+KOMMANDO:
+        telnegs [einstellung]
+
+ARGUMENTE:
+        einstellung
+          * ein - Schaltet die Anzeige ein
+          * aus - Schaltet die Anzeige aus
+
+          Wird kein Argument angegeben, wird die aktuelle Einstellung
+          angezeigt.
+    
+BESCHREIBUNG:
+          Man kann festlegen, ob man Aenderungen der Fenstergroesse
+          angezeigt bekommen will oder nicht. Dies setzt voraus, dass
+          man ein Telnet benutzt, das Telnetnegotiations unterstuetzt.
+
+
+SIEHE AUCH:
+        zeilen, telnet
+----------------------------------------------------------------------------
+Last modified: Sun Nov  7 23:00:00 1999 by Tiamak
+
diff --git a/doc/pcmd/telnet b/doc/pcmd/telnet
new file mode 100644
index 0000000..7e11a2a
--- /dev/null
+++ b/doc/pcmd/telnet
@@ -0,0 +1,34 @@
+
+telnet
+------
+
+ KOMMANDO:
+    telnet <kommando> <argumente>
+
+ ARGUMENTE:
+
+     <kommando>
+        Eines von den unten angebenen Kommandos, um bestimmte Aspekte der
+        Kommunikation des Muds mit dem Client einzustellen.
+
+     <arguments>
+        Argumente fuer das jeweilige telnet Kommando
+
+ BESCHREIBUNG:
+    Dies ist ein Sammelkommando, um Einfluss auf die Eigenschaften der
+    Kommunikation vom Mud mit dem Client nehmen zu koennen oder sich diese
+    anzeigen zu lassen.
+    Moegliche Kommandos sind:
+    * keepalive
+      Stellt ein, dass regelmaessig Daten vom MG zum Client geschickt werden,
+      damit die Verbindung aufrechterhalten wird.
+      Fuer Details s. Hilfeseite telnet_keepalive
+    * rttime
+      Ausgabe der letzten gemessenen "round-trip time" vom MG zum Client
+      in Mikrosekunden (1s == 1000000 Mikrosekunden)
+
+ SIEHE AUCH:
+    telnegs, telnet keepalive, telnet gmcp
+
+ LETZTE AeNDERUNG:
+    03.02.2013, Zesstra
diff --git a/doc/pcmd/telnet_keepalive b/doc/pcmd/telnet_keepalive
new file mode 100644
index 0000000..eecbfd7
--- /dev/null
+++ b/doc/pcmd/telnet_keepalive
@@ -0,0 +1,42 @@
+
+telnet keepalive
+----------------
+
+ KOMMANDO:
+    telnet keepalive <ein|aus>
+
+ ARGUMENTE:
+
+     <ein>
+        Schaltet das Telnet-Keep-Alive ein.
+     <aus>
+        Schaltet das Telnet-Keep-Alive aus.
+
+ BESCHREIBUNG:
+    Einige Spieler und Magier haben immer mal wieder Probleme, dass sie bei
+    laengerer Inaktivitaet rausfliegen, weil irgendein Router im Netzwerk die
+    inaktive Verbindung abbricht oder weil aus aehnlichen Gruenden die SSL
+    Verbindung terminiert wird. Daher besitzen die Spielershells ein
+    einschaltbares 'Telnet-Keep-Alive'.
+
+    Diese Funktion schickt alle 4 min Daten an eure Clients, die diese
+    nicht anzeigen, aber ihrerseits beantworten/bestaetigen (sofern der Client
+    dies unterstuetzt). So gibt es in der Verbindung zum Mud min. alle 4 min
+    Datenverkehr. Das sollte Verbindungsabbruechen durch Inaktivitaet
+    vorbeugen.
+
+    Bitte schaltet diese Funktion aber nur ein, wenn ihr sie braucht, d.h.
+    ohne sie Probleme mit Verbindungsabbruechen beim Ideln habt.
+    Habt ihr Verbindungsabbrueche, ohne Idle zu sein, wird euch dieses
+    Keep-Alive nichts helfen.
+
+    Ohne Argumente wird der aktuelle Zustand angezeigt.
+
+    Hinweis fuer Magier: Magier im Magiermodus (mschau ein) kommen leider
+    nicht in den Genuss dieses Features, weil sie keinen Heartbeat haben.
+
+ SIEHE AUCH:
+    telnegs, telnet gmcp
+
+ LETZTE AeNDERUNG:
+    08.12.2015, Zesstra
diff --git a/doc/pcmd/titel b/doc/pcmd/titel
new file mode 100644
index 0000000..0921202
--- /dev/null
+++ b/doc/pcmd/titel
@@ -0,0 +1,32 @@
+
+titel
+-----
+
+ KOMMANDO:
+    titel <text>
+    titel 0
+
+ ARGUMENTE:
+
+     <text>
+        Der Titeltext.
+
+ BESCHREIBUNG:
+    Der Text wird als neuer Titel gesetzt. Dabei sollte der Titel nicht mit
+    einem Spielertitel identisch oder einem solchen sehr aehnlich sein. Der
+    uebergebene Text darf ein Backspace (\b) am Anfang enhalten, wenn
+    darauf ein Komma (,) oder ein Hochkomma (') folgt.
+
+    Wird kein Argument uebergeben, so wird der aktuelle Titel geloescht.
+
+    Wird 0 als Argument uebergeben, so wird der Titel durch den aktuellen
+    Gildentitel ersetzt.
+    
+    Das Kommando steht Spielern ab Level 21 zur Verfuegung, sofern sie sich
+    in der Fraternitas Dono Archmagorum diese Faehigkeit beibringen lassen.
+
+ SIEHE AUCH:
+    stufen, presay (Seherkommando)
+
+ LETZTE AeNDERUNG:
+    Fri, 25.05.2007, 19:57:00 - Miril
diff --git a/doc/pcmd/tmhist b/doc/pcmd/tmhist
new file mode 100644
index 0000000..d5f6cf6
--- /dev/null
+++ b/doc/pcmd/tmhist
@@ -0,0 +1,38 @@
+
+tmhist
+-----------
+
+ KOMMANDO:
+    tmhist
+    tmhist aus
+    tmhist namen
+    tmhist ein
+    tmhist <spielername>
+    tmhist <nr>
+
+ BESCHREIBUNG:
+    Ohne Argument wird die aktuelle Teile-mit-History ausgegeben.
+    'tmhist aus' schaltet die Speicherung komplett aus,
+    'tmhist namen' speichert nur die Namen der Gespraechspartner und einige
+    statistische Daten.
+    'tmhist ein' speichert Namen der Gespraechspartner sowie die Inhalte der
+    Gespraeche.
+    'tmhist <name>' gibt das Gespraech mit dem angegebenen Spieler wieder,
+    sofern so ein Gespraech existiert und der Inhalt gespeichert wurde.
+    'tmhist <nr>' gibt das Gespraech mit der Nummer <nr> in der History
+    wieder.
+
+    Die Gespraechsinhalte werden beim Ausloggen mittels 'schlafe ein'
+    innerhalb von ca. 4s geloescht, bei 'ende' sofort. Bricht die Verbindung
+    zum MorgenGrauen ab, werden die Gespraechsinhalte nach 15min geloescht.
+    Es werden max. 20 Gespraeche mit jeweils max. 50 Nachrichten gespeichert.
+
+    Alle mit dem Befehl 'rfluester' mitgeteilten Mitteilungen werden nicht
+    gespeichert.
+
+ SIEHE AUCH:
+    erwidere, sage, frage, antworte, fluestere, gespraech, rufe, ebenen, weg,
+    ignoriere, kobold, muds, senderwiederholung, klingelton, teile, rfluestere
+
+ LETZTE AeNDERUNG:
+    Sa, 09.08.2008, Zesstra
diff --git a/doc/pcmd/toete b/doc/pcmd/toete
new file mode 100644
index 0000000..6893ac6
--- /dev/null
+++ b/doc/pcmd/toete
@@ -0,0 +1,32 @@
+
+toete
+-----
+
+ KOMMANDO:
+    toete <monster>
+    toete alle
+
+ ARGUMENTE:
+
+     <monster>
+        Der zu toetende Gegner
+
+ BESCHREIBUNG:
+    Startet eine Attacke auf das angegebene Monster. Es muss sich im selben
+    Raum befinden. Es ist moeglich, aus einem laufenden Kampf heraus zu
+    fliehen. Wenn man das fliehende Monster faengt, darf man den ersten Schlag
+    ausfuehren (umgekehrt gilt das allerdings auch!).
+
+    Es ist zwar auch moeglich, andere Spieler zu toeten. Dies ist jedoch unter
+    Strafe gestellt, es sei denn, der Kampf findet in extra dafuer
+    vorgesehenen Gebieten statt.
+
+    Mit 'toete alle' greift man ALLE potentiellen Gegner im Raum an, man
+    sollte sich also gut ueberlegen, wo man dieses Kommando einsetzt.
+
+ SIEHE AUCH:
+     Verwandt: stop, angriffsmeldung
+     Anderes:  kaempfen, heilung, leben, tod 
+
+ LETZTE AeNDERUNG:
+    Mon, 25.08.2003, 15:30:00 von Boing
diff --git a/doc/pcmd/ton b/doc/pcmd/ton
new file mode 100644
index 0000000..e61189e
--- /dev/null
+++ b/doc/pcmd/ton
@@ -0,0 +1,26 @@
+KOMMANDO:
+	ton [<Status>]
+
+ARGUMENTE:
+	<Status>
+	  EIN: Ton einschalten.
+	  AUS: Ton ausschalten.
+
+BESCHREIBUNG:
+	Die meisten Terminals koennen einfache Pieptoene erklingen lassen,
+	was auch an einigen Stellen hier im MUD zum Einsatz kommt.
+	Genannt seien hierbei vorrangig 'erwarte' und 'wecke', welche einen
+	Grossteil der zweifelhaften Geraeuschkulisse ausmachen. Nun ist es
+	nicht immer guenstig, die schwer arbeitenden Menschen in einem
+	Rechenzentrum mit offensichtlich nicht studienbezogenen Toenen zu
+	stoeren. Wer nicht die Moeglichkeit hat, diese stoerenden Laute am
+	Computer direkt abzuschalten, dem sei mit diesem Befehl geholfen:
+	  'ton EIN' - Es werden Toene vom MUD erzeugt (Standard).
+	  'ton AUS' - Es werden keine Toene vom MUD erzeugt.
+	'ton' ohne Parameter zeigt den aktuellen Status.
+
+SIEHE AUCH:
+	erwarte, wecke
+
+----------------------------------------------------------------------------
+11.11.2006 Zesstra
diff --git a/doc/pcmd/trage b/doc/pcmd/trage
new file mode 100644
index 0000000..22b1704
--- /dev/null
+++ b/doc/pcmd/trage
@@ -0,0 +1,24 @@
+
+trage
+-----
+
+ KOMMANDO:
+    trage <kleidung>
+
+ ARGUMENTE:
+
+     <kleidung>
+        Das anzulegende Kleidungsstueck
+
+ BESCHREIBUNG:
+    `trage' ist ein Kommando um Kleidung anzulegen. Robuste Kleidung bietet
+    nur dann Schutz gegen Angriffe, wenn sie angezogen wurde.
+
+    Man kann normalerweise von jeder Art Kleidung nur ein Stueck gleichzeitig
+    tragen (zwei Huete uebereinander saehen ja auch etwas laecherlich aus...).
+
+ SIEHE AUCH:
+    zuecke, ziehe (an/aus)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/tutorial b/doc/pcmd/tutorial
new file mode 100644
index 0000000..a187f96
--- /dev/null
+++ b/doc/pcmd/tutorial
@@ -0,0 +1,28 @@
+
+tutorial
+--------
+
+ BESCHREIBUNG:
+
+   Im Startraum jeder Rasse kann man mit dem Befehl 'tutorial' das
+   Neuspielertutorial beginnen. Im Tutorial bekommt man von einem
+   alten Steinbeisser die wichtigsten Faehigkeiten fuer das Ueberleben
+   im MorgenGrauen beigebracht.
+
+   Es werden: Bewegung, Untersuchen, Kommunikation, Aktionen, Quests,
+   Benutzung von Containern, Lichtquellen, Handel und Kampf behandelt.
+
+   Das Tutorial kann per 'ueberspringe tutorial' verlassen werden, sobald
+   Du das erste Mal dem Steinbeisser begegnet bist. Du hast jederzeit die 
+   Moeglichkeit, es wieder zu beginnen, indem Du den Befehl 'tutorial' in
+   Deinem Startraum eingibst.
+
+   Die Geschwindigkeit der Informationen innerhalb des Tutorials ist
+   mittels 'schneller', 'langsamer', 'pause', 'weiter', 'abbruch' und
+   'neustart' steuerbar.  
+
+SIEHE AUCH: einfuehrung, cicerones, hilfe
+
+ LETZTE AeNDERUNG:
+   07.05.2016, Arathorn
+
diff --git a/doc/pcmd/typo b/doc/pcmd/typo
new file mode 100644
index 0000000..6470489
--- /dev/null
+++ b/doc/pcmd/typo
@@ -0,0 +1,48 @@
+typo
+----
+
+KOMMANDO:
+    typo <text>
+    typo <objekt>:<text>
+
+ARGUMENTE:
+
+    <text>
+        Eine Mitteilung
+    <objekt>
+        Ein Referenzobjekt, das neben Dir liegt oder in Deinem Inventar ist
+
+BESCHREIBUNG:
+    In den Beschreibungen von Raeumen und Objekten kommt es immer wieder mal
+    zu Tippfehlern, die auch die Testphase des Objektes/Gebietes unerkannt
+    ueberstanden haben.
+
+    Wenn Du einen Tippfehler gefunden hast, so kannst Du den Verantwortlichen
+    mit diesem Befehl davon unterrichten.
+
+    Fuer den Magier ist es sehr hilfreich, wenn Du bei in Meldung angibst,
+    wo genau der Tippfehler zu finden ist (also z.B, welches Detail den
+    Fehler enthaelt).
+
+    Zoegere nicht, wenn Du einen Tippfehler findest; Fehlermitteilungen sind
+    *sehr* willkommen!
+
+    Wenn Du einen Typo an einem bestimmten Objekt oder NPC entdeckst, kannst
+    Du dieses/diesen hinter einem Doppelpunkt angeben, damit der fuer das
+    Objekt verantwortliche Magier die Meldung bekommt.
+    Wenn das Objekt nicht zu finden ist, wird die ganze Eingabe als
+    Meldung aufgefasst.
+
+BEMERKUNG:
+    Der Befehl 'typo' bezieht sich bei Nichtangabe eines Bezugsobjekts
+    auf das letzte betrachtete Objekt. Hast Du also ein Objekt untersucht,
+    dann wird die Meldung fuer diese Objekt abgegeben. Hast Du aber den
+    Raum untersucht oder 'schau' eingegeben, wird die Meldung fuer Deinen
+    momentanen Raum abgesetzt.
+
+SIEHE AUCH:
+    bug, idee, detail, bezugsobjekt
+
+LETZTE AeNDERUNG:
+    03.06.2013, Zesstra
+
diff --git a/doc/pcmd/uhrmeldung b/doc/pcmd/uhrmeldung
new file mode 100644
index 0000000..65b4dcf
--- /dev/null
+++ b/doc/pcmd/uhrmeldung
@@ -0,0 +1,33 @@
+
+uhrmeldung
+----------
+
+ KOMMANDO:
+    uhrmeldung [<meldung>]
+
+ ARGUMENTE:
+
+     <meldung>
+        Deine ganz persoenliche Uhrmeldung
+
+ BESCHREIBUNG:
+    Ohne Argumente wird Deine aktuelle Uhrmeldung angezeigt.
+
+    Mit dem Argument <meldung> kann man sich eine eigene Uhrmeldung setzen.
+    Der Platzhalter fuer die Uhrzeit in der Meldung ist `%d'.
+
+    Es darf nur *ein* `%d' in der Meldung vorkommen!
+
+    Mit dem Befehl "uhrmeldung 0" kannst Du Deine Uhrmeldung auf die
+    Standardmeldung zuruecksetzen.
+
+ BEISPIELE:
+
+    > uhrmeldung Schon %d Uhr, und immer noch im MUD.
+
+    Das gibt dann zB. abends um zehn:
+
+    Schon 22 Uhr, und immer noch im MUD.
+
+ LETZTE AeNDERUNG:
+    Sam, 08.03.2008, 13:08:00 von Arathorn
diff --git a/doc/pcmd/ultrakurz b/doc/pcmd/ultrakurz
new file mode 100644
index 0000000..f98bda7
--- /dev/null
+++ b/doc/pcmd/ultrakurz
@@ -0,0 +1,21 @@
+
+ultrakurz
+---------
+
+ KOMMANDO:
+    ultrakurz
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Schaltet auf den "Ultrakurz"-Modus um. Wenn Du Dich in diesem Modus
+    befindest, siehst Du *keine* Raumbeschreibung - nuetzlich, wenn man
+    altbekannte Pfade ablaeuft. Mit den Kommandos `lang' und `kurz' kannst Du
+    diesen Modus wieder beenden.
+
+ SIEHE AUCH:
+    lang, kurz, schau, ausgaenge
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/unalias b/doc/pcmd/unalias
new file mode 100644
index 0000000..2621c13
--- /dev/null
+++ b/doc/pcmd/unalias
@@ -0,0 +1,46 @@
+
+unalias
+-------
+
+ KOMMANDO:
+    unalias <alias>
+    unalias <muster>
+
+ ARGUMENTE:
+
+     <alias>
+        Das zu entfernende Alias
+     <muster>
+        Muster, das die zu entfernenden Aliase beschreibt
+        (Das Muster muss ein sog. 'regular expression' sein.)
+
+ BESCHREIBUNG:
+    (Statt `unalias' kann man auch `unali' verwenden!)
+
+    Es werden ein oder mehrere Aliase geloescht.
+
+    *Achtung!* Es erfolgt keine Sicherheitsabfrage!
+
+ BEISPIELE:
+    Ein einzelnes Alias loeschen:
+
+    > unalias weg
+
+    Alle "tm"-Aliase loeschen (man beachte den . vor dem *):
+
+    > unalias tm.*
+
+    Alle Aliase loeschen, die auf Ziffern liegen:
+
+    > unalias [0-9]
+
+    Alle Aliase loeschen:
+
+    > unalias .*
+
+ SIEHE AUCH:
+    alias
+
+ LETZTE AeNDERUNG:
+   02.10.2012, Zesstra
+
diff --git a/doc/pcmd/url b/doc/pcmd/url
new file mode 100644
index 0000000..5bcad42
--- /dev/null
+++ b/doc/pcmd/url
@@ -0,0 +1,34 @@
+
+url
+---
+
+ KOMMANDO:
+    url [<adresse>]
+
+ ARGUMENTE:
+
+     <adresse> (optional)
+        Die neue Adresse
+
+ BESCHREIBUNG:
+    Wenn Du eine eigene HomePage im Internet hast und sie fuer Deine
+    Mitspieler erreichbar machen willst, so kannst Du das mit diesem
+    Kommando tun.
+
+    Ohne <adresse> wird die aktuelle Adresse angezeigt, ist sie 'keine',
+    so wird die Adresse geloescht.
+
+    Aus <adresse> werden saemtliche HTML-Tags entfernt!
+
+    Zu finden sind diese Informationen:
+
+     http://mg.mud.de/
+     -> Information
+        -> Online
+
+ SIEHE AUCH:
+    Persoenliche Details: email, icq, messenger, ort
+    Sonstiges:            finger
+
+ LETZTE AeNDERUNG:
+    Sun, 05.07.1997, 17:00:00 von Rikus
diff --git a/doc/pcmd/verben b/doc/pcmd/verben
new file mode 100644
index 0000000..8ccda58
--- /dev/null
+++ b/doc/pcmd/verben
@@ -0,0 +1,29 @@
+
+verben
+------
+
+ KOMMANDO:
+    verben
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Mit diesem Befehl werden alle moeglichen Verben der Seele angezeigt. Diese
+    Verben haben in der Regel keinen tiefen Sinn, sondern dienen dazu, eine
+    gewisse Stimmung zu verbreiten.
+
+    Da dies eine ganze Menge an Verben sind, deren Funktion meist eh auf der
+    Hand liegt, existieren fuer sie keine separaten Hilfeseiten.
+
+    Eine kurze Hilfe zu jedem Verb kannst Du jedoch jederzeit mit `<verb> -h'
+    erhalten.
+
+    Oft genutzte Verben sind: `lache', `laechel [an]', `danke', `argl',
+    `grinse', `umarme', `wuschel', ...
+
+ SIEHE AUCH:
+    adverb
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/vorsicht b/doc/pcmd/vorsicht
new file mode 100644
index 0000000..47484ac
--- /dev/null
+++ b/doc/pcmd/vorsicht
@@ -0,0 +1,35 @@
+
+vorsicht
+--------
+
+ KOMMANDO:
+    vorsicht <lp>
+
+ ARGUMENTE:
+
+     <lp>
+        Zahl zwischen 0 und der max. Zahl Deiner Lebenspunkte
+
+ BESCHREIBUNG:
+    Schaltet den `Vorsichtsmodus' ein. Wenn Du Dich im Vorsichtsmodus
+    befindest, rennen Deine Beine mit Dir fort, sobald Deine Lebenspunkte
+    unter den angegebenen Wert gesunken sind, und Du mit dem naechsten Schlag
+    in der naechsten Kampfrunde an der Reihe bist.
+
+    Die Begruessungsschlaege, die man eventuell austeilt oder einsteckt,
+    fallen *nicht* in eine Kampfrunde. Entsprechend wird der Vorsichtsmodus
+    hier auch *nicht* aktiv!
+
+    Der Defaultmodus ist der Prinz-Eisenherz-Modus `vorsicht 0'.
+
+    Der Vorsichtsmodus funktioniert nicht immer. Er kann Dich zwar retten,
+    wenn Du eine langsame Verbindung oder muede Finger besitzt, aber es kann
+    immer passieren, dass ein Monster Dir mehr Lebenspunkte nimmt als Du noch
+    hast. Manchmal finden Deine Beine auch keinen Fluchtweg.
+
+ SIEHE AUCH:
+    toete, report
+    (nur Seher): fluchtrichtung
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/wecke b/doc/pcmd/wecke
new file mode 100644
index 0000000..b0ca4e0
--- /dev/null
+++ b/doc/pcmd/wecke
@@ -0,0 +1,24 @@
+KOMMANDO:
+	wecke <Lebewesen>
+
+ARGUMENTE:
+	<Lebewesen>
+	  Hier gibt man das Lebewesen an, bei welchem man sich bemerkbar
+	  machen moechte.
+
+BESCHREIBUNG:
+	Will man sich bei insbesondere herumlungernden (auch ideln genannt)
+	Spielern bemerkbar machen, so kann einem dieses Kommando
+	weiterhelfen. Es erzeugt beim zu Weckenden nebst einem kleinen Text,
+	wer verzweifelt um Aufmerksamkeit ringt, auch einen kurzen Piepton.
+
+BEMERKUNGEN:
+	Dieser Ton kann sich in gewissen RL-Umgebungen recht stoerend
+	auswirken. Der zu Weckende kann sich jedoch dagegen mit dem Kommando
+	'ton AUS' wehren.
+
+SIEHE AUCH:
+	ton
+
+----------------------------------------------------------------------------
+11.11.2006 Zesstra
diff --git a/doc/pcmd/weg b/doc/pcmd/weg
new file mode 100644
index 0000000..6420fba
--- /dev/null
+++ b/doc/pcmd/weg
@@ -0,0 +1,30 @@
+
+weg
+---
+
+ KOMMANDO:
+    weg [<text>]
+
+ ARGUMENTE:
+
+     <text>
+        Erklaert die Abwesenheit
+
+ BESCHREIBUNG:
+    Ist man einmal fuer laengere Zeit nicht anwesend und kann nicht auf
+    Mitteilungen reagieren, so kann man den Grund mit diesem Kommando kund und
+    zu wissen tun.
+
+    Wenn Dir nun jemand etwas mitteilt, erhaelt er die Meldung
+
+    <name> ist gerade nicht da: <text>
+
+    und braucht sich nicht zu wundern, wieso keine Antwort kommt.
+
+    Ohne Argument wird die Kennzeichnung wieder aufgehoben.
+
+ SIEHE AUCH:
+    teile (mit), erzaehle, wegmeldung
+
+ LETZTE AeNDERUNG:
+    25. Apr 2011 Gloinson
diff --git a/doc/pcmd/wegmeldung b/doc/pcmd/wegmeldung
new file mode 100644
index 0000000..9461e69
--- /dev/null
+++ b/doc/pcmd/wegmeldung
@@ -0,0 +1,19 @@
+
+wegmeldung
+------
+
+ KOMMANDO:
+    wegmeldung <name>
+
+ ARGUMENTE:
+
+     <name>
+        Name eines Spielers
+
+ BESCHREIBUNG:
+    Dieser Befehl gibt die Weg-Meldung eines Spieler aus, wenn dieser eine 
+    hat. Dann muss man nicht jedes mal den Spieler fingern, wenn man wissen
+    will, ob der grad weg ist oder nicht.
+
+ LETZTE AeNDERUNG:
+    Son, 11. Aug 2002, 19:07:00 von Vanion
diff --git a/doc/pcmd/wer b/doc/pcmd/wer
new file mode 100644
index 0000000..57250ce
--- /dev/null
+++ b/doc/pcmd/wer
@@ -0,0 +1,51 @@
+
+wer
+---
+
+ KOMMANDO:
+    wer [<mud>|<option>]
+
+ ARGUMENTE:
+
+     <mud> (optional)
+        Ein MUD-Name aus der `muds'-Liste
+
+    <optionen> (optional)
+        -s  zeigt statt der Gilde die Herkunft des Mudders an
+        -k  Kurzform der Liste; statt Presay+Titel nur Name, dafuer aber
+            Gilde und Herkunft
+
+ BESCHREIBUNG:
+    Es wird angezeigt, wer sich gerade im MorgenGrauen (oder alternativ im MUD
+    <mud>) befindet. Das Format der Liste fremder MUDs haengt immer von dem
+    jeweiligen MUD ab; in der Liste des MorgenGrauen wird jeder Anwesende wie
+    folgt aufgefuehrt:
+
+    [X] Presay Name Titel - Rasse/Gilde
+
+    Die Buchstaben in eckigen Klammern am Anfang bedeuten:
+
+     [s]   Spieler
+     [S]   Seher
+     [z]   Zweitspieler
+
+     [t]   Testspieler
+     [T]   Testspieler mit Seherlevel
+
+     [L]   Magierlehrling
+     [m]   Vollmagier, ohne Region
+     [M]   Vollmagier, mit Region
+     [H]   Hilfsmagier
+     [R]   Regionschef
+     [W]   Weiser
+     [E]   Erzmagier
+     [G]   Gott
+
+    Die Liste wird in drei Schritten sortiert (von grob nach fein):
+    Magierlevel -> Spielerlevel -> alphabetisch.
+
+ SIEHE AUCH:
+    kwer, kkwer, muds
+
+ LETZTE AeNDERUNG:
+    Wed, 05.04.2000, 01:00:00 von Tiamak
diff --git a/doc/pcmd/wirf b/doc/pcmd/wirf
new file mode 100644
index 0000000..71e555f
--- /dev/null
+++ b/doc/pcmd/wirf
@@ -0,0 +1,25 @@
+
+wirf (weg)
+----------
+
+ KOMMANDO:
+    wirf <objekt> weg
+    wirf alles weg
+    lass <objekt> fallen
+    lass alles fallen
+
+ ARGUMENTE:
+
+     <objekt>
+        Das wegzuwerfende Objekt
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kannst Du Gegenstaende aus Deinem Besitz wieder
+    loswerden. Allerdings lassen sich manche Gegenstaende nicht so ohne
+    weiteres weglegen!
+
+ SIEHE AUCH:
+    stecke (in), nimm [aus]
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/zeilen b/doc/pcmd/zeilen
new file mode 100644
index 0000000..fc55941
--- /dev/null
+++ b/doc/pcmd/zeilen
@@ -0,0 +1,41 @@
+
+zeilen
+------
+
+ KOMMANDO:
+    zeilen [<zahl>]
+    zeilen auto[ -<zahl>]
+    zeilen abs[olut] | rel[ativ]
+
+ ARGUMENTE:
+
+     <zahl>
+        Eine ganze Zahl zwischen 0 und 100
+
+ BESCHREIBUNG:
+    Hiermit kann man die Anzahl der Zeilen einstellen, nach der ein `more'
+    (z.B. in der Topliste) anhaelt.
+
+    Bei 0 haelt das `more' nicht an.
+
+    Mit der Einstellung `auto' wird die Zeilenzahl automatisch ermittelt,
+    sofern Dein Telnet dies unterstuetzt (siehe auch `hilfe telnegs').
+    Um nach dem `more' noch etwas Platz zu haben, kann man z.B. mit
+    `zeilen auto -3' die Zeilenzahl bei automatischer Einstellung verkleinern.
+
+    Mit `zeilen' wird der derzeitig eingestellte Wert angezeigt.
+    Defaultmaessig ist <zahl> auf 20 gesetzt.
+
+    Normalerweise wird in der Promptzeile des `more' eine relative Angabe
+    gemacht, wieviel Prozent des Textes man schon gesehen hat. Mit
+    `zeilen absolut' (auch als `zeilen abs' abkuerzbar) kann man auf eine
+    alternative Darstellung umschalten. Dabei werden die Nummer der untersten
+    angezeigten Zeile sowie die Gesamtzeilenzahl des Textes angezeigt.
+
+    Mit `zeilen rel' kann man wieder auf die relative Anzeige zurueckschalten.
+
+ SIEHE AUCH:
+    telnegs
+
+ LETZTE AeNDERUNG:
+    Sun, 07.11.1999, 23:30:00 von Tiamak
diff --git a/doc/pcmd/zeit b/doc/pcmd/zeit
new file mode 100644
index 0000000..719c8f6
--- /dev/null
+++ b/doc/pcmd/zeit
@@ -0,0 +1,17 @@
+
+zeit
+----
+
+ KOMMANDO:
+    zeit
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Die aktuelle Uhrzeit samt Datum wird ausgegeben.
+
+ QUERVERWEISE: uhrmeldung, zeitzone
+
+ LETZTE AeNDERUNG:
+    Sat Jul  6 14:04:42 2002 von Bambi.
\ No newline at end of file
diff --git a/doc/pcmd/zeitzone b/doc/pcmd/zeitzone
new file mode 100644
index 0000000..631694b
--- /dev/null
+++ b/doc/pcmd/zeitzone
@@ -0,0 +1,45 @@
+
+zeitzone
+----------
+
+ KOMMANDO:
+    zeitzone [<zeitdifferenz>]
+
+ ARGUMENTE:
+
+     <zeitdifferenz>
+        Entweder: Ein ganzzahliger Wert, der den Zeitunterschied zwischen
+                  Deiner Zeitzone und Berlin in Stunden angibt.
+        Oder: UTC +/-i   Deine Zeitzone im Bezug auf die koordinierte
+                         Weltzeit UTC.
+
+ BESCHREIBUNG:
+    Ohne Argumente wird Deine aktuelle Zeitzone angezeigt.
+
+    Mit dem Argument <zeitdifferenz> kann man die eigene Zeitzone
+    einstellen. Diese Zeitdifferenz wird bei der stuendlichen Uhrmeldung
+    und beim Befehl (uhr)zeit beruecksichtigt.
+
+ BEISPIELE:
+
+    > zeitzone UTC 0
+    
+    Sollte man angeben, wenn man in London wohnt.
+    
+    > zeitzone UTC -10
+    
+    Sollte man angeben, wenn man auf Hawaii wohnt.
+    
+    > zeitzone 0
+    
+    Ist die Standard-Einstellung und entspricht der gleichen Zeitzone
+    wie Berlin.
+ 
+ ANMERKUNGEN:
+    Die mit "zeitzone" angegebenen Zeitzonen beruecksichtigen keine lokalen
+    Sommerzeiten - unter anderem, weil die sehr laenderspezifisch sind. Zudem
+    sind keine halben Stunden Zeitunterschiede beruecksichtigt, wie sie in
+    einigen australischen Territorien ueblich sind.
+
+ LETZTE AeNDERUNG:
+    Sat, 30.09.2000, 21:00:00 von Silvana
diff --git a/doc/pcmd/ziehe b/doc/pcmd/ziehe
new file mode 100644
index 0000000..6d766e1
--- /dev/null
+++ b/doc/pcmd/ziehe
@@ -0,0 +1,29 @@
+
+ziehe
+-----
+
+ KOMMANDO:
+    ziehe <kleidung> an | aus
+    ziehe <waffe> hervor
+
+ ARGUMENTE:
+
+     <kleidung>
+        Ein Kleidungsstueck
+     <waffe>
+        Eine Waffe
+
+ BESCHREIBUNG:
+    `ziehe (an/aus)' ist das allgemeine Kommando, um Kleidung an- und
+    abzulegen. Robuste Kleidung bietet nur dann Schutz gegen Angriffe, wenn
+    sie angezogen wurde.
+
+    `ziehe (hervor)' ist das allgemeine Kommando, um eine Waffe zum Kampf in
+    die Hand zu nehmen; nur wenn die Waffe hervorgezogen wurde, wird sie im
+    Kampf zum Angriff eingesetzt.
+
+ SIEHE AUCH:
+    trage, zuecke, stecke (weg)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/zuecke b/doc/pcmd/zuecke
new file mode 100644
index 0000000..31140e2
--- /dev/null
+++ b/doc/pcmd/zuecke
@@ -0,0 +1,23 @@
+
+zuecke
+------
+
+ KOMMANDO:
+    zuecke <waffe>
+
+ ARGUMENTE:
+
+     <waffe>
+        Eine Waffe
+
+ BESCHREIBUNG:
+    `zuecke' ist das allgemeine Kommando, um eine Waffe zum Kampf in die Hand
+    zu nehmen; nur wenn die Waffe gezueckt wurde, wird sie im Kampf zum
+    Angriff eingesetzt. Es kann immer nur eine Waffe im Kampf eingesetzt
+    werden. Schwere Waffen koennen auch behindern.
+
+ SIEHE AUCH:
+    ziehe (an/aus), stecke (weg/zurueck)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/pcmd/zweitiemarkierung b/doc/pcmd/zweitiemarkierung
new file mode 100644
index 0000000..4a906d3
--- /dev/null
+++ b/doc/pcmd/zweitiemarkierung
@@ -0,0 +1,30 @@
+KOMMANDO:
+        Zweitiemarkierung [Status]
+
+ARGUMENTE:
+        Status
+          Hier gibt man an, ob und wie Spieler jemanden als Zweitie
+          erkennen:
+          * unsichtbar - kein Spieler sieht, ob man Zweitie ist
+          * sichtbar   - Spieler sieht, dass man Zweitie ist, aber nicht
+                          wessen Zweitie man ist
+          * Name       - alle Spieler sehen, wessen Zweitie man ist
+
+BESCHREIBUNG:
+        Jeder Spieler im MUD ist verpflichtet, seine Zweities zu markieren,
+        um damit Verantwortlichkeiten besser zuordnen zu koennen.
+        Es ist jedoch nicht noetig, dass andere Spieler diese Information
+        erhalten, da dies nur fuer Magier interessant ist. Dieser Befehl
+        ermoeglicht es nun, diese Information vor anderen Spielern ganz oder
+        auch nur teilweise zu verbergen.
+        Man kann angeben, ob man als Zweitie erkannt wird und ob sogar
+        erkannt wird, wessen Zweitie man ist.
+        Die Standardeinstellung ist hierbei, dass andere Spieler erkennen,
+        ob man Zweitie ist, nicht jedoch, wessen Zweitie man ist.
+
+SIEHE AUCH:
+        regeln, Zweitspieler, Testspieler, Magier
+
+----------------------------------------------------------------------------
+Last modified: Son, 27. Okt 2002, 10:00:00, Vanion
+
diff --git a/doc/props/.svn-commit.tmp.swp b/doc/props/.svn-commit.tmp.swp
new file mode 100644
index 0000000..9931e7d
--- /dev/null
+++ b/doc/props/.svn-commit.tmp.swp
Binary files differ
diff --git a/doc/props/.synonym b/doc/props/.synonym
new file mode 100644
index 0000000..bc3b73a
--- /dev/null
+++ b/doc/props/.synonym
@@ -0,0 +1,54 @@
+autoattack P_AGGRESSIVE
+P_AUTOATTACK P_AGGRESSIVE
+hochzeit P_MARRIED
+SI_SKILLFUNC skill_info_liste
+SI_CLOSURE skill_info_liste
+SI_SKILLABILITY skill_info_liste
+SI_SKILLDAMAGE_TYPE skill_info_liste
+SI_SKILLDAMAGE_MSG skill_info_liste
+SI_SKILLDAMAGE_MSG2 skill_info_liste
+SI_INHERIT skill_info_liste
+SI_DIFFICULTY skill_info_liste
+SI_LASTLIGHT skill_info_liste
+SI_TESTFLAG skill_info_liste
+SI_GUILD skill_info_liste
+SI_ENEMY skill_info_liste
+SI_FRIEND skill_info_liste
+SI_MAGIC_TYPE skill_info_liste
+SI_LAST_USE skill_info_liste
+SI_LEARN_PROB skill_info_liste
+SI_SKILLDURATION skill_info_liste
+SI_SPELLBOOK skill_info_liste
+SM_RACE skill_info_liste
+SI_SPELLCOST skill_info_liste
+SI_TIME_MSG skill_info_liste
+SI_SP_LOW_MSG skill_info_liste
+SI_PREPARE_MSG skill_info_liste
+SI_PREPARE_BUSY_MSG skill_info_liste
+SI_PREPARE_ABORT_MSG skill_info_liste
+SI_NOMAGIC skill_info_liste
+SI_NOMAGIC_MSG skill_info_liste
+SI_SPELLFATIGUE skill_info_liste
+SI_X_SPELLFATIGUE skill_info_liste
+SI_SKILLLEARN skill_info_liste
+SI_LEARN_ATTRIBUTE skill_info_liste
+SI_SKILLARG skill_info_liste
+SI_SKILLRESTR_USE skill_info_liste
+SI_SKILLRESTR_LEARN skill_info_liste
+SI_SKILLINFO skill_info_liste
+SI_SKILLINFO_LONG skill_info_liste
+SI_SKILLDAMAGE skill_info_liste
+SI_SKILLDAMAGE_BY_ROW skill_info_liste
+SI_SPELL skill_info_liste
+SI_COLLATERAL_DAMAGE skill_info_liste
+SI_NUMBER_ENEMIES skill_info_liste
+SI_NUMBER_FRIENDS skill_info_liste
+SI_DISTANCE skill_info_liste
+SI_WIDTH skill_info_liste
+SI_DEPTH skill_info_liste
+SI_SKILLHEAL skill_info_liste
+SI_USR skill_info_liste
+SI_PREPARE_TIME skill_info_liste
+SI_ATTACK_BUSY_MSG skill_info_liste
+SI_NO_ATTACK_BUSY skill_info_liste
+SI_ATTACK_BUSY_AMOUNT skill_info_liste
diff --git a/doc/props/P_ABILITIES b/doc/props/P_ABILITIES
new file mode 100644
index 0000000..b82a0f6
--- /dev/null
+++ b/doc/props/P_ABILITIES
@@ -0,0 +1,9 @@
+NAME:
+    P_ABILITIES                   "abilities"                   
+
+DEFINIERT IN:
+    /sys/living/attributes.h
+
+BESCHREIBUNG:
+     *** OBSOLET! ***
+     Siehe P_NEWSKILLS.
diff --git a/doc/props/P_AC b/doc/props/P_AC
new file mode 100644
index 0000000..c62d786
--- /dev/null
+++ b/doc/props/P_AC
@@ -0,0 +1,28 @@
+P_AC
+
+NAME:
+     P_AC "ac"
+
+DEFINIERT IN:
+     <armour.h>
+
+BESCHREIBUNG:
+     Diese Property beschreibt die Ruestungsklasse (engl: armour class),
+     also den Schutz, den die Ruestung dem Traeger verleiht. Je hoeher der
+     Wert (als Zahl), um so besser ist die Ruestung. Negative Werte bewirken
+     negativen Schutz, d.h. der Schaden wird vergroessert statt verringert.
+
+BEMERKUNGEN:
+     Query- und Setmethoden auf P_AC sollten unbedingt vermieden werden. Sie
+     fuehren in der Regel zu massiven Inkonsistenzen im Mechanismus der
+     Ruestungsbeschaedigung und -reparatur.
+     Fuer jeden Ruestungstyp ist in <combat.h> eine Obergrenze definiert,
+     die man nicht ueberschreiten darf.
+     Ruestungen vom Typ AT_MISC haben immer AC 0 und werden mit keinen 
+     hoeheren Werten genemigt.
+
+SIEHE AUCH:
+     /std/armour.c, P_DAMAGED, Damage() P_TOTAL_AC
+
+----------------------------------------------------------------------------
+02.10.2007, Zesstra
diff --git a/doc/props/P_ACCEPT_PEACE b/doc/props/P_ACCEPT_PEACE
new file mode 100644
index 0000000..07b63a0
--- /dev/null
+++ b/doc/props/P_ACCEPT_PEACE
@@ -0,0 +1,18 @@
+PROPERTY
+     P_ACCEPT_PEACE                           "accept_peace"
+
+DEFINIERT IN 
+	/sys/combat.h
+
+BESCHREIBUNG
+	Mittels setzen Dieser Prop lassen sich leicht NPCs bauen,
+	die von jedem zu befrieden sind. Wenn die Property == 1 ist,
+	ist der NPC immer wieder befriedbar, sonst fuehrt der NPC das
+	uebliche Verhalten aus.
+
+SIEHE AUCH
+  QueryPacify(),
+  P_PEACE_HISTORY
+
+LETZTE AENDERUNG
+01.05.2008, Zesstra
diff --git a/doc/props/P_ACHATS b/doc/props/P_ACHATS
new file mode 100644
index 0000000..4097620
--- /dev/null
+++ b/doc/props/P_ACHATS
@@ -0,0 +1,8 @@
+NAME:
+    P_ACHATS                      "achats"                      
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Chats, die das Monster im Kampf ausgibt.
diff --git a/doc/props/P_ACHAT_CHANCE b/doc/props/P_ACHAT_CHANCE
new file mode 100644
index 0000000..9ccdf16
--- /dev/null
+++ b/doc/props/P_ACHAT_CHANCE
@@ -0,0 +1,8 @@
+NAME:
+    P_ACHAT_CHANCE                "achat_chance"                
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wahrscheinlichkeit fuer die Attack-Chat-Ausgabe.
diff --git a/doc/props/P_ACTUAL_NOTIFY_FAIL b/doc/props/P_ACTUAL_NOTIFY_FAIL
new file mode 100644
index 0000000..435a646
--- /dev/null
+++ b/doc/props/P_ACTUAL_NOTIFY_FAIL
@@ -0,0 +1,27 @@
+********************** VERALTETE PROPERTY *********************************
+NAME:
+     P_ACTUAL_NOTIFY_FAIL          "actual_notify_fail"          
+
+DEFINIERT IN:
+     /sys/player.h
+
+ACHTUNG:
+     Diese Prop wird nicht mehr gesetzt (und auch nicht mehr abgefragt), da LD
+     eine efun hat, um das Objekt zu ermitteln, was als letztes ein
+     notify_fail() gesetzt hat, ein Speichern im Spieler also voellig
+     ueberfluessig ist.
+
+BESCHREIBUNG:
+     Ist im Spielerobjekt  gesetzt und enthaelt das Objekt, welches zuletzt
+     eine Fehlermeldung mit notify_fail()/_notify_fail() erfolgreich
+     waehrend des aktuellen Kommandos abgespeichert hat.
+
+BEMERKUNGEN:
+     Dient dazu, bei _notify_fail() zu ueberpruefen, ob schon vorher eine
+     Fehlermeldung gesetzt wurde.
+
+SIEHE AUCH:
+     AddCmd(), add_action()
+     notify_fail(), _notify_fail()
+
+10.03.2007, Zesstra
diff --git a/doc/props/P_ADJECTIVES b/doc/props/P_ADJECTIVES
new file mode 100644
index 0000000..3b44a4f
--- /dev/null
+++ b/doc/props/P_ADJECTIVES
@@ -0,0 +1,22 @@
+P_ADJECTIVES
+
+NAME:
+     P_ADJECTIVES "adjectives"
+
+DEFINIERT IN:
+     <thing/description.h>
+
+BESCHREIBUNG:
+     Hier steht ein Array von Strings, welche die Identifizierung des
+     Objektes ergaenzen. Die Verwaltung erfolgt ueber die Funktionen
+     AddAdjective() und RemoveAdjective().
+
+BEMERKUNGEN:
+     Man sollte an dieser Property nicht "von Hand" herumfummeln, sondern
+     immer die zugehoerigen Funktionen benutzen!
+
+SIEHE AUCH:
+     /std/thing/description.c, AddAdjective(), RemoveAdjective()
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 20:22:24 1996 by Wargon
diff --git a/doc/props/P_AERIAL_HELPERS b/doc/props/P_AERIAL_HELPERS
new file mode 100644
index 0000000..2606884
--- /dev/null
+++ b/doc/props/P_AERIAL_HELPERS
@@ -0,0 +1,45 @@
+P_AERIAL_HELPERS
+
+NAME:
+     P_AERIAL_HELPERS "lib_p_aerial_helpers"
+
+DEFINIERT IN:
+     <living/helpers.h>
+
+BESCHREIBUNG:
+     Diese Property kann in allen Lebewesen abgefragt werden, um die Objekte
+     zu ermitteln, die fuer die Unterstuetzung beim Fliegen/Segeln bei diesem 
+     Lebewesen registriert haben. Die Daten werden als Mapping der folgenden
+     Form zurueckgeliefert:
+     ([ Objekt : Rueckgabewert von dessen Callback-Methode ])
+     Eine Erlaeuterung dazu findet sich in der Dokumentation zu 
+     RegisterHelperObject().
+
+BEMERKUNGEN:
+     Diese Property kann nur abgefragt werden.
+     Es ist erwuenscht, dass entsprechende, neu geschaffene Stellen jegliche 
+     Helfer akzeptieren, deren Callback-Methode >0 zurueckgibt.
+
+BEISPIEL:
+     Um zu ermitteln, ob der Spieler mindestens ein Objekt bei sich hat, das 
+     beim Fliegen hilft, sucht man alle Objekte aus dem Mapping heraus, die
+     einen Wert >0 eingetragen haben und prueft deren Anzahl:
+
+     mapping aerial = this_player()->QueryProp(P_AERIAL_HELPERS);
+     object* helpers = filter( aerial, function int (object h) {
+                         return (aerial[h]>0); });
+     if ( sizeof(helpers) ) {
+       tell_object(this_player(), "Du erhebst Dich mit Hilfe "+
+         helpers[0]->name(WESSEN,1)+" elegant in die Luefte.\n");
+     }
+     else {
+       tell_object(this_player(), "Du hast nichts zum Fliegen bei Dir.\n");
+     }
+
+SIEHE AUCH:
+     Methoden:    RegisterHelperObject(L), UnregisterHelperObject(L)
+     Properties:  P_HELPER_OBJECTS, P_AQUATIC_HELPERS
+
+----------------------------------------------------------------------------
+12.03.2016, Arathorn
+
diff --git a/doc/props/P_AGE b/doc/props/P_AGE
new file mode 100644
index 0000000..ad6388a
--- /dev/null
+++ b/doc/props/P_AGE
@@ -0,0 +1,8 @@
+NAME:
+    P_AGE                         "age"                         
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Alter des Spielers in Heart-Beats (1 HB == 2 Sekunden)
diff --git a/doc/props/P_AGGRESSIVE b/doc/props/P_AGGRESSIVE
new file mode 100644
index 0000000..b10d97e
--- /dev/null
+++ b/doc/props/P_AGGRESSIVE
@@ -0,0 +1,39 @@
+NAME:
+    P_AGGRESSIVE                  "aggressive"                  
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+	Gesetzt, wenn das Wesen von sich aus Angriffe startet.
+
+	Ueblicherweise nimmt man als Wert 1, man kann jedoch auch
+	einen kleineren Wert nehmen wenn es nur mit einer bestimmten
+	Wahrscheinlichkeit automatisch angreifen soll.
+
+	Der Wert von Spieler und Monster wird addiert, um zu entscheiden,
+	ob ein Spieler angegriffen werden soll,	man kann P_AGGRESSIVE
+	also auch bei Spielern setzen, so dass sie von allen Monstern
+	angegriffen werden.
+
+	Bei Monstern (und NUR bei diesen) kann man hier auch ein Mapping
+	angeben, das als Keys Namen von Properties des Spielers enthaelt
+	und als Values Mappings, in denen steht welcher Wert bei welchen
+	Wert fuer die Property genommen werden soll (Beispiele folgen).
+	Mit Key 0 kann man einen Default-Wert (sowohl in inneren Mappings
+	wie auch im aeusseren Mapping) festlegen. Default-Werte werden
+	genommen, falls keine anderen gesetzt sind, also Vorsicht mit
+	0-Eintraegen (Tip: 0.0 ist in LPC ungleich 0).
+	Bei mehreren Properties werden alle gesetzten Werte gemittelt.
+
+BEISPIELE:
+	SetProp(P_AGGRESSIVE,([P_RACE:(["Zwerg":1, "Elf":0.0, 0:0.5])]))
+	Zwerge werden immer automatisch angegriffen, Elfen nie und
+	alle anderen mit 50% Wahrscheinlichkeit.
+	Man beachte, dass hier 0.0 genommen werden musste anstelle von 0,
+	weil sonst Elfen auch 50% Wahrscheinlichkeit bekommen haetten.
+
+	SetProp(P_AGGRESSIVE,([P_RACE:(["Zwerg":0.3]),
+	                       P_GUILD:(["Chaos":0.7])]))
+	Zwerge werden mit 30% Wahrscheinlichkeit angegriffen,
+	Chaoten mit 70% und Zwerg-Chaoten mit 50%.
diff --git a/doc/props/P_ALCOHOL b/doc/props/P_ALCOHOL
new file mode 100644
index 0000000..63005b7
--- /dev/null
+++ b/doc/props/P_ALCOHOL
@@ -0,0 +1,22 @@
+NAME:
+     P_ALCOHOL			"alcohol"
+
+DEFINIERT IN:
+     /sys/living/life.h
+
+BESCHREIBUNG:
+
+     - Lebewesen
+       Numerischer Wert fuer den Grad der Betrunkenheit eines Lebewesens.
+       Der maximale Wert steht in P_MAX_ALCOHOL.
+
+     - Speisen/Kneipen
+       Numerischer Wert fuer den Grad, den eine Portion der Speise den
+       Konsumenten betrunken macht
+
+SIEHE AUCH:
+	P_MAX_ALCOHOL, P_ALCOHOL_DELAY, consume,
+	P_FOOD, P_DRINK, wiz/food, 
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_ALCOHOL_DELAY b/doc/props/P_ALCOHOL_DELAY
new file mode 100644
index 0000000..4c6d2c1
--- /dev/null
+++ b/doc/props/P_ALCOHOL_DELAY
@@ -0,0 +1,10 @@
+NAME:
+    P_ALCOHOL_DELAY                 "alcohol_delay"                     
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Anzahl der heart_beats, bis P_ALCOHOL um einen Punkt sinkt.
+     Aenderungen dieser Property in Spielern beduerfen der 
+     Genehmigung des EM fuer Balance.
diff --git a/doc/props/P_ALC_FULL_MSG b/doc/props/P_ALC_FULL_MSG
new file mode 100644
index 0000000..bd84a86
--- /dev/null
+++ b/doc/props/P_ALC_FULL_MSG
@@ -0,0 +1,24 @@
+NAME:
+     P_ALC_FULL_MSG                "std_food_alc_full_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Konsumenten, wenn Alkohol konsumiert werden soll,
+     obwohl dieser nicht mehr Alkohol vertraegt.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "Soviel Alkohol vertraegst Du nicht mehr."
+
+SIEHE AUCH:
+     P_ALCOHOL, P_MAX_ALCOHOL, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_ALIGN b/doc/props/P_ALIGN
new file mode 100644
index 0000000..f1d3465
--- /dev/null
+++ b/doc/props/P_ALIGN
@@ -0,0 +1,17 @@
+NAME:
+    P_ALIGN                       "align"                       
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Numerischer Wert fuer Gut- oder Boesheit des Wesens.
+
+     Kann Werte von -1000 (Boese wie der Teufel hoechstpersoenlich)
+     bis +1000 (Jesus, bist Du's ?) annehmen.
+
+     Werte ausserhalb dieser Skala werden zwar teilweise verwendet,
+     das Setzen derselben sollte jedoch UNBEDINGT unterbleiben.
+
+----------------------------------------------------------------------------
+Last modified: Sat Jul 12 17:00:00 by Mandragon
diff --git a/doc/props/P_ALLOWED_SHADOW b/doc/props/P_ALLOWED_SHADOW
new file mode 100644
index 0000000..39482fd
--- /dev/null
+++ b/doc/props/P_ALLOWED_SHADOW
@@ -0,0 +1,24 @@
+NAME:
+    P_ALLOWED_SHADOW              "allowed_shadow"
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+
+     Normalerweise koennen nur Shadows an Spieler gebunden werden, die in 
+     /std/player/shadows/ liegen. 
+     
+     Zu Testzwecken kann in dieser Property der Pfad eines Shadows eingetragen
+     werden. Damit wird die oben beschriebene Regel fuer diesen Spieler und 
+     diesen Shadow ausser Kraft gesetzt.
+
+BEMERKUNG: 
+
+     Der Spieler muss ein Testspieler sein. Ansonsten wird diese Property
+     ignoriert.
+
+     Die Property ist secured gesetzt. Das heisst, nur EM+ koennen
+     diese Property setzen und loeschen.
+------------------------------------------------------------------------------
+Last modified: Sun Mar 21 00:27:46 2004 by Vanion
diff --git a/doc/props/P_AMMUNITION b/doc/props/P_AMMUNITION
new file mode 100644
index 0000000..f8903af
--- /dev/null
+++ b/doc/props/P_AMMUNITION
@@ -0,0 +1,42 @@
+P_AMMUNITION
+
+NAME:
+    P_AMMUNITION     "munition"
+
+DEFINIERT IN:
+    <combat.h>
+
+BESCHREIBUNG:
+    Enthaelt die fuer eine Waffe gueltige Munition als String. Die
+    Munition muss diesen String als ID besitzen.
+
+    Fuer die Munitionsobjekte gilt:
+    * es kann ein Skill am Spieler definiert werden, dieser wirkt dann
+      zusaetzlich zum generellen SK_SHOOT-Skill.
+    * sie koennen eine HitFunc besitzten, die beim Schuss abgefragt wird
+
+BEMERKUNGEN:
+    Bitte das #define MUN_MISC(x) benutzen. Munition sollte auch immer
+    in Deutsch und Plural angegeben werden, da P_AMMUNITION direkt
+    fuer Ausgaben an den Spieler ausgewertet wird.
+
+    Momentan sind vier Munitionsarten in der combat.h vordefiniert:
+    MUN_ARROW, MUN_STONE, MUN_BOLT, MUN_MISC
+
+BEISPIELE:
+    // fuer ein kleines Blasrohr im Blasrohr
+    SetProp(P_AMMUNITION, MUN_MISC("Erbsen"));
+
+    // Entsprechend in der Munition:
+    AddId(MUN_MISC("Erbsen"));
+
+SIEHE AUCH:
+    Generell:  P_SHOOTING_WC, P_STRETCH_TIME
+    Methoden:  FindRangedTarget(L), shoot_dam(L), cmd_shoot(L)
+    Gebiet:    P_RANGE, P_SHOOTING_AREA, P_TARGET_AREA
+    Waffen:    P_WEAPON_TYPE, P_WC, P_EQUIP_TIME, P_NR_HANDS
+    Kampf:     Attack(L), Defend(L), P_DISABLE_ATTACK, P_ATTACK_BUSY
+    Team:      PresentPosition(L)
+    Sonstiges: fernwaffen
+
+29.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_AMOUNT b/doc/props/P_AMOUNT
new file mode 100644
index 0000000..a44e45a
--- /dev/null
+++ b/doc/props/P_AMOUNT
@@ -0,0 +1,8 @@
+NAME:
+    P_AMOUNT                      "amount"                      
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Anzahl der Objekte, fuer die das Objekt steht.
diff --git a/doc/props/P_AQUATIC_HELPERS b/doc/props/P_AQUATIC_HELPERS
new file mode 100644
index 0000000..33a07ab
--- /dev/null
+++ b/doc/props/P_AQUATIC_HELPERS
@@ -0,0 +1,46 @@
+P_AQUATIC_HELPERS
+
+NAME:
+     P_AQUATIC_HELPERS "lib_p_aquatic_helpers"
+
+DEFINIERT IN:
+     <living/helpers.h>
+
+BESCHREIBUNG:
+     Diese Property kann in allen Lebewesen abgefragt werden, um die Objekte
+     zu ermitteln, die fuer die Unterstuetzung beim Tauchen bei diesem 
+     Lebewesen registriert haben. Die Daten werden als Mapping der folgenden
+     Form zurueckgeliefert:
+     ([ Objekt : Rueckgabewert von dessen Callback-Methode ])
+     Eine Erlaeuterung dazu findet sich in der Dokumentation zu 
+     RegisterHelperObject().
+
+BEMERKUNGEN:
+     Diese Property kann nur abgefragt werden.
+     Es ist erwuenscht, dass entsprechende, neu geschaffene Stellen jegliche 
+     Helfer akzeptieren, deren Callback-Methode >0 zurueckgibt.
+
+BEISPIEL:
+     Um zu ermitteln, ob der Spieler mindestens ein Objekt bei sich hat, das 
+     beim Tauchen hilft, sucht man alle Objekte aus dem Mapping heraus, die
+     einen Wert >0 eingetragen haben und prueft deren Anzahl:
+
+     mapping aquatic = this_player()->QueryProp(P_AQUATIC_HELPERS);
+     object* helpers = filter( aquatic, function int (object h) {
+                         return (aquatic[h]>0); });
+     if ( sizeof(helpers) ) {
+       tell_object(this_player(), "Du stuerzt Dich in die Fluten und "
+         "stellst ueberrascht fest, dass Du mit Hilfe "+
+         helpers[0]->name(WESSEN,1)+" sogar unter Wasser atmen kannst!\n");
+     }
+     else {
+       tell_object(this_player(), "Du hast nichts zum Tauchen bei Dir.\n");
+     }
+
+SIEHE AUCH:
+     Methoden:    RegisterHelperObject(L), UnregisterHelperObject(L)
+     Properties:  P_HELPER_OBJECTS, P_AERIAL_HELPERS
+
+----------------------------------------------------------------------------
+06.04.2016, Arathorn
+
diff --git a/doc/props/P_ARMOURS b/doc/props/P_ARMOURS
new file mode 100644
index 0000000..3156bf6
--- /dev/null
+++ b/doc/props/P_ARMOURS
@@ -0,0 +1,25 @@
+P_ARMOURS
+
+NAME:
+     P_ARMOURS                     "armours"
+
+DEFINIERT IN:
+     <living/combat.h>
+
+BESCHREIBUNG:
+     Array mit den getragenen Schutzbekleidungen des Lebewesen.
+
+     Bitte nach Moeglichkeit davon absehen, diese Property zu beschreiben, da
+     es hierbei zu Inkonsistenzen kommen kann.
+     
+     Falls ihr die Ruestungen des Lebewesens, ggf. mit bestimten Kriterien,
+     ermitteln wollt, benutzt hierfuer bitte die Funktion FilterArmours()
+     statt selber ueber dieses Array zu laufen.
+
+SIEHE AUCH:
+     Verwandt:		QueryArmourByType(L), P_WEAPON, FilterClothing(), 
+                  FilterArmours()
+     Ruestungen:	P_AC, P_ARMOUR_TYPE, P_NR_HANDS
+     Sonstiges:		P_EQUIP_TIME, P_LAST_USE
+
+14.03.2009, Zesstra
diff --git a/doc/props/P_ARMOUR_TYPE b/doc/props/P_ARMOUR_TYPE
new file mode 100644
index 0000000..35978f2
--- /dev/null
+++ b/doc/props/P_ARMOUR_TYPE
@@ -0,0 +1,46 @@
+P_ARMOUR_TYPE
+
+NAME:
+     P_ARMOUR_TYPE "armour_type"
+
+DEFINIERT IN:
+     <armour.h>
+
+BESCHREIBUNG:
+     In dieser Property wird der Typ einer Ruestung festgehalten. Man sollte
+     hier nur die in <combat.h> definierten Konstanten verwenden:
+
+        AT_AMULET     Amulett
+        AT_ARMOUR     Ruestung
+        AT_BELT       Guertel
+        AT_BOOT       Schuhe
+        AT_CLOAK      Umhang
+        AT_GLOVE      Handschuhe
+        AT_HELMET     Helm
+        AT_QUIVER     Koecher
+        AT_RING       Ring
+        AT_SHIELD     Schild
+        AT_TROUSERS   Hosen
+        AT_MISC       Sonstiges
+
+     Der Ruestungstyp AT_MISC ist schnoedem Tand und anderem nutzlosen
+     Kram vorbehalten. Auf keinen Fall darf eine AT_MISC-Ruestung ueber
+     eine AC > 0 verfuegen noch irgendwie kampfrelevante Bedeutung be-
+     sitzen. Ruestungen des Typs AT_MISC, die KEINE DefendFunc benoetigen,
+     muessen mittels /std/clothing als einfaches Kleidungsstueck realisiert
+     werden.
+
+BEMERKUNGEN:
+     Die P_AC wird bei AT_MISC-Ruestungen gar nicht erst ausgewertet.
+     DefendFuncs werden zwar ausgewertet, aber bitte ueberlegt euch gut, ob
+     ihr sie braucht (Rechenzeit im Kampf ist kritisch!) und ob sie seitens 
+     der Balance in eurem Fall erlaubt sind.
+
+SIEHE AUCH:
+     Verwandt:          QueryArmourByType(L), P_WEAPON
+     Ruestungen:        P_AC, P_NR_HANDS (Schilde)
+     Sonstiges:         P_EQUIP_TIME, P_LAST_USE
+     Code:              /std/armour.c, /std/clothing.c
+     Gildenergaenzung:  P_GLOVE_FINGERLESS
+
+27. Mai 2015, Arathorn
diff --git a/doc/props/P_ARRIVEMSG b/doc/props/P_ARRIVEMSG
new file mode 100644
index 0000000..02d5759
--- /dev/null
+++ b/doc/props/P_ARRIVEMSG
@@ -0,0 +1,8 @@
+NAME:
+    P_ARRIVEMSG                   "arrivemsg"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+     Meldung, wenn der Transporter anlegt.
diff --git a/doc/props/P_ARTICLE b/doc/props/P_ARTICLE
new file mode 100644
index 0000000..1517865
--- /dev/null
+++ b/doc/props/P_ARTICLE
@@ -0,0 +1,15 @@
+NAME:
+    P_ARTICLE                     "article"                     
+
+DEFINIERT IN:
+    /sys/thing/language.h
+
+BESCHREIBUNG:
+     Gibt an, ob in der Beschreibung ein Artikel ausgegeben werden soll
+     oder nicht.
+
+     Wenn ein Artikel angegeben werden soll, so wird 1 gesetzt, sonst 0.
+     Diese Property ist aus historischen Gruenden auf 1 voreingestellt
+     und intern invertiert. (d.h., beim Auslesen per Query kommt als 
+     Ergebnis genau das falsche heraus). Bitte beachtet das bei Set- bzw.
+     Query-Funktionen.
\ No newline at end of file
diff --git a/doc/props/P_ATTACK_BUSY b/doc/props/P_ATTACK_BUSY
new file mode 100644
index 0000000..b55dc5b
--- /dev/null
+++ b/doc/props/P_ATTACK_BUSY
@@ -0,0 +1,44 @@
+NAME:
+    P_ATTACK_BUSY                 "attack_busy"                 
+
+DEFINIERT IN:
+    /sys/living/combat.h
+
+BESCHREIBUNG:
+    Ueber diese Property kann festgestellt werden, ob ein Spieler noch 
+    Spezialwaffen (zB Flammenkugel) einsetzen kann.
+    
+    Ist der Wert bei Abfrage ungleich 0, dann darf der Spieler in dieser
+    Runde keine Aktion mehr durchfuehren. Mit SetProp(P_ATTACK_BUSY, 1)
+    wird eine Aktion verbraucht.
+
+    Intern wird relativ fein gerechnet, ein SetProp(P_ATTACK_BUSY, x)
+    wird in das Abziehen von x*100 Punkten umgerechnet. Der Wert freier
+    Aktionen pro Runde berechnet sich wie folgt:
+    
+    Spieler: 100 + QuerySkillAttribute(SA_SPEED)
+    Seher:   Spieler + 200 + QueryProp(P_LEVEL)
+
+    Das Maximum liegt bei 500.
+    Damit betraegt die Anzahl der moeglichen Aktionen pro Runde: Wert/100,
+    also maximal 5 Aktionen pro Runde.
+
+    Zaubersprueche zaehlen im Normalfall auch als eine Aktion.
+
+BEMERKUNGEN:
+    Benutzt man P_ATTACK_BUSY fuer eine sich nicht sofort verbrauchende
+    Sache, kann ein Seher dieses Objekt im Normalfall dreimal pro Runde
+    benutzen. Wenn ungewollt, muss das ueber einen Zeitmarker selbst
+    verhindert werden.
+    
+BEISPIELE:
+    (Code eines Objektes ist in
+     /doc/beispiele/testobjekte/attack_busy_sensitive_testobj.c)
+    // einfacher Test auf ATTACK_BUSY und anschliessendes Setzen
+    if (this_player()->QueryProp(P_ATTACK_BUSY)) {
+      write("Du hast dafuer momentan einfach nicht mehr die Puste.\n");
+      return 1;
+    }
+    this_player()->SetProp(P_ATTACK_BUSY, 1);
+
+7. Mar 2011 Gloinson
diff --git a/doc/props/P_ATTRIBUTES b/doc/props/P_ATTRIBUTES
new file mode 100644
index 0000000..29da911
--- /dev/null
+++ b/doc/props/P_ATTRIBUTES
@@ -0,0 +1,58 @@
+NAME:
+	P_ATTRIBUTES			"attributes"
+
+DEFINIERT IN:
+	/sys/living/attributes.h
+
+BESCHREIBUNG:
+	Diese Property enthaelt ein Mapping mit den Attributen des
+	Lebewesens. Die Schluessel kennzeichnen hierbei das jeweilige
+	Attribut. Die verschiedenen Standardattribute findet man in
+	/sys/living/attributes.h, welche derzeit folgende Moeglichkeiten
+	bieten:	- A_STR (Kraft)
+		- A_INT (Intelligenz)
+		- A_DEX (Geschick)
+		- A_CON (Konstitution)
+	Sie werden automatisch an verschiedenen Stellen in der MUDLib
+	ausgewertet, zum Beispiel bestimmt A_INT die maximal moeglichen
+	Konzentrationspunkte und A_CON die maximal moeglichen Lebenspunkte.
+
+BEMERKUNGEN:
+        Keine echte Property, _query_attributes() und _set_attributes() sind 

+        in /std/living/attributes.c implementiert.
+
+	Es bietet sich an, zum Erfragen der Attributwerte die Funktion
+	QueryAttribute() zu nutzen, da es auch moegliche Offsets gibt,
+	so beispielsweise ueber die Properties P_ATTRIBUTES_OFFSETS bzw.
+	P_ATTRIBUTES_MODIFIER im Lebewesen selbst, oder auch ueber
+	P_X_ATTR_MOD bzw. P_M_ATTR_MOD in Objekten im Lebewesen.
+	Kurzfristige zeit- oder objektgebundene Attributveraenderungen
+	koennen ueber die Property P_TIMED_ATTR_MOD realisiert werden.
+
+	Es gibt auch zahlreiche andere Dienstfunktionen fuer diesen sehr
+	balancekritischen Bereich, siehe unten.
+
+BEISPIEL:
+	Ein moegliches Ergebnis fuer einen frischen Level 1 Spieler waere:
+	  QueryProp(P_ATTRIBUTES);
+	  Ergebnis: (["int":1,"con":1,"str":1,"dex":1])
+	Hinzu kommen eventuell moegliche Rassenboni, die mittels
+	P_ATTRIBUTE_OFFSETS realisiert werden, Zwerge sind beispielsweise
+	recht stark:
+	  QueryProp(P_ATTRIBUTES_OFFSETS);
+	  Ergebnis: (["int":1,"con":1,"str":1,"dex":3])
+	Jetzt bekaeme man (sofern keine weiteren Offsets realisiert sind)
+	mittels QueryAttribute() insgesamt:
+	  QueryAttribute(A_DEX);
+	  Ergebnis: 4
+
+SIEHE AUCH:
+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),
+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),
+	SetTimedAttrModifier(), QueryTimedAttrModifier(),
+	DeleteTimedAttrModifier(),
+	P_ATTRIBUTES_OFFSETS, P_ATTRIBUTES_MODIFIER,P_TIMED_ATTR_MOD,
+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c
+
+----------------------------------------------------------------------------
+Last modified: Tue Jul 27 20:00:20 2004 by Muadib
diff --git a/doc/props/P_ATTRIBUTES_MODIFIER b/doc/props/P_ATTRIBUTES_MODIFIER
new file mode 100644
index 0000000..f5ba513
--- /dev/null
+++ b/doc/props/P_ATTRIBUTES_MODIFIER
@@ -0,0 +1,56 @@
+NAME:
+    P_ATTRIBUTES_MODIFIER         "attributes_modifier"
+
+DEFINIERT IN:
+    /sys/living/attributes.h
+
+BESCHREIBUNG:
+    In dieser Property werden Attribut-Modifikatoren gespeichert, die
+    laengere Zeit wirksam sein sollen, tlw. auch ueber einen Reboot
+    hinweg.
+    Intern werden die Modifikatoren in einem Mapping der Form
+
+        ([ Setzer-Key : ([ A_xy : Wert, ... ]) , ... ])
+
+    gespeichert. Das Setzen folg hingegen in der Form
+
+        spieler->SetProp(P_ATTRIBUTES_MODIFIER, ([ A_xy : Wert, ... ]));
+    oder
+        spieler->SetProp(P_ATTRIBUTES_MODIFIER, ({ Setzer-Key, ([ ... ]) }));
+
+    Bei der ersten Variante wird hierbei der Filename des setzenden Objektes
+    als Setzer-Key genommen.
+    Es koennen also durchaus von mehreren Objekten Modifier gesetzt werden.
+    Bekannte Modifier sind:
+
+        #death      Attribut-Abzug durch Todesfolgen      (Mudlib)
+        #drain      Statabzug durch NPCs                  (Paracelsus)
+        #frosch     Staerken-Abzug bei Froeschen          (Mudlib)
+
+BEMERKUNGEN:
+    Keine echte Property, _query_attributes_modifier() und
+    _set_attributes_modifier() sind in /std/living/attributes.c
+    implementiert
+    - SetProp/QueryProp nutzen!
+    - Wenn ein Modifier nicht mehr gebracht wird, nicht die Attributswerte auf
+      0 setzen, sondern den ganzen Eintrag! also:
+      SetProp(P_ATTRIBUTES_MODIFIER, ([]) );
+      oder: SetProp(P_ATTRIBUTES_MODIFIER, 0 ); 
+      aber nicht: SetProp(P_ATTRIBUTES_MODIFIER, ([A_STR:0]));
+
+BEISPIELE:
+    // ein Bonus ... 'ende'-fest (muss also per uid gesichert werden)
+    player->SetProp(P_ATTRIBUTES_MODIFIER,
+                    ({"g_klerus_segen", ([A_CON:5, A_INT:5])}));
+    ...
+    player->SetProp(P_ATTRIBUTES_MODIFIER, ({"g_klerus_segen", 0}));
+
+SIEHE AUCH:
+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),
+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),
+	SetTimedAttrModifier(), QueryTimedAttrModifier(),
+	DeleteTimedAttrModifier(),
+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,
+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c
+----------------------------------------------------------------------------
+Last modified: Tue Jul 27 20:00:20 2004 by Muadib
diff --git a/doc/props/P_ATTRIBUTES_OFFSETS b/doc/props/P_ATTRIBUTES_OFFSETS
new file mode 100644
index 0000000..3ebe2b7
--- /dev/null
+++ b/doc/props/P_ATTRIBUTES_OFFSETS
@@ -0,0 +1,27 @@
+NAME:
+	P_ATTRIBUTES_OFFSETS		"attributes_offsets"
+
+DEFINIERT IN:
+	/sys/living/attributes.h
+
+BESCHREIBUNG:
+	Diese Property enthaelt ein Mapping mit Offsets, die zu den
+	Attributen eine Lebewesens addiert werden. Diese koennen auch
+	negativ sein! Realisiert werden damit beispielsweise Rassenboni.
+	Es gibt noch weitere Moeglichkeiten, Attributoffsets anzugeben.
+	Fuer weiteres siehe P_ATTRIBUTES.
+
+BEMKERUNGEN:
+        Keine echte Property, _query_attributes_offsets() und 

+        _set_attributes_offsets() sind in /std/living/attributes.c 

+        implementiert.
+
+SIEHE AUCH:
+	QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),
+	SetAttribute(), SetRealAttribute(), UpdateAttributes(),
+	SetTimedAttrModifier(), QueryTimedAttrModifier(),
+	DeleteTimedAttrModifier(),
+	P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_TIMED_ATTR_MOD,
+	P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c
+----------------------------------------------------------------------------
+Last modified: Tue Jul 27 20:00:20 2004 by Muadib
diff --git a/doc/props/P_AUTH_INFO b/doc/props/P_AUTH_INFO
new file mode 100644
index 0000000..5ca65c5
--- /dev/null
+++ b/doc/props/P_AUTH_INFO
@@ -0,0 +1,8 @@
+NAME:
+    P_AUTH_INFO                   "auth_info"                   
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Username des Spielers, wenn bei ihm ein AUTHD laeuft
diff --git a/doc/props/P_AUTOLOAD b/doc/props/P_AUTOLOAD
new file mode 100644
index 0000000..6ea69c9
--- /dev/null
+++ b/doc/props/P_AUTOLOAD
@@ -0,0 +1,15 @@
+NAME:
+    P_AUTOLOAD                    "autoload"                    
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Mapping mit der Menge der Autoloadobjekte und den zugeh.
+     Properties.
+
+BEMERKUNGEN:
+     Funktioniert momentan nicht. Die Methode wurde entfernt. Doku bleibt
+     hier bis der Fall geklaert ist. (Stand 27.Aug 2006)
+
+27.Aug 2006 Gloinson
diff --git a/doc/props/P_AUTOLOADOBJ b/doc/props/P_AUTOLOADOBJ
new file mode 100644
index 0000000..32b433d
--- /dev/null
+++ b/doc/props/P_AUTOLOADOBJ
@@ -0,0 +1,119 @@
+NAME:
+    P_AUTOLOADOBJ                 "autoloadobj"
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Hiermit kann prinzipiell angegeben werden ob ein Objekt ueber das
+     Ausloggen eines Spielers (Reboot/ende) behalten werden soll.
+
+     Als Inhalt der Property koennen permanente Eigenschaften des Objektes
+     angegeben werden.
+     Beim Einloggen wird das Objekt neu erzeugt und P_AUTOLOADOBJ auf die
+     gespeicherten Werte gesetzt. Die Werte muessen allerdings selbst
+     verwaltet werden.
+
+     Bitte geht nicht davon aus, dass es waehrend des Setzens/Abfragens dieser
+     Prop einen this_player() oder ein this_interactive() geben muss.
+     Speziell ist this_interactive() nicht == /secure/login!
+     Ebenfalls muss das Objekt beim Setzen/Abfragen nicht in einem Spieler
+     sein.
+
+BEMERKUNGEN:
+     Autoloadobjekte werden beim Ausloggen nicht fallengelassen!
+
+BEISPIELE:
+     ## Variante 1: simples Objekt, bleibt einfach nur erhalten,
+     ##             Variablen werden nicht gesichert ##
+     void create() {
+      ...
+      SetProp(P_AUTOLOADOBJ,1);
+      ...
+     }
+
+
+     ## Variante 2: Speicherung mehrerer Variablen ueber
+     ##             P_AUTOLOADOBJ (elegante Verwaltung)
+
+     // ein paar #defines fuer die Plaetze in der Speichervariablen
+     #define MY_AL_SHORT    0
+     #define MY_AL_ATTRM    1
+     #define MY_AL_OWNER    2
+     #define MY_AL_DESTRUCT 3
+
+     // die Variablen, die erhalten bleiben sollen
+     static object owner;
+     static int destruct_time;
+
+     // diese hier wird gerufen, wenn der Spieler gespeichert wird,
+     // wir packen also alle aktuellen Variablen in eine und geben die
+     // zum Speichern heraus ... wir nehmen hier ein Array (statt
+     // zB eines Mappings), weil das am wenigsten Platz braucht
+     static mixed* _query_autoloadobj() {
+      mixed *ret;
+      ret=allocate(4);
+      ret[MY_AL_SHORT] = QueryProp(P_SHORT);      // SHORT merken
+      ret[MY_AL_ATTRM] = QueryProp(P_M_ATTR_MOD); // einen Modifikator merken
+      ret[MY_AL_OWNER] = getuid(owner);           // ah, ein Besitzer!
+      ret[MY_AL_DESTRUCT]=destruct_time-time();   // und eine Lebensdauer!
+
+      return ret;
+
+      /*
+      // normalerweise wuerde man das einfach so schreiben:
+      return (({QueryProp(P_SHORT),
+                QueryProp(P_M_ATTR_MOD),
+                getuid(owner),
+                destruct_time-time()}));
+      */
+     }
+
+     // diese hier wird gerufen, wenn das Objekt neu im Spieler
+     // erzeugt wurde (Login), also packen wir das Speicherarray wieder
+     // aus und in alle entsprechenden Variablen
+     static mixed* _set_autoloadobj(mixed *new) {
+      // wenn das Format nicht mit dem oben uebereinstimmt ist was
+      // schiefgelaufen
+      if(pointerp(new) && !owner && sizeof(new)>4 &&
+         (owner=find_player(new[MY_AL_OWNER]))) {
+       // los, zuweisen!
+
+       SetProp(P_SHORT,      new[MY_AL_SHORT]);
+       SetProp(P_M_ATTR_MOD, new[MY_AL_ATTRM]);
+       destruct_time=        time()+new[MY_AL_DESTRUCT];
+
+       call_out(#'remove,new[3]);
+      } else call_out(#'remove,0);
+
+      return new;
+     }
+
+
+     ## Variante 3: und das gleiche mit Set/Querymethoden ##
+     // Prototypen fuer Set und Query-Methoden -> man Set
+     static mixed *my_query_autoloadobj();
+     static mixed *my_set_autoloadobj(mixed *new);
+
+     void create() {
+      // Binden der Methoden
+      Set(P_AUTOLOADOBJ, #'my_query_autoloadobj, F_QUERY_METHOD);
+      Set(P_AUTOLOADOBJ, #'my_set_autoloadobj, F_SET_METHOD);
+
+      // die werden nur von mir veraendert!
+      Set(P_AUTOLOADOBJ, PROTECTED, F_MODE_AS);
+      ...
+     }
+
+     static mixed *my_query_autoloadobj () {
+       // s.o.
+     }
+
+     static mixed *my_set_autoloadobj (mixed *new) {
+       // s.o.
+     }
+
+SIEHE AUCH:
+     P_AUTOLOAD, SetProp
+
+24.Aug.2006 Gloinson@MG
diff --git a/doc/props/P_AVATAR_URI b/doc/props/P_AVATAR_URI
new file mode 100644
index 0000000..3275399
--- /dev/null
+++ b/doc/props/P_AVATAR_URI
@@ -0,0 +1,22 @@
+NAME:
+    P_AVATAR_URI                    "p_lib_avataruri"
+
+DEFINIERT IN:
+    /sys/living/description.h
+
+BESCHREIBUNG:
+    Lebewesen speichern in der Prop P_AVATAR_URI eine URI (string), welche auf
+    ein Bild im Netz verweist, welches ein Client fuer dieses Lebewesen
+    anzeigen kann.
+    Spieler koennen diese Avatar-URI mit dem Befehl 'avatar' anzeigen,
+    aendern und loeschen.
+    Avatar-URIs anderer Spieler lassen sich mit 'finger -a' ausgeben.
+
+BEMERKUNGEN:
+    Diese Property kann nur vom Spieler oder einem EM modifiziert werden.
+
+SIEHE AUCH:
+    avatar
+
+LETZTER AENDERUNG:
+    03.9.2011, Zesstra
diff --git a/doc/props/P_AVERAGE_SIZE b/doc/props/P_AVERAGE_SIZE
new file mode 100644
index 0000000..4a61208
--- /dev/null
+++ b/doc/props/P_AVERAGE_SIZE
@@ -0,0 +1,8 @@
+NAME:
+    P_AVERAGE_SIZE                "average_size"                
+
+DEFINIERT IN:
+    /sys/player/description.h
+
+BESCHREIBUNG:
+     Durchschnittliche Groesse eines Wesens dieser Rasse (derzeit nur Player)
diff --git a/doc/props/P_AVERAGE_WEIGHT b/doc/props/P_AVERAGE_WEIGHT
new file mode 100644
index 0000000..18557cc
--- /dev/null
+++ b/doc/props/P_AVERAGE_WEIGHT
@@ -0,0 +1,8 @@
+NAME:
+    P_AVERAGE_WEIGHT                "average_weight"
+
+DEFINIERT IN:
+    /sys/player/description.h
+
+BESCHREIBUNG:
+     Durchschnittliche Gewicht eines Wesens dieser Rasse (derzeit nur Player)
diff --git a/doc/props/P_AWAY b/doc/props/P_AWAY
new file mode 100644
index 0000000..ba2c938
--- /dev/null
+++ b/doc/props/P_AWAY
@@ -0,0 +1,8 @@
+NAME:
+    P_AWAY                        "away"                        
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     String der ausgegeben wird, wenn man weg ist und eine Mitteilung bekommt.
diff --git a/doc/props/P_BAD_MSG b/doc/props/P_BAD_MSG
new file mode 100644
index 0000000..e067f2a
--- /dev/null
+++ b/doc/props/P_BAD_MSG
@@ -0,0 +1,27 @@
+NAME:
+     P_BAD_MSG                     "std_food_bad_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung, wenn eine Speise gerade verdirbt.
+     Befindet sich die Speise in einem Spieler, geht die Meldung an genau
+     diesen, liegt die Speise im Raum, geht die Meldung an alle anwesenden
+     Spieler.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "@WER1 verdirbt."
+
+SIEHE AUCH:
+     P_LIFETIME, P_RESET_LIFETIME, P_NO_BAD,
+     wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_BLIND b/doc/props/P_BLIND
new file mode 100644
index 0000000..a80814b
--- /dev/null
+++ b/doc/props/P_BLIND
@@ -0,0 +1,35 @@
+NAME:
+    P_BLIND                       "blind"                       
+
+DEFINIERT IN:
+    /sys/player/viewcmd.h
+
+BESCHREIBUNG:
+    1, wenn der Spieler blind ist und nichts mehr sehen kann.
+
+    Wird von CannotSee() bei 'schau' und Betreten von Raeumen 
+    u.ae. ausgewertet.
+
+    P_BLIND kann auch auf einen String gesetzt werden, der 
+    dann statt des 'Du bist blind' ausgegeben wird.
+
+BEISPIELE:
+
+    this_player()->SetProp(P_BLIND,1);
+
+    this_player()->SetProp(P_BLIND,"Du hast Dir vorhin so schoen die "
+                                  +"Augen ausgekratzt ... deswegen "
+                                  +"siehst Du nun nichts mehr.\n");    
+BEMERKUNGEN:
+    Um herauszufinden, ob ein Spieler etwas sehen kann oder nicht,
+    sollte man lieber if(this_player()->CannotSee() != 0) pruefen
+    statt if(this_player()->QueryProp(P_BLIND)).
+
+    Denn CannotSee() beruecksichtigt auch Nachtsicht (bzw. hier 
+    eine nicht aktivierte) und die Lichtmodifikatoren.
+
+SIEHE AUCH:
+    P_LIGHT_MODIFIER, P_PLAYER_LIGHT, CannotSee
+
+----------------------------------------------------------------------------
+Letzte Aenderung: Sa 02.11.02, 00:30:00 Uhr, von Tilly
diff --git a/doc/props/P_BODY b/doc/props/P_BODY
new file mode 100644
index 0000000..7d04581
--- /dev/null
+++ b/doc/props/P_BODY
@@ -0,0 +1,9 @@
+NAME:
+    P_BODY                        "body"                        
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Numerischer Wert fuer die Abwehrstaerke des blanken Koerpers
+     des Wesens.
diff --git a/doc/props/P_BRIEF b/doc/props/P_BRIEF
new file mode 100644
index 0000000..33ef486
--- /dev/null
+++ b/doc/props/P_BRIEF
@@ -0,0 +1,8 @@
+NAME:
+    P_BRIEF                       "brief"                       
+
+DEFINIERT IN:
+    /sys/player/viewcmd.h
+
+BESCHREIBUNG:
+     Ist gesetzt, wenn der Spieler nur die Kurzbeschreibung sehen will.
diff --git a/doc/props/P_BUFFER b/doc/props/P_BUFFER
new file mode 100644
index 0000000..268f719
--- /dev/null
+++ b/doc/props/P_BUFFER
@@ -0,0 +1,9 @@
+NAME:
+    P_BUFFER                      "buffer"                      
+
+DEFINIERT IN:
+    /sys/player/comm.h
+
+BESCHREIBUNG:
+    Zeigt an, ob der Kobold des Spielers aktiv oder nicht aktiv ist.
+
diff --git a/doc/props/P_BUY_ONLY_PLANTS b/doc/props/P_BUY_ONLY_PLANTS
new file mode 100644
index 0000000..46747c4
--- /dev/null
+++ b/doc/props/P_BUY_ONLY_PLANTS
@@ -0,0 +1,15 @@
+NAME:
+    P_BUY_ONLY_PLANTS              "lib_p_buy_only_plants"
+
+DEFINIERT IN:
+    /sys/room/description.h
+
+BESCHREIBUNG:
+    Diese Property kann auf 1 gesetzt werden, wenn ein Laden nur Kraeuter
+    ankaufen darf. Hierzu muss /std/room/kraeuterladen.c geerbt werden,
+    da nur dieses Objekt die Property beruecksichtigt.
+
+SIEHE AUCH:
+    /std/room/kraeuterladen.c
+----------------------------------------------------------------------------
+Last modified: 02.04.2015 Arathorn 
diff --git a/doc/props/P_CALLED_FROM_IP b/doc/props/P_CALLED_FROM_IP
new file mode 100644
index 0000000..d9427d2
--- /dev/null
+++ b/doc/props/P_CALLED_FROM_IP
@@ -0,0 +1,8 @@
+NAME:
+    P_CALLED_FROM_IP              "called_from_ip"              
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Letzte IP-Adr, von der aus sich der Spieler eingeloggt hat.
diff --git a/doc/props/P_CAN_FLAGS b/doc/props/P_CAN_FLAGS
new file mode 100644
index 0000000..ba3eb2a
--- /dev/null
+++ b/doc/props/P_CAN_FLAGS
@@ -0,0 +1,9 @@
+NAME:
+    P_CAN_FLAGS                   "can_flags"                   
+
+DEFINIERT IN:
+    /sys/player/can.h
+
+BESCHREIBUNG:
+    Flags die bestimmte Befehle freischalten:
+    CAN_EMOTE, CAN_ECHO, CAN_REMOTE, CAN_PRESAY
diff --git a/doc/props/P_CAP_NAME b/doc/props/P_CAP_NAME
new file mode 100644
index 0000000..7fbe408
--- /dev/null
+++ b/doc/props/P_CAP_NAME
@@ -0,0 +1,9 @@
+NAME:
+    P_CAP_NAME                    "cap_name"                    
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Name des Spielers, der dekliniert und ausgegen wird.
+     NOT YET IMPLEMENTED.
diff --git a/doc/props/P_CARRIED_VALUE b/doc/props/P_CARRIED_VALUE
new file mode 100644
index 0000000..7df9b63
--- /dev/null
+++ b/doc/props/P_CARRIED_VALUE
@@ -0,0 +1,8 @@
+NAME:
+    P_CARRIED_VALUE               "carried"                     
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Entschaedigung, die der Spieler beim Einloggen erhaelt.
diff --git a/doc/props/P_CHATS b/doc/props/P_CHATS
new file mode 100644
index 0000000..633cdea
--- /dev/null
+++ b/doc/props/P_CHATS
@@ -0,0 +1,8 @@
+NAME:
+    P_CHATS                       "chats"                       
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Alist mit Strings, die das Monster zufaellig ausgibt.
diff --git a/doc/props/P_CHAT_CHANCE b/doc/props/P_CHAT_CHANCE
new file mode 100644
index 0000000..b6acf08
--- /dev/null
+++ b/doc/props/P_CHAT_CHANCE
@@ -0,0 +1,8 @@
+NAME:
+    P_CHAT_CHANCE                 "chat_chance"                 
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wahrscheinlichkeit, mit der die Chats ausgegeben werden.
diff --git a/doc/props/P_CLASS b/doc/props/P_CLASS
new file mode 100644
index 0000000..e074394
--- /dev/null
+++ b/doc/props/P_CLASS
@@ -0,0 +1,19 @@
+P_CLASS
+NAME:
+     P_CLASS						"class"
+
+DEFINIERT IN:
+     <thing/description.h>
+
+BESCHREIBUNG:
+     Die Klassifizierung eines Objektes, soweit sie nicht schon ueber die 
+     Rasse oder die IDs des Objektes erfolgt ist. Zum Setzen dieser Property 
+     sollte man AddClass() benutzen, zur Klassenabfrage steht 
+     is_class_member() zur Verfuegung.
+     Die moeglichen Klassen findet man in /sys/class.h
+
+SIEHE AUCH:
+     AddClass(), RemoveClass(), is_class_member()
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 20:30:09 1996 by Wargon
diff --git a/doc/props/P_CLOCKMSG b/doc/props/P_CLOCKMSG
new file mode 100644
index 0000000..8b72d68
--- /dev/null
+++ b/doc/props/P_CLOCKMSG
@@ -0,0 +1,8 @@
+NAME:
+    P_CLOCKMSG                    "clockmsg"                    
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Die Meldung wird zur vollen Stunde ausgegeben
diff --git a/doc/props/P_CLONER b/doc/props/P_CLONER
new file mode 100644
index 0000000..659b614
--- /dev/null
+++ b/doc/props/P_CLONER
@@ -0,0 +1,12 @@
+NAME:
+    P_CLONER                      "cloner"                      
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Enthaelt einen String mit dem Namen desjenigen, der das Objekt gecloned 
+     hat.
+
+SIEHE AUCH:
+     P_CLONE_TIME
diff --git a/doc/props/P_CLONE_MSG b/doc/props/P_CLONE_MSG
new file mode 100644
index 0000000..d9c96a2
--- /dev/null
+++ b/doc/props/P_CLONE_MSG
@@ -0,0 +1,8 @@
+NAME:
+    P_CLONE_MSG                   "clone_msg"                   
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Meldung, die beim Clonen eines Obj ausgegegen wird (nur Magier)
diff --git a/doc/props/P_CLONE_TIME b/doc/props/P_CLONE_TIME
new file mode 100644
index 0000000..a904846
--- /dev/null
+++ b/doc/props/P_CLONE_TIME
@@ -0,0 +1,14 @@
+NAME:
+    P_CLONE_TIME                   "clone_time"                      
+
+DEFINIERT IN:
+    /sys/thing/description.h
+
+BESCHREIBUNG:
+     Enthaelt die Clone-Time eines Objektes.
+     Heutzutage obsolet, bitte stattdessen lieber die Efun object_time()
+     benutzen.
+
+SIEHE AUCH:
+     Verwandt: object_time(E)
+     Aehnlich: program_time(E)
diff --git a/doc/props/P_CLOTHING b/doc/props/P_CLOTHING
new file mode 100644
index 0000000..793f098
--- /dev/null
+++ b/doc/props/P_CLOTHING
@@ -0,0 +1,22 @@
+P_CLOTHINGS
+
+NAME:
+     P_CLOTHING                     "std:clothing"
+
+DEFINIERT IN:
+     <living/clothing.h>
+
+BESCHREIBUNG:
+     Array mit der getragenen nicht-schuetzenden Kleidung des Lebewesen.
+     
+     Falls ihr die Kleidung des Lebewesens, ggf. mit bestimten Kriterien,
+     ermitteln wollt, benutzt hierfuer bitte die Funktion FilterClothing()
+     statt selber ueber dieses Array zu laufen.
+
+     Diese Property kann nur vom Lebewesen selber beschrieben werden.
+     
+SIEHE AUCH:
+     Verwandt:		QueryArmourByType(L), FilterClothing(), FilterArmours()
+                  Wear(), Unwear(), P_ARMOURS
+
+14.03.2009, Zesstra
diff --git a/doc/props/P_CMSG b/doc/props/P_CMSG
new file mode 100644
index 0000000..9001722
--- /dev/null
+++ b/doc/props/P_CMSG
@@ -0,0 +1,8 @@
+NAME:
+    P_CMSG                        "clonemsg"                    
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     *** OBSOLET! *** Siehe P_CLONE_MSG
diff --git a/doc/props/P_CNT_STATUS b/doc/props/P_CNT_STATUS
new file mode 100644
index 0000000..cd92324
--- /dev/null
+++ b/doc/props/P_CNT_STATUS
@@ -0,0 +1,9 @@
+NAME:
+    P_CNT_STATUS                  "cnt_status"                  
+
+DEFINIERT IN:
+    /sys/container.h
+
+BESCHREIBUNG:
+     Status des Containers (offen, geschlossen, abgeschlossen)
+     siehe auch /sys/container.h
diff --git a/doc/props/P_COMBATCMDS b/doc/props/P_COMBATCMDS
new file mode 100644
index 0000000..c29a65f
--- /dev/null
+++ b/doc/props/P_COMBATCMDS
@@ -0,0 +1,31 @@
+NAME:
+    P_COMBATCMDS                  "combatcmds"                  
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Fuer den Kampf gebrauchbare Befehle spezieller Objekte (damit auch
+     Monster sie automatisch richtig anwenden koennen)
+     Der Inhalt von P_COMBATCMDS ist ein Mapping, der Key ist das Kommando,
+     um den Gegenstand zu benutzen (also z.B. "wirf flammenkugel"), und der
+     Value ein weiteres Mapping mit Zusatzinfos (definiert in /sys/combat.h).
+     Folgende Keys sind definiert:
+     - C_MIN, C_AVG, C_MAX:
+       minimaler, mittlerer und maximaler Schaden, den das
+       Objekt macht. Alle Angaben in LEBENSPUNKTEN, d.h. Defend-Einheiten/10.
+       Bei einem Aufruf wie 'enemy->Defend(200+random(200), ...)' ist dann
+       C_MIN=20, C_AVG=30, C_MAX=40.
+     - C_DTYPES:
+       Array mit dem Schadenstyp oder den Schadenstypen. Beim Eisstab
+       wuerde der Eintrag dann 'C_DTYPES:({DT_COLD})' lauten.
+     - C_HEAL:
+       Sollte das Kampfobjekt ueber die Moeglichkeit verfuegen, den Anwender
+       irgendwie zu heilen, so wird hier die Heilung in LP/MP eingetragen.
+       Das funktioniert auch bei Objekten, die nur heilen, also sonst
+       nichts mit Kampf zu tun haben.
+       Im Lupinental z.B. gibt es Pfirsiche, die beim Essen 5LP heilen. Da
+       kann man dann 'SetProp(P_COMBATCMDS, (["iss pfirsich":([C_HEAL:5])]))'
+       eintragen.
+     Es sind auch mehrere Kommandos moeglich, z.B. bei Objekten, die sowohl
+     heilen als auch Kampfwirkung haben.
diff --git a/doc/props/P_COMMANDS b/doc/props/P_COMMANDS
new file mode 100644
index 0000000..527d1a1
--- /dev/null
+++ b/doc/props/P_COMMANDS
@@ -0,0 +1,47 @@
+P_COMMANDS
+NAME:
+     P_COMMANDS "commands"
+
+DEFINIERT IN:
+     <thing/commands.h>
+
+BESCHREIBUNG:
+     Diese Property enthaelt ein Mapping mit den Befehlen, die dem Objekt
+     zugeordnet sind.
+
+     Sie sollte nicht von Hand manipuliert werden, sondern nur ueber die
+     Funktionen AddCmd() und RemoveCmd().
+
+     Das Mapping hat folgenden Aufbau:
+
+     ([ befehl : ({funktion1,...});
+                 ({flag1,...});
+                 ({regel1,...});
+                 ({id1, ...}),
+        ... ])
+
+     Die Eintraege entsprechen den Parametern des AddCmd()-Aufrufs, sind
+     aber in anderer Form. Als Beispiel:
+
+     AddCmd(verb,fun1,1);
+     AddCmd(verb+syn1a|syn1b&syn2a|syn2b|syn2c,fun2,
+	   error1_notify|error2_notify^error2_write);
+     -->
+     ([verb:({fun1,fun2});					  // funs
+	    ({1,({error1_notify, error2_write^error2_say, 1})});  // flags
+            ({0,({({syn1a,syn1b}),({syn2a,syn2b,syn2c})})});	  // rules
+            0])							  // IDs
+
+     Aufgeschluesselt sehen die einzelnen Arrays folgendermassen aus:
+
+     Rules: ({<Regelsatz fuer fun1>, ({<1. Synonymgruppe>,
+				       <2. Synonymgruppe, ...}), ...})
+     Flags: ({<Flag fuer fun1>, ({<Fehlermeldung 1. Synonymgruppe>, ... ,
+				  [, Index fuer write anstatt notify_fail]}),
+	      ... })
+     IDs:   0 oder ({<ID fuer fun1>}) oder ({0, <ID fuer fun2>}) ...
+
+SIEHE AUCH:
+     /std/thing/commands.c, AddCmd(), RemoveCmd()
+
+08.Dez.2003 Gloinson
diff --git a/doc/props/P_COMPILER_PATH b/doc/props/P_COMPILER_PATH
new file mode 100644
index 0000000..ecd2743
--- /dev/null
+++ b/doc/props/P_COMPILER_PATH
@@ -0,0 +1,21 @@
+NAME:
+    P_COMPILER_PATH               "compiler_path"               
+
+DEFINIERT IN:
+    /sys/v_compiler.h
+
+BESCHREIBUNG:
+    Directory in dem ein Virtual Compiler Objekte erzeugt.
+    Muss im virtual_compiler.c gesetzt werden.
+
+    Der VirtualCompiler muss nicht zwingend in diesem Verzeichnis
+    liegen, um zu funktionieren, sollte es aber, um die Zuordnung des VCs zu
+    "seinen" Objekten zu erleichern.
+
+BEISPIEL:
+    SetProp(P_COMPILER_PATH,"/d/region/magier/vc/");
+
+SIEHE AUCH:
+    P_STD_OBJECT, virtual_compiler
+-------------------------------------------------------------------------
+Letzte Aenderung: 23.10.2007, von Zesstra
diff --git a/doc/props/P_CONSUME_MSG b/doc/props/P_CONSUME_MSG
new file mode 100644
index 0000000..8b8a05a
--- /dev/null
+++ b/doc/props/P_CONSUME_MSG
@@ -0,0 +1,24 @@
+NAME:
+     P_CONSUME_MSG                 "std_food_consume_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Raum exklusive Konsument, wenn eine Speise konsumiert
+     wird.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "@WER2 konsumiert @WEN1."
+
+SIEHE AUCH:
+     /std/food.c, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_CONTAINER b/doc/props/P_CONTAINER
new file mode 100644
index 0000000..ed15ca5
--- /dev/null
+++ b/doc/props/P_CONTAINER
@@ -0,0 +1,8 @@
+NAME:
+    P_CONTAINER                   "container"                   
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_CONTENTS b/doc/props/P_CONTENTS
new file mode 100644
index 0000000..1212da7
--- /dev/null
+++ b/doc/props/P_CONTENTS
@@ -0,0 +1,8 @@
+NAME:
+    P_CONTENTS                    "contents"                    
+
+DEFINIERT IN:
+    /sys/container.h
+
+BESCHREIBUNG:
+     *** OBSOLET! ***
diff --git a/doc/props/P_CORPSE b/doc/props/P_CORPSE
new file mode 100644
index 0000000..bcb0ab6
--- /dev/null
+++ b/doc/props/P_CORPSE
@@ -0,0 +1,25 @@
+NAME:
+    P_CORPSE		"corpse"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Hier kann man angeben, welche Art von Leiche beim Tod des NPCs
+    hinterlassen wird. Damit die Leiche auf dem Moerder-Kanal senden
+    kann, muss das Leichen-Objekt /std/corpse sein oder erben.
+
+BEISPIELE:
+    Die uebliche Standardleiche befindet sich unter "/std/corpse.c",
+    welches auch die Defaulteinstellung fuer diese Property darstellt:
+      SetProp(P_CORPSE,"/std/corpse");
+    Man koennte aber auch einen Zombie entstehen lassen:
+      SetProp(P_CORPSE,PATH("zombie"));
+    PATH kennzeichnet hierbei den Pfad, unter welchem "zombie.c" zu
+    finden ist.
+
+SIEHE AUCH:
+    P_NOCORPSE, P_ZAP_MSG, P_DIE_MSG, P_MURDER_MSG, P_KILL_MSG
+
+----------------------------------------------------------------------------
+Last modified: Mon Apr 07 11:02:06 2003 by Mandragon
diff --git a/doc/props/P_CURRENTDIR b/doc/props/P_CURRENTDIR
new file mode 100644
index 0000000..87bbd5c
--- /dev/null
+++ b/doc/props/P_CURRENTDIR
@@ -0,0 +1,15 @@
+NAME:
+    P_CURRENTDIR                  "currentdir"
+
+DEFINIERT IN:
+    /sys/shells.h
+
+BESCHREIBUNG:
+    Momentanes Verzeichnis in dem der Magier ist.
+    (nur fuer Magier von Belang)
+
+Siehe auch:
+    P_CURRENTDIR
+
+Letzte Aenderung:
+    03.06.2015, Bugfix
diff --git a/doc/props/P_CURSED b/doc/props/P_CURSED
new file mode 100644
index 0000000..d9486fe
--- /dev/null
+++ b/doc/props/P_CURSED
@@ -0,0 +1,35 @@
+P_CURSED
+
+NAME:
+     P_CURSED "cursed"
+
+DEFINIERT IN:
+     <properties.h>
+
+BESCHREIBUNG:
+     Ruestungen und Waffen, die sich, einmal angezogen bzw. gezueckt, nicht
+     wieder entfernen lassen sollen, kann man ueber diese Property
+     realisieren. Die Waffe oder Ruestung hat dann in der Regel negative
+     Auswirkungen auf den Traeger...
+
+     Setzt man diese Property auf eine Zahl ungleich 0, so bekommt man bei
+     dem Versuch, den verfluchten Gegenstand auszuziehen bzw. wegzustecken
+     eine Defaultmeldung.
+
+     Traegt man dagegen einen String ein, so wird dieser beim Versuch, den
+     Gegenstand loszuwerden, ausgegeben.
+
+BEMERKUNGEN:
+     Der 'Fluch' wird erst wirksam, wenn das Opfer die Waffe zueckt bzw. die
+     Ruestung anzieht. Ist dies erst einmal geschehen, helfen nur noch
+     Zaubersprueche oder fluchbrechende Institutionen.
+
+     Moechte man, dass der Gegenstand entfluchbar ist, dann sollte er auch
+     ansprechbar sein (gueltige ID, nicht unsichtbar), da das durch derzeitige
+     Entfluchmoeglichkeiten vorausgesetzt wird.
+
+SIEHE AUCH:
+     /std/armour.c, /std/weapon.c
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 14:45:28 1996 by Wargon
diff --git a/doc/props/P_DAMAGED b/doc/props/P_DAMAGED
new file mode 100644
index 0000000..671e0e0
--- /dev/null
+++ b/doc/props/P_DAMAGED
@@ -0,0 +1,28 @@
+P_DAMAGED
+
+NAME:
+     P_DAMAGED "item_damaged"
+
+DEFINIERT IN:
+     <combat.h>
+
+BESCHREIBUNG:
+     Ruestungen und Waffen koennen im Eifer des Gefechts beschaedigt werden.
+     Der Grad der Beschaedigung sollte in dieser Property festgehalten
+     werden.
+
+     Bei Waffen ergibt sich die urspruengliche Waffenklasse aus der Summe
+     von aktueller Waffenklasse und dem Wert von P_DAMAGED:
+     altes P_WC = aktuelles P_WC + P_DAMAGED.
+
+     Analoges gilt fuer die Ruestungsklasse einer beschaedigten Ruestung:
+     altes P_AC = aktuelles P_AC + P_DAMAGED.
+
+     P_DAMAGED bitte niemals direkt setzen, sondern immer ueber
+     die Funktion Damage() manipulieren!
+
+SIEHE AUCH:
+     /std/armour.c, /std/weapon.c, TakeFlaw(), QueryFlaw(), Damage()
+
+----------------------------------------------------------------------------
+02.10.2007, Zesstra
diff --git a/doc/props/P_DAMAGE_MSG b/doc/props/P_DAMAGE_MSG
new file mode 100644
index 0000000..8923b19
--- /dev/null
+++ b/doc/props/P_DAMAGE_MSG
@@ -0,0 +1,47 @@
+P_DAMAGE_MSG
+
+NAME:
+     P_DAMAGE_MSG      "std_p_dam_msg"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+     In dieser Property lassen sich individuelle Treffer-/Schadensmeldungen
+     fuer dieses Lebewesen festlegen. Sie werden verwendet, falls bei
+     eingehendem Schaden der Aufrufer von Defend() Schadensmeldungen wuenscht
+     (d.h. SP_SHOW_DAMAGE != 0), jedoch keine eigenen Meldungen vorgibt.
+
+     Enthaelt diese Property kein Array, werden ggf. die Standardmeldungen
+     ausgegeben.
+
+     Datenstruktur der Property:
+       ({
+        ({ int lphit1, string mess_me,
+                       string mess_en,
+                       string mess_room }),
+        ({ lphit2, mess_me, mess_en, mess_room }),
+        ...
+        ({ lphitn, mess_me, mess_en, mess_room }),
+       })
+       wobei lphit1<lphit2<...<lphitn sein muss, d.h. das Array-
+       Array ist aufsteigend sortiert.
+
+     Ist ein Treffer x LP hart, werden die Meldungen des lphit-
+     Arrays ausgegeben, dessen Wert am naechsten unter dem Schaden
+     liegt.
+
+     In den Meldungen mess_me (an den Getroffenen), mess_en (an
+     den Feind), mess_room (an die restlichen Umstehenden) koennen
+     Ersatzstrings wie folgt verwendet werden:
+     @WER1/@WESSEN1/@WEM1/@WEN1 - name(casus) des Getroffenen (TO)
+     @WER2/@WESSEN2/@WEM2/@WEN2 - name(casus) des Feindes (enemy)
+
+BEISPIEL:
+     
+
+SIEHE AUCH:
+     Defend()
+     /std/living/combat.c
+
+15.09.2010, Zesstra
diff --git a/doc/props/P_DAM_DESC b/doc/props/P_DAM_DESC
new file mode 100644
index 0000000..59938c7
--- /dev/null
+++ b/doc/props/P_DAM_DESC
@@ -0,0 +1,35 @@
+P_DAM_DESC
+
+NAME:
+     P_DAM_DESC "dam_desc"
+
+DEFINIERT IN:
+     <weapon/description.h>
+
+BESCHREIBUNG:
+     In dieser Property befindet sich ein String oder String-Array, durch 
+     den die Langbeschreibung einer Ruestung oder Waffe ergaenzt wird,
+     wenn diese Beschaedigt ist.
+
+BEMERKUNGEN:
+     Wird ein String gesetzt, so wird dieser angezeigt, wenn die Waffe
+     mehr als die Haelfte beschaedigt ist. Bei einem Array wird der
+     Text entsprechend dem Grad der Beschaedigung ausgewaehlt; das Array
+     muss in der Reihenfolge zunehmender Beschaedigung sortiert sein.
+     
+     Bei Waffen ist P_DAM_DESC defaultmaessig auf DFLT_DAM_DESC gesetzt,
+     bei Ruestungen auf 0.
+
+BEISPIELE:
+     SetProp(P_DAM_DESC,"ist beschaedigt");
+     SetProp(P_DAM_DESC,({
+         "ist etwas beschaedigt",
+         "ist beschaedigt",
+         "ist beschaedigt",
+         "ist sehr beschaedigt"}) );
+
+SIEHE AUCH:
+     /std/weapon/description.c
+
+----------------------------------------------------------------------------
+Last modified: Mon Oct 14 15:29:00 1996 by Paracelsus
diff --git a/doc/props/P_DAM_TYPE b/doc/props/P_DAM_TYPE
new file mode 100644
index 0000000..56fb4bb
--- /dev/null
+++ b/doc/props/P_DAM_TYPE
@@ -0,0 +1,22 @@
+P_DAM_TYPE
+
+NAME:
+     P_DAM_TYPE "dam_type"
+
+DEFINIERT IN:
+     <weapon.h>
+
+BESCHREIBUNG:
+     Was fuer eine Art von Schaden richtet die Waffe an? Hier kann man einen
+     String oder ein Array von Strings angeben, je nachdem, welche Effekte
+     die Waffe ausloesen kann. Man sollte hier nur die in <combat.h>
+     definierten Schadenstypen verwenden.
+
+     Fragt man diese Property ab, bekommt man uebrigens immer ein Array von
+     Strings zurueck.
+
+SIEHE AUCH:
+     /std/weapon.c
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 15:23:43 1996 by Wargon
diff --git a/doc/props/P_DEADS b/doc/props/P_DEADS
new file mode 100644
index 0000000..ca44cd7
--- /dev/null
+++ b/doc/props/P_DEADS
@@ -0,0 +1,9 @@
+NAME:
+    P_DEADS                       "deads"                       
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Anzahl der Tode des Spielers seit Einfuehrung dieser Property (irgendwann
+     im Dezember 94)
diff --git a/doc/props/P_DEAF b/doc/props/P_DEAF
new file mode 100644
index 0000000..8745dfd
--- /dev/null
+++ b/doc/props/P_DEAF
@@ -0,0 +1,10 @@
+NAME:
+    P_DEAF                        "deaf"                        
+
+DEFINIERT IN:
+    /sys/player/comm.h
+
+BESCHREIBUNG:
+     Der Spieler ist taub. Falls hier ein String steht, wird dieser bei
+     "teile ... mit" an den Mitteilenden ausgegeben, ansonsten kommt nur
+     "Soundso ist leider gerade taub.\n"
diff --git a/doc/props/P_DEATH_MSG b/doc/props/P_DEATH_MSG
new file mode 100644
index 0000000..4e044bf
--- /dev/null
+++ b/doc/props/P_DEATH_MSG
@@ -0,0 +1,48 @@
+DEFINIERT IN:

+        /sys/living/combat.h

+

+BESCHREIBUNG:

+        In dieser Property kann man ein Array ablegen, das beim Tod eines

+        Spielers ausgewertet und der darin enthaltene String

+        anschliessend auf dem Todeskanal gesendet wird.

+        Der Array muss folgenden Aufbau haben:

+

+          SetProp( P_DEATH_MSG, ({ Text, Flag }) )

+          

+        Text: Der Text kann beliebig eingegeben werde. Allerdings darf 

+              er nicht mit einem '\n' abgeschlossen werden.

+        

+        Flag: Hier kann man drei Arten von Sendemethoden waehlen.

+              1. MSG_SAY      Normales Senden

+              2. MSG_GEMOTE   Genitiv-Emote

+              3. MSG_EMOTE    Emote

+

+

+BEISPIEL:

+        Der Spieler soll direkt nach seinem Tod eine Meldung auf dem 

+        Todeskanal senden.

+        

+        Nachricht auf dem Todes-Kanal:

+	

+        [Tod:Spieler] Ich will keine Beleidsbekundungen!

+        

+        void spieler_stirbt()

+	{

+         this_player()->SetProp( P_DEATH_MSG, ({ "Ich will keine "

+                                        "Beleidsbekundungen!", MSG_SAY}) );

+         this_player()->die();

+        }

+        

+        Nachricht auf dem Todes-Kanal:

+	

+        [Tod:Spieler liebt es zu sterben.]

+        

+        void spieler_stirbt()

+        {

+         this_player()->SetProp( P_DEATH_MSG, ({ "liebt es zu sterben.",

+                                                 MSG_EMOTE }) );

+         this_player()->die();

+        }

+

+SIEHE AUCH:

+        P_MURDER_MSG, P_FORCE_MURDER_MSG

diff --git a/doc/props/P_DEATH_SPONSORED_BY b/doc/props/P_DEATH_SPONSORED_BY
new file mode 100644
index 0000000..52d7d42
--- /dev/null
+++ b/doc/props/P_DEATH_SPONSORED_BY
@@ -0,0 +1,25 @@
+NAME:
+    P_DEATH_SPONSORED_BY          "responsible_wizard_for_death"
+
+DEFINIERT IN:
+    /sys/living/combat.h
+
+BESCHREIBUNG:
+    Diese Property hat fuer den Spielverlauf keinerlei Bedeutung.
+    Doch gibt es Magier, die ihren Namen gern in /log/KILLS lesen.
+    Wird ein Spieler durch einen Npc getoetet, ist normalerweise der
+    Magier fuer den Tod verantwortlich, in dessen Verzeichnis sich 
+    das Monster befindet. 
+    Doch gibt es nun auch den Fall, dass sich das Monster in einem 
+    Verzeichnis /alle/mon/ befindet, oder der Spieler durch eine
+    Aktion im Raum oder an einem Objekt stirbt.
+
+    Ist in einem solchen Monster, Raum oder Objekt diese Property
+    gesetzt, wird der dort angebene String an das Log-File ueber-
+    geben.
+
+BEISPIEL:
+    SetProp(P_DEATH_SPONSORED_BY,"tilly");
+ 
+----------------------------------------------------------------------------
+Last modified: Don Feb 15 14:01:00 2001 von Tilly
diff --git a/doc/props/P_DEFAULT_GUILD b/doc/props/P_DEFAULT_GUILD
new file mode 100644
index 0000000..28ca4e6
--- /dev/null
+++ b/doc/props/P_DEFAULT_GUILD
@@ -0,0 +1,25 @@
+NAME:
+	P_DEFAULT_GUILD			"default_guild"
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	Diese Property enthaelt den Namen der Gilde, welcher der Spieler
+	standardmaessig angehoert. Der Name wird hierbei in Form eines
+	kleingeschriebenen Strings angegeben. Ist P_GUILD gleich Null, so
+	wird bei der Abfrage selbiger Property hierfuer der Eintrag von
+	P_DEFAULT_GUILD eingesetzt.
+
+BEMERKUNGEN:
+	Nach dem ersten Einloggen des Spielers wird ebenfalls dieser Eintrag
+	genutzt, um die Gildenzugehoerigkeit festzulegen. Dies kann dazu
+	genutzt werden, um eine rassenabhaengige Bestimmung der
+	Standardgilde zu gewaehrleisten
+	 (Felinen -> Katzenkrieger, andere Rassen -> Abenteurer).
+
+SIEHE AUCH:
+	P_GUILD, P_VISIBLE_GUILD
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_DEFAULT_NOTIFY_FAIL b/doc/props/P_DEFAULT_NOTIFY_FAIL
new file mode 100644
index 0000000..611e8df
--- /dev/null
+++ b/doc/props/P_DEFAULT_NOTIFY_FAIL
@@ -0,0 +1,8 @@
+NAME:
+    P_DEFAULT_NOTIFY_FAIL         "default_notify_fail"         
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Welche Fehlermeldung kommt, wenn kein Objekt ein notify_fail macht?
diff --git a/doc/props/P_DEFENDERS b/doc/props/P_DEFENDERS
new file mode 100644
index 0000000..b471d45
--- /dev/null
+++ b/doc/props/P_DEFENDERS
@@ -0,0 +1,30 @@
+NAME:
+	P_DEFENDERS			"defenders"
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	Diese Property wird in Lebewesen gesetzt, welche zum Beispiel durch
+	andere Lebewesen verteidigt werden. Die Verteidiger muessen
+	natuerlich bekannt sein, damit sie per InformDefend() ueber Angriffe
+	informiert werden und per DefendOther() in den laufenden Angriff
+	eingreifen koennen (zum Beispiel Schaeden abwehren oder umwandeln).
+	Es muessen jedoch nicht unbedingt Lebewesen oder echte Verteidiger
+	sein, auch beliebige Objekte koennen ueber Angriffe informiert
+	werden und in diese eingreifen. Allerdings besteht die
+	Einschraenkung, dass diese Objekte in der gleichen Umgebung sein
+	muessen, wie das zu verteidigende Lebewesen oder im zu verteidigenden
+	Lebewesen selbst.
+	Die Objekte, welche dies betrifft, sind in Form eines Arrays in
+	der Property P_DEFENDERS abgelegt.
+	Gesetzt und geloescht werden sollten die Eintraege dieses Arrays
+	jedoch nur mittels der dafuer bereitgestellten Funktionen
+	AddDefender() und RemoveDefender().
+
+SIEHE AUCH:
+	AddDefender(), RemoveDefender(), InformDefend(), DefendOther(),
+	/std/living/combat.c
+
+----------------------------------------------------------------------------
+Last modified: 21.09.2007, Zesstra
diff --git a/doc/props/P_DEFEND_FUNC b/doc/props/P_DEFEND_FUNC
new file mode 100644
index 0000000..02f1e8c
--- /dev/null
+++ b/doc/props/P_DEFEND_FUNC
@@ -0,0 +1,31 @@
+P_DEFEND_FUNC
+
+NAME:
+     P_DEFEND_FUNC "defend_func"
+
+DEFINIERT IN:
+     <armour.h>
+
+BESCHREIBUNG:
+     Falls ein Objekt eine DefendFunc() fuer die Ruestung definiert, so muss
+     dieses Objekt in dieser Property eingetragen sein.
+
+     Die Auswertung dieser Property erfolgt in QueryDefend().
+
+BEMERKUNGEN:
+     1. Es funktioniert _nicht_ hier eine Closure reinzuschreiben.
+     2. Diese Prop laesst sich _nicht_ sinnvoll mit Set() setzen, also z.B.
+        keine Query-Methoden hier reinzuschreiben.
+     3. Definieren von _set_defend_func() oder Set-Methoden via Set()
+        funktioniert auch nicht, zumindest nicht mit dem gewuenschten
+        Ergebnis. ;-)
+     4. Bei Verwendung bitte Balance-Richtlinien beachten!
+
+BEISPIELE:
+     Siehe das Beispiel zu DefendFunc()
+
+SIEHE AUCH:
+     /std/armour.c, DefendFunc(), balance, grenzwerte
+
+----------------------------------------------------------------------------
+Last modified: Sat May 18 15:26:17 1996 by Wargon
diff --git a/doc/props/P_DEFUEL_AMOUNT_DRINK b/doc/props/P_DEFUEL_AMOUNT_DRINK
new file mode 100644
index 0000000..558e261
--- /dev/null
+++ b/doc/props/P_DEFUEL_AMOUNT_DRINK
@@ -0,0 +1,20 @@
+NAME:
+    P_DEFUEL_AMOUNT_DRINK                          "defuel_amount_drink"
+
+DEFINIERT IN:
+    /sys/defuel.h
+
+BESCHREIBUNG:
+    Enthaelt die rassenabhaengige Enttankvorgabe fuer Trinken.
+    
+SIEHE AUCH:
+     Aehnlich:  P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+                P_DEFUEL_LIMIT_FOOD, P_DEFUEL_LIMIT_DRINK,
+                P_DEFUEL_AMOUNT_FOOD
+     Methoden:  defuel_drink, defuel_food
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Weitere:   P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/props/P_DEFUEL_AMOUNT_FOOD b/doc/props/P_DEFUEL_AMOUNT_FOOD
new file mode 100644
index 0000000..a8554be
--- /dev/null
+++ b/doc/props/P_DEFUEL_AMOUNT_FOOD
@@ -0,0 +1,20 @@
+NAME:
+    P_DEFUEL_AMOUNT_FOOD                          "defuel_amount_food"
+
+DEFINIERT IN:
+    /sys/defuel.h
+
+BESCHREIBUNG:
+    Enthaelt die rassenabhaengige Enttankvorgabe fuer Essen.
+    
+SIEHE AUCH:
+     Aehnlich:  P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+                P_DEFUEL_LIMIT_FOOD, P_DEFUEL_LIMIT_DRINK,
+                P_DEFUEL_AMOUNT_DRINK
+     Methoden:  defuel_drink, defuel_food
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Weitere:   P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/props/P_DEFUEL_LIMIT_DRINK b/doc/props/P_DEFUEL_LIMIT_DRINK
new file mode 100644
index 0000000..0a59df4
--- /dev/null
+++ b/doc/props/P_DEFUEL_LIMIT_DRINK
@@ -0,0 +1,21 @@
+NAME:
+    P_DEFUEL_LIMIT_DRINK                          "defuel_limit_drink"
+
+DEFINIERT IN:
+    /sys/defuel.h
+
+BESCHREIBUNG:
+    Enthaelt die rassenabhaengige minimale Menge an Trinken, ab dem ein
+    Enttankvorgang fuer den Spieler moeglich ist.
+    
+SIEHE AUCH:
+     Aehnlich:  P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+                P_DEFUEL_LIMIT_FOOD,
+                P_DEFUEL_AMOUNT_FOOD, P_DEFUEL_AMOUNT_DRINK
+     Methoden:  defuel_drink, defuel_food
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Weitere:   P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/props/P_DEFUEL_LIMIT_FOOD b/doc/props/P_DEFUEL_LIMIT_FOOD
new file mode 100644
index 0000000..26e33fd
--- /dev/null
+++ b/doc/props/P_DEFUEL_LIMIT_FOOD
@@ -0,0 +1,21 @@
+NAME:
+    P_DEFUEL_LIMIT_FOOD                          "defuel_limit_food"
+
+DEFINIERT IN:
+    /sys/defuel.h
+
+BESCHREIBUNG:
+    Enthaelt die rassenabhaengige minimale Menge an Essen, ab dem ein
+    Enttankvorgang fuer den Spieler moeglich ist.
+    
+SIEHE AUCH:
+     Aehnlich:  P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+                P_DEFUEL_LIMIT_DRINK,
+                P_DEFUEL_AMOUNT_FOOD, P_DEFUEL_AMOUNT_DRINK
+     Methoden:  defuel_drink, defuel_food
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Weitere:   P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/props/P_DEFUEL_TIME_DRINK b/doc/props/P_DEFUEL_TIME_DRINK
new file mode 100644
index 0000000..de5eaf0
--- /dev/null
+++ b/doc/props/P_DEFUEL_TIME_DRINK
@@ -0,0 +1,21 @@
+NAME:
+    P_DEFUEL_TIME_DRINK                          "defuel_time_drink"
+
+DEFINIERT IN:
+    /sys/defuel.h
+
+BESCHREIBUNG:
+    Enthaelt die rassenabhaengige minimale Zeit zwischen einzelnen
+    Enttankvorgaengen fuer Trinken eines Spielers.
+    
+SIEHE AUCH:
+     Aehnlich:  P_DEFUEL_TIME_FOOD,
+                P_DEFUEL_LIMIT_FOOD, P_DEFUEL_LIMIT_DRINK,
+                P_DEFUEL_AMOUNT_FOOD, P_DEFUEL_AMOUNT_DRINK
+     Methoden:  defuel_drink, defuel_food
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Weitere:   P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/props/P_DEFUEL_TIME_FOOD b/doc/props/P_DEFUEL_TIME_FOOD
new file mode 100644
index 0000000..d7bdd79
--- /dev/null
+++ b/doc/props/P_DEFUEL_TIME_FOOD
@@ -0,0 +1,21 @@
+NAME:
+    P_DEFUEL_TIME_FOOD                          "defuel_time_food"
+
+DEFINIERT IN:
+    /sys/defuel.h
+
+BESCHREIBUNG:
+    Enthaelt die rassenabhaengige minimale Zeit zwischen einzelnen
+    Enttankvorgaengen fuer Essen eines Spielers.
+    
+SIEHE AUCH:
+     Aehnlich:  P_DEFUEL_TIME_DRINK,
+                P_DEFUEL_LIMIT_FOOD, P_DEFUEL_LIMIT_DRINK,
+                P_DEFUEL_AMOUNT_FOOD, P_DEFUEL_AMOUNT_DRINK
+     Methoden:  defuel_drink, defuel_food
+     Tanken:    consume, drink_alcohol, drink_soft, eat_food
+     Weitere:   P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_FOOD, P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, enttanken, food
+
+9. August 2015 Gloinson
diff --git a/doc/props/P_DEPARTMSG b/doc/props/P_DEPARTMSG
new file mode 100644
index 0000000..515c8bd
--- /dev/null
+++ b/doc/props/P_DEPARTMSG
@@ -0,0 +1,8 @@
+NAME:
+    P_DEPARTMSG                   "departmsg"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+     Meldung, mit der ein Transporter ablegt.
diff --git a/doc/props/P_DESCRIPTION b/doc/props/P_DESCRIPTION
new file mode 100644
index 0000000..d275cc7
--- /dev/null
+++ b/doc/props/P_DESCRIPTION
@@ -0,0 +1,8 @@
+NAME:
+    P_DESCRIPTION                 "description"                 
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Beschreibung des Spielers
diff --git a/doc/props/P_DESTROY_BAD b/doc/props/P_DESTROY_BAD
new file mode 100644
index 0000000..d563af9
--- /dev/null
+++ b/doc/props/P_DESTROY_BAD
@@ -0,0 +1,29 @@
+NAME:
+     P_DESTROY_BAD                 "std_food_destroy_bad"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Speichert den Wert fuer das Verhalten, wenn eine Speise verdirbt.
+     Dieses Verhalten wird in make_bad() umgesetzt.
+     
+     DESTROY_BAD   : Die Speise wird beim Verderben zerstoert
+                     bzw. der Behaelter wird geleert
+     DESTROY_NEVER : Die Speise wird beim Verderben nicht zerstoert
+     pos. Integer  : Anzahl der Sekunden, die zwischen Verderben
+                     und Zerstoeren der Speise liegen sollen
+     
+BEMERKUNGEN:
+     Ist ein positiver Integer-Wert in dieser Property gespeichert, wird nach
+     Ausfuehren der Methode make_bad() nach Ablauf der angegebenen Sekunden
+     ein weiterer Reset ausgeloest, der make_destroy() aufruft.
+     
+DEFAULT:
+     Initial ist diese Property auf DESTROY_BAD gesetzt.
+
+SIEHE AUCH:
+     /std/food.c, wiz/food
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_DESTRUCT_MSG b/doc/props/P_DESTRUCT_MSG
new file mode 100644
index 0000000..4b7e7e9
--- /dev/null
+++ b/doc/props/P_DESTRUCT_MSG
@@ -0,0 +1,8 @@
+NAME:
+    P_DESTRUCT_MSG                "destruct_msg"                
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Meldung, die beim Destructen Obj ausgegegen wird (nur Magier)
diff --git a/doc/props/P_DETAILS b/doc/props/P_DETAILS
new file mode 100644
index 0000000..e23513a
--- /dev/null
+++ b/doc/props/P_DETAILS
@@ -0,0 +1,25 @@
+NAME:
+    P_DETAILS            "details"
+
+DEFINIERT IN:
+    /sys/thing/description.h
+
+BESCHREIBUNG:
+    Diese Property enthaelt ein Mapping, in der Details im Objekt
+    definiert werden und Beschreibungen, die ausgegeben werden, wenn man
+    sich diese Details anschaut.
+
+BEMERKUNGEN:
+    Man kann diese Property nicht per SetProp() veraendern, sondern muss die
+    entsprechenden Funktionen nutzen.
+    AddSpecialDetail() und RemoveSpecialDetail() sollten nicht mehr
+    verwendet werden.
+
+SIEHE AUCH:
+    Setzen:    AddDetail()
+    Loeschen:  RemoveDetail()
+    Aehnlich:  P_SPECIAL_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail()
+    Sonstiges: GetDetail(), break_string()
+
+27. Jan 2013 Gloinson
diff --git a/doc/props/P_DIE_MSG b/doc/props/P_DIE_MSG
new file mode 100644
index 0000000..99f1d7c
--- /dev/null
+++ b/doc/props/P_DIE_MSG
@@ -0,0 +1,40 @@
+P_DIE_MSG
+
+NAME:
+     P_DIE_MSG			"die_msg"
+
+DEFINIERT IN:
+     /sys/properties.h
+
+BESCHREIBUNG:
+     In dieser Property uebergibt man einen String, der ausgegeben wird, wenn
+     das Lebewesen stirbt. Ist die Property nicht gesetzt, so wird als String
+     benutzt:
+	" faellt tot zu Boden.\n".
+
+     Der Name des Lebewesens wird dem String vor der Ausgabe vorangestellt.
+     Der Satzumbruch am Zeilenende und das Leerzeichen nach dem Namen des
+     Lebewesens muss man selbst angegeben. Es sollte allerdings beachtet
+     werden, dass ein Lebewesen, das durch Gift getoetet wird, eine spezielle
+     nicht zu beeinflussende Meldung erhaelt. Es wird dann als String
+     benutzt:
+	" wird von Gift hinweggerafft und kippt um.\n".
+
+BEISPIELE:
+     Bei einem mitkaempfenden Schatten waere es eher unlogisch, wenn nach
+     dessen 'Tod' eine Leiche zurueckbliebe. Eine logische Konsequenz waere
+     folgende Meldung:
+	SetProp(P_DIE_MSG," loest sich auf.\n");
+	SetProp(P_NOCORPSE,1);
+
+     Damit dann auch wirklich keine Leiche zurueckbleibt, wird zusaetzlich
+     die Property P_NOCORPSE gesetzt.
+
+SIEHE AUCH:
+     Tod:		die(L)
+     Todesmeldungen:	P_KILL_NAME, P_KILL_MSG, P_MURDER_MSG
+			P_ZAP_MSG, P_ENEMY_DEATH_SEQUENCE
+     Sonstiges:		P_CORPSE, P_NOCORPSE, /std/corpse.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_DISABLE_ATTACK b/doc/props/P_DISABLE_ATTACK
new file mode 100644
index 0000000..25e051d
--- /dev/null
+++ b/doc/props/P_DISABLE_ATTACK
@@ -0,0 +1,46 @@
+NAME:
+    P_DISABLE_ATTACK              "disable_attack"              
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Das Lebewesen kann nicht angreifen. Beim Setzen der Property ist es
+    wichtig, SetProp() zu benutzen und die Anzahl der Kampfrunden anzugeben,
+    die das Lebewesen paralysiert sein soll.
+
+    Ein negativer Wert ist nicht gueltig. Bei mehr als 30 Kampfrunden wird
+    die Paralyse auf 30 Kampfrunden gekappt.
+
+    Fuer jede Paralyse bekommt ein Living eine ebenso lange Schutzzeit nach
+    der Paralyse gewaehrt. Versucht man, vor Ablauf der Paralyse
+    P_DISABLE_ATTACK hoeher zu setzen (oder setzt man innerhalb der folgenden
+    Schutzzeit P_DISABLE_ATTACK auf > 0), wird DISABLE_TOO_EARLY von SetProp
+    zurueck gegeben.
+    Eine Reduktion von einem P_DISABLE_ATTACK ist moeglich, allerdings
+    reduziert dies _nicht_ eine einmal gesetzte Schutzzeit.
+
+    Einen Gegner,der nie paralysiert werden koennen soll, kann man einfach
+    per 
+
+    Set(P_DISABLE_ATTACK, function int () {return 0;}, F_SET_METHOD);
+
+    erstellen, da bei diesem der Wert von P_DISABLE_ATTACK nicht mehr mit
+    einem normalen SetProp()-Aufruf geaendert werden kann.
+
+BEISPIELE:
+    // Gegner 17 Runden lang paralysieren, ohne Ruecksicht auf fruehere P.
+    // (in diesem Moment ist das Living bis time() + 4 * 17 vor laengerer
+    //  oder erneuter Paralyse geschuetzt)
+    en->SetProp(P_DISABLE_ATTACK, 17);
+    // Der Gegner kann jetzt fuer 34 Kampfrunden nicht erneut paralysiert
+    // werden.
+    // Paralyse reduzieren auf 10 Kampfrunden
+    en->SetProp(P_DISABLE_ATTACK, 10);
+    // Die Schutzzeit ist immer noch bei 34 Kampfrunden, nicht bei 20.
+
+SIEHE AUCH:
+    P_NEXT_DISABLE_ATTACK
+
+19.08.2014, Zesstra
+
diff --git a/doc/props/P_DISABLE_COMMANDS b/doc/props/P_DISABLE_COMMANDS
new file mode 100644
index 0000000..f0318e0
--- /dev/null
+++ b/doc/props/P_DISABLE_COMMANDS
@@ -0,0 +1,74 @@
+P_DISABLE_COMMANDS
+
+NAME:
+     P_DISABLE_COMMANDS             "p_lib_disablecommands"
+
+DEFINIERT IN:
+     /sys/player/command.h
+
+BESCHREIBUNG:
+    Mit dieser Prop kann man verhindern, dass Kommandos eines Spielers
+    verarbeitet werden. Dies ist z.B. in Sequenzen nuetzlich, wo der Spieler
+    rein passiv konsumieren soll.
+    In diese Property muss ein Array mit 2 oder 3 Elementen geschrieben 
+    werden:
+       1) Endzeitpunkt in Sekunden seit 1.1.1970 (int)
+       2) Meldung (String oder Closure)
+       3) (optional) Array von trotzdem erlaubten Verben (string*)
+         (nur ausgewertet, wenn die Meldung ein String ist)
+    
+    Ist die Meldung ein String, wird dieser einfach bei jedem Kommando so wie
+    er ist an den Spieler ausgegeben und das Kommando abgebrochen.
+    Ist die Meldung eine Closure wird diese bei jedem Kommando aufgerufen und
+    das Kommando abgebrochen, wenn sie einen Rueckgabewert != 0 zurueckgibt.
+    In diesem Fall ist die gerufene Funktion dafuer verantwortlich, geeignete
+    Meldungen an den Spieler auszugeben!
+    Der Funktion wird der vom Spieler eingebene Befehl (string) als erstes
+    Argument uebergeben. Zu diesem Zeitpunkt wurde alle Aliase schon
+    ausgewertet. Die Funktion kann den Kommandogeber via this_player()
+    ermitteln.
+    Fuer weitere Informationen steht auch command_stack() zur Verfuegung,
+    allerdings ist dort die Alias-Ersetzung nicht beruecksichtigt.
+
+    Die Ausnahmeliste wird nur fuer simple Strings als Meldung ausgewertet,
+    wird eine Closure verwendet, kann diese besser selber die Ausnahmen
+    bestimmen.
+    
+    Fragt man diese Prop ab, erhaelt man ein Array mit 4 Elementen: setzendes
+    Objekt (object), Ablaufzeit (int), Meldung (String oder Closure) und
+    Liste von Ausnahmen (string*).
+
+BEMERKUNGEN:
+    1. Die Prop wird fuer Magier mit eingeschaltetem P_WANTS_TO_LEARN
+       ignoriert.
+    2. Wenn das Objekt zerstoert wird, was die Prop gesetzt hat, wird der
+       Eintrag unwirksam.
+    3. Wenn diese Prop gesetzt und nicht abgelaufen ist, kann nur das gleiche
+       Objekt sie mit neuen Daten ueberschreiben. Alle anderen Objekte koennen
+       die Prop nur loeschen. Dies soll verhindern, dass Magier unabsichtlich
+       einfach anderer Leute Eintraege ueberschreiben. Dementsprechend: Lasst
+       die Finger davon, wenn die schon gesetzt ist. ;-)
+    4. Diese Prop darf _ausschliesslich_ mit SetProp() und QueryProp() benutzt
+       werden, Set() und Query() funktionieren _nicht_.
+    5. Es gibt einige Verben, die NIE blockiert werden. Zur Zeit sind dies
+       "mrufe", "mschau", "bug", "idee", "typo" und "detail".
+    6. Bitte nicht missbrauchen, speziell nicht dazu, die Kommandos von
+       Spieler zu ueberwachen/mitzuschreiben. Das Setzen dieser Prop wird 
+       geloggt.
+
+BEISPIEL:
+   In einem Raum startet eine Sequenz, in der der Spieler nichts machen soll:
+
+   if (!pl->QueryProp(P_DISABLE_COMMANDS))
+      pl->SetProp(P_DISABLE_COMMANDS,
+            ({ time() + 120, "Du bist tief in Deinem Traum gefangen!\n" }) );
+   else // ... Fehlerbehandlung, falls Prop schon gesetzt ...
+   
+   Soll die Prop aus irgendeinem Grund (vorzeitig) geloescht werden:
+   pl->SetProp(P_DISABLE_COMMANDS, 0);
+
+SIEHE AUCH:
+     command(), query_command(), command_stack(), modify_command(), 
+     this_player()
+
+01.12.2012, Zesstra
diff --git a/doc/props/P_DISTRIBUTION b/doc/props/P_DISTRIBUTION
new file mode 100644
index 0000000..529c53e
--- /dev/null
+++ b/doc/props/P_DISTRIBUTION
@@ -0,0 +1,16 @@
+NAME:

+     P_DISTRIBUTION                "std_food_distribution"

+

+DEFINIERT IN:

+     /sys/food.h

+

+BESCHREIBUNG:

+     Verteilung der Heilung ueber mehrere Heartbeats.

+     Dieser Wert wird im entry_info als H_DISTRIBUTION dem consume() im

+     Living uebergeben.

+     

+SIEHE AUCH:

+     consume

+

+------------------------------------------------------------------------------

+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_DMSG b/doc/props/P_DMSG
new file mode 100644
index 0000000..f43fbb4
--- /dev/null
+++ b/doc/props/P_DMSG
@@ -0,0 +1,8 @@
+NAME:
+    P_DMSG                        "destmsg"                     
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     *** OBSOLET! *** Siehe P_DESTRUCT_MSG
diff --git a/doc/props/P_DOMAIN b/doc/props/P_DOMAIN
new file mode 100644
index 0000000..80fd1f7
--- /dev/null
+++ b/doc/props/P_DOMAIN
@@ -0,0 +1,31 @@
+NAME:
+    P_DOMAIN                                        "lib_p_domain"
+
+DEFINIERT IN:
+    /sys/room/description.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt die Region, in der ein Raum liegt, sofern er
+     in /d/ liegt.
+
+     Falls ein Raum nicht in /d/ liegt, aber es eigentlich ein Gebiet ist,
+     welches eindeutig in einer Region zugeordnet ist, kann der Magier
+     hier gezielt einen anderen Wert setzen.
+     
+     Bitte keine Regionen faelschen!
+
+BEISPIEL:
+     In /d/inseln/zesstra/vulkanweg/room/r1 liefert
+     QueryProp(P_DOMAIN)
+     ein "Inseln" zurueck.
+
+     In einem Raum der Chaosgilde:
+     SetProp(P_DOMAIN, "Polar");
+     damit der Raum als Raum der Region Polar angezeigt wird.
+
+SIEHE AUCH:
+     gmcp
+
+----------------------------------------------------------------------------
+23.02.2013, Zesstra
+
diff --git a/doc/props/P_DOOR_INFOS b/doc/props/P_DOOR_INFOS
new file mode 100644
index 0000000..8b5f71b
--- /dev/null
+++ b/doc/props/P_DOOR_INFOS
@@ -0,0 +1,44 @@
+NAME:
+    P_DOOR_INFOS                  "door_infos"
+
+DEFINIERT IN:
+    /sys/doorroom.h
+
+BESCHREIBUNG:
+    Mapping mit Informationen ueber eine im Raum per NewDoor() definierte
+    Tuer. Diese Infos werden ueber /std/room/doors.c an den /obj/doormaster.c
+    weitergegeben und dem Raum, der die Tuer besitzt, als Property gesetzt.
+    Werden mehrere Tueren in einem Raum eingebunden, enthaelt das Mapping
+    entsprechend viele Eintraege.
+
+    Dieses Mapping dient zur internen Verwaltung der Tueren im
+    /obj/doormaster.c und sollte nicht per Hand veraendert werden!
+
+    Die Eintraege im Mapping haben folgende keys (definiert in
+    /sys/doorroom.h):
+
+    D_DEST : Zielraum (string)
+    D_CMDS : Befehl(e), um durch die Tuer zu gehen (string oder *string)
+    D_IDS  : IDs der Tuer (string oder *string)
+    D_FLAGS : Besondere Eigenschaften der Tuer (Tuer braucht Schluessel etc.)
+    D_LONG  : Langbeschreibung (string)
+    D_SHORT : Kurzbeschreibung (string)
+    D_NAME  : Name (string oder *string)
+    D_GENDER  : Geschlecht
+    D_FUNC    : Funktion, die VOR dem Durchschreiten der Tuer aufgerufen wird
+    D_MSGS    : Bewegungsmeldungen
+    D_FUNC2   : Funktion, die NACH dem Durchschreiten der Tuer aufgerufen wird
+    D_TESTFUNC  : Funktion die im Sartraum testet, ob die Tuer durchschritten
+                  werden darf
+    D_RESET_MSG : Meldungen beim Tuer-Reset
+    D_OPEN_WITH_MOVE : Falls gesetzt, wird die Tuer auch mit dem
+                       Bewegungsbefehl geoeffnet und durchschritten, falls
+                       Oeffnen erfolgreich
+
+
+SIEHE AUCH:
+    NewDoor(), QueryDoorKey(), QueryDoorStatus(), SetDoorStatus(),
+    /std/room/doors.c, /obj/doormaster.c, GetPhiolenInfos(), QueryAllDoors()
+
+-----------------------------------------------------------------------------
+Letzte Aenderung: Don, 08.05.2014, Gabylon
diff --git a/doc/props/P_DO_DESTRUCT b/doc/props/P_DO_DESTRUCT
new file mode 100644
index 0000000..7e9a230
--- /dev/null
+++ b/doc/props/P_DO_DESTRUCT
@@ -0,0 +1,17 @@
+NAME:
+    P_DO_DESTRUCT                 "do_destruct"                 
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Flag, ob sich die Lichtquelle am Ende der Leuchtzeit selbst
+     zerstoert. 
+
+SIEHE AUCH:
+     Basisklassen: /std/lightsource.c
+     Properties: P_FUEL, P_LIGHTDESC, P_LIGHT
+     Methoden: AddFuel(L)
+
+LETZTE AENDERUNG:
+    22. Dez. 2015, Arathorn
diff --git a/doc/props/P_DRINK b/doc/props/P_DRINK
new file mode 100644
index 0000000..f2fe982
--- /dev/null
+++ b/doc/props/P_DRINK
@@ -0,0 +1,25 @@
+NAME:
+     P_DRINK                       "drink"
+
+DEFINIERT IN:
+     /sys/living/life.h
+
+BESCHREIBUNG:
+
+     - Lebewesen
+       Numerischer Wert fuer den Saettigungsgrad eines Lebewesens mit
+       Getraenken. Der maximale Wert steht in P_MAX_DRINK.
+
+     - Speisen/Kneipen
+       Numerischer Wert fuer den Saettigungsgrad einer Portion eines
+       Getraenkes. Ist diese Property nicht gesetzt oder zusaetzlich
+       P_FOOD gesetzt, kann man diese Speise nicht trinken. Eine
+       funktionierende Speise _muss_ entweder P_FOOD oder P_DRINK
+       groesser 0 gesetzt haben.
+     
+SIEHE AUCH:
+     P_MAX_DRINK, P_DRINK_DELAY, consume
+     P_FOOD, P_ALCOHOL, wiz/food
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_DRINK_DELAY b/doc/props/P_DRINK_DELAY
new file mode 100644
index 0000000..0118843
--- /dev/null
+++ b/doc/props/P_DRINK_DELAY
@@ -0,0 +1,10 @@
+NAME:
+    P_DRINK_DELAY                 "drink_delay"                     
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Anzahl der heart_beats, bis P_DRINK um einen Punkt sinkt.
+     Aenderungen dieser Property in Spielern beduerfen der 
+     Genehmigung des EM fuer Balance.
diff --git a/doc/props/P_DRINK_FULL_MSG b/doc/props/P_DRINK_FULL_MSG
new file mode 100644
index 0000000..2903af3
--- /dev/null
+++ b/doc/props/P_DRINK_FULL_MSG
@@ -0,0 +1,24 @@
+NAME:
+     P_DRINK_FULL_MSG              "std_food_drink_full_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Konsumenten, wenn ein Getraenk getrunken werden soll,
+     obwohl dieser nichts mehr trinken kann.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "So viel kannst Du im Moment nicht trinken."
+
+SIEHE AUCH:
+     P_DRINK, P_MAX_DRINK, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_DROP_MSG b/doc/props/P_DROP_MSG
new file mode 100644
index 0000000..5a4c9d7
--- /dev/null
+++ b/doc/props/P_DROP_MSG
@@ -0,0 +1,62 @@
+P_DROP_MSG
+NAME:
+     P_DROP_MSG				"drop_message" 
+
+DEFINIERT IN:
+     /sys/living/put_and_get.h
+
+BESCHREIBUNG:
+     Mit P_DROP_MSG kann man die Meldung, die man beim Ablegen eines
+     Objektes bekommt, modifizieren.
+
+     Folgende Werte sind moeglich:
+	
+     o 0
+       Es wird eine Standardmeldung ausgegeben. Dies ist Voreinstellung. 
+	  
+     o NO_PNG_MSG       == -1
+       Es wird keinerlei Meldung ausgegeben
+	  
+     o Ein Array aus Strings 
+       Der erste String wird an den Spieler ausgegeben, der zweite 
+       (optionale) an den Raum. 
+	  
+       Die Strings werden durch die Funktion replace_personal() geparst.
+	Objekt1 - Spieler
+        Objekt2 - das Objekt, das fallengelassen wird
+	  
+       Wird der zweite String nicht angegeben, erfolgt keine Meldung an
+       den Raum.
+				
+BEISPIEL:
+     void create() {
+      ...
+      SetProp( P_SHORT, "Ugars Handaxt" );
+      SetProp( P_LONG, break_string(
+       "Dieses ist eine Kampfaxt, wie sie Orks normalerweise benutzen. "
+       "Da Du Zeit hast, sie Dir anzuschauen, ist der Besitzer wohl "
+       "bereits bei Lars.",78 ));
+	  
+      SetProp( P_NAME, "Axt" );
+      AddId( ({"handaxt","axt"}) );
+      SetProp( P_GENDER, FEMALE );
+	  
+      SetProp( P_DROP_MSG, ({
+       "Du schmeisst @WEN2 hin.",
+       "@WER1 schmeisst Dir @WENU2 vor die Fuesse.\n"}));
+      ...
+     }
+
+     Will Ugar seine Axt ablegen und gibt "lasse axt fallen" ein, werden 
+     folgende Meldungen ausgegeben:
+	
+     Ugar: "Du schmeisst die Axt hin."
+     Raum: "Ugar schmeisst Dir eine Axt vor die Fuesse."
+	
+SIEHE AUCH:
+     Aehnliches: P_PICK_MSG, P_PUT_MSG, P_GIVE_MSG, P_WEAR_MSG, P_WIELD_MSG
+     Fehler:     P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_TOO_MANY_MSG,
+                 P_NOINSERT_MSG, P_NOLEAVE_MSG, P_NODROP, P_NOGET 
+     Sonstiges:  replace_personal(E), drop_obj(L), /std/living/put_and_get.c
+
+14. Maerz 2004 Gloinson
diff --git a/doc/props/P_EARMUFFS b/doc/props/P_EARMUFFS
new file mode 100644
index 0000000..97e6b1c
--- /dev/null
+++ b/doc/props/P_EARMUFFS
@@ -0,0 +1,9 @@
+NAME:
+    P_EARMUFFS                    "earmuffs"                    
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Shouts von Spielern und Magiern mit Magierlevel < earmuffs werden
+     abgeblockt (Nur fuer Magier).
diff --git a/doc/props/P_EATER_MSG b/doc/props/P_EATER_MSG
new file mode 100644
index 0000000..99ae4d3
--- /dev/null
+++ b/doc/props/P_EATER_MSG
@@ -0,0 +1,23 @@
+NAME:
+     P_EATER_MSG                   "std_food_eater_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Konsumenten, wenn eine Speise konsumiert wird.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "Du konsumierst @WEN1."
+
+SIEHE AUCH:
+     /std/food.c, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_EFFECTIVE_AC b/doc/props/P_EFFECTIVE_AC
new file mode 100644
index 0000000..ff7dd53
--- /dev/null
+++ b/doc/props/P_EFFECTIVE_AC
@@ -0,0 +1,87 @@
+P_EFFECTIVE_AC
+
+NAME:
+     P_EFFECTIVE_AC      "effective_ac"
+
+DEFINIERT IN:
+     <combat.h>
+
+BESCHREIBUNG:
+     Diese Property kommt sowohl in Ruestungen als auch in Waffen, die
+     schuetzen sollen, zum Einsatz.
+
+     In Ruestungen kann hier der Effektivwert der Ruestungsklasse vermerkt
+     werden, wenn diese noch durch eine DefendFunc() modifiziert wird
+     (soweit sich ein solcher Effektivwert angeben laesst).
+
+     In einigen Gilden koennen Waffen auch als Ruestung eingesetzt werden
+     (z.B. beim Parieren eines Angriffs). In dieser Property kann man die
+     Ruestungsklasse eintragen, die die Waffe bei solchen Aktionen aufweisen
+     soll. Dabei ist man an die ueblichen Beschraenkungen der
+     Ruestungsklasse gebunden! (s. /sys/combat.h)
+
+BERMERKUNGEN:
+     Das Kaempferspellbook verwendet fuer Paraden etc. P_EFFECTIVE_AC anstatt
+     P_AC, wenn verfuegbar.
+
+BEISPIELE:
+     * DefendFuncs: 
+       Der doppelte Mittelwert der DefendFunc wird zur Basis-AC dazuaddiert,
+       da sich der 'Schutzwert = random(Basis-AC) + absolut(DefendFunc-Wert)'
+       berechnet.
+
+     // #1 Eine Ruestung mit P_AC von 35 und randomisierter DefendFunc
+        SetProp(P_AC, 35);
+        SetProp(P_DEFEND_FUNC, this_object());
+
+        int DefendFunc(...) {
+          return random(20);                       // Mittelwert: 10
+        }
+        -> SetProp(P_EFFECTIVE_AC, 55);            // 35 + 2*10 = 55
+
+     // #2 Eine Ruestung mit P_AC von 35 und teilrandomisierter DefendFunc
+        SetProp(P_AC, 35);
+        SetProp(P_DEFEND_FUNC, this_object());
+
+        int DefendFunc(...) {
+          return 20 + random(10);                  // Mittelwert: 20 + 5
+        }
+        -> SetProp(P_EFFECTIVE_AC, 85);            // 35 + 2*(20+5) = 85
+
+     * Sonderfunktion im Kontext der Kaempfergilde:
+       Auch wenn der eigentliche AC-Wert durch keine DefendFunc oAe
+       modifiziert wird, sind abweichende Werte in P_EFFECTIVE_AC zB in der
+       Kaempfergilde fuer Paraden oder aehnliches sinnvoll. Maximalwert ist
+       dafuer der doppelte Wert des Basis-AC-Wertes.
+
+     // #3 Ein schon sehr gutes Schild, welches bei der Schildparade aber
+     //    noch besser schuetzen soll.
+        SetProp(P_ARMOUR_TYPE, AT_SHIELD);
+        SetProp(P_AC, 38);
+        SetProp(P_EFFECTIVE_AC, 55);
+
+     // #4 Ein sehr labbriges Schild schuetzt zwar gegen normale Schlaege,
+     //    ist zum Parieren aber irgendwie ungeeignet weil unkontrollierbar.
+        SetProp(P_ARMOUR_TYPE, AT_SHIELD);
+        SetProp(P_AC, 38);
+        SetProp(P_EFFECTIVE_AC, 20);
+
+     * Waffen:
+       P_EFFECTIVE_AC wird im Kaempferspellbook als Bonus dazugezaehlt! Daher
+       sollten gute Parierwaffen auch einen niedrigeren P_WC-Wert haben.
+       Reine Parierwaffen duerfen den maximalen AC-Wert von Schilden als
+       Maximum gesetzt haben - die Balance klaert ggf, ob das auch auf den
+       Gildenparierwert anwendbar ist.
+
+     // #5 Eine maessige Hellebarde/Axtwaffe mit Parierhaken.
+        SetProp(P_WEAPON_TYPE, WT_AXE);
+        SetProp(P_WC, 100);
+        SetProp(P_EFFECTIVE_AC, 25);
+
+SIEHE AUCH:
+     Waffen:     P_WC, P_TOTAL_WC, P_EFFECTIVE_WC, HitFunc()
+     Ruestungen: P_AC, P_TOTAL_AC, DefendFunc()
+     Files:      /std/weapon.c, /std/weapon/combat.c
+     Balance:    waffen, ruestungen, properties, kaempferboni
+
+6. Nov 2011 Gloinson
diff --git a/doc/props/P_EFFECTIVE_WC b/doc/props/P_EFFECTIVE_WC
new file mode 100644
index 0000000..0328629
--- /dev/null
+++ b/doc/props/P_EFFECTIVE_WC
@@ -0,0 +1,86 @@
+P_EFFECTIVE_WC
+
+NAME:
+     P_EFFECTIVE_WC     "effective_wc"
+
+DEFINIERT IN:
+     <combat.h>
+
+BESCHREIBUNG:
+     Diese Property kommt sowohl in Waffen als auch Ruestungen, die Schaden
+     machen sollen, zum Einsatz.
+
+     Falls die Staerke einer Waffe noch durch eine HitFunc() modifiziert
+     wird, sollte hier der Effektivwert der Waffenklasse vermerkt werden,
+     soweit er sich angeben laesst.
+     Diese Property dient vor allem dazu, eine Waffe mit HitFunc() korrekt
+     einzuschaetzen.
+
+     In einigen Gilden koennen Ruestungen auch als Waffen eingesetzt werden
+     (z.B. ein Paar Schuhe zum Treten). In dieser Property kann man die
+     Waffenklasse eintragen, die die Ruestung bei solchen Aktionen aufweisen
+     soll. Dabei ist man an die ueblichen Beschraenkungen der Waffenklasse
+     gebunden! (s. /sys/combat.h)
+     Der Ruestung kann man dann auch einen Schadenstyp mit auf den Weg
+     geben.
+
+BEMERKUNGEN:
+     Das Kaempferspellbook verwendet bei Ruestungen P_AC, wenn
+     P_EFFECTIVE_WC nicht gesetzt ist.
+
+BEISPIELE:
+     * HitFuncs:
+       Der doppelte Mittelwert der HitFunc wird zur Basis-WC dazuaddiert,
+       da sich der 'Angriffswert = random(Basis-WC) + absolut(HitFunc-Wert)'
+       berechnet.
+
+     // #1 Waffe mit Basis-WC 120 und randomisierter HitFunc
+        SetProp(P_WC, 120);
+        SetProp(P_HIT_FUNC, this_object());
+       
+        int HitFunc(...) {
+          return random(30);                       // Mittelwert: 15
+        }
+        -> SetProp(P_EFFECTIVE_WC, 150);           // 120 + 2*15 = 150
+     
+     // #2 Waffe mit Basis-WC 120 und teilweise absoluter HitFunc
+        SetProp(P_WC, 120);
+        SetProp(P_HIT_FUNC, this_object());
+       
+        int HitFunc(...) {
+          return 30 + random(10);                  // Mittelwert: 30 + 5
+        }
+        -> SetProp(P_EFFECTIVE_WC, 190);           // 120 + 2*(30+5) = 190
+
+     * Ruestungen (zB Gildennutzung):
+       Der Maximalwert fuer die P_EFFECTIVE_WC bei Kaempfern ist der jeweils
+       doppelte maximale P_AC-Wert. Angabe eines Schadenstyps ist sinnvoll.
+
+     // #3 Ein paar Schuhe, mit maximalem Schlag-/Saeureschaden.
+        SetProp(P_ARMOUR_TYPE, AT_BOOT);
+        SetProp(P_AC, 2);
+        SetProp(P_DAM_TYPE, ({DT_BLUDGEON,DT_ACID}));
+        -> SetProp(P_EFFECTIVE_WC, 12);  // hoechstmoeglicher Wert bei
+                                         // Schuhen, da deren max. P_AC = 6
+     // aequivalent und zukunftssicher:
+        -> SetProp(P_EFFECTIVE_WC, 2 * VALID_ARMOUR_CLASS[AT_BOOT]);
+
+     // #4 Ein Schild mit spitzem Dorn. (Stichschaden beim Schildstoss.)
+        SetProp(P_ARMOUR_TYPE, AT_SHIELD);
+        SetProp(P_AC, 5);
+        SetProp(P_DAM_TYPE, ({DT_PIERCE}));
+        SetProp(P_EFFECTIVE_WC, 55);
+
+     // #5 Ein Gummischild ist schlecht fuer Angriffe. BOING!
+        SetProp(P_ARMOUR_TYPE, AT_SHIELD);
+        SetProp(P_AC, 30);
+        SetProp(P_DAM_TYPE, ({DT_BLUDGEON}));
+        SetProp(P_EFFECTIVE_WC, 10);
+
+SIEHE AUCH:
+     Waffen:     P_WC, P_TOTAL_WC, HitFunc()
+     Ruestungen: P_AC, P_TOTAL_AC, P_EFFECTIVE_AC, DefendFunc()
+     Files:      /std/weapon.c, /std/weapon/combat.c
+     Balance:    waffen, ruestungen, properties, kaempferboni
+
+6. Nov 2011 Gloinson
diff --git a/doc/props/P_EMPTY_MSG b/doc/props/P_EMPTY_MSG
new file mode 100644
index 0000000..7248d8e
--- /dev/null
+++ b/doc/props/P_EMPTY_MSG
@@ -0,0 +1,24 @@
+NAME:
+     P_EMPTY_MSG                   "std_food_eater_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Konsumenten, wenn versucht wird, eine aufgebrauchte Speise
+     (also einen leeren Behaelter) zu konsumieren.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise (also den leeren Behaelter)
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "@WER1 ist bereits leer."
+
+SIEHE AUCH:
+     /std/food.c, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_EMPTY_PROPS b/doc/props/P_EMPTY_PROPS
new file mode 100644
index 0000000..a8156d7
--- /dev/null
+++ b/doc/props/P_EMPTY_PROPS
@@ -0,0 +1,33 @@
+NAME:
+     P_EMPTY_PROPS                 "std_food_empty_props"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Mapping mit Properties fuer den leeren Behaelter, der uebrig bleibt,wenn
+     eine Speise aufgebraucht ist. Alle enthaltenen Properties werden gesetzt,
+     wenn keine Portionen mehr vorhanden sind.
+     Bereits in diesen Properties eingetragene Werte werden ueberschrieben!
+     Wenn diese Property nicht gesetzt ist, wird die Speise zerstoert, wenn
+     alle Portionen aufgebraucht ist - es bleibt also kein Behaelter zurueck.
+     Achtung: Es werden keine closures in diesem Mapping unterstuetzt!
+     
+BEMERKUNGEN:
+     Bei der Abfrage von P_VALUE und P_WEIGHT in der Speise, werden die dazu
+     in P_EMPTY_PROPS gespeicherten Werte verwendet, um das Gewicht/Wert des
+     leeren Behaelters zum Gesamtwert der Speise zu addieren.
+     Man kann alle Properties in dieses Mapping eintragen, die sich in der
+     Speise per SetProp setzen lassen. Zusaetzlich kann man Arrays in P_IDS
+     und P_ADJECTIVES speichern, die per Add-Methode in der Speise
+     hinzugefuegt werden, nachdem die im create() der Speise hinzugefuegten
+     Ids/Adjectives dort entfernt wurden.
+     
+BEISPIELE:
+     Beispiele zur Verwendung findet man unter /doc/beispiele/food
+
+SIEHE AUCH:
+     /std/food.c, wiz/food
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_ENABLE_IN_ATTACK_OUT b/doc/props/P_ENABLE_IN_ATTACK_OUT
new file mode 100644
index 0000000..d60a807
--- /dev/null
+++ b/doc/props/P_ENABLE_IN_ATTACK_OUT
@@ -0,0 +1,33 @@
+NAME:
+	P_ENABLE_IN_ATTACK_OUT		"enable_in_attack_out"
+
+DEFINIERT IN:
+	/sys/combat.h
+
+BESCHREIBUNG:
+	Normalerweise wird die bekannte Taktik Rein-Angriff-Raus
+	standardmaessig unterbunden, damit NPCs auch eine Chance haben, sich
+	zu verteidigen. Hierzu wird der Schaden innerhalb do_damage()
+	durch einen Wert geteilt, der sich aus der Verweildauer des
+	Angreifers im Raum ergibt (bis zu 3 Sekunden).
+	Da manche NPCs so konzeptioniert wurden, dass man sie nur mit der
+	erwaehnten Taktik toeten kann, kann man sie auch explizit erlauben
+	(manche NPCs verwenden auch eigene Methoden, diese Taktik zu
+	 verbieten, und sie waere dann doppelt abgefangen).
+	Hierzu setzt man einfach die Property P_ENABLE_IN_ATTACK_OUT im NPC.
+
+BEISPIEL:
+	Das folgende Beispiel erlaubt einfach mal die angesprochene Taktik:
+	  void create()
+	  { ...
+	    SetProp(P_ENABLE_IN_ATTACK_OUT,1);
+	    ...
+	  }
+	Jetzt kann man den NPC mit Rein-Angriff-Raus auch wirkungsvoll
+	bekaempfen.
+
+SIEHE AUCH:
+	do_damage(), P_LAST_MOVE, /std/living/life.c
+
+-----------------------------------------------------------------------------
+Last modified: Sat Jan 30 12:53:00 1999 by Patryn
diff --git a/doc/props/P_ENEMY_DAMAGE b/doc/props/P_ENEMY_DAMAGE
new file mode 100644
index 0000000..216339d
--- /dev/null
+++ b/doc/props/P_ENEMY_DAMAGE
@@ -0,0 +1,31 @@
+P_ENEMY_DAMAGE
+
+NAME:
+     P_ENEMY_DAMAGE "enemy_damage"
+
+DEFINIERT IN:
+     <living/life.h>
+
+BESCHREIBUNG:
+     In dieser Property ist vermerkt, welches Wesen diesem Wesen wieviel
+     Schaden zugefuegt hat.
+
+     Die Property enthaelt ein Mapping, das den Angreifern den
+     errechten Schaden zuordnet:
+     ([ <obname1>: <damage>; <owner>, ... ])
+
+       <obname1>: Name des Objekts, das den Schaden verursacht hat (string),
+                  z.B. "/magier:zesstra"
+       <damage> : Schadensmenge (int)
+       <owner>  : wenn das schadensverursachende Wesen ein NPC war/ist,
+                  welches P_HELPER_NPC gesetzt hatte und somit einem Spieler
+                  hilft, steht hier das Objekt des jeweiligen Spielers
+                  (object)
+
+BEMERKUNGEN:
+     Diese Property laesst sich nur abfragen!
+
+SIEHE AUCH:
+     P_HELPER_NPC
+----------------------------------------------------------------------------
+26.10.2009, Zesstra
diff --git a/doc/props/P_ENEMY_DEATH_SEQUENCE b/doc/props/P_ENEMY_DEATH_SEQUENCE
new file mode 100644
index 0000000..260d325
--- /dev/null
+++ b/doc/props/P_ENEMY_DEATH_SEQUENCE
@@ -0,0 +1,44 @@
+P_ENEMY_DEATH_SEQUENCE
+
+NAME:
+     P_ENEMY_DEATH_SEQUENCE        "enemy_death_sequence"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+     Ueber diese Property kann Einfluss auf die Todessequenz eines getoeten
+     Spielers genommen werden. Sie muss im toetenden Objekt, d.h. dem
+     Objekt welches die()/do_damage()/Defend() im Spieler gerufen hat,
+     gesetzt sein.
+
+     Es gibt folgende gueltige Werte:
+     - string: Pfad zu einer eigenen Todessequenz im gueltigen Format
+     - mixed*  Eine Todessequenz im Format des Todesraumes:
+               ({<int gesamtlaenge>,
+                 ([<int index1>: <string umgebrochene Meldung1>,
+                   <int index2>: <string umgebrochene Meldung2>,
+                   ...])
+               })
+     - mapping In die Standard-Lars-Todessequenz einzufuegende Zeilen:
+               ([<int zeitindex>: <string umgebrochener Text>])
+
+BEISPIELE:
+     // Pfad zu einer eigenen DSQ
+     SetProp(P_ENEMY_DEATH_SEQUENCE,  ".../passende_dsq.txt");
+
+     // eigene DSQ im Todesraumformat:
+     SetProp(P_ENEMY_DEATH_SEQUENCE,
+             ({ 2, ([1: "DU LERNST AUS DEINEM FEHLER.\n"])}));
+
+     // Einfuegen einer Meldung (des NPCs) in die Standard-Todessequenz
+     SetProp(P_ENEMY_DEATH_SEQUENCE,
+             ([5: "Du hoerst "+name(WEN)+" hoehnisch kichern.\n"]));
+
+SIEHE AUCH:
+     Tod:            die(L)
+     Todesmeldungen: P_KILL_NAME, P_KILL_MSG, P_DIE_MSG, P_MURDER_MSG
+                     P_ZAP_MSG, P_NEXT_DEATH_SEQUENCE
+     Sonstiges:      P_CORPSE, P_NOCORPSE, /room/death/death_room.c
+
+10. Nov 2011 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_ENTERCMDS b/doc/props/P_ENTERCMDS
new file mode 100644
index 0000000..0f7e3d9
--- /dev/null
+++ b/doc/props/P_ENTERCMDS
@@ -0,0 +1,33 @@
+NAME:
+    P_ENTERCMDS                   "leavecmds"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+    Ein Array mit Befehlen, die zum Betreten des Transporters fuehren. 
+
+BEISPIEL:
+    SetProp(P_ENTERCMDS,({ "betrete","betritt" }) );
+
+    Gibt der Spieler nun 'betrete xxx' ein, so sorgt /std/transport.c 
+    dafuer, das der Spieler auch auf oder in den Transporter bewegt 
+    wird. Vorausgesetzt natuerlich, er ist an einem Haltepunkt ange-
+    langt und es ist genuegend Platz dort.
+
+BEMERKUNGEN:
+    Um /std/transport.c nicht aufzublaehen, werden weitere Argumente wie
+    etwa 'betrete das|die|den xxx' _nicht_ unterstuetzt!
+
+    Hier muss der verantwortliche Magier schon eine eigene Loesung finden
+    und in seinen Transporter schreiben.
+
+    Sollen Kommandos zum Betreten UND Verlassen eines Transporters ver-
+    wendet werden koennen, muessen diese in P_TRAVEL_CMDS gesetzt werden.
+
+SIEHE AUCH:
+    P_LEAVEFAIL, P_ENTERFAIL, P_LEAVECMDS, P_TRAVEL_CMDS, transporter,
+
+LETZTE AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
+    
\ No newline at end of file
diff --git a/doc/props/P_ENTERFAIL b/doc/props/P_ENTERFAIL
new file mode 100644
index 0000000..2ecd1e6
--- /dev/null
+++ b/doc/props/P_ENTERFAIL
@@ -0,0 +1,24 @@
+NAME:
+    P_ENTERFAIL                   "enterfail"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+     Meldung an den Spieler, wenn er einen vollen Transporter betreten 
+     will. Ist die Propertie ein Array, so wird das erste Element als
+     Meldung an den Spieler, das zweite als Meldung an die Mitspieler 
+     im Raum geschickt.
+
+BEISPIEL:
+     SetProp(P_ENTERFAIL,"Dort ist wirklich kein Platz mehr fuer Dich");
+     
+     SetProp(P_ENTERFAIL, ({ "Dort ist wirklich kein Platz mehr fuer Dich",
+                             "versucht, auf die Kutsche zu klettern, wird "
+                            +"aber wieder heruntergeschickt" }) );
+
+SIEHE AUCH:
+     P_ENTERMSG, P_LEAVEFAIL, P_LEAVEMSG, transporter
+
+LETZTE AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
diff --git a/doc/props/P_ENTERMSG b/doc/props/P_ENTERMSG
new file mode 100644
index 0000000..2a2128e
--- /dev/null
+++ b/doc/props/P_ENTERMSG
@@ -0,0 +1,18 @@
+NAME:
+    P_ENTERMSG                    "entermsg"                    
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+     Array mit zwei Meldungen, eine fuer den Raum, den der Spieler
+     verlaesst, und eine fuer den Transporter, in den er geht.
+
+BEISPIEL:
+     SetProp(P_ENTERMSG, ({ "klettert in die Kutsche","klettert herein" }) );
+
+SIEHE AUCH:
+     P_ENTERFAIL, P_LEAVEFAIL, P_LEAVEMSG, transporter
+
+LETZTER AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
diff --git a/doc/props/P_ENV_MSG b/doc/props/P_ENV_MSG
new file mode 100644
index 0000000..b39e2c1
--- /dev/null
+++ b/doc/props/P_ENV_MSG
@@ -0,0 +1,26 @@
+NAME:
+     P_ENV_MSG                     "std_food_env_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Konsumenten, wenn eine Speise konsumiert werden soll,
+     die nicht im eigenen Inventory liegt.
+     Wenn diese Property leer ist, kann man die Speise dann sogar
+     konsumieren!
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "Vielleicht solltest Du @WEN1 vorher nehmen."
+
+SIEHE AUCH:
+     wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_ENV_TOO_HEAVY_MSG b/doc/props/P_ENV_TOO_HEAVY_MSG
new file mode 100644
index 0000000..8c73ac1
--- /dev/null
+++ b/doc/props/P_ENV_TOO_HEAVY_MSG
@@ -0,0 +1,31 @@
+NAME:
+    P_ENV_TOO_HEAVY_MSG                      "env_too_heavy_msg"                      
+
+DEFINIERT IN:
+    /sys/thing/moving.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt eine Meldung, die ausgegeben wird, wenn jemand
+     versucht, ein Objekt in einen Behaelter zu legen, und dieser dann fuer
+     sein Environment zu schwer wird.
+     Die Property ist im Behaelter zu setzen.
+     Ist diese Property nicht oder auf einen nicht-String-Wert gesetzt,
+     so wird die Standardmeldung ausgegeben.
+     ("<Behaelter> wuerde dir dann zu schwer werden.")
+     Der String in der Property wird noch durch replace_personal()
+     verarbeitet, das zu bewegende Objekt wird als erstes, der Behaelter als
+     zweites Objekt angegeben. Danach wird der String auf 78 Zeichen
+     umgebrochen.
+     Das Setzen eines leeren Strings unterdrueckt die Ausgabe einer Meldung
+     ganz.
+
+BEISPIELE:
+     SetProp(P_ENV_TOO_HEAVY_MSG, "Mit @WEM1 koenntest du den Rucksack nicht"
+                                  " mehr tragen.");
+
+SIEHE AUCH:
+     Aehnliches: P_TOO_HEAVY_MSG, P_TOO_MANY_MSG, P_NOINSERT_MSG,
+                 P_NOLEAVE_MSG, P_NODROP, P_NOGET 
+     Erfolg:     P_PICK_MSG, P_DROP_MSG, P_GIVE_MSG, P_PUT_MSG,
+                 P_WEAR_MSG, P_WIELD_MSG
+     Sonstiges:  replace_personal(E), /std/living/put_and_get.c
diff --git a/doc/props/P_EQUIP_TIME b/doc/props/P_EQUIP_TIME
new file mode 100644
index 0000000..71b2f35
--- /dev/null
+++ b/doc/props/P_EQUIP_TIME
@@ -0,0 +1,26 @@
+P_EQUIP_TIME
+
+NAME:
+      P_EQUIP_TIME			"equip_time"
+
+DEFINIERT IN:
+      /sys/combat.h
+
+BESCHREIBUNG:
+      Innerhalb von Waffen und Ruestungen wird in dieser Property

+      registriert, wann diese zuletzt gezueckt bzw. angezogen wurden.
+      Innerhalb der Funktionen wield_me() in '/std/weapon/combat' bzw.

+      DoWear() in '/std/armour/combat' wird hierbei jeweils folgende Aktion

+      ausgefuehrt:
+	SetProp(P_EQUIP_TIME,time());
+
+SIEHE AUCH:
+      Verwandt:		P_LAST_USE
+      Waffen:		P_UNWIELD_TIME
+			DoWield()
+      Ruestungen:	DoWear()
+      Sonstiges:	time()
+			/std/weapon/combat.c, /std/armour/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Sun Jul 26 23:59:12 1998 by Patryn
diff --git a/doc/props/P_EVAL_FACTORS b/doc/props/P_EVAL_FACTORS
new file mode 100644
index 0000000..04e881e
--- /dev/null
+++ b/doc/props/P_EVAL_FACTORS
@@ -0,0 +1,8 @@
+NAME:
+    P_EVAL_FACTORS                "inpc_eval_factors"           
+
+DEFINIERT IN:
+    /sys/inpc/eval.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_EVAL_OFFSETS b/doc/props/P_EVAL_OFFSETS
new file mode 100644
index 0000000..d82ef39
--- /dev/null
+++ b/doc/props/P_EVAL_OFFSETS
@@ -0,0 +1,8 @@
+NAME:
+    P_EVAL_OFFSETS                "inpc_eval_offsets"           
+
+DEFINIERT IN:
+    /sys/inpc/eval.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_EXITS b/doc/props/P_EXITS
new file mode 100644
index 0000000..3b3856f
--- /dev/null
+++ b/doc/props/P_EXITS
@@ -0,0 +1,9 @@
+NAME:
+    P_EXITS                       "exits"                       
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Mapping aller unmittelbar sichtbaren Ausgaenge mit zugehoerigen
+     Nachbarraeumen. Sollte nur mittels AddExit() benutzt werden.
diff --git a/doc/props/P_FAO b/doc/props/P_FAO
new file mode 100644
index 0000000..62f33e1
--- /dev/null
+++ b/doc/props/P_FAO
@@ -0,0 +1,19 @@
+P_FAO
+
+NAME:
+     P_FAO      "fraternitasdonoarchmagorum"
+
+DEFINIERT IN:
+     <player/fao.h>
+
+BESCHREIBUNG:
+     Fraternitas-relevante Property.
+
+     Genaue Informationen unbekannt.
+     Schreibender Zugriff ist nur EMs oder dem FAOMASTER (s. Headerfile)
+     moeglich.
+
+SIEHE AUCH:
+     P_FAO_PORTALS
+
+1.September 2008 Gloinson
diff --git a/doc/props/P_FAO_PORTALS b/doc/props/P_FAO_PORTALS
new file mode 100644
index 0000000..465750a
--- /dev/null
+++ b/doc/props/P_FAO_PORTALS
@@ -0,0 +1,22 @@
+P_FAO_PORTALS
+
+NAME:
+     P_FAO_PORTALS      "fraternitasdonoarchmagorumPORTALS"
+
+DEFINIERT IN:
+     <player/fao.h>
+
+BESCHREIBUNG:
+     Fraternitas-relevante Property.
+
+     Enthaelt eine Array mit einer Liste der ueber die Fraternitas
+     gefundenen und benutzbaren Seher-Portale.
+
+     Genaue Informationen unbekannt.
+     Schreibender Zugriff ist nur EMs oder dem FAOMASTER (s. Headerfile) 
+     moeglich.
+
+SIEHE AUCH:
+     P_FAO_PORTALS, P_SEERDOORS
+     
+1.September 2008 Gloinson
diff --git a/doc/props/P_FISH b/doc/props/P_FISH
new file mode 100644
index 0000000..c694c09
--- /dev/null
+++ b/doc/props/P_FISH
@@ -0,0 +1,75 @@
+NAME:
+    P_FISH                        "fish"
+
+DEFINIERT IN:
+    /sys/fishing.h
+
+BESCHREIBUNG:
+    Enthaelt Einstellungen zu allem, was mit Fischen zu tun hat. 
+    Kann in Fischen, Raeumen und Koedern gesetzt werden. Die verfuegbaren 
+    Optionen und Funktionsweisen sind in den nachfolgenden Abschnitten 
+    aufgefuehrt.
+
+    Fische:
+    *******
+    Die Property legt zusaetzliche Eigenschaften fest:
+
+      F_NOROTTEN
+        Fisch fault nicht; ggf. sollte hier auch gleich F_NOHEAL gesetzt 
+        werden, weil sonst eine unverderbliche tragbare Tanke erzeugt wuerde.
+      F_NOTHUNGRY
+        Fisch frisst Koeder nur, wenn er auch wirklich nachher an der Angel
+        haengt. Ist er zu schwer fuer die Angel und reisst ab, bleibt der
+        Koeder erhalten.
+      F_REPLACE
+        Fisch soll sich beim Entfernen von der Angel verwandeln. Hierzu ist
+        die Funktion ReplaceFish() im Fisch zu definieren, die sich um die
+        Verwandlung kuemmert (z.B. Monster clonen und Fisch zerstoeren; ein
+        Beispiel findet sich in /d/ebene/fraggle/angel2/obj/saegefisch.c).
+      F_NOHEAL
+        Fisch heilt nicht bei Verzehr
+
+    Raum (OPTIONAL):
+    ****************
+    Legt die Fischdichte des Gewaessers fest. Der eingestellte Wert wirkt 
+    sich auf die Wartezeit aus, die der Angler verbringen muss, bis ein 
+    Fisch anbeisst. Berechnung im Detail (alle Zahlenwerte in Sekunden):
+    - Basis-Wartezeit: delay = 80
+    - Die Werte von P_FISH von Raum und Koeder werden addiert:
+      summe = raum->QueryProp(P_FISH) + koeder->QueryProp(P_FISH)
+      -> positive Werte (Bonus) werden auf 60 begrenzt und mit Zufalls-
+         komponente von <delay> abgezogen:
+         delay -= random(summe)
+      -> negative Werte (Malus) werden auf -300 begrenzt und mit Zufalls-
+         komponente auf <delay> aufgeschlagen:
+         delay += random(-summe)
+
+    Zusaetzlich wird ein weiterer Malus auf die Wartezeit faellig, falls 
+    P_WATER in der Angel und/oder P_WATER im Koeder nicht zum aktuellen 
+    Gewaesser passen. Der Malus betraegt jeweils 60+random(60) Sekunden.
+    
+    Der Standardwert fuer P_FISH im Raum ist 0 und bedeutet 100 % Bestand.
+    Positive Werte erhoehen die Dichte, negative senken sie. Positive Werte 
+    sollten nicht >100 sein.
+
+    Sofern sich die Werte fuer P_FISH in den empfohlenen Grenzen bewegen,
+    koennen Abzuege fuer falsches Gewaesser ueblicherweise kaum durch
+    Boni auf Angel oder Koeder kompensiert werden. Ausserdem ist zu
+    bedenken, dass es keine Boni fuer richtige Gewaesserwahl gibt.
+ 
+
+    Koeder (OPTIONAL):
+    ******************
+    Ein Koeder kann mittels P_FISH die Fischdichte modifizieren, um hierueber
+    ein besseres Beissen der Fische zu simulieren (reduziert die Wartezeit
+    beim Angeln, siehe oben unter "Raum"). Wenn also der Raum einen Wert
+    von -100 gesetzt hat und der Koeder +100, entspricht die Fischdichte im 
+    Gewaesser wieder dem Normalwert.
+
+SIEHE AUCH:
+
+    Properties: P_WATER
+    Methoden:   GetAquarium(L)
+
+------------------------------------------------------------------------------
+Zuletzt geaendert: 2014-Aug-21, Arathorn
diff --git a/doc/props/P_FLAGS b/doc/props/P_FLAGS
new file mode 100644
index 0000000..3c54aea
--- /dev/null
+++ b/doc/props/P_FLAGS
@@ -0,0 +1,8 @@
+NAME:
+    P_FLAGS                       "can_flags"                   
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Flags des Spielers
diff --git a/doc/props/P_FOLLOW_SILENT b/doc/props/P_FOLLOW_SILENT
new file mode 100644
index 0000000..7662ad1
--- /dev/null
+++ b/doc/props/P_FOLLOW_SILENT
@@ -0,0 +1,9 @@
+NAME:
+    P_FOLLOW_SILENT               "follow_silent"               
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Wenn diese Property 1 ist, wird der MOVE vom verfolge Silent ausge-
+     fuehrt.
diff --git a/doc/props/P_FOOD b/doc/props/P_FOOD
new file mode 100644
index 0000000..769694f
--- /dev/null
+++ b/doc/props/P_FOOD
@@ -0,0 +1,24 @@
+NAME:
+     P_FOOD                        "food"
+
+DEFINIERT IN:
+     /sys/living/life.h
+
+BESCHREIBUNG:
+
+     - Lebewesen
+       Numerischer Wert fuer den Saettigungsgrad eines Lebewesens.
+       Der maximale Wert steht in P_MAX_FOOD.
+
+     - Speisen/Kneipen
+       Numerischer Wert fuer den Saettigungsgrad einer Portion einer
+       Speise. Ist diese Property nicht gesetzt, kann man diese
+       Speise nicht essen. Eine funktionierende Speise _muss_ entweder
+       P_FOOD oder P_DRINK groesser 0 gesetzt haben.
+
+SIEHE AUCH:
+     P_MAX_FOOD, P_FOOD_DELAY, consume,
+     P_DRINK, P_ALCOHOL, wiz/food
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_FOOD_DELAY b/doc/props/P_FOOD_DELAY
new file mode 100644
index 0000000..11ccf6e
--- /dev/null
+++ b/doc/props/P_FOOD_DELAY
@@ -0,0 +1,10 @@
+NAME:
+    P_FOOD_DELAY                 "food_delay"                     
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Anzahl der heart_beats, bis P_FOOD um einen Punkt sinkt.
+     Aenderungen dieser Property in Spielern beduerfen der 
+     Genehmigung des EM fuer Balance.
diff --git a/doc/props/P_FOOD_FULL_MSG b/doc/props/P_FOOD_FULL_MSG
new file mode 100644
index 0000000..a331ec5
--- /dev/null
+++ b/doc/props/P_FOOD_FULL_MSG
@@ -0,0 +1,24 @@
+NAME:
+     P_FOOD_FULL_MSG               "std_food_full_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Konsumenten, wenn eine Speise gegessen werden soll,
+     obwohl dieser nichts mehr essen kann.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "Du bist zu satt, das schaffst Du nicht mehr."
+
+SIEHE AUCH:
+     P_FOOD, P_MAX_FOOD, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_FORCE_MURDER_MSG b/doc/props/P_FORCE_MURDER_MSG
new file mode 100644
index 0000000..cf0157c
--- /dev/null
+++ b/doc/props/P_FORCE_MURDER_MSG
@@ -0,0 +1,39 @@
+NAME:
+	P_FORCE_MURDER_MSG		"force_murder_msg"
+
+DEFINIERT IN:
+	/sys/properties.h
+
+BESCHREIBUNG:
+	Ob der Tod eines NPCs auf dem Moerder-Kanal erscheint, haengt davon
+	ab, wie oft und welche Art von NPCs in der letzten Zeit getoetet
+	wurden. Zum Beispiel ist es eher selten, dass ein schwacher NPC auf
+	dem Kanal erscheint, wenn kuerzlich viele starke NPCs getoetet
+	wurden. Mittels der Property P_FORCE_MURDER_MSG kann man auf diese
+	Regelung Einfluss nehmen.
+	Ein Wert groesser Null erzwingt die Meldung auf dem Moerder-Kanal,
+	ein Wert kleiner Null unterdrueckt sie generell. Letzteres ist
+	insbesondere fuer allzuoft getoetete Monster sinnvoll, um den
+	Moerder-Kanal nicht uebermaessig zu belasten. Mit dem Erzwingen der
+	Meldungen sollte man somit vorsichtig sein: Weniger ist oftmals
+	besser als zu viel!
+	Die Defaulteinstellung von P_FORCE_MURDER_MSG ist natuerlich Null
+	und fuehrt zur bereits beschriebenen opferabhaengigen Meldung.
+
+BEISPIELE:
+	Ein grosser starker NPC, der getoetet wurde, sollte schon eine tolle
+	Meldung auf dem Moerder-Kanal erzeugen. In der Property
+	P_MURDER_MSG koennen hierzu alternative Texte zu den normal per
+	Zufall ausgewaehlten angegeben werden:
+	  SetProp(P_MURDER_MSG,
+                  "Nicht schlecht, aber das schafft eh nur einer!");
+	  SetProp(P_FORCE_MURDER_MSG,1);
+	Zwar ist es bei grossen NPCs hinreichend wahrscheinlich, dass es
+	infolge derer Staerke zur automatischen Ausgabe einer Moerdermeldung
+	kommt, aber mit der letzten Zeile wurde dies absolut sichergestellt.
+
+SIEHE AUCH:
+	P_MURDER_MSG, P_ZAP_MSG, P_KILL_MSG, P_DIE_MSG, P_CORPSE, P_NOCORPSE
+
+----------------------------------------------------------------------------
+Last modified: Tue Nov 10 02:15:26 1998 by Patryn
diff --git a/doc/props/P_FREE_HANDS b/doc/props/P_FREE_HANDS
new file mode 100644
index 0000000..6143cad
--- /dev/null
+++ b/doc/props/P_FREE_HANDS
@@ -0,0 +1,22 @@
+P_FREE_HANDS
+NAME:
+    P_FREE_HANDS                  "free_hands"
+
+DEFINIERT IN:
+    /sys/living/combat.h
+
+BESCHREIBUNG:
+    Anzahl der freien Haende.
+    Effektiv nur ein die Differenz von P_MAX_HANDS und P_USED_HANDS.
+
+BEMERKUNGEN:
+    Keine echte Property. Die Methode /std/living/combat::_query_free_hands
+    stellt die Daten zusammen. Nicht setzen!
+
+SIEHE AUCH:
+    P_HANDS, P_HANDS_USED_BY
+    P_MAX_HANDS, P_USED_HANDS
+    UseHands, FreeHands
+    /std/weapon.c, /std/spellbook.c
+
+1. Okt 2012, Gloinson
diff --git a/doc/props/P_FRIEND b/doc/props/P_FRIEND
new file mode 100644
index 0000000..ded080c
--- /dev/null
+++ b/doc/props/P_FRIEND
@@ -0,0 +1,24 @@
+NAME:
+	P_FRIEND			"friend"
+
+DEFINIERT IN:
+	<combat.h>
+
+BESCHREIBUNG:
+	Setzt man diese Property in einem NPC auf einen Wert ungleich Null,
+	so wird der NPC bei Zauberspruechen, die auf bestimmte Gruppen
+	wirken, der Gruppe der Spieler und nicht der Gruppe der NPCs
+	zugeordnet. Ausserdem wird der NPC bei einem "toete alle" nicht mit
+	angegriffen.
+	Wurde der NPC einem Spieler per AssocMember() zugeordnet, so
+	befindet sich der NPC automatisch im jeweiligen Team des Spielers
+	 (moeglichst auch in der selben Kampfreihe), und die Property hat
+	dann automatisch das Spielerobjekt als Wert.
+	Da dieser Wert in diesem Fall natuerlich ungleich Null ist, wird der
+	NPC dann auch der Gruppe der Spieler zugeordnet.
+
+SIEHE AUCH:
+	FindGroup(), AssocMember(), P_TEAM_ASSOC_MEMBERS, /std/living/team.c
+
+----------------------------------------------------------------------------
+Last modified: Tue Dec 29 17:02:55 1998 by Patryn
diff --git a/doc/props/P_FROG b/doc/props/P_FROG
new file mode 100644
index 0000000..5f64eac
--- /dev/null
+++ b/doc/props/P_FROG
@@ -0,0 +1,8 @@
+NAME:
+    P_FROG                        "frog"                        
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Gesetzt, wenn der Spieler ein Frosch ist.
diff --git a/doc/props/P_FUEL b/doc/props/P_FUEL
new file mode 100644
index 0000000..890ca60
--- /dev/null
+++ b/doc/props/P_FUEL
@@ -0,0 +1,26 @@
+NAME:
+    P_FUEL                        "fuel"                        
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Numerischer Wert fuer die Zeitdauer, die die Lichtquelle noch
+     leuchten kann. Standardmaessig ist der Wert auf 20 gesetzt.
+
+     Setzt man die Property auf einen Wert, der groesser ist als der vorige
+     Maximalwert, wird dieser auf den neuen Wert erhoeht. Aendert man den
+     Brennstoffvorrat der Lichtquelle hingegen mittels AddFuel(), so wird
+     der Wert von P_FUEL ueber den Maximalwert hinaus erhoeht.
+
+HINWEIS:
+     Fuer Aenderungen an der Property kann auch die Funktion AddFuel()
+     verwendet werden. 
+
+SIEHE AUCH:
+     Basisklassen: /std/lightsource.c
+     Properties:   P_LIGHTDESC, P_DO_DESTRUCT, P_LIGHT
+     Methoden:     AddFuel(L)
+
+LETZTE AENDERUNG:
+    22. Dez. 2015, Arathorn
diff --git a/doc/props/P_FUNC_MSG b/doc/props/P_FUNC_MSG
new file mode 100644
index 0000000..b4f9d1e
--- /dev/null
+++ b/doc/props/P_FUNC_MSG
@@ -0,0 +1,21 @@
+NAME:
+    P_FUNC_MSG                    "func_msg"                    
+
+DEFINIERT IN:
+    /sys/room/description.h
+
+BESCHREIBUNG:
+     Liste mit Funktionen, die zufaellig im Raum aufgerufen werden.
+
+     Hier ist nur eine zur rufende lokale Methode als String oder eine
+     Sammlung davon als Stringarray gespeichert.
+
+ANMERKUNGEN:
+     Bitte AddRoomMessage() zum Hinzufuegen/Ueberschreiben benutzen!
+
+SIEHE AUCH:
+     LFuns:    AddRoomMessage()
+     Verwandt: tell_room(), ReceiveMsg()
+     Props:    P_ROOM_MSG, P_MSG_PROB
+
+2.Feb 2016 Gloinson
diff --git a/doc/props/P_FW_ALWAYS_READABLE b/doc/props/P_FW_ALWAYS_READABLE
new file mode 100644
index 0000000..31700ed
--- /dev/null
+++ b/doc/props/P_FW_ALWAYS_READABLE
@@ -0,0 +1,8 @@
+NAME:
+    P_FW_ALWAYS_READABLE          "fw_always_readable"          
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_FW_UNDERSTAND b/doc/props/P_FW_UNDERSTAND
new file mode 100644
index 0000000..ff8f6e6
--- /dev/null
+++ b/doc/props/P_FW_UNDERSTAND
@@ -0,0 +1,8 @@
+NAME:
+    P_FW_UNDERSTAND               "fw_understand"               
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_GENDER b/doc/props/P_GENDER
new file mode 100644
index 0000000..93f73dc
--- /dev/null
+++ b/doc/props/P_GENDER
@@ -0,0 +1,9 @@
+NAME:
+    P_GENDER                      "gender"                      
+
+DEFINIERT IN:
+    /sys/thing/language.h
+
+BESCHREIBUNG:
+     Grammatikalisches Geschlecht des Objektes:
+     (Definiert in language.h) MALE, FEMALE oder NEUTER
diff --git a/doc/props/P_GHOST b/doc/props/P_GHOST
new file mode 100644
index 0000000..9cbf309
--- /dev/null
+++ b/doc/props/P_GHOST
@@ -0,0 +1,8 @@
+NAME:
+    P_GHOST                       "ghost"                       
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Gesetzt, wenn der Spieler tot ist.
diff --git a/doc/props/P_GIVE_MSG b/doc/props/P_GIVE_MSG
new file mode 100644
index 0000000..bd6a624
--- /dev/null
+++ b/doc/props/P_GIVE_MSG
@@ -0,0 +1,65 @@
+P_GIVE_MSG
+NAME:
+     P_GIVE_MSG				"give_message"
+
+DEFINIERT IN:
+     /sys/living/put_and_get.h
+
+BESCHREIBUNG:
+     Mit P_GIVE_MSG kann man die Meldung, die man beim Uebergeben eines
+     Objektes bekommt, modifizieren.
+
+     Folgende Werte sind moeglich:
+
+     o 0
+       Es wird eine Standardmeldung ausgegeben. Dies ist Voreinstellung.
+
+     o NO_PNG_MSG	== -1
+       Es wird keinerlei Meldung ausgegeben
+
+     o Ein Array aus Strings
+       Der erste String wird an den Spieler ausgegeben, der zweite
+       (optionale) an den Raum, der dritte (ebenfalls optionale) an den
+       Empfaenger.
+
+       Die Strings werden durch die Funktion replace_personal() geparst.
+	Objekt1 - Spieler
+        Objekt2 - das Objekt, das uebergeben wird
+	Objekt3 - Empfaenger
+
+       Wird der zweite String nicht angegeben, erfolgt keine Meldung an den
+       Raum. Beim Fehlen des dritten gibt es keine Meldung an den Empfaenger.
+
+BEISPIEL:
+     void create() {
+      ...
+      SetProp( P_SHORT, "Etwas Sand" );
+      SetProp( P_LONG, break_string(
+	"Ein wenig magischer Sand. Sehr feinkruemelig.",78 ));
+
+      SetProp( P_NAME, "Sand" );
+      AddId( ({"sand"}) );
+      SetProp( P_GENDER, MALE );
+
+      SetProp( P_GIVE_MSG, ({
+       "Du laesst @WEN2 in @WESSEN3 Haende rieseln.",
+       "@WER1 laesst @WENU2 in @WESSEN3 Haende rieseln.",
+       "@WER1 laesst @WENU2 in deine Haende rieseln."}));
+       ...
+      }
+
+     Das ganze fuehrt bei Ugars "gib sand an peter" zu folgenden
+     Meldungen:
+
+     Ugar: "Du laesst den Sand in Peters Haende rieseln."
+     Raum: "Ugar laesst Sand in Peters Haende rieseln."
+     Peter: "Ugar laesst Sand in deine Haende rieseln."
+
+SIEHE AUCH:
+     Aehnliches: P_DROP_MSG, P_PUT_MSG, P_PICK_MSG, P_SHOW_MSG
+     Fehler:     P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_TOO_MANY_MSG,
+                 P_NOINSERT_MSG, P_NOLEAVE_MSG, P_NODROP, P_NOGET 
+     Sonstiges:  replace_personal(E), give(L), give_objects(L),
+		 give_notify(L), /std/living/put_and_get.c
+
+14. Maerz 2004 Gloinson
diff --git a/doc/props/P_GLOBAL_SKILLPROPS b/doc/props/P_GLOBAL_SKILLPROPS
new file mode 100644
index 0000000..fc12c1e
--- /dev/null
+++ b/doc/props/P_GLOBAL_SKILLPROPS
@@ -0,0 +1,27 @@
+NAME:
+    P_GLOBAL_SKILLPROPS        "sm_global"                   
+
+DEFINIERT IN:
+    /sys/new_skills.h
+
+BESCHREIBUNG:
+    Diese Gilden- und Spellbookproperty enthaelt Eigenschaften, die
+    alle Spells eines Spellbooks bzw. alle Skills und Spells einer Gilde
+    haben sollen.
+
+BEISPIELE:
+    SetProp(P_GLOBAL_SKILLPROPS,
+      ([SI_SKILLRESTR_USE:     ([SR_FUN: #'spellTest]),
+        OFFSET(SI_SKILLLEARN): #'learnOffset,
+        OFFSET(SI_SPELLCOST):  #'costOffset,
+        FACTOR(SI_SPELLCOST):  #'costFactor]));
+
+SIEHE AUCH:
+    GObj Verwalten:   LearnSkill, LearnSpell, InitialSkillAbility
+    * Properties:     P_GUILD_SKILLS
+    Spellbook Lernen: Learn, SpellSuccess, Erfolg, Misserfolg
+    * Verwalten:      AddSpell, QuerySpell
+    * Properties:     P_SB_SPELLS
+    Skills:           P_NEWSKILLS, spruchermuedung, skill_info_liste
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_GUARD b/doc/props/P_GUARD
new file mode 100644
index 0000000..ebeb989
--- /dev/null
+++ b/doc/props/P_GUARD
@@ -0,0 +1,50 @@
+P_GUARD
+NAME:
+     P_GUARD				"guard"
+
+DEFINIERT IN:
+     /sys/guard.h
+
+BESCHREIBUNG:
+     Diese Property gibt an, ob ein NPC aus einem Raum entfernt werden darf
+     oder nicht. Abgefragt werden muss dies von den Items oder Spells, die
+     den NPC zu einer Bewegung zwingen wollen. Es wird nicht automatisch
+     darauf geachtet!
+
+     Entscheidend hierbei ist ein in der Property enthaltene (ganzzahliger)
+     Zahlenwert zwischen 0 und 100, der hierbei den Grad der
+     'Bewachungsstaerke' eines NPCs angibt. Bei 0 laesst sich das Lebewesen
+     immer zu einer Bewegung ueberreden, bei 100 ueberhaupt nicht. Dazwischen
+     gibt es die Wahrscheinlichkeit dafuer an.
+
+BEMERKUNGEN:
+     - alle von /std/npc abgeleiteten NPCs haben standardmaessig P_GUARD
+       auf 100 gesetzt, sind also nicht fortfuehrbar
+     - bei der Erzeugung von NPCs mit P_GUARD < 100 AddItem() mit dem
+       Parameter REFRESH_MOVE_HOME verwenden, damit sie bei einem Raumreset
+       gegebenenfalls an ihren Ausgangsort zurueckkehren. 
+     - gildenspezifische weitere Abfragen auf Level oAe bitte bei Gilden-
+       magiern erfragen
+
+BEISPIELE:
+     // ein Test
+     if(random(100)<=liv->QueryProp(P_GUARD))
+      cannotMoveNPC(); // NPC darf nicht bewegt werden!
+     else
+      moveNPC();       // NPC darf bewegt werden
+
+     // ein wegfuehrbarer NPC
+     void create() {
+      ::create();
+      ...
+      SetProp(P_GUARD,50);
+      ...
+     }
+     // mit 50% Wahrscheinlichkeit (pro Versuch) laesst sich der NPC nun
+     // fortfuehren
+
+
+SIEHE AUCH:
+     AddItem()
+
+13.April 2004 Gloinson
diff --git a/doc/props/P_GUILD b/doc/props/P_GUILD
new file mode 100644
index 0000000..bcffb4c
--- /dev/null
+++ b/doc/props/P_GUILD
@@ -0,0 +1,22 @@
+P_GUILD
+NAME:
+     P_GUILD				"guild"                       
+
+DEFINIERT IN:
+     /sys/properties.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt den Namen der Gilde, welcher das Lebewesen
+     angehoert. Der Name der Gilde ist hierbei kleingeschrieben als String
+     definiert.
+
+BEMERKUNGEN:
+     Bei Spielern ist der Wert dieser Property niemals Null, denn sie
+     gehoeren standardmaessig der in P_DEFAULT_GUILD stehenden Gilde an.
+     Ueber die gesetzte P_GUILD werden auch aktive Skills ermittelt.
+
+SIEHE AUCH:
+     P_DEFAULT_GUILD, P_VISIBLE_GUILD
+     P_GUILD_TITLE, P_SUBGUILD_TITLE
+
+26. Maerz 2004 Gloinson
diff --git a/doc/props/P_GUILD_DEACTIVATE_SKILLS b/doc/props/P_GUILD_DEACTIVATE_SKILLS
new file mode 100644
index 0000000..019da30
--- /dev/null
+++ b/doc/props/P_GUILD_DEACTIVATE_SKILLS
@@ -0,0 +1,38 @@
+PROPERTY:
+
+  P_GUILD_DEACTIVATE_SKILLS     "guild_deactivate_skills"
+
+DEFINIERT IN: 
+
+  new_skills.h
+
+BESCHREIBUNG:
+
+  Diese Property erlaubt es, Gildenmitgliedern die benutzung von ANY-
+  Skills zu untersagen. Dies sind einerseits die allgemeinen Waffenskills,
+  andererseits koennte das auch der entgifte-Spruch der Duesterwald -
+  Quest sein.
+
+  Wert dieser Property ist ein Mapping, das als Keys die einzelnen
+  Skills und als Wert 1 enthaelt, wenn ein Skill deaktiviert
+  werden soll und 0, falls nicht.
+
+  Diese Property wird nur bei einem Neuerzeugen des Spielers neu 
+  ausgelesen, da es sonst zuviel Rechenzeit kostet.
+
+BEISPIEL:
+
+  Jede Gilde, die keine Waffenskills benutzen soll (oder selbst welche hat)
+  enthaelt folgenden Befehl:
+
+    SetProp(P_GUILD_DEACTIVATE_SKILLS,
+    ([FIGHT(WT_SWORD):1,
+    FIGHT(WT_AXE):1,
+    FIGHT(WT_CLUB):1,
+    FIGHT(WT_SPEAR):1,
+    FIGHT(WT_KNIFE):1,
+    FIGHT(WT_WHIP):1]));
+    
+LETZTE AENDERUNG: 
+
+2003-01-30, 14:15, Humni
diff --git a/doc/props/P_GUILD_DEFAULT_SPELLBOOK b/doc/props/P_GUILD_DEFAULT_SPELLBOOK
new file mode 100644
index 0000000..9ad9150
--- /dev/null
+++ b/doc/props/P_GUILD_DEFAULT_SPELLBOOK
@@ -0,0 +1,23 @@
+NAME:
+	P_GUILD_DEFAULT_SPELLBOOK	"guild_sb"                    
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	Diese Gildenproperty enthaelt den Namen des Spellbooks, welches
+	standardmaessig von der Gilde verwendet wird.
+
+BEMERKUNGEN:
+	Bei Spells kann sie mit SI_SPELLBOOK ueberschrieben werden.
+
+BEISPIELE:
+	Bei Zauberern waere folgendes denkbar:
+	  SetProp(P_GUILD_DEFAULT_SPELLBOOK,"magie_sp");
+	Das Spellbook ist hierbei unter "/spellbooks/magie_sp.c" zu finden.
+
+SIEHE AUCH:
+	P_GUILD
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_GUILD_FEMALE_TITLES b/doc/props/P_GUILD_FEMALE_TITLES
new file mode 100644
index 0000000..b1528e9
--- /dev/null
+++ b/doc/props/P_GUILD_FEMALE_TITLES
@@ -0,0 +1,24 @@
+NAME:
+	P_GUILD_FEMALE_TITLES		"guild_female_titles"         
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	Diese Gildenproperty enthaelt die Stufenbezeichnungen fuer
+	weibliche Gildenmitglieder. Als Schluessel dienen hierbei die
+	Gildenstufen und die entsprechenden Eintraege sind dann die zur
+	Stufe gehoerigen Gildentitel.
+
+BEISPIELE:
+	Eine Programmierergilde koennte folgende Stufenbezeichnungen
+	beinhalten:
+	  SetProp(P_GUILD_FEMALE_TITLES,([1:"die Anfaengerin",
+	                                  2:"die Fortgeschrittene",
+	                                  3:"die Professionelle ;)"]));
+
+SIEHE AUCH:
+	P_GENDER, P_GUILD_LEVEL, P_GUILD_TITLE, P_GUILD_MALE_TITLES
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_GUILD_LEVEL b/doc/props/P_GUILD_LEVEL
new file mode 100644
index 0000000..4920449
--- /dev/null
+++ b/doc/props/P_GUILD_LEVEL
@@ -0,0 +1,23 @@
+NAME:
+	P_GUILD_LEVEL			"guild_level"                 
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	Diese Property enthaelt die Gildenstufe des Lebewesens, welche nicht
+	unbedingt seiner Spielerstufe entspricht.
+
+BEMERKUNGEN:
+	Bei manchen Gilden entspricht die Gildenstufe standardmaessig der
+	Spielerstufe (Abenteurer, Katzenkrieger). In der Property selbst
+	wird eigentlich ein Mapping eingetragen, welches die Gildennamen als
+	Schluessel und die dazugehoerige Gildenstufe als Eintrag enthaelt.
+	Bei der Abfrage der Property wird jedoch die Gilde beruecksichtigt
+	und die aktuelle Gildenstufe zurueckgeliefert.
+
+SIEHE AUCH:
+	P_GUILD, P_GUILD_TITLE, P_GUILD_MALE_TITLES, P_GUILD_FEMALE_TITLES
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_GUILD_LEVELS b/doc/props/P_GUILD_LEVELS
new file mode 100644
index 0000000..80d2237
--- /dev/null
+++ b/doc/props/P_GUILD_LEVELS
@@ -0,0 +1,35 @@
+NAME:
+	P_GUILD_LEVELS			"guild_levels"                
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	Diese Gildenproperty enthaelt ein Mapping mit den
+	Stufenbeschraenkungen fuer die jeweiligen Gildenstufen. Als
+	Schluessel dient der jeweilige Gildenlevel und die entsprechenden
+	Eintraege sind wiederum Mappings, in welchen die Beschraenkungen
+	angegeben sind.
+
+BEMERKUNGEN:
+	Die Beschraenkungen fuer Level 1 sollten auch fuer die
+	Eintrittsbeschraenkungen der Gilde gelten. Letztere kann man in der
+	Property P_GUILD_RESTRICTIONS angeben.
+
+BEISPIELE:
+	Das folgende Beispiel zeigt ein paar moegliche Abfragen:
+	  string check(object pl);
+	  SetProp(P_GUILD_LEVELS,([1:([P_LEVEL:3,P_QP:100,SR_FUN:#'check]),
+	                           2:([A_INT:10,P_LEVEL:25]),
+	                           3:([A_INT:20,P_LEVEL:50])]));
+	  string check(object pl)
+	  { if(pl->QueryProp(P_MALE))
+	      return 0;
+	    return "Fuer Frauen ist das nichts!\n";
+	  }
+
+SIEHE AUCH:
+	P_GUILD_LEVEL, P_GUILD_RESTRICTIONS, /std/restriction_checker.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_GUILD_MALE_TITLES b/doc/props/P_GUILD_MALE_TITLES
new file mode 100644
index 0000000..27e05a5
--- /dev/null
+++ b/doc/props/P_GUILD_MALE_TITLES
@@ -0,0 +1,24 @@
+NAME:
+	P_GUILD_MALE_TITLES		"guild_male_titles"           
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	Diese Gildenproperty enthaelt die Stufenbezeichnungen fuer
+	maennliche Gildenmitglieder. Als Schluessel dienen hierbei die
+	Gildenstufen und die entsprechenden Eintraege sind dann die zur
+	Stufe gehoerigen Gildentitel.
+
+BEISPIELE:
+	Eine Programmierergilde koennte folgende Stufenbezeichnungen
+	beinhalten:
+	  SetProp(P_GUILD_MALE_TITLES,([1:"der Anfaenger",
+	                                2:"der Fortgeschrittene",
+	                                3:"der Profi"]));
+
+SIEHE AUCH:
+	P_GENDER, P_GILD_LEVEL, P_GUILD_TITLE, P_GUILD_FEMALE_TITLES
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_GUILD_PREPAREBLOCK b/doc/props/P_GUILD_PREPAREBLOCK
new file mode 100644
index 0000000..e429a49
--- /dev/null
+++ b/doc/props/P_GUILD_PREPAREBLOCK
@@ -0,0 +1,37 @@
+P_GUILD_PREPAREBLOCK (int)
+
+NAME:
+  P_GUILD_PREPAREBLOCK                           "guild_prepareblock" 
+
+DEFINIERT IN:
+  /sys/new_skills.h
+
+BESCHREIBUNG:
+  Diese Property enthaelt die Information, ob das Lebewesen in
+  der Konzentrationsphase eines Spells weiterkaempft oder ob
+  die Angriffe derweil ausgesetzt werden.
+
+BEMERKUNGEN:
+  In der Property selbst wird eigentlich ein Mapping eingetragen,
+  welches die Gildennamen als Schluessel und das dazugehoerige
+  Block-Flag als Eintrag enthaelt. Bei der Abfrage der Property wird
+  jedoch die Gilde beruecksichtigt und das aktuelle Flag
+  zurueckgeliefert.
+  Dementsprechend das diese Prop nicht mit Set() manipuliert werden, 
+  bitte ausschliessliche SetProp() verwenden.
+
+BEISPIELE:
+  Die Property sollte natuerlich nur von der Gilde gesetzt werden
+  und auch nur bei Gildenmitgliedern
+
+  if ( IsGuildMember(pl) )
+    pl->SetProp(P_GUILD_PREPAREBLOCK,1);
+
+  Resultat: Kein Ausfuehren von Attack(), wenn pl sich auf einen
+  Zauberspruch konzentriert.
+
+SIEHE AUCH:
+  P_PREPARED_SPELL
+
+----------------------------------------------------------------------------
+18.03.2008, Zesstra
diff --git a/doc/props/P_GUILD_RATING b/doc/props/P_GUILD_RATING
new file mode 100644
index 0000000..df5800a
--- /dev/null
+++ b/doc/props/P_GUILD_RATING
@@ -0,0 +1,22 @@
+NAME:
+	P_GUILD_RATING			"guild_rating"                
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	In dieser Property wird die Einstufung des Spielers innerhalb
+	seiner Gilde festgelegt. Der dafuer zu ermittelnde Wert muss in
+	einem Bereich von 0 bis 10000 liegen. Wie sich die Einstufung
+	zusammensetzt, bleibt der jeweiligen Gilde ueberlassen.
+
+BEMERKUNGEN:
+	Der Wert muss von der Gilde ermittelt werden! Meist setzt er sich
+	aus den Faehigkeiten des Mitglieds zusammen und mitunter fliessen
+	auch Gildenquests oder aehnliches mit ein.
+
+SIEHE AUCH:
+    P_NEWSKILLS, GuildRating
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_GUILD_RESTRICTIONS b/doc/props/P_GUILD_RESTRICTIONS
new file mode 100644
index 0000000..8bbabc1
--- /dev/null
+++ b/doc/props/P_GUILD_RESTRICTIONS
@@ -0,0 +1,37 @@
+NAME:
+    P_GUILD_RESTRICTIONS        "guild_rest"                  
+
+DEFINIERT IN:
+    /sys/new_skills.h
+
+BESCHREIBUNG:
+    Diese Gildenproperty enthaelt ein Mapping mit den
+    Eintrittsbeschraenkungen fuer die jeweilige Gilde.
+
+BEMERKUNGEN:
+    Im allgemeinen sollte das Mapping mit den Eintrittsbeschraenkungen
+    mit den Beschraenkungen fuer Level 1 im Mapping von P_GUILD_LEVELS
+    uebereinstimmen.
+
+BEISPIELE:
+    Ein paar moegliche Abfragen waeren folgende:
+    string check(object pl);
+
+    SetProp(P_GUILD_RESTRICTIONS,
+            ([P_LEVEL:3,
+              P_QP:100,
+              SR_FUN:#'check]));
+
+    string check(object pl) {
+      if(pl->QueryProp(P_MALE))
+        return 0;
+      return "Fuer Frauen ist das nichts!\n";
+    }
+
+SIEHE AUCH:
+    Gildenfkt.:
+    * Ein/Austritt: beitreten, bei_oder_aus_treten, austreten
+    * Sonstiges:    P_GUILD_LEVELS
+    Sonstiges:      /std/restriction_checker.c
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_GUILD_SKILLS b/doc/props/P_GUILD_SKILLS
new file mode 100644
index 0000000..d7e30a2
--- /dev/null
+++ b/doc/props/P_GUILD_SKILLS
@@ -0,0 +1,24 @@
+P_GUILD_SKILLS
+NAME:
+    P_GUILD_SKILLS            "guild_skills"                
+
+DEFINIERT IN:
+    /sys/new_skills.h
+
+BESCHREIBUNG:
+    Diese Gildenproperty enthaelt ein Mapping mit allen Skills und
+    Spells der Gilde.
+
+BEMERKUNGEN:
+    Man sollte diese Property sollte nicht per Hand veraendern, sondern
+    die Funktionen AddSkill() bzw. AddSpell() nutzen.
+
+SIEHE AUCH:
+    GObj Verwalten:   LearnSkill, LearnSpell, InitialSkillAbility
+    * Sonstiges:      GuildRating
+    Spellbook Lernen: Learn, SpellSuccess, Erfolg, Misserfolg
+    * Verwalten:      AddSpell, QuerySpell
+    * Properties:     P_SB_SPELLS, P_GLOBAL_SKILLPROPS, P_GUILD_RATING
+    Skills:           P_NEWSKILLS, spruchermuedung, skill_info_liste
+
+3. Okt 2011 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_GUILD_TITLE b/doc/props/P_GUILD_TITLE
new file mode 100644
index 0000000..4554349
--- /dev/null
+++ b/doc/props/P_GUILD_TITLE
@@ -0,0 +1,37 @@
+P_GUILD_TITLE
+NAME:
+     P_GUILD_TITLE			"guild_title"                 
+
+DEFINIERT IN:
+     /sys/new_skills.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt den Gildentitel des Lebewesens, welcher der
+     Gildenstufe des Lebewesens entspricht und jedoch nur angezeigt wird,
+     wenn P_TITLE des Lebewesens gleich Null ist.
+
+BEMERKUNGEN:
+     In der Property selbst wird eigentlich ein Mapping eingetragen, welches
+     die Gildennamen als Schluessel und die dazugehoerigen Gildentitel als
+     Eintrag enthaelt. Bei der Abfrage der Property wird jedoch die Gilde
+     beruecksichtigt und der aktuelle Gildentitel zurueckgeliefert.
+
+BEISPIELE:
+	Fuer eine Programmierergilde waere folgendes denkbar:
+	  SetProp(P_GUILD_MALE_TITLES,([1:"der Anfaenger",
+	                                2:"der Fortgeschrittene",
+	                                3:"der Profi"]));
+	  SetProp(P_GUILD_FEMALE_TITLES,([1:"die Anfaengerin",
+	                                  2:"die Fortgeschrittene",
+	                                  3:"die Professionelle"]));
+	Ein weibliches Gildenmitglied mit der dritten Gildenstufe und ohne
+	P_TITLE wuerde dann den Titel "die Professionelle" tragen. Das hat
+	zwar nichts mit Programmierern zu tun, aber wie heisst eigentlich
+	ein weiblicher "Profi"?! :)
+
+SIEHE AUCH:
+     P_TITLE, P_GUILD, P_GUILD_LEVEL,
+     P_GUILD_MALE_TITLES, P_GUILD_FEMALE_TITLES,
+     P_SUBGUILD_TITLE
+
+26. Maerz 2004 Gloinson
diff --git a/doc/props/P_HANDS b/doc/props/P_HANDS
new file mode 100644
index 0000000..9eda7c5
--- /dev/null
+++ b/doc/props/P_HANDS
@@ -0,0 +1,57 @@
+P_HANDS
+NAME:
+     P_HANDS                    "hands"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt ein dreielementiges Array mit
+     den folgenden Eintraegen:
+     1. Element: String mit der Meldung, wenn ohne Waffen angegriffen
+                 wird.
+     2. Element: Waffenklasse, wenn ohne Waffen angegriffen wird.
+     3. Element: Array mit Schadensarten (frueher auch: Schadensart)
+
+     eim Setzen dieser Property wird auch P_TOTAL_WC mit veraendert,
+     wenn das Lebewesen keine Waffe gezueckt hat. Steckt das Lebewesen
+     eine gezueckte Waffe weg, so wird ebenfalls P_TOTAL_WC mit der
+     Waffenklasse aus P_HANDS aktualisiert. Zueckt das Lebewesen eine
+     Waffe, so wird P_TOTAL_WC mit der Waffenklasse der Waffe (P_WC)
+     ueberschrieben. Die Property P_TOTAL_WC enthaelt somit immer die
+     aktuelle Angriffsstaerke des Lebewesen.
+
+BEMERKUNGEN
+     In alten Objekten kann es vorkommen, dass das dritte Element (Angabe des
+     Schadenstyps) fehlt. Dies ist eine Altlast, die Angabe des Schadenstypes
+     ist NICHT optional.)
+
+BEISPIEL:
+     Ein starker Tausendfuessler mit Schlagschaden:
+
+       SetProp(P_HANDS,({" mit tausend kleinen Fuesschen",1000, 
+                         ({DT_BLUDGEON}) }));
+
+
+     Ein Saeurededaemon:
+       SetProp(P_HANDS,
+         ({
+           " mit saeuretriefenden Klauen",
+           250,
+           ({DT_RIP, DT_ACID})
+         })
+       );
+
+     Hier wurden gleich zwei Schadensarten angegeben, also wird
+     Mischschaden verursacht. Man sollte es jedoch nicht zu sehr
+     uebertreiben! Mehr als zwei oder drei gleichzeitig verwendete
+     Schadensarten lassen sich kaum mehr begruenden.
+
+SIEHE AUCH:
+     P_HANDS_USED_BY
+     P_MAX_HANDS, P_USED_HANDS, P_FREE_HANDS
+     UseHands, FreeHands
+     P_TOTAL_WC, P_WC
+     /std/living/combat.c, /std/weapon/combat.c, /sys/combat.h
+
+22.02.2014 Zesstra
diff --git a/doc/props/P_HANDS_USED_BY b/doc/props/P_HANDS_USED_BY
new file mode 100644
index 0000000..dd0e5fe
--- /dev/null
+++ b/doc/props/P_HANDS_USED_BY
@@ -0,0 +1,21 @@
+P_HANDS_USED_BY
+NAME:
+     P_HANDS_USED_BY           "hands_used_by"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+     Enthaelt eine Liste mit den Objekten, die derzeit die Haende
+     des Livings belegen. Dabei koennen Objekte mehrmals auftauchen,
+     je nachdem wie viele Haende sie belegen.
+
+BEMERKUNGEN:
+     Darf nur ueber UseHands() und FreeHands() manipuliert werden.
+
+SIEHE AUCH:
+     P_HANDS
+     P_MAX_HANDS, P_USED_HANDS, P_FREE_HANDS
+     UseHands, FreeHands
+
+1.Feb.2004 Gloinson
diff --git a/doc/props/P_HARBOUR b/doc/props/P_HARBOUR
new file mode 100644
index 0000000..c0e1048
--- /dev/null
+++ b/doc/props/P_HARBOUR
@@ -0,0 +1,66 @@
+NAME:
+    P_HARBOUR                                  "harbour_name"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+    Array mit eindeutiger Bezeichnung des 'Hafens'
+
+BEMERKUNGEN:
+    Diese Property wird in Raeumen gesetzt, die als Anleger fuer Transporter
+    dienen sollen. Sie enthaelt ein Array aus zwei Elementen, einem String
+    und einem String-Array, zum Beispiel:
+
+    ({ "zur Sonneninsel", ({"sonneninsel"}) }) oder 
+    ({ "nach Titiwu", ({"titiwu"}) })
+
+    Damit bekommt der Spieler bei einer Abfrage seiner Reiseroute mittels
+    "reise route" eine Ausgabe wie 
+      'Du reist mit dem Floss nach Titiwu' oder
+      'Du reist mit dem Wal zur Sonneninsel'.
+
+    Das zweite Element der Property enthaelt eine Liste der IDs, mit denen
+    sich der Hafen mit dem Befehl "reise nach <ID>" ansprechen laesst. Im
+    Beispiel oben wuerde also "reise nach sonneninsel" und 
+    "reise nach titiwu" akzeptiert werden. Der erste Eintrag in dieser ID-
+    Liste wird in der Ausgabe des Befehls "reise route" verwendet, sollte
+    also den Anlegeort korrekt bezeichnen und nicht z.B. eine Abkuerzung
+    enthalten.
+    Es bietet sich an, bei bestimmten, deklinierbaren Bezeichnungen alle
+    Varianten einzutragen, z.B. "verlorenes land" und zusaetzlich
+    "verlorene land" und "verlorenen land", damit alle Varianten von 
+    "reise nach ..." funktionieren.
+
+    Ist in einem Hafen diese Property nicht gesetzt, so bekommt der 
+    Spieler keinerlei Hinweis darauf, wohin ihn ein bestimmter Trans-
+    porter befoerdert. 
+    Stattdessen erhaelt er die Bezeichnung 'unbekannt'.
+
+HINWEISE:
+    Wird der zweite Parameter in dieser Property, d.h. die Liste der 
+    Anleger-IDs, nicht korrekt gesetzt, kann das dazu fuehren, dass Spieler
+    den hier anlegenden Transporter nicht benutzen koennen, weil es
+    keine sinnvolle Syntax gibt, um den gewuenschten Zielhafen zu finden.
+
+    Zu achten ist auch darauf, das der erste Eintrag unveraendert in einer 
+    Meldung an den Spieler ausgegeben wird, d.h. Gross-und Kleinschreibung
+    sollte korrekt sein.
+
+HISTORIE:
+    Frueher war der zweite Eintrag in dieser Property ein einzelner String.
+    Es existiert eine SetMethode auf dieser Property, die solche Daten in
+    altem Code auf die neue Datenstruktur umbiegt. Dies fuehrt dazu, dass
+    bei solchen Objekten die im geladenen Raum enthaltenen Daten nicht mit
+    den Daten im File uebereinstimmen. Dies moege aber bitte niemand 
+    zum Anlass nehmen, in neuem Code veraltete Daten in die Property zu 
+    schreiben!
+    
+SIEHE AUCH:
+  Properties:     P_NO_TRAVELING, P_TRAVEL_INFO
+  Funktionen:     AddRoute(L)
+  Spielerbefehle: reise
+  weitere Doku:   /d/inseln/schiffe/HowTo
+
+LETZTE AENDERUNG:
+2015-Jan-18, Arathorn
diff --git a/doc/props/P_HAUS_ERLAUBT b/doc/props/P_HAUS_ERLAUBT
new file mode 100644
index 0000000..8ac6495
--- /dev/null
+++ b/doc/props/P_HAUS_ERLAUBT
@@ -0,0 +1,29 @@
+NAME:
+    P_HAUS_ERLAUBT                "haus_erlaubt"                
+
+DEFINIERT IN:
+    /sys/room/description.h
+
+BESCHREIBUNG:
+     Hier darf ein Seherhaus abgestellt werden
+
+BEMERKUNGEN:
+     Diese Property sollte nicht per default in Raeumen auf einen Wert > 0
+     gesetzt werden um einem Wildwuchs an Seherhaus(-ruinen) vorzubeugen.
+     Auch sei darauf geachtet, dass in Raeumen die P_INDOORS auf einen 
+     Wert > 0 haben, per default nicht gebaut werden kann.     
+     Hier lieber die Property per Hand auf 1 setzen und nach dem Aufstellen
+     des Hauses wieder loeschen.
+      
+     xcall $h->SetProp(P_HAUS_ERLAUBT,1);
+
+     Angemerkt sei noch, dass der Magier dem der Raum gehoert ueber Hausbau
+     entscheidet und nicht der Regionsmagier. In jedem Fall Ruecksprache 
+     halten falls der entsprechende Magier zumindest ab und an anwesend sein
+     sollte.
+
+     Unter /doc/beispiele/misc liegt ein File, in dem dokumentiert ist,
+     wie nach Aenderungen am Seherhaus zu verfahren ist.
+
+----------------------------------------------------------------------------
+Last modified: Fri Nov 26 15:41:47 1999 by Tilly
diff --git a/doc/props/P_HB b/doc/props/P_HB
new file mode 100644
index 0000000..eee2dcb
--- /dev/null
+++ b/doc/props/P_HB
@@ -0,0 +1,9 @@
+NAME:
+    P_HB                          "hb"                          
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Diese Property wird gesetzt, wenn das Monster immer einen
+     heart_beat haben soll. (VORSICHT, nur wenn es WIRKLICH sein muss!)
diff --git a/doc/props/P_HEAL b/doc/props/P_HEAL
new file mode 100644
index 0000000..242802f
--- /dev/null
+++ b/doc/props/P_HEAL
@@ -0,0 +1,32 @@
+NAME:
+     P_HEAL                        "heal"                        
+
+DEFINIERT IN:
+     /sys/properties.h
+
+BESCHREIBUNG:
+     Numerischer Wert, der beim Verzehr einer Leiche zu den Lebenspunkten 
+     desjenigen hinzugezaehlt wird, der die Leiche isst. Der Wert kann auch 
+     negativ sein. Falls die Leiche den maximalen Verfallszustand erreicht 
+     hat, wird dieser Wert automatisch auf -4 gesetzt, sofern nicht schon
+     ein geringerer Wert eingetragen ist.
+
+     Werte unter -4 sind sehr sparsam und nur in begruendeten Einzelfaellen
+     zu setzen. Die Regionsmagier werden auf sinnvolle Wertebereiche in
+     ihrem Zustaendigkeitsbereich achten und ggf. Grenzwerte fuer ihre 
+     Region festlegen.
+
+     Die Gilden koennen P_HEAL abfragen und eigene, grobe Informationstexte
+     ausgeben, die den Spieler ueber den zu erwartenden Effekt beim Essen
+     einer Leiche informieren.
+
+     Positive Werte von P_HEAL sind bei der Heilungsbalance als Heilstelle
+     zu beantragen.
+
+     Fuer nicht allzu harte NPCs sollte P_HEAL auf 0 gesetzt sein. Dieser
+     Wert ist gleichzeitig der Standardwert.
+
+SIEHE AUCH:
+     /std/corpse, QueryHealInfo()
+     
+31.03.2008 Arathorn
diff --git a/doc/props/P_HELPER_NPC b/doc/props/P_HELPER_NPC
new file mode 100644
index 0000000..eb71e47
--- /dev/null
+++ b/doc/props/P_HELPER_NPC
@@ -0,0 +1,30 @@
+P_HELPER_NPC
+
+NAME:
+     P_HELPER_NPC             "std:helper_npc
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+    Mit dieser Prop laesst sich herausfinden, ob ein NPC einem Spieler hilft
+    bzw. welche NPC einem Spieler helfen.
+    Wird diese Prop in einem NPC abgefragt, enthaelt sie ein Array 
+      ({ spielerobjekt, flags }) oder 0.
+    Wird diese Prop in einem Spieler abgefragt, enthaelt sie ein Mapping
+      ([npcobjekt1: flags1, npc-objekt2: flags2]).
+
+    <flags> ist ein Integer, der eine Reihe von ver-oder-ten Konstanten (s.
+    RegisterHelperNPC) enthalten kann.
+
+BEMERKUNGEN:
+    Diese Prop wird automatisch von RegisterHelperNPC() und
+    UnregisterHelperNPC() verwaltet. Bitte aendert sie nicht per Hand.
+
+BEISPIEL:
+    s. RegisterHelperNPC().
+
+SIEHE AUCH:
+     RegisterHelperNPC(), UnregisterHelperNPC()
+
+10.03.2009, Zesstra
diff --git a/doc/props/P_HELPER_OBJECTS b/doc/props/P_HELPER_OBJECTS
new file mode 100644
index 0000000..bdf031d
--- /dev/null
+++ b/doc/props/P_HELPER_OBJECTS
@@ -0,0 +1,25 @@
+P_HELPER_OBJECTS
+
+NAME:
+     P_HELPER_OBJECTS "lib_p_helper_objects"
+
+DEFINIERT IN:
+     <living/helpers.h>
+
+BESCHREIBUNG:
+     Diese Property enthaelt eine Liste von Hilfsobjekten, die das Lebewesen,
+     in dem sie gesetzt ist, bei bestimmten Aktivitaeten wie Tauchen oder
+     Fliegen/Segeln unterstuetzt. Die Property enthaelt ein Mapping der Form
+     ([ HELPER_TYPE : ({ Callback-Closures }) ]).
+
+BEMERKUNGEN:
+     Externe Manipulationen an dieser Property bitte unterlassen, zum Ein-
+     und Austragen von Objekten gibt es die unten aufgefuehrten Methoden.
+
+SIEHE AUCH:
+     Methoden:    RegisterHelperObject(L), UnregisterHelperObject(L)
+     Properties:  P_AERIAL_HELPERS, P_AQUATIC_HELPERS
+
+----------------------------------------------------------------------------
+18.02.2013, Arathorn
+
diff --git a/doc/props/P_HIDE_EXITS b/doc/props/P_HIDE_EXITS
new file mode 100644
index 0000000..0c92a4a
--- /dev/null
+++ b/doc/props/P_HIDE_EXITS
@@ -0,0 +1,35 @@
+P_HIDE_EXITS
+NAME:
+     P_HIDE_EXITS                  "hide_exits"
+
+DEFINIERT IN:
+     /sys/room/exits.h
+
+BESCHREIBUNG:
+     Ist diese Property in einem Raum auf einen Integerwert ungleich 0
+     gesetzt, werden einem Spieler fuer diesen Raum keine Ausgaenge angezeigt.
+     Auch der Text "Keine sichtbaren Ausgaenge." (oder so) kommt nicht.
+     Alternativ kann man auch ein array von strings uebergeben. In diesem
+     Fall werden all die Ausgaenge nicht angezeigt, deren Index in P_EXITS
+     in dem array vorkommt.
+     In diesem Fall wird ggf. der Text "Keine sichtbaren Ausgaenge."
+     ausgegeben.
+
+BEISPIEL:
+     AddExit("raus", "/ganz/wo/anders");
+     AddExit("weiter", "/in/der/naehe");
+
+     // KEINE Ausgaenge anzeigen. Noch nicht mal, dass man keine sieht.
+     SetProp(P_HIDE_EXITS, 1);
+
+     // Der Ausgang weiter wird nicht angezeigt.
+     SetProp(P_HIDE_EXITS, ({"weiter"}) );
+
+     // Keinen Ausgang zeigen, aber den Text, dass keiner sichtbar, ausgeben.
+     SetProp(P_HIDE_EXITS, ({"weiter", "raus"}) );
+
+SIEHE AUCH:
+     Aehnliches:	P_SHOW_EXITS
+     Sonstiges:		AddExit(), GetExits(), int_long(), int_short()
+
+25. Apr 1996 Highlander
\ No newline at end of file
diff --git a/doc/props/P_HISTMIN b/doc/props/P_HISTMIN
new file mode 100644
index 0000000..e84d90c
--- /dev/null
+++ b/doc/props/P_HISTMIN
@@ -0,0 +1,8 @@
+NAME:
+    P_HISTMIN                     "histmin"                     
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Minimale Laenge, die eine Zeile haben muss, um in die History zu kommen
diff --git a/doc/props/P_HIT_FUNC b/doc/props/P_HIT_FUNC
new file mode 100644
index 0000000..c5b3b31
--- /dev/null
+++ b/doc/props/P_HIT_FUNC
@@ -0,0 +1,22 @@
+P_HIT_FUNC
+
+NAME:
+     P_HIT_FUNC "hit_func"
+
+DEFINIERT IN:
+     <weapon.h>
+
+BESCHREIBUNG:
+     Falls ein Objekt eine HitFunc() fuer die Waffe definiert, so muss
+     dieses Objekt in dieser Property eingetragen werden.
+
+     Die Auswertung dieser Property erfolgt in QueryDamage().
+
+BEISPIELE:
+     Siehe das Beispiel zu HitFunc()
+
+SIEHE AUCH:
+     /std/weapon.c, HitFunc()
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 15:37:35 1996 by Wargon
diff --git a/doc/props/P_HOMEPAGE b/doc/props/P_HOMEPAGE
new file mode 100644
index 0000000..7d90438
--- /dev/null
+++ b/doc/props/P_HOMEPAGE
@@ -0,0 +1,8 @@
+NAME:
+    P_HOMEPAGE                    "homepage"                    
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Die Homepage eines Spielers (mit dem Befehl 'url' zu setzen).
diff --git a/doc/props/P_HP b/doc/props/P_HP
new file mode 100644
index 0000000..f2aea74
--- /dev/null
+++ b/doc/props/P_HP
@@ -0,0 +1,25 @@
+NAME:
+    P_HP                          "hp"
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+
+     - Lebewesen
+       Anzahl der Lebenspunkte des Wesens.
+
+     - Speisen/Kneipen
+       Heilwirkung einer Portion der Speise auf die Lebenspunkte
+       des Konsumenten
+
+SIEHE AUCH:
+     Props:		P_MAX_HP
+     Veraenderung:	reduce_hit_points(), restore_hit_points()
+			do_damage(L), Defend(L)
+			buffer_hp()
+     Ueberwachung:	AddHpHook(L)
+     Speisen/Kneipen:   std/pub, wiz/food, consume
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_HP_DELAY b/doc/props/P_HP_DELAY
new file mode 100644
index 0000000..a807ad9
--- /dev/null
+++ b/doc/props/P_HP_DELAY
@@ -0,0 +1,10 @@
+NAME:
+    P_HP_DELAY                 "hp_delay"                     
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Anzahl der heart_beats, bis P_HP um einen Punkt regeneriert.
+     Aenderungen dieser Property in Spielern beduerfen der 
+     Genehmigung des EM fuer Balance.
diff --git a/doc/props/P_HP_HOOKS b/doc/props/P_HP_HOOKS
new file mode 100644
index 0000000..28f1a1e
--- /dev/null
+++ b/doc/props/P_HP_HOOKS
@@ -0,0 +1,19 @@
+NAME:
+    P_HP_HOOKS                    "hp_hooks"                    
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Welche Objekte sollen bei HP-Aenderungen benachrichtigt werden?
+     Diese Property bitte NICHT manipulieren! Zum Ein- und Austragen stehen
+     hierfuer AddHpHook() und RemoveHpHook() bereit.
+
+BEMERKUNGEN:
+    Das neuere Hooksystem (s. Manpage std/hooks) stellt ebenfalls Hooks zur
+    Ueberwachung von P_HP bereit.
+
+SIEHE AUCH:
+    AddHpHook(), RemoveHpHook(),
+    NotifyHpChange()
+    std/hooks
diff --git a/doc/props/P_HUNTTIME b/doc/props/P_HUNTTIME
new file mode 100644
index 0000000..377ab18
--- /dev/null
+++ b/doc/props/P_HUNTTIME
@@ -0,0 +1,35 @@
+P_HUNTTIME (int)
+
+NAME:
+     P_HUNTTIME					"p_lib_hunttime"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+    Mit dieser Property laesst sich festlegen, wie lange ein Monster einen 
+    Gegner verfolgt (also automatisch angreift), nachdem dieser geflohen ist.
+    Die Angabe erfolgt in Sekunden.
+    Die Standardzeit ist 600s (300 Heartbeats).
+
+BEMERKUNGEN:
+    1. Wenn der Standardwert akzeptabel ist, bitte die Prop auch nicht setzen.
+    2. Enthaelt die Property keinen Integer oder ist sie <= 0, wird sie 
+       ignoriert und der Standardwert von 600s verwendet.
+    3. Kaempft man mit einem Lebenwesen mit einem groesseren Wert als man 
+       selber und man selber hat das Verfolgen eingestellt, der Gegner aber 
+       nicht, wird dieser beim Reinkommen den Kampf neu starten (und den 
+       ersten Schlag haben).
+
+BEISPIEL:
+    Ein NPC soll sich erst eine Stunde nach Flucht des Gegners beruhigen.
+    protected void create() {
+      ...
+      SetProp(P_HUNTTIME, 3600);
+    }
+
+SIEHE AUCH:
+     InsertSingleEnemy, InsertEnemy
+     /std/living/combat.c
+
+13.03.2008, Zesstra
diff --git a/doc/props/P_IDS b/doc/props/P_IDS
new file mode 100644
index 0000000..311407b
--- /dev/null
+++ b/doc/props/P_IDS
@@ -0,0 +1,25 @@
+P_IDS
+
+NAME:
+     P_IDS "ids"
+
+DEFINIERT IN:
+     <thing/description.h>
+
+BESCHREIBUNG:
+     In dieser Property steht ein Array von den Strings, mit denen sich das
+     Objekt ansprechen laesst. Die Verwaltung dieser Property erfolgt ueber
+     die Funktionen AddId() und RemoveId().
+
+     Der Inhalt dieser Property wird von den Funktionen id() und (indirekt)
+     present() ausgewertet.
+
+BEMERKUNGEN:
+     Man sollte an dieser Property nicht "von Hand" herumfummeln, sondern
+     immer die zugehoerigen Funktionen benutzen!
+
+SIEHE AUCH:
+     /std/thing/description.c, AddId(), RemoveId()
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 20:17:36 1996 by Wargon
diff --git a/doc/props/P_IGNORE b/doc/props/P_IGNORE
new file mode 100644
index 0000000..d95fd14
--- /dev/null
+++ b/doc/props/P_IGNORE
@@ -0,0 +1,22 @@
+NAME:
+    P_IGNORE                      "ignore"
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+    Array mit Spielern, Kommandos, Aktionen u.ae. die ignoriert werden.
+    In aller Regel sollte die Ignorierepruefung durch Aufruf von TestIgnore()
+    im Spieler erfolgen und nicht selber P_IGNORE durchsucht werden.
+
+BEMERKUNGEN:
+    Die Daten in dieser Property werden intern als Mapping gespeichert, nicht
+    als Array von Strings. Bitte nicht mit Set/Query() an dieser Property
+    herumbasteln.
+
+SIEHE AUCH:
+    TestIgnore, /std/player/comm.c
+
+----------------------------------------------------------------------------
+Last modified: 02.10.2011, Zesstra
+
diff --git a/doc/props/P_INDOORS b/doc/props/P_INDOORS
new file mode 100644
index 0000000..c1ab07a
--- /dev/null
+++ b/doc/props/P_INDOORS
@@ -0,0 +1,33 @@
+NAME:
+     P_INDOORS                     "indoors"
+
+DEFINIERT IN:
+     /sys/room/description.h
+
+BESCHREIBUNG:
+     Gesetzt, wenn von dem Raum aus der Himmel nicht sichtbar ist.
+
+     Objekte oder Gilden werten diese Property teilweise aus, fuer
+     Innenraeume sollte sie also sinnvollerweise gesetzt werden.
+
+     Licht wird _nicht_ durch P_INDOORS beeinflusst, muss also
+     selbst angepasst werden.
+
+BEISPIEL
+     // Ein dunkler Innenraum:
+     SetProp(P_INDOORS, 1);            // ein Innenraum liegt innen :)
+     SetProp(P_LIGHT, 0);              // Licht auf 0
+
+     // Ein richtig heller Aussenraum:
+     SetProp(P_INDOORS, 0);
+     SetProp(P_LIGHT, 2);
+
+     // Ein heller Aussenraum mit Mondlicht (gut fuer Delfen)
+     SetProp(P_INDOORS, 0);
+     SetProp(P_LIGHT, 1);
+     SetProp(P_LIGHT_TYPE, LT_STARS|LT_MOON);
+
+SIEHE AUCH
+     P_LIGHT, P_LIGHT_ABSORPTION, P_LIGHT_TYPE
+
+25.Aug 2008 Gloinson
diff --git a/doc/props/P_INFO b/doc/props/P_INFO
new file mode 100644
index 0000000..06dabe6
--- /dev/null
+++ b/doc/props/P_INFO
@@ -0,0 +1,18 @@
+P_INFO
+NAME:
+     P_INFO                        "info"                        
+
+DEFINIERT IN:
+     /sys/properties.h
+
+BESCHREIBUNG:
+     Geheime Information, die ggf. ueber einen Zauberspruch
+     von Spielern ermittelt werden kann.
+     
+BEISPIEL:
+     SetProp(P_INFO,"Du ergruendest das Geheimnis.\n")
+
+SIEHE AUCH:
+     GetOwner(L)
+
+24. April 2006, Vanion 
diff --git a/doc/props/P_INFORMME b/doc/props/P_INFORMME
new file mode 100644
index 0000000..4736933
--- /dev/null
+++ b/doc/props/P_INFORMME
@@ -0,0 +1,14 @@
+NAME:
+    P_INFORMME                    "informme"                    
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Enthaelt das Flag, ob der Spieler ueber ein-/ausloggende Spieler
+    informiert werden will.
+
+SIEHE AUCH:
+    Spielerkommando: inform
+
+6.Feb 2016 Gloinson
diff --git a/doc/props/P_INPC_HOME b/doc/props/P_INPC_HOME
new file mode 100644
index 0000000..31fea0b
--- /dev/null
+++ b/doc/props/P_INPC_HOME
@@ -0,0 +1,8 @@
+NAME:
+    P_INPC_HOME                   "inpc_home"                   
+
+DEFINIERT IN:
+    /sys/inpc/walking.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_INPC_LAST_ENVIRONMENT b/doc/props/P_INPC_LAST_ENVIRONMENT
new file mode 100644
index 0000000..2b7437a
--- /dev/null
+++ b/doc/props/P_INPC_LAST_ENVIRONMENT
@@ -0,0 +1,8 @@
+NAME:
+    P_INPC_LAST_ENVIRONMENT       "inpc_last_environment"       
+
+DEFINIERT IN:
+    /sys/inpc/walking.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_INPC_LAST_PLAYER_CONTACT b/doc/props/P_INPC_LAST_PLAYER_CONTACT
new file mode 100644
index 0000000..f32cd02
--- /dev/null
+++ b/doc/props/P_INPC_LAST_PLAYER_CONTACT
@@ -0,0 +1,8 @@
+NAME:
+    P_INPC_LAST_PLAYER_CONTACT    "inpc_last_player_contact"    
+
+DEFINIERT IN:
+    /sys/inpc/walking.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_INPC_WALK_AREA b/doc/props/P_INPC_WALK_AREA
new file mode 100644
index 0000000..3d7dfc6
--- /dev/null
+++ b/doc/props/P_INPC_WALK_AREA
@@ -0,0 +1,8 @@
+NAME:
+    P_INPC_WALK_AREA              "inpc_walk_area"              
+
+DEFINIERT IN:
+    /sys/inpc/walking.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_INPC_WALK_DELAYS b/doc/props/P_INPC_WALK_DELAYS
new file mode 100644
index 0000000..f510764
--- /dev/null
+++ b/doc/props/P_INPC_WALK_DELAYS
@@ -0,0 +1,8 @@
+NAME:
+    P_INPC_WALK_DELAYS            "inpc_walk_delay"             
+
+DEFINIERT IN:
+    /sys/inpc/walking.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_INPC_WALK_FLAGS b/doc/props/P_INPC_WALK_FLAGS
new file mode 100644
index 0000000..3e8749b
--- /dev/null
+++ b/doc/props/P_INPC_WALK_FLAGS
@@ -0,0 +1,8 @@
+NAME:
+    P_INPC_WALK_FLAGS             "inpc_walk_flags"             
+
+DEFINIERT IN:
+    /sys/inpc/walking.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_INPC_WALK_MODE b/doc/props/P_INPC_WALK_MODE
new file mode 100644
index 0000000..22da99d
--- /dev/null
+++ b/doc/props/P_INPC_WALK_MODE
@@ -0,0 +1,8 @@
+NAME:
+    P_INPC_WALK_MODE              "inpc_walk_mode"              
+
+DEFINIERT IN:
+    /sys/inpc/walking.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_INPC_WALK_ROUTE b/doc/props/P_INPC_WALK_ROUTE
new file mode 100644
index 0000000..4d11cb1
--- /dev/null
+++ b/doc/props/P_INPC_WALK_ROUTE
@@ -0,0 +1,8 @@
+NAME:
+    P_INPC_WALK_ROUTE             "inpc_walk_route"             
+
+DEFINIERT IN:
+    /sys/inpc/walking.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_INTERMUD b/doc/props/P_INTERMUD
new file mode 100644
index 0000000..6d4bd59
--- /dev/null
+++ b/doc/props/P_INTERMUD
@@ -0,0 +1,13 @@
+NAME:
+    P_INTERMUD                    "intermud"                    
+
+DEFINIERT IN:
+    /sys/player/comm.h
+
+BESCHREIBUNG:
+   Die Bedeutung dieser Property ist in den praehistorischen Untiefen
+   der Mudlib verlorengegangen.
+   Wird nicht mehr benutzt.
+   Nicht benutzen.
+   Ignorieren.
+
diff --git a/doc/props/P_INTERNAL_EXTRA_LOOK b/doc/props/P_INTERNAL_EXTRA_LOOK
new file mode 100644
index 0000000..160125d
--- /dev/null
+++ b/doc/props/P_INTERNAL_EXTRA_LOOK
@@ -0,0 +1,39 @@
+NAME:
+	P_INTERNAL_EXTRA_LOOK			"internal_extralook"
+
+DEFINIERT IN:
+	/sys/living/description.h
+
+BESCHREIBUNG:
+	Diese Property enthaelt ein Mapping, in dem alle einzelnen
+  Extra-Look-Eintraege des Livings enthalten sind. Dabei weden die Daten von
+  AddExtraLook() und RemoveExtraLook() verwaltet. Fragt man diese Prop mit
+  QueryProp() ab, erhaelt man die Ausgabe der gueltigen Extralooks des
+  Livings. Bei Abfrage per Query() erhaelt man ein Mapping mit allen
+  Eintraegen und deren Daten. Jeder Wert im Mapping ist erneut ein Mapping, 
+  welches folgende Keys enthalten kann:
+  - "xllook": String, der im Extralook des Living angezeigt wird.
+  - "xlduration": Zeitstempel (int), der angibt, wie lang der Eintrag gueltig
+                  ist. 0 == "Unendlich", negative Zahlen besagen, dass der
+                  Eintrag nur bis Reboot/Ende gueltig sein und abs(xlduration)
+                  ist der Zeitpunkt des Eintrages dieses Extralooks.
+  - "xlende": String, der nach Ablaufen an das Living ausgegeben wird.
+  - "xlfun": Funktion, die gerufen wird und den String zurueckliefern muss, 
+             der ausgeben werden soll.
+  - "xlendefun": Funktion, die gerufen wird, wenn der Eintrag abgelaufen ist
+                 und den String zurueckliefern muss, der dann ans Living
+                 ausgeben wird.
+  - "xlobjectname": Objekt, in dem die o.a. Funktionen gerufen werden.
+
+BEMERKUNG:
+  DIESE PROPERTY BITTE NIEMALS PER HAND MIT Set()/SetProp() AENDERN!
+  Die Daten in dieser Prop werden vom Living selber verwaltet. Extralooks
+  koennen mittel AddExtraLook() eingetragen und mit RemoveExtraLook() entfernt
+  werden.
+
+SIEHE AUCH:
+  long(), /std/living/description.c, /std/player/base.c
+  AddExtraLook(), RemoveExtraLook()
+
+----------------------------------------------------------------------------
+13.05.2007, Zesstra
diff --git a/doc/props/P_INT_LIGHT b/doc/props/P_INT_LIGHT
new file mode 100644
index 0000000..04504a6
--- /dev/null
+++ b/doc/props/P_INT_LIGHT
@@ -0,0 +1,20 @@
+NAME:
+    P_INT_LIGHT                       "int_light"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Gibt den Lichtlevel an, der _in_ einem Objekt ist. Ein Abfragen dieser
+    Property kann z.B. in Raeumen sinnvoll sein, wenn es z.B. um das
+    aufwachen einer Eule oder einer Fledermaus geht. Zum Abfragen ob ein
+    Spieler etwas sehen kann, bitte auf jeden Fall P_PLAYER_LIGHT benutzen!
+
+    Bitte _nur_ ueber QueryProp auf diese Property zugreifen,
+    da das Lichtlevel ggf. neu berechnet werden muss!
+
+    Ein direktes setzen dieser Property ist NICHT moeglich, hierzu bitte
+    P_LIGHT benutzen!
+
+SIEHE AUCH:
+    P_LIGHT, P_TOTAL_LIGHT, P_PLAYER_LIGHT, P_LIGHT_MODIFIER, CannotSee()
diff --git a/doc/props/P_INT_LONG b/doc/props/P_INT_LONG
new file mode 100644
index 0000000..3e59249
--- /dev/null
+++ b/doc/props/P_INT_LONG
@@ -0,0 +1,32 @@
+P_INT_LONG
+NAME:
+     P_INT_LONG                    "int_long"
+
+DEFINIERT IN:
+     /sys/room/description.h
+
+BESCHREIBUNG:
+     Enthaelt Beschreibung, die man bekommt, wenn man sich in dem
+     Container (jeder Raum ist einer) umschaut als String.
+
+     Der Text sollte bereits umgebrochen sein.
+
+     Diese Property bestimmt die Ansicht des Containers von innen.
+     Fuer die Aussen(lang)ansicht muss P_LONG benutzt werden.
+
+BEMERKUNGEN:
+     - Beschreibungen fuer etwaige Tueren im Raum werden in int_long()
+       hinzugefuegt. (Frueher wurde dies in einer Querymethode auf diese Prop
+       gemacht.)
+
+BEISPIELE:
+     SetProp(P_INT_LONG, break_string(
+      "Du stehst in einem total spannenden Testraum. Seine absolute "
+      "Nichtigkeit erfuellt dich mit ehrfuerchtigem Grauen.",78));
+
+SIEHE AUCH:
+     Aehnliches:	P_INT_SHORT
+     Sonstiges:		int_long(), P_LONG
+			process_string(), break_string()
+
+04.06.2009, Zesstra
diff --git a/doc/props/P_INT_SHORT b/doc/props/P_INT_SHORT
new file mode 100644
index 0000000..9c6a0af
--- /dev/null
+++ b/doc/props/P_INT_SHORT
@@ -0,0 +1,36 @@
+P_INT_SHORT
+NAME:
+     P_INT_SHORT			"int_short"
+
+DEFINIERT IN:
+     /sys/thing/description.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt die Innen-Kurzbeschreibung des Containers
+     als String oder Closure (mit String-Rueckgabewert).
+
+     Container sind hierbei z.B. Raeume.
+     ACHTUNG: Die Kurzbeschreibung sollte dabei weder mit einem
+	      Satzzeichen noch mit einem "\n" abgeschlossen sein
+	      (dies wird von den zustaendigen Funktionen erledigt).
+
+     Man sollte die Property nicht auf 0 setzen.
+
+     Diese Property bestimmt die Ansicht des Containers von innen.
+     Fuer die Aussen(kurz)ansicht muss P_SHORT benutzt werden.
+
+BEMERKUNGEN:
+     - int_short() (bei Bewegung) filtert P_INT_SHORT durch process_string()
+       -> daher sind Closures moeglich
+
+BEISPIELE:
+     // ein Gang sieht natuerlich so aus
+     SetProp(P_INT_SHORT, "Ein Gang");
+
+SIEHE AUCH:
+     Aehnliches:	P_INT_LONG
+     Sonstiges:		int_short(), P_SHORT
+			process_string(), break_string()
+
+----------------------------------------------------------------------------
+Last modified: Thu May 31 15:34:05 2001 by Patryn
diff --git a/doc/props/P_INVIS b/doc/props/P_INVIS
new file mode 100644
index 0000000..7022ea0
--- /dev/null
+++ b/doc/props/P_INVIS
@@ -0,0 +1,50 @@
+NAME:
+     P_INVIS                       "invis"                       
+
+DEFINIERT IN:
+     /sys/player/base.h
+
+BESCHREIBUNG:
+     Die Property P_INVIS dient dazu, Objekte als unsichtbar zu kennzeichnen.
+     Hierbei versucht P_INVIS die moeglichen Interaktionen mit Spielern zu
+     minimieren (im Gegensatz zu einer fehlenden P_SHORT, welche das Objekt
+     nur einfach nicht-sichtbar macht).
+     
+     Man sollte drei Arten von unsichtbaren Objekten unterscheiden:
+
+     - Gegenstaende
+       Setzt man P_INVIS auf eine Zahl ungleich 0, wird der Gegenstand
+       unsichtbar und der Name zu "etwas". Zusaetzlich koennen Spieler ihn
+       nicht mehr ansprechen, d.h. nehmen, wegwerfen, weitergeben etc.
+       (Bei magier-eigenen Kommandos ist dies evtl. nicht umgesetzt...)
+       Setzt man P_SHORT auf 0, wird der Gegenstand nur nicht mehr in
+       der Inventarliste von Behaeltern/Raeumen angezeigt, er behaelt aber
+       seinen Namen und ist durch Spieler ansprechbar, wenn sie eine ID
+       kennen.
+
+     - NPCs
+       Bei gesetztem P_INVIS wird der NPC unsichtbar und sein Name wird zu
+       "Jemand". Zusaetzlich koennen Spieler ihn nicht mehr ansprechen, z.B.
+       toeten oder knuddeln.
+       (Bei magier-eigenen Kommandos ist dies evtl. nicht umgesetzt...)
+       Setzt man P_SHORT auf 0, wird der NPC nur nicht mehr in der
+       Inventarliste von Behaeltern/Raeumen angezeigt, er behaelt aber seinen
+       Namen und ist durch Spieler ansprechbar, wenn sie eine ID kennen. Auch
+       angreifen und kaempfen ist moeglich.
+     
+     - Magier
+       Magier macht man unsichtbar, indem man ihnen die Property P_INVIS auf
+       einen Wert <> 0 setzt.
+       *  Spieler duerfen nicht unsichtbar gemacht werden!               *
+       *  Wird ein Magier unsichtbar gemacht, muss man ihm die Property	 *
+       *  P_INVIS auf den Wert setzen, den die Property P_AGE zu diesem	 *
+       *  Zeitpunkt hat (keine F_QUERY_METHOD !).				                 *
+       Setzt man die Property auf den Wert 1, so erhaelt ein Spieler,
+       wenn er den entsp. Magier fingert, die Ausgabe: Alter: 00:00:02,
+       was genauso verraeterisch ist, wie ein Alter, dass bei einem
+       scheinbar nicht eingeloggten Magier immer weiter hochgezaehlt
+       wird.
+
+----------------------------------------------------------------------------
+27.05.2015, Zesstra
+
diff --git a/doc/props/P_IP_NAME b/doc/props/P_IP_NAME
new file mode 100644
index 0000000..7b503ea
--- /dev/null
+++ b/doc/props/P_IP_NAME
@@ -0,0 +1,8 @@
+NAME:
+    P_IP_NAME                     "ip_name"                     
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Rechnername des Interactives
diff --git a/doc/props/P_IS_ARTILLERY b/doc/props/P_IS_ARTILLERY
new file mode 100644
index 0000000..051b20f
--- /dev/null
+++ b/doc/props/P_IS_ARTILLERY
@@ -0,0 +1,15 @@
+NAME:
+	P_IS_ARTILLERY			"artillery"
+
+DEFINIERT IN:
+	/sys/combat.h
+
+BESCHREIBUNG:
+	Is ein Objekt Artillerie, so muss diese Property
+	gesetzt sein. (Derzeit einfach auf 1 setzen.)
+
+SIEHE AUCH:
+	artillerie
+
+----------------------------------------------------------------------------
+Last modified: Sam,  5. Jul 2003, 22:07:12 by Zook.
diff --git a/doc/props/P_ITEMS b/doc/props/P_ITEMS
new file mode 100644
index 0000000..add4255
--- /dev/null
+++ b/doc/props/P_ITEMS
@@ -0,0 +1,9 @@
+NAME:
+    P_ITEMS                       "items"                       
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Definition von Gegenstaenden, die in dem Raum liegen sollen.
+     Erklaerung in einem Extrafile.
diff --git a/doc/props/P_I_HATE_ALCOHOL b/doc/props/P_I_HATE_ALCOHOL
new file mode 100644
index 0000000..f60a38f
--- /dev/null
+++ b/doc/props/P_I_HATE_ALCOHOL
@@ -0,0 +1,23 @@
+NAME:
+    P_I_HATE_ALCOHOL                        "i_hate_alcohol"
+
+DEFINIERT IN:
+    /sys/inpc/boozing.h
+
+BESCHREIBUNG:
+    Numerischer Wert, der die Obergrenze an P_ALCOHOL in einem Monster
+    definiert, welcher beim eigenstaendigen Tanken beruecksichtigt wird.
+
+BEMERKUNG:
+    Geht der Npc (und nur fuer solche ist diese Prop gedacht) eigen-
+    staendig tanken, werden vor dem Bestellen die Getraenke und Speisen
+    auf ihren Alkoholgehalt geprueft und mit dem aktuellen Wert von
+    P_ALCOHOL im Verhaeltnis zu P_I_HATE_ALCOHOL verglichen. Laege der
+    Wert fuer P_ALCOHOL dann ueber dem von P_I_HATE_ALCOHOL, wird dieses
+    Getraenk (diese Speise) nicht bestellt.
+
+SIEHE AUCH:
+     P_ALCOHOL, P_MAX_ALCOHOL
+
+----------------------------------------------------------------------------
+Last modified: Sam Apr 14 12:35:00 2001 by Tilly
diff --git a/doc/props/P_KEEPER b/doc/props/P_KEEPER
new file mode 100644
index 0000000..c0275ba
--- /dev/null
+++ b/doc/props/P_KEEPER
@@ -0,0 +1,14 @@
+NAME:
+    P_KEEPER                       "shop_keeper"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    In diese Property kann man in Kneipen und Laeden einen String schreiben.
+    Dann wird vor den Transaktionen geprueft, ob ein NPC anwesend ist,
+    der diesen String als ID hat.
+    Ist der NPC nicht vorhanden, kann nichts ge- oder verkauft werden.
+
+----------------------------------------------------------------------------
+Last modified: Mon Aug 23 14:29:00 1999 by Paracelsus
\ No newline at end of file
diff --git a/doc/props/P_KEEP_ON_SELL b/doc/props/P_KEEP_ON_SELL
new file mode 100644
index 0000000..8a21407
--- /dev/null
+++ b/doc/props/P_KEEP_ON_SELL
@@ -0,0 +1,8 @@
+NAME:
+    P_KEEP_ON_SELL                "keep_on_sell"                
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Bei "verkaufe alles" wird das Objekt behalten.
diff --git a/doc/props/P_KILLER b/doc/props/P_KILLER
new file mode 100644
index 0000000..83f6b18
--- /dev/null
+++ b/doc/props/P_KILLER
@@ -0,0 +1,27 @@
+NAME:
+    P_KILLER                      "killer"                      
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+   Diese Property enthaelt das Objekt, welches das Lebewesen als letztes
+   getoetet hat. Sie wird von do_damage(), heart_beat() (Vergiftungen) und
+   die() (bei direkten Aufrufen) automatisch gesetzt. Ein manuelles
+   Setzen vor Aufruf von do_damage() oder die() hat keinerlei Wirkung!
+   Sinnvollerweise liest man diese Property im NotifyPlayerDeath() aus,
+   spaeteres Auslesen ist unzuverlaessig, da der Killer inzwischen zerstoert
+   sein koennte.
+   Diese Property sollte _nicht_ per Hand gesetzt werden, schon gar nicht
+   waehrend eines NotifyPlayerDeath(), weil es evtl. noch andere Objekte gibt,
+   die sich dafuer interessieren!
+
+BEMERKUNGEN:
+   Normalerweise steht hier ein Objekt drin (s.o.). Es gibt allerdings eine
+   Ausnahme: Stirbt ein Lebewesen an Gift, enthaelt P_KILLER den String
+   "gift".
+
+SIEHE AUCH:
+   do_damage()
+
+29.08.2008, Zesstra
diff --git a/doc/props/P_KILLS b/doc/props/P_KILLS
new file mode 100644
index 0000000..3dae72d
--- /dev/null
+++ b/doc/props/P_KILLS
@@ -0,0 +1,10 @@
+NAME:
+    P_KILLS                       "playerkills"                 
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Anzahl der Spieler, die dieser Spieler schon getoetet hat.
+     Unerlaubte Manipulation ist ein SCHWERES VERGEHEN gegen
+     die Mudreglen.
diff --git a/doc/props/P_KILL_MSG b/doc/props/P_KILL_MSG
new file mode 100644
index 0000000..0a9e3bb
--- /dev/null
+++ b/doc/props/P_KILL_MSG
@@ -0,0 +1,80 @@
+P_KILL_MSG
+
+NAME:
+	P_KILL_MSG			"kill_msg"
+
+DEFINIERT IN:
+	/sys/properties.h
+
+BESCHREIBUNG:
+     Wenn ein Spieler getoetet wird, so erscheint dazu eine kurze Information
+     auf dem Todeskanal. Um dem toetenden Objekt zusaetzlich die Moeglichkeit
+     zu geben, noch etwas mehr auf diesem Kanal auszugeben, kann man in
+     dieser Property einen String uebergeben.
+     Noetige Zeilenumbrueche werden hierbei automatisch generiert.
+
+     Es ist auch moeglich anzugeben, ob Emotes verwendet werden und ob das
+     toetende Objekt ein Plural-Objekt ist. Hierzu uebergibt man ein Array
+     der Gestalt:
+
+	({Killmessage,Emotes}) bzw. ({Killmessage,Emotes,PLURAL})
+
+     Der Eintrag <Killmessage> stellt hierbei die Meldung selbst dar, PLURAL
+     gibt an, dass es sich um ein Plural-Objekt handelt und <Emotes> kann
+     folgende Werte annehmen:
+
+	MSG_SAY    - Meldung wird normal ausgegeben.
+	MSG_EMOTE  - Meldung erscheint als Emote.
+	MSG_GEMOTE - Meldung erscheint als Genitiv-Emote.
+	MSG_EMPTY  - Meldung erscheint ohne zuvorige Angabe des
+	               toetenden Objektes.
+
+     Moechte man die Meldung noch etwas "persoenlicher" ;-) gestalten, so
+     kann man den Platzhalter %s verwenden. An dessen Stelle wird dann der
+     Name des Verblichenen eingesetzt.
+
+BEISPIEL:
+     Ein nettes Beispiel ist das folgende: Wenn ein Spieler sich als
+     Drachentoeter bewehrt hat, so kann er traditionell in seinem Blut baden.
+     Hin und wieder ist jedoch auch der Drache erfolgreich, dem man eine
+     lustige Zusatzmeldung fuer den Todeskanal uebergeben kann:
+
+     void create() {
+       ::create();
+       ...
+       SetProp(P_KILL_MSG,"Jetzt bade ich mal in DEINEM Blut, %s!");
+       ...
+     }
+
+
+     Falls der 'Killer' ein Plural-Objekt oder -NPC war, koennte eine Meldung
+     auch folgendermassen aussehen:
+
+     SetProp(P_KILL_MSG,({"haun sich jetzt die Hucke voll.",
+			  MSG_EMOTE,
+			  PLURAL}));
+
+     wobei P_KILL_NAME hier natuerlich auf "Eine Menge Orks" oder
+     dergleichen gesetzt sein sollte. Auf dem Kanal waere dann dies zu
+     lesen:
+
+	[Tod:Lars] Eine Menge Orks haben gerade Orktoeter umgebracht.
+	[Tod:Eine Menge Orks haun sich jetzt die Hucke voll.]
+
+
+     Weiteres Beispiel.
+     Man habe einen NPC, dessen Killname als Plural aufzufassen ist, der aber
+     keinen zusaetlichen Text auf -Tod bringen soll.
+
+     SetProp(P_NAME, "Eine Horde Gummibaeren");
+     SetProp(P_KILL_NAME, "Viele kleine Gummibaeren");
+     SetProp(P_KILL_MSG, ({0, 0, 1}));
+
+SIEHE AUCH:
+     Tod:		die(L)
+     Todesmeldungen:	P_KILL_NAME, P_DIE_MSG, P_MURDER_MSG
+			P_ZAP_MSG, P_ENEMY_DEATH_SEQUENCE
+     Sonstiges:		P_CORPSE, P_NOCORPSE, /room/death/death_room.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Aug 21 14:36:04 2002 by Bambi
diff --git a/doc/props/P_KILL_NAME b/doc/props/P_KILL_NAME
new file mode 100644
index 0000000..3f214ab
--- /dev/null
+++ b/doc/props/P_KILL_NAME
@@ -0,0 +1,43 @@
+P_KILL_NAME
+
+NAME:
+     P_KILL_NAME			"kill_name"
+
+DEFINIERT IN:
+     /sys/properties.h
+
+BESCHREIBUNG:
+     Wenn ein Spieler getoetet wird, so erscheint eine kurze Information auf
+     dem Todeskanal. Im Normalfall werden die Informationen aus P_NAME,
+     P_ARTICLE und P_GENDER des toetenden Objektes verwendet, um einen Namen
+     fuer eben dieses Objekt zu kreieren. Manchmal moechte man jedoch einen
+     davon unabhaengigen Namen dort stehen haben. Dann kommt die Property
+     P_KILL_NAME zum Einsatz.
+     Man sollte beachten, dass der Name des Toetenden nicht zu lang sein
+     sollte, denn obwohl bei einer Todesmeldung automatisch umgebrochen wird,
+     kann es doch ziemlich stoeren. Wenn das toetende Objekt ein Plural-
+     Objekt ist, so kann man dies zusaetzlich in der Property P_KILL_MSG
+     angeben.
+
+BEISPIEL:
+     Eine Wolke, die wahlweise zwischen verschiedenen Zustaenden mutiert,
+     koennte mal eine Eiswolke, mal eine Giftwolke oder auch mal eine
+     Feuerwolke sein. Fuer den Todeskanal soll jedoch immer erscheinen:
+     '[Tod:] Eine mutierende Wolke hat gerade <Spieler> umgebracht.'
+
+     void create()
+     {
+       ::create();
+       ...
+       SetProp(P_KILL_NAME,"Eine mutierende Wolke");
+       ...
+     }
+
+SIEHE AUCH:
+     Tod:		die(L)
+     Todesmeldungen:	P_KILL_MSG, P_DIE_MSG, P_MURDER_MSG
+			P_ZAP_MSG, P_ENEMY_DEATH_SEQUENCE
+     Sonstiges:		P_CORPSE, P_NOCORPSE, /room/death/death_room.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_KNOWN_POTIONROOMS b/doc/props/P_KNOWN_POTIONROOMS
new file mode 100644
index 0000000..f5adb97
--- /dev/null
+++ b/doc/props/P_KNOWN_POTIONROOMS
@@ -0,0 +1,19 @@
+NAME:
+    P_KNOWN_POTIONROOMS                 "known_potionrooms"                 
+
+DEFINIERT IN:
+    /sys/player/potion.h
+
+BESCHREIBUNG:
+    Array mit den Nummern der Raeume, in denen der Spieler Zauber-
+    traenke finden kann. Die Zuordnung der Raeume und Nummern
+    geschieht im Potionmaster.
+
+    Nur lesbare _query - Property.
+
+SIEHE AUCH:
+    Sonstiges: zaubertraenke, /secure/potionmaster.c, /room/orakel.c
+    Verwandt:  FindPotion(), AddKnownPotion(), RemoveKnownPotion(), InList()
+    Props:     P_POTIONROOMS
+
+6.Feb 2016 Gloinson
diff --git a/doc/props/P_LASTDIR b/doc/props/P_LASTDIR
new file mode 100644
index 0000000..eae9071
--- /dev/null
+++ b/doc/props/P_LASTDIR
@@ -0,0 +1,15 @@
+NAME:
+    P_LASTDIR                  "p_lib_lastdir"
+
+DEFINIERT IN:
+    /sys/shells.h
+
+BESCHREIBUNG:
+    Das jeweils letzte Verzeichnis, in dem der Magier war.
+    (Nur fuer Magier von Belang)
+
+Siehe auch:
+    P_CURRENTDIR
+
+Letzte Aenderung:
+    03.05.2016, Zesstra
diff --git a/doc/props/P_LAST_COMBAT_TIME b/doc/props/P_LAST_COMBAT_TIME
new file mode 100644
index 0000000..b3df96d
--- /dev/null
+++ b/doc/props/P_LAST_COMBAT_TIME
@@ -0,0 +1,23 @@
+NAME:
+	P_LAST_COMBAT_TIME		"last_combat_time"
+
+DEFINIERT IN:
+	/sys/combat.h
+
+BESCHREIBUNG:
+	In dieser Property wird genau die Zeit festgehalten, zu der ein
+	Lebewesen zuletzt einen Angriff abgewehrt oder einen Angriff
+	durchgefuehrt hat. Die Property enthaelt diese Information hierbei
+	immer in Form eines Integerwertes.
+	Dieser Wert koennte z.B. wichtig sein, wenn man wissen moechte, wann
+	ein Lebewesen zuletzt gekaempft hat. Es ist beispielsweise nicht
+	moeglich, waehrend oder auch unmittelbar nach einem Kampf den Befehl
+	'Ende' zu nutzen, da dies zur Flucht missbraucht werden kann. Dafuer
+	wird der Wert der Property zuvor ausgewertet.
+
+SIEHE AUCH:
+	P_LAST_DAMTIME, P_LAST_DAMAGE, P_LAST_DAMTYPES, Attack(), Defend(),
+	/std/living/combat.c, /std/living/life.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 26 16:43:00 1999 by Patryn
diff --git a/doc/props/P_LAST_COMMAND_ENV b/doc/props/P_LAST_COMMAND_ENV
new file mode 100644
index 0000000..576e34d
--- /dev/null
+++ b/doc/props/P_LAST_COMMAND_ENV
@@ -0,0 +1,15 @@
+P_LAST_COMMAND_ENV
+NAME:
+    P_LAST_COMMAND_ENV            "last_command_env"            
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Der Raum, in dem das letzte Kommando eingegeben wurde.
+
+BEMERKUNGEN:
+     Keine echte Property, _query_last_command_env() ist
+     in /std/players/command.c implementiert.
+
+14.Feb.2004 Gloinson
diff --git a/doc/props/P_LAST_CONTENT_CHANGE b/doc/props/P_LAST_CONTENT_CHANGE
new file mode 100644
index 0000000..0fa64bb
--- /dev/null
+++ b/doc/props/P_LAST_CONTENT_CHANGE
@@ -0,0 +1,16 @@
+NAME:
+    P_LAST_CONTENT_CHANGE         "last_content_change"         
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wann wurde zum letzten Mal was ins Obj gestopft oder rausgenommen?
+     Wichtig fuer den Weight-Cache
+
+ANMERKUNG:
+     Die Property kann nur ueber QueryProp() und SetProp() ausgelesen bzw.
+     gesetzt werden. Query() und Set() funktionieren *nicht*.
+
+     Ausserdem fuehrt ein Setzen per SetProp() zu einer Erhoehung des 
+     Wertes um eins - unabhaengig vom gesetzten Wert.
diff --git a/doc/props/P_LAST_DAMAGE b/doc/props/P_LAST_DAMAGE
new file mode 100644
index 0000000..8d618b1
--- /dev/null
+++ b/doc/props/P_LAST_DAMAGE
@@ -0,0 +1,22 @@
+NAME:
+	P_LAST_DAMAGE			"last_damage"
+
+DEFINIERT IN:
+	/sys/living/combat.h
+
+BESCHREIBUNG:
+	In dieser Property wird genau die Schadensstaerke festgehalten,
+	welche ein Lebewesen zuletzt abbekommen hat. Die Property enthaelt
+	diese Information hierbei immer in Form eines Integerwertes.
+	Auch die Staerke des Giftschadens durch die Wirkung einer Vergiftung
+	wird hier festgehalten.
+	Dieser Wert koennte z.B. wichtig sein, wenn man wissen moechte,
+	welche Schadensstaerke nach Einwirkung von Defendern, Ruestung,
+	Hooks und Skills uebriggeblieben ist.
+
+SIEHE AUCH:
+	P_LAST_DAMTIME, P_LAST_DAMTYPES, Defend(),
+	/std/living/combat.c, /std/living/life.c
+
+----------------------------------------------------------------------------
+Last modified: Tue Jan 26 12:34:29 1999 by Patryn
diff --git a/doc/props/P_LAST_DAMTIME b/doc/props/P_LAST_DAMTIME
new file mode 100644
index 0000000..72ffb51
--- /dev/null
+++ b/doc/props/P_LAST_DAMTIME
@@ -0,0 +1,22 @@
+NAME:
+	P_LAST_DAMTIME			"last_damtime"
+
+DEFINIERT IN:
+	/sys/living/combat.h
+
+BESCHREIBUNG:
+	In dieser Property wird genau die Zeit festgehalten, zu der ein
+	Lebewesen zuletzt einen Schaden abbekommen hat. Die Property
+	enthaelt diese Information hierbei immer in Form eines
+	Integerwertes.
+	Auch der Zeitpunkt der Einwirkung von Giftschaden durch die Wirkung
+	einer Vergiftung wird hier festgehalten.
+	Dieser Wert koennte z.B. wichtig sein, wenn man wissen moechte, wann
+	ein Lebewesen zuletzt verletzt wurde.
+
+SIEHE AUCH:
+	P_LAST_COMBAT_TIME, P_LAST_DAMAGE, P_LAST_DAMTYPES, Defend(),
+	/std/living/combat.c, /std/living/life.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 26 16:44:38 1999 by Patryn
diff --git a/doc/props/P_LAST_DAMTYPES b/doc/props/P_LAST_DAMTYPES
new file mode 100644
index 0000000..9d7b060
--- /dev/null
+++ b/doc/props/P_LAST_DAMTYPES
@@ -0,0 +1,21 @@
+NAME:
+	P_LAST_DAMTYPES			"last_damtypes"
+
+DEFINIERT IN:
+	/sys/living/combat.h
+
+BESCHREIBUNG:
+	In dieser Property werden genau die Schadensarten festgehalten,
+	welche ein Lebewesen zuletzt abbekommen hat. Die Property enthaelt
+	diese Information hierbei immer in Form eines Arrays.
+	Auch der Giftschaden durch die Wirkung einer Vergiftung wird hier
+	festgehalten.
+	Dieser Wert koennte z.B. wichtig sein, wenn man nach dem Tod eines
+	Lebewesens feststellen moechte, durch was es umgekommen ist.
+
+SIEHE AUCH:
+	P_LAST_DAMAGE, P_LAST_DAMTIME, Defend(),
+	/std/living/combat.c, /std/living/life.c
+
+----------------------------------------------------------------------------
+Last modified: Tue Jan 26 12:34:29 1999 by Patryn
diff --git a/doc/props/P_LAST_DEATH_PROPS b/doc/props/P_LAST_DEATH_PROPS
new file mode 100644
index 0000000..712e04e
--- /dev/null
+++ b/doc/props/P_LAST_DEATH_PROPS
@@ -0,0 +1,18 @@
+NAME:
+    P_LAST_DEATH_PROPS                "last_death_props"
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt nach dem Tod eines Spielers ein Mapping mit 
+     den Werte aller Properties, die im die() zurueckgesetzt werden.
+
+     Auf diese Weise kann ein Objekt auch im NotifyPlayerDeath() noch 
+     auf die Werte zurueckgreifen, obwohl sie bereits geloescht sind.
+
+     Folgende Properties werden so gesichert:
+   
+     P_POISON, P_FROG, P_ALCOHOL, P_DRINK, P_FOOD , P_BLIND, P_DEAF, 
+     P_MAX_HANDS, P_PARA, P_NO_REGENERATION , P_HP, P_SP, P_LAST_DEATH_TIME
+
diff --git a/doc/props/P_LAST_DEATH_TIME b/doc/props/P_LAST_DEATH_TIME
new file mode 100644
index 0000000..71bd787
--- /dev/null
+++ b/doc/props/P_LAST_DEATH_TIME
@@ -0,0 +1,8 @@
+NAME:
+    P_LAST_DEATH_TIME                "last_death_time"
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Der Zeitpunkt des letzten Todes des Spielers.
diff --git a/doc/props/P_LAST_LOGIN b/doc/props/P_LAST_LOGIN
new file mode 100644
index 0000000..9287654
--- /dev/null
+++ b/doc/props/P_LAST_LOGIN
@@ -0,0 +1,16 @@
+NAME:
+    P_LAST_LOGIN                  "last_login"                  
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Zeitpunkt des letzten Logins
+
+BEMERKUNGEN:
+     Gegen aeussere Aenderung und Set/QueryMethoden geschuetzt.
+
+SIEHE AUCH:
+     P_LAST_LOGOUT, save_me
+
+28. Jan 2013 Gloinson
diff --git a/doc/props/P_LAST_LOGOUT b/doc/props/P_LAST_LOGOUT
new file mode 100644
index 0000000..296ae92
--- /dev/null
+++ b/doc/props/P_LAST_LOGOUT
@@ -0,0 +1,20 @@
+NAME:
+    P_LAST_LOGOUT                 "last_logout"                 
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Zeitpunkt des letzten Logouts. Anhand dieser Zeit werden die Feindes-
+     listen und in Abwesenheit eingefuegte Gegenstaende aktualisiert.
+
+     Dieses Datum wird bei Magiern nicht aktualisiert, wenn sie unsichtbar
+     sind/sich unsichtbar ausloggen.
+
+BEMERKUNGEN:
+     Gegen aeussere Aenderung und Set/QueryMethoden geschuetzt.
+
+SIEHE AUCH:
+     P_LAST_LOGIN, P_INVIS, save_me, init, StopHuntFor
+
+28. Jan 2013 Gloinson
diff --git a/doc/props/P_LAST_MOVE b/doc/props/P_LAST_MOVE
new file mode 100644
index 0000000..6b202a2
--- /dev/null
+++ b/doc/props/P_LAST_MOVE
@@ -0,0 +1,21 @@
+NAME:
+	P_LAST_MOVE			"last_move"
+
+DEFINIERT IN:
+	/sys/thing/moving.h
+
+BESCHREIBUNG:
+	In dieser Property wird die Zeit der letzten Bewegung eines
+	Lebewesens festgehalten. Selbsterklaerend ist auch der dazugehoerige
+	Quellcode innerhalb move() in '/std/living/moving.c':
+	  SetProp(P_LAST_MOVE,time());
+	Wichtig ist diese Property insbesondere fuer die Unterbindung von
+	Rein-Angriff-Raus-Taktiken. Dieser Modus ist standardmaessig in jedem
+	NPC aktiviert und kann ueber die Property P_ENABLE_IN_ATTACK_OUT
+	ausgeschalten werden.
+
+SIEHE AUCH:
+	move(), time(), P_ENABLE_IN_ATTACK_OUT, /std/living/moving.c
+
+-----------------------------------------------------------------------------
+Last modified: Sat Jan 30 12:53:00 1999 by Patryn
diff --git a/doc/props/P_LAST_USE b/doc/props/P_LAST_USE
new file mode 100644
index 0000000..5ca875d
--- /dev/null
+++ b/doc/props/P_LAST_USE
@@ -0,0 +1,20 @@
+P_LAST_USE
+
+NAME:
+     P_LAST_USE "last_use"
+
+DEFINIERT IN:
+     <properties.h>
+
+BESCHREIBUNG:
+     Diese Property wird in Ruestungen und Waffen dazu benutzt um
+     festzuhalten, wann die Ruestung/Waffe zuletzt im Kampf benutzt
+     wurde.
+
+SIEHE AUCH:
+     Ruestungen:	QueryDefend(L)
+     Waffen:		QueryDamage(L)
+     Sonstiges:		P_EQUIP_TIME, P_UNWIELD_TIME
+
+----------------------------------------------------------------------------
+Last modified: Fri Feb 06 10:15:00 1998 by Paracelsus
diff --git a/doc/props/P_LAST_WEAR_ACTION b/doc/props/P_LAST_WEAR_ACTION
new file mode 100644
index 0000000..1a4d224
--- /dev/null
+++ b/doc/props/P_LAST_WEAR_ACTION
@@ -0,0 +1,24 @@
+PROPERTY:
+
+	P_LAST_WEAR_ACTION    "last_wear_action"
+
+DEFINIERT IN: 
+
+	/sys/armour.h (und damit auch in properties.h)
+
+BESCHREIBUNG:
+
+	Diese Prop gibt an, welche An/Auszieh-Aktion ein Spieler zuletzt
+	durchgefuehrt hat. Sie ist ein zweielementiges Array, wobei der
+	erste Eintrag angibt, ob der Spieler sich an- oder ausgezogen
+	hat (WA_WEAR, WA_UNWEAR, auch in armour.h definiert) und der
+	zweite den Zeitpunkt.
+
+	Die Property wird (unter anderem?) dafuer verwendet festzustellen ob
+	der Spieler in der letzten Runde schon einen Ruestungswechsel
+	vorgenommen hat und einen entgegengesetzten zu unterbinden.
+
+LETZTE AENDERUNG: 
+
+2003-01-29, 17:30 von Humni
+
diff --git a/doc/props/P_LAST_XP b/doc/props/P_LAST_XP
new file mode 100644
index 0000000..e5ee055
--- /dev/null
+++ b/doc/props/P_LAST_XP
@@ -0,0 +1,27 @@
+NAME:
+    P_LAST_XP                        "last_xp"
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+    Ein Array vom Typ ({ pfad, xp }).
+
+    Der Eintrag "pfad" gibt das Gebiet an, in dem ein Spieler zuletzt XP
+    bekommen hat. Dabei wird aus "/d/ebene/magier/room/raum1.c" dann
+    "/d/ebene/magier/room".
+
+    Der Wert "xp" zeigt an, wieviele XP der Spieler _in diesem Gebiet_
+    gesammelt hat. Sobald er auch nur einen XP in einem anderen Gebiet
+    bekommt, zeigt P_LAST_XP nur noch diesen neu erhaltenen XP an.
+
+    Der Anwendungszweck waere z.B. eine Heilstelle, die nur dann Wirkung
+    zeigt, wenn der Spieler wirklich in dem betreffenden Gebiet gemetzelt hat
+    und nicht nur zum Tanken hergerannt ist oder eine Unterscheidung, ob
+    jemand metzelt oder nur uebt (ueber die XP).
+
+SIEHE AUCH:
+     Funktionen:  AddExp()
+     Verwandt:    P_NO_XP, P_XP
+
+14.Feb 2007 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_LEAVECMDS b/doc/props/P_LEAVECMDS
new file mode 100644
index 0000000..e31cf8a
--- /dev/null
+++ b/doc/props/P_LEAVECMDS
@@ -0,0 +1,32 @@
+NAME:
+    P_LEAVECMDS                   "leavecmds"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+    Ein Array mit Befehlen, die zum Verlassen des Transporters fuehren. 
+
+BEISPIEL:
+    SetProp(P_LEAVECMDS,({ "verlass","verlasse" }) );
+
+    Gibt der Spieler nun 'verlasse xxx' ein, so sorgt /std/transport.c 
+    dafuer, das der Spieler auch von oder aus dem Transporter bewegt 
+    wird. Vorausgesetzt natuerlich, er ist an einem Haltepunkt angelangt.
+
+BEMERKUNGEN:
+    Um /std/transport.c nicht aufzublaehen, werden weitere Argumente wie
+    etwa 'verlasse das|die|den xxx' _nicht_ unterstuetzt!
+
+    Hier muss der verantwortliche Magier schon eine eigene Loesung finden
+    und in seinen Transporter schreiben.
+
+    Sollen Kommandos zum Betreten UND Verlassen eines Transporters ver-
+    wendet werden koennen, muessen diese in P_TRAVEL_CMDS gesetzt werden.
+
+SIEHE AUCH:
+    P_LEAVEFAIL, P_ENTERFAIL, P_ENTERCMDS, P_TRAVEL_CMDS, transporter,
+
+LETZTE AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
+    
\ No newline at end of file
diff --git a/doc/props/P_LEAVEFAIL b/doc/props/P_LEAVEFAIL
new file mode 100644
index 0000000..a54b4a1
--- /dev/null
+++ b/doc/props/P_LEAVEFAIL
@@ -0,0 +1,26 @@
+NAME:
+    P_LEAVEFAIL                   "leavefail"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+     Meldung an den Spieler, wenn er ausserhalb der Anlegezeiten einen 
+     Transporter verlassen will. Ist die Propertie ein Array, so wird 
+     das erste Element als Meldung an den Spieler, das zweite als 
+     Meldung an die Mitspieler im Transporter geschickt. Ist der Eintrag
+     dagegen ein simpler String, so wird die Meldung nur an den Spieler
+     ausgegeben.
+
+BEISPIEL:
+     SetProp(P_LEAVEFAIL, "Die Wildgaense fliegen viel zu hoch" );
+
+     SetProp(P_LEAVEFAIL, ({ "Die Wildgaense fliegen viel zu hoch",
+                             "versucht, vom Ruecken der Wildgans zu "
+                            +"klettern und besinnt sich dann doch" }) );
+                             
+SIEHE AUCH:
+     P_LEAVEMSG, P_ENTERMSG, P_ENTERFAIL, transporter
+
+LETZTE AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
diff --git a/doc/props/P_LEAVEMSG b/doc/props/P_LEAVEMSG
new file mode 100644
index 0000000..592bbc4
--- /dev/null
+++ b/doc/props/P_LEAVEMSG
@@ -0,0 +1,19 @@
+NAME:
+    P_LEAVEMSG                    "leavemsg"                    
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+     Array mit zwei Meldungen. Der erste Eintrag wird an den Transporter
+     ausgegeben, der zweite an den Raum in den der Spieler kommt.
+
+BEISPIEL:
+     SetProp(P_LEAVEMSG, ({ "klettert vom Ruecken der Wildgans",
+                            "kommt vom Ruecken einer Wildgans herunter" }) );
+
+SIEHE AUCH: 
+     P_ENTERMSG, P_LEAVEFAIL, P_ENTERFAIL, transporter
+
+LETZTE AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
diff --git a/doc/props/P_LEP b/doc/props/P_LEP
new file mode 100644
index 0000000..7628b1c
--- /dev/null
+++ b/doc/props/P_LEP
@@ -0,0 +1,9 @@
+NAME:
+    P_LEP                         "lep"                         
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Levelpunkte eines Spielers
+     NICHT VON HAND SETZEN!!!
diff --git a/doc/props/P_LEVEL b/doc/props/P_LEVEL
new file mode 100644
index 0000000..40be5d0
--- /dev/null
+++ b/doc/props/P_LEVEL
@@ -0,0 +1,33 @@
+NAME:
+    P_LEVEL                       "level"                       
+
+DEFINIERT IN:
+    /sys/living/description.h
+
+BESCHREIBUNG:
+
+     Spieler-Level (!= Magierlevel)
+
+     In Krankheits- (CL_DISEASE) und Giftobjekten (CL_POISON) drueckt 
+     P_LEVEL aus, wie schwer die Krankheit/das Gift ist. Je nachdem, wie 
+     hoch oder niedrig der Level gesetzt wird, muss z.B. ein Kleriker mehr 
+     oder weniger oft kurieren, um  eine (ggf. stufenweise) Heilung zu 
+     bewirken.
+
+     In Fluchobjekten (CL_CURSE) gibt P_LEVEL ebenfalls die Schwere des
+     Fluches an, jedoch ist hier zu beachten, dass z.B. Kleriker aktuell
+     keine stufenweise Schwaechung bewirken koennen, sondern entweder den
+     Fluch entfernen koennen oder komplett scheitern. 
+     Der Fluchlevel ist hier grob als Chance des Scheiterns in einem 
+     Wertebereich von 1-100 zu sehen, was bedeutet, dass ein Fluchlevel 
+     von 100 als permanenter, nicht entfernbarer Fluch anzusehen ist.
+
+     Genaueres ist in der Klerusgilde nachzulesen oder beim GM Klerus zu
+     erfragen.
+
+SIEHE AUCH:
+     Properties:  P_GUILD_LEVEL
+     Allgemeines: /doc/wiz/gift, /doc/help/gift
+     Funktionen:  AddClass(L), is_class_member(L)
+
+Letzte Aenderung: 2015-Feb-02, Arathorn.
diff --git a/doc/props/P_LIFETIME b/doc/props/P_LIFETIME
new file mode 100644
index 0000000..250c287
--- /dev/null
+++ b/doc/props/P_LIFETIME
@@ -0,0 +1,30 @@
+NAME:

+     P_LIFETIME                    "std_food_lifetime"

+

+DEFINIERT IN:

+     /sys/food.h

+

+BESCHREIBUNG:

+     Zeit in Sekunden, die die Speise haltbar ist.

+     Mit Setzen dieser Property wird der Wert fuer P_RESET_LIFETIME und

+     dort gespeichert.

+     Nach dieser Zeit wird diese Speise schlecht und je nach Konfiguration

+     der Speise eventuell zerstoert. Sichergestellt wird dies durch den

+     Aufruf von reset() nach dieser Anzahl Sekunden.

+     Moechte man eine Speise haben, die niemals verdirbt

+     (genehmigungspflichtig!), nutzt man die Property P_NO_BAD

+     

+BEMERKUNGEN:

+     Sobald der Countdown zum Schlechtwerden der Speise laeuft, also ein

+     Spieler damit in Beruehrung kam, zeigt SetProp auf diese Property keine

+     Wirkung mehr.

+

+DEFAULT:

+     Ohne Setzen von P_LIFETIME ,P_RESET_LIFETIME und P_NO_BAD verdirbt die

+     Speise nach einem Reset, also zwischen 30 und 60 Minuten

+

+SIEHE AUCH:

+     wiz/food, P_RESET_LIFETIME, P_NO_BAD

+

+------------------------------------------------------------------------------

+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_LIGHT b/doc/props/P_LIGHT
new file mode 100644
index 0000000..251e927
--- /dev/null
+++ b/doc/props/P_LIGHT
@@ -0,0 +1,62 @@
+NAME:
+    P_LIGHT                       "light"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Gibt den Lichtlevel eines Objektes an, d.h. wie hell das Objekt von sich
+    aus leuchtet. Moechte man den gesamten Lichtlevel haben der von einem
+    Objekt ausgeht, so sollte man P_TOTAL_LIGHT nehmen, das den Inhalt eines
+    Containers direkt mit verrechnet.
+
+    Bitte _nur_ ueber SetProp bzw. QueryProp zugreifen, da es fuer die
+    Berechnung wichtig ist, das in allen Containern P_LAST_CONTENT_CHANGE
+    gesetzt wird um ein neuberechnen des Lichtlevels auszuloesen!
+
+ANMERKUNG:
+    Um ein ungefaehres Gefuehl davon zu bekommen was ein Lichtlevel in
+    etwa bedeutet hier einige allgemeine Beispiele von Gegenstaenden.
+    Grundsaetzlich sollten Lichtlevel <0 und >2 nur in Ruecksprache mit dem
+    Balanceteam benutzt werden.
+
+    Lichtlevel -1,  z.B. ein schwarzer Ring, von dem eine kleine dunkle Aura
+                    ausgeht, die den Spieler umgibt.
+    Lichtlevel  0,  der Gegenstand beeinflusst das Licht ueberhaupt nicht
+    Lichtlevel  1,  der Spieler haelt eine kleine Lichtquelle in Haenden,
+                    dieses kann ein Leuchtpfirsich, eine Fackel oder ein
+                    Feuerschwert oder aehnliches sein.
+    Lichtlevel  2,  eine etwas groessere Lichtquelle, die aber immer noch
+                    nicht den Raum beleuchtet sondern lediglich dem Spieler
+                    einen Lichtschein gewaehrt mit dem er sehen kann.
+    Lichtlevel >2,  extrem helle Lichtquellen, die den gesamten Raum
+                    ausleuchten, in der Regel wohl eher magischer Natur.
+                    Solche Lichtquellen sollten sich mit der Zeit
+                    verbrauchen, dem Spieler Schaden zufuegen oder
+                    aehnliches, damit die Spieler nicht defaultmaessig mit
+                    einer solchen Lichtquelle durchs MG ziehn.
+
+    Daraus ergeben sich dann folgende Konsequenzen fuer Raeume:
+    Lichtlevel  >1: Der Raum ist sehr hell erleuchtet und kann von Spielern
+                    nicht oder nur sehr schwer abgedunkelt werden. Ein Wert
+                    von 2-3 kann interessant sein, wenn die NPCs im Raum
+                    ueber keine Nachtsicht verfuegen. Ueber ein Abdunkeln des
+                    Raumes kann der Spieler dann doch den Nachtkampf nutzen.
+    Lichtlevel   1: Der Raum ist erleuchtet und die Spieler koennen ohne
+                    weitere Lichtquellen sehen...
+    Lichtlevel   0: Ein dunkler Raum in dem man mit jeder Fackel sehen kann.
+    Lichtlevel  -1: man benoetigt zwei einfache Lichtquellen oder Nachtsicht
+                    um in diesem Raum etwas sehen zu koennen.
+    Lichtlevel  -2: Man benoetigt schon eine besondere Lichtquelle um in
+                    diesem Raum noch etwas sehen zu koennen. Solche
+                    Lichtquellen sind nichts fuer Anfaenger oder mittlere
+                    Spieler da sie schwer zu beschaffen und in der Regel
+                    auch einige Handicaps haben.
+    Lichtlevel <-2: Der Raum ist wirklich absolut stockduster und
+                    Lichtquellen die solch einen Raum ausleuchten koennen,
+                    sind ausserordentlich selten und haben immer ihre
+                    Tuecken. Diese Lichtlevel sollten nur mit Vorsicht
+                    genossen werden.
+
+SIEHE AUCH:
+    P_TOTAL_LIGHT, P_INT_LIGHT, P_PLAYER_LIGHT, P_LIGHT_MODIFIER, CannotSee()
diff --git a/doc/props/P_LIGHTDESC b/doc/props/P_LIGHTDESC
new file mode 100644
index 0000000..5898db8
--- /dev/null
+++ b/doc/props/P_LIGHTDESC
@@ -0,0 +1,34 @@
+NAME:
+    P_LIGHTDESC                   "lightdesc"                   
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    String oder Array von Strings mit Adjektiven, die das Leuchten der 
+    Lichtquelle beschreiben (z.B. leuchtend, brennend, gluehend).
+    Standardmaessig ist die Property auf "brennend" gesetzt.
+
+    Wenn ein Array angegeben wird, werden die Beschreibungen passend auf
+    die Benndauer aufgeteilt und das zur aktuell noch vorhandenen Rest-
+    Brenndauer passende Adjektiv ausgegeben. Das Array wird dabei rueck-
+    aerts durchlaufen, d.h. fuer eine frisch entzuendete Lichtquelle wird
+    der letzte Eintrag des Arrays verwendet (s. Beispiele).
+
+BEISPIELE:
+    Eine einfache Oellampe:
+
+    SetProp(P_LIGHTDESC, "angezuendet");
+
+    Eine Fackel mit mehreren Brennstadien (aus /items/fackel.c):
+
+    SetProp(P_LIGHTDESC, ({"glimmend","flackernd","leicht flackernd",
+                         "brennend","hell lodernd","frisch angezuendet"}));
+
+SIEHE AUCH:
+    Basisklassen: /std/lightsource.c
+    Properties:   P_FUEL, P_DO_DESTRUCT, P_LIGHT
+    Methoden:     AddFuel(L)
+
+LETZTE AENDERUNG:
+    22. Dez. 2015, Arathorn
diff --git a/doc/props/P_LIGHTED b/doc/props/P_LIGHTED
new file mode 100644
index 0000000..9029b02
--- /dev/null
+++ b/doc/props/P_LIGHTED
@@ -0,0 +1,8 @@
+NAME:
+    P_LIGHTED                     "lighted"                     
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Flag, ob die Lichtquelle in Betrieb ist.
diff --git a/doc/props/P_LIGHT_ABSORPTION b/doc/props/P_LIGHT_ABSORPTION
new file mode 100644
index 0000000..213120f
--- /dev/null
+++ b/doc/props/P_LIGHT_ABSORPTION
@@ -0,0 +1,15 @@
+NAME:
+    P_LIGHT_ABSORPTION                  "light_absorption"
+
+DEFINIERT IN:
+    /sys/room/description.h
+
+BESCHREIBUNG:
+    In Raeumen verteilt sich aufgrund ihrer Groesse das Licht und gerade in
+    groesseren Raeumen kann eine kleine Fackel unter Umstaenden nicht mehr
+    ausreichen den gesamten Raum auszuleuchten. In diesem Fall kann man
+    ueber diese Property das Verhalten des Lichts steuern.
+    Ein "normaler" durchschnittlicher Raum hat hier den Defaultwert 1.
+
+SIEHE AUCH:
+    P_TOTAL_LIGHT, P_INT_LIGHT, P_PLAYER_LIGHT, P_LIGHT_MODIFIER, CannotSee()
diff --git a/doc/props/P_LIGHT_MODIFIER b/doc/props/P_LIGHT_MODIFIER
new file mode 100644
index 0000000..2409c79
--- /dev/null
+++ b/doc/props/P_LIGHT_MODIFIER
@@ -0,0 +1,49 @@
+NAME:
+    P_LIGHT_MODIFIER                     "light_modifier"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Veraendert das Lichtlevel das von einem Lebewesen wahrgenommen wird.
+    Der Wert dieser Property wird additiv in P_PLAYER_LIGHT beruecksichtigt.
+    Es ist hiermit z.B. moeglich eine Sonnenbrille zu programmieren, diese
+    veraendert ja nicht das tatsaechliche Lichtlevel, sondern verdunkelt nur
+    die Sicht.
+
+ANMERKUNG:
+    Damit NPCs in der Lage sind solche Gegenstaende richtig einzuschaetzen,
+    sollte diese Property in jedem Gegenstand der einen Light-Modifier setzt,
+    auch gesetzt sein. Das veraendern dieser Property in Spielern durch NPCs
+    oder Gegenstaende ist selbstverstaendlich genehmigungspflichtig.
+
+BEISPIELE:
+       // Ein NPC der auch in relativ dunklen Raeumen mit Lichtlevel -2
+       // noch sehen kann...
+       create_default_npc(10);
+       SetProp(P_LIGHT_MODIFIER, 3);
+
+       // Eine Sonnenbrille, die das Lichtlevel um eins senkt.
+
+       create()
+       {
+          :
+          SetProp(P_ARMOUR_TYPE, AT_GLASSES);
+          SetProp(P_LIGHT_MODIFIER, -1);
+          :
+       }
+
+       // Achtung: Falls pl Query- oder Set-Methoden auf P_LIGHT_MODIFIER hat,
+       // wird diese Methode hier furchtbar schief gehen und im besten Fall
+       // nichts veraendern. In realen Objekten empfiehlt sich zumindest eine
+       // Pruefung im Vorfeld, ob eine Query-/Set-Methode gesetzt ist.
+       protected void InformWear(object pl, int silent, int all) {
+           pl->SetProp(P_LIGHT_MODIFIER, pl->QueryProp(P_LIGHT_MODIFIER) -1);
+       }
+
+       protected void InformUnwear(object pl, int silent, int all) {
+           pl->SetProp(P_LIGHT_MODIFIER, pl->QueryProp(P_LIGHT_MODIFIER) +1);
+       }
+
+SIEHE AUCH:
+    P_TOTAL_LIGHT, P_INT_LIGHT, P_PLAYER_LIGHT, P_LIGHT_MODIFIER, CannotSee()
diff --git a/doc/props/P_LIGHT_TRANSPARENCY b/doc/props/P_LIGHT_TRANSPARENCY
new file mode 100644
index 0000000..4af4415
--- /dev/null
+++ b/doc/props/P_LIGHT_TRANSPARENCY
@@ -0,0 +1,14 @@
+NAME:
+    P_LIGHT_TRANSPARENCY             "light_transparency"
+
+DEFINIERT IN:
+    /sys/container.h
+
+BESCHREIBUNG:
+    Wieviel Licht schluckt ein Container, d.h. wieviel Licht dringt aus
+    einem Behaelter noch nach draussen. Bei Containern die _nicht_
+    transparent sind, liefert eine _query_method hier immer 999 zurueck.
+    Defaultmaessig steht diese Property auf 2.
+
+SIEHE AUCH:
+    P_TOTAL_LIGHT, P_INT_LIGHT, P_PLAYER_LIGHT, P_LIGHT_MODIFIER, CannotSee()
diff --git a/doc/props/P_LIGHT_TYPE b/doc/props/P_LIGHT_TYPE
new file mode 100644
index 0000000..07322e0
--- /dev/null
+++ b/doc/props/P_LIGHT_TYPE
@@ -0,0 +1,75 @@
+NAME:
+    P_LIGHT_TYPE                       "light_type"
+
+DEFINIERT IN:
+    /sys/thing/description.h
+
+BESCHREIBUNG:
+    Gibt an, was fuer ein Licht in einem Objekt vorherrscht. 
+    
+    Es sind verschiedene 'atomare' Lichttypen, vordefiniert:
+    LT_MISC         Unbestimmt, keine Angaben.
+
+    LT_SUN          Sonnenlicht.
+    LT_MOON         Mondlicht 
+    LT_STARS        Sternenlicht.
+    
+    LT_DIFFUSE      Indirektes Tageslicht. (z.B. im Wald)
+
+    LT_CANDLE       Kerzenlicht.
+    LT_TORCH        Fackelschein.
+    LT_OPEN_FIRE    Sonstiges offenes Feuer. (Lagerfeuer etc.)
+    
+    LT_MAGIC        Irgendeine magische Lichtquelle.
+
+    LT_GLOWING      Eine selbstleuchtende Lichtquelle.
+
+    LT_DARKNESS     Kein wirkliches Licht, aber auch Dunkelheit soll
+                    explizit gesetzt werden koennen.
+
+    In einem Objekt koennen mehrere Lichttypen gesetzt werden. Dies
+    geschieht durch logische Oder-Verknuepfungen, siehe man operators.
+
+    Wenn in einem Raum mehr als ein Lichttyp gesetzt ist, bedeutet das, 
+    normalerweise, dass mehrere Lichtquellen verschiedenen Typs im Raum 
+    sind.
+
+    Es gibt zudem noch Lichttypen, die zusammengesetzt sind:
+
+    LT_DAYLIGHT    Tageslicht (Sonne/Diffuse)
+    LT_NATURAL     Natuerliches Licht (Daylight/Sterne/Mond)
+    LT_ARTIFICIAL  Kuenstliches Licht (Magie/Feuer/Gluehen)
+    LT_FIRE        Feuer (Kerzen/Fackeln/offenes Feuer)
+
+BEISPIELE:
+    Ein Objekt soll ein geheimnisvolles Gluehen von sich geben:
+    
+    objekt->SetProp( P_LIGHT_TYPE, LT_GLOWING )
+
+    Soll ein Raum beschrieben werden, der durch Sternenlicht erhellt ist,
+    in dem aber zusaetzlich noch ein Lagerfeuer brennt, sieht die Syntax
+    folgendermassen aus:
+    
+    raum->SetProp( P_LIGHT_TYPE, LT_STARS|LT_OPEN_FIRE );
+
+    Einer brennenden Hose kann der Lichttyp fuer offenes Feuer mitgegeben 
+    werden. Es muss jedoch nicht zwingend der Lichttyp fuer magische
+    Lichtquellen benutzt werden. Es ist klar, dass es irgendwas mit Magie
+    zu tun hat, wenn brennende Spieler durch die Gegend laufen, ohne zu 
+    schreien. P_LIGHT_TYPE sollte jedoch das fassbare Licht beschreiben.
+    LT_MAGIC ist also eher eine Notloesung fuer Licht, dessen Ursache man
+    nicht erklaeren kann.
+
+
+ANMERKUNG:
+    P_LIGHT_TYPE dient ausschliesslich der Beschreibung des Lichtes, das 
+    vorherrscht. Es ist nicht verbunden mit dem Lichtsystem, und soll es
+    auch nicht werden.
+
+    Die Empfindlichkeit der Dunkelelfen gegen Sonnenlicht wird ueber diese
+    Property gesteuert. Soll ein Raum mit (P_INDOORS==0) so dunkel sein, dass
+    sie nicht in Gefahr sind, sollten nicht LT_MISC oder LT_SUN gesetzt
+    sein.
+
+SIEHE AUCH:
+    CheckLightType, /std/thing/description.h, operators
diff --git a/doc/props/P_LIQUID b/doc/props/P_LIQUID
new file mode 100644
index 0000000..1631a8e
--- /dev/null
+++ b/doc/props/P_LIQUID
@@ -0,0 +1,8 @@
+NAME:
+    P_LIQUID                      "w_max_wasserfuellmenge"      
+
+DEFINIERT IN:
+    /sys/fishing.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_LOCALCMDS b/doc/props/P_LOCALCMDS
new file mode 100644
index 0000000..5a7b515
--- /dev/null
+++ b/doc/props/P_LOCALCMDS
@@ -0,0 +1,12 @@
+NAME:
+    P_LOCALCMDS                   "localcmds"                   
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Ein Array von Arrays aller Befehle die im Spieler selbst definiert sind.
+    ({ ({ "befehl", "funktion", flag, wizlevel }) })
+    Wenn flag gesetzt ist werden nur die ersten Zeichen die auch in Befehl
+    angegeben sind mit dem Verb ueberprueft. Siehe auch
+    add_action("funktion", "befehl", 1) und AddCmd("befehl", "funktion", 1).
diff --git a/doc/props/P_LOCATION b/doc/props/P_LOCATION
new file mode 100644
index 0000000..97344d8
--- /dev/null
+++ b/doc/props/P_LOCATION
@@ -0,0 +1,19 @@
+NAME:
+    P_LOCATION                   "location"
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+    Hier kann der Spieler mit dem Befehl "ort" den Ort setzen,
+    von dem er kommt bzw. zu kommen glaubt ;)
+    Um wieder den automatisch ermittelten Ort anzuzeigen, ist
+    P_LOCATION auf 0 zu setzen.
+    
+SIEHE AUCH:
+    ort
+
+----------------------------------------------------------------------------
+Last modified: Sat Jul 01 23:16:00 2000 by Mupfel
+    
+    
diff --git a/doc/props/P_LOG_INFO b/doc/props/P_LOG_INFO
new file mode 100644
index 0000000..b6bd8dc
--- /dev/null
+++ b/doc/props/P_LOG_INFO
@@ -0,0 +1,32 @@
+NAME:
+    P_LOG_INFO                    "log_info"                    
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wenn diese Property gesetzt ist wird jede Frage, die ein
+     Monster nicht beantworten kann, im Report-File des
+     zustaendigen Magiers geloggt.
+
+     Es ist jedoch auch moeglich, direkt einen Filenamen anzugeben.
+     Bei diesen wird dann jedoch automatisch ein /log/ vorne angehaengt.
+
+BEISPIELE:
+     SetProp(P_LOG_INFO,1);           // Alle fehlenden Infos dieses
+                                         Monsters werden in das Report-
+                                         File unter /log/report/ gelogt.
+
+     SetProp(P_LOG_INFO,"tilly/opa"); // Alle fehlenden Infos dieses
+                                         Monsters werden in das File
+                                         monster unter /log/tilly/ ge-
+                                         logt.
+BEMERKUNGEN:
+     Bei nachtraeglich angeschlossenen Monstern empfiehlt sich Variante 
+     2 der Beispiele. Ein muehsames Suchen (und Loeschen) der fehlenden 
+     Infos des Monsters im Report-File eruebrigt sich dann naemlich.
+
+SIEHE AUCH:
+     P_LOG_FILE, write_file(), log_file(), AddInfo
+
+Letzte Aenderung: 13.09.04 Tilly@MorgenGrauen
diff --git a/doc/props/P_LONG b/doc/props/P_LONG
new file mode 100644
index 0000000..04a3659
--- /dev/null
+++ b/doc/props/P_LONG
@@ -0,0 +1,29 @@
+P_LONG
+NAME:
+     P_LONG					"long"
+
+DEFINIERT IN:
+     <thing/description.h>
+
+BESCHREIBUNG:
+     Die Langbeschreibung des Objektes als String oder Closure (diese muss
+     einen String zurueckgeben). Die Langbeschreibung wird beim Untersuchen
+     des Objektes ausgegeben. Sie sollte umgebrochen sein.
+
+     Diese Property bestimmt die Ansicht des Objektes von aussen. Fuer die
+     Innen(lang)ansicht von Raeumen muss man P_INT_LONG benutzen.
+
+BEMERKUNGEN:
+     - long() ("untersuche") filtert P_LONG durch process_string()
+       -> daher sind Closures moeglich
+
+BEISPIELE:
+
+     SetProp(P_LONG, "Diese Axt ist eine furchtbare Waffe!\n");
+
+SIEHE AUCH:
+     Aehnliches:	P_SHORT, long()
+     Sonstiges:		P_INT_LONG, process_string(), break_string()
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 20:10:18 1996 by Wargon
diff --git a/doc/props/P_LONG_EMPTY b/doc/props/P_LONG_EMPTY
new file mode 100644
index 0000000..1a9cce2
--- /dev/null
+++ b/doc/props/P_LONG_EMPTY
@@ -0,0 +1,8 @@
+NAME:
+    P_LONG_EMPTY                  "w_longdesc_empty"            
+
+DEFINIERT IN:
+    /sys/fishing.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_LONG_FULL b/doc/props/P_LONG_FULL
new file mode 100644
index 0000000..3b997f6
--- /dev/null
+++ b/doc/props/P_LONG_FULL
@@ -0,0 +1,8 @@
+NAME:
+    P_LONG_FULL                   "w_longdesc_full"             
+
+DEFINIERT IN:
+    /sys/fishing.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_MAGIC b/doc/props/P_MAGIC
new file mode 100644
index 0000000..b3a0bb7
--- /dev/null
+++ b/doc/props/P_MAGIC
@@ -0,0 +1,8 @@
+NAME:
+    P_MAGIC                       "magic"                       
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Dieses Objekt ist magisch.
diff --git a/doc/props/P_MAGIC_RESISTANCE_OFFSET b/doc/props/P_MAGIC_RESISTANCE_OFFSET
new file mode 100644
index 0000000..e6120a8
--- /dev/null
+++ b/doc/props/P_MAGIC_RESISTANCE_OFFSET
@@ -0,0 +1,33 @@
+NAME:
+     P_MAGIC_RESISTANCE_OFFSET                     "mag_res_offset"                     
+
+DEFINIERT IN:
+     /sys/new_skills.h
+
+BESCHREIBUNG:
+     Mapping mit ganzzahligen Prozentwerten in 0.01%-Schritten
+     (0-10000) zur Resistenz/Empfindlichkeit gegen bestimmte
+     Magieklassen.
+
+     Die Property wird in der Methode SpellDefend() ausgewertet und
+     fuer einen auf den NPC/Spieler gesprochenen Spell werden die
+     Werte fuer all dessen Magieklassen aufaddiert. Daher sind auch
+     negative Werte fuer einzelne Magieklassen sinnvoll.
+
+     P_MAGIC_RESISTANCE_OFFSET und SpellDefend werden von den Spellbooks
+     ausgewertet. Der Einfluss ist daher abhängig vom Spellbook.
+
+BEISPIELE:
+     // Goblins
+     SetProp(P_MAGIC_RESISTANCE_OFFSET,
+               ([MT_ANGRIFF:600,         // 6% Resistenz gegen Angriff
+	         MT_ILLUSION:500,        // 6% Resistenz gegen Illusionen
+                 MT_VERWANDLUNG:-300,    // 3% Empfindlichkeit
+		 MT_HELLSICHT:-750,      // 7.5% Empfindlichkeit
+		 MT_BEHERRSCHUNG:250])); // 2.5% Resistenz
+
+SIEHE AUCH:
+     Verwandt:     SpellDefend
+     Aehnlich:     P_NOMAGIC
+
+29.Dez 2007 Gloinson
diff --git a/doc/props/P_MAILADDR b/doc/props/P_MAILADDR
new file mode 100644
index 0000000..e1b849d
--- /dev/null
+++ b/doc/props/P_MAILADDR
@@ -0,0 +1,8 @@
+NAME:
+    P_MAILADDR                    "mailaddr"                    
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     EMailadresse des Spielers.
diff --git a/doc/props/P_MAP_RESTRICTIONS b/doc/props/P_MAP_RESTRICTIONS
new file mode 100644
index 0000000..fd422c0
--- /dev/null
+++ b/doc/props/P_MAP_RESTRICTIONS
@@ -0,0 +1,39 @@
+NAME:
+    P_MAP_RESTRICTIONS                      "lib_p_map_restrictions"
+
+DEFINIERT IN:
+    /sys/rooms.h
+
+BESCHREIBUNG:
+     Mit dieser Property laesst sich beeinflussen, welche Informationen ueber
+     den Raum das Morgengrauen dem Client zukommen laesst (zur Zeit nur via
+     GMCP, aber es mag irgendwann auch andere Wege geben).
+     Beispielsweise sollen vielleicht in einem Labyrinth keine eindeutigen
+     Raum-IDs uebermittelt werden.
+
+     Als Werte duerfen alle MR_-Konstanten aus <rooms.h> verwendet werden.
+     Diese duerfen auch ver-ODER-t werden, wenn mehr als eine davon gelten
+     soll.
+
+     Moegliche Werte:
+       MR_NOUID - verhindert, dass die eindeutige Raum-ID uebertragen wird.
+       MR_NOINFO - verhindert, dass ueberhaupt irgendetwas an den Client
+                   uebermittelt wird. Damit kriegt er ggf. auch nicht mit,
+                   dass er Raum gewechselt wurde. Ist fuer Sequenzraeume
+                   gedacht. Bitte SEHR sparsam einsetzen.
+
+     Die Verwendung dieser Property sollte der Ausnahmefall sein!
+
+BEISPIEL:
+     (in einem Raum)
+     SetProp(P_MAP_RESTRICTIONS, MR_NOUID);
+
+     Nun bekommt der Client zwar die Kurzbeschreibung des Raums, die Region
+     und die sichtbaren Ausgaenge, aber keine UID mehr uebermittelt.
+
+SIEHE AUCH:
+     gmcp
+
+----------------------------------------------------------------------------
+23.02.2013, Zesstra
+
diff --git a/doc/props/P_MARRIED b/doc/props/P_MARRIED
new file mode 100644
index 0000000..768404e
--- /dev/null
+++ b/doc/props/P_MARRIED
@@ -0,0 +1,12 @@
+NAME:
+    P_MARRIED                     "married"                     
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Enthaelt einen String mit der uid des Partners
+     (sofern vorhanden)
+
+SIEHE AUCH:
+     scheidung
diff --git a/doc/props/P_MATERIAL b/doc/props/P_MATERIAL
new file mode 100644
index 0000000..5be1bef
--- /dev/null
+++ b/doc/props/P_MATERIAL
@@ -0,0 +1,79 @@
+P_MATERIAL
+NAME:
+     P_MATERIAL					"material"
+
+DEFINIERT IN:
+     <thing/material.h>
+
+BESCHREIBUNG:
+     Mapping mit prozentualen Anteilen von Materialien, aus denen ein Objekt 
+     besteht.
+
+BEMERKUNGEN:
+     Bei SetProp kann man zu Vereinfachung auch ein einzelnes Material oder 
+     ein Array aus Materialien angeben. Die Anteile werden dann 
+     gleichmaessig verteilt.
+
+BEISPIELE:
+     // 100% Eis
+     SetProp(P_MATERIAL, MAT_ICE);
+     // QueryProp(P_MATERIAL) -> ([MAT_ICE:100])
+
+     // 50% Eis, 50% Misc-Holz
+     SetProp(P_MATERIAL, ({ MAT_ICE, MAT_MISC_WOOD }));
+     // QueryProp(P_MATERIAL) -> ([MAT_ICE:50, MAT_MISC_WOOD: 50])
+
+     // 60% Eis, 40% Misc-Holz
+     SetProp(P_MATERIAL, ([ MAT_ICE: 60, MAT_MISC_WOOD: 40 ]));
+
+     // 100% Papier
+     SetProp(P_MATERIAL, MAT_PAPER);
+     // QueryProp(P_MATERIAL) -> ([MAT_PAPER:100])
+
+     // 50% Silber, 50% Gold
+     SetProp(P_MATERIAL, ({MAT_SILVER, MAT_GOLD}))
+     // QueryProp(P_MATERIAL) -> ([MAT_SILVER:50,MAT_GOLD:50])
+
+     // ein weiser Schmied, der was daraus macht:
+     int i;
+     string *mat, mname, mgroup;
+     mat=m_indices(ob->QueryProp(P_MATERIAL));
+     i=sizeof(mat);
+
+     write("Der Schmied sagt: "+ob->Name(WER)+" besteht aus ...\n");
+     while(i--) {
+      // den Namen erkennen/aussprechen:
+      // Materialien werden allgemein ganz schlecht erkannt (zu 5%), aber
+      // alles aus Metall wird zu +100% gut erkannt ...
+      mname=MATERIALDB->MaterialName(mat[i], WER,
+	     ({5, ([MATERIAL_SYMMETRIC_RECOGNIZABILITY:
+			({MATGROUP_METAL, 100})])}));
+
+      // und nur Metalle analysieren ...
+      if(MATERIALDB->MaterialGroup(([mat[i]:100]),MATGROUP_METAL)>=100) {
+       int j;
+       string *mgr;
+       mgr=MATERIALDB->GetMatMembership(mat[i]);
+       j=sizeof(mgr);
+       mgroup=" gehoert zu ";
+       while(j--) {
+        mgroup+=MATERIALDB->GroupName(mgr[j]);
+        if(j>0) mgroup+=", ";
+       }
+      } else mgroup=" kenne ich nicht";
+      printf("%-12.12s: %s\n",mname, mgroup);
+     }
+
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: /sys/thing/material.h
+     Methoden:    QueryMaterial(), QueryMaterialGroup(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_MATERIAL_KNOWLEDGE b/doc/props/P_MATERIAL_KNOWLEDGE
new file mode 100644
index 0000000..c954083
--- /dev/null
+++ b/doc/props/P_MATERIAL_KNOWLEDGE
@@ -0,0 +1,39 @@
+P_MATERIAL_KNOWLEDGE
+NAME:
+     P_MATERIAL_KNOWLEDGE				"material_knowledge"
+
+DEFINIERT IN:
+     <thing/material.h>
+
+BESCHREIBUNG:
+     Mapping, Closure oder Integer mit Regeln zur Materialienerkennung. Die
+     Regeln sind in "man materialerkennung" zu lesen.
+
+     Diese werden bei Angabe eines Spielerobjektes in MaterialList() oder
+     MaterialName() an diesem abgefragt und hat Einfluss darauf, ob ein
+     Material genau, generell oder gar nicht erkannt wird.
+
+     In den einzelnen Rassenshells sind Defaultwerte dafuer angegeben.
+
+
+BEISPIELE:
+     // Erkennungsbonus auf diverse Materialgruppen und
+     // Erkennungsbonus/-malus auf biologische/nichtbiologische Materialien
+     SetProp(P_MATERIAL_KNOWLEDGE,
+	([MATGROUP_WOOD:20,
+	  MATGROUP_METAL:20,
+	  MATGROUP_ELEMENTAL:20,
+	  MATGROUP_CLOTH:20,
+	  MATERIAL_SYMMETRIC_RECOGNIZABILITY: ({MATGROUP_BIO,5})]));
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterial(), QueryMaterialGroup(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_MAX_ALCOHOL b/doc/props/P_MAX_ALCOHOL
new file mode 100644
index 0000000..10a64c3
--- /dev/null
+++ b/doc/props/P_MAX_ALCOHOL
@@ -0,0 +1,21 @@
+NAME:
+	P_MAX_ALCOHOL			"max_alcohol"
+
+DEFINIERT IN:
+	/sys/living/life.h
+
+BESCHREIBUNG:
+	Numerischer Wert fuer den maximalen Grad der Betrunkenheit eines
+	Lebewesens.
+
+ANMERKUNGEN:
+	Der Wert von P_MAX_ALCOHOL ist bei den einzelnen Rassen verschieden,
+	ebenso wie der fuer P_ALCOHOL_DELAY. Die genauen Werte stehen in den
+	Rassen-Shells (/std/shells).
+
+SIEHE AUCH:
+	P_ALCOHOL, P_ALCOHOL_DELAY, drink_alcohol,
+	P_MAX_FOOD, P_MAX_DRINK
+
+----------------------------------------------------------------------------
+Last modified: Tue Dec 18 12:16:10 2001 by Patryn
diff --git a/doc/props/P_MAX_DRINK b/doc/props/P_MAX_DRINK
new file mode 100644
index 0000000..940eddc
--- /dev/null
+++ b/doc/props/P_MAX_DRINK
@@ -0,0 +1,21 @@
+NAME:
+	P_MAX_DRINK			"max_drink"
+
+DEFINIERT IN:
+	/sys/living/life.h
+
+BESCHREIBUNG:
+	Numerischer Wert fuer die maximale Saettigung eines Lebewesens mit
+	Getraenken.
+
+ANMERKUNGEN:
+	Der Wert von P_MAX_DRINK ist bei den einzelnen Rassen verschieden,
+	ebenso wie der fuer P_DRINK_DELAY. Die genauen Werte stehen in den
+	Rassen-Shells (/std/shells).
+
+SIEHE AUCH:
+	P_DRINK, P_DRINK_DELAY, drink_soft,
+	P_MAX_FOOD, P_MAX_ALCOHOL
+
+----------------------------------------------------------------------------
+Last modified: Tue Dec 18 12:16:10 2001 by Patryn
diff --git a/doc/props/P_MAX_FOOD b/doc/props/P_MAX_FOOD
new file mode 100644
index 0000000..5f49cfe
--- /dev/null
+++ b/doc/props/P_MAX_FOOD
@@ -0,0 +1,20 @@
+NAME:
+	P_MAX_FOOD			"max_food"
+
+DEFINIERT IN:
+	/sys/living/life.h
+
+BESCHREIBUNG:
+	Numerischer Wert fuer die maximale Saettigung eines Lebewesens.
+
+ANMERKUNGEN:
+	Der Wert von P_MAX_FOOD ist bei den einzelnen Rassen verschieden, 
+	ebenso wie der fuer P_FOOD_DELAY. Die genauen Werte stehen in den
+	Rassen-Shells (/std/shells).
+
+SIEHE AUCH:
+	P_FOOD, P_FOOD_DELAY, eat_food,
+	P_MAX_DRINK, P_MAX_ALCOHOL
+
+----------------------------------------------------------------------------
+Last modified: Tue Dec 18 12:16:10 2001 by Patryn
diff --git a/doc/props/P_MAX_HANDS b/doc/props/P_MAX_HANDS
new file mode 100644
index 0000000..96b1ae8
--- /dev/null
+++ b/doc/props/P_MAX_HANDS
@@ -0,0 +1,27 @@
+P_MAX_HANDS
+NAME:
+     P_MAX_HANDS                   "max_hands"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+     Anzahl der Haende, die ein Wesen hat.
+
+BEMERKUNGEN:
+     An dieser Propertie sollte bei Spielern nur im Rahmen der
+     Gilden 'gespielt' werden.
+
+     Fuer Magier, die in ihren Npc gerne alle Properties setzen,
+     gilt folgendes:
+
+                  Setzt diese Propertie NIE auf 0 !
+
+     Ohne Haende wird kein Npc irgendeinen Spieler angreifen koennen.
+
+SIEHE AUCH:
+     P_HANDS, P_HANDS_USED_BY
+     P_USED_HANDS, P_FREE_HANDS
+     UseHands, FreeHands
+
+1.Feb.2004 Gloinson
diff --git a/doc/props/P_MAX_HP b/doc/props/P_MAX_HP
new file mode 100644
index 0000000..13a84c4
--- /dev/null
+++ b/doc/props/P_MAX_HP
@@ -0,0 +1,14 @@
+NAME:
+    P_MAX_HP                      "max_hp"
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Maximale Anzahl der Lebenspunkte.
+
+SIEHE AUCH:
+     Props:	P_HP
+     Verwandt:	UpdateAttributes()
+
+21.April 2006 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_MAX_OBJECTS b/doc/props/P_MAX_OBJECTS
new file mode 100644
index 0000000..a76f0d1
--- /dev/null
+++ b/doc/props/P_MAX_OBJECTS
@@ -0,0 +1,22 @@
+NAME:
+    P_MAX_OBJECTS                  "max_objects"                  
+
+DEFINIERT IN:
+    /sys/container.h
+
+BESCHREIBUNG:
+     Maximale Anzahl an Objekten, die in einen Container passen.
+     P_MAX_OBJECTS sollte im Normfall zwischen 0 - 100 liegen.
+
+BEMERKUNGEN:
+     Soll es sich um einen herausragenden Container handeln, der zum
+     Beispiel das Gewicht um mehr als 50% reduziert, sollte P_MAX_OBJECTS
+     einen kleineren Wert haben. Das Verhaeltnis von P_MAX_WEIGHT,
+     P_WEIGHT_PERCENT und dieser Property sollte stimmen.
+
+BEISPIELE:
+     Als Beispiel sollte man sich das Postpaket ansehen und sich an dessen
+     Werten orientieren (/p/service/loco/obj/parcel).
+
+SIEHE AUCH:
+     P_MAX_WEIGHT, P_WEIGHT_PERCENT, P_LIGHT_TRANSPARENCY, container
diff --git a/doc/props/P_MAX_PASSENGERS b/doc/props/P_MAX_PASSENGERS
new file mode 100644
index 0000000..b0bc6a5
--- /dev/null
+++ b/doc/props/P_MAX_PASSENGERS
@@ -0,0 +1,9 @@
+NAME:
+    P_MAX_PASSENGERS              "maxpass"                     
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+     Numerischer Wert fuer die maximale Anzahl von Wesen in dem Transporter.
+     0 bedeutet unbeschaenkte Spielerzahl.
diff --git a/doc/props/P_MAX_POISON b/doc/props/P_MAX_POISON
new file mode 100644
index 0000000..35b8e9b
--- /dev/null
+++ b/doc/props/P_MAX_POISON
@@ -0,0 +1,8 @@
+NAME:
+    P_MAX_POISON                  "max_poison"                  
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Maximale Vergiftung
diff --git a/doc/props/P_MAX_SP b/doc/props/P_MAX_SP
new file mode 100644
index 0000000..307aaf5
--- /dev/null
+++ b/doc/props/P_MAX_SP
@@ -0,0 +1,14 @@
+NAME:
+    P_MAX_SP                      "max_sp"
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Maximale Anzahl der Magiepunkte.
+
+SIEHE AUCH:
+     Props:	P_SP
+     Verwandt:	UpdateAttributes()
+
+21.April 2006 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_MAX_WEIGHT b/doc/props/P_MAX_WEIGHT
new file mode 100644
index 0000000..7e2f16b
--- /dev/null
+++ b/doc/props/P_MAX_WEIGHT
@@ -0,0 +1,19 @@
+NAME:
+    P_MAX_WEIGHT                  "max_weight"                  
+
+DEFINIERT IN:
+    /sys/container.h
+
+BESCHREIBUNG:
+     Maximales Gewicht in Gramm, das in dem Container verstaut werden
+     kann.
+
+BEMERKUNGEN:
+     Das Verhaeltnis von P_WEIGHT_PERCENT, P_MAX_OBJECTS und dieser Property
+     sollte stimmen. Eine feste Grenze gibt es nicht. Als Beispiel kann 
+     das Postpaket von Loco unter /p/servive/loco/obj herangezogen werden.
+     Bessere Werte als in diesem sollte es nicht, und wenn doch nur gut be-
+     gruendet, geben.
+
+SIEHE AUCH:
+     P_WEIGHT_PERCENT, P_MAX_OBJECTS, P_LIGHT_TRANSPARENCY, container
diff --git a/doc/props/P_MESSAGE_BEEP b/doc/props/P_MESSAGE_BEEP
new file mode 100644
index 0000000..9e40fa5
--- /dev/null
+++ b/doc/props/P_MESSAGE_BEEP
@@ -0,0 +1,19 @@
+NAME:
+    P_MESSAGE_BEEP                        "message_beep"
+
+DEFINIERT IN:
+    /sys/player/comm.h
+
+BESCHREIBUNG:
+     Wertebereich: int=0..3600 (Sekunden)
+     Wenn gesetzt wird in der Kommunikation des Spielers in den angegebenen
+     Zeitraeumen ein Signalton ausgegeben. Wird in player/comm.c in comm_beep()
+     verarbeitet.
+     Ausgabe erfolgt nur, wenn P_VISUALBELL nicht gesetzt ist.
+     Wird im Spielerobjekt gespeichert!
+
+SIEHE AUCH:
+     klingelton, ton, P_VISUALBELL, P_MESSAGE_LAST_BEEP
+
+LETZTE AENDERUNG:
+   16. Mai 2007  Ennox
diff --git a/doc/props/P_MESSAGE_PREPEND b/doc/props/P_MESSAGE_PREPEND
new file mode 100644
index 0000000..ee44dda
--- /dev/null
+++ b/doc/props/P_MESSAGE_PREPEND
@@ -0,0 +1,18 @@
+NAME:
+    P_MESSAGE_PREPEND                        "message_prepend"
+
+DEFINIERT IN:
+    /sys/player/comm.h
+
+BESCHREIBUNG:
+     Wertebereich: int = 0,1
+     Wenn vom Ziel eingeschaltet, wird von teile mit (_tell) und sag (_communicate) das 
+     BS_PREPEND_INDENT Flag fuer break_string genutzt, um den Indent (Sender) ggf.
+     vor dem Textblock anzuzeigen.
+     Wird im Spielerobjekt gespeichert!
+
+SIEHE AUCH:
+     grafik aus, break_string, senderwiederholung
+
+LETZTE AENDERUNG:
+   16. Mai 2007  Ennox
diff --git a/doc/props/P_MIN_STOCK b/doc/props/P_MIN_STOCK
new file mode 100644
index 0000000..d896fb3
--- /dev/null
+++ b/doc/props/P_MIN_STOCK
@@ -0,0 +1,37 @@
+NAME:
+	P_MIN_STOCK			"min_stock"
+
+DEFINIERT IN:
+	/sys/bank.h
+
+BESCHREIBUNG:
+	P_MIN_STOCK enthaelt die Anzahl an Objekten, die ein Lager eines
+	Ladens minimal behaelt. Standardmaessig entspricht dies 20 Objekten
+	und sollte auch nicht wesentlich erhoeht werden. Nur fuer
+	Anfaengergebiete waeren Werte zwischen 20 und 60 akzeptabel. In die
+	Berechnung der Anzahl von Objekten gehen keine Objekte ein, die im
+	Laden mittels AddFixedObject() staendig verfuegbar gemacht worden
+	sind und auch keine Objekte, die per AddItem() im Lager hinzugefuegt
+	wurden und nach jedem Reset aufgefrischt werden.
+	Bei jedem Reset wird nun aus Speicher- und Laggruenden das Lager um
+	eine bestimmte Prozentzahl an Objekten dezimiert. Entscheidend
+	dafuer ist der Wert in der Property P_STORE_CONSUME.
+	Beide hier erwaehnten Properties sollten ueberigens nur mittels
+	QueryProp/SetProp ausgelesen bzw. veraendert werden.
+
+BEISPIEL:
+	In '/std/store.c' befindet sich bereits ein gutes Beispiel, da dort
+	der Standardwert von 20 Objekten bereitgestellt wird:
+	  create()
+	  { ...
+	    SetProp(P_MIN_STOCK,20);
+	  }
+	Diesen Wert kann man in einem davon abgeleiteten eigenen Lager
+	natuerlich auch veraendern.
+
+SIEHE AUCH:
+	P_STORE_CONSUME, SetStorageRoom(), /std/store.c, /std/shop.c
+	AddItem(), RemoveItem(), AddFixedObject(), RemoveFixedObject()
+
+----------------------------------------------------------------------------
+Last modified: 19-Jun-2015, Arathorn 
diff --git a/doc/props/P_MMSGIN b/doc/props/P_MMSGIN
new file mode 100644
index 0000000..cd8e84e
--- /dev/null
+++ b/doc/props/P_MMSGIN
@@ -0,0 +1,9 @@
+NAME:
+    P_MMSGIN                      "mmsgin"                      
+
+DEFINIERT IN:
+    /sys/player/moving.h
+
+BESCHREIBUNG:
+     String mit der Meldung, die beim Verlassen eines Raumes mit M_TPORT
+     an die uebrigen Anwesenden ausgegeben wird.
diff --git a/doc/props/P_MMSGOUT b/doc/props/P_MMSGOUT
new file mode 100644
index 0000000..defd09f
--- /dev/null
+++ b/doc/props/P_MMSGOUT
@@ -0,0 +1,9 @@
+NAME:
+    P_MMSGOUT                     "mmsgout"                     
+
+DEFINIERT IN:
+    /sys/player/moving.h
+
+BESCHREIBUNG:
+     String mit der Meldung, die beim Betreten eines Raumes mit M_TPORT
+     an die uebrigen Anwesenden ausgegeben wird.
diff --git a/doc/props/P_MSGIN b/doc/props/P_MSGIN
new file mode 100644
index 0000000..cf14a91
--- /dev/null
+++ b/doc/props/P_MSGIN
@@ -0,0 +1,9 @@
+NAME:
+    P_MSGIN                       "msgin"                       
+
+DEFINIERT IN:
+    /sys/player/moving.h
+
+BESCHREIBUNG:
+     String mit der Meldung, die beim Betreten eines Raumes mit M_GO
+     an die uebrigen Anwesenden ausgegeben wird.
diff --git a/doc/props/P_MSGOUT b/doc/props/P_MSGOUT
new file mode 100644
index 0000000..0587afb
--- /dev/null
+++ b/doc/props/P_MSGOUT
@@ -0,0 +1,9 @@
+NAME:
+    P_MSGOUT                      "msgout"                      
+
+DEFINIERT IN:
+    /sys/player/moving.h
+
+BESCHREIBUNG:
+     String mit der Meldung, die beim Verlassen eines Raumes mit M_GO
+     an die uebrigen Anwesenden ausgegeben wird.
diff --git a/doc/props/P_MSG_PROB b/doc/props/P_MSG_PROB
new file mode 100644
index 0000000..d520067
--- /dev/null
+++ b/doc/props/P_MSG_PROB
@@ -0,0 +1,19 @@
+NAME:
+    P_MSG_PROB                    "msg_prob"                    
+
+DEFINIERT IN:
+    /sys/room/description.h
+
+BESCHREIBUNG:
+     Parameter fuer die Wartezeit in Sekunden bis zur naechsten Ausgabe
+     einer Raumnachricht.
+     Wird in AddRoomMessage() explizit mitgesetzt. Koennte natuerlich von
+     einer Nachrichtenmethode auch regelmaessig geaendert werden, um
+     mehr Zufall in die Intervalle zu bringen.
+
+SIEHE AUCH:
+     LFuns:    AddRoomMessage()
+     Props:    P_ROOM_MSG, P_MSG_PROB
+     Verwandt: call_out()
+
+2.Feb 2016 Gloinson
diff --git a/doc/props/P_MUD_NEWBIE b/doc/props/P_MUD_NEWBIE
new file mode 100644
index 0000000..bebb77f
--- /dev/null
+++ b/doc/props/P_MUD_NEWBIE
@@ -0,0 +1,17 @@
+NAME:
+    P_MUD_NEWBIE                      "_lib_mud_newbie" 
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+    Der Spieler hat bei Erstellung des Charakters angegeben, noch nie in einem
+    Mud gespielt zu haben. In diesem Fall enthaelt die Property den
+    Zeitstempel der Charaktererstellung.
+
+    ACHTUNG: Diese Prop wird nicht gespeichert, d.h. nachdem ein solcher
+    Spieler "ende" gemacht hat oder ein Reboot erfolgte, ist diese Information
+    verloren.
+
+SIEHE AUCH:
+
diff --git a/doc/props/P_MURDER_MSG b/doc/props/P_MURDER_MSG
new file mode 100644
index 0000000..85bbf81
--- /dev/null
+++ b/doc/props/P_MURDER_MSG
@@ -0,0 +1,63 @@
+P_MURDER_MSG
+
+NAME:
+     P_MURDER_MSG			"murder_msg"
+
+DEFINIERT IN:
+     /sys/properties.h
+
+BESCHREIBUNG:
+     In dieser Property kann man einen String oder eine Closure ablegen
+     dessen Wert bzw. deren Resultat beim Tod des NPCs auf dem
+     Moerder-Kanal erscheint.
+     Normalerweise ist die Property nicht gesetzt, woraufhin zufaellig
+     eine Meldung generiert wird.
+
+     Ob der Tod eines NPCs auf dem Moerder-Kanal erscheint, haengt davon ab,
+     wie oft und welche Art von NPCs in der letzten Zeit getoetet wurden. Zum
+     Beispiel ist es eher selten, dass ein schwacher NPC auf dem Kanal
+     erscheint, wenn kuerzlich viele starke NPCs getoetet wurden. Allerdings
+     kann man auf diese Regelung mittels der Property P_FORCE_MURDER_MSG
+     Einfluss nehmen.
+
+     Wird in einen String der Platzhalter %s eingefuegt, so erscheint an der
+     Stelle spaeter der Name des Moerders.
+
+BEISPIELE:
+     // Zum Beispiel koennte man ja bei einer Ratte, die getoetet wird,
+     // folgendes auf dem Moerder-Kanal ausgeben lassen:
+     SetProp(P_MURDER_MSG,
+       "Ratten aller MUDs, vereinigt euch gegen %s!");
+
+
+     // Um auch mal eine Closure zu zeigen: die Ratte könnte auch ihre
+     // Meldung erst bei ihrem Tod erstellen lassen:
+     private string moerder_meldung() {
+       return ({"Achweh!", "Au!", "Weia!"})[random(3)];
+     }
+
+     SetProp(P_MURDER_MSG, #'moerder_meldung);
+
+BEMERKUNGEN:
+     - P_NOCORPSE:
+       Ist in dem Npc die Property P_NOCORPSE gesetzt, so wird die
+       Moerdermeldung nicht auf dem Kanal gesendet, da diese Ausgabe ueber
+       /std/corpse laeuft.
+       Will man dennoch eine Meldung, so sollte man /std/corpse im die()
+       selbst clonen, daran Identify(this_object()) rufen und das geclonte
+       Objekt wieder entsorgen.
+
+     - Closures:
+       Closures bieten sich an, wenn ein zentrales Objekt für mehrere NPCs
+       bestimmte Moerdermeldungen generieren soll. Dann muss nur noch bei
+       den NPCs die Closure, die auf die erstellende Methode zeigt gesetzt
+       werden.
+
+SIEHE AUCH:
+     Tod:		die(L)
+     Verwandt:		P_FORCE_MURDER_MSG
+     Todesmeldungen:	P_KILL_NAME, P_KILL_MSG, P_DIE_MSG
+			P_ZAP_MSG, P_ENEMY_DEATH_SEQUENCE
+     Sonstiges:		P_CORPSE, P_NOCORPSE, /std/corpse.c
+
+30. Mai 2006, Gloinson
\ No newline at end of file
diff --git a/doc/props/P_M_ATTR_MOD b/doc/props/P_M_ATTR_MOD
new file mode 100644
index 0000000..8a79717
--- /dev/null
+++ b/doc/props/P_M_ATTR_MOD
@@ -0,0 +1,42 @@
+NAME:
+    P_M_ATTR_MOD                  "magic_attributes_modifier"
+
+DEFINIERT IN:
+    /sys/living/attributes.h
+
+BESCHREIBUNG:
+    Mapping, das die Attribute des Spielers veraendert, der diese Ruestung
+    bzw. Waffe traegt bzw. benutzt.
+
+    Zu beachten:
+    P_M_ATTR_MOD kann problemlos durch ein SetProp() gesetzt werden. Es wird
+    nur dann beruecksichtigt, wenn die Ruestung/Waffe getragen/benutzt wird.
+    Beim Tragen/Ausziehen/Zuecken/Wegstecken wird im Spieler automatisch
+    UpdateAttributes() aufgerufen.
+
+    Fuer Krankheiten etc. oder Objekte, deren *Besitz* allein schon die
+    Attribute veraendern sollen, verwendet man besser P_X_ATTR_MOD.
+
+    P_X_ATTR_MOD und P_M_ATTR_MOD duerfen einen gemeinsamen kumulierten
+    positiven Grenzwert nicht ueberschreiten. Dieser Grenzwert,
+    CUMULATIVE_ATTR_LIMIT, ist in /sys/living/attributes.h definiert.
+
+BEMERKUNGEN:
+    Die Werte sollten moeglichst nicht dynamisch geaendert werden.
+    Wenn doch, muss mit TestLimitViolation() am Spieler auf Validitaet
+    geprueft und ggf. mit UpdateAttributes() an ihm upgedatet werden.
+
+BEISPIELE:
+    // Dem Spieler, der das Objekt benutzt, wird 2 von A_INT abgezogen und
+    // dafuer 1 auf A_STR aufaddiert.
+    SetProp(P_M_ATTR_MOD, ([A_INT:-2, A_STR:1]) );
+
+SIEHE AUCH:
+    QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),
+    SetAttribute(), SetRealAttribute(), UpdateAttributes(),
+    SetTimedAttrModifier(), QueryTimedAttrModifier(),
+    DeleteTimedAttrModifier(),
+    P_X_HEALTH_MOD, P_M_HEALTH_MOD, P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS,
+    P_TIMED_ATTR_MOD, P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c
+
+02.02.2016, Gloinson
diff --git a/doc/props/P_M_HEALTH_MOD b/doc/props/P_M_HEALTH_MOD
new file mode 100644
index 0000000..a4c89e6
--- /dev/null
+++ b/doc/props/P_M_HEALTH_MOD
@@ -0,0 +1,40 @@
+NAME:
+     P_M_HEALTH_MOD                  "magic_health_modifier"
+
+DEFINIERT IN:
+     /sys/living/attributes.h
+
+BESCHREIBUNG:
+     Mapping, mit dem die maximalen Lebenspunkte und Magiepunkte eines 
+     Spielers veraendert werden, der diese Ruestung/Waffe traegt/benutzt. Im 
+     Gegensatz zu P_M_ATTR_MOD erfolgt hier jedoch keine Blockade.
+
+     Zu beachten: P_M_HEALTH_MOD kann problemlos durch ein SetProp() gesetzt 
+     werden, es wird nur beruecksichtigt, wenn die Ruestung/Waffe 
+     getragen/benutzt wird. Beim tragen/ausziehen/zuecken/wegstecken wird im 
+     Spieler automatisch UpdateAttributes() aufgerufen.
+
+     Fuer Krankheiten etc. verwendet man besser die Property P_X_HEALTH_MOD.
+
+     Bitte beachten: Die positiven Modifier werden nicht mehr 1:1 auf die
+     Lebens- und Magiepunkte draufaddiert. Stattdessen wird nur noch ein 
+     gewisser Teil dort hinzuaddiert, der mit groesserer Menge von Punkten
+     zunimmt, und im unteren Bereich grob dem Wert entspricht. Das 
+     theoretische Maximum ist insgesamt 149.
+
+BEMERKUNGEN:
+     Die Werte sollten moeglichst nicht dynamisch geaendert werden.
+     Wenn doch, muss mit TestLimitViolation() am Spieler auf Validitaet 
+     geprueft werden und mit UpdateAttributes() an ihm ggf. upgedatet.
+
+BEISPIEL:
+     SetProp(P_M_HEALTH_MOD,([P_HP:5,P_SP:-5]));
+     // Dem Spieler, der das Objekt benutzt, wird P_MAX_HP um 5 erhoeht und
+     // P_MAX_SP um 5 erniedrigt.
+
+SIEHE AUCH:
+     P_X_HEALTH_MOD, P_X_ATTR_MOD, P_M_ATTR_MOD, balance
+
+LETZTE AeNDERUNG:
+    Fre,11.05.2007, 00:20 von Humni
+
diff --git a/doc/props/P_NAME b/doc/props/P_NAME
new file mode 100644
index 0000000..f609cea
--- /dev/null
+++ b/doc/props/P_NAME
@@ -0,0 +1,65 @@
+P_NAME
+
+NAME:
+     P_NAME "name"
+
+DEFINIERT IN:
+     <thing/description.h>
+
+BESCHREIBUNG:
+     In dieser Property wird der Name eines Objektes vermerkt. Wenn der Name
+     regelmaessig dekliniert wird, reicht ein einfacher String. Wird der
+     Name unregelmaessig dekliniert, so kann man ein Array von vier Strings
+     mit dem Namen im Nominativ, Genitiv, Dativ und Akkusativ (in dieser
+     Reihenfolge) angeben.
+
+     Die Funktion name() behandelt recht viele Sonderfaelle; man sollte den
+     Namen also erst einmal in der Form eines einzelnen Strings pruefen.
+
+     Eine Sonderrolle nehmen Unit-Objekte ein: Hier kann man einen Namen
+     fuer den Singular und einen Namen fuer den Plural vergeben.
+
+     Setzt man P_NAME eines Unit-Objekts auf einen einfachen String, so wird
+     dieser als Name sowohl im Singular als auch im Plural verwendet.
+
+     Uebergibt man ein Array von Strings, so wird der erste Eintrag fuer den
+     Singular und der zweite Eintrag fuer den Plural benutzt.
+
+     Bei Unit-Objekten ist es nicht moeglich, auch noch zwischen den
+     verschiedenen Faellen zu unterscheiden.
+
+BEMERKUNGEN:
+     Diese Property sollte nur den reinen Namen enthalten; will man dem
+     Namen noch Adjektive voranstellen, so sollte man dies mit P_NAME_ADJ
+     bewerkstelligen, also statt
+
+     SetProp(P_NAME, ({ "alter Hut", "alten Huts",
+                        "alten Hut", "alten Hut" }) );
+
+     besser
+
+     SetProp(P_NAME, "Hut");
+     SetProp(P_NAME_ADJ, "alt");
+
+     Bei Lebewesen wird lower_case(P_NAME) (bei Arrays das erste Element 
+     daraus) automatisch als LivingName gesetzt.
+
+BEISPIELE:
+     Ein regelmaessig deklinierbarer Name:
+
+     SetProp(P_NAME, "Arkshat");
+
+     Hier ein Beispiel fuer einen unregelmaessig deklinierbaren Namen:
+
+     SetProp(P_NAME, ({ "Drache", "Drachen", "Drachen", "Drachen" }));
+
+     Und schliesslich der Name eines allseits bekannten Unit-Objektes:
+
+     SetProp(P_NAME, ({ "Muenze", "Muenzen" }));
+
+SIEHE AUCH:
+     /std/thing/description.c, name(), P_NAME_ADJ, set_living_name(),
+     find_living(), find_livings()
+
+----------------------------------------------------------------------------
+Last modified: 19. Okt. 2015, Arathorn. 
diff --git a/doc/props/P_NAME_ADJ b/doc/props/P_NAME_ADJ
new file mode 100644
index 0000000..2bf15e6
--- /dev/null
+++ b/doc/props/P_NAME_ADJ
@@ -0,0 +1,55 @@
+P_NAME_ADJ
+
+NAME:
+     P_NAME_ADJ "name_adj"
+
+DEFINIERT IN:
+     <thing/description.h>
+
+BESCHREIBUNG:
+     Diese Property enthaelt ein oder mehrere Adjektive in Form eines Arrays
+     von Strings. Es ist nur der Wortstamm anzugeben! Die Adjektive werden
+     von der Funktion name() dekliniert und vor den Namen gesetzt, wirken
+     also als Aufzaehlung von Adjektiven vor dem Namen.
+
+     Die hier angegebenen Adjektive dienen nur zur Ausgabe! Soll sich das
+     Objekt auch ueber Adjektive ansprechen lassen, muss man diese mit
+     AddAdjective() uebergeben.
+
+     Soll das Objekt nur ein einzelnes Namensadjektiv besitzen, kann man dem
+     SetProp()-Aufruf auch einen String uebergeben; gespeichert wird die
+     Property aber in jedem Fall als Array.
+
+     Wenn ein Adjektiv unregelmaessig ist, kann man die vier Faelle auch
+     als Array uebergeben. Man muss dann aber Arrays schachteln, damit von den
+     mehrfachen Adjektiven unterschieden werden kann.
+	
+BEISPIELE:
+     SetProp(P_NAME, "Hut");
+     SetProp(P_NAME_ADJ, "alt");
+
+     name(WESSEN,1)      => "des alten Huts"
+
+
+     // Zwei Adjektive, gleichrangig zu Substantiv
+     SetProp(P_NAME_ADJ, ({"alt", "gammelig"}));
+
+     name(WESSEN,1)      => "des alten, gammeligen Huts"
+
+
+     // Zwei Adjektive, erstes ist Attribut zu zweitem
+     falsch:  SetProp(P_NAME_ADJ, ({"gruen", "gestreift"}));
+              name(WESSEN,1)      => "des gruenen, gestreiften Huts"
+     richtig: SetProp(P_NAME_ADJ, ({"gruen gestreift"}));
+              name(WESSEN,1)      => "des gruen gestreiften Huts"
+
+     // Unregelmaessiges Adjektiv
+     SetProp( P_NAME_ADJ,({({"rosa","rosa","rosa","rosa"})});
+              name(WESSEN,1)         => "des rosa Huts"
+     // Ohne inneres Array haette man 4 mal rosa als Adjektiv
+     // => "des rosaen, rosaen, rosaen, rosaen Huts"
+
+SIEHE AUCH:
+     /std/thing/description.c, name(), P_NAME, DeclAdj()
+
+23.April 2007 Rumata
diff --git a/doc/props/P_NEEDED_QP b/doc/props/P_NEEDED_QP
new file mode 100644
index 0000000..e38f9eb
--- /dev/null
+++ b/doc/props/P_NEEDED_QP
@@ -0,0 +1,15 @@
+NAME:
+    P_NEEDED_QP                   "needed_qp"                   
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     APs, die man fuer den Seherstatus braucht
+
+     Diese Property ist mittlerweile obsolet. Die
+     aktuell geltenden Seher-Anforderungen stehen in
+     /secure/lepmaster.h
+
+LETZTE AENDERUNG:
+     2006-09-30, Zook.
\ No newline at end of file
diff --git a/doc/props/P_NETDEAD_ENV b/doc/props/P_NETDEAD_ENV
new file mode 100644
index 0000000..b2d6317
--- /dev/null
+++ b/doc/props/P_NETDEAD_ENV
@@ -0,0 +1,24 @@
+NAME:
+    P_NETDEAD_ENV                  "netdead_env"
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+    Diese Property kann in netztoten Spielern abgefragt werden,
+		um herauszufinden, in welchem Raum sie netztot geworden sind.
+
+		Es wird der selbe Wert zurueckgegeben, den die Mudlib benutzen
+		wuerde, um die Spieler beim reconnect wieder an den richtigen
+		ort zu bringen. Das ist normalerweise das Raumobjekt oder der
+		Dateiname des Raums (zum Beispiel so dieser ein clone war).
+
+		Bei nicht netztoten Spielern wird 0 zurueckgegeben.
+
+BEMERKUNGEN:
+    Diese Property ist read-only.
+
+SIEHE AUCH:
+    P_NETDEAD_INFO
+
+2009-08-04 Rumata
diff --git a/doc/props/P_NETDEAD_INFO b/doc/props/P_NETDEAD_INFO
new file mode 100644
index 0000000..83c36fd
--- /dev/null
+++ b/doc/props/P_NETDEAD_INFO
@@ -0,0 +1,91 @@
+NAME:
+    P_NETDEAD_INFO                "netdead_info"                
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Wird im Raum X gesetzt und wirkt nur, falls dieser Raum ein '#' im
+     object_name() hat (normale Clones, zB "/room/void#10153018").
+     
+     Bei Einschlafen eines Spielers in diesem Raum werden die Werte aus
+     der Property im Spieler gespeichert (Netztoteninformationen).
+
+     Ist beim Aufwachen des Spielers das Raumobjekt X zerstoert worden, dann
+     wird bei der Blueprint von X per SetProp() die gespeicherte Information
+     gesetzt. Der Rueckgabewert des SetProp wird als Pfad zu einem Ausweich-
+     Aufwach-Raum interpretiert und der Spieler wird in dem Fall dorthin
+     bewegt.
+
+BEMERKUNGEN:
+     Zum Clonen von Raeumen sollten Virtual Compiler benutzt werden:
+     Wird in den erzeugten Objektnamen KEIN '#' verwendet, dann ist diese
+     Property nicht sinnvoll und wird nicht verwendet. Ein ordentlicher
+     VC kann Bewegen eines Spielers in dessen alten, nicht mehr existierenden
+     Raum oder einen Ersatzraum beim Aufwachen selbst loesen.
+
+BEISPIELE:
+     // #1: geclonter Raum mit Ausweich-Aufwachraum: Klerus-Gilde
+     #include <properties.h>
+     inherit "/std/room";
+     
+     void create() {
+       ::create();
+
+       SetProp(P_NETDEAD_INFO, "/gilden/klerus");
+       SetProp(P_LIGHT, 1);
+     }
+     
+     // #2: komplexerer Beispielraum fuer P_NETDEAD_INFO-Funktionalitaet
+     // Siehe auch: /doc/beispiele/testobjekte/netdead_info_testraum.c
+     #include <properties.h>
+     inherit "/std/room";
+
+     void create() {
+       ::create();
+
+       if (clonep(this_object()))
+         // setze Informationen, die im Netztoten gespeichert werden sollen
+         Set(P_NETDEAD_INFO, random(5));
+       else
+         // Blueprint: hier kann man zu einem Cloneraum gehen
+         AddExit("cloneraum", #'create_room);
+
+       // Set-Method, um die Informationen aus P_NETDEAD_INFO beim Aufwachen
+       // in der Blueprint auswerten zu koennen
+       Set(P_NETDEAD_INFO, #'create_destiny, F_SET_METHOD);
+       SetProp(P_LIGHT, 1);
+     }
+     
+     // Raum entfernen, normalerweise so KEINE GUTE IDEE!
+     void BecomesNetDead(object pl) {
+       call_out(#'remove, 30);
+     }
+
+     // erzeuge einen Cloneraum und bewege den Spieler dahin
+     int create_room(string dir) {
+       object dest = clone_object(object_name(this_object()));
+       this_player()->move(dest, M_NOCHECK);
+       return 1;
+     }
+     
+     // Set-Method fuer P_NETDEAD_INFO: gibt Pfad zurueck
+     // benutze die Informationen aus dem jetzt aufwachenden Netztoten, um
+     // einen alternativen Aufwachraum zu ermitteln, da der Einschlafraum
+     // zerstoert ist
+     string create_destiny(mixed val) {
+       if (intp(val)) {
+         switch (val) {
+           case 0:
+             return "/d/ebene/room/PortVain/po_haf1";
+           case 1:
+             return "/gilden/klerus";
+           case 2:
+             return "/gilden/karate";
+           default:
+         }
+         return "/d/ebene/room/waldweg4";
+       }
+     }
+
+2. Jan 2012 Gloinson
diff --git a/doc/props/P_NEVERDROP b/doc/props/P_NEVERDROP
new file mode 100644
index 0000000..80364ce
--- /dev/null
+++ b/doc/props/P_NEVERDROP
@@ -0,0 +1,29 @@
+NAME:
+	P_NEVERDROP			"neverdrop"
+
+DEFINIERT IN:
+	/sys/thing/moving.h
+
+BESCHREIBUNG:
+	Objekte, welche diese Property gesetzt haben, werden beim Tod eines
+	Lebewesens nicht automatisch in die Leiche oder in den umgebenden
+	Raum (z.B. bei bei gesetztem P_NOCORPSE) transportiert.
+
+BEMERKUNGEN:
+	Soll das Objekt vom Lebewesen nicht weggelegt werden koennen, so ist
+	die Property P_NODROP zu verwenden.
+	Beide Properties zusammen stellen sicher, dass ein Objekt nicht
+	weitergegeben werden kann.
+
+BEISPIELE:
+	Eine dauerhafte Belohnung, die auch beim Tod des Spielers bei ihm
+	verbleiben soll, setzt das so:
+	  SetProp(P_NEVERDROP,1);
+	Sollen auch Reboots ueberstanden werden, ist zusaetzlich
+	P_AUTOLOADOBJ zu setzen.
+
+SIEHE AUCH:
+	P_NODROP, P_NOGET, P_NOCORPSE, P_AUTOLOADOBJ, /std/living/life.c
+
+----------------------------------------------------------------------------
+Last modified: Thu Jun 14 22:26:29 2001 by Patryn
diff --git a/doc/props/P_NEVER_CLEAN b/doc/props/P_NEVER_CLEAN
new file mode 100644
index 0000000..5a84820
--- /dev/null
+++ b/doc/props/P_NEVER_CLEAN
@@ -0,0 +1,35 @@
+NAME:
+	P_NEVER_CLEAN			" never clean "                   
+
+DEFINIERT IN:
+	/sys/rooms.h
+
+BESCHREIBUNG:
+	Normalerweise wird ein Raum nach 2 Resets zerstoert, wenn er waerend
+	dieser Zeit von keinem Lebewesen betreten wurde und wenn
+	keine REFRESH_NONE- oder REFRESH_DESTRUCT-Objekte existieren, die
+	nicht mehr im Raum vorhanden sind.
+	Mit dieser Property kann man den sogenannten Clean-Up unterbinden.
+
+BEISPIEL:
+	Der folgende Raum wird nicht mehr zerstoert, wenn er einmal geladen
+	wurde:
+	  #include <properties.h>
+	  // #include <rooms.h> ... wird schon von properties.h included!
+	  inherit "std/room";
+	  void create()
+	  { ::create();
+	    SetProp(P_SHORT,"Ein toller Raum");
+	    ...
+	    SetProp(P_NEVER_CLEAN,1);
+	    ...
+	  }
+	Man sollte die Anwendung nicht uebertreiben! Wichtig ist diese
+	Funktion zum Beispiel fuer Raeume, die gleichzeitig Masterobjekte
+	darstellen.
+
+SIEHE AUCH:
+	/std/room.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Feb  3 00:54:32 1999 by Patryn
diff --git a/doc/props/P_NEWSKILLS b/doc/props/P_NEWSKILLS
new file mode 100644
index 0000000..66ba1ff
--- /dev/null
+++ b/doc/props/P_NEWSKILLS
@@ -0,0 +1,20 @@
+NAME:
+	P_NEWSKILLS			"newskills"                   
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	In dieser Property sind saemtliche Skills und Spells vermerkt, die
+	das Lebewesen kennt.
+
+BEMERKUNGEN:
+	Man sollte diese Property nicht per Hand veraendern, sondern die
+	Funktionen von "/std/living/skills.c" nutzen.
+
+SIEHE AUCH:
+	ModifySkill(), LearnSkill(), UseSkill(), /std/living/skills.c,
+	P_GUILD_SKILLS, P_SB_SPELLS
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_NEXT_DEATH_SEQUENCE b/doc/props/P_NEXT_DEATH_SEQUENCE
new file mode 100644
index 0000000..4ae7e7a
--- /dev/null
+++ b/doc/props/P_NEXT_DEATH_SEQUENCE
@@ -0,0 +1,48 @@
+P_NEXT_DEATH_SEQUENCE
+
+NAME:
+     P_NEXT_DEATH_SEQUENCE         "p_lib_next_death_sequence"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+     Im Spieler kann damit dessen eigene Todessequenz fuer den naechsten
+     Tod festgelegt werden. Nach einem Tod (egal welche Todessequenz
+     gewaehlt wurde) wird die Property geloescht und muesste neu gesetzt
+     werden.
+
+     Es gibt folgende gueltige Werte:
+     - string: Pfad zu einer eigenen Todessequenz im gueltigen Format
+     - mixed*  Eine Todessequenz im Format des Todesraumes:
+               ({<int gesamtlaenge>,
+                 ([<int index1>: <string umgebrochene Meldung1>,
+                   <int index2>: <string umgebrochene Meldung2>,
+                   ...])
+               })
+     - mapping In die Standard-Lars-Todessequenz einzufuegende Zeilen:
+               ([<int zeitindex>: <string umgebrochener Text>])
+
+BEMERKUNGEN:
+     Eine Todessequenz eines Gegners, festgelegt ueber
+     P_ENEMY_DEATH_SEQUENCE hat Vorrang vor dieser Property.
+
+BEISPIELE:
+     // Pfad zu einer eigenen DSQ
+     SetProp(P_NEXT_DEATH_SEQUENCE,  ".../passende_dsq.txt");
+
+     // eigene DSQ im Todesraumformat:
+     SetProp(P_NEXT_DEATH_SEQUENCE,
+             ({ 2, ([1: "Der Tod entlaesst dich eilig.\n"])}));
+
+     // Einfuegen einer Meldung in die Standard-Todessequenz
+     SetProp(P_NEXT_DEATH_SEQUENCE,
+             ([5: "Du fuehlst dich etwas daemlich.\n"]));
+
+SIEHE AUCH:
+     Tod:            die(L)
+     Todesmeldungen: P_KILL_NAME, P_KILL_MSG, P_DIE_MSG, P_MURDER_MSG
+                     P_ZAP_MSG, P_ENEMY_DEATH_SEQUENCE
+     Sonstiges:      P_CORPSE, P_NOCORPSE, /room/death/death_room.c
+
+10. Nov 2011 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_NEXT_DISABLE_ATTACK b/doc/props/P_NEXT_DISABLE_ATTACK
new file mode 100644
index 0000000..7019ac6
--- /dev/null
+++ b/doc/props/P_NEXT_DISABLE_ATTACK
@@ -0,0 +1,31 @@
+PROPERTY
+  P_NEXT_DISABLE_ATTACK    "next_diable_attack"
+
+DEFINIERT IN 
+  combat.h
+
+BESCHREIBUNG
+  Diese Property gibt an, wann der NPC das naechste Mal paralysiert
+  werden kann. Ueblicherweise wird sie automatisch beim Setzen
+  von P_DISABLE_ATTACK gesetzt. Sie gibt einen Zeitpunkt wie
+  die Funktion time() an, an dem zum ersten Mal wieder Paralyse
+  moeglich ist.
+
+  Will man einen NPC schreiben, der immer paralysierbar ist und nicht erst
+  nach einer gewissen Wartezeit nach der letzten Paralyse, laesst sich dies
+  durch eine Set-Methode auf P_NEXT_DISABLE_ATTACK erreichen:
+    
+  Set(P_NEXT_DISABLE_ATTACK, function int () {return 0;}, F_SET_METHOD);
+
+  Diese Set-Methode verhindert das Setzen von P_NEXT_DISABLE_ATTACK mittels
+  eines SetProp-Aufrufes.
+
+BEMERKUNGEN:
+  Die Zeit zum Schutz vor erneuter Paralyse existiert absichtlich. Bitte
+  waegt sorgfaeltig ab, bevor ihr diese Property an Gegnern/Spielern
+  manipuliert.
+
+SIEHE AUCH:
+  P_DISABLE_ATTACK
+
+21.Jul 2014 Gloinson
diff --git a/doc/props/P_NOBUY b/doc/props/P_NOBUY
new file mode 100644
index 0000000..561bbba
--- /dev/null
+++ b/doc/props/P_NOBUY
@@ -0,0 +1,10 @@
+NAME:
+    P_NOBUY                       "nobuy"                       
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wenn diese Property gesetzt ist, wird das Objekt nach einem
+     Verkauf im Laden zerstoert, damit es nicht wieder von einem Spieler
+     gekauft werden kann.
diff --git a/doc/props/P_NOCORPSE b/doc/props/P_NOCORPSE
new file mode 100644
index 0000000..799391a
--- /dev/null
+++ b/doc/props/P_NOCORPSE
@@ -0,0 +1,30 @@
+NAME:
+	P_NOCORPSE			"nocorpse"
+
+DEFINIERT IN:
+	/sys/properties.h
+
+BESCHREIBUNG:
+	Diese Property ist gesetzt, wenn im Todesfall kein Leichnam
+	automatisch erzeugt werden soll.
+
+BEMERKUNGEN:
+	In diesem Fall wird die Property P_CORPSE ignoriert, mit der man
+	ein spezielles Leichenobjekt angeben kann, sofern nicht die
+	Standardleiche "/std/corpse.c" verwendet werden soll.
+	Da die Moerdermeldungen ueber ebendiese Objekt laufen, werden
+	hierbei auch keine ausgegeben.
+
+BEISPIELE:
+	Das Lebewesen soll keine Leiche hinterlassen, weil es zu Staub
+	zerfaellt:
+	  SetProp(P_DIE_MSG," zerfaellt zu Staub!\n");
+	  SetProp(P_NOCORPSE,1)
+	Es wurde auch gleich die Sterbemeldung dementsprechend gesetzt.
+
+SIEHE AUCH:
+	P_CORPSE, P_ZAP_MSG, P_DIE_MSG, P_MURDER_MSG, P_KILL_MSG,
+	P_NEVERDROP, /std/corpse.c
+
+----------------------------------------------------------------------------
+Last modified: Thu Jun 14 22:26:29 2001 by Patryn
diff --git a/doc/props/P_NODRINK_MSG b/doc/props/P_NODRINK_MSG
new file mode 100644
index 0000000..3f847c7
--- /dev/null
+++ b/doc/props/P_NODRINK_MSG
@@ -0,0 +1,25 @@
+NAME:
+     P_NODRINK_MSG                 "std_food_nodrink_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Konsumenten, wenn versucht wird, ein Nicht-Getraenk
+     zu trinken. Sobald eine Speise einen Wert in P_FOOD setzt, gilt es als
+     Nicht-Getraenk.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "@WEN1 kann man nicht trinken!"
+
+SIEHE AUCH:
+     P_FOOD, P_DRINK, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_NODROP b/doc/props/P_NODROP
new file mode 100644
index 0000000..37eb5b5
--- /dev/null
+++ b/doc/props/P_NODROP
@@ -0,0 +1,39 @@
+NAME:
+	P_NODROP			"nodrop"                      
+
+DEFINIERT IN:
+	/sys/thing/moving.h
+
+BESCHREIBUNG:
+	Ist diese Property in einem Objekt gesetzt, so kann ein Lebewesen
+	das Objekt nicht weglegen.
+	Als Standardmeldung kommt in diesem Fall beispielsweise:
+	  Du kannst <Objektname> nicht wegwerfen!
+	  Du kannst <Objektname> nicht weggeben.
+	Man kann auch eine alternative Meldung angeben, wobei selbstaendig
+	auf einen korrekten Zeilenumbruch zu achten ist.
+
+BEMERKUNGEN:
+	Soll ein Objekt beim Tod des Lebewesens oder bei Ende eines Spielers
+	nicht in der Leiche bzw. im Raum zurueckgelassen werden, so ist
+	die Property P_NEVERDROP zu nutzen.
+	Beide Properties zusammen stellen sicher, dass ein Objekt nicht
+	weitergegeben werden kann.
+
+BEISPIELE:
+	Ein schwer zu erkaempfender Dolch koennte folgendes beinhalten,
+	um nicht weitergegeben werden zu koennen:
+	  SetProp(P_NODROP,1);
+	Informativer jedoch ist eine eigene Meldung:
+	  SetProp(P_NODROP,
+	 "Den Dolch hast Du Dir hart erkaempft, nicht wegwerfen!\n");
+
+SIEHE AUCH:
+     Aehnliches: P_NOGET, P_NEVERDROP, P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG,
+                 P_TOO_MANY_MSG, P_NOINSERT_MSG, P_NOLEAVE_MSG,  
+     Erfolg:     P_PICK_MSG, P_DROP_MSG, P_GIVE_MSG, P_PUT_MSG,
+                 P_WEAR_MSG, P_WIELD_MSG
+     Sonstiges:  replace_personal(E), /std/living/put_and_get.c
+
+----------------------------------------------------------------------------
+Last modified: Thu Jun 14 22:26:29 2001 by Patryn
diff --git a/doc/props/P_NOFOOD_MSG b/doc/props/P_NOFOOD_MSG
new file mode 100644
index 0000000..c367b7c
--- /dev/null
+++ b/doc/props/P_NOFOOD_MSG
@@ -0,0 +1,25 @@
+NAME:
+     P_NOFOOD_MSG                  "std_food_nofood_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung an den Konsumenten, wenn versucht wird, ein Getraenk zu essen.
+     Sobald eine Speise keinen Wert in P_FOOD und einen Wert in P_DRINK
+     setzt, gilt es als Getraenk.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "@WEN1 kann man nicht essen!"
+
+SIEHE AUCH:
+     P_FOOD, P_DRINK, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_NOGET b/doc/props/P_NOGET
new file mode 100644
index 0000000..af3ed1d
--- /dev/null
+++ b/doc/props/P_NOGET
@@ -0,0 +1,31 @@
+NAME:
+	P_NOGET				"noget"
+
+DEFINIERT IN:
+	/sys/thing/moving.h
+
+BESCHREIBUNG:
+	Ist diese Property in einem Objekt gesetzt, so kann ein Lebewesen
+	das Objekt nicht nehmen.
+	Als Standardmeldung kommt in diesem Fall beispielsweise:
+	  Du kannst <Objektname> nicht nehmen.
+	  Du kannst <Objektname> so nirgendwo reinstecken.
+	Man kann auch eine alternative Meldung angeben, wobei selbstaendig
+	auf einen korrekten Zeilenumbruch zu achten ist.
+
+BEISPIELE:
+	Ein Objekt, welches fest im Raum verankert ist, kann natuerlich
+	nicht entfernt werden, z.B. ein angebundenes Seil:
+	  SetProp(P_NOGET,"Das Seil ist fest am Baum verknotet!\n");
+	In einem Kommando zum Losknoten koennte man die Property dann
+	loeschen, um ein Wegnehmen zu ermoeglichen.
+
+SIEHE AUCH:
+     Aehnliches: P_NODROP, P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG,
+                 P_TOO_MANY_MSG, P_NOINSERT_MSG, P_NOLEAVE_MSG 
+     Erfolg:     P_PICK_MSG, P_DROP_MSG, P_GIVE_MSG, P_PUT_MSG,
+                 P_WEAR_MSG, P_WIELD_MSG
+     Sonstiges:  replace_personal(E), /std/living/put_and_get.c
+
+----------------------------------------------------------------------------
+Last modified: Thu Jun 14 22:26:29 2001 by Patryn
diff --git a/doc/props/P_NOINSERT_MSG b/doc/props/P_NOINSERT_MSG
new file mode 100644
index 0000000..a79994e
--- /dev/null
+++ b/doc/props/P_NOINSERT_MSG
@@ -0,0 +1,46 @@
+NAME:
+    P_NOINSERT_MSG                      "noinsert_msg"                      
+
+DEFINIERT IN:
+    /sys/thing/moving.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt eine Meldung, die ausgegeben wird, wenn
+     jemand versucht, ein Objekt in einen Behaelter zu bewegen und der
+     Behaelter dieses im PreventInsert() verhindert.
+     Die Property ist im Zielbehaelter zu setzen.
+     Ist diese Property nicht oder auf einen nicht-String-Wert gesetzt,
+     so wird die Standardmeldung ausgegeben.
+     ("<Objekt> kannst Du dort nicht hineinstecken.")
+     Der String in der Property wird noch durch replace_personal()
+     verarbeitet, das zu bewegende Objekt wird als erstes, der Zielbehaelter
+     als zweites Objekt angegeben. Danach wird der String auf 78 Zeichen
+     umgebrochen.
+     Das Setzen eines leeren Strings unterdrueckt die Ausgabe einer Meldung
+     ganz.
+
+BEISPIELE:
+     1. Ein Kochtopf laesst im PreventInsert nur bestimmte Objekte zu, die zu
+     einer Suppe gehoeren. Fuer eine passende Meldung wird im Topf jetzt die
+     Property gesetzt:
+     SetProp(P_NOINSERT_MSG, "Du kannst @WEN1 nicht in den Kochtopf tun, da"
+	                     " gehoeren doch nur Suppenzutaten rein!");
+     Wenn jemand jetzt versucht, eine Muenze reinzustecken, dann wuerde
+     folgende Meldung erscheinen:
+	Du kannst die Muenze nicht in den Kochtopf tun, da gehoeren doch nur
+	Suppenzutaten rein!
+
+     2. Ein Rucksack soll in einer bestimmten Reihenfolge gepackt werden, dazu
+     kann im PreventInsert die Meldung je nach Bedarf gesetzt werden:
+     if (<objekt noch nicht an der Reihe>)
+	SetProp(P_NOINSERT_MSG, "@WEN1 solltest du erst spaeter einpacken.");
+     else if (<objekt schon im Rucksack>)
+	SetProp(P_NOINSERT_MSG, "Aber @WER1 ist doch schon eingepackt!");
+     else ...
+
+SIEHE AUCH:
+     Aehnliches: P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_TOO_MANY_MSG,
+                 P_NOLEAVE_MSG, P_NODROP, P_NOGET 
+     Erfolg:     P_PICK_MSG, P_DROP_MSG, P_GIVE_MSG, P_PUT_MSG,
+                 P_WEAR_MSG, P_WIELD_MSG
+     Sonstiges:  replace_personal(E), /std/living/put_and_get.c
diff --git a/doc/props/P_NOLEAVE_MSG b/doc/props/P_NOLEAVE_MSG
new file mode 100644
index 0000000..c1ad0f1
--- /dev/null
+++ b/doc/props/P_NOLEAVE_MSG
@@ -0,0 +1,33 @@
+NAME:
+    P_NOLEAVE_MSG                      "noleave_msg"                      
+
+DEFINIERT IN:
+    /sys/thing/moving.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt eine Meldung, die ausgegeben wird, wenn
+     jemand versucht, ein Objekt aus einem Behaelter zu entfernen und der
+     Behaelter dieses im PreventLeave() verhindert.
+     Die Property ist im verhindernden Behaelter zu setzen.
+     Ist diese Property nicht oder auf einen nicht-String-Wert gesetzt,
+     so wird die Standardmeldung ausgegeben.
+     ("Du kannst <Objekt> nicht nehmen.")
+     Der String in der Property wird noch durch replace_personal()
+     verarbeitet, das zu bewegende Objekt wird als erstes, der verhindernde
+     Behaelter als zweites Objekt angegeben. Danach wird der String auf 78
+     Zeichen umgebrochen.
+     Das Setzen eines leeren Strings unterdrueckt die Ausgabe einer Meldung
+     ganz.
+
+BEISPIELE:
+     Nur Bierschüttler sollen eine Bierflasche aus einem Kasten nehmen
+     koennen, neben einer entsprechenden Behandlung im PreventLeave setzt man
+     dazu die Property:
+     SetProp(P_NOLEAVE_MSG, "Nur Bierschuettler duerfen das!");
+
+SIEHE AUCH:
+     Aehnliches: P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_TOO_MANY_MSG,
+                 P_NOINSERT_MSG, P_NODROP, P_NOGET 
+     Erfolg:     P_PICK_MSG, P_DROP_MSG, P_GIVE_MSG, P_PUT_MSG,
+                 P_WEAR_MSG, P_WIELD_MSG
+     Sonstiges:  replace_personal(E), /std/living/put_and_get.c
diff --git a/doc/props/P_NOMAGIC b/doc/props/P_NOMAGIC
new file mode 100644
index 0000000..bdee7f7
--- /dev/null
+++ b/doc/props/P_NOMAGIC
@@ -0,0 +1,21 @@
+NAME:
+    P_NOMAGIC                     "nomagic"                     
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Angabe in Prozent, mit welcher Wahrscheinlichkeit Magie fehlschlaegt.
+     
+     Fuer einen Raum ist es eine generelle Aussage, wie wahrscheinlich ein
+     Spell in ihm fehlschlaegt. Bei NPC zeigt es an, wie wahrscheinlich
+     ein auf ihn gesprochener Spell fehlschlaegt.
+
+BEISPIEL:
+     // in einem Raum keine Spells zulassen
+     SetProp(P_NOMAGIC, 100)
+
+SIEHE AUCH:
+     Aehnlich:     P_MAGIC_RESISTANCE_OFFSET, SpellDefend
+
+29.Dez 2007 Gloinson
diff --git a/doc/props/P_NOSELL b/doc/props/P_NOSELL
new file mode 100644
index 0000000..48b0ddb
--- /dev/null
+++ b/doc/props/P_NOSELL
@@ -0,0 +1,33 @@
+NAME:
+    P_NOSELL                      "nosell"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wenn diese Property gesetzt ist, kann das Objekt nicht in einem
+     Laden verkauft werden.
+     Gibt man in der Property einen String an, wird dieser ausgegeben,
+     ansonsten erfolgt eine Meldung "Du kannst <NAME> nicht verkaufen!"
+
+     Diese Meldung beinhaltet auch den Namen des in P_NAME einge-
+     tragenen Besitzer des Ladens. Ist dies nicht gesetzt, wird per
+     default 'Der Haendler' ausgegeben.
+
+BEISPIEL:
+     SetProp(P_NOSELL,"Den Schrott behaeltst Du lieber selber.");
+
+     ==> Apu sagt: Den Schrott behaeltst Du lieber selber.
+     ==> Der Haendler sagt: Den Schrott behaeltst Du lieber selber.
+
+     SetProp(P_NOSELL,1);
+
+     ==> Apu sagt: Du kannst <name> nicht verkaufen!
+     ==> Der Haendler sagt: Du kannst <name> nicht verkaufen!
+
+SIEHE AUCH:
+     P_NOBUY, P_NODROP, P_KEEPER
+
+----------------------------------------------------------------------------
+03.09.2010, Zesstra
+
diff --git a/doc/props/P_NO_ASCII_ART b/doc/props/P_NO_ASCII_ART
new file mode 100644
index 0000000..9b40cde
--- /dev/null
+++ b/doc/props/P_NO_ASCII_ART
@@ -0,0 +1,20 @@
+NAME:
+    P_NO_ASCII_ART                   "no_ascii_art"
+
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+    Diese Property kann der Spieler mit dem Befehl "grafik aus" auf
+    1 setzen. Damit zeigt er an, dass er keine ASCII Art sehen moechte.
+
+    Wer ASCII-Art einsetzt, sollte an diesen Stellen die Property 
+    abfragen und textliche Umschreibungen oder Alternativloesungen
+    einbauen.
+    
+SIEHE AUCH:
+    grafik
+
+----------------------------------------------------------------------------
+    Letzte Aenderung: 2005-10-18, Zook.   
diff --git a/doc/props/P_NO_ATTACK b/doc/props/P_NO_ATTACK
new file mode 100644
index 0000000..0f39180
--- /dev/null
+++ b/doc/props/P_NO_ATTACK
@@ -0,0 +1,82 @@
+P_NO_ATTACK
+
+NAME:
+     P_NO_ATTACK "no_attack"
+
+DEFINIERT IN:
+     <living/combat.h>
+
+BESCHREIBUNG:
+     Wenn ein NPC nicht angreifbar sein soll (weil er zum Beispiel in einer
+     Gilde oder einer Quest Informationen vermittelt oder aehnlichen), sollte
+     man diese Property auf einen Wert ungleich Null setzen. Sie wird immer
+     abgefragt, wenn ermittelt wird, ob ein Lebewesen prinzipiell angreifbar
+     ist. D.h. auch, dass nach Abfragen von P_NO_ATTACK _nicht_ immer ein
+     Kampf gestartet wird und dass man dabei _nicht_ im Kampf sein muss!
+
+     Gibt man hier einen String an (mit einem Satzzeichen und "\n" abge-
+     schlossen), wird dieser bei direkten Angriffen ausgegeben. Bei anderen
+     Datentypen wird eine Defaultmeldung ausgegeben. Die Defaultmeldung
+     lautet: "<Name> laesst sich nicht angreifen!\n"
+
+     Mit direkten Angriffen sind 'toete <name>' und Angriffszauber gemeint
+     (bzw. alles, was living/life::Kill(), spellbook::TryAttackSpell(),
+     spellbook::TryDefaultAttackSpell() und spellbook::FindEnemyVictim()
+     aufruft).
+
+ACHTUNG:
+
+  1) Zum Thema QueryMethoden auf P_NO_ATTACK
+     Grundsaetzlich legt man entweder eine Query-Methode auf P_NO_ATTACK:
+        Set(P_NO_ATTACK, #'my_no_attack, F_QUERY_METHOD);
+     oder definiert eine Funktion _query_no_attack() im NPC.
+
+     Wie muss nun eine solche Funktion aussehen? Z.B.:
+     
+     int|string my_no_attack() {
+       if (!objectp(this_player())) return 0;
+       if (opfer==getuid(this_player()) || this_player()==this_object())
+         return(0);
+       return(1); //nicht angreifbar
+     }
+
+     Diese Funktion macht den NPC nun nur fuer den Spieler 'opfer' angreifbar.
+     Stattdessen kann natuerlich auch jede andere Bedingung genutzt werden.
+
+     Aber warum die zweite Bedingung, this_player()==this_object()?
+     Warum sollte der NPC sich selber angreifen duerfen?
+
+     Das liegt an folgenden 2 Dingen:
+
+     1. Kaempfer kriegen bei eingeschaltetem Fokus Probleme, wenn man das 
+     nicht macht. Das liegt an folgendem: Wenn der NPC angreift, ruft er 
+     natuerlich Defend() im Spieler auf. Dieses schaut nach, ob der Spieler 
+     den Skill SK_MAGICAL_DEFENSE hat. Dieser ist bei Kaempfern das Parieren.
+     Dieses schaut nach, ob der Fokus aktiv ist, wenn ja, wird dem 
+     ge'fokus'te Gegner besonders gut ausgewichen. Zu diesem Zweck wird die 
+     Liste der Feind im Raum erstellt mit PresentEnemies() abgerufen. Dieses 
+     fragt aber in allen (potentiellen) Gegnern P_NO_ATTACK ab und beendet 
+     den Kampf mit allen Gegnern, die nicht angreifbar sind. Bei dieser 
+     Abfrage ist jedoch TP==NPC, weil der ja angreift. Wenn er nun 1 
+     zurueckgibt, wird der Kampf an der Stelle beendet. 
+
+     2. Wenn der NPC den Spieler angreift, wird im Spieler InsertEnemy(NPC)
+     aufgerufen. Auch diesem Fall findet die Abfrage von P_NO_ATTACK statt, 
+     da InsertEnemy() ja erstmal rausfinden muss, ob der Gegner angreifbar 
+     ist, bevor er in die Feindliste eingetragen wird. Da der NPC den 
+     Angriff beginnt, ist TP der NPC. Wenn die Query-Methode auf P_NO_ATTACK
+     hier abbricht, wird der NPC nicht in die Feindliste des Spielers 
+     eingetragen. Dann bekaempft der NPC den Spieler, aber der Spieler nicht
+     den NPC.
+
+
+  2) P_NO_ATTACK des NPC wird z.B. beim Kampf eines Kaempfers mit dem NPC 
+     pro Kampfrunde um die 10mal abgerufen. Wenn der Kaempfer nur eine 
+     Attacke macht. Wenn er noch Sonderattacken machen, Spells ausfuehrt, 
+     etc. wird das noch mehr. D.h. was auch immer ihr in der Query-Methode 
+     im NPC macht: 
+     Es sollte schnell sein, jeder Tick an Rechenzeit zaehlt hier xfach!
+
+
+LETZTE AENDERUNG:
+09.11.2015, Arathorn
diff --git a/doc/props/P_NO_BAD b/doc/props/P_NO_BAD
new file mode 100644
index 0000000..60df1e7
--- /dev/null
+++ b/doc/props/P_NO_BAD
@@ -0,0 +1,23 @@
+NAME:
+     P_NO_BAD                      "std_food_no_bad"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Flag, ob die Speise ewig haltbar ist.
+     0: Speise verdirbt nach der Anzahl Sekunden, die in P_LIFETIME
+        angegeben ist bzw. nach einem Reset
+     1: Speise verdirbt nicht
+     
+     ACHTUNG: Diese Property darf nur in Absprache mit der Balance
+              geaendert werden.
+     
+DEFAULT:
+     Initial ist diese Property auf 0 gesetzt.
+
+SIEHE AUCH:
+     /std/food.c, wiz/food
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_NO_GLOBAL_ATTACK b/doc/props/P_NO_GLOBAL_ATTACK
new file mode 100644
index 0000000..01df4e9
--- /dev/null
+++ b/doc/props/P_NO_GLOBAL_ATTACK
@@ -0,0 +1,20 @@
+P_NO_GLOBAL_ATTACK
+
+NAME:
+     P_NO_GLOBAL_ATTACK "no_global_attack"
+
+DEFINIERT IN:
+     <combat.h>
+
+BESCHREIBUNG:
+     Setzt man diese Property in einem NPC auf einen Wert ungleich 0, so
+     wird der NPC bei einem "toete alle" nicht angegriffen.
+
+     Damit kann man zB. NPCs, die dem eigenen Schutz dienen (als Folge von
+     Zauberspruechen o.ae.) vor versehentlichen Angriffen schuetzen.
+
+SIEHE AUCH:
+     /std/npc.c, P_FRIEND
+
+----------------------------------------------------------------------------
+Last modified: Sat May 18 15:26:28 1996 by Wargon
diff --git a/doc/props/P_NO_PARA_TRANS b/doc/props/P_NO_PARA_TRANS
new file mode 100644
index 0000000..578c245
--- /dev/null
+++ b/doc/props/P_NO_PARA_TRANS
@@ -0,0 +1,15 @@
+NAME:
+	P_NO_PARA_TRANS				"no_para_trans"
+
+DEFINIERT IN:
+	/sys/properties.h
+
+BESCHREIBUNG:
+	Wenn in einem Raum diese Property gesetzt ist, darf dort kein
+	Wechsel in oder aus der Paralellwelt erfolgen. Objekte die so
+	einen Wechsel ermoeglichen sind dafuer verantwortlich diese
+	Property abzufragen.
+
+SIEHE AUCH:
+	P_NO_TPORT
+
diff --git a/doc/props/P_NO_PLAYERS b/doc/props/P_NO_PLAYERS
new file mode 100644
index 0000000..062b915
--- /dev/null
+++ b/doc/props/P_NO_PLAYERS
@@ -0,0 +1,37 @@
+NAME:
+    P_NO_PLAYERS                     "no_players"                     
+
+DEFINIERT IN:
+    /sys/rooms.h
+
+BESCHREIBUNG:
+    Wenn in einem Raum die Property P_NO_PLAYERS auf einen Wert != 0 gesetzt
+    ist, kann dieser von Spielern auf normalem Wege nicht mehr betreten werden.
+    Magier und Testspieler(*) koennen den Raum betreten; Spieler muessen mit
+    M_NOCHECK hineinbewegt werden.
+
+    Auf diese Weise koennen Gebiete, die noch nicht offiziell angeschlossen
+    sind, vor 'unbeabsichtigtem' Betreten durch Spieler geschuetzt werden.
+
+    Moechte man zu einem schon angeschlossenen Gebiet nachtraeglich eine
+    Parallelwelt einbauen, so sollte P_NO_PLAYERS *dringend* in den
+    Parallelweltraeumen gesetzt werden, bis die Parallelwelt ausdruecklich
+    fuer Spieler freigegeben wird. Andernfalls sind alle Parallelweltraeume,
+    zu denen angeschlossene Normalweltraeume mit gleichem Filenamen existieren,
+    automatisch durch Spieler erreichbar!
+
+    (*) Ausschliesslich Testspieler, die auf den Namen eines existierenden
+    Magiers markiert sind, koennen 'geschuetzte' Raeume betreten.
+    Gildentesties werden wie Spieler behandelt.
+
+ANMERKUNG:
+    Im Gegensatz zu Bewegungen von Livings wird bei der Bewegung von Gegen-
+    staenden P_NO_PLAYERS nur beim Wechsel der Welt ausgewertet, um z.B. zu
+    verhindern, dass Bumerangs in noch nicht angeschlossene Gebiete fliegen.
+
+    Moechte man in seinem eigenen Gebiet mit Bumerangs o.ae. testen, muss
+    in diesen P_TESTPLAYER gesetzt sein. Das ist zwar eher ein Missbrauch
+    der Property, aber ein Umkompieren vom Werfer war auf Dauer zu teuer. ;-)
+
+SIEHE AUCH:
+    P_PARA, move
diff --git a/doc/props/P_NO_REGENERATION b/doc/props/P_NO_REGENERATION
new file mode 100644
index 0000000..b8dea8c
--- /dev/null
+++ b/doc/props/P_NO_REGENERATION
@@ -0,0 +1,34 @@
+P_NO_REGENERATION
+
+NAME:
+     P_NO_REGENERATION    "no_regeneration"
+
+DEFINIERT IN:
+     <living/life.h> und <health.h>
+
+BESCHREIBUNG:
+     Durch das Setzen dieser Property kann man verhindern, das ein Lebewesen
+     sich regeneriert.
+     Es gibt sieben moegliche Werte, die man durch verodern kombinieren
+     kann:
+     NO_REG_HP        : es werden keine HP regeneriert
+     NO_REG_BUFFER_HP : es werden beim "tanken" keine HP regeneriert
+     NO_REG_SP        : es werden keine SP regeneriert
+     NO_REG_BUFFER_SP : es werden beim "tanken" keine SP regeneriert
+     NO_REG_ALCOHOL   : der Alkoholspiegel wird nicht gesenkt
+     NO_REG_DRINK     : der Fluessigkeitsspiegel wird nicht gesenkt
+     NO_REG_FOOD      : der Nahrungsspiegel wird nicht gesenkt
+     sowie die Konstante NO_REG, die eine Kombination aller moeglichen
+     Werte darstellt (quasi das groesstmoegliche Uebel ;).
+
+BEISPIELE:
+     Dieses Lebewesen heilt nur beim "tanken" in der Kneipe, ansonsten
+     nicht:
+     
+     SetProp( P_NO_REGENERATION, NO_REG_HP|NO_REG_SP );
+
+SIEHE AUCH:
+     /std/living/life.c
+
+----------------------------------------------------------------------------
+Last modified: 14-05-2001 by Mupfel
diff --git a/doc/props/P_NO_SCORE b/doc/props/P_NO_SCORE
new file mode 100644
index 0000000..6c4a2d2
--- /dev/null
+++ b/doc/props/P_NO_SCORE
@@ -0,0 +1,51 @@
+NAME:
+     P_NO_SCORE               "no_score"
+
+DEFINIERT IN:
+     /secure/scoremaster.h
+
+BESCHREIBUNG:
+     Die Property stellt ein Flag innerhalb von Lebewesen dar, welches
+     standardmaessig nicht gesetzt ist. In diesem Fall werden
+     Erstkillstufenpunkte an den Angreifer vergeben, sofern er ein Opfer
+     toetet.
+
+     Innerhalb eines Teams koennen Erstkillstufenpunkte auch an
+     Mitglieder vergeben werden, die das Lebewesen nicht selbst getoetet
+     haben. Voraussetzung hierfuer ist, dass derjenige, der den letzten
+     Schlag ausfuehrte, den Kill schon hat. Danach werden Mitglieder des
+     Teams gesucht, welche den Kill noch nicht haben und in der Formation
+     moeglichst weit vorne stehen.
+
+     Mit der gesetzten Property P_NO_SCORE im Opfer erreicht man nun,
+     dass diese Gutschrift fuer den/die Angreifer unterbunden wird.
+
+BEISPIEL:
+     Folgendermassen unterbindet man die Vergabe von
+     Erstkillstufenpunkten fuer den Tod eines NPC's:
+
+       include "/secure/scoremaster.h"
+       inherit "std/npc";
+       void create() {
+         ::create();
+         ...
+         SetProp(P_NO_SCORE,1);
+       }
+
+     Damit kann P_XP einen Wert haben, der eigentlich zum automatischen
+     Eintragen von Erstkillstufenpunkten fuer ein Lebewesen fuehrt, und
+     trotzdem wird dieser Eintrag nicht vorgenommen.
+     Sinnvoll ist dies insbesondere bei Lebewesen, die nicht jeder
+     Spieler erreichen kann (man moechte doch eine gewisse
+     Chancengleichheit fuer das Erreichen von Stufenpunkten bieten).
+
+BEMERKUNGEN:
+     Auch die Vergabe von Erfahrungspunkten kann explizit unterbunden
+     werden. Hierfuer gibt es die aehnlich geartete Property P_NO_XP.
+
+SIEHE AUCH:
+     Funktionen:  GiveKillScore(), do_damage()
+     Verwandt:    P_NO_XP
+     Sonstiges:   P_XP
+
+14.Feb 2007 Gloinson
diff --git a/doc/props/P_NO_STD_DRINK b/doc/props/P_NO_STD_DRINK
new file mode 100644
index 0000000..a91e92d
--- /dev/null
+++ b/doc/props/P_NO_STD_DRINK
@@ -0,0 +1,19 @@
+NAME:
+	P_NO_STD_DRINK			"no_std_drink"
+
+DEFINIERT IN:
+	/sys/pub.h
+
+BESCHREIBUNG:
+        Durch setzen dieser Property in einer Kneipe sorgt man dafuer, dass 
+        "Standard-Drinks" (z.B. Gluehwein im Dezember) nicht in das Menue
+        der Kneipe aufgenommen werden.
+
+BEMERKUNGEN:
+        Keine.
+
+SIEHE AUCH:
+	/std/room/pub.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Mar 04 22:42:00 2000 by Paracelsus
diff --git a/doc/props/P_NO_TPORT b/doc/props/P_NO_TPORT
new file mode 100644
index 0000000..40350e5
--- /dev/null
+++ b/doc/props/P_NO_TPORT
@@ -0,0 +1,15 @@
+NAME:
+    P_NO_TPORT                    "tport"                       
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Kann folgende Werte annnehmen (definiert in moving.h):
+     NO_TPORT_IN	= Man kann nicht in den Raum hinein teleportieren.
+     NO_TPORT_OUT = Man kann nicht aus dem Raum hinaus teleportieren.
+     NO_TPORT	= Weder noch.
+
+SIEHE AUCH:
+	P_NO_PARA_TRANS
+
diff --git a/doc/props/P_NO_TRAVELING b/doc/props/P_NO_TRAVELING
new file mode 100644
index 0000000..61425bc
--- /dev/null
+++ b/doc/props/P_NO_TRAVELING
@@ -0,0 +1,25 @@
+NAME:
+    P_NO_TRAVELING                   "no_traveling"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+    Hier steht der allgemeine reise-Befehl nicht zur Verfuegung.
+
+BEMERKUNGEN:
+    P_NO_TRAVELING wird in Transportern gesetzt wenn Spieler ihn 
+    nicht mehr 'automatisch' mittels des 'reise'-Befehls betreten
+    koennen sollen.
+
+    Sie bekommen in dem Transporter und in den Zielraeumen auch 
+    keinerlei Hinweise darauf, wohin sie evtl. reisen koennten.
+    
+    Standardmaessig ist P_NO_TRAVELING natuerlich 0.
+
+SIEHE AUCH:
+    reise
+
+LETZTER AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
+    
\ No newline at end of file
diff --git a/doc/props/P_NO_XP b/doc/props/P_NO_XP
new file mode 100644
index 0000000..f12fe8d
--- /dev/null
+++ b/doc/props/P_NO_XP
@@ -0,0 +1,43 @@
+NAME:
+     P_NO_XP                    "no_xp"
+
+DEFINIERT IN:
+     /sys/living/life.h
+
+BESCHREIBUNG:
+     Im Normalfall bekommt man im Kampf gegen einen Gegner fuer Treffer
+     und beim Toeten eine XP-Gutschrift.
+
+     Ist P_NO_XP gesetzt, so erhält man keinerlei XP-Gutschriften
+     für den Kampf oder den Tod des NPCs.
+
+BEISPIEL:
+     Folgendermassen unterbindet man die Vergabe von Erfahrungspunkte
+     fuer den Angriff eines NPC's:
+
+       include "/sys/living/life.h"
+       inherit "std/npc";
+       void create() {
+         ::create();
+         ...
+         SetProp(P_NO_XP,1);
+       }
+
+     Damit kann P_XP trotzdem einen Wert im NPC haben, der
+     Erstkillstufenpunkte fuer Lebewesen automatisch eintraegt!
+
+     Auch fuer das kurzzeitige Unterbinden der Vergabe von
+     Erfahrungspunkten ist diese Property sinnvoller, als P_XP im NPC
+     auf 0 zu setzen.
+
+BEMERKUNGEN:
+     Auch die Vergabe von Erstkillstufenpunkten kann explizit unterbunden
+     werden. Hierfuer gibt es die aehnlich geartete Property P_NO_SCORE.
+
+SIEHE AUCH:
+     Funktionen:  AddExp(), DistributeExp(), do_damage()
+     Properties:  P_XP, P_LAST_XP
+     Verwandt:    P_NO_SCORE
+     Sonstiges:   P_TOTAL_WC, create_default_npc()
+
+14.Feb 2007 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_NPC b/doc/props/P_NPC
new file mode 100644
index 0000000..69d1270
--- /dev/null
+++ b/doc/props/P_NPC
@@ -0,0 +1,8 @@
+NAME:
+    P_NPC                         "is_npc"                      
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Gesetzt bei Monstern.
diff --git a/doc/props/P_NPC_FASTHEAL b/doc/props/P_NPC_FASTHEAL
new file mode 100644
index 0000000..3f588b9
--- /dev/null
+++ b/doc/props/P_NPC_FASTHEAL
@@ -0,0 +1,21 @@
+NAME:
+	P_NPC_FASTHEAL			"npc_fastheal"
+
+DEFINIERT IN:
+	/sys/pub.h
+
+BESCHREIBUNG:
+        Durch setzen dieser Property in einer Kneipe sorgt man dafuer, dass 
+        bei NPCs, die dort "tanken", die Lebens- und Konzentrationspunkte
+        direkt erhoeht werden und nicht, wie bei ungesetzter Property, in
+        die jew. Buffer geschrieben werden.
+
+BEMERKUNGEN:
+        Die Benutzung dieser Property sollte nicht unbedingt zum Standard
+        werden.
+
+SIEHE AUCH:
+	/std/room/pub.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Sep 29 13:58:00 1999 by Paracelsus
diff --git a/doc/props/P_NR_HANDS b/doc/props/P_NR_HANDS
new file mode 100644
index 0000000..b0827a9
--- /dev/null
+++ b/doc/props/P_NR_HANDS
@@ -0,0 +1,31 @@
+P_NR_HANDS
+NAME:
+     P_NR_HANDS "nr_hands"
+
+DEFINIERT IN:
+     <weapon.h>
+
+BESCHREIBUNG:
+     Wieviele Haende muss man frei haben, um die Waffe zuecken oder den
+     Schild tragen zu koennen?
+     Dieser Wert muss mindestens 1 betragen!
+
+     Sollen Spieler die Waffe benutzen koennen, so sind hier nur die Werte 1
+     und 2 moeglich. Falls die Waffe nur von Monstern benutzbar sein soll,
+     kann man hier auch hoehere Werte eintragen (dazu muss man beim Monster
+     P_MAX_HANDS entsprechend hoch setzen). Als Beispiel sei hier nur das
+     vierhaendige Schwert aus dem Friedhof genannt.
+
+     Defaultmaessig sind alle Waffen Zweihaender.
+
+     Diese Property kann auch bei Zaubern benutzt werden, bei denen man eine
+     oder mehrere Haende frei haben muss.
+
+SIEHE AUCH:
+     P_HANDS, P_HANDS_USED_BY
+     P_MAX_HANDS, P_USED_HANDS, P_FREE_HANDS
+     UseHands, FreeHands
+     /std/weapon.c, /std/spellbook.c
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 15:00:02 1996 by Wargon
diff --git a/doc/props/P_ORAKEL b/doc/props/P_ORAKEL
new file mode 100644
index 0000000..cf383da
--- /dev/null
+++ b/doc/props/P_ORAKEL
@@ -0,0 +1,9 @@
+NAME:
+    P_ORAKEL                      "orakel"                      
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wenn diese Property gesetzt ist, kann der Wanderer in diesen
+     Raum hinein.
diff --git a/doc/props/P_ORIG_FILE_NAME b/doc/props/P_ORIG_FILE_NAME
new file mode 100644
index 0000000..2064360
--- /dev/null
+++ b/doc/props/P_ORIG_FILE_NAME
@@ -0,0 +1,8 @@
+NAME:
+    P_ORIG_FILE_NAME                "original_object_name"               
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     In einer Leiche der Filename des Gestorbenen.
diff --git a/doc/props/P_ORIG_NAME b/doc/props/P_ORIG_NAME
new file mode 100644
index 0000000..96a5d73
--- /dev/null
+++ b/doc/props/P_ORIG_NAME
@@ -0,0 +1,8 @@
+NAME:
+    P_ORIG_NAME                   "original_name"               
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     In einer Leiche der Name des Gestorbenen. (name(RAW))
diff --git a/doc/props/P_PARA b/doc/props/P_PARA
new file mode 100644
index 0000000..87cc92b
--- /dev/null
+++ b/doc/props/P_PARA
@@ -0,0 +1,54 @@
+NAME:
+    P_PARA                        "para"                        
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Nummer der Parallelwelt, in der sich ein Spieler befindet.
+
+    Ist die Property P_PARA auf Null gesetzt, so befindet sich der Spieler in
+    der 'Normalwelt'. Gibt es bei einer Bewegung dieses Spielers mehrere
+    moegliche Zielraeume mit identischem Namen aber unterschiedlichen Endungen
+    'name.c', 'name^1.c', 'name^2.c' etc., so wird der Spieler in den Raum
+    'name.c' bewegt. 
+
+    Wird die Property P_PARA auf einen Wert n>0 gesetzt, so landet der Spieler
+    bei einer Bewegung im Raum 'name^n.c'. Ist kein Raum mit entsprechender
+    Endung vorhanden, wird der Spieler stattdessen in den Normalweltraum
+    bewegt.
+
+    Diese Prop kann auch in einem Virtual Compiler gesetzt werden. In diesem
+    Fall schraenkt sie die Dimensionen ein, in denen der VC Objekte erzeugt.
+    Die Prop kann eine einzelne Ziffer (Int) oder ein Array von Ints 
+    aufnehmen, dann ist der VC fuer alle angegeben Dimensionen zustaendig. 
+    Ein leeres Array erlaubt gar keine Para-Objekte.
+
+ANMERKUNG:
+    Die Endung '^0' kennzeichnet _nicht_ die Normalwelt. So lange kein Ausgang
+    explizit auf den Raum 'name^0.c' verweist, wird kein Spieler den Raum
+    betreten koennen. Deshalb kann man die Endung '^0' z.B. dazu benutzen, um
+    eigene Standardraeume fuer ein Gebiet zu schreiben, die dann sowohl von
+    den Normal- als auch von den Parallelweltraeumen inheritet werden.
+
+    Raeume mit Endungen '^n.c', bei denen 'n' keine positive ganze Zahl ist,
+    werden nicht beachtet.
+
+    Fuer die Entscheidung, in welchem Raum ein Spieler in Abhaengigkeit von
+    P_PARA landet, ist die Funktion move() zustaendig. Als Magier muss man sich
+    darum nicht gesondert kuemmern. Das heisst aber auch, dass beim Anschluss
+    eines Normalweltraumes automatisch alle in dem Verzeichnis mit gleichem
+    Namen vorhandenen Parallelweltraeume mit angeschlossen werden.
+
+    Sollen einzelne Parallelweltraeume noch nicht angeschlossen werden, so muss
+    in ihnen die Property P_NO_PLAYERS gesetzt werden. Diese Raeume sind dann
+    nur durch Magier und Testspieler zu betreten (und zu testen).
+
+    In Paraweltraeumen liefert P_PARA 'n' zurueck.
+    Man kann also z.B. in NPCs einfach ueber environment()->QueryProp(P_PARA) 
+    abfragen, in welcher Parawelt sich dieser gerade befindet.
+
+SIEHE AUCH:
+    P_NO_PLAYERS, move, pararaeume
+    
+25.Jan 2015 Gloinson
diff --git a/doc/props/P_PARRY b/doc/props/P_PARRY
new file mode 100644
index 0000000..03550df
--- /dev/null
+++ b/doc/props/P_PARRY
@@ -0,0 +1,31 @@
+P_PARRY
+
+NAME:
+     P_PARRY "parry"
+
+DEFINIERT IN:
+     <combat.h>
+
+BESCHREIBUNG:
+     Diese Property legt fest, inwiefern eine Waffe als Parierwaffe
+     genutzt werden kann. Moegliche Werte:
+
+         PARRY_NOT     Eine reine Angriffswaffe ohne Parierfunktion.
+
+         PARRY_TOO     Eine kombinierte Angriffs- und Parierwaffe.
+
+         PARRY_ONLY    Eine reine Parierwaffe. Diese kann zusaetzlich
+                       zu einer normalen Waffe gezueckt werden.
+
+     Man sollte nur die in <combat.h> definierten Konstanten verwenden.
+
+BEMERKUNGEN:
+     Durch diese Propertie laesst sich _kein_ Parade-Bonus fuer Trves 
+     setzen! Alle Gilden haben etwas davon. Vor Verwendung bitte mit
+     der Objekt-Balance absprechen.
+
+SIEHE AUCH:
+     /std/weapon/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Jun 01 13:28:45 2001 by Tilly
diff --git a/doc/props/P_PARRY_WEAPON b/doc/props/P_PARRY_WEAPON
new file mode 100644
index 0000000..c873bfb
--- /dev/null
+++ b/doc/props/P_PARRY_WEAPON
@@ -0,0 +1,17 @@
+P_PARRY_WEAPON
+
+NAME:
+     P_PARRY_WEAPON "parry_weapon"
+
+DEFINIERT IN:
+     <combat.h>
+
+BESCHREIBUNG:
+     Diese Property gibt an, welche Parierwaffe ein Spieler derzeit
+     gezueckt hat.
+
+SIEHE AUCH:
+     /std/weapon/combat.c, /std/living/combat.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Jun 26 15:23:00 1999 by Paracelsus
diff --git a/doc/props/P_PEACE_HISTORY b/doc/props/P_PEACE_HISTORY
new file mode 100644
index 0000000..f3cb2d2
--- /dev/null
+++ b/doc/props/P_PEACE_HISTORY
@@ -0,0 +1,42 @@
+P_PEACE_HISTORY
+
+NAME:
+     P_PEACE_HISTORY      "_peace_history"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+    In dieser Prop wird nach Gilden getrennt gespeichet, wie oft das Lebewesen
+    in letzter Zeit befriedet worden ist. Diese Information geht in die
+    Chance auf eine zukuenftige Befriedung ein.
+    Die Zaehler werden im Durchschnitt alle 2700s um 2-3 reduziert.
+    Die Datenstruktur ist ein Array, welches einen Zeitstempel als erstes
+    Element und ein Mapping als zweites enthaelt. Das Mapping enthaelt unter
+    den Gildennamen als Keys den ganzzahligen Zaehler erfolgreicher
+    Befriedungen von Spielern dieser Gilde.
+
+BEMERKUNGEN:
+    * Diese Property sollte niemals direkt geaendert werden. Bitte greift also
+      nur lesend darauf zu. Sollte hiermit Schindluder getrieben werden,
+      werden die Daten vor externer Aenderung geschuetzt.
+    * Die Datenstruktur in dieser Prop kann in Zukunft u.U. geaendert werden.
+      Daher aendert sie am besten auch nicht im eigenen NPC oder seid darauf
+      gefasst, irgendwann Hand anlegen zu muessen.
+    * Die Aktualisierung (auch die Reduktion) findet im Zuge eines
+      QueryPacify() statt, nicht im Reset des Lebewesens.
+
+BEISPIEL:
+    In P_PEACE_HISTORY steht:
+    ({1209654597, (["zauberer": 3, "klerus": 4]) })
+    Bei der Berechnung der naechsten Befriede-Chance gehen bei Zauberern also
+    3 erfolgreiche Versuche, bei Klerikern 4 erfolgreiche Versuche ein.
+    Der Zeitwert an erster Stelle des Arrays wird der bei der Berechnung der
+    naechsten Reduktion der Zaehler beruecksichtigt. (Genaues: s. combat.c)
+
+SIEHE AUCH:
+     P_PEACE_ACCEPT
+     QueryPacify()
+     /std/living/combat.c
+
+01.05.2008, Zesstra
diff --git a/doc/props/P_PERM_STRING b/doc/props/P_PERM_STRING
new file mode 100644
index 0000000..d7904b7
--- /dev/null
+++ b/doc/props/P_PERM_STRING
@@ -0,0 +1,11 @@
+NAME:
+    P_PERM_STRING                 "perm_string"                 
+
+DEFINIERT IN:
+    /sys/player/comm.h
+
+BESCHREIBUNG:
+     Fuer Sprachflueche, Property ist im Spieler-Objekt zu setzen. In dem
+     Objekt, das in P_PERM_STRING gespeichert ist, wird bei Sprachbefehlen
+     permutate_string(str) aufgerufen und der zurueckgegebene String 
+     stattdessen ausgegeben.
diff --git a/doc/props/P_PICK_MSG b/doc/props/P_PICK_MSG
new file mode 100644
index 0000000..f77d508
--- /dev/null
+++ b/doc/props/P_PICK_MSG
@@ -0,0 +1,60 @@
+P_PICK_MSG
+NAME:
+     P_PICK_MSG				"pick_message"
+
+DEFINIERT IN:
+     /sys/living/put_and_get.h
+
+BESCHREIBUNG:
+     Mit P_PICK_MSG kann man die Meldung, die man beim Aufnehmen eines
+     Objektes bekommt, modifizieren.
+
+     Folgende Werte sind moeglich:
+
+     o 0
+       Es wird eine Standardmeldung ausgegeben. Dies ist Voreinstellung.
+
+     o NO_PNG_MSG       == -1
+       Es wird keinerlei Meldung ausgegeben
+
+     o Ein Array aus Strings
+       Der erste String wird an den Spieler ausgegeben, der zweite
+       (optionale) an den Raum.
+
+       Die Strings werden durch die Funktion replace_personal() geparst.
+	Objekt1 - Spieler
+        Objekt2 - das Objekt, das genommen wird
+
+       Wird der zweite String nicht angegeben, erfolgt keine Meldung an den
+       Raum.
+
+BEISPIEL:
+     void create() {
+      ...
+      SetProp( P_SHORT, "Etwas Sand" );
+      SetProp( P_LONG, break_string(
+       "Ein wenig magischer Sand. Sehr feinkruemelig.",78 ));
+
+      SetProp( P_NAME, "Sand" );
+      AddId( ({"sand"}) );
+      SetProp( P_GENDER, MALE );
+
+      SetProp( P_PICK_MSG, ({
+       "Du schaufelst @WEN2 in deine Hand.",
+       "@WER1 schaufelt @WEN2 in eine Hand."}));
+      ...
+     }
+
+     Das ganze fuehrt bei Ugars "nimm sand" zu folgenden
+     Meldungen:
+
+     Ugar: "Du schaufelst den Sand in deine Hand."
+     Raum: "Ugar schaufelt den Sand in eine Hand."
+
+SIEHE AUCH:
+     Aehnliches: P_DROP_MSG, P_PUT_MSG, P_GIVE_MSG, P_WEAR_MSG, P_WIELD_MSG
+     Fehler:     P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_TOO_MANY_MSG,
+                 P_NOINSERT_MSG, P_NOLEAVE_MSG, P_NODROP, P_NOGET 
+     Sonstiges:  replace_personal(E), pick_obj(L), /std/living/put_and_get.c
+
+14. Maerz 2004 Gloinson
diff --git a/doc/props/P_PILE_NAME b/doc/props/P_PILE_NAME
new file mode 100644
index 0000000..e54dc72
--- /dev/null
+++ b/doc/props/P_PILE_NAME
@@ -0,0 +1,9 @@
+NAME:
+    P_PILE_NAME                   "file_name"               
+
+DEFINIERT IN:
+    /sys/container/properties.h
+
+BESCHREIBUNG:
+     In einer Leiche der Name des Gestorbenen im Dativ. (name(WEM))
+     Wird vom Haufen benoetigt.
diff --git a/doc/props/P_PLAYER_LIGHT b/doc/props/P_PLAYER_LIGHT
new file mode 100644
index 0000000..ddd59b5
--- /dev/null
+++ b/doc/props/P_PLAYER_LIGHT
@@ -0,0 +1,28 @@
+NAME:
+    P_PLAYER_LIGHT                       "player_light"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Gibt den Lichtlevel an, mit dem ein Lebewesen sieht, ein Abfragen dieser
+    Property kann z.B. sinnvoll sein wenn man abfragen will ob ein Spieler
+    genug Licht dabei hat um ein bestimmtes Detail untersuchen zu koennen.
+
+    Bitte _nur_ ueber QueryProp auf diese Property zugreifen,
+    da das Lichtlevel ggf. neu berechnet werden muss!
+
+    Ein direktes setzen dieser Property ist NICHT moeglich. Es ist jedoch
+    moeglich entweder eine Closure zu benutzen oder den Wert ueber einen
+    P_LIGHT_MODIFIER zu veraendern.
+
+    Um zu erreichen, das ein NPC Nachtsicht bekommt, gibt es nun 3 Varianten.
+    - eine closure:
+        Set(P_PLAYER_LIGHT, function int () {return 1;} , F_QUERY_METHOD) 
+      dieses bedeutet, dass der NPC in jeder Dunkelheit perfekt sehen kann.
+    - das setzen von einem P_LIGHT_MODIFIER
+    - das benutzen des stdskills. Hierzu schreibt man in das create() des
+      NPCs einfach ein: ModifySkill(SK_NIGHTVISION, 10000);
+
+SIEHE AUCH:
+    P_LIGHT_MODIFIER, P_LIGHT, P_TOTAL_LIGHT, P_INT_LIGHT, CannotSee()
diff --git a/doc/props/P_PLURAL b/doc/props/P_PLURAL
new file mode 100644
index 0000000..0a5e3a5
--- /dev/null
+++ b/doc/props/P_PLURAL
@@ -0,0 +1,39 @@
+NAME:
+    P_PLURAL                      "plural"
+
+DEFINIERT IN:
+    /sys/thing/language.h
+
+BESCHREIBUNG:
+    Mit Hilfe von P_PLURAL koennen auch nicht Unit Objekte als Pluralobjekte
+    markiert werden. Bei einem Wert > 1 wird der Wert ausserdem auch noch in
+    den Namen eingefuegt. Sollte man in eigenem Code zulassen wollen, das
+    etwas mit bestimmten Objekten geschieht, dann sollte man die Verben
+    entsprechen konjugieren.
+
+BEMERKUNGEN:
+    Wirkt nicht auf Todesmeldungen -> siehe dafuer P_KILL_MSG
+
+BEISPIELE:
+    SetProp(P_NAME, "Stiefel"); SetProp(P_PLURAL, 2);
+    name(WER, 1) -> "die zwei Stiefel"
+
+    SetProp(P_NAME, "Stiefel"); SetProp(P_PLURAL, 1);
+    name(WER, 1) -> "die Stiefel"
+
+    // Ein Beispiel fuer das konjugieren von Verben
+    static int cmd_opfer(string str)
+    {
+       int i;
+       object *obs;
+       notify_fail("Was moechtest Du opfern?\n");
+       if (!str || !sizeof(obs=PL->find_obs(str))) return 0;
+       for (i=sizeof(obs)-1; i>=0; i--)
+          if (obs[i]->QueryProp(P_VALUE)<=0)
+            write(obs[i]->Name(WER)+" "
+                 +(ob->QueryProp(P_PLURAL) ? "sind" : "ist")
+                 +" doch gar nichts wert.\n");
+          else obs[i]->remove();
+    }
+
+26. Juni 2004 Gloinson
diff --git a/doc/props/P_POISON b/doc/props/P_POISON
new file mode 100644
index 0000000..2b7ea7b
--- /dev/null
+++ b/doc/props/P_POISON
@@ -0,0 +1,8 @@
+NAME:
+    P_POISON                      "poison"                      
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wie stark wir vergiftet sind (0-11)
diff --git a/doc/props/P_POISON_DELAY b/doc/props/P_POISON_DELAY
new file mode 100644
index 0000000..aba57c6
--- /dev/null
+++ b/doc/props/P_POISON_DELAY
@@ -0,0 +1,13 @@
+NAME:
+    P_POISON_DELAY                     "poison_delay"                     
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Anzahl der heart_beats nach denen sich die Giftwirkung erneut 
+     zeigt. Je kleiner der Wert, desto empfindlicher ist das Lebewesen
+     gegen Gift.
+     Aenderungen dieser Property in Spielern beduerfen der Genehmigung
+     des EMs fuer Balance.
+     
diff --git a/doc/props/P_PORTIONS b/doc/props/P_PORTIONS
new file mode 100644
index 0000000..cb134e6
--- /dev/null
+++ b/doc/props/P_PORTIONS
@@ -0,0 +1,21 @@
+NAME:
+     P_PORTIONS                    "std_food_portions"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     In dieser Property steht die Anzahl der Portionen einer Speise.
+     Es duerfen nur Werte > -1 gesetzt werden. Ist diese Property 0,
+     wird die Speise als leer bzw. verbraucht angesehen und kann nicht
+     konsumiert werden.
+     
+DEFAULT:
+     Initial ist diese Property auf 1 gesetzt, die Speise ist also mit
+     einem Bissen/Schluck verbraucht bzw. leer.
+
+SIEHE AUCH:
+     /std/food.c, wiz/food
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_POST b/doc/props/P_POST
new file mode 100644
index 0000000..53a6f74
--- /dev/null
+++ b/doc/props/P_POST
@@ -0,0 +1,64 @@
+NAME:
+	P_POST				"Post"
+
+DEFINIERT IN:
+	/mail/post.h
+
+BESCHREIBUNG:
+	In dieser Property laesst sich die Versendeerlaubnis von Paketen
+	regeln. Hierbei gibt es zum einen die postlagernden Pakete, die man
+	in einer Post abholen muss, und es gibt die sogenannten
+	Kurierpakete, welche direkt und unmittelbar zugestellt werden.
+	Nicht immer ist es erwuenscht, dass Pakete aus der Ferne in einen
+	Raum geschickt werden duerfen. Dies duerfte insbesondere innerhalb
+	von Gebieten interessant sein, in welche man nur beschraenkt viele
+	Objekte mitfuehren kann. Mit dieser Property nun ist es leicht
+	moeglich, dies zu verbieten. Man kann auch in den Objekten selbst
+	angeben, ob diese per postlagerndem Paket bzw. Kurierpaket
+	verschickt werden duerfen. Dies duerfte zum Beispiel bei Komponenten
+	fuer Spells oder fuer Unique-Objekte interessant sein.
+	Folgende Werte sind moeglich, wobei in Raeumen und Objekten
+	Standardmaessig PP_DEFAULT genutzt wird:
+
+	  PP_FORBIDDEN		-2	// auf jeden Fall verboten
+	  PP_NO_EXPRESS		-1	// Kurierpakete verboten
+	  PP_DEFAULT		 0	// Default
+	  PP_NORMAL_ALLOWED	 1	// postlagernde Pakete erlaubt
+	  PP_ALLOWED		 2	// auf jeden Fall erlaubt
+
+	Raeume, die von /std/post.c abgeleitet wurden, nutzen als Standard
+	natuerlich PP_ALLOWED.
+
+BEISPIEL:
+	Um Kurierpakete fuer einen Raum zu verbieten, nutzt man die
+	Funktionalitaet dieser Property folgendermassen:
+
+	  include "/mail/post.h"
+	  ...
+	  void create()
+	  { ::create();
+	    ...
+	    SetProp(P_POST,PP_NO_EXPRESS);
+	    ...
+	  }
+
+	Objekte selbst koennte man folgendermassen aus Paketen verbannen,
+	welche versendet werden sollen:
+
+	  include "/mail/post.h"
+	  ...
+	  void create()
+	  { ::create();
+	    ...
+	    SetProp(P_POST,PP_FORBIDDEN);
+	    ...
+	  }
+
+	In letzterem Fall funktionieren im Gegensatz zum ersten Beispiel
+	auch keine postlagernden Pakete mehr.
+
+SIEHE AUCH:
+	/std/post.c, /std/mailcabin.c, /p/service/loco/std/mailcabin.c
+
+----------------------------------------------------------------------------
+Last modified: Sun Sep  6 19:34:37 1998 by Patryn
diff --git a/doc/props/P_POTIONROOMS b/doc/props/P_POTIONROOMS
new file mode 100644
index 0000000..5820be2
--- /dev/null
+++ b/doc/props/P_POTIONROOMS
@@ -0,0 +1,19 @@
+NAME:
+    P_POTIONROOMS                 "potionrooms"                 
+
+DEFINIERT IN:
+    /sys/player/potion.h
+
+BESCHREIBUNG:
+    Array mit den Nummern der Raeume, in denen der Spieler noch Zauber-
+    traenke hat. Die Freischaltung als bekannt geschieht im Orakel.
+    Die Zuordnung der Raeume und Nummern geschieht im Potionmaster.
+
+    Nur lesbare _query - Property.
+
+SIEHE AUCH:
+    Sonstiges: zaubertraenke, /secure/potionmaster.c, /room/orakel.c
+    Verwandt:  FindPotion(), AddKnownPotion(), RemoveKnownPotion(), InList()
+    Props:     P_KNOWN_POTIONROOMS
+
+6.Feb 2016 Gloinson
diff --git a/doc/props/P_PRAY_ROOM b/doc/props/P_PRAY_ROOM
new file mode 100644
index 0000000..3c8f9ff
--- /dev/null
+++ b/doc/props/P_PRAY_ROOM
@@ -0,0 +1,36 @@
+NAME:
+    P_PRAY_ROOM                      "_lib_p_pray_room"                  
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+    Dies ist der Raum, in den der Spieler nach dem Ende der Todessequenz
+    bewegt wird, d.h. ein Raum, wo er beten kann, um einen neuen Koerper zu
+    erhalten.
+    Der Raum muss als String angegeben werden (kein Objekt).
+
+    Diese Property wird im Spieler rebootfest gespeichert.
+
+    Der jeweils gueltige Betraum wird im Spieler mittels QueryPrayRoom()
+    ermittelt. Jede Rasse hat einen Default fuer diese Funktion. Wird die
+    Property auf 0 dgesetzt, wird dieser Default wiederhergestellt.
+
+    Von einer Ueberlagerung mittels Query- oder gar Setmethoden wird
+    abgeraten. Ebenso lasst bitte die Modusbits unveraendert.
+
+    Vor einer Aenderung dieser Property sollte geprueft werden, ob sie 0 ist.
+    Wenn nicht, sollte von einem Setzen der Property abgesehen werden, da dann
+    schon jemand anders den Betraum des Spielers geaendert hat. (Gleiches gilt
+    fuers Loeschen.) Bitte niemals den Inhalt der Property woanders speichern
+    und spaeter zurueckschreiben.
+
+    Eine dauerhafte Aenderung des Betraums des Spielers muss mit dem EM
+    Rassen und dem EM Gilden abgestimmt werden.
+
+SIEHE AUCH
+    QueryPrayRoom(), SetDefaultPrayRoom()
+
+LETZTE AeNDERUNG:
+21.05.2013, Zesstra
+
diff --git a/doc/props/P_PREFERED_ENEMY b/doc/props/P_PREFERED_ENEMY
new file mode 100644
index 0000000..eed58e6
--- /dev/null
+++ b/doc/props/P_PREFERED_ENEMY
@@ -0,0 +1,26 @@
+NAME:
+	P_PREFERED_ENEMY		"pref_enemy"
+
+DEFINIERT IN:
+	/sys/living/combat.h
+
+BESCHREIBUNG:
+	Diese Property enthaelt ein Array mit folgenden Eintraegen:
+	  Eintrag 1:      Integerwert zwischen 0 und 100, welcher die
+	                  Wahrscheinlichkeit dafuer angibt, dass ein
+	                  Lebewesen bevorzugt bei einem Angriff gewaehlt
+	                  werden soll.
+	  Eintraege ab 2: Lebewesen, aus welchen per Zufall eines
+	                  ausgewaehlt wird, welches beim aktuellen Angriff
+	                  bevorzugt wird.
+	Es ist zu beachten, dass solch ein bevorzugtes Opfer natuerlich auch
+	wirklich Gegner sein muss und auch im selben Raum zu stehen hat, wie
+	der Angreifer. Ist dies nicht der Fall, wird dann doch irgendein
+	anderer Gegner aus diesem Raum genommen.
+
+SIEHE AUCH:
+	QueryPreferedEnemy(), IsEnemy(), SelectEnemy(), Attack(),
+	/std/living/combat.c, /std/living/life.c
+
+----------------------------------------------------------------------------
+Last modified: Wed May 26 16:44:38 1999 by Patryn
diff --git a/doc/props/P_PRESAY b/doc/props/P_PRESAY
new file mode 100644
index 0000000..c5ec2d2
--- /dev/null
+++ b/doc/props/P_PRESAY
@@ -0,0 +1,9 @@
+NAME:
+    P_PRESAY                      "presay"                      
+
+DEFINIERT IN:
+    /sys/player/description.h
+
+BESCHREIBUNG:
+     Presay des Spielers. Erscheint vor dem Namen in Kurz/Langbeschreibung.
+     Erscheint auch in name(), also in sag, ruf, teile mit usw.
diff --git a/doc/props/P_PREVENT_PILE b/doc/props/P_PREVENT_PILE
new file mode 100644
index 0000000..39ddf14
--- /dev/null
+++ b/doc/props/P_PREVENT_PILE
@@ -0,0 +1,22 @@
+NAME:
+    P_PREVENT_PILE                   "prevent_pile"
+
+DEFINIERT IN:
+    /sys/container/properties.h
+
+BESCHREIBUNG:
+    Wenn in einem Raum diese Property gesetzt ist, endet das Verwesen einer
+    Leiche damit, dass ihr Inventar in dem Raum verteilt wird. Ist diese
+    Property nicht gesetzt, entsteht ein "Haufen", der das Inventar
+    enthaelt.
+
+    Diese Property sollte nur in Ausnahmefaellen benutzt werden!
+
+    Diese Property ist vor allem fuer "Store-Rooms" gedacht, in denen die
+    Magier die Leiche eines Spieler ablegen und in denen nachher die
+    gesammelten Sachen von einer anderen Stelle aus gesucht werden. In
+    diesem Fall wuerden Spieler sonst die Moeglichkeit haben, einen Haufen
+    als Ganzes zu bekommen, das soll aber *NIE* passieren.
+
+----------------------------------------------------------------------------
+Last modified: Tue May 15 13:56:18 CEST 2007 by Rumata
diff --git a/doc/props/P_PRE_INFO b/doc/props/P_PRE_INFO
new file mode 100644
index 0000000..48f1d9e
--- /dev/null
+++ b/doc/props/P_PRE_INFO
@@ -0,0 +1,55 @@
+NAME:
+        P_PRE_INFO                        "npc_pre_info"
+
+DEFINIERT IN:
+        /sys/npc.h
+
+BESCHREIBUNG:
+        Ist die Property in einem NPC definiert, so wird ihr Ergebnis
+        ausgewertet, bevor eine Frage an das Infosystem uebergeben wird.
+        
+        Moegliche Werte:
+        - numerischer Wert ungleich 0
+          => der NPC gibt _keinerlei_ Antwort, die Frage fuehrt sozusagen
+             ins Leere
+
+        - Stringwert
+          => wird als Rueckgabe an den Fragenden ausgegeben, umstehende 
+             Personen bekommen den Text:
+            "XY ist nicht gewillt, Spieler YZ zu antworten".
+            Der Fragende selbst bekommt bei angegebenem Stringwert:
+            "XY " + Stringwert.
+
+        - Closure
+          => die Antwort bzw. Reaktion des NPCs obliegt ganz der 
+             angegebenen Closure. Diese muss dabei einen String oder 
+             Ganzzahlen-Wert zurueckgeben
+
+BEISPIEL:
+        Ein NPC der manchmal herumrennt, um z.B. eine Aufgabe zu verrichten,
+        koennte so lange Chats abschalten, z.B.
+
+          SetProp(P_CHAT_CHANCE,0); // NPC latscht los
+        
+        Und eine Weile spaeter:
+        
+          SetProp(P_CHAT_CHANCE,5); // NPC ruht wieder, quasselt rum
+        
+        Waehrend des Herumlaufens, also wenn er nicht automatisch schwatzt,
+        soll er auch keinerlei Fragen beantworten:
+          
+          Set(P_PRE_INFO, function mixed () {
+            return (QueryProp(P_CHAT_CHANCE) ? 0 : 
+              "hat gerade keine Zeit fuer Dich."); 
+            }, F_QUERY_METHOD);
+
+HINWEISE:
+        Bitte beachten, dass der interne Name der Property "npc_pre_info" 
+        ist und somit nur das Ueberschreiben von _query_npc_pre_info() 
+        funktioniert. 
+
+SIEHE AUCH:
+        AddInfo(), /std/npc/info.c
+
+----------------------------------------------------------------------------
+Last modified: 01.03.2016 by Arathorn
diff --git a/doc/props/P_PROMPT b/doc/props/P_PROMPT
new file mode 100644
index 0000000..b380215
--- /dev/null
+++ b/doc/props/P_PROMPT
@@ -0,0 +1,8 @@
+NAME:
+    P_PROMPT                      "prompt"                      
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Das Prompt (Nur fuer Magier).
diff --git a/doc/props/P_PUB_NOT_ON_MENU b/doc/props/P_PUB_NOT_ON_MENU
new file mode 100644
index 0000000..07029b0
--- /dev/null
+++ b/doc/props/P_PUB_NOT_ON_MENU
@@ -0,0 +1,21 @@
+NAME:
+	P_PUB_NOT_ON_MENU			"pub_not_on_menu"
+
+DEFINIERT IN:
+	/sys/pub.h
+
+BESCHREIBUNG:
+        In diese Property kann man einen String schreiben, der ausgegeben
+        wird, wenn der Spieler etwas bestellt, was es in der Kneipe nicht
+        gibt.
+
+BEMERKUNGEN:
+        Die Standardmeldung ist:
+        "Tut mir leid, das fuehren wir nicht! Wir sind ein anstaendiges
+         Lokal!\n"
+
+SIEHE AUCH:
+	/std/room/pub.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Mar 04 22:46:00 2000 by Paracelsus
diff --git a/doc/props/P_PUB_NO_KEEPER b/doc/props/P_PUB_NO_KEEPER
new file mode 100644
index 0000000..8f4c26e
--- /dev/null
+++ b/doc/props/P_PUB_NO_KEEPER
@@ -0,0 +1,19 @@
+NAME:
+	P_PUB_NO_KEEPER				"pub_no_keeper"
+
+DEFINIERT IN:
+	/sys/pub.h
+
+BESCHREIBUNG:
+        In diese Property kann man einen String schreiben, der ausgegeben
+        wird, wenn der in P_KEEPER eingetragene NPC nicht anwesend ist.
+
+BEMERKUNGEN:
+        Die Standardmeldung ist:
+        "Es ist niemand anwesend, der Dich bedienen koennte.\n"
+
+SIEHE AUCH:
+	/std/room/pub.c
+
+----------------------------------------------------------------------------
+Last modified: Son Apr 11 19:28:00 2010 by Caldra
diff --git a/doc/props/P_PUB_NO_MONEY b/doc/props/P_PUB_NO_MONEY
new file mode 100644
index 0000000..9ff293a
--- /dev/null
+++ b/doc/props/P_PUB_NO_MONEY
@@ -0,0 +1,21 @@
+NAME:
+	P_PUB_NO_MONEY				"pub_no_money"
+
+DEFINIERT IN:
+	/sys/pub.h
+
+BESCHREIBUNG:
+        In diese Property kann man einen String schreiben, der ausgegeben
+        wird, wenn der Spieler nicht ueber genug Geld verfuegt, um das
+        gewuenschte Gericht zu bezahlen.
+        Fuer den Preis kann man ein %d als Platzhalter einfuegen.
+
+BEMERKUNGEN:
+        Die Standardmeldung ist:
+        "Das kostet %d Goldstuecke, und Du hast nicht so viel!\n"
+
+SIEHE AUCH:
+	/std/room/pub.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Mar 04 22:48:00 2000 by Paracelsus
diff --git a/doc/props/P_PUB_UNAVAILABLE b/doc/props/P_PUB_UNAVAILABLE
new file mode 100644
index 0000000..13aaa4f
--- /dev/null
+++ b/doc/props/P_PUB_UNAVAILABLE
@@ -0,0 +1,20 @@
+NAME:
+	P_PUB_UNAVAILABLE			"pub_unavailable"
+
+DEFINIERT IN:
+	/sys/pub.h
+
+BESCHREIBUNG:
+        In diese Property kann man einen String schreiben, der ausgegeben
+        wird, wenn in einer Kneipe ein Getraenk oder eine Speise nicht mehr
+        vorraetig ist.
+
+BEMERKUNGEN:
+        Die Standardmeldung ist:
+        "Davon ist leider nichts mehr da.\n"
+
+SIEHE AUCH:
+	/std/room/pub.c
+
+----------------------------------------------------------------------------
+Last modified: Sat Mar 04 22:44:00 2000 by Paracelsus
diff --git a/doc/props/P_PURSUERS b/doc/props/P_PURSUERS
new file mode 100644
index 0000000..c35bfe2
--- /dev/null
+++ b/doc/props/P_PURSUERS
@@ -0,0 +1,14 @@
+NAME:
+    P_PURSUERS                    "pursuers"                    
+
+DEFINIERT IN:
+    /sys/living/moving.h
+
+BESCHREIBUNG:
+     Enthaelt Verfolger - nicht von Hand manipulieren!
+
+SIEHE AUCH:
+     AddPursuer(L), RemovePursuer(L)
+
+-----------------------------------------------------------------------------
+16.06.2016, Arathorn
diff --git a/doc/props/P_PUT_MSG b/doc/props/P_PUT_MSG
new file mode 100644
index 0000000..5f6caef
--- /dev/null
+++ b/doc/props/P_PUT_MSG
@@ -0,0 +1,62 @@
+P_PUT_MSG
+NAME:
+     P_PUT_MSG				"put_message"
+
+DEFINIERT IN:
+     /sys/living/put_and_get.h
+
+BESCHREIBUNG:
+
+     Mit P_PUT_MSG kann man die Meldung, die man beim Hineinstecken eines
+     Objektes in einen Container bekommt, modifizieren.
+
+     Folgende Werte sind moeglich:
+
+     o 0
+       Es wird eine Standardmeldung ausgegeben. Dies ist Voreinstellung.
+
+     o NO_PNG_MSG	== -1
+       Es wird keinerlei Meldung ausgegeben
+
+     o Ein Array aus Strings
+       Der erste String wird an den Spieler ausgegeben, der zweite
+       (optionale) an den Raum.
+
+       Die Strings werden durch die Funktion replace_personal() geparst.
+	Objekt1 - Spieler
+        Objekt2 - das Objekt, das irgendwohin gesteckt wird
+	Objekt3 - der Container
+
+       Wird der zweite String nicht angegeben, erfolgt keine Meldung an den
+       Raum.
+
+BEISPIEL:
+     void create() {
+      ...
+      SetProp( P_SHORT, "Etwas Sand" );
+      SetProp( P_LONG, break_string(
+       "Ein wenig magischer Sand. Sehr feinkruemelig.",78 ));
+
+      SetProp( P_NAME, "Sand" );
+      AddId( ({"sand"}) );
+      SetProp( P_GENDER, MALE );
+
+      SetProp( P_PUT_MSG, ({
+       "Du laesst @WEN2 in @WENU3 rieseln.",
+       "@WER1 laesst @WEN2 in @WENU3 rieseln."}));
+      ...
+     }
+
+     Das ganze fuehrt bei Ugars "stecke sand in paket" zu folgenden
+     Meldungen:
+
+     Ugar: "Du laesst den Sand in ein Paket rieseln."
+     Raum: "Ugar laesst den Sand in ein Paket rieseln."
+
+SIEHE AUCH:
+     Aehnliches: P_PICK_MSG, P_DROP_MSG, P_GIVE_MSG, P_WEAR_MSG, P_WIELD_MSG
+     Fehler:     P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_TOO_MANY_MSG,
+                 P_NOINSERT_MSG, P_NOLEAVE_MSG, P_NODROP, P_NOGET 
+     Sonstiges:  replace_personal(E), put_obj(L), /std/living/put_and_get.c
+
+14. Maerz 2004 Gloinson
diff --git a/doc/props/P_QP b/doc/props/P_QP
new file mode 100644
index 0000000..08fb5a4
--- /dev/null
+++ b/doc/props/P_QP
@@ -0,0 +1,13 @@
+NAME:
+    P_QP                          "questpoints"                 
+
+DEFINIERT IN:
+    /sys/player/quest.h
+
+BESCHREIBUNG:
+     Anzahl der Questpunkte, die ein Spieler hat.
+
+HINWEIS:
+     Nur Abfragen der Property mit QueryProp() liefert den korrekten Wert,
+     da eine Quermethode fuer die Auslieferung der Daten sorgt. Query()
+     oder gar QueryProperties() enthalten u.U. einen veralteten Wert.
diff --git a/doc/props/P_QUALITY b/doc/props/P_QUALITY
new file mode 100644
index 0000000..3a4118c
--- /dev/null
+++ b/doc/props/P_QUALITY
@@ -0,0 +1,38 @@
+P_QUALITY
+
+NAME:
+     P_QUALITY "quality"
+
+DEFINIERT IN:
+     <combat.h>
+
+BESCHREIBUNG:
+     Ruestungen und Waffen koennen im Eifer des Gefechts beschaedigt werden.
+     Setzt man die Property P_QUALITY auf einen Wert n (n>0), so wird
+     eine Waffe (Ruestung) bei jedem n-ten Schlag (Treffer) beschaedigt,
+     d.h. P_WC (P_AC) wird um 1 erniedrigt und P_DAMAGED um 1 erhoeht.
+
+BEISPIEL:
+     inherit "/std/weapon";
+
+     ...
+     #include <combat.h>
+
+     create()
+     {
+       ...
+       SetProp(P_QUALITY,200);
+       ...
+     }
+
+     Diese Waffe wuerde bei jedem 200. Schlag etwas beschaedigt.
+
+BEMERKUNG:
+     Defaultmaessig ist P_QUALITY auf 0 gesetzt, d.h. die entspr.
+     Waffe/Ruestung wird nicht beschaedigt.
+
+SIEHE AUCH:
+     /std/armour.c, /std/weapon.c, TakeFlaw(), QueryFlaw(), Damage()
+
+----------------------------------------------------------------------------
+Last modified: Thu May 22 10:42:39 1997 by Paracelsus
diff --git a/doc/props/P_QUESTS b/doc/props/P_QUESTS
new file mode 100644
index 0000000..446ea90
--- /dev/null
+++ b/doc/props/P_QUESTS
@@ -0,0 +1,8 @@
+NAME:
+    P_QUESTS                      "quests"                      
+
+DEFINIERT IN:
+    /sys/player/quest.h
+
+BESCHREIBUNG:
+     Liste der geloesten Quests.
diff --git a/doc/props/P_QUEST_ITEM b/doc/props/P_QUEST_ITEM
new file mode 100644
index 0000000..e4eebb5
--- /dev/null
+++ b/doc/props/P_QUEST_ITEM
@@ -0,0 +1,46 @@
+NAME:
+	P_QUEST_ITEM				"quest_item" 
+
+DEFINIERT IN:
+	/sys/quest_items.h
+
+BESCHREIBUNG:
+        Diese Property gibt an, ob es sich bei dem Objekt um ein Quest-
+	relevantes Objekt handelt.
+	
+BEISPIEL:
+        Ein Schwert (Notung) koennte folgendermassen definiert sein:
+
+	create()
+	{
+	  ::create() ;
+	  SetProp(P_SHORT, "Notung das neidliche Schwert") ;
+	  SetProp(P_LONG, "Das aus seinen Truemmern neu geschmiedete Schwert " 
+	                  "Notung.\n");
+
+	  SetProp(P_NAME, "Notung");
+	  SetProp(P_GENDER, NEUTER);
+	  SetProp(P_ARTICLE,0);
+	  AddId(({"notung","schwert","Notung", "\nNotung"}));
+	
+	  SetProp(P_WEAPON_TYPE, WT_SWORD);
+	  SetProp(P_DAM_TYPE, DT_BLUDGEON);
+
+	  SetProp(P_QUEST_ITEM,QI_OBJ);
+	  ...
+	}
+	    
+	Andere Magier koennen nun auf Notung Ruecksicht nehmen, und zum
+	Beispiel davon absehen, es bei einem NPC-Spell zu destructen.
+
+BEMERKUNGEN:
+        Alle questrelevanten Objekte sollten auf diese Weise markiert werden.
+	
+	Questrelevante Objekte anderer Magier sollten immer mit Vorsicht 
+	behandelt werden.
+
+SIEHE AUCH:
+	"/sys/quest_items.h"
+
+----------------------------------------------------------------------------
+Last modified: Thu Jul 10 07:08:32 2003 by Vanion
diff --git a/doc/props/P_RACE b/doc/props/P_RACE
new file mode 100644
index 0000000..7ed77cd
--- /dev/null
+++ b/doc/props/P_RACE
@@ -0,0 +1,30 @@
+NAME:
+	P_RACE				"race"
+
+DEFINIERT IN:
+	/sys/living/description.h
+
+BESCHREIBUNG:
+	Die Rasse eines Lebewesens kann ueber diese Property ermittelt bzw.
+	gesetzt werden. Es empfiehlt sich hierbei, Rassen nur in Form von
+	grossgeschriebenen Strings zu setzen. Leichen erhalten mittels
+	dieser Property automatisch die Rasse der Lebewesen, aus denen sie
+	hervorgegangen sind.
+	Der Sinn des Ganzen liegt darin, das Spiel differenzierter zu
+	gestalten und auf Rassenspezifika einzugehen. Zum Beispiel koennen
+	Elfen weniger Alkohol vertragen als Zwerge, was in '/std/pub'
+	beruecksichtigt wurde.
+
+BEISPIEL:
+	void create()
+	{ ::create();
+	  // Definitionen
+	  SetProp(P_RACE,"Ork");
+	  // weitere Definitionen
+	}
+
+SIEHE AUCH:
+	/std/npc.c, /std/pub.c
+
+----------------------------------------------------------------------------
+Last modified: Mon Sep 15 21:15:49 2003 by Vanion
diff --git a/doc/props/P_RACESTRING b/doc/props/P_RACESTRING
new file mode 100644
index 0000000..b75f46b
--- /dev/null
+++ b/doc/props/P_RACESTRING
@@ -0,0 +1,9 @@
+NAME:
+    P_RACESTRING                  "racestring"                  
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Gibt eine dem Geschlecht angepasste Beschreibung der Rasse zurueck
+     ("Zwerg" oder "Zwergin" etc.)
diff --git a/doc/props/P_RACE_DESCRIPTION b/doc/props/P_RACE_DESCRIPTION
new file mode 100644
index 0000000..5b2ebfb
--- /dev/null
+++ b/doc/props/P_RACE_DESCRIPTION
@@ -0,0 +1,8 @@
+NAME:
+    P_RACE_DESCRIPTION            "racedescr"                   
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Beschreibung der Vor/Nachteile einer Rasse.
diff --git a/doc/props/P_RANGE b/doc/props/P_RANGE
new file mode 100644
index 0000000..37a98b7
--- /dev/null
+++ b/doc/props/P_RANGE
@@ -0,0 +1,26 @@
+P_RANGE
+
+NAME:
+    P_RANGE     "range"
+
+DEFINIERT IN:
+    <combat.h>
+
+BESCHREIBUNG:
+    Legt die Reichweite einer Schusswaffe fest. Ist ein Schuetze in einem
+    Raum mit gueltigem P_TARGET_AREA (andere Raum) oder environment() und
+    ist fuer diesen Raum P_SHOOTING_AREA festgelegt, dann kann er mit seiner
+    Schusswaffe in diesen anderen Raum schießen, wenn die P_RANGE groesser
+    als P_SHOOTING_AREA ist.
+
+BEISPIELE:
+    // Langbogen mit 100 Reichweite
+    SetProp(P_RANGE, 100);
+
+SIEHE AUCH:
+    Generell:  P_AMMUNITION, P_SHOOTING_WC, P_STRETCH_TIME
+    Methoden:  FindRangedTarget(L), shoot_dam(L), cmd_shoot(L)
+    Gebiet:    P_SHOOTING_AREA, P_TARGET_AREA
+    Sonstiges: fernwaffen
+
+29.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_READ_DETAILS b/doc/props/P_READ_DETAILS
new file mode 100644
index 0000000..035a2cc
--- /dev/null
+++ b/doc/props/P_READ_DETAILS
@@ -0,0 +1,21 @@
+NAME:
+    P_READ_DETAILS                "read_details"                
+
+DEFINIERT IN:
+    /sys/thing/description.h
+
+BESCHREIBUNG:
+    Mapping mit den Daten der Details, die durch Lesen ermittelt werden
+    koennen.
+
+BEMERKUNGEN:
+    Bitte nur mit den entsprechenden Methoden veraendern!
+
+SIEHE AUCH:
+    Setzen:    AddReadDetail()
+    Loeschen:  RemoveReadDetail()
+    Aehnlich:  AddDetail(), P_DETAILS
+    Veraltet:  P_READ_MSG
+    Sonstiges: GetDetail(), break_string()
+
+27. Jan 2013 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_READ_NEWS b/doc/props/P_READ_NEWS
new file mode 100644
index 0000000..b64a252
--- /dev/null
+++ b/doc/props/P_READ_NEWS
@@ -0,0 +1,8 @@
+NAME:
+    P_READ_NEWS                   "read_news"                   
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Welche Artikel bereits gelesen wurde (frueher: in der MPA)
diff --git a/doc/props/P_REAL_RACE b/doc/props/P_REAL_RACE
new file mode 100644
index 0000000..88279a6
--- /dev/null
+++ b/doc/props/P_REAL_RACE
@@ -0,0 +1,72 @@
+NAME:
+	P_REAL_RACE				"real_race"
+
+DEFINIERT IN:
+	/sys/living/description.h
+
+BESCHREIBUNG:
+        Diese Property enthaelt die Rasse des Livings. Sie darf nicht durch 
+	Shadows ueberschrieben werden.
+	
+	Wirklich interessant ist sie, wenn ein Spieler sich tarnt. Dort kann
+	man mit dieser Property trotz Tarnung feststellen, welche Rasse der
+	Spieler hat.
+
+	Bei NPC enthaelt sie den gleichen Wert wie P_RACE. Wenn P_REAL_RACE
+	allerdings gesetzt wird, kann man damit einen getarnten NPC simu-
+	lieren, da dann P_RACE und P_REAL_RACE voneinander abweichen.
+	
+BEISPIEL:
+        Ein Zwerg mag Zwergenbrot, fuer Elfen ist es giftig. Selbst wenn der
+	Elf sich als Zwerg tarnt, wird ihm durch lembas sicher uebel werden:
+
+        int futter(string arg)
+        {
+          notify_fail("Was willst Du essen?\n");
+          if(!arg || !id(arg)) return 0;
+
+          notify_fail("Du kannst nichts mehr essen.\n");
+          if(!this_player()->eat_food(55)) return 0;
+
+          write("Du isst ein Stueck Zwegenbrot. Du versuchst es zumindest!\n");
+          say(sprintf("%s beisst in ein Stueck Zwergenbrot. Zahnschmerz!!!\n",
+              this_player()->Name()));
+
+
+          switch( this_player()->QueryProp(P_REAL_RACE) )
+          {
+          case "Zwerg":
+	    if ((this_player()->QueryProp(P_RACE))!="Zwerg")
+	      write("Zur Tarnung spuckst Du etwas von dem Brot aus!\n"); 
+            this_player()->buffer_hp(100,10);
+            this_player()->buffer_sp(100,10);
+            break;
+
+          case "Elf":
+	    write("Das Zwergenbrot brennt wie Feuer auf Deiner Zunge!");
+	    // Getarnt?
+	    if ((this_player()->QueryProp(P_RACE))!="Elf")
+	      write(" Deine Tarnung nutzt Dir da wenig.\n"
+            else write("\n");
+            this_player()->restore_spell_points(-100);
+            this_player()->do_damage(100,this_object());
+            break;
+
+          default:
+	    write("Du bekommst nur wenig davon herunter..\n");
+            this_player()->buffer_hp(10,1);
+            this_player()->buffer_sp(10,2);
+            break;
+          }
+  
+          remove();
+  
+          return 1;
+        }
+
+	
+SIEHE AUCH:
+	/std/living/description.c, /sys/living/description.h, P_RACE
+
+----------------------------------------------------------------------------
+Last modified: Mon Sep 15 21:15:49 2003 by Vanion
diff --git a/doc/props/P_REFERENCE_OBJECT b/doc/props/P_REFERENCE_OBJECT
new file mode 100644
index 0000000..e2a6405
--- /dev/null
+++ b/doc/props/P_REFERENCE_OBJECT
@@ -0,0 +1,27 @@
+P_REFERENCE_OBJECT
+NAME:
+     P_REFERENCE_OBJECT            "reference_object"
+
+DEFINIERT IN:
+     /sys/player/description.h
+
+BESCHREIBUNG:
+     In dieser Propertie wird das aktuelle Bezugsobjekt eines Spielers 
+     gespeichert. Untersucht der Spieler ein Monster, so ist dies das 
+     Monsterobjekt, untersucht der Spieler sich selber, ist es das 
+     Spielerobjekt.
+
+     Der Inhalt dieser Propertie besteht also immer aus dem zuletzt 
+     betrachteten Objekt. Sei es ein Raum, eine Ruestung, ein Monster oder 
+     was auch immer. Bewegungsbefehle und andere Kommandos werden nicht 
+     beruecksichtigt.
+
+     Einzig wenn der Spieler 'schau' tippt, wird der Inhalt der Propertie 
+     geloescht und betraegt 0.
+
+SIEHE AUCH:
+     Sonstiges:		P_INT_LONG, P_LONG, P_SHORT
+			int_long(), long(), short(), make_invlist()
+
+----------------------------------------------------------------------------
+Letzte Aenderung: 29.06.02, 23:50:00 h, von Tilly
diff --git a/doc/props/P_REJECT b/doc/props/P_REJECT
new file mode 100644
index 0000000..4af07f3
--- /dev/null
+++ b/doc/props/P_REJECT
@@ -0,0 +1,51 @@
+NAME:
+	P_REJECT			"reject"
+
+DEFINIERT IN:
+	/sys/properties.h
+
+BESCHREIBUNG:
+	Diese Property zeigt standardmaessig nur in NPCs eine Wirkung. Mit
+	ihr laesst sich sehr einfach einstellen, wie sich ein solcher NPC
+	gegenueber Gegenstaenden verhalten soll, welche ihm zugesteckt
+	werden. Hierbei besteht die Property aus 2 Elementen, welche
+	bestimmt, was der NPC mit Dingen tuen soll, die ihm gegeben werden.
+	Standardmaessig behaelt der NPC die Sachen einfach.
+	Folgende Moeglichkeiten gibt es ausserdem:
+	  1. Arrayelement: Art der Handlung. (aus "/sys/moving.h")
+	    REJECT_GIVE: Der NPC gibt das Objekt zurueck.
+	    REJECT_DROP: Der NPC laesst das Objekt fallen.
+	    REJECT_KEEP: Der NPC behaelt das Objekt doch.
+	    REJECT_LIGHT_MODIFIER: Der NPC nimmt keine Gegenstaende an, die
+	      sein Lichtlevel veraendern und damit Einfluss auf sein
+	      Kampfverhalten haben koennten.
+	  2. Arrayelement: Meldung, mit welcher der NPC die Handlung
+	                   kommentiert.
+	    Der Meldung wird nichts automatisch vorangestellt und ein
+	    abschliessender Zeilenumbruch ist ebenfalls selbstaendig
+	    vorzunehmen. Mit einem Leerstring ist somit auch gar keine
+	    Rueckmeldung moeglich.
+
+BEISPIEL:
+	Der NPC schmeisst alle ihm gegebenen Gegenstaende einfach weg:
+	  void create()
+	  { ::create();
+	    ...
+	    SetProp(P_REJECT,({REJECT_GIVE,
+	    Name(WER)+" murmelt: Was soll ich denn damit?!\n"}));
+	    ...
+	  }
+	Manchmal ist das recht nuetzlich, z.B. kann man so eigentlich schwer
+	zu toetende NPCs dagegen schuetzen, dass man ihnen angezuendetes
+	Dynamit oder aehnliches ueberreicht.
+
+BEMERKUNGEN:
+	Innerhalb von NPCs ist die Funktion give_notify() fuer die
+	automatische Auswertung dieser Property verantwortlich; das sollte
+	man insbesondere beim Ueberschreiben dieser Funktion beachten!
+
+SIEHE AUCH:
+	give_notify(), /std/npc/put_and_get.c
+
+-----------------------------------------------------------------------------
+Last modified: Mon Apr 23 16:54:07 2001 by Patryn
diff --git a/doc/props/P_REMOVE_FUNC b/doc/props/P_REMOVE_FUNC
new file mode 100644
index 0000000..2d431fa
--- /dev/null
+++ b/doc/props/P_REMOVE_FUNC
@@ -0,0 +1,25 @@
+P_REMOVE_FUNC
+
+NAME:
+     P_REMOVE_FUNC "remove_func"
+
+DEFINIERT IN:
+     <armour.h>
+
+BESCHREIBUNG:
+     Falls ein Objekt eine RemoveFunc() fuer die Ruestung oder Kleidung 
+     definiert, so muss dieses Objekt in dieser Property eingetragen sein.
+
+     Die Auswertung dieser Property erfolgt im Laufe des DoUnwear() in
+     der nicht-oeffentlichen Funktionen _check_unwear_restrictions().
+
+BEISPIELE:
+     Siehe das Beispiel zu RemoveFunc()
+
+SIEHE AUCH:
+     /std/armour.c, /std/clothing.c, clothing, armours
+     RemoveFunc()
+
+
+Letzte Aenderung:
+15.02.2009, Zesstra
\ No newline at end of file
diff --git a/doc/props/P_REMOVE_MSG b/doc/props/P_REMOVE_MSG
new file mode 100644
index 0000000..9eb1d8d
--- /dev/null
+++ b/doc/props/P_REMOVE_MSG
@@ -0,0 +1,28 @@
+NAME:
+     P_REMOVE_MSG                  "std_food_remove_msg"
+
+DEFINIERT IN:
+     <sys/food.h>
+
+BESCHREIBUNG:
+     Meldung, wenn eine verdorbene Speise gerade vernichtet wird.
+     Diese Meldung erscheint nur, wenn in P_DESTROY_BAD ein positiver
+     Integer-Wert gesetzt ist.
+     Befindet sich die Speise in einem Spieler, geht die Meldung an genau
+     diesen, liegt die Speise im Raum, geht die Meldung an alle anwesenden
+     Spieler.
+     
+BEMERKUNGEN:
+     Diese Meldung wird von replace_personal mit den Argumenten:
+     1. Speise
+     2. Konsument
+     verarbeitet, kann als entsprechende Platzhalter enthalten
+     
+DEFAULT:
+     "@WER1 zerfaellt zu Staub."
+
+SIEHE AUCH:
+     P_DESTROY_BAD, wiz/food, replace_personal
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_RESET_LIFETIME b/doc/props/P_RESET_LIFETIME
new file mode 100644
index 0000000..378cf0c
--- /dev/null
+++ b/doc/props/P_RESET_LIFETIME
@@ -0,0 +1,31 @@
+NAME:

+     P_RESET_LIFETIME              "std_food_lifetime_reset"

+

+DEFINIERT IN:

+     /sys/food.h

+

+BESCHREIBUNG:

+     Zeit in Resets, die die Speise haltbar ist.

+     Jeder einzelne Reset wird in seiner Laenge zufaellig festgelegt und

+     zu einer Gesamtanzahl von Sekunden zusammengefasst. Diese Zeit in

+     Sekunden wird dann in P_LIFETIME gespeichert.

+     Nach dieser Zeit wird diese Speise schlecht und je nach Konfiguration

+     der Speise eventuell zerstoert. Sichergestellt wird dies durch den

+     Aufruf von reset() nach dieser Anzahl "Resets".

+     Moechte man eine Speise haben, die niemals verdirbt

+     (genehmigungspflichtig!), nutzt man die Property P_NO_BAD

+     

+BEMERKUNGEN:

+     Sobald der Countdown zum Schlechtwerden der Speise laeuft, also ein

+     Spieler damit in Beruehrung kam, zeigt SetProp auf diese Property keine

+     Wirkung mehr.

+

+DEFAULT:

+     Ohne Setzen von P_LIFETIME ,P_RESET_LIFETIME und P_NO_BAD verdirbt die

+     Speise nach einem Reset, also zwischen 30 und 60 Minuten

+

+SIEHE AUCH:

+     wiz/food, P_LIFETIME, P_NO_BAD

+

+------------------------------------------------------------------------------

+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_RESISTANCE b/doc/props/P_RESISTANCE
new file mode 100644
index 0000000..ff3de74
--- /dev/null
+++ b/doc/props/P_RESISTANCE
@@ -0,0 +1,37 @@
+P_RESISTANCE
+NAME:
+     P_RESISTANCE                  "resistance"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+WICHTIG:
+     DIESE PROPERTY IST VERALTET! BITTE P_RESISTANCE_STRENGTHS
+     VERWENDEN! AUCH FUNKTIONIERT Set() NICHT WIE ES SOLLTE.
+
+BESCHREIBUNG:
+     Hiermit koennen die Resistenzen eines Lebewesens sehr einfach gesetzt
+     werden. Es kann ein Array mit Schadensarten gesetzt werden, jeder
+     Eintrag eines Schadens verdoppelt die Resistenz gegen diesen.
+
+BEMERKUNGEN:
+     - P_RESISTANCE_STRENGTHS spiegelt diese Eintraege hier wieder
+     - um genauere Werte anzugeben einen AddResistanceModifier() oder
+       P_RESISTANCE_STRENGTHS benutzen.
+     - P_RESISTANCE kann und wird nicht aus P_RESISTANCE_STRENGTHS
+       upgedatet
+
+BEISPIELE:
+     // ein NPC mit halbierter Feuerempfindlichkeit und
+     // geviertelter Windempfindlichkeit
+     SetProp(P_RESISTANCE, ({DT_FIRE, DT_AIR, DT_AIR}));
+
+SIEHE AUCH:
+     simple Resistenz:	P_RESISTANCE
+     Modifikatoren:	AddResistanceModifier, RemoveResistanceModifier(),
+			P_RESISTANCE_MODIFIER
+     Hauptmapping:	P_RESISTANCE_STRENGTHS
+     Berechnung:	CheckResistance(), UpdateResistanceStrengths()
+     anderes:		balance, /std/armour/combat.c, /std/living/combat.c
+
+1.Dez 2004, Gloinson
diff --git a/doc/props/P_RESISTANCE_MODIFIER b/doc/props/P_RESISTANCE_MODIFIER
new file mode 100644
index 0000000..0a0538e
--- /dev/null
+++ b/doc/props/P_RESISTANCE_MODIFIER
@@ -0,0 +1,26 @@
+NAME:
+     P_RESISTANCE_MODIFIER             "rstr:mod"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+     Hier werden die Resistenzmodifikatoren in einem Mapping abgespeichert.
+
+     Format:
+
+     (["me":<Aufaddition aller Resistenz/Empfindlichkeitsmodifikationen>;0,
+       "<Objektname>#<Schluessel>":<Resistenzmapping>;<Objekreferenz>,
+       ...])
+
+BEMERKUNGEN:
+     Nur ueber AddResistanceModifier(), RemoveResistanceModifier() aendern!
+
+SIEHE AUCH:
+     Modifikatoren:	AddResistanceModifier, RemoveResistanceModifier()
+     simple Resistenz:	P_RESISTANCE, P_VULNERABILITY
+     Hauptmapping:	P_RESISTANCE_STRENGTHS
+     Berechnung:	CheckResistance(), UpdateResistanceStrengths()
+     anderes:		balance, /std/armour/combat.c, /std/living/combat.c
+
+29.Apr 2002, Gloinson@MG
diff --git a/doc/props/P_RESISTANCE_STRENGTHS b/doc/props/P_RESISTANCE_STRENGTHS
new file mode 100644
index 0000000..ed24d2d
--- /dev/null
+++ b/doc/props/P_RESISTANCE_STRENGTHS
@@ -0,0 +1,92 @@
+NAME:
+     P_RESISTANCE_STRENGTHS     "resistance_strengths"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+BESCHREIBUNG:
+     Lebewesen:
+
+     Mapping mit Schadensarten, gegen die das Lebewesen resistent oder
+     anfaellig ist. Durch eine _query_method werden alle existierenden
+     Resistenzen hier zusammengefasst.
+
+     Die Staerke der Resistenz oder Anfaelligkeit wird numerisch aus-
+     gedrueckt:
+     - Resistenzen gehen bis von 0 bis -1.0 (absolute Resistenz)
+       - -0.5 == halbierter Schaden, -0.75 == geviertelter Schaden
+       -> in % des "aufgehaltenen" Schadens interpretierbar
+     - Empfindlichkeiten gehen von 0 bis MAX_INT
+       -  1.0 == verdoppelter Schaden, 3.0 == vervierfachter Schaden
+       -> als Faktor (x+1.0) interpretierbar
+
+     Ruestungen:
+
+     Mapping mit Prozentwerten der Maximalwerte fuer Ruestungen des
+     entsprechenden Typs. Dabei sind positive Werte Resistenzen und
+     negative Empfindlichkeiten. Dabei duerfen die Prozentwerte nur
+     im Bereich von +100 bis -800 (-1000 ?!) liegen.
+
+     Bei Ruestungen ist es damit unnoetig, Resistenzen mittels
+     AddResistanceModifier() im Traeger zu setzen, da dies bereits
+     in /std/armour automatisch gemacht wird. Der Schluessel fuer
+     den Eintrag ist dabei P_ARMOUR_TYPE.
+
+     Die Maximalwerte sind derzeit:
+      AT_CLOAK, AT_RING, AT_AMULET: max 10% Resistenz
+      AT_SHIELD, AT_ARMOUR:  max 15% Resistenz
+      alle anderen:   max 5% Resistenz
+
+BEMERKUNGEN:
+     Ruestungen:
+     * die Property muss _nach_ P_ARMOUR_TYPE gesetzt werden (_set-Method)
+
+     Lebewesen:
+     * -1.0 bedeutet bereits absolute Resistenz, bei kleineren Werten werden
+       die anderen Schadensanteile im Kampf u.U. nicht mehr wie gewuenscht
+       bilanziert. Bitte daher drauf verzichten. ;-)
+     * Aenderungen an P_RESISTANCE und P_VULNERABILITY werden direkt in 
+       P_RESISTANCE_STRENGTHS gespeichert:
+       -> daher niemals im Nachhinein bei fremden NPCs P_RESISTANCE_STRENGTHS
+          manipulieren, dafuer gibt es AddResistanceModifier
+     * QueryProp(P_RESISTANCE_STRENGTHS) enthaelt die gesamten Resistenzen
+       P_RESISTANCE, P_VULNERABILITY, P_RESISTANCE_MODIFIER (_query-Method)
+
+     Die Werte in P_RESISTANCE_STRENGTHS sollten nur in Ausnahmefaellen oder
+     gut begruendet den Hoechstwert haben. Ein Eiswesen kann zwar sehr
+     resistent gegen Kaelteschaden sein, sollte aber zu gleichem Teil auch
+     anfaellig auf Feuerschaden sein.
+
+     Auf dieser Property liegt eine Querymethode, welche eine Kopie der
+     Daten zurueckliefert.
+
+BEISPIELE:
+     // ein Eistroll
+     SetProp(P_RESISTANCE_STRENGTHS,([DT_FIRE:0.5,DT_COLD:-0.5,
+                                      DT_MAGIC:0.1]));
+
+     Feuerangriffe werden mit 1.5 multipliziert, magische mit 1.1 und
+     der Schadenswert von Kaelteangriffen wird halbiert. Zum Beispiel
+     wuerde
+     Defend(100, ({DT_FIRE,DT_MAGIC}), ...)
+     einen Schaden von 130 statt den normalen 100 verursachen.
+
+
+     // eine Eisruestung
+     SetProp(P_RESISTANCE_STRENGTHS, ([DT_COLD:50, DT_FIRE:-100]));
+
+     Dieses Kettenhemd schuetzt nun mit 50% des Maximalwertes gegen
+     Kaelte (also 0.5*15%=7,5% Resistenz) und macht mit dem Maximal-
+     wert anfaellig gegen Feuer (1*15%=15% Empfindlichkeit).
+
+     ! der Code spricht zusaetzlich von
+       Empfindlichkeit=(Empfindlichkeit/4)*5 -> 15/4*5=18.75% !
+
+SIEHE AUCH:
+     simple Resistenz: P_RESISTANCE, P_VULNERABILITY
+     Modifikatoren: AddResistanceModifier, RemoveResistanceModifier(),
+     P_RESISTANCE_MODIFIER
+     Berechnung: CheckResistance(), UpdateResistanceStrengths()
+     anderes:  balance, /std/armour/combat.c, /std/living/combat.c
+
+6.Feb 2016 Gloinson
diff --git a/doc/props/P_RESTRICTIONS b/doc/props/P_RESTRICTIONS
new file mode 100644
index 0000000..34890ff
--- /dev/null
+++ b/doc/props/P_RESTRICTIONS
@@ -0,0 +1,140 @@
+NAME:
+    P_RESTRICTIONS                                "restrictions"
+
+DEFINIERT IN:
+    /sys/combat.h
+    (Die SR_*-Parameter sind in /sys/new_skills.h definiert.)
+
+BESCHREIBUNG:
+    Enthaelt ein mapping mit den zu pruefenden Einschraenkungen.
+
+    In dieser Property lassen sich Restriktionen setzen, die vor dem
+    Zuecken einer Waffe / Anziehen einer Ruestung oder Kleidung geprueft
+    werden und dies gegebenfalls verhindern, ohne gleich auf eine evtl.
+    vorhandene WieldFunc / WearFunc zuzugreifen.
+
+    Die Auswertung erfolgt ueber den Aufruf von check_restrictions()
+    in /std/restriction_checker.c
+
+    Folgende Keys werden in dem Mapping ausgewertet:
+
+    P_LEVEL
+      Mindeststufe, die das Lebewesen besitzen muss, um die Aktion
+      auszufuehren.
+    P_GUILD_LEVEL
+      Gildenlevel, das das Lebewesen mindestens erreicht haben muss, um die
+      Aktion auszufuehren.
+    SR_SEER
+      Ist gesetzt, wenn das Lebewesen Seher sein muss.
+      Auswertung nur fuer Interactives, NSC ignorieren das Flag.
+    P_XP
+      Mindestmenge an Erfahrungspunkten, die ein Lebewesen besitzen muss,
+      um die Aktion auszufuehren.
+    P_QP
+      Mindestmenge an Abenteuerpunkten, die das Lebewesen haben muss.
+    P_ALCOHOL
+      Menge an Alkohol, unter der der Alkoholspiegel des Lebewesen liegen
+      muss, um die Aktion noch ausfuehren zu koennen.
+    P_DRINK
+      Menge an Fluessigkeit, unter der der Fluessigkeitsspiegel des
+      Lebewesen liegen muss, um die Aktion noch ausfuehren zu koennen.
+    P_FOOD
+      Beinhaltet die Menge an Nahrung, unter der der Nahrungsspiegel des
+      Spielers liegen muss, um die Aktion noch ausfuehren zu koennen.
+    P_DEAF
+      Ist gesetzt, falls der Spieler nicht taub sein darf.
+    P_FROG
+      Ist gesetzt, falls der Spieler kein Frosch sein darf.
+    P_BLIND
+      Ist gesetzt, falls der Spieler nicht blind sein darf.
+      Achtung: das ist nicht gleichbedeutend mit dem Umstand, dass er evtl.
+      nichts mehr sehen kann. Auch andere Gruende (zum Beispiel Dunkelheit)
+      koennen bewirken, dass ein Spieler nichts mehr sieht.
+    A_INT, A_DEX, A_CON, A_STR
+      Jeweilige Mindesthoehe eines Attribut, um eine Aktion ausfuehren zu
+      koennen.
+    SR_BAD, SR_GOOD
+      Gibt an, wie [minimal] boese bzw. wie [maximal] gut ein Charakter sein
+      darf, um eine Aktion ausfuehren zu koennen.
+    SR_MIN_SIZE, SR_MAX_SIZE
+      Gibt die minimale, bzw. die maximale Groesse an, die ein Charakter
+      maximal haben darf, um eine Aktion ausfuehren zu koennen.
+    SR_FREE_HANDS
+      Gibt an, wieviele freie Haende ein Charakter fuer diese Aktion
+      besitzen muss.
+    SR_EXCLUDE_RACE
+      Mitglieder aller in dieser Liste aufgefuehrten Rassen koennen
+      diese Aktion nicht ausfuehren.
+    SR_INCLUDE_RACE
+      Mitglieder aller NICHT in dieser Liste aufgefuehrten Rassen koennen
+      diese Aktion nicht ausfuehren.
+    SM_RACE
+      Hier kann pro Rasse ein Mapping mit besonderen (nur) fuer diese Rasse
+      geltenden Einschraenkungen vorgenommen werden. Als Keys sind die
+      in dieser Manpage beschriebenen Keys erlaubt, wobei SM_RACE nicht
+      rekursiv ausgewertet wird.
+      Der Rassenname ist gross geschrieben und "*" steht fuer alle Rassen.
+    SR_EXCLUDE_GUILD
+    SR_INCLUDE_GUILD
+      Diese beiden Keys verhalten sich wie SR_*_RACE, nur dass hier Gilden
+      genannt werden.
+    SR_FUN
+      Hier kann eine Funktion in verschiedenen Formen zum Pruefen der
+      Restriktionen angegeben werden, siehe execute_anything().
+      Das kann nuetzlich sein, um andere Restriktionen zu pruefen,
+      wie das Bestehen von Miniquests oder andere Faehigkeiten/Flags.
+      Ist der Test nicht bestanden, gibt die Funktion einen String zurueck.
+    SR_PROP
+      Hier kann ein Mapping mit Properties und zugehoerigen Werten angegeben
+      werden, die jeweils auf Identitaet geprueft werden. Zusaetzlich sollte
+      eine Meldung angegeben werden, die als Fehlermeldung ausgegeben wird,
+      wenn der Spieler die Bedingung nicht erfuellt. Es sollte immer eine
+      passende Meldung fuer den Spieler eingebaut werden. Beispiel:
+      ([ SR_PROP: ([P_AUSGANG_ENTDECKT: 1; "Dein Schwert fluestert "
+          "veraergert: Ich werde Dir erst dann zu Diensten sein, wenn Du "
+          "Dich als wuerdig erwiesen hast!"]) ])
+      Aufgrund der Meldung wird empfohlen, SR_PROP nicht in Restriktionen 
+      einzusetzen, die massenweise in Savefiles landen (z.B. 
+      Spielersavefiles).
+    SR_QUEST
+      Hier kann ein String-Array mit den Namen (Keys) der Quest(s) angegeben
+      werden, die der Spieler bestanden haben muss, um die Aktion ausfuehren
+      zu koennen.
+    SR_MINIQUEST
+      Hier kann entweder ein String-Array mit den Ladenamen der vergebenden
+      Objekte oder ein Int-Array mit den Index-Nummern (IDs) der
+      Miniquest(s) (empfohlen!) angegeben werden, die der Spieler bestanden
+      haben muss, um die Aktion ausfuehren zu koennen.
+
+
+
+BEMERKUNGEN:
+    Diese Property eignet sich hervorragend dafuer, einige Grundbedingungen
+    fuer das Nutzen der Waffe / Ruestung / Kleidung zu stellen ohne gleich
+    eine Wield- oder WearFunc setzen und auswerten zu muessen.
+
+    Denkbar waere der Einsatz bei hochwertigen Waffen / Ruestungen / Kleidung,
+    z.B. aus der Para-Welt oder solchen, die sich nah am Limit der geltenden
+    Grenzwerte fuer P_WC / P_AC bewegen oder sogar (nach Genehmigung durch
+    die Balance) darueber.
+
+BEISPIEL:
+    Mindeststufe 25: SetProp(P_RESTRICTIONS,([P_LEVEL:25]));
+    Keine Menschen:  SetProp(P_RESTRICTIONS,([SR_EXCLUDE_RACE:({"Mensch"})]));
+    Alignment >499:  SetProp(P_RESTRICTIONS,([SR_GOOD:500]));
+
+    Komplexeres Beispiel
+
+    Quest "Diamond Club" bestanden, magiereigene Property P_AUSGANG_GEFUNDEN
+    muss gesetzt sein, Stufe 10, nicht taub, max. 45 Food:
+    SetProp(P_RESTRICTIONS, ([ P_LEVEL: 10, P_DEAF: 1, P_FOOD: 45,
+      SR_PROP: ([P_AUSGANG_GEFUNDEN:1]), SR_QUEST:({"Diamond Club"}) ]));
+
+SIEHE AUCH:
+    check_restrictions(L)
+    WieldFunc(L), WearFunc(L), RemoveFunc(L), UnwieldFunc(L),
+    P_WIELD_FUNC, P_WEAR_FUNC, P_REMOVE_FUNC, P_UNWIELD_FUNC
+    /std/armour/wear.c, /std/weapon/combat.c, clothing, armours, weapon
+
+LETZTE AeNDERUNG:
+03. Januar 2014, Arathorn
diff --git a/doc/props/P_ROOM_MSG b/doc/props/P_ROOM_MSG
new file mode 100644
index 0000000..c3324f2
--- /dev/null
+++ b/doc/props/P_ROOM_MSG
@@ -0,0 +1,20 @@
+NAME:
+    P_ROOM_MSG                    "room_msg"                    
+
+DEFINIERT IN:
+    /sys/room/description.h
+
+BESCHREIBUNG:
+     Liste mit Meldungen, die zufaellig im Raum ausgegeben werden.
+
+     Hier sind nur die Textmeldungen als String-Array gespeichert.
+
+ANMERKUNGEN:
+     Bitte AddRoomMessage() zum Hinzufuegen/Ueberschreiben benutzen!
+
+SIEHE AUCH:
+     LFuns:    AddRoomMessage()
+     Verwandt: tell_room(), ReceiveMsg()
+     Props:    P_FUNC_MSG, P_MSG_PROB
+
+2.Feb 2016 Gloinson
diff --git a/doc/props/P_ROOM_TYPE b/doc/props/P_ROOM_TYPE
new file mode 100644
index 0000000..d9dd746
--- /dev/null
+++ b/doc/props/P_ROOM_TYPE
@@ -0,0 +1,23 @@
+NAME:
+    P_ROOM_TYPE                       "room_type"                       
+
+DEFINIERT IN:
+    /sys/rooms.h
+
+BESCHREIBUNG:
+    In P_ROOM_TYPE wird die Art des Raumes durch entsprechende Flags
+    beschrieben.
+
+    Bisher unterstuetzt werden:
+        - RT_SHOP       fuer Raeume, die /std/room/shop inheriten
+        - RT_PUB        fuer Raeume, die /std/room/pub inheriten
+
+BEISPIEL:
+    Wenn ein NPC abfragen moechte, ob er sich in einer Kneipe aufhaelt (um
+    selbststaendig tanken zu koennen) koennte eine Abfrage z.B. so aussehen:
+
+        if ( environment() &&
+             environment()->QueryProp(P_ROOM_TYPE) & RT_PUB ){
+
+            ... tanken ...
+        }
diff --git a/doc/props/P_SB_SPELLS b/doc/props/P_SB_SPELLS
new file mode 100644
index 0000000..84aa723
--- /dev/null
+++ b/doc/props/P_SB_SPELLS
@@ -0,0 +1,23 @@
+NAME:
+    P_SB_SPELLS            "sb_spells"                   
+
+DEFINIERT IN:
+    /sys/new_skills.h
+
+BESCHREIBUNG:
+    In dieser Spellbookproperty sind saemtliche Sprueche des Spellbooks
+    vermerkt. Veraendert wird sie durch AddSpell().
+
+BEMERKUNGEN:
+    Man sollte diese Property nicht per Hand veraendern, sondern die
+    Funktion AddSpell() nutzen.
+
+SIEHE AUCH:
+    GObj Verwalten:   LearnSkill, LearnSpell, InitialSkillAbility
+    * Properties:     P_GUILD_SKILLS
+    Spellbook Lernen: Learn, SpellSuccess, Erfolg, Misserfolg
+    * Verwalten:      AddSpell, QuerySpell
+    * Properties:     P_GLOBAL_SKILLPROPS
+    Skills:           P_NEWSKILLS, spruchermuedung, skill_info_liste
+
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
\ No newline at end of file
diff --git a/doc/props/P_SCREENSIZE b/doc/props/P_SCREENSIZE
new file mode 100644
index 0000000..fc9dd15
--- /dev/null
+++ b/doc/props/P_SCREENSIZE
@@ -0,0 +1,8 @@
+NAME:
+    P_SCREENSIZE                  "screensize"                  
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Bildschirmgroesse in Zeilen (fuer More)
diff --git a/doc/props/P_SECOND b/doc/props/P_SECOND
new file mode 100644
index 0000000..4aa835a
--- /dev/null
+++ b/doc/props/P_SECOND
@@ -0,0 +1,21 @@
+NAME:
+    P_SECOND                      "second"                      
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Wenn diese Prop gesetzt ist, ist der Spieler ein Zweitie. Inhalt der
+     Prop ist ein String mit dem (lowercase) Namen des Ersties.
+
+BEISPIEL:
+     if (this_player()->QueryProp(P_SECOND)=="notstrom") {
+       tell_object(this_player(), "Nicht alles aufessen!\n");
+     }
+
+SIEHE AUCH:
+     Properties: P_SECOND_MARK
+     Sonstiges:  /secure/zweities.c
+
+----------------------------------------------------------------------------
+Last modified: 18-Jun-2015, Arathorn.
diff --git a/doc/props/P_SECOND_MARK b/doc/props/P_SECOND_MARK
new file mode 100644
index 0000000..c1c0c42
--- /dev/null
+++ b/doc/props/P_SECOND_MARK
@@ -0,0 +1,18 @@
+NAME:
+    P_SECOND_MARK                 "second_mark"
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Gibt an, wie mit der Zweitie-Markierung eines Spielers umgegangen wird.
+
+     -1  'unsichtbare' Markierung; im wer/kwer wird bei diesem Zweitie s
+         oder S angezeigt.
+
+      0  'sichtbare' Markierung; im wer/kwer wird bei diesem Zweitie z oder
+         Z angezeigt. Der Name des Ersties ist beim Fingern jedoch nur
+         fuer Magier sichtbar.
+
+      1  Markierung 'sichtbar + Name'; wie 0, nur dass beim Fingern alle
+         Spieler den Namen des Ersties sehen koennen.
diff --git a/doc/props/P_SEERDOORS b/doc/props/P_SEERDOORS
new file mode 100644
index 0000000..8ffb852
--- /dev/null
+++ b/doc/props/P_SEERDOORS
@@ -0,0 +1,26 @@
+P_SEERDOORS
+
+NAME:
+     P_SEERDOORS      "rw_sehertore"
+
+DEFINIERT IN:
+     /d/seher/portale/sehertor.h
+
+BESCHREIBUNG:
+     Sehertor-relevante Property.
+
+     Enthaelt ein Mapping mit den Wertepaaren
+     ([ Seher-Portal-Nummer: x ])
+     mit x != 0 fuer entdeckte Tore.
+     
+     0 hat ein Sonderverhalten fuer mobile Tore.
+
+BEMERKUNG:
+     Auf gar keinen Fall in Spielern manipulieren! Und bitte das enthaltene
+     Mapping nicht von einem Spieler abfragen und P_SEERDOORS in einem
+     Testspieler zuweisen!
+     
+SIEHE AUCH:
+     P_FAO_PORTALS
+     
+1.September 2008 Gloinson
diff --git a/doc/props/P_SEERDOOR_ALLOWED b/doc/props/P_SEERDOOR_ALLOWED
new file mode 100644
index 0000000..b8225e3
--- /dev/null
+++ b/doc/props/P_SEERDOOR_ALLOWED
@@ -0,0 +1,15 @@
+NAME:
+    P_SEERDOOR_ALLOWED		"rw_sehertor_erlaubt"                          
+
+DEFINIERT IN:
+    /d/seher/portale/sehertor.h
+
+BESCHREIBUNG:
+     Diese Property muss in einem Raum gesetzt sein, soll
+     ein Seher dort ein mobiles Sehertor abstellen duerfen.
+     Zusaetzlich darf der Raum nicht in PARA liegen und muss
+     als eigenes File existieren.
+     Es ist darauf zu achten, Sehertore nicht in Questgebieten,
+     direkt an Tanken oder aehnlichen Plaetzen zu erlauben.
+     Es gilt die Einschaetzung des fuer den Raum Verantwortlichen.
+
diff --git a/doc/props/P_SENSITIVE b/doc/props/P_SENSITIVE
new file mode 100644
index 0000000..23d1fee
--- /dev/null
+++ b/doc/props/P_SENSITIVE
@@ -0,0 +1,125 @@
+P_SENSITIVE
+NAME:
+     P_SENSITIVE                   "sensitive"
+
+DEFINIERT IN:
+     /sys/thing/moving.h
+
+BESCHREIBUNG:
+     Diese Property kann in Objekten gesetzt werden, die auf bestimmte
+     Schadensarten empfindlich reagieren sollen. Moegliche Anwendungsfaelle:
+     - Das Lebewesen, in dessen Inventar sich ein Objekt befindet, erleidet
+       einen Angriff mit der fraglichen Schadensart (Beispiel: eine 
+       Pusteblume, die bei Angriff mit Luftschaden auseinanderfaellt).
+     - Zwei Objekte treffen im gleichen Environment aufeinander, wobei
+       eines empfindlich auf eine Schadensart reagiert, und das zweite diese
+       Schadensart mitbringt, d.h. die Empfindlichkeit ausloesen kann.
+       (Beispiel: ein feuerempfindlicher Postsack wird angesengt, wenn eine
+        brennende Fackel ins gleiche Inventar kommt.)
+       Das Ausloesen dieser Empfindlichkeit ist unabhaengig davon, welches 
+       Objekt zuerst da war.
+
+     Die Property enthaelt ein Array aus Arrays:
+       ({<sensprops_1>, <sensprops_2>, ..., <sensprops_n>})
+     
+     wobei jeder Eintrag <sensprops> jeweils folgende Struktur hat:
+       ({string list_key, string damtype, int treshold, mixed options })
+     
+     Die Eintraege haben dabei folgende Bedeutung:
+     
+     list_key: Kann einen von folgenden drei Werten annehmen 
+          1) SENSITIVE_INVENTORY, passive Eigenschaft; zeigt an, dass das
+             Objekt empfindlich auf aktive Objekte reagiert, die in das
+             Inventory des Containers hineinbewegt werden
+          2) SENSITIVE_ATTACK, passive Eigenschaft; zeigt an, dass das 
+             Objekt empfindlich auf aeussere Einfluesse bzw. Angriffe 
+             auf ein Lebewesen reagiert, in dessen Inventar es sich befindet
+          3) SENSITIVE_INVENTORY_TRIGGER, aktive Eigenschaft; zeigt an, dass
+             das Objekt eine Ausstrahlung auf andere Objekte im Inventar
+             hat. Wird ausgeloest, wenn das Objekt ins Inventar hineinbewegt
+             wird.
+     damtype: eine Schadensart (DT_FIRE, DT_WATER, ...)
+     treshold: hat zwei Bedeutungen abhaengig von dem Wert in list_key:
+          1) Fuer Objekte mit SENSITIVE_INVENTORY oder SENSITIVE_ATTCK ist
+             dies der Schadenswert, ab dem das Objekt benachrichtigt werden 
+             soll.
+             Hier wird ein Wert in "Defend-Einheiten" erwartet, d.h. das
+             Zehnfache dessen, was am Ende in LP abgezogen wuerde.
+          2) Fuer Objekte mit SENSITIVE_INVENTORY_TRIGGER ist dies der 
+             Schadenswert, mit dem das Objekt andere bereits im Inventar
+             des Containers befindliche Objekte beeinflusst, die eine 
+             entsprechende Empfindlichkeit gesetzt haben
+     options: Optionale Daten, die der programmierende Magier selbst
+            definieren kann. Werden an die in den betroffenen Objekten
+            aufgerufenen Funktionen durchgereicht.
+
+     Ein SENSITIVE_ATTACK-Objekt, dessen Trigger-Bedingungen erfuellt sind,
+     wird durch folgenden Funktionsaufruf darueber informiert:
+       trigger_sensitive_attack(object enemy, string damtype, int damage,
+                 mixed spell, mixed options)
+     
+     Ein SENSITIVE_INVENTORY-Objekt, dessen Trigger-Bedingungen erfuellt sind,
+     wird durch folgenden Funktionsaufruf darueber informiert:
+       trigger_sensitive_inv(object whodid, string damtype, int threshold,
+                 mixed options, mixed options)
+
+     Die beiden Funktionen muessen selbst ge-/ueberschrieben werden.
+
+BEMERKUNGEN:
+     1. P_SENSITIVE-Objekte kosten Rechenzeit bei jedem Angriff oder jedem
+        move() - daher bitte sparsam verwenden
+     2. Ist P_SENSITIVE nicht statisch, sondern wird es situationsabhaengig 
+        geaendert, muss man das environment() jeweils selbst ueber seine 
+        neue Empfindlichkeit benachrichtigen. Dies geschieht mit den 
+        Funktionen RemoveSensitiveObject() bzw.InsertSensitiveObject(), 
+        siehe deren Manpages.
+
+BEISPIEL:
+     Beispiel 1:
+     Beispielcode eines Objektes mit SENSITIVE_ATTACK und SENSITIVE_INVENTORY
+     siehe hier: /doc/beispiele/testobjekte/attack_busy_sensitive_testobj.c
+
+     Beispiel 2:
+     Ein Eiszapfen, der bei Feuerangriffen oder bei heissen Gegenstaenden im
+     gemeinsamen Environment zerschmelzen soll:
+
+     void create() {
+       SetProp( P_SENSITIVE, ({ ({SENSITIVE_ATTACK,     DT_FIRE, 100}),
+                                 ({SENSITIVE_INVENTORY, DT_FIRE, 100}) }) );
+       [...]
+     }
+
+     varargs void trigger_sensitive_attack() {
+       remove();
+     }
+
+     varargs void trigger_sensitive_inv() {
+       call_out("remove",0);  // verzoegert, wegen move()
+     }
+
+     varargs int remove(int silent) {
+       if(!silent) {
+         object room = all_environment(this_object())[<1];
+         tell_room(room, Name()+" zerschmilzt.\n");
+       }
+       return ::remove();
+     }
+
+     - wird eine Fackel mit
+       SetProp(P_SENSITIVE,({({SENSITIVE_INVENTORY_TRIGGER,DT_FIRE,250})}))
+       in das gleiche environment() wie dieser Zapfen bewegt wird, loest
+       diese im Zapfen trigger_sensitive_inv() aus
+     - wird ein Angriff mit DT_FIRE und initialem Schaden > 100 auf das
+       environment() veruebt, loest dies im Zapfen trigger_sensitive_attack()
+       aus
+
+SIEHE AUCH:
+     Properties: P_SENSITIVE_ATTACK, P_SENSITIVE_INVENTORY,
+                 P_SENSITIVE_INVENTORY_TRIGGER
+     Funktionen: InsertSensitiveObject(L), RemoveSensitiveObject(L),
+                 CheckSensitiveAttack(L), Defend(), 
+                 insert_sensitive_inv(L), insert_sensitive_inv_trigger(L),
+                 trigger_sensitive_inv(L), trigger_sensitive_attack(L)
+     Defines:    /sys/sensitive.h
+
+Letzte Aenderung: 10. Januar 2015, Arathorn
diff --git a/doc/props/P_SENSITIVE_ATTACK b/doc/props/P_SENSITIVE_ATTACK
new file mode 100644
index 0000000..b1586eb
--- /dev/null
+++ b/doc/props/P_SENSITIVE_ATTACK
@@ -0,0 +1,24 @@
+P_SENSITIVE_ATTACK
+NAME:
+    P_SENSITIVE_ATTACK            "sensitive_attack"
+
+DEFINIERT IN:
+    /sys/sensitive.h
+
+BESCHREIBUNG:
+    Hier steht die Liste der zu informierenden Objekte, die potentiell
+    auf einen Angriff reagieren koennten.
+    Wird von InsertSensitiveObject() und RemoveSensitiveObject()
+    geschrieben und in CheckSensitiveAttack() ausgewertet.
+
+BEMERKUNGEN:
+    Nicht selbst veraendern - bitte P_SENSITIVE fuer Eintraege benutzen.
+
+SIEHE AUCH:
+     P_SENSITIVE
+     InsertSensitiveObject, RemoveSensitiveObject
+     insert_sensitive_inv_trigger, insert_sensitive_inv
+     P_SENSITIVE_INVENTORY_TRIGGER, P_SENSITIVE_INVENTORY
+     CheckSensitiveAttack
+
+25.Apr.2001, Gloinson@MG
diff --git a/doc/props/P_SENSITIVE_INVENTORY b/doc/props/P_SENSITIVE_INVENTORY
new file mode 100644
index 0000000..1e75423
--- /dev/null
+++ b/doc/props/P_SENSITIVE_INVENTORY
@@ -0,0 +1,24 @@
+NAME:
+    P_SENSITIVE_INVENTORY         "sensitive_inv"
+
+DEFINIERT IN:
+    /sys/sensitive.h
+
+BESCHREIBUNG:
+    Hier steht die Liste der zu informierenden Objekte, die potentiell
+    auf ein anderes Objekt mit gesetztem P_SENSITIVE_INVENTORY_TRIGGER
+    reagieren koennten.
+    Wird von InsertSensitiveObject() und RemoveSensitiveObject()
+    geschrieben.
+
+BEMERKUNGEN:
+    Nicht selbst veraendern - bitte P_SENSITIVE fuer Eintraege benutzen.
+
+SIEHE AUCH:
+     P_SENSITIVE
+     InsertSensitiveObject, RemoveSensitiveObject
+     insert_sensitive_inv_trigger, insert_sensitive_inv
+     P_SENSITIVE_INVENTORY_TRIGGER, P_SENSITIVE_ATTACK
+     CheckSensitiveAttack
+
+25.Apr.2001, Gloinson@MG
diff --git a/doc/props/P_SENSITIVE_INVENTORY_TRIGGER b/doc/props/P_SENSITIVE_INVENTORY_TRIGGER
new file mode 100644
index 0000000..df6feae
--- /dev/null
+++ b/doc/props/P_SENSITIVE_INVENTORY_TRIGGER
@@ -0,0 +1,24 @@
+P_SENSITIVE_INVENTORY_TRIGGER
+NAME:
+    P_SENSITIVE_INVENTORY_TRIGGER "sensitive_inv_trigger"
+
+DEFINIERT IN:
+    /sys/sensitive.h
+
+BESCHREIBUNG:
+    Hier steht die Liste der aktiven Objekte, die eine potentielle
+    "Ausstrahlung" auf andere Objekte haben.
+    Wird von InsertSensitiveObject() und RemoveSensitiveObject()
+    geschrieben.
+
+BEMERKUNGEN:
+    Nicht selbst veraendern - bitte P_SENSITIVE fuer Eintraege benutzen.
+
+SIEHE AUCH:
+     P_SENSITIVE
+     InsertSensitiveObject, RemoveSensitiveObject
+     insert_sensitive_inv_trigger, insert_sensitive_inv
+     P_SENSITIVE_ATTACK, P_SENSITIVE_INVENTORY
+     CheckSensitiveAttack
+
+25.Apr.2001, Gloinson@MG
diff --git a/doc/props/P_SHOOTING_AREA b/doc/props/P_SHOOTING_AREA
new file mode 100644
index 0000000..770564f
--- /dev/null
+++ b/doc/props/P_SHOOTING_AREA
@@ -0,0 +1,24 @@
+P_SHOOTING_AREA
+
+NAME:
+    P_SHOOTING_AREA     "shooting_area"
+
+DEFINIERT IN:
+    <combat.h>
+
+BESCHREIBUNG:
+    Legt die 'Groesse' eines Raumes fest. Ein Schuetze kann mit seiner
+    Fernkampfwaffe nur dann aus diesem Raum in einen anderen Raum schiessen,
+    wenn die P_RANGE seiner Waffe mindestens gleich ist.
+
+    Erreichbare Raeume sind entweder das environment() oder der in
+    P_SHOOTING_AREA festgelegte Raum.
+
+SIEHE AUCH:
+    Generell:  P_AMMUNITION, P_SHOOTING_WC, P_STRETCH_TIME
+    Methoden:  FindRangedTarget(L), shoot_dam(L), cmd_shoot(L)
+    Gebiet:    P_RANGE, P_TARGET_AREA
+    Raeume:    P_NEVER_CLEAN
+    Sonstiges: fernwaffen
+
+29.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_SHOOTING_WC b/doc/props/P_SHOOTING_WC
new file mode 100644
index 0000000..35ca215
--- /dev/null
+++ b/doc/props/P_SHOOTING_WC
@@ -0,0 +1,31 @@
+P_SHOOTING_WC
+
+NAME:
+    P_SHOOTING_WC     "shooting_wc"
+
+DEFINIERT IN:
+    <combat.h>
+
+BESCHREIBUNG:
+    Legt in einer Fernkampfwaffe UND ihrer Munition die Waffenstaerke fest.
+    Bei einem Schuss wird die Summe kombiniert mit der Geschicklichkeit
+    zur Berechnung der Angriffstaerke benutzt.
+
+BEISPIELE:
+    SetProp(P_SHOOTING_WC, 70);     // Langbogen
+    SetProp(P_SHOOTING_WC, 50);     // Kurzbogen
+
+    SetProp(P_SHOOTING_WC, 40);     // Bambuspfeil
+    SetProp(P_SHOOTING_WC, 60);     // Aluminiumpfeil
+
+    // So haetten Langbogen mit Aluminiumpfeil eine P_SHOOTING_WC von 70+60.
+
+SIEHE AUCH:
+    Generell:  P_AMMUNITION, P_STRETCH_TIME
+    Methoden:  FindRangedTarget(L), shoot_dam(L), cmd_shoot(L)
+    Gebiet:    P_RANGE, P_SHOOTING_AREA, P_TARGET_AREA
+    Waffen:    P_WEAPON_TYPE, P_WC, P_EQUIP_TIME, P_NR_HANDS
+    Kampf:     Attack(L), Defend(L), P_DISABLE_ATTACK, P_ATTACK_BUSY
+    Sonstiges: fernwaffen
+
+29.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_SHORT b/doc/props/P_SHORT
new file mode 100644
index 0000000..b6502d4
--- /dev/null
+++ b/doc/props/P_SHORT
@@ -0,0 +1,41 @@
+P_SHORT
+NAME:
+     P_SHORT				"short"
+
+DEFINIERT IN:
+     /sys/thing/description.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt die Kurzbeschreibung des Objektes als String 
+     oder Closure (diese muss einen String zurueckgeben).
+
+     ACHTUNG: Die Kurzbeschreibung sollte dabei weder mit einem
+	      Satzzeichen noch mit einem "\n" abgeschlossen sein
+	      (dies wird von den zustaendigen Funktionen erledigt).
+
+     Setzt man diese Property auf 0, so ist das Objekt unsichtbar, allerdings
+     ansprechbar, wenn der Spieler eine ID des Objektes kennt. D.h. Objekte
+     koennen mitgenommen, weggeworfen oder ggf. auch angegriffen werden. Will
+     man dies nicht, sollte man das Objekt mit P_INVIS unsichtbar machen.
+
+     Diese Property bestimmt die Ansicht des Objektes von aussen. Fuer die
+     Innen(kurz)ansicht von Raeumen muss man P_INT_LONG benutzen.
+
+BEMERKUNGEN:
+     Die Funktion, die die Kurzbeschreibung ausgibt (short()), filtert P_SHORT
+     durch process_string(). Von der Nutzung dieses Features wird in neuem
+     Code abgeraten.
+     Soll eine dyn. Kurzbeschreibung geschaffen werden, bitte eine
+     F_QUERY_METHOD einsetzen oder short() passend ueberschreiben.
+
+BEISPIELE:
+     // eine Axt sieht natuerlich so aus:
+     SetProp(P_SHORT, "Eine Axt");
+
+SIEHE AUCH:
+     Aehnliches:	P_LONG, short()
+     Sonstiges:		P_INT_SHORT, process_string()
+
+----------------------------------------------------------------------------
+27.05.2015, Zesstra
+
diff --git a/doc/props/P_SHORT_CWD b/doc/props/P_SHORT_CWD
new file mode 100644
index 0000000..a6343ae
--- /dev/null
+++ b/doc/props/P_SHORT_CWD
@@ -0,0 +1,8 @@
+NAME:
+    P_SHORT_CWD                   "short_cwd"                   
+
+DEFINIERT IN:
+    /sys/shells.h
+
+BESCHREIBUNG:
+     .readme bei cd ausgeben oder nicht
diff --git a/doc/props/P_SHOWEMAIL b/doc/props/P_SHOWEMAIL
new file mode 100644
index 0000000..82d1348
--- /dev/null
+++ b/doc/props/P_SHOWEMAIL
@@ -0,0 +1,10 @@
+NAME:
+     P_SHOWEMAIL                        "showemail"
+
+DEFINIERT IN:
+     /sys/player/base.h
+
+BESCHREIBUNG:
+     Eintrag, wer die E-Mail im "finger" zu sehen bekommen soll:
+     0, "alle", "freunde"
+     Kann durch "emailanzeige" (/std/player/base.c) geaendert werden.
diff --git a/doc/props/P_SHOW_ALIAS_PROCESSING b/doc/props/P_SHOW_ALIAS_PROCESSING
new file mode 100644
index 0000000..cb49cf8
--- /dev/null
+++ b/doc/props/P_SHOW_ALIAS_PROCESSING
@@ -0,0 +1,8 @@
+NAME:
+    P_SHOW_ALIAS_PROCESSING       "show_alias_processing"       
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Arbeit des Parsers beobachten (debugging)
diff --git a/doc/props/P_SHOW_EXITS b/doc/props/P_SHOW_EXITS
new file mode 100644
index 0000000..9c8d87b
--- /dev/null
+++ b/doc/props/P_SHOW_EXITS
@@ -0,0 +1,15 @@
+NAME:
+    P_SHOW_EXITS                  "show_exits"
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Im Spieler gesetzt, wenn der Spieler die offensichtlichen Ausgaenge
+     immer automatisch sehen will.
+
+SIEHE AUCH:
+     Aehnliches:	P_HIDE_EXITS
+     Sonstiges:		AddExit(), GetExits(), int_long(), int_short()
+
+11. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_SHOW_INV b/doc/props/P_SHOW_INV
new file mode 100644
index 0000000..73a2ffe
--- /dev/null
+++ b/doc/props/P_SHOW_INV
@@ -0,0 +1,19 @@
+P_SHOW_INV
+
+NAME:
+     P_SHOW_INV "show_inv"
+
+DEFINIERT IN:
+     <thing/description.h>
+
+BESCHREIBUNG:
+     Wenn diese Property auf einen Wert ungleich 0 gesetzt ist, wird das
+     Objekt, soweit es sich in einem Spieler befindet, in dessen
+     Langbeschreibung angezeigt. Zur Anzeige wird der Name des Objektes
+     verwendet.
+
+SIEHE AUCH:
+     /std/thing/description.c
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 20:36:05 1996 by Wargon
diff --git a/doc/props/P_SHOW_MSG b/doc/props/P_SHOW_MSG
new file mode 100644
index 0000000..8841154
--- /dev/null
+++ b/doc/props/P_SHOW_MSG
@@ -0,0 +1,51 @@
+P_SHOW_MSG
+NAME:
+    P_SHOW_MSG                          "show_message"
+
+DEFINIERT IN:
+    /sys/living/put_and_get.h
+
+BESCHREIBUNG:
+    Mit P_SHOW_MSG kann man die Meldungen, die beim Vorzeigen eines Objektes
+    ausgegeben werden, modifizieren.
+
+    Folgende Werte sind moeglich:
+
+    o 0
+      Es wird eine Standardmeldung ausgegeben. Dies ist Voreinstellung.
+
+    o NO_PNG_MSG        == -1
+      Es wird keinerlei Meldung ausgegeben
+
+    o Ein Array aus Strings
+      Der erste String wird an den Spieler ausgegeben, der zweite
+      (optionale) an den Raum, der dritte (ebenfalls optionale) an den
+      Empfaenger.
+
+      Die Strings werden durch die Funktion replace_personal() geparst.
+        Objekt1 - Spieler
+        Objekt2 - das Objekt, das uebergeben wird
+        Objekt3 - Empfaenger
+
+      Wird der zweite String nicht angegeben, erfolgt keine Meldung an den
+      Raum. Beim Fehlen des dritten gibt es keine Meldung an den Empfaenger.
+
+BEISPIEL:
+    SetProp(P_SHOW_MSG, ({
+      "Du haeltst @WEM3 @WEN2 unter die Nase.",
+      "@WER1 haelt @WEM3 @WENU2 unter die Nase.",
+      "@WER1 haelt Dir @WENU2 unter die Nase."
+    }));
+
+    Das fuehrt bei Ugars "zeig peter medaille" zu folgenden Meldungen:
+
+    Ugar: "Du haeltst Peter die Medaille unter die Nase."
+    Raum: "Ugar haelt Peter eine Medaille unter die Nase."
+    Peter: "Ugar haelt Dir eine Medaille unter die Nase."
+
+SIEHE AUCH:
+     Aehnliches: P_DROP_MSG, P_PUT_MSG, P_PICK_MSG, P_GIVE_MSG
+     Sonstiges:  replace_personal(E), show(L), show_objects(L),
+                 show_notify(L), /std/living/put_and_get.c
+
+3. Juni 2008 Amynthor
diff --git a/doc/props/P_SIBLINGS b/doc/props/P_SIBLINGS
new file mode 100644
index 0000000..15d0977
--- /dev/null
+++ b/doc/props/P_SIBLINGS
@@ -0,0 +1,9 @@
+NAME:
+    P_SIBLINGS                     "siblings"                     
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Enthaelt einen String mit den Blutsbruedern eines Spielers
+     (sofern vorhanden).
diff --git a/doc/props/P_SIZE b/doc/props/P_SIZE
new file mode 100644
index 0000000..b5fdb72
--- /dev/null
+++ b/doc/props/P_SIZE
@@ -0,0 +1,31 @@
+NAME:
+    P_SIZE                        "size"                        
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Groesse des Lebewesens bzw. Laenge der Waffe (in cm).
+
+     Wird keine Waffenlaenge explizit angegeben, so sind die Defaultwerte
+     fuer die entsprechenden Waffentypen folgende:
+
+    	WT_SWORD  : 100
+    	WT_AXE    :  80
+    	WT_CLUB   :  80
+    	WT_SPEAR  : 180
+    	WT_KNIFE  :  20
+    	WT_WHIP   : 200
+    	WT_STAFF  : 150
+
+BEMERKUNGEN:
+     1. Uebertreibt es bitte mit der Groesse nicht, auch sehr grosse NPCs 
+        sollten nicht ueber 1000000 liegen. Sonst kriegt die Karategilde 
+        Probleme.
+     2. Negative Werte fuer P_SIZE sind nicht moeglich, da dies zum einen
+        voellig unsinnig ist und zum anderen evtl. zu Problemen mit Waffen
+        fuehrt, die Schaden in Abhaengigkeit von P_SIZE machen und sich
+        darauf verlassen, dass nur positive Werte vorkommen.
+
+LETZTE AENDERUNG:
+    2006-09-29, von Zesstra
diff --git a/doc/props/P_SKILLS b/doc/props/P_SKILLS
new file mode 100644
index 0000000..02a76c7
--- /dev/null
+++ b/doc/props/P_SKILLS
@@ -0,0 +1,15 @@
+NAME:
+	P_SKILLS			"skills"                      
+
+DEFINIERT IN:
+	/sys/player/skills.h
+
+BESCHREIBUNG:
+	Diese Property sollte nicht mehr verwendet werden. Sie wurde
+	vollstaendig durch P_NEWSKILLS ersetzt.
+
+SIEHE AUCH:
+	P_NEW_SKILLS
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_SKILL_ATTRIBUTES b/doc/props/P_SKILL_ATTRIBUTES
new file mode 100644
index 0000000..6eb5b97
--- /dev/null
+++ b/doc/props/P_SKILL_ATTRIBUTES
@@ -0,0 +1,50 @@
+NAME:
+    P_SKILL_ATTRIBUTES        "skill_attr"
+
+DEFINIERT IN:
+    /sys/living/skill_attributes.h
+
+BESCHREIBUNG:
+    In dieser Prop stehen alle nicht-permanenten Modifikatoren der
+    Skill-Attribute.
+    Die Datenstruktur ist ein Mapping mit den SA-Namen als Schluessel und
+    jeweils drei Werten pro Schluessel.
+    Der erste Wert ist ein Array mit drei Werten: der Summe der stat.
+    Modifier, dem Zeitpunkt an dem dies Summe ungueltig wird und der
+    Gesamtzahl aktiver Modifikatoren.
+    Der zweite Wert enthaelt ein Mapping mit allen statischen Modifikatoren
+    und den Objekten dieser Mods als Schluessel. Die beiden Werte dieses
+    Mappings sind der Wert des Modifikators (int) und die Ablaufzeit (int).
+    Der dritte Wert enthaelt ein Mapping mit allen dynamischen
+    Modifikatoren und den Objekten dieser Mods als Schluessel. Die beiden
+    Werte dieses Mappings sind die zu rufende Closure (closure) und die
+    Ablaufzeit des Mods (int).
+
+    ([ SA_ATTR: ({Summe_Stat_Modifier, Zeitpunkt, AnzahlModifier, });
+                ([ ob1:value;duration,
+                   ob2:value;duration, ...]);  // stat. Modifier
+                ([ ob1:closure;duration,
+                   ob2:closure;duration, ...])     // dyn. Modifier
+                ,
+       SA_ATTR2: ({...}); ([]); ([]),
+       SA_ATTR3: ({...}); ([]); ([]),
+    ])
+
+BEMERKUNGEN:
+    Diese Property darf AUF GAR KEINEN FALL per Hand manipuliert werden,
+    dafuer gibt es die Funktionen ModifySkillAttribute() und
+    RemoveSkillAttributeModifier().
+    Zum Auslesen stehen QuerySkillAttribute() und
+    QuerySkillAttributeModifier() zur Verfuegung.
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+
+13.09.2008, Zesstra
\ No newline at end of file
diff --git a/doc/props/P_SKILL_ATTRIBUTE_OFFSETS b/doc/props/P_SKILL_ATTRIBUTE_OFFSETS
new file mode 100644
index 0000000..2568f76
--- /dev/null
+++ b/doc/props/P_SKILL_ATTRIBUTE_OFFSETS
@@ -0,0 +1,32 @@
+NAME:
+    P_SKILL_ATTRIBUTE_OFFSETS       "skill_attr_offsets"                        
+
+DEFINIERT IN:
+    /sys/living/skill_attributes.h
+
+BESHREIBUNG:
+
+    Der Wert der Property ist ein Mapping: ([Attributname: Wert])
+    In dieser Property stehen permanente Abweichungen der Skillattribute
+    vom Standardwert 100.
+
+    Zu den Moeglichen Attributwerten, siehe P_SKILL_ATTRIBUTES.
+
+    Die Werte duerfen zwischen 10 und 1000 liegen.
+
+BEMERKUNG:
+    Diese Property sollte AUF GAR KEINEN FALL in einem Spieler gesetzt
+    werden, ohne Ruecksprachen mit allerhoechsten Stellen!
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung, skill_info_liste
+    * Properties:   P_NEWSKILLS
+
+31.12.2013, Zesstra
+
diff --git a/doc/props/P_SMELLS b/doc/props/P_SMELLS
new file mode 100644
index 0000000..b510ce1
--- /dev/null
+++ b/doc/props/P_SMELLS
@@ -0,0 +1,24 @@
+NAME:
+    P_SMELLS            "smell_details"
+
+DEFINIERT IN:
+    /sys/thing/description.h
+
+BESCHREIBUNG:
+    Diese Property entspricht dem P_DETAILS fuer Standarddetails,
+    nur werden hierin Gerueche gespeichert:
+    Diese Property enthaelt ein Mapping, in der Details im Objekt
+    definiert werden und Beschreibungen, die ausgegeben werden, wenn man
+    sich diese Details anschaut.
+
+BEMERKUNGEN:
+    Man sollte diese Property nicht per Hand veraendern, sondern die
+    Funktionen nutzen.
+
+SIEHE AUCH:
+    Setzen:    AddSmells()
+    Loeschen:  RemoveSmells()
+    Aehnlich:  AddDetail(), P_DETAILS
+    Sonstiges: GetDetail(), break_string()
+
+27. Jan 2013 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_SNOOPFLAGS b/doc/props/P_SNOOPFLAGS
new file mode 100644
index 0000000..4c47e39
--- /dev/null
+++ b/doc/props/P_SNOOPFLAGS
@@ -0,0 +1,8 @@
+NAME:
+    P_SNOOPFLAGS                  "snoopflags"                  
+
+DEFINIERT IN:
+    /sys/snooping.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_SOUNDS b/doc/props/P_SOUNDS
new file mode 100644
index 0000000..9b9a350
--- /dev/null
+++ b/doc/props/P_SOUNDS
@@ -0,0 +1,24 @@
+NAME:
+    P_SOUNDS            "sound_details"
+
+DEFINIERT IN:
+    /sys/thing/description.h
+
+BESCHREIBUNG:
+    Diese Property entspricht dem P_DETAILS fuer Standarddetails,   
+    nur werden hierin Gerauesche gespeichert:
+    Diese Property enthaelt ein Mapping, in der Details im Objekt
+    definiert werden und Beschreibungen, die ausgegeben werden, wenn man
+    sich diese Details anschaut.
+
+BEMERKUNGEN:
+    Man sollte diese Property nicht per Hand veraendern, sondern die
+    Funktionen nutzen.
+
+SIEHE AUCH:
+    Setzen:    AddSounds()
+    Loeschen:  RemoveSounds()
+    Aehnlich:  AddDetail(), P_DETAILS
+    Sonstiges: GetDetail(), break_string()
+
+27. Jan 2013 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_SP b/doc/props/P_SP
new file mode 100644
index 0000000..02bab65
--- /dev/null
+++ b/doc/props/P_SP
@@ -0,0 +1,23 @@
+NAME:
+    P_SP                          "sp"
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+
+     - Lebewesen
+       Anzahl der Konzentrationspunkte des Wesens.
+
+     - Speisen/Kneipen
+       Heilwirkung einer Portion der Speise auf die Konzentrationspunkte
+       des Konsumenten
+
+SIEHE AUCH:
+     Props:		P_MAX_SP
+     Veraenderung:	reduce_spell_points(), restore_spell_points()
+			buffer_sp()
+     Speisen/Kneipen:   std/pub, wiz/food, consume
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_SPECIAL_DETAILS b/doc/props/P_SPECIAL_DETAILS
new file mode 100644
index 0000000..2eb2123
--- /dev/null
+++ b/doc/props/P_SPECIAL_DETAILS
@@ -0,0 +1,23 @@
+NAME:
+    P_SPECIAL_DETAILS             "special_details"             
+
+DEFINIERT IN:
+    /sys/thing/description.h
+
+BESCHREIBUNG:
+    Mapping von Details, die beim Anschauen eine Funktion starten.
+
+BEMERKUNGEN:
+    Dies ist keine "echte" Property. Die Daten werden bei der Abfrage in einer
+    Querymethode dynamisch aus P_DETAILS extrahiert. Dementsprechend
+    funktioniert es auch nicht, hier eine Query- oder Setmethode von aussen
+    drauf zu legen.
+
+SIEHE AUCH:
+    Setzen:    AddDetail()
+    Loeschen:  RemoveDetail()
+    Daten:     P_DETAILS
+    Veraltet:  AddSpecialDetail(), RemoveSpecialDetail()
+    Sonstiges: GetDetail(), break_string()
+
+27. Jan 2013 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_SPECIAL_EXITS b/doc/props/P_SPECIAL_EXITS
new file mode 100644
index 0000000..1914366
--- /dev/null
+++ b/doc/props/P_SPECIAL_EXITS
@@ -0,0 +1,9 @@
+NAME:
+    P_SPECIAL_EXITS               "special_exits"               
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Dito, aber anstatt des Nachbarraums wird eine Funktion (im Raum)
+     angegebem, die bei Eingabe der Richtung ausgefuehrt wird.
diff --git a/doc/props/P_SPELLRATE b/doc/props/P_SPELLRATE
new file mode 100644
index 0000000..1672a33
--- /dev/null
+++ b/doc/props/P_SPELLRATE
@@ -0,0 +1,8 @@
+NAME:
+    P_SPELLRATE                   "spellrate"                   
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     NPC-Spellrate (in %)
diff --git a/doc/props/P_SPELLS b/doc/props/P_SPELLS
new file mode 100644
index 0000000..17112fb
--- /dev/null
+++ b/doc/props/P_SPELLS
@@ -0,0 +1,8 @@
+NAME:
+    P_SPELLS                      "spells"                      
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     NPC-Spells
diff --git a/doc/props/P_SP_DELAY b/doc/props/P_SP_DELAY
new file mode 100644
index 0000000..84f6372
--- /dev/null
+++ b/doc/props/P_SP_DELAY
@@ -0,0 +1,10 @@
+NAME:
+    P_SP_DELAY                 "sp_delay"                     
+
+DEFINIERT IN:
+    /sys/living/life.h
+
+BESCHREIBUNG:
+     Anzahl der heart_beats, bis die Magiepunkte um einen Punkt steigen.
+     Aenderungen dieser Property in Spielern beduerfen der 
+     Genehmigung des EM fuer Balance.
diff --git a/doc/props/P_START_HOME b/doc/props/P_START_HOME
new file mode 100644
index 0000000..25fff2c
--- /dev/null
+++ b/doc/props/P_START_HOME
@@ -0,0 +1,8 @@
+NAME:
+    P_START_HOME                  "start_home"                  
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Raum, in dem der Spieler nach dem Einloggen landen soll
diff --git a/doc/props/P_STD_OBJECT b/doc/props/P_STD_OBJECT
new file mode 100644
index 0000000..87e21da
--- /dev/null
+++ b/doc/props/P_STD_OBJECT
@@ -0,0 +1,38 @@
+NAME:
+    P_STD_OBJECT                  "std_object"                  
+
+DEFINIERT IN:
+    /sys/v_compiler.h
+
+BESCHREIBUNG:
+   Enthaelt den Namen eines Files welches als Standard-Objekt fuer den 
+   Virtual Compiler gelten soll.
+
+   In diesem File werden das generelle Aussehen, Ausgaenge, Funktionen
+   usw. der VC-generierten Raeume / Objekte festgelegt.
+
+   Dieses File ist ein 'normales' .c - File, welches geclont wird und
+   anschliessend umbenannt wird.
+   
+   Ganz wichtig: Falls euer Standardobjekt (direkt oder indirekt) von
+   /std/room.c erbt, solltet ihr darauf achten, dass euer Objekt ausser dem
+   create() noch eine weitere (beliebige) Funktion hat.  
+   Ansonsten wuerde das Programm eures Standardobjekts automatisch durch
+   /std/room.c ersetzt, was in der Regel zu schwer zu findenen Bugs fuehrt.
+
+BEISPIEL:
+   (create eines VCs)
+   protected void create() {
+     ...
+     SetProp(P_STD_OBJECT,"/d/region/magier/vc/std_raum");
+     ...
+   }
+
+   Was in diesem std_raum.c nun steht, wird in jedem VC-Clone
+   verfuegbar. Sei es Details, Gerueche, auch Objekte die per 
+   AddItem eingebunden sind, ...
+
+SIEHE AUCH:
+   P_COMPILER_PATH, virtual_compiler
+-----------------------------------------------------------------------
+Letzte Aenderung: 22.10.07 von Zesstra
diff --git a/doc/props/P_STORE_CONSUME b/doc/props/P_STORE_CONSUME
new file mode 100644
index 0000000..7b65641
--- /dev/null
+++ b/doc/props/P_STORE_CONSUME
@@ -0,0 +1,51 @@
+NAME:
+	P_STORE_CONSUME			"store_consume"
+
+DEFINIERT IN:
+	/sys/bank.h
+
+BESCHREIBUNG:
+	Diese Property ist entscheidend dafuer, wieviel Prozent an Objekten
+	bei jedem Reset in einem Lager eines Ladens vernichtet werden. Dies
+	geschieht aus Speicher- und Laggruenden. Es verbleibt dabei jedoch
+	eine Grundmenge an Objekten, deren Anzahl in der Property
+	P_MIN_STOCK festgehalten ist. Standardwert fuer P_STORE_CONSUME ist
+	hierbei 30%, aber in oft benutzten Laeden kann man dort ruhig einen
+	hoeheren Wert eintragen. Erlaubt sind Werte zwischen 0% und 100%.
+	Aufgeraeumt werden jedoch keine Objekte, die mittels AddItem() im
+	Lager eingebunden wurden. Mittels der Ladenfunktion AddFixedObject()
+	als staendig verfuegbar markierte Objekte werden natuerlich auch
+	nicht beruecksichtigt.
+	Beide hier erwaehnten Properties sollten ueberigens nur mittels
+	QueryProp/SetProp ausgelesen bzw. veraendert werden.
+
+BEISPIEL:
+	Ein eigener haeufig benutzter Laden koennte ein Lager in folgender
+	Form erhalten:
+	  // myStore
+	  #include <bank.h>
+	  inherit "std/store";
+	  void create()
+	  { ::create();
+	    SetProp(P_STORE_CONSUME,90);
+	    // keine weiteren Beschreibungen, Spieler sollen da drin
+	    // schliesslich nicht rumwuseln
+	  }
+	Um das Lager dem Laden zuzuweisen, nutzt man folgendes:
+	  // myShop
+	  inherit "std/laden";
+	  void create()
+	  { ::create();
+	    SetStorageRoom("pfad/myStore");
+	    // Beschreibungen folgen
+	    ...
+	  }
+	Es werden hierbei waehrend jedes Lager-Resets 90% der im Lager
+	befindlichen Objekte vernichtet.
+
+SIEHE AUCH:
+	P_MIN_STOCK, SetStorageRoom(), /std/store.c, /std/shop.c
+	AddItem(), RemoveItem(), AddFixedObject(), RemoveFixedObject()
+
+----------------------------------------------------------------------------
+Last modified: 19-Jun-2015, Arathorn 
diff --git a/doc/props/P_STRETCH_TIME b/doc/props/P_STRETCH_TIME
new file mode 100644
index 0000000..dfef4f1
--- /dev/null
+++ b/doc/props/P_STRETCH_TIME
@@ -0,0 +1,20 @@
+P_STRETCH_TIME
+
+NAME:
+    P_STRETCH_TIME     "stretch_time"
+
+DEFINIERT IN:
+    <combat.h>
+
+BESCHREIBUNG:
+    Enthaelt die Zeit in Runden (2s), die man braucht, um eine Fernwaffe zu
+    spannen/benutzen. Zaehlt seit dem letzten Schuss oder der Zeit des
+    Zueckens (P_EQUIP_TIME).
+
+SIEHE AUCH:
+    Generell:  P_AMMUNITION, P_SHOOTING_WC
+    Methoden:  FindRangedTarget(L), shoot_dam(L), cmd_shoot(L)
+    Gebiet:    P_RANGE, P_SHOOTING_AREA, P_TARGET_AREA
+    Sonstiges: fernwaffen
+
+29.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_SUBGUILD_TITLE b/doc/props/P_SUBGUILD_TITLE
new file mode 100644
index 0000000..58a59d5
--- /dev/null
+++ b/doc/props/P_SUBGUILD_TITLE
@@ -0,0 +1,20 @@
+P_SUBGUILD_TITLE
+NAME:
+     P_SUBGUILD_TITLE		"subguild_title"                       
+
+DEFINIERT IN:
+     /sys/new_skills.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt eventuelle Zusatztitel eines Spielers, den er
+     innerhalb einer Gilde traegt. Das kann z.B. ein Clan sein, ein Zweig oder
+     einfach nur der Gildenrang.
+
+BEMERKUNGEN:
+     Inhalt der Property kann 0 sein oder ein String.  Ein Zusatztitel kann
+     mittels P_VISIBLE_SUBGUILD_TITLE vorgetaeuscht werden.
+
+SIEHE AUCH:
+     P_GUILD_TITLE, P_VISIBLE_SUBGUILD_TITLE
+
+26. Maerz 2004 Gloinson
diff --git a/doc/props/P_TARGET_AREA b/doc/props/P_TARGET_AREA
new file mode 100644
index 0000000..9d2cec9
--- /dev/null
+++ b/doc/props/P_TARGET_AREA
@@ -0,0 +1,75 @@
+P_TARGET_AREA
+
+NAME:
+    P_TARGET_AREA     "target_area"
+
+DEFINIERT IN:
+    <combat.h>
+
+BESCHREIBUNG:
+    Kann in einem Raum gesetzt werden, um einen anderen, von dort aus mit
+    Fernkampfwaffen beschiessbaren Raum als Objekt oder Objektnamen (zu
+    einem geladenen Objekt) festzulegen.
+
+BEMERKUNGEN:
+    Ein Schuetze kann nur in den anderen Raum schiessen, wenn die P_RANGE
+    seiner Waffe mindest gleich der P_SHOOTING_AREA des Raums (nicht des
+    Zielraums) ist.
+
+    Idealerweise sollte in mit P_TARGET_AREA angegebenen Raeumen auch
+    P_NEVER_CLEAN gesetzt sein.
+
+BEISPIELE:
+    // #1 Ein Baum-Raum (/std/room)
+    void create() {
+      ::create();
+      SetProp(P_INT_SHORT, "Auf einem Baum");
+      SetProp(P_INT_LONG, break_string("Du hockst auf einem Baum und kannst "
+        "auf die Lichtung unter Dir sehen.\n");
+
+      AddExit("unten", RAEUME("lichtung"));
+
+      SetProp(P_TARGET_AREA, RAEUME("lichtung"));  // Lichtung beschiessbar
+      SetProp(P_SHOOTING_AREA, 15);                // 15 Entfernung
+    }
+
+    // #2 Ein Elefanten-Transporter (/std/transport)
+    // Er trampelt durch mehrere Raeume durch und der Schuetze kann vom
+    // Ruecken des Elefanten aus auf Gegner draussen schiessen.
+    void create() {
+      ::create();
+      SetProp(P_NAME, "Kampfelefant");
+      AddId(({"elefant", "kampfelefant")});
+      SetProp(P_GENDER, MALE);
+      SetProp(P_SHORT, "Ein Kampfelefant");
+      SetProp(P_INT_SHORT, "Auf einem Kampfelefanten");
+      // P_LONG, P_INT_LONG
+
+      SetProp(P_ENTERCMDS, ({"kletter", "erkletter"}));
+      SetProp(P_LEAVECMDS, ({"verlass", "verlasse"}));
+
+      SetProp(P_ARRIVEMSG, ({"Der Elefant trampelt in einen Raum.\n",
+                             "Ein Kampfelefant trampelt herein.\n"}));
+      SetProp(P_DEPARTMSG, ({"Der Elefant trampelt weiter.\n",
+                             "Der Kampfelefant trampelt weiter.\n"}));
+
+      SetProp(P_SHOOTING_AREA, 8); // weiter als 8 sollte man schiessen
+
+      AddRoute(RAEUME("schlachtfeld"), 20+random(10), 6, "Schlachtfeld");
+      AddRoute(RAEUME("burgtor"), 20+random(10), 6, "Burgtor");
+      AddRoute(RAEUME("burghof"), 20+random(10), 6, "Burghof");
+      AddRoute(RAEUME("halle"), 20+random(10), 6, "Halle");
+      AddRoute(RAEUME("bresche"), 20+random(10), 6, "Bresche");
+      // ...
+
+      Start();
+    }
+
+SIEHE AUCH:
+    Generell:  P_AMMUNITION, P_SHOOTING_WC, P_STRETCH_TIME
+    Methoden:  FindRangedTarget(L), shoot_dam(L), cmd_shoot(L)
+    Gebiet:    P_RANGE, P_SHOOTING_AREA
+    Raeume:    P_NEVER_CLEAN
+    Sonstiges: fernwaffen
+
+29.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_TEAM b/doc/props/P_TEAM
new file mode 100644
index 0000000..f03109d
--- /dev/null
+++ b/doc/props/P_TEAM
@@ -0,0 +1,24 @@
+NAME:
+	P_TEAM                         "team"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Liefert das Teamobjekt, falls Spieler in einem Team ist, sonst 0.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD, P_TEAM_AUTOFOLLOW,
+                    P_TEAM_COLORS, P_TEAM_LEADER, P_TEAM_NEWMEMBER,
+                    P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TEAM_ASSOC_MEMBERS b/doc/props/P_TEAM_ASSOC_MEMBERS
new file mode 100644
index 0000000..c4f95b8
--- /dev/null
+++ b/doc/props/P_TEAM_ASSOC_MEMBERS
@@ -0,0 +1,30 @@
+NAME:
+	P_TEAM_ASSOC_MEMBERS           "team_assoc_members"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Array mit den zugeordneten NPCs des Spielers bzw. der Spieler,
+	dem dieser NPC zugeordnet ist.
+	Zugeordnete NPCs sind automatisch im Team des Spielers.
+
+BEMERKUNG:
+	Der Zugriff auf diese Property sollte ueber AssocMember()
+	bzw. DeAssocMember() erfolgen.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_TEAM_ATTACK_CMD, P_TEAM_AUTOFOLLOW,
+                    P_TEAM_COLORS, P_TEAM_LEADER, P_TEAM_NEWMEMBER,
+                    P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TEAM_ATTACK_CMD b/doc/props/P_TEAM_ATTACK_CMD
new file mode 100644
index 0000000..3f77349
--- /dev/null
+++ b/doc/props/P_TEAM_ATTACK_CMD
@@ -0,0 +1,24 @@
+NAME:
+	P_TEAM_ATTACK_CMD              "team_attack_cmd"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Angriffsbefehl des Spielers, nicht setzbar.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_AUTOFOLLOW,
+                    P_TEAM_COLORS, P_TEAM_LEADER, P_TEAM_NEWMEMBER,
+                    P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TEAM_AUTOFOLLOW b/doc/props/P_TEAM_AUTOFOLLOW
new file mode 100644
index 0000000..45be50f
--- /dev/null
+++ b/doc/props/P_TEAM_AUTOFOLLOW
@@ -0,0 +1,24 @@
+NAME:
+	P_TEAM_AUTOFOLLOW              "team_autofollow"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Folgewunsch des Spielers, nicht setzbar.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_COLORS, P_TEAM_LEADER, P_TEAM_NEWMEMBER,
+                    P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TEAM_COLORS b/doc/props/P_TEAM_COLORS
new file mode 100644
index 0000000..d23815d
--- /dev/null
+++ b/doc/props/P_TEAM_COLORS
@@ -0,0 +1,25 @@
+NAME:
+	P_TEAM_COLORS                  "team_colors"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Grenzwerte fuer farbige Anzeige im Teaminfo.
+	Array mit 4 Werten: ({ lp_rot, lp_gelb, sp_rot, sp_gelb })
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_LEADER, P_TEAM_NEWMEMBER,
+                    P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TEAM_LEADER b/doc/props/P_TEAM_LEADER
new file mode 100644
index 0000000..a123c37
--- /dev/null
+++ b/doc/props/P_TEAM_LEADER
@@ -0,0 +1,24 @@
+NAME:
+	P_TEAM_LEADER                  "team_leader"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Liefert das Teamobjekt, falls Spieler Anfuehrer eines Teams ist.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_NEWMEMBER,
+                    P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TEAM_NEWMEMBER b/doc/props/P_TEAM_NEWMEMBER
new file mode 100644
index 0000000..f506c5b
--- /dev/null
+++ b/doc/props/P_TEAM_NEWMEMBER
@@ -0,0 +1,25 @@
+NAME:
+	P_TEAM_NEWMEMBER               "potential_team_member"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Enthaelt das Objekt des Teamleaders, sobald ein Spieler um
+	Teamaufnahme gebeten hat, sonst 0.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TEAM_WANTED_ROW b/doc/props/P_TEAM_WANTED_ROW
new file mode 100644
index 0000000..7cd3c36
--- /dev/null
+++ b/doc/props/P_TEAM_WANTED_ROW
@@ -0,0 +1,24 @@
+NAME:
+	P_TEAM_WANTED_ROW              "team_wanted_row"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Gewuenschte Reihe des Spielers (von 1 bis MAX_TEAMROWS)
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD, P_TEAM_AUTOFOLLOW,
+                    P_TEAM_COLORS, P_TEAM_LEADER, P_TEAM_NEWMEMBER,
+                    P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TEAM_WIMPY_ROW b/doc/props/P_TEAM_WIMPY_ROW
new file mode 100644
index 0000000..a832255
--- /dev/null
+++ b/doc/props/P_TEAM_WIMPY_ROW
@@ -0,0 +1,28 @@
+NAME:
+	P_TEAM_WIMPY_ROW               "team_wimpy_row"
+
+DEFINIERT IN:
+	/sys/living/team.h
+
+BESCHREIBUNG:
+	Fluchtreihe des Spielers, von 1 bis MAX_TEAMROWS.
+
+BEMERKUNG:
+	Wenn die Fluchtreihe <=1 ist, ist die Flucht in eine hintere Reihe
+	deaktiviert.
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD, P_TEAM_AUTOFOLLOW,
+                    P_TEAM_COLORS, P_TEAM_LEADER, P_TEAM_NEWMEMBER,
+                    P_TEAM_WANTED_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      DeAssocMember, InsertEnemyTeam, SelectNearEnemy,
+                    SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/props/P_TELNET_RTTIME b/doc/props/P_TELNET_RTTIME
new file mode 100644
index 0000000..fc30011
--- /dev/null
+++ b/doc/props/P_TELNET_RTTIME
@@ -0,0 +1,25 @@
+NAME:
+    P_TELNET_RTTIME                                  "p_lib_telnet_rttime"
+
+DEFINIERT IN:
+    /secure/telnetneg.h
+
+BESCHREIBUNG:
+    In dieser Properties steht die letzte gemessene 'round-trip' Zeit
+    (in Mikrosekunden) einer 'Telnet timing mark' vom MUD zum Client und
+    zurueck.
+
+    Voraussetzung hierfuer ist allerdings, dass das Telnet des Spielers
+    Telnetnegotiations unterstuetzt und 'telnet keepalive' eingeschaltet
+    ist, ansonsten bleibt diese Property 0.
+    Die meisten Telnets/Clients antworten zumindest eine Ablehnung auf
+    die 'timing marks', so dass trotzdem eine Zeit bestimmt werden kann.
+
+    Die Prop kann nicht gesetzt werden bzw. es hat keinen Effekt.
+
+SIEHE AUCH:
+    P_TTY_COLS, P_TTY_ROWS, P_TTY_SHOW, P_TTY, P_TTY_TYPE
+
+LETZTE AeNDERUNG:
+    03.02.2013, Zesstra
+
diff --git a/doc/props/P_TESTPLAYER b/doc/props/P_TESTPLAYER
new file mode 100644
index 0000000..6f64ade
--- /dev/null
+++ b/doc/props/P_TESTPLAYER
@@ -0,0 +1,29 @@
+NAME:
+    P_TESTPLAYER                  "testplayer"                  
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Gesetzt, wenn der Spieler ein Testspieler ist. Enthaelt die UID des
+     Magiers, dem dieser Testie (momentan) gehoert.
+     
+     Bei Testspielern duerfen Skills geaendert werden, sie duerfen gezappt
+     werden und - ihre eigentliche Aufgabe - nicht angeschlossene Gebiete
+     testen.
+
+     AUSNAHMEN: Gildentesties duerfen nur sehr eingeschraenkt manipuliert
+                werden werden, da sie im ganzen Mud rumlaufen koennen,
+                Spielerkontakt haben und nach Abschluss der Tests ggf. sogar
+                die Testiemarkierung entfernt werden kann.
+                
+     Fuer Spielertesties, die von einem Spieler kontrolliert werden, gelten
+     teilweise besondere Regeln, s. 'spielertesties'.
+
+BEMERKUNGEN: 
+     P_TESTPLAYER kann nur per SetProp() gesetzt werden und das auch nur ein
+     Mal! Geloescht werden kann das Flag nur von EM+.
+
+ZULETZT GEAeNDERT:
+05.01.2010, Zesstra
+
diff --git a/doc/props/P_TIMED_ATTR_MOD b/doc/props/P_TIMED_ATTR_MOD
new file mode 100644
index 0000000..1175c50
--- /dev/null
+++ b/doc/props/P_TIMED_ATTR_MOD
@@ -0,0 +1,59 @@
+NAME:
+    P_TIMED_ATTR_MOD         "timed_attr_mod"
+
+DEFINIERT IN:
+    /sys/living/attributes.h
+
+BESCHREIBUNG:
+    In dieser Property werden Attribut-Modifikatoren gespeichert, die
+    nicht ueber laengere Zeit wirksam sein sollen.
+    Die Wirksamkeit der Modifikatoren kann an Zeit und Objekte
+    gebunden werden.
+
+    Intern werden die Modifikatoren in einer Datenstruktur der Form
+
+    ({
+       ({ Ablaufzeiten }),
+       ([ Key : Ablaufobjekt ]),
+       ([ Key : ([ Mapping mit den Modifikatoren ]);
+         Ablaufzeit ; Ablaufobjekt ; Nachrichtenempfaenger
+       ])
+    })
+
+    gespeichert mit:
+    * Ablaufzeiten:  Zeit in Sekunden seit 1. Jan 1970, 0.0:0 GMT
+    * Ablaufobjekte: Objekte, an deren Existenz die Attribut-
+                     veraenderungen gebunden sind
+    * Nachrichtenempfaenger:
+      Objekte/Klassen, welche ueber abgelaufene Attributveraenderung
+      durch den Aufruf von "NotifyTimedAttrModExpired" (mit key als
+      Argument) benachrichtigt werden.
+
+    Das Setzen der Werte erfolgt NUR ueber die Methoden SetTimedAttrModifier
+    und DeleteTimedAttrModifier.
+
+    Die Daten zu einem Key koennen ueber QueryTimedAttrModifier abgefragt
+    werden. Die Abfrage mittels QueryProp liefert eine Kopie der gueltigen
+    Datenstruktur, die per Query nicht (siehe Bemerkungen).
+
+    Die Bedingungen fuer die ueber P_TIMED_ATTR_MOD gesetzten
+    Attributveraenderungen werden im Heartbeat in der Funktion
+    attribute_hb ueberprueft. Eine verminderte Funktionalitaet im
+    Falle von Magiern ist somit kein Fehlerfall.
+
+BEMERKUNGEN:
+    Keine echte Property. Die Methode _query_timed_attr_mod() in
+    /std/living/attributes.c stellt die Daten zusammen.
+
+    ACHTUNG: Bitte nur die bereitgestellten Methoden zur Manipulation
+             benutzen! Setzen als Property hat keinen Effekt.
+
+SIEHE AUCH:
+    QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),
+    SetAttribute(), SetRealAttribute(), UpdateAttributes(),
+    SetTimedAttrModifier(), QueryTimedAttrModifier(),
+    DeleteTimedAttrModifier(),
+    P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS, P_ATTRIBUTES_MODIFIER,
+    P_X_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c
+----------------------------------------------------------------------------
+Last modified: Tue Jul 27 20:00:20 2004 by Muadib
diff --git a/doc/props/P_TIMEZONE b/doc/props/P_TIMEZONE
new file mode 100644
index 0000000..8243d07
--- /dev/null
+++ b/doc/props/P_TIMEZONE
@@ -0,0 +1,10 @@
+NAME:
+    P_TIMEZONE                 "timezone"
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Ein Integer-Wert, der bei der Uhrzeitmeldung und beim Befehl
+     "(uhr)zeit" beruecksichtig wird. Gibt die Anzahl der Stunden
+     Zeitabweichung von Berliner Zeit an.
diff --git a/doc/props/P_TITLE b/doc/props/P_TITLE
new file mode 100644
index 0000000..49afd57
--- /dev/null
+++ b/doc/props/P_TITLE
@@ -0,0 +1,8 @@
+NAME:
+    P_TITLE                       "title"                       
+
+DEFINIERT IN:
+    /sys/player/description.h
+
+BESCHREIBUNG:
+     Titel des Spielers. Erscheint hinter dem Namen in Kurz/Langbeschreibung.
diff --git a/doc/props/P_TOO_HEAVY_MSG b/doc/props/P_TOO_HEAVY_MSG
new file mode 100644
index 0000000..27ef315
--- /dev/null
+++ b/doc/props/P_TOO_HEAVY_MSG
@@ -0,0 +1,31 @@
+NAME:
+    P_TOO_HEAVY_MSG                      "too_heavy_msg"                      
+
+DEFINIERT IN:
+    /sys/thing/moving.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt eine Meldung, die ausgegeben wird, wenn jemand
+     versucht, ein Objekt in einen Behaelter zu legen, fuer den dieses Objekt
+     zu schwer ist.
+     Die Property ist im Behaelter zu setzen.
+     Ist diese Property nicht oder auf einen nicht-String-Wert gesetzt,
+     so wird die Standardmeldung ausgegeben.
+     ("<Objekt> passt in <Behaelter> nicht mehr rein.")
+     Der String in der Property wird noch durch replace_personal()
+     verarbeitet, das zu bewegende Objekt wird als erstes, der Behaelter als
+     zweites Objekt angegeben. Danach wird der String auf 78 Zeichen
+     umgebrochen.
+     Das Setzen eines leeren Strings unterdrueckt die Ausgabe einer Meldung
+     ganz.
+
+BEISPIELE:
+     SetProp(P_TOO_HEAVY_MSG, "Wenn du @WEN1 noch in den Beutel stecken"
+			      " wuerdest, wuerde er reissen.");
+
+SIEHE AUCH:
+     Aehnliches: P_ENV_TOO_HEAVY_MSG, P_TOO_MANY_MSG, P_NOINSERT_MSG,
+                 P_NOLEAVE_MSG, P_NODROP, P_NOGET 
+     Erfolg:     P_PICK_MSG, P_DROP_MSG, P_GIVE_MSG, P_PUT_MSG,
+                 P_WEAR_MSG, P_WIELD_MSG
+     Sonstiges:  replace_personal(E), /std/living/put_and_get.c
diff --git a/doc/props/P_TOO_MANY_MSG b/doc/props/P_TOO_MANY_MSG
new file mode 100644
index 0000000..e23ce32
--- /dev/null
+++ b/doc/props/P_TOO_MANY_MSG
@@ -0,0 +1,31 @@
+NAME:
+    P_TOO_MANY_MSG                      "too_many_msg"                      
+
+DEFINIERT IN:
+    /sys/thing/moving.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt eine Meldung, die ausgegeben wird, wenn jemand
+     versucht, ein Objekt in einen Behaelter zu legen, der schon die maximale
+     Anzahl an Objekten enthaelt.
+     Die Property ist im Behaelter zu setzen.
+     Ist diese Property nicht oder auf einen nicht-String-Wert gesetzt,
+     so wird die Standardmeldung ausgegeben.
+     ("Dafuer ist nicht mehr genug Platz in <Behaelter>.")
+     Der String in der Property wird noch durch replace_personal()
+     verarbeitet, das zu bewegende Objekt wird als erstes, der Behaelter als
+     zweites Objekt angegeben. Danach wird der String auf 78 Zeichen
+     umgebrochen.
+     Das Setzen eines leeren Strings unterdrueckt die Ausgabe einer Meldung
+     ganz.
+
+BEISPIELE:
+     SetProp(P_TOO_MANY_MSG, "Aber der Korb hat doch nur drei Faecher, die"
+			     " sind alle schon voll.");
+
+SIEHE AUCH:
+     Aehnliches: P_TOO_HEAVY_MSG, P_ENV_TOO_HEAVY_MSG, P_NOINSERT_MSG,
+                 P_NOLEAVE_MSG, P_NODROP, P_NOGET 
+     Erfolg:     P_PICK_MSG, P_DROP_MSG, P_GIVE_MSG, P_PUT_MSG,
+                 P_WEAR_MSG, P_WIELD_MSG
+     Sonstiges:  replace_personal(E), /std/living/put_and_get.c
diff --git a/doc/props/P_TOTAL_AC b/doc/props/P_TOTAL_AC
new file mode 100644
index 0000000..222cffa
--- /dev/null
+++ b/doc/props/P_TOTAL_AC
@@ -0,0 +1,23 @@
+NAME:
+    P_TOTAL_AC                    "total_ac"                    
+
+DEFINIERT IN:
+    /sys/living/combat.h
+
+BESCHREIBUNG:
+     Numerischer Wert der Abwehrstaerke des Wesens.
+     Dieser wird durch Aufaddieren der P_AC aller getragenen Ruestungen
+     bestimmt. Aus diesem Grund ist das Abfragen dieser Property ziemlich
+     teuer. Falls das Ergebnis mehrfach kurz hintereinander gebraucht wird,
+     sollte die Property auf jeden Fall nur einmal abgefragt und der Wert
+     gespeichert werden.
+
+BEMERKUNGEN:
+    Auf diese Property sollte nicht mittels Query() oder Set() zugegriffen
+    werden, das Setzen von Query- oder Setmethoden bitte auf jeden Fall
+    unterlassen.
+
+SIEHE AUCH:
+    P_AC
+
+05.09.2008, Zesstra
diff --git a/doc/props/P_TOTAL_LIGHT b/doc/props/P_TOTAL_LIGHT
new file mode 100644
index 0000000..41006d2
--- /dev/null
+++ b/doc/props/P_TOTAL_LIGHT
@@ -0,0 +1,23 @@
+NAME:
+    P_TOTAL_LIGHT                 "total_light"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Gibt das Lichtlevel an, das von einem Objekt ausgeht. Hierzu wird das
+    eigene Lichtlevel P_LIGHT mit dem gesamten Inhalt eines Containers
+    verrechnet.
+
+    Bitte _nur_ ueber QueryProp auf diese Property zugreifen,
+    da das Lichtlevel ggf. neu berechnet werden muss!
+
+    Ein direktes setzen dieser Property ist NICHT moeglich, hierzu bitte
+    P_LIGHT benutzen!
+
+BEMERKUNGEN:
+    Das ist die VON einem Objekt ausgehende Lichtstaerke. Fuer das IN einem
+    Raum herrschende Licht bitte P_INT_LIGHT abfragen!
+
+SIEHE AUCH:
+    P_LIGHT, P_INT_LIGHT, P_PLAYER_LIGHT, P_LIGHT_MODIFIER, CannotSee()
diff --git a/doc/props/P_TOTAL_OBJECTS b/doc/props/P_TOTAL_OBJECTS
new file mode 100644
index 0000000..5f01567
--- /dev/null
+++ b/doc/props/P_TOTAL_OBJECTS
@@ -0,0 +1,16 @@
+NAME:
+    P_TOTAL_OBJECTS                "total_objects"                
+
+DEFINIERT IN:
+    /sys/container.h
+
+BESCHREIBUNG:
+     Anzahl der Objekte im Container. Diese Property kann man nur abfragen!
+     Es werden nur Objekte gezaehlt, deren Methode short() einen
+     Wert != 0 zurueckgibt. Insofern koennen Spielern beliebig
+     viele unsichtbare Objekte gegeben werden ohne sie zu behindern.
+
+SIEHE AUCH:
+     P_MAX_OBJECTS
+
+26.Jan 2005 Gloinson
diff --git a/doc/props/P_TOTAL_WC b/doc/props/P_TOTAL_WC
new file mode 100644
index 0000000..35ef4a9
--- /dev/null
+++ b/doc/props/P_TOTAL_WC
@@ -0,0 +1,27 @@
+NAME:
+	P_TOTAL_WC			"total_wc"
+
+DEFINIERT IN:
+	/sys/properties.h
+
+BESCHREIBUNG:
+	In dieser Property wird der numerische Wert der Angriffsstaerke
+	eines Lebewesens registriert.
+  Hierzu werden die P_WC von P_WEAPON bzw. P_HANDS sowie die Kraft des
+  Lebewesens beruecksichtigt.
+	Nicht eingerechnet in die Angriffsstaerke sind natuerlich Extraspells und
+  -skills des Angreifers.
+  Braucht man den Wert mehrfach kurz hintereinander, sollte man die Prop aber
+  nur einmal abfragen und den Wert speichern (sofern sich in der Zwischenzeit
+  nichts an der Waffe, den Hands oder den Attributen des Lebenwesens aendert).
+
+BEMERKUNGEN:
+  Auf diese Property sollte nicht mittels Query() oder Set() zugegriffen 
+  werden, das Setzen von Query- oder Setmethoden bitte auf jeden Fall 
+  unterlassen.
+
+SIEHE AUCH:
+	P_HANDS, P_WC, P_XP
+
+----------------------------------------------------------------------------
+05.09.2008, Zesstra
diff --git a/doc/props/P_TOTAL_WEIGHT b/doc/props/P_TOTAL_WEIGHT
new file mode 100644
index 0000000..2b62db1
--- /dev/null
+++ b/doc/props/P_TOTAL_WEIGHT
@@ -0,0 +1,8 @@
+NAME:
+    P_TOTAL_WEIGHT                "total_weight"                
+
+DEFINIERT IN:
+    /sys/thing/restrictions.h
+
+BESCHREIBUNG:
+     Gewicht incl. Inhalt in Gramm. P_WEIGHT_PERCENT wird beruecksichtigt.
diff --git a/doc/props/P_TOUCH_DETAILS b/doc/props/P_TOUCH_DETAILS
new file mode 100644
index 0000000..d0670f6
--- /dev/null
+++ b/doc/props/P_TOUCH_DETAILS
@@ -0,0 +1,24 @@
+NAME:
+    P_TOUCH_DETAILS            "touch_details"
+
+DEFINIERT IN:
+    /sys/thing/description.h
+
+BESCHREIBUNG:
+    Diese Property entspricht dem P_DETAILS fuer Standarddetails,
+    nur werden hierin Gerueche gespeichert:
+    Diese Property enthaelt ein Mapping, in der Details im Objekt
+    definiert werden und Beschreibungen, die ausgegeben werden, wenn man
+    sich diese Details anschaut.
+
+BEMERKUNGEN:
+    Man sollte diese Property nicht per Hand veraendern, sondern die
+    Funktionen nutzen.
+
+SIEHE AUCH:
+    Setzen:    AddTouchDetail()
+    Loeschen:  RemoveTouchDetail()
+    Aehnlich:  AddDetail(), P_DETAILS
+    Sonstiges: GetDetail(), break_string()
+
+27. Jan 2013 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_TPORT_COST_IN b/doc/props/P_TPORT_COST_IN
new file mode 100644
index 0000000..d15e948
--- /dev/null
+++ b/doc/props/P_TPORT_COST_IN
@@ -0,0 +1,9 @@
+NAME:
+    P_TPORT_COST_IN               "tport_cost_in"               
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     In einem Raum mit Sehertor: Kostenanteil, um sich in den Raum zu
+     teleportieren
diff --git a/doc/props/P_TPORT_COST_OUT b/doc/props/P_TPORT_COST_OUT
new file mode 100644
index 0000000..369a35d
--- /dev/null
+++ b/doc/props/P_TPORT_COST_OUT
@@ -0,0 +1,9 @@
+NAME:
+    P_TPORT_COST_OUT              "tport_cost_out"              
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     In einem Raum mit Sehertor: Kostenanteil, sich aus dem Raum heraus
+     zu teleportieren
diff --git a/doc/props/P_TRANK_FINDEN b/doc/props/P_TRANK_FINDEN
new file mode 100644
index 0000000..8db2365
--- /dev/null
+++ b/doc/props/P_TRANK_FINDEN
@@ -0,0 +1,9 @@
+NAME:
+    P_TRANK_FINDEN                "trank_finden"                
+
+DEFINIERT IN:
+    /sys/player/potion.h
+
+BESCHREIBUNG:
+     Wenn die Property auf 1 steht kann immer ein Zaubertrank gefunden
+     werden, auch wenn er nicht in der Liste des Spielers steht.
diff --git a/doc/props/P_TRANSPARENT b/doc/props/P_TRANSPARENT
new file mode 100644
index 0000000..a081b00
--- /dev/null
+++ b/doc/props/P_TRANSPARENT
@@ -0,0 +1,29 @@
+P_TRANSPARENT
+NAME:
+     P_TRANSPARENT                 "transparent"
+
+DEFINIERT IN:
+     /sys/container.h
+
+BESCHREIBUNG:
+     ist != 0, wenn in einen Container hinein (offen) oder aus einem 
+     hinausgeschaut werden kann.
+
+     Schaut man aus einem hinaus, erhaelt der Spieler normalerweise die 
+     Meldung 'Ausserhalb siehst Du:'. Diese kann jedoch durch eine eigene, 
+     stimmigere  Meldung ersetzt werden, wenn in P_TRANSPARENT ein String 
+     mit dieser Meldung angegeben wird.
+
+BEISPIEL:
+     SetProp(P_TRANSPARENT,1); -> normale Meldung
+
+     SetProp(P_TRANSPARENT,"Vom Ruecken des Pferdes aus siehst Du:\n");
+
+     Diese Meldung ist natuerlich nur dann sinnvoll, wenn es sich
+     auch tatsaechlich um ein Pferd handelt :-)
+
+SIEHE AUCH:
+     int_long()
+
+----------------------------------------------------------------------------
+Last modified: Mon Jul 18 24:00:00 2001 by Tilly
diff --git a/doc/props/P_TRAVEL_CMDS b/doc/props/P_TRAVEL_CMDS
new file mode 100644
index 0000000..32f6f65
--- /dev/null
+++ b/doc/props/P_TRAVEL_CMDS
@@ -0,0 +1,38 @@
+NAME:
+    P_TRAVEL_CMDS                   "travel_cmds"                   
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+    Ein Array mit Befehlen, die zum Verlassen UND Betreten des Trans-
+    porters fuehren. 
+
+BEISPIEL:
+    void create()
+    {
+      ::create();
+
+      SetProp(P_TRAVEL_CMDS,({ "steig","steige" }) );
+
+    }
+
+    Als Parameter werden hier ausschliesslich 'auf,in' und 'von,aus'
+    verarbeitet.
+
+    steige auf|in  <xxx>    fuehrt also zum Betreten des Transporters,
+    steige von|aus <xxx>    dagegen fuehrt zum Verlassen desselben.
+
+BEMERKUNGEN:
+    Um /std/transport.c nicht aufzublaehen, werden weitere Parameter wie
+    etwa 'steige auf|in das|die|den xxx' _nicht_ unterstuetzt!
+
+    Hier muss der verantwortliche Magier schon eine eigene Loesung finden
+    und in seinen Transporter schreiben.
+
+SIEHE AUCH:
+    P_LEAVEFAIL, P_ENTERFAIL, P_ENTERCMDS, P_LEAVECMDS, transporter,
+
+LETZTER AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
+    
\ No newline at end of file
diff --git a/doc/props/P_TRAVEL_INFO b/doc/props/P_TRAVEL_INFO
new file mode 100644
index 0000000..b3a502e
--- /dev/null
+++ b/doc/props/P_TRAVEL_INFO
@@ -0,0 +1,31 @@
+NAME:
+    P_TRAVEL_INFO                 "travel_info"
+
+DEFINIERT IN:
+    /sys/transport.h
+
+BESCHREIBUNG:
+    Array mit Informationen zur vom Spieler gewuenschten Reiseroute.
+
+    [0]        Der Raum (object), in dem die Reiseroute momentan 
+               'aktiv' ist. Nur hier wird sie beruecksichtigt.
+
+    [1]        Das gewuenschte Transportmittel (object) falls 
+               gewaehlt. Ansonsten 0.
+
+    [2]        Der gewuenschte Zielort (string) oder 0 (ziellos).
+
+    [3]        Der gewuenschte Zielort als Richtung (string), falls
+               gewaehlt (z.B. 'zur Feuerinsel'). Sonst 0. Wird aus
+               P_HARBOUR des Zielraumes ausgelesen.
+
+BEMERKUNGEN:
+    Diese Property wird von /std/transport.c sowie std/player/travel.c
+    verwendet, und sollte NICHT von anderen Objekten oder per Hand 
+    veraendert werden!
+
+SIEHE AUCH:
+    /std/transport.c, /std/player/travel.c, reise
+
+LETZTER AENDERUNG:
+    Don, 24.01.2002, 10:15:07h von Tilly
diff --git a/doc/props/P_TRAY b/doc/props/P_TRAY
new file mode 100644
index 0000000..34c9d90
--- /dev/null
+++ b/doc/props/P_TRAY
@@ -0,0 +1,8 @@
+NAME:
+    P_TRAY                        "tray"                        
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    *** KEINE BESCHREIBUNG VORHANDEN ***
diff --git a/doc/props/P_TTY b/doc/props/P_TTY
new file mode 100644
index 0000000..9e4aded
--- /dev/null
+++ b/doc/props/P_TTY
@@ -0,0 +1,28 @@
+NAME:
+    P_TTY                         "tty"
+
+DEFINIERT IN:
+    /secure/telnetneg.h
+
+BESCHREIBUNG:
+     Name der Terminalemulation, die der Spieler nutzt.
+     Es existieren bisher "dumb", "vt100" und "ansi".
+
+	
+ANMERKUNG:
+     Farben duerfen ausschliesslich bei P_TTY=="ansi" benutzt werden.
+     Bei nicht farbfaehigen Terminals koennen ANSI-Codes die gesamte
+     Ausgabe zerschiessen!
+
+     Die Attribute fett, unterstrichen, blinkend und invers koennen auch
+     schon von vt100-Terminals dargestellt werden. Aber nicht ueberall
+     sind alle Attribute/Farben implementiert.
+
+     Bei allen ANSI-Codes sind drei Sachen zu beachten:
+     
+        1) Sparsam benutzen! Aufgezwungene Hervorhebungen koennen
+	   Spieler ganz schnell nerven.
+
+	2) Nicht jeder benutzt dieselbe Hintergrundfarbe!
+
+	3) Sparsam benutzen! Beser noch: nur im Notfall!
diff --git a/doc/props/P_TTY_COLS b/doc/props/P_TTY_COLS
new file mode 100644
index 0000000..1716a33
--- /dev/null
+++ b/doc/props/P_TTY_COLS
@@ -0,0 +1,22 @@
+NAME:
+    P_TTY_COLS                                  "tty_cols"
+
+DEFINIERT IN:
+    /secure/telnetneg.h
+
+BESCHREIBUNG:
+    In dieser Properties steht die Anzahl der Spalten, die das 
+    Terminalfenster des Spielers derzeit hat.
+
+    Voraussetzung hierfuer ist allerdings, dass das Telnet des Spielers
+    Telnetnegotiations unterstuetzt, ansonsten bleibt diese Property
+    leer.
+    Das Setzen der Property aendert die Fenstergroesse des Spielers
+    natuerlich nicht.
+
+SIEHE AUCH:
+    P_TTY_ROWS, P_TTY_TYPE, P_TTY_SHOW
+
+LETZTE AeNDERUNG:
+    Sat, 06.02.1999, 14:00:00 von Paracelsus
+
diff --git a/doc/props/P_TTY_ROWS b/doc/props/P_TTY_ROWS
new file mode 100644
index 0000000..1294d9b
--- /dev/null
+++ b/doc/props/P_TTY_ROWS
@@ -0,0 +1,22 @@
+NAME:
+    P_TTY_ROWS                                  "tty_rows"
+
+DEFINIERT IN:
+    /secure/telnetneg.h
+
+BESCHREIBUNG:
+    In dieser Properties steht die Anzahl der Zeilen, die das
+    Terminalfenster des Spielers derzeit hat.
+
+    Voraussetzung hierfuer ist allerdings, dass das Telnet des Spielers
+    Telnetnegotiations unterstuetzt, ansonsten bleibt diese Property
+    leer.
+    Das Setzen der Property aendert die Fenstergroesse des Spielers
+    natuerlich nicht.
+
+SIEHE AUCH:
+    P_TTY_COLS, P_TTY_TYPE, P_TTY_SHOW
+
+LETZTE AeNDERUNG:
+    Sat, 06.02.1999, 14:00:00 von Paracelsus
+
diff --git a/doc/props/P_TTY_SHOW b/doc/props/P_TTY_SHOW
new file mode 100644
index 0000000..f727433
--- /dev/null
+++ b/doc/props/P_TTY_SHOW
@@ -0,0 +1,17 @@
+NAME:
+    P_TTY_SHOW                                  "tty_show"
+
+DEFINIERT IN:
+    /secure/telnetneg.h
+
+BESCHREIBUNG:
+    Bei Telnets, die Telnetnegotiations unterstuetzen, wird eine Aenderung
+    der Fenstergroesse dem Spielerobjekt mitgeteilt. Steht in P_TTY_SHOW
+    ein Wert ungleich Null, wird dem Spieler diese Aenderung mitgeteilt.
+
+SIEHE AUCH:
+    P_TTY_ROWS, P_TTY_COLS, P_TTY_TYPE, telnegs
+
+LETZTE AeNDERUNG:
+    Sat, 06.02.1999, 14:00:00 von Paracelsus
+
diff --git a/doc/props/P_TTY_TYPE b/doc/props/P_TTY_TYPE
new file mode 100644
index 0000000..6935b23
--- /dev/null
+++ b/doc/props/P_TTY_TYPE
@@ -0,0 +1,23 @@
+NAME:
+    P_TTY_TYPE                                  "tty_type"
+
+DEFINIERT IN:
+    /secure/telnetneg.h
+
+BESCHREIBUNG:
+    In dieser Properties steht der Terminaltyp, den ein Spieler lokal auf
+    seinem Rechner verwendet.
+
+    Voraussetzung hierfuer ist allerdings, dass das Telnet des Spielers
+    Telnetnegotiations unterstuetzt, ansonsten bleibt diese Property
+    leer. Die meisten Telnets/Clients geben ihren Terminaltyp allerdings
+    nicht preis.
+    Das Setzen der Property aendert den Terminaltyp des Spielers
+    natuerlich nicht.
+
+SIEHE AUCH:
+    P_TTY_COLS, P_TTY_ROWS, P_TTY_SHOW
+
+LETZTE AeNDERUNG:
+    Sat, 06.02.1999, 14:00:00 von Paracelsus
+
diff --git a/doc/props/P_UNIT_DECAY_FLAGS b/doc/props/P_UNIT_DECAY_FLAGS
new file mode 100644
index 0000000..f924ff7
--- /dev/null
+++ b/doc/props/P_UNIT_DECAY_FLAGS
@@ -0,0 +1,70 @@
+P_UNIT_DECAY_FLAGS
+
+NAME:
+     P_UNIT_DECAY_FLAGS					"unit_decay_flags"
+
+DEFINIERT IN:
+     /sys/unit.h
+
+BESCHREIBUNG:
+     Mit dieser Prop kann das Zerfallsverhalten gesteuert werden, entweder
+     fuer alle Clones durch Setzen in der Blueprint oder fuer einzelne Clones.
+
+     In dieser Prop koennen momentan 4 Flags gesetzt werden:
+     - NO_DECAY: 
+          Zerfall ist abgeschaltet.
+     - NO_DECAY_UNTIL_MOVE: 
+          Der Zerfall ist solange ausgesetzt, bis dieses Objekt in ein anderes
+          Env bewegt wird. Setzt also ein NPC beim AddItem() diese Prop,
+          zerfaellt seine Unit nicht, bis sie bewegt wurde (Leiche, Spieler
+          etc.). Hierbei zaehlt das move() nicht, wenn das Objekt noch kein
+          Env hatte, es zaehlen nur Moves von einem Env in ein anderes Env.
+          Dieses Flag sollte nur in Clones gesetzt werden.
+     - INACCURATE_DECAY
+          Sollen z.b. 45.34 Einheiten zerfallen, wird der Rest von 0.34
+          normalerweise als Wahrscheinlichkeit aufgefasst, dass eine
+          zusaetzliche Einheit zerfaellt. Dieses Flag sorgt dafuer, dass
+          dieser Rest weggeworfen wird und einfach 45 Einheiten zerfallen.
+          Gleichzeitig wird bei diesem Flag aber _immer min_ 1 Einheit
+          zerstoert!
+     - ABSOLUTE_DECAY
+          P_UNIT_DECAY_QUOTA wird nicht als prozentualer Anteil aufgefasst,
+          sondern als absolute Zahl, d.h. es zerfallen immer einfach
+          P_UNIT_DECAY_QUOTA Einheiten.
+
+     Diese Flags koennen z.B. genutzt werden, den Zerfall fuer einzelne
+     Objekte temporaer oder dauerhaft abzuschalten, auch wenn alle anderen
+     Clones weiterzerfallen.
+
+     Diese Prop kann in der Blueprint gesetzt werden. In diesem Fall wird
+     allerdings NO_DECAY_UNTIL_MOVE ignoriert, weil die BP ja nie bewegt
+     wuerde. NO_DECAY in der BP schaltet den Zerfallsprozess (temporaer) fuer
+     alle Clones aus. Ist nie ein Zerfall gewuenscht, sollte in der Blueprint
+     aber besser P_UNIT_DECAY_INTERVAL auf 0 gesetzt werden!
+
+     Ist die Prop in einem einzelnen Clone nicht explizit gesetzt,
+     liefert ein klon->QueryProp(P_UNIT_DECAY_FLAGS) den in der Blueprint
+     eingestellten Wert zurueck.
+     
+BEMERKUNGEN:
+     * Setzt man diese Prop in einem Clone auf 0, wird der Wert aus der
+       Blueprint zurueckgeben. Hierbei wird allerdings ein NO_DECAY_UNTIL_MOVE
+       ausgefiltert, da dies den Zerfall fuer alle Objekte dauerhaft stoppen
+       wuerde, weil BPs nicht bewegt werden.
+     * Die Flags koennen "verodert" werden:
+       SetProp(P_UNIT_DECAY_FLAGS, NO_DECAY_UNTIL_MOVE | ABSOLUTE_DECAY);
+
+BEISPIEL:
+     // Dieser NPC hat tolle Pfeile, die sollen aber nicht zerfallen, solange
+     // sie im Inventar des NPCs sind:
+     AddItem("/d/tolleregion/tollermagier/obj/pfeile", REFRESH_NONE,
+         ([ P_AMOUNT: 50+random(50),
+            P_UNIT_DECAY_FLAGS: NO_DECAY_UNTIL_MOVE ]) );
+
+SIEHE AUCH:
+     unit
+     P_UNIT_DECAY_INTERVAL, P_UNIT_DECAY_QUOTA, P_UNIT_DECAY_MIN
+     DoDecay, DoDecayMessage
+     /std/unit.c
+
+14.10.2007, Zesstra
diff --git a/doc/props/P_UNIT_DECAY_INTERVAL b/doc/props/P_UNIT_DECAY_INTERVAL
new file mode 100644
index 0000000..93154cd
--- /dev/null
+++ b/doc/props/P_UNIT_DECAY_INTERVAL
@@ -0,0 +1,37 @@
+P_UNIT_DECAY_INTERVAL
+
+NAME:
+     P_UNIT_DECAY_INTERVAL					"unit_decay_interval"
+
+DEFINIERT IN:
+     /sys/unit.h
+
+BESCHREIBUNG:
+     Diese Prop bestimmt, wie oft ein Zerfall der entsprechenden Unitobjekte
+     durchgefuehrt wird. Das Intervall ist in Sekunden anzugeben (int).
+     Die Prop muss in der Blueprint der entsprechenden Unitobjekte gesetzt
+     werden, in Clones kann sie nicht gesetzt werden.
+     Die Blueprint resettet dann in diesem Intervall und ruft in allen ihren
+     Clones (und denen alter Versionen der gleichen BP!) DoDecay() auf,
+     woraufhin die Clones den Zerfall durchfuehren.
+     Ist die Prop in der Blueprint nicht gesetzt, erfolgt kein Zerfall.
+
+BEMERKUNGEN:
+     * Ist die Blueprint nicht geladen, erfolgt kein Zerfall der Clones.
+     * Ein Setzen dieser Prop beinhaltet immer auch einen Aufruf von
+       set_next_reset() auf das ensprechende Intervall.
+     * Die Prop kann in den Clones abgefragt werden und liefert das in der
+       Blueprint eingestellte Intervall.
+     * Von einer Manipulation per Set() wird dringend abgeraten.
+     * Die Prop kann nur vom Objekt selber, vom Programmierer des Objekts, vom
+       RM der entsprechenden Region, von einem Weisen oder von einem Objekt
+       gesetzt werden, welches die gleiche UID hat.
+
+BEISPIEL:
+
+SIEHE AUCH:
+     unit
+     P_UNIT_DECAY_QUOTA, P_UNIT_DECAY_FLAGS, P_UNIT_DECAY_MIN
+     DoDecay(), DoDecayMessage()
+
+13.10.2007, Zesstra
diff --git a/doc/props/P_UNIT_DECAY_MIN b/doc/props/P_UNIT_DECAY_MIN
new file mode 100644
index 0000000..79f9c80
--- /dev/null
+++ b/doc/props/P_UNIT_DECAY_MIN
@@ -0,0 +1,51 @@
+P_UNIT_DECAY_MIN
+
+NAME:
+     P_UNIT_DECAY_MIN					                    "unit_decay_min"
+
+DEFINIERT IN:
+     /sys/unit.h
+
+BESCHREIBUNG:
+     Diese Prop bestimmt, wieviele Einheiten der Unitobjekten mindestens
+     uebrig bleiben sollen. 
+     Faellt die Menge eines Unitobjekts unter diesen Wert, zerfaellt diese
+     Unit solange nicht weiter, bis der Wert wieder ueberschritten wird.
+     Die Prop kann in der Blueprint und in den einzelnen Clones gesetzt
+     werden.
+     Ist die Prop in einem einzelnen Clone nicht explizit gesetzt,
+     liefert ein QueryProp(P_UNIT_DECAY_MIN) den in der Blueprint
+     eingestellten Wert zurueck und die Unit zerfaellt bis zu dieser
+     Mindestmenge..
+     D.h. man sollte diese Prop in der Blueprint setzen und in einzelnen
+     Clones nur soweit diese abweichende Werte haben sollen.
+     Es sind nur Werte zwischen 0 und 100 zulaessig. Auf diese Art laesst sich
+     die minidestens uebrig bleibende Menge aller Clones durch Aendern einer
+     Prop in der Blueprint aendern.
+
+BEMERKUNGEN:
+     * Setzt man diese Prop in einem Clone auf 0, wird der Wert aus er
+       Blueprint zum Zerfall benutzt.
+     * Will man fuer ein bestimmtes Unitobjekt kein Minimum haben, also dass
+       dieses Objekt zerfaellt, bis nichts mehr da ist, die Blueprint hat aber
+       einen Minimalwert gesetzt, sollte diese Prop im betreffenden Objekt auf
+       -1 gesetzt werden.
+     * Diese Prop sollte vorsichtig angewandt werden, da Spieler so den
+       Zerfall von Units stoppen koennen, indem sie die Units entsprechend
+       aufteilen, so dass jedes Einzelobjekt unter dem Minimum liegt.
+
+BEISPIEL:
+     // es soll min. 1 Einheit uebrig bleiben.
+     SetProp(P_UNIT_DECAY_MIN, 1);
+
+     // die Blueprint hat ein Minimum von 10 gesetzt, dieser Clone soll
+     // aber zerfallen, bis nix mehr da ist.
+     klon->SetProp(P_UNIT_DECAY_MIN, -1);
+
+SIEHE AUCH:
+     unit
+     P_UNIT_DECAY_INTERVAL, P_UNIT_DECAY_FLAGS, P_UNIT_DECAY_QUOTA
+     DoDecay, DoDecayMessage
+     /std/unit.c
+
+14.10.2007, Zesstra
diff --git a/doc/props/P_UNIT_DECAY_QUOTA b/doc/props/P_UNIT_DECAY_QUOTA
new file mode 100644
index 0000000..9144564
--- /dev/null
+++ b/doc/props/P_UNIT_DECAY_QUOTA
@@ -0,0 +1,45 @@
+P_UNIT_DECAY_QUOTA (int)
+
+NAME:
+     P_UNIT_DECAY_QUOTA					"unit_decay_quota"
+
+DEFINIERT IN:
+     /sys/unit.h
+
+BESCHREIBUNG:
+     Diese Prop bestimmt, welcher Anteil der einzelnen Unitobjekte pro Zerfall
+     zerstoert wird. Dieser Anteil wird als ganze Zahl zwischen 0 und 10000
+     ausgedrueckt. 1 entspricht einem Zerfall von 0.01%, 10000 entspricht
+     100%.
+     Momentan sind keine Werte < 0 zulaessig, die einem Zuwachs entsprechend
+     wurden.
+
+     Falls das Flag ABSOLUTE_DECAY (s. P_UNIT_DECAY_FLAGS) gesetzt ist, steht
+     die Zahl in dieser Prop fuer die absolute Anzahl an zu zerstoerenden
+     Einheiten.
+
+     Die Prop kann in der Blueprint und in den einzelnen Clones gesetzt
+     werden.
+     Ist die Prop in einem einzelnen Clone nicht explizit gesetzt,
+     liefert ein QueryProp(P_UNIT_DECAY_QUOTA) den in der Blueprint
+     eingestellten Wert zurueck und die Unit zerfaellt zu diesem Anteil.
+     D.h. man sollte diese Prop in der Blueprint setzen und in einzelnen
+     Clones nur soweit diese abweichende Zerfallsraten haben sollen.
+
+BEMERKUNGEN:
+     * Setzt man diese Prop in einem Clone auf 0, wird der Wert aus er
+       Blueprint zum Zerfall benutzt.
+     * Will man den Zerfall fuer ein bestimmtes Unitobjekt abschalten, sollte
+       man P_UNIT_DECAY_FLAGS benutzen.
+
+BEISPIEL:
+     // pro Zerfallsintervall sollen 12% zerfallen.
+     SetProp(P_UNIT_DECAY_QUOTA, 1200);
+
+SIEHE AUCH:
+     unit
+     P_UNIT_DECAY_INTERVAL, P_UNIT_DECAY_FLAGS, P_UNIT_DECAY_MIN
+     DoDecay, DoDecayMessage
+     /std/unit.c
+
+14.03.2008, Zesstra
diff --git a/doc/props/P_UNWEAR_MSG b/doc/props/P_UNWEAR_MSG
new file mode 100644
index 0000000..1ee0d80
--- /dev/null
+++ b/doc/props/P_UNWEAR_MSG
@@ -0,0 +1,56 @@
+P_UNWEAR_MSG
+NAME:
+     P_UNWEAR_MSG                       "unwear_msg"     
+
+DEFINIERT IN:
+     /sys/armour.h
+
+BESCHREIBUNG:
+     Zweiteiliges Array mit Meldungen, die beim Ausziehen einer Ruestung 
+     oder Kleidung an den Spieler und die Umgebung ausgegeben werden.
+     Der erste Eintrag geht an den Spieler, der zweite Eintrag an die
+     Umgebung. Zeilenumbrueche werden automatisch gemacht, existierende
+     jedoch beruecksichtigt.
+
+     Platzhalter fuer Spieler ist @WExxx1, fuer die Waffe @WExxx2 (siehe
+     man replace_personal()).
+
+     [Wegen Abwaertskompatibilitaet ist auch noch der Platzhalter %s
+      moeglich, wobei in der eigenen Meldung %s fuer den Waffennamen steht,
+      in der an den Raum das erste %s fuer den Spielernamen, das zweite fuer
+      den Waffennamen.]
+
+BEISPIELE:
+    SetProp(P_NAME, "Mantel");
+    SetProp(P_UNWEAR_MSG,
+     ({"Du reisst Dir @WEN2 vom Leib.",
+       "@WER1 reisst sich @WENU2 vom Leib." }));
+
+    -> beim Ausziehen durch Urk:
+       Urk bekommt: Du reisst dir den Mantel vom Leib.
+       Der Raum:    Urk reisst sich einen Mantel vom Leib.
+
+    SetProp(P_UNWEAR_MSG,
+     ({"Dir wird furchtbar warm. So eine Hitze aber auch. Schnell "
+       "schluepfst Du aus Deiner dicken Ruestung. Aaaah, was fuer "
+       "eine Wohltat.",
+       "@WEM1 scheint ploetzlich warm zu werden. Schnell schluepft "
+       "@WERQP1 aus @WEMQPPFS1 dicken Ruestung. Du hoffst instaendig, "
+       "das es noch etwas waermer wird ... "}));
+
+    -> beim Ausziehen durch Urk:
+       Urk bekommt: Dir wird furchtbar warm. So eine Hitze aber auch.
+		    Schnell schluepfst Du aus Deiner dicken Ruestung.
+		    Aaaah, was fuer eine Wohltat.
+       Der Raum:    Urk scheint ploetzlich warm zu werden. Schnell
+		    schluepft er aus seiner dicken Ruestung. Du hoffst
+		    instaendig, das es noch etwas waermer wird ...
+SIEHE AUCH:
+     Aehnliches: P_WEAR_MSG, P_WIELD_MSG, P_UNWIELD_MSG
+                 P_DROP_MSG, P_PUT_MSG, P_GIVE_MSG, P_PICK_MSG
+     Funktionen: WearFunc, UnwearFunc
+     Sonstiges:  replace_personal(E), /std/armour/wear.c, armours
+                 clothing, /std/clothing.wear.c
+
+LETZTE AeNDERUNG:
+15.02.2009, Zesstra
\ No newline at end of file
diff --git a/doc/props/P_UNWIELD_FUNC b/doc/props/P_UNWIELD_FUNC
new file mode 100644
index 0000000..da0fa7c
--- /dev/null
+++ b/doc/props/P_UNWIELD_FUNC
@@ -0,0 +1,19 @@
+P_UNWIELD_FUNC
+
+NAME:
+     P_UNWIELD_FUNC "unwield_func"
+
+DEFINIERT IN:
+     <weapon.h>
+
+BESCHREIBUNG:
+     Falls ein Objekt eine UnwieldFunc() fuer die Waffe definiert, so muss
+     dieses Objekt in dieser Property eingetragen werden.
+
+     Die Auswertung dieser Property erfolgt in DoUnwield().
+
+SIEHE AUCH:
+     /std/weapon.c, UnwieldFunc()
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 15:44:08 1996 by Wargon
diff --git a/doc/props/P_UNWIELD_MSG b/doc/props/P_UNWIELD_MSG
new file mode 100644
index 0000000..49a6466
--- /dev/null
+++ b/doc/props/P_UNWIELD_MSG
@@ -0,0 +1,59 @@
+P_UNWIELD_MSG
+NAME:
+     P_UNWIELD_MSG                       "unwield_msg"                       
+
+DEFINIERT IN:
+     /sys/weapon.h
+
+BESCHREIBUNG:
+     Zweiteiliges Array mit Meldungen, die beim Wegstecken einer 
+     Waffe an den Spieler und die Umgebung ausgegeben werden.
+
+     Der erste Eintrag geht an den Spieler, der zweite Eintrag an die
+     Umgebung.  Zeilenumbrueche werden automatisch gemacht, existierende
+     jedoch beruecksichtigt.
+
+     Platzhalter fuer Spieler ist @WExxx1, fuer die Waffe @WExxx2 (siehe
+     man replace_personal()).
+
+     [Wegen Abwaertskompatibilitaet ist auch noch der Platzhalter %s
+      moeglich, wobei in der eigenen Meldung %s fuer den Waffennamen steht,
+      in der an den Raum das erste %s fuer den Spielernamen, das zweite fuer
+      den Waffennamen.]
+
+BEISPIELE:
+    SetProp(P_NAME, "Streitkolben");
+    SetProp(P_UNWIELD_MSG,
+     ({ "Du steckst @WEN2 zurueck und atmest erstmal tief durch.", 
+        "@WER1 steckt @WENU2 zurueck und atmet erstmal tief durch." }));
+
+    -> beim Wegstecken durch Urk:
+       Urk bekommt: Du steckst den Streitkolben zurueck und atmest erstmal
+		    tief durch.
+       Der Raum:    Urk steckt einen Streitkolben zurueck und atmet erstmal
+		    tief durch.
+
+    SetProp(P_UNWIELD_MSG,
+     ({"Du steckst die schwere Keule zurueck. Zufaellig landet sie "
+       "dabei auf Deinem Fuss. Laut schreiend humpelst Du in der "
+       "Gegend herum.",
+       "@WER1 steckt eine schwere Keule zurueck. Dummerweise landet diese "
+       "direkt auf dem eigenen Fuss. Aua, das tat sicher weh ... nicht "
+       "umsonst humpelt @WERQP1 jetzt schreiend durch die Gegend."}));
+
+    -> beim Wegstecken durch Urk:
+       Urk bekommt: Du steckst die schwere Keule zurueck. Zufaellig landet
+		    sie dabei auf Deinem Fuss. Laut schreiend humpelst Du in
+		    der Gegend herum.
+       Der Raum:    Urk steckt eine schwere Keule zurueck. Dummerweise
+		    landet diese direkt auf dem eigenen Fuss. Aua, das tat
+                    sicher weh ... nicht umsonst humpelt er jetzt schreiend
+                    durch die Gegend.
+
+SIEHE AUCH:
+     Aehnliches: P_WIELD_MSG, P_WEAR_MSG, P_UNWEAR_MSG
+                 P_DROP_MSG, P_PUT_MSG, P_GIVE_MSG, P_PICK_MSG
+     Funktionen: UnwieldFunc, WieldFunc
+     Sonstiges:  replace_personal(E), /std/weapon/combat.c
+
+29. Maerz 2004 Gloinson
diff --git a/doc/props/P_UNWIELD_TIME b/doc/props/P_UNWIELD_TIME
new file mode 100644
index 0000000..43128d4
--- /dev/null
+++ b/doc/props/P_UNWIELD_TIME
@@ -0,0 +1,19 @@
+P_UNWIELD_TIME
+
+NAME:
+      P_UNWIELD_TIME			"unwield_time"
+
+DEFINIERT IN:
+      /sys/weapon.h

+
+BESCHREIBUNG:
+      Enthaelt den Zeitpunkt zu dem ein Living eine Waffe weggesteckt hat und

+      ist im Living gesetzt.

+
+SIEHE AUCH:

+      Verwandt:		P_WEAPON, P_WIELDED, DoUnwield()

+			P_LAST_USE
+      Sonstiges:	P_EQUIP_TIME

+			time()
+
+10.Feb 2005 Gloinson

diff --git a/doc/props/P_USED_HANDS b/doc/props/P_USED_HANDS
new file mode 100644
index 0000000..456d32c
--- /dev/null
+++ b/doc/props/P_USED_HANDS
@@ -0,0 +1,21 @@
+P_USED_HANDS
+NAME:
+    P_USED_HANDS                  "used_hands"
+
+DEFINIERT IN:
+    /sys/living/combat.h
+
+BESCHREIBUNG:
+    Anzahl der Haende in Benutzung.
+    Effektiv nur ein sizeof(P_HANDS_USED_BY).
+
+BEMERKUNGEN:
+    Keine echte Property. Die Methode /std/living/combat::_query_used_hands
+    stellt die Daten zusammen. Nicht setzen!
+
+SIEHE AUCH:
+    P_HANDS, P_HANDS_USED_BY
+    P_MAX_HANDS, P_FREE_HANDS
+    UseHands, FreeHands
+
+1. Okt 2012, Gloinson
diff --git a/doc/props/P_VALID_GUILDS b/doc/props/P_VALID_GUILDS
new file mode 100644
index 0000000..2734ad9
--- /dev/null
+++ b/doc/props/P_VALID_GUILDS
@@ -0,0 +1,23 @@
+NAME:
+	P_VALID_GUILDS			"valid_guilds"                
+
+DEFINIERT IN:
+	/sys/new_skills.h
+
+BESCHREIBUNG:
+	Diese Property enthaelt die zugelassenen Gilden in Form von
+	kleingeschriebenen Gildennamen, welche in einem Array
+	zusammengefasst sind. Sie ist nur fuer den Gildenmaster selbst von
+	Bedeutung.
+
+BEISPIELE:
+	Abfrage der zugelassenen Gilden:
+	  find_object("/obj/gildenmaster")->QueryProp(P_VALID_GUILDS)
+	Das ergibt zum Beispiel:
+          ({"abenteurer","zauberer","klerus","kaempfer"})
+
+SIEHE AUCH:
+	P_GUILD, /obj/gildenmaster.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_VALUE b/doc/props/P_VALUE
new file mode 100644
index 0000000..d9b5961
--- /dev/null
+++ b/doc/props/P_VALUE
@@ -0,0 +1,26 @@
+NAME:
+    P_VALUE                       "value"                       
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+
+     - Objekte
+       Wert des Objektes in Goldmuenzen. Diesen Wert erhaelt man beim
+       Verkauf. Kaufen kostet ein Vielfaches hiervon.
+
+     - Speisen/Kneipen
+       Wert einer Portion der Speise.
+       
+BEMERKUNGEN:
+     In tragbaren Speisen (erben von /std/food) setzt man mit SetProp
+     den Wert _einer_ Portion. Per QueryProp erhaelt man aber den Gesamt-
+     wert der Speise inclusive des eventuell vorhandenen Behaelters. Der
+     Wert des Behaelters wird dabei aus P_EMPTY_PROPS[P_VALUE] gelesen.
+     
+SIEHE AUCH:
+     Speisen: std/pub, wiz/food, P_EMPTY_PROPS
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_VALUE_PER_UNIT b/doc/props/P_VALUE_PER_UNIT
new file mode 100644
index 0000000..da779c5
--- /dev/null
+++ b/doc/props/P_VALUE_PER_UNIT
@@ -0,0 +1,14 @@
+NAME:
+    P_VALUE_PER_UNIT              "value_per_unit"              
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Wert in Goldstuecken pro Untereinheit.
+
+BEMERKUNGEN:
+     Deprecated. Bitte SetCoinsPerUnits() (U_CPU) benutzen.
+
+25.Aug 2015 Gloinson
+
diff --git a/doc/props/P_VARIABLES b/doc/props/P_VARIABLES
new file mode 100644
index 0000000..5e7fb5c
--- /dev/null
+++ b/doc/props/P_VARIABLES
@@ -0,0 +1,16 @@
+
+NAME:
+    P_VARIABLES "variables"                 
+
+DEFINIERT IN:
+    /sys/magier.h
+
+BESCHREIBUNG:
+	
+     Interne Variable der Magiershell in dem die mit dem 'Set'-Befehl
+     gesetzten Variablen gespeichert werden.
+     
+     NICHT VON HAND VERAENDERN! IMMER 'SET' VERWENDEN!
+
+----------------------------------------------------------------------------
+Letzte Aenderung: 13.02.2003 22:00:00 von Mandragon
diff --git a/doc/props/P_VISIBLE_GUILD b/doc/props/P_VISIBLE_GUILD
new file mode 100644
index 0000000..df267b5
--- /dev/null
+++ b/doc/props/P_VISIBLE_GUILD
@@ -0,0 +1,25 @@
+P_VISIBLE_GUILD
+NAME:
+     P_VISIBLE_GUILD			"visible_guild"                       
+
+DEFINIERT IN:
+     /sys/properties.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt die sichtbare Gilde des Lebewesens in Form eines
+     kleingeschriebenen Strings, also die Gilde, die bei Spielern zum
+     Beispiel bei 'kwer' oder 'finger' angezeigt wird. So kann man fremde
+     Gilden testen und trotzdem nach aussen hin in der gleichen Gilde wie
+     zuvor bleiben.
+
+BEISPIEL:
+     Wenn man gerne nach aussen hin Zauberer bleiben moechte:
+	  pl->SetProp(P_VISIBLE_GUILD,"zauberer");
+     Nach aussen hin bleibt man jetzt auch Zauberer, wenn P_GUILD eine
+     andere Gilde angibt.
+
+SIEHE AUCH:
+     P_GUILD, P_DEFAULT_GUILD
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/P_VISIBLE_SUBGUILD_TITLE b/doc/props/P_VISIBLE_SUBGUILD_TITLE
new file mode 100644
index 0000000..e398f02
--- /dev/null
+++ b/doc/props/P_VISIBLE_SUBGUILD_TITLE
@@ -0,0 +1,21 @@
+P_VISIBLE_SUBGUILD_TITLE
+NAME:
+     P_VISIBLE_SUBGUILD_TITLE		"visible_subguild_title"                       
+DEFINIERT IN:
+     /sys/new_skills.h
+
+BESCHREIBUNG:
+     Diese Property dient dazu, als Magier einen Zusatztitel innerhalb einer
+     Gilde vorzutaeuschen, ohne den tatsaechlichen P_SUBGUILD_TITLE zu
+     aendern.
+
+BEMERKUNGEN:
+     Inhalt der Property kann 0 sein oder ein String.
+     Wenn der Inhalt 0 ist, wird bei QueryProp der P_SUBGUILD_TITLE
+     durchgereicht.
+
+SIEHE AUCH:
+     P_GUILD_TITLE, P_SUBGUILD_TITLE
+
+----------------------------------------------------------------------------
+Last modified: Mon Aug 13 21:20:00 2001 by Nachtwind
diff --git a/doc/props/P_VISUALBELL b/doc/props/P_VISUALBELL
new file mode 100644
index 0000000..19e8519
--- /dev/null
+++ b/doc/props/P_VISUALBELL
@@ -0,0 +1,37 @@
+NAME:
+	P_VISUALBELL			"visualbell"
+
+DEFINIERT IN:
+	/sys/properties.h
+
+BESCHREIBUNG:
+	Die Property stellt ein Flag innerhalb von Spielern dar, welches
+	standardmaessig nicht gesetzt ist. In diesem Fall werden Toene,
+	welche innerhalb einiger Funktionen erzeugt werden, auch wirklich an
+	den Spieler geschickt.
+	Setzt man die Property, so erhaelt der Spieler keine Toene mehr.
+
+BEISPIEL:
+	Pieptoene werden durch den ASCII-Code 0x7 praesentiert. Ausgeben
+	kann man diesen folgendermassen:
+	  if(!IS_WIZARD(caster)&&!victim->QueryProp(P_VISUALBELL))
+	    tell_object(victim,sprintf("%c",7));
+	Das waere beispielsweise ein Codestueck aus einem Piepspell. :)
+	Das Opfer bekommt den Piepton hierbei nur ab, wenn der Caster ein
+	Magier ist oder das Spieleropfer die Property P_VISUALBELL gesetzt
+	hat (kann mit Kommando 'ton' vom Spieler beeinflusst werden).
+
+BEMERKUNGEN:
+  Achtung: P_VISUALBELL steht auf 1, wenn der Spieler _keine_ Piepstoene
+	hoeren will!
+	Die Funktionalitaet dieser Property wirkt nur soweit, wie sie auch
+	von tonerzeugenden Befehlen selbst unterstuetzt wird. Es ist darauf
+	zu achten, dass P_VISUALBELL zu diesem Zweck grundsaetzlich
+	ausgewertet wird! Eine Ausnahme sei hierbei zugelassen: Magier
+	koennen Spielern grundsaetzlich Toene zusenden.
+
+SIEHE AUCH:
+	ton, wecke, erwarte, P_WAITFOR, /std/player/base.c
+
+----------------------------------------------------------------------------
+Last modified: 07.02.2007 by Zesstra
diff --git a/doc/props/P_VULNERABILITY b/doc/props/P_VULNERABILITY
new file mode 100644
index 0000000..7e1c676
--- /dev/null
+++ b/doc/props/P_VULNERABILITY
@@ -0,0 +1,37 @@
+NAME:
+     P_VULNERABILITY               "vulnerability"
+
+DEFINIERT IN:
+     /sys/living/combat.h
+
+WICHTIG:
+     DIESE PROPERTY IST VERALTET! BITTE P_RESISTANCE_STRENGTHS
+     VERWENDEN! AUCH FUNKTIONIERT Set() NICHT WIE ES SOLLTE.
+
+BESCHREIBUNG:
+     Hiermit koennen die Empfindlichkeiten eines Lebewesens definiert
+     werden. Es kann ein Array mit Schadensarten gesetzt werden, jeder
+     Eintrag eines Schadens verdoppelt die Empfindlichkeit gegen
+     diesen.
+
+BEMERKUNGEN:
+     - P_RESISTANCE_STRENGTHS spiegelt die Eintraege hier wieder
+     - um genauere Werte anzugeben einen AddResistanceModifier() oder
+       P_RESISTANCE_STRENGTHS benutzen.
+     - P_VULNERABILITY kann und wird nicht aus P_RESISTANCE_STRENGTHS
+       upgedatet
+
+BEISPIELE:
+     // ein NPC mit verdoppelter Eisempfindlichkeit und
+     // vervierfachter Wasserempfindlichkeit
+     SetProp(P_VULNERABILITY, ({DT_COLD, DT_WATER, DT_WATER}));
+
+SIEHE AUCH:
+     simple Resistenz:	P_RESISTANCE
+     Hauptmapping:	P_RESISTANCE_STRENGTHS
+     Modifikatoren:	AddResistanceModifier, RemoveResistanceModifier(),
+			P_RESISTANCE_MODIFIER
+     Berechnung:	CheckResistance(), UpdateResistanceStrengths()
+     anderes:		balance, /std/armour/combat.c, /std/living/combat.c
+
+1.Dez 2004, Gloinson
diff --git a/doc/props/P_WAITFOR b/doc/props/P_WAITFOR
new file mode 100644
index 0000000..a8cf8ee
--- /dev/null
+++ b/doc/props/P_WAITFOR
@@ -0,0 +1,14 @@
+NAME:
+     P_WAITFOR                     "waitfor"                     
+
+DEFINIERT IN:
+     /sys/player/base.h
+
+BESCHREIBUNG:
+     Die Erwarte-Liste. Ein Array mit den Namen der Erwarteten.
+
+SIEHE AUCH:
+     erwarte
+     P_WAITFOR_REASON, P_WAITFOR_FLAGS
+
+16. Feb 2008 Gloinson
diff --git a/doc/props/P_WAITFOR_FLAGS b/doc/props/P_WAITFOR_FLAGS
new file mode 100644
index 0000000..f137dd1
--- /dev/null
+++ b/doc/props/P_WAITFOR_FLAGS
@@ -0,0 +1,17 @@
+P_WAITFOR_FLAGS
+NAME:
+     P_WAITFOR_FLAGS                  "waitfor_flags"                     
+
+DEFINIERT IN:
+     /sys/player/base.h
+
+BESCHREIBUNG:
+     Ein Int. Bisher bekannte Flags:
+     
+     0x01 - "erwarte aus"
+
+SIEHE AUCH:
+     erwarte
+     P_WAITFOR, P_WAITFOR_REASON
+
+16. Feb 2008 Gloinson
diff --git a/doc/props/P_WAITFOR_REASON b/doc/props/P_WAITFOR_REASON
new file mode 100644
index 0000000..b19c821
--- /dev/null
+++ b/doc/props/P_WAITFOR_REASON
@@ -0,0 +1,18 @@
+P_WAITFOR_REASON
+NAME:
+     P_WAITFOR_REASON                  "waitfor_reason"                     
+
+DEFINIERT IN:
+     /sys/player/base.h
+
+BESCHREIBUNG:
+     Ein Mapping mit den Erwarteten als Schluessel und einem Grund als
+     Key, zB:
+     
+     (["Zook":"muh muh"])
+
+SIEHE AUCH:
+     erwarte (erwarte <wen> wegen <was>)
+     P_WAITFOR, P_WAITFOR_FLAGS
+
+16. Feb 2008 Gloinson
diff --git a/doc/props/P_WANTS_TO_LEARN b/doc/props/P_WANTS_TO_LEARN
new file mode 100644
index 0000000..a1553bd
--- /dev/null
+++ b/doc/props/P_WANTS_TO_LEARN
@@ -0,0 +1,12 @@
+NAME:
+    P_WANTS_TO_LEARN              "wants_to_learn"              
+
+DEFINIERT IN:
+    /sys/player/base.h
+
+BESCHREIBUNG:
+     Gesetzt, wenn der Magier die Filenamen sehen will.
+     (Nur fuer Magier). Wird diese Property auf 0 gesetzt, gehen auch
+     einige andere Dinge nicht mehr - verfolge zB. Eigentlich sollten
+     dann auch die Magierbefehle wie "goto" usw unterbunden werden -
+     das kommt vielleicht noch.
diff --git a/doc/props/P_WATER b/doc/props/P_WATER
new file mode 100644
index 0000000..6be4fe6
--- /dev/null
+++ b/doc/props/P_WATER
@@ -0,0 +1,110 @@
+NAME:
+    P_WATER                       "water"                       
+
+DEFINIERT IN:
+    /sys/fishing.h
+
+BESCHREIBUNG:
+    Enthaelt den Gewaessertyp. Kann in Raeumen, Angeln und Wasserbehaeltern
+    verwendet werden. Die verfuegbaren Optionen und Funktionsweisen sind in 
+    den nachfolgenden Abschnitten aufgefuehrt.
+
+    Raum:
+    *****
+      Legt den Typ des Gewaessers fest, das es in diesem Raum gibt. Von
+      diesem Typ haengt ab, welche Arten von Fischen es hier standardmaessig
+      gibt und welche Arten von Angeln verwendet werden koennen. 
+      
+      Beispiel:
+
+      SetProp(P_WATER, W_HARBOR);
+      
+      Folgende
+      Typen stehen zur Verfuegung, von denen in Raeumen nur einer gesetzt
+      werden darf:
+
+      Salzwasser:
+        W_BEACH   Strand: Scholle, Flunder, Rochen, Seezunge, Katzenhai
+        W_HARBOR  Hafen: Dorsch, Rochen, Seezunge, Hering, Katzenhai
+        W_OCEAN   Ozean/Meer: Hai, Thunfisch, Kabeljau, Schwertfisch, Seehase,
+                  Seeteufel, Seewolf
+
+      Suesswasser:
+        W_RIVER   Fluss: Piranha, Lachs, Forelle, Bachsaibling
+        W_POOL    Teich: Stichling, Goldfisch, Schlei, Karpfen, Goldorfe
+        W_LAKE    See: Karpfen, Barsch, Hecht, Seesaibling
+        W_ROCK    Bergbach: Lachs, Forelle, Bachsaibling
+        W_STREAM  Bach: Stichling, Bachforelle, Neuauge, Bachsaibling
+
+      Sonstige:
+        W_USER    wenn dieser Gewaessertyp gesetzt wird, MUSS der Raum 
+                  zusaetzlich die Funktion GetAquarium() definieren, die
+                  eine Liste der hier fangbaren Fische zurueckgeben muss.
+                  Beispiel:
+
+                  string* GetAquarium(){ 
+                    return ({"/d/ebene/fraggle/angel/fisch"}); 
+                  }
+        W_DEAD    Lebloses Wasser. Enthaelt keine Fische, man kann
+                  aber die Standardflasche fuellen.
+
+        W_OTHER   1024   // Flasche enthaelt Fluessigkeit!=Wasser
+
+
+    Angel:
+    ******
+      Angeln sind ueblicherweise auf bestimmte Anwendungsbereiche ausgelegt.
+      Ob eine Angel in einem Gewaesser benutzt werden kann, haengt davon ab,
+      ob P_WATER in der Angel den Gewaessertyp des Raumes enthaelt. Von den
+      oben genannten Typen koennen mehrere ver-ODER-t gesetzt werden.
+      Verwendung einer fuer das oertliche Gewaesser ungeeigneten Angel fuehrt
+      zu einer um 60+random(60) Sekunden verlaengerten Wartezeit beim Angeln.
+      
+      Beispiel: Setzt man den Gewaessertyp mit 
+
+        SetProp(P_WATER, W_HARBOR|W_OCEAN);
+
+      schaltet das die Angel sowohl fuer Haefen, als auch fuer offene Meere
+      (Ozeane) frei.
+
+      Folgende kombinierte Gewaessertypen sind fuer einfache Angeln 
+      vordefiniert:
+
+      Kurze Standardangeln:
+        W_SHORT W_HARBOR|W_RIVER|W_POOL|W_LAKE|W_ROCK|W_USER|W_OCEAN|W_STREAM
+      Spezielle Strandruten:
+        W_LONG  W_BEACH|W_USER
+      funktioniert in allen Salzgewaessern:
+        W_SALT  W_HARBOR|W_OCEAN|W_BEACH
+      funktioniert in allen Suessgewaessern:
+        W_SWEET W_RIVER|W_POOL|W_LAKE|W_ROCK|W_STREAM
+
+      Hinweis: W_DEAD ist in diesen Kombinationen nicht enthalten, da es
+      in solchen Gewaessern ohnehin keine Fische gibt.
+      Die Kombi-Typen enthalten W_USER, um bei entsprechenden Gewaessern
+      zu vermeiden, dass es dort standardmaessig einen Malus auf die 
+      Wartezeit gibt. Standardwert fuer P_WATER in Angeln ist ebenfalls 
+      W_USER.
+
+    Koeder:
+    *******
+      Auch Koeder koennen fuer die Verwendung in bestimmten Gewaessern besser
+      geeignet sein als in anderen, z.B. eine Seeschnecke fuer Salzwasser,
+      ein Mehlwurm hingegen fuer Suesswasser. Gesetzt wird P_WATER hierfuer
+      auf die oben aufgefuehrten Werte.
+      Verwendung eines ungeeigneten Koeders fuehrt zu einer um 60+random(60)
+      Sekunden laengeren Wartezeit beim Angeln.
+
+    Wasserbehaelter:
+    ****************
+      Die Property gibt an, ob der Behaelter Wasser enthaelt oder nicht.
+      Der Wert sollte immer auf den Typ jenes Gewaessers gesetzt sein, aus
+      dem der Behaelter aufgefuellt wurde.
+
+SIEHE AUCH:
+
+    Properties: P_FISH
+    Methoden:   GetAquarium(L)
+
+------------------------------------------------------------------------------
+Zuletzt geaendert: 2014-Aug-21, Arathorn
diff --git a/doc/props/P_WC b/doc/props/P_WC
new file mode 100644
index 0000000..042de3d
--- /dev/null
+++ b/doc/props/P_WC
@@ -0,0 +1,37 @@
+NAME:
+	P_WC				"wc"
+
+DEFINIERT IN:
+	/sys/weapon.h
+
+BESCHREIBUNG:
+	Die Waffenklasse (engl: weapon class), also die Staerke der Waffe,
+	stellt einen numerischen Wert dar, der umso groesser ist, desto mehr
+	Schaden eine Waffe im Kampf anrichtet. Beim Zuecken oder Wegstecken
+	einer Waffe durch ein Lebewesen wird innerhalb des Lebewesens auch
+	die Property P_TOTAL_WC aktualisiert, welche somit immer die
+	aktuelle Angriffsstaerke enthaelt. Beim Zuecken erhaelt sie hierbei
+	die Waffenklasse der Waffe und beim Wegstecken die Angriffsstaerke
+	aus der Property P_HANDS (Kaempfen mit blossen Haenden).
+	Die Waffenklasse von einhaendigen Waffen sollte 150 nicht
+	ueberschreiten, die Obergrenze fuer zweihaendige Waffen liegt bei
+	200. Ausnahmen von dieser Regel beduerfen der Absprache mit dem
+	Erzmagier fuer Ruestungen, Waffen und Monster!
+	Negative Werte bewirken keinen Schaden, allerdings auch keine
+	Heilung.
+
+BEMERKUNGEN:
+	Query- und Setmethoden auf P_WC sollten unbedingt vermieden werden. Sie
+	fuehren in der Regel zu massiven Inkonsistenzen im Mechanismus der 
+	Ruestungsbeschaedigung und -reparatur.
+	Auch mit einer HitFunc() duerfen die Obergrenzen nicht ohne
+	Absprache ueberschritten werden! Ausserdem ist es ratsam, die
+	zusaetzlichen Kampfeigenschaften in P_EFFECTIVE_WC gesondert
+	anzugeben.
+
+SIEHE AUCH:
+	/std/weapon.c, /std/weapon/combat.c
+	P_DAMAGED, P_EFFECTIVE_WC, P_WEAPON_TYPE
+	Damage()
+----------------------------------------------------------------------------
+02.10.2007, Zesstra
diff --git a/doc/props/P_WEAPON b/doc/props/P_WEAPON
new file mode 100644
index 0000000..5b1854c
--- /dev/null
+++ b/doc/props/P_WEAPON
@@ -0,0 +1,17 @@
+P_WEAPON
+
+NAME:
+     P_WEAPON                      "weapon"
+
+DEFINIERT IN:
+     /sys/properties.h
+
+BESCHREIBUNG:
+      Momentan gezueckte Waffe. Im Living gesetzt.
+
+SIEHE AUCH:
+      Verwandt:		P_ARMOURS
+      Waffen:		P_WC, P_WEAPON_TYPE, P_DAM_TYPE, P_NR_HANDS, P_PARRY
+      Sonstiges:	P_UNWIELD_TIME, P_EQUIP_TIME, P_LAST_USE
+
+10.Feb 2005 Gloinson
diff --git a/doc/props/P_WEAPON_TEACHER b/doc/props/P_WEAPON_TEACHER
new file mode 100644
index 0000000..913cfe7
--- /dev/null
+++ b/doc/props/P_WEAPON_TEACHER
@@ -0,0 +1,20 @@
+P_WEAPON_TEACHER   "weapon_teacher"
+----------------
+
+DEFINIERT IN:
+-------------
+
+combat.h
+
+BESCHREIBUNG
+------------
+
+Diese Property wird in einem Azubi gesetzt (zur Zeit nur fuer die 
+Kaempfer-Gilde), der selbst ueber die allgemeinen Waffenskills
+verfuegt.
+
+In diese Property wird der Name eines Kaempfergilden-Ausbilders
+eingetragen.
+
+Unter Anleitung des Ausbilders lernt der Azubi dann etwas schneller
+die allgemeinen Waffenskills.
diff --git a/doc/props/P_WEAPON_TYPE b/doc/props/P_WEAPON_TYPE
new file mode 100644
index 0000000..06f3c0b
--- /dev/null
+++ b/doc/props/P_WEAPON_TYPE
@@ -0,0 +1,31 @@
+P_WEAPON_TYPE
+
+NAME:
+     P_WEAPON_TYPE "weapon_type"
+
+DEFINIERT IN:
+     <weapon.h>
+
+BESCHREIBUNG:
+     Um was fuer eine Waffe handelt es sich? Es stehen verschiedene
+     Typen zur Auswahl. Man sollte hier nur die in <combat.h> definierten
+     Konstanten verwenden:
+
+        WT_AMMU           Munition fuer Fernkampfwaffen
+        WT_AXE            Axt
+        WT_CLUB           Keule
+        WT_HANDS          blosse Haende
+        WT_KNIFE          Messer, Dolch
+        WT_RANGED_WEAPON  Fernkampfwaffe
+        WT_SPEAR          Speer
+        WT_STAFF          Kampfstab
+        WT_SWORD          Schwert
+        WT_WHIP           Peitsche
+        WT_MISC           Sonstiges
+
+    Der Waffentyp WT_MISC ist schnoedem Tand und nutzlosem Kram vorbehalten.
+    Waffen dieses Typs duerfen keine P_WC > 0 besitzen oder kampfrelevante
+    Bedeutung haben.
+
+----------------------------------------------------------------------------
+Letzte Aenderung: 27. Mai 2015, Arathorn.
diff --git a/doc/props/P_WEAR_FUNC b/doc/props/P_WEAR_FUNC
new file mode 100644
index 0000000..edc9bcc
--- /dev/null
+++ b/doc/props/P_WEAR_FUNC
@@ -0,0 +1,24 @@
+P_WEAR_FUNC
+
+NAME:
+     P_WEAR_FUNC "wear_func"
+
+DEFINIERT IN:
+     <armour.h>
+
+BESCHREIBUNG:
+     Falls ein Objekt eine WearFunc() fuer die Ruestung / Kleidung definiert, 
+     so muss dieses Objekt in dieser Property eingetragen sein.
+
+     Die Auswertung dieser Property erfolgt in Laufe eines DoWear() in der
+     nicht-oeffentlichen Funktion _check_wear_restrictions()..
+
+BEISPIELE:
+     Siehe das Beispiel zu WearFunc()
+
+SIEHE AUCH:
+     armours, clothing, /std/clothing/wear.c, /std/armour/wear.c
+     WearFunc(), InformWear()
+
+LETZTE AeNDERUNG:
+15.02.2009, Zesstra
\ No newline at end of file
diff --git a/doc/props/P_WEAR_MSG b/doc/props/P_WEAR_MSG
new file mode 100644
index 0000000..31407fa
--- /dev/null
+++ b/doc/props/P_WEAR_MSG
@@ -0,0 +1,61 @@
+P_WEAR_MSG
+NAME:
+    P_WEAR_MSG                       "wear_msg"                       
+
+DEFINIERT IN:
+    /sys/armour.h
+
+BESCHREIBUNG:
+     Zweiteiliges Array mit Meldungen, die beim Anziehen einer Ruestung oder
+     Kleidung an den Spieler und die Umgebung ausgegeben werden.
+     Der erste Eintrag geht an den Spieler, der zweite Eintrag an die
+     Umgebung. Zeilenumbrueche werden automatisch gemacht, existierende
+     jedoch beruecksichtigt.
+
+     Platzhalter fuer Spieler ist @WExxx1, fuer die Waffe @WExxx2 (siehe
+     man replace_personal()).
+
+     [Wegen Abwaertskompatibilitaet ist auch noch der Platzhalter %s
+      moeglich, wobei in der eigenen Meldung %s fuer den Waffennamen steht,
+      in der an den Raum das erste %s fuer den Spielernamen, das zweite fuer
+      den Waffennamen.]
+
+BEISPIELE:
+    SetProp(P_NAME, "Helm");
+    SetProp(P_WEAR_MSG,
+     ({"Du stuelpst die @WEN2 ueber.", 
+       "@WER1 stuelpt sich @WENU2 ueber."}));
+
+    -> beim Anziehe durch Urk:
+       Urk bekommt: Du stuelpst dir den Helm ueber.
+       Der Raum:    Urk stuelpt sich einen Helm ueber.
+
+    SetProp(P_WEAR_MSG,
+     ({"Als Du Dir den langen Mantel ueberziehst, steckst Du erstmal "
+       "mit Deinem dicken Schaedel fest. Doch nach einem kraeftigen "
+       "Ruck bist Du endlich durch und siehst wieder etwas.",
+       "@WER1 zieht sich einen langen Mantel ueber und bleibt "
+       "prompt mit dem dicken Schaedel stecken. Doch nach einem "
+       "kraeftigen Ruck kann @WERQP1 wieder etwas sehen und grinst Dich "
+       "verlegen an."}));
+
+    -> beim Anziehen durch Urk:
+       Urk bekommt: Als Du Dir den langen Mantel ueberziehst, steckst Du
+		    erstmal mit Deinem dicken Schaedel fest. Doch nach einem
+		    kraeftigen Ruck bist Du endlich durch und siehst wieder
+		    etwas.
+
+       Der Raum:    Urk zieht sich einen langen Mantel ueber und bleibt
+		    prompt mit dem dicken Schaedel stecken. Doch nach
+		    einem kraeftigen Ruck kann er wieder etwas sehen und
+		    grinst Dich verlegen an.
+
+SIEHE AUCH:
+     Aehnliches: P_UNWEAR_MSG, P_WIELD_MSG, P_UNWIELD_MSG
+                 P_DROP_MSG, P_PUT_MSG, P_GIVE_MSG, P_PICK_MSG
+     Funktionen: WearFunc, UnwearFunc, InformWear()
+     Sonstiges:  replace_personal(E), clothing, /std/clothing/wear.c
+                 armour, /std/armour/wear.c
+
+LETZTE AeNDERUNG:
+15.02.2009
\ No newline at end of file
diff --git a/doc/props/P_WEIGHT b/doc/props/P_WEIGHT
new file mode 100644
index 0000000..22af5f0
--- /dev/null
+++ b/doc/props/P_WEIGHT
@@ -0,0 +1,26 @@
+NAME:
+    P_WEIGHT                      "weight"                      
+
+DEFINIERT IN:
+    /sys/thing/restrictions.h
+
+BESCHREIBUNG:
+
+     - Objekte
+       Das Gewicht eines Objetes in Gramm.
+
+     - Speisen
+       Gewicht einer Portion der Speise.
+       
+BEMERKUNGEN:
+     In tragbaren Speisen (erben von /std/food) setzt man mit SetProp
+     das Gewicht _einer_ Portion. Per QueryProp erhaelt man aber das
+     Gesamtgewicht der Speise inclusive des eventuell vorhandenen Behaelters.
+     Das Gewicht des Behaelters wird dabei aus P_EMPTY_PROPS[P_WEIGHT]
+     gelesen.
+     
+SIEHE AUCH:
+     Speisen: wiz/food, P_EMPTY_PROPS
+
+------------------------------------------------------------------------------
+Last modified: Thu Oct 28 12:15:00 2010 by Caldra
\ No newline at end of file
diff --git a/doc/props/P_WEIGHT_PERCENT b/doc/props/P_WEIGHT_PERCENT
new file mode 100644
index 0000000..7bb1ad3
--- /dev/null
+++ b/doc/props/P_WEIGHT_PERCENT
@@ -0,0 +1,25 @@
+NAME:
+    P_WEIGHT_PERCENT              "weight_percent"              
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Diese Property gibt an, wieviel Prozent des Gewichts des Inhaltes
+     "nach aussen" wiedergegeben werden.
+
+BEMERKUNGEN:
+     Alle Werte die < 50% liegen sollten sehr gut begruendet und mit Vor-
+     sicht verwendet werden. Hier koennten dann zum Beispiel P_MAX_OBJECTS
+     auf einen kleinen Wert begrenzt werden.
+
+     Container die hier einen Wert ueber dem des Postpakets haben, sollten
+     auch schwer zu erreichen sein. Auf jeden Fall mit dem Regionsmagier
+     besprechen!
+
+BEISPIELE:
+     Um sich zu orientieren kann das Postpaket von Loco als Beispiel hin-
+     zugezogen werden (/p/service/loco/obj/parcel).
+
+SIEHE AUCH:
+     P_MAX_OBJECTS, P_MAX_WEIGHT, P_LIGHT_TRANSPARENCY, container
diff --git a/doc/props/P_WEIGHT_PER_UNIT b/doc/props/P_WEIGHT_PER_UNIT
new file mode 100644
index 0000000..2796b7b
--- /dev/null
+++ b/doc/props/P_WEIGHT_PER_UNIT
@@ -0,0 +1,13 @@
+NAME:
+    P_WEIGHT_PER_UNIT             "weight_per_unit"             
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Gewicht in Gramm pro Untereinheit.
+
+BEMERKUNGEN:
+     Deprecated. Bitte SetGramsPerUnits() (U_GPU) benutzen.
+
+25.Aug 2015 Gloinson
diff --git a/doc/props/P_WIELDED b/doc/props/P_WIELDED
new file mode 100644
index 0000000..bce8580
--- /dev/null
+++ b/doc/props/P_WIELDED
@@ -0,0 +1,21 @@
+P_WIELDED
+
+NAME:
+     P_WIELDED "wielded"
+
+DEFINIERT IN:
+     <weapon.h>
+
+BESCHREIBUNG:
+     Ist diese Property gesetzt, dann ist die Waffe gerade gezueckt. Der
+     Traeger ist in der Property vermerkt.
+
+BEMERKUNGEN:
+     Diese Property laesst sich nur abfragen!
+
+SIEHE AUCH:
+     /std/weapon.c
+     P_WEAPON
+
+----------------------------------------------------------------------------
+Last modified: 2015-Jul-11, Arathorn 
diff --git a/doc/props/P_WIELD_FUNC b/doc/props/P_WIELD_FUNC
new file mode 100644
index 0000000..fac481b
--- /dev/null
+++ b/doc/props/P_WIELD_FUNC
@@ -0,0 +1,22 @@
+P_WIELD_FUNC
+
+NAME:
+     P_WIELD_FUNC "wield_func"
+
+DEFINIERT IN:
+     <weapon.h>
+
+BESCHREIBUNG:
+     Falls ein Objekt eine WieldFunc() fuer die Waffe definiert, so muss
+     dieses Objekt in dieser Property eingetragen werden.
+
+     Die Auswertung dieser Property erfolgt in wield_me().
+
+BEISPIELE:
+     Siehe das Beispiel zu WieldFunc()
+
+SIEHE AUCH:
+     /std/weapon.c, WieldFunc()
+
+----------------------------------------------------------------------------
+Last modified: Sun May 19 15:40:02 1996 by Wargon
diff --git a/doc/props/P_WIELD_MSG b/doc/props/P_WIELD_MSG
new file mode 100644
index 0000000..357a304
--- /dev/null
+++ b/doc/props/P_WIELD_MSG
@@ -0,0 +1,57 @@
+P_WIELD_MSG
+NAME:
+     P_WIELD_MSG                       "wield_msg" 
+
+DEFINIERT IN:
+     /sys/weapon.h
+
+BESCHREIBUNG:
+
+     Zweiteiliges Array mit Meldungen, die beim Zuecken einer Waffe an den
+     Spieler und die Umgebung ausgegeben werden.
+     Der erste Eintrag geht an den Spieler, der zweite Eintrag an die
+     Umgebung.  Zeilenumbrueche werden automatisch gemacht, existierende
+     jedoch beruecksichtigt.
+
+     Platzhalter fuer Spieler ist @WExxx1, fuer die Waffe @WExxx2 (siehe
+     man replace_personal()).
+
+     [Wegen Abwaertskompatibilitaet ist auch noch der Platzhalter %s
+      moeglich, wobei in der eigenen Meldung %s fuer den Waffennamen steht,
+      in der an den Raum das erste %s fuer den Spielernamen, das zweite fuer
+      den Waffennamen.]
+
+BEISPIELE:
+    SetProp(P_NAME, "Streitkolben");
+    SetProp(P_WIELD_MSG,
+     ({"Du zueckst @WEN2 und stoesst einen markerschuetternden Schrei aus.", 
+       "@WER1 zueckt @WENU2 und stoesst einen markerschuetternden Schrei "
+       "aus." }));
+
+    -> beim Zuecken durch Urk:
+       Urk bekommt: Du zueckst den Streitkolben und stoesst einen
+		    markerschuetternden Schrei aus.
+       Der Raum:    Urk zueckt einen Streitkolben und stoesst einen
+		    markerschuetternden Schrei aus.
+
+    SetProp(P_WIELD_MSG,
+     ({"Du zueckst den klobigen Streitkolben und fuchtelst damit "
+       "wild vor Deiner Nase herum.",
+       "@WER1 zueckt einen klobigen Streitkolben und fuchtelt "
+       "damit wild vor der eigenen Nase herum. Hoffentlich verletzt "
+       "@WERQP1 sich dabei nicht ..."}));
+
+    -> beim Zuecken durch Urk:
+       Urk bekommt: Du zueckst den klobigen Streitkolben und fuchtelst
+                    damit wild vor Deiner Nase herum.
+       Der Raum:    Urk zueckt einen klobigen Streitkolben und fuchtelt
+		    damit wild vor der eigenen Nase herum. Hoffentlich
+                    verletzt er sich dabei nicht ...
+
+SIEHE AUCH:
+     Aehnliches: P_UNWIELD_MSG, P_WEAR_MSG, P_UNWEAR_MSG
+                 P_DROP_MSG, P_PUT_MSG, P_GIVE_MSG, P_PICK_MSG
+     Funktionen: UnwieldFunc, WieldFunc
+     Sonstiges:  replace_personal(E), /std/weapon/combat.c
+
+29. Maerz 2004 Gloinson
diff --git a/doc/props/P_WIMPY b/doc/props/P_WIMPY
new file mode 100644
index 0000000..97633fa
--- /dev/null
+++ b/doc/props/P_WIMPY
@@ -0,0 +1,15 @@
+NAME:
+    P_WIMPY                       "wimpy"                       
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Numerischer Wert. Das Lebewesen flieht, wenn die Lebenspunkte
+     unter diesen Wert sinken.
+
+SIEHE AUCH:
+     P_WIMPY_DIRECTION
+
+----------------------------------------------------------------------------
+Letzte Aenderung: Mon Feb 12 17:50:47 2001 von Tilly
diff --git a/doc/props/P_WIMPY_DIRECTION b/doc/props/P_WIMPY_DIRECTION
new file mode 100644
index 0000000..57d2f01
--- /dev/null
+++ b/doc/props/P_WIMPY_DIRECTION
@@ -0,0 +1,22 @@
+NAME:
+    P_WIMPY_DIRECTION             "wimpy_dir"                   
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+     Fluchtrichtung eines Spielers oder NPCs
+
+BEMERKUNGEN:
+     Die Fluchtrichtung kann nicht nur ein Ausgang (sueden, osten, ...)
+     sein, sondern auch ein Kommando, welches der Spieler beim Anschlagen
+     ausfuehrt (z.b. <kletter seil hoch> oder <rufe Elender Mist!>).
+
+     Ausgefuehrt wird die Fluchtrichtung per command(), wenn die LP des 
+     Lebewesens unter die mit <vorsicht> angegebe LP-Grenze sinkt.
+
+SIEHE AUCH:
+     P_WIMPY
+
+----------------------------------------------------------------------------
+Letzte Aenderung: Mon Feb 12 17:46:47 2001 von Tilly
diff --git a/doc/props/P_WIZ_DEBUG b/doc/props/P_WIZ_DEBUG
new file mode 100644
index 0000000..cf7ac21
--- /dev/null
+++ b/doc/props/P_WIZ_DEBUG
@@ -0,0 +1,20 @@
+NAME:
+    P_WIZ_DEBUG                    "std_p_wizdebug"
+
+DEFINIERT IN:
+    /sys/player/comm.h
+
+BESCHREIBUNG:
+     Gesetzt, wenn der Magier (oder ein Testspieler) Debugmeldungen wahrnehmen
+     moechte.
+     Debugmeldungen sind Nachrichten, die mit dem Typ MT_DEBUG an ReceiveMsg()
+     uebergeben werden.
+     
+     Die Werte von P_WIZ_DEBUG sind zur Zeit 0 oder 1, das kann sich aber
+     jederzeit aendern.
+     Magier aendern diese Prop bitte ueber "mschau".
+
+SIEHE AUCH:
+     mschau
+     P_WANTS_TO_LEARN
+
diff --git a/doc/props/P_WORN b/doc/props/P_WORN
new file mode 100644
index 0000000..7afd03e
--- /dev/null
+++ b/doc/props/P_WORN
@@ -0,0 +1,40 @@
+P_WORN
+
+NAME:
+     P_WORN "worn"
+
+DEFINIERT IN:
+     <armour.h>
+
+BESCHREIBUNG:
+     Mittels dieser Property laesst sich ermitteln, ob eine Ruestung bzw. 
+     Kleidung derzeit getragen wird und wenn ja, von wem.
+
+     Entweder enthaelt die Property den Wert 0, oder sie enthaelt den
+     Traeger der Ruestung / Kleidung (als Objekt).
+
+BEMERKUNGEN:
+     Diese Property laesst sich nur abfragen!
+
+BEISPIELE:
+     Eine DefendFunc() koennte dem Traeger der Ruestung wie folgt etwas
+     mitteilen:
+
+     // Die Ruestung gibt Schutz gegen Feuer
+     int DefendFunc(string *dtyp, mixed spell, object enemy)
+     {
+       if (member(dtyp, DT_FIRE) != -1) {
+         // P_WORN ist auf jeden Fall gesetzt, da sonst die
+         // DefendFunc ueberhaupt nicht aufgerufen wuerde!
+         tell_object(QueryProp(P_WORN),
+           "Die Flammen zuengeln nur leicht ueber die Ruestung.\n");
+         return 10;
+       }
+       return 0;
+     }
+
+SIEHE AUCH:
+     clothing, /std/clothing.c, armour, /std/armour.c
+
+LETZTE AeNDERUNG:
+15.02.2009, Zesstra
\ No newline at end of file
diff --git a/doc/props/P_XP b/doc/props/P_XP
new file mode 100644
index 0000000..097ec65
--- /dev/null
+++ b/doc/props/P_XP
@@ -0,0 +1,59 @@
+NAME:
+     P_XP                    "xp"
+
+DEFINIERT IN:
+     /sys/living/life.h
+
+BESCHREIBUNG:
+     Diese Property enthaelt die Anzahl der Erfahrungspunkte, die ein
+     Lebewesen erreicht hat. Dies geschieht insbesondere durch
+     Kampfhandlungen, wobei es sowohl fuer Einzelschlaege als auch fuer
+     das Toeten eines Opfers Punkte gibt.
+
+     Bei einzelnen Schlaegen ist die Vergabe von Erfahrungspunkten davon
+     abhaengig, wie stark man das Opfer getroffen hat, und welche
+     Gesamtwaffenklasse es hat (damage*P_TOTAL_WC/10).
+
+     Beim Todesschlag erhaelt man zusaetzlich die Erfahrungspunkte des
+     Opfers geteilt durch 100 (P_XP/100). Dieser Wert wird allerdings
+     gegebenenfalls auf ein Team aufgeteilt, sofern der Angreifer sich in
+     einem solchigen befindet.
+
+BEISPIEL:
+     NPC's gibt man im allgemeinen einen levelabhaengigen Sockelwert an
+     Erfahrungspunkten mit, da sie nicht allzuoft selbst Gegner toeten
+     und somit kaum die Moeglichkeit haben, diese Punkte selbst
+     anzusammeln. Trotzdem sollen sie ja dem Spieler eine gewisse Anzahl
+     an Erfahrungspunkten liefern, wenn sie getoetet werden:
+
+       include "/sys/living/life.h"
+       inherit "std/npc";
+       void create() {
+         ...
+         SetProp(P_XP,25000000);
+       }
+
+     Beim Toeten gibt es nun 25.000.000/100 = 250.000 Erfahrungspunkte.
+     Damit wird der NPC sogar automatisch fuer die Vergabe von
+     Erstkillstufenpunkten vorgesehen.
+
+     Die Funktion create_default_npc() setzt P_XP und andere Eigenschaften
+     auf geeignete Werte.
+
+BEMERKUNGEN:
+     Die Vergabe von Erstkillstufenpunkten kann man ueber die Property
+     P_NO_SCORE unterbinden, die Vergabe von Erfahrungspunkten ueber
+     P_NO_XP. Automatisch werden Lebewesen fuer Erstkillstufenpunkte
+     vorgesehen, sofern sie eine der folgenden Grenzen ueberschritten
+     haben:
+       SCORE_LOW_MARK:  200000 (1 Stufenpunkt)
+       SCORE_HIGH_MARK: 600000 (2 Stufenpunkte)
+     Definiert sind die Konstanten in "/secure/scoremaster.h".
+
+SIEHE AUCH:
+     Funktionen:  AddExp(), do_damage()
+     Verwandt:    P_NO_XP, P_LAST_XP
+     Sonstiges:   P_NO_SCORE, create_default_npc()
+                  P_TOTAL_WC
+
+14.Feb 2007 Gloinson
\ No newline at end of file
diff --git a/doc/props/P_X_ATTR_MOD b/doc/props/P_X_ATTR_MOD
new file mode 100644
index 0000000..c6a8bda
--- /dev/null
+++ b/doc/props/P_X_ATTR_MOD
@@ -0,0 +1,46 @@
+NAME:
+    P_X_ATTR_MOD                  "extern_attributes_modifier"
+
+DEFINIERT IN:
+    /sys/living/attributes.h
+
+BESCHREIBUNG:
+    Mapping, das die Attribute des Spielers veraendert, der das Objekt bei
+    sich hat.
+
+    Zu beachten:
+    Diese Property bitte _ausschliesslich_ mit SetProp aendern, weil damit
+    gleichzeitig UpdateAttributes() im Lebewesen aufgerufen und ggf. das
+    Objekt als Statmodifizierer registriert wird.
+
+    Diese Property ist fuer Krankheiten, Flueche etc. gedacht. Bei
+    Waffen/Ruestungen, die die Attribute beeinflussen sollen, verwendet
+    man besser P_M_ATTR_MOD.
+
+    P_X_ATTR_MOD und P_M_ATTR_MOD duerfen einen gemeinsamen kumulierten
+    positiven Grenzwert nicht ueberschreiten. Dieser Grenzwert,
+    CUMULATIVE_ATTR_LIMIT, ist in /sys/living/attributes.h definiert.
+
+BEMERKUNGEN:
+    Die Methode /std/thing/restrictions::_set_extern_attributes_modifier()
+    benachrichtigt tragende Livings ueber Aenderungen.
+    Bitte beim "Loeschen" der Prop nicht den Wert des jew. Attributes im
+    uebergebenen Mapping als 0 uebergeben, sondern das Key/Werte-Paar ganz
+    entfernen und bzw. ein leeres Mapping oder 0 uebergeben.
+
+BEISPIEL:
+    // Dem Lebewesen, das das Objekt bei sich hat, wird 2 von A_INT abgezogen
+    SetProp(P_X_ATTR_MOD,([A_INT:-2]));
+
+    // Stats wiederherstellen:
+    SetProp(P_X_ATTR_MOD,([]));
+
+SIEHE AUCH:
+    QueryAttribute(), QueryRealAttribute(), QueryAttributeOffset(),
+    SetAttribute(), SetRealAttribute(), UpdateAttributes(),
+    SetTimedAttrModifier(), QueryTimedAttrModifier(),
+    DeleteTimedAttrModifier(),
+    P_X_HEALTH_MOD, P_M_HEALTH_MOD, P_ATTRIBUTES, P_ATTRIBUTES_OFFSETS,
+    P_TIMED_ATTR_MOD, P_M_ATTR_MOD, P_M_ATTR_MOD, /std/living/attributes.c
+
+02.02.2016, Gloinson
diff --git a/doc/props/P_X_HEALTH_MOD b/doc/props/P_X_HEALTH_MOD
new file mode 100644
index 0000000..d78d2bf
--- /dev/null
+++ b/doc/props/P_X_HEALTH_MOD
@@ -0,0 +1,36 @@
+NAME:
+    P_X_HEALTH_MOD                  "extern_health_modifier"
+
+DEFINIERT IN:
+    /sys/living/attributes.h
+
+BESCHREIBUNG:
+    Mapping, mit dem die maximalen Lebenspunkte und Magiepunkte eines
+    Spielers veraendert werden, der dieses Objekt bei sich traegt.
+
+    Zu beachten: Diese Property bitte _ausschliesslich_ mit SetProp
+    aendern, weil damit gleichzeitig UpdateAttributes() im
+    Lebewesen aufgerufen und ggf. das Objekt als Statmodifizierer 
+    registriert wird.
+
+    Bei Ruestungen/Waffen, die diese Wirkung entfalten sollen, verwendet
+    man besser P_M_HEALTH_MOD.
+
+BEMERKUNGEN:
+    Bitte bei "Loeschen" der Prop nicht den Wert des jew. Attributes im 
+    uebergebenen Mapping als 0 uebergeben, sondern das Key/Werte-Paar ganz 
+    entfernen und ggf. ein leeres Mapping oder 0 uebergeben.
+
+BEISPIEL:
+    // Dem Spieler, der das Objekt bei sich traegt, wird P_MAX_HP um 5
+    // erhoeht und P_MAX_SP um 5 erniedrigt.
+    SetProp(P_X_HEALTH_MOD,([P_HP:5,P_SP:-5]));
+    // Stats wiederherstellen:
+    SetProp(P_X_HEALTH_MOD,([]);
+
+SIEHE AUCH:
+    P_M_HEALTH_MOD, P_X_ATTR_MOD, P_M_ATTR_MOD, balance
+
+LETZTE AeNDERUNG:
+    Sat, 06.02.1999, 14:00:00 von Paracelsus
+
diff --git a/doc/props/P_ZAP_MSG b/doc/props/P_ZAP_MSG
new file mode 100644
index 0000000..fbabff4
--- /dev/null
+++ b/doc/props/P_ZAP_MSG
@@ -0,0 +1,28 @@
+P_ZAP_MSG
+
+NAME:
+      P_ZAP_MSG			"zap_msg"
+
+DEFINIERT IN:
+      /sys/properties.h
+
+BESCHREIBUNG:
+      Die Property enthaelt ein dreielementiges Array mit den folgenden

+      Eintraegen:
+	  1.) Meldung, die der Magier beim Zappen bekommt.
+	  2.) Meldung, die die Spieler im Raum beim Zappen bekommen.
+	  3.) Meldung, die das Opfer beim Zappen bekommt.
+
+      Mit @@wer@@, @@wessen@@, ... kann der Name des Opfers und mit @@ich@@

+      der Name des Magiers in die Meldung eingewoben werden.
+
+      Die Property ist in Magiern gesetzt und gilt nur dort.
+
+SIEHE AUCH:
+     Tod:		die(L)
+     Todesmeldungen:	P_KILL_NAME, P_KILL_MSG, P_DIE_MSG, P_MURDER_MSG
+			P_ENEMY_DEATH_SEQUENCE
+     Sonstiges:		P_CORPSE, P_NOCORPSE, /room/death/death_room.c
+
+----------------------------------------------------------------------------
+Last modified: Wed Jan 14 19:17:06 1998 by Patryn
diff --git a/doc/props/U_REQ b/doc/props/U_REQ
new file mode 100644
index 0000000..cb395db
--- /dev/null
+++ b/doc/props/U_REQ
@@ -0,0 +1,63 @@
+NAME:
+    U_REQ                         "u_req"
+
+DEFINIERT IN:
+    /sys/unit.h
+
+BESCHREIBUNG:
+     Die Prop kann in Unitobjekten gesetzt werden.
+     Sie gibt die Anzahl der Einheiten an, die an der Unit manipuliert werden
+     sollen, falls mit weniger als P_AMOUNT umgegegangen werden soll.
+     
+     Die Prop wird automatisch gesetzt, wenn id() an einem Unitobjekt gerufen
+     wird und die ID grundsaetzlich zutreffend ist, die aus der ID ermittelte
+     Zahl aber kleiner als P_AMOUNT ist.
+     Sie kann auch manuell mittel SetProp() (aber nicht Set()) gesetzt werden.
+
+     U_REQ wird beim Bewegen und Zerstoeren, bei Ermittlung von Wert und
+     Gewicht beruecksichtigt.
+
+     U_REQ wird vom Unitobjekt automatisch wieder auf P_AMOUNT gesetzt, wenn
+     sich query_verb() oder debug_info(DINFO_EVAL_NUMBER) veraendert haben.
+     (DINFO_EVAL_NUMBER ist eine Zahl, die sich jedesmal erhoeht, wenn der
+      Driver eine neue Berechnung/Ausfuehrung beginnt. Diese Nummer wird fuer
+      jeden vom driver initiierten Aufruf von LPC-Code erhoeht, z.B. bei jedem
+      Kommando, call_out, heart_beat etc. Details s. debug_info().)
+
+     Ebenso wird U_REQ bei der Vereinigung mit einem anderen (gleichen)
+     Objekt auf P_AMOUNT des vereinigten Objektes gesetzt.
+
+
+BUGS
+    Viele. Dies ist ein uebler Hack. Geht aber nicht ohne.
+    Diese Prop war endlos lang gar nicht dokumentiert. Hier beschrieben ist
+    das Verhalten, was zur Zeit vorliegt. Dies mag unterschiedlich zu dem
+    irgendwann intendierten sein.
+
+
+BEISPIELE
+    object o = clone_object("unitobjekt");
+    o->SetProp(P_AMOUNT, 100);   // ab jetzt hat o 100 Einheiten.
+    o->move(npc, M_GET);         // ob mit 100 Einheiten wird bewegt
+    o->SetProp(U_REQ, 50);
+    o->move(anderernpc, M_GIVE); // 50 Einheiten werden bewegt, 50 verbleiben
+    (Technisch: das Objekt wird auf 50 Einheiten geaendert, bewegt und in der
+     alten Umgebung wird ein neues Objekt mit 50 Einheiten erzeugt.)
+
+    o->SetProp(U_REQ, 42);
+    o->remove(1);               // 42 Einheiten von den 50 werden zerstoert.
+    (Technisch: P_AMOUNT wird einfach um U_REQ reduziert.)
+
+    # gib 18 muenzen an blupp
+    Hierbei wird ob->id("18 muenzen") gerufen, was U_REQ im Geldobjekt auf 18
+    setzt. Bei der Bewegung bekommt blupp daher das Objekt mit P_AMOUNT==18
+    und der Rest wird im Abgebenden neu erzeugt.
+    # gib geld an flubbel
+    Das U_REQ aus dem verherigen Kommando ist jetzt nicht mehr gueltig. Zwar
+    ist es das gleiche Kommandoverb, aber DINFO_EVAL_NUMBER ist jetzt
+    anders.
+
+
+ZULETZT GEAeNDERT:
+16.01.2015, Zesstra
+
diff --git a/doc/props/gildenprops/.synonym b/doc/props/gildenprops/.synonym
new file mode 100644
index 0000000..17607d8
--- /dev/null
+++ b/doc/props/gildenprops/.synonym
@@ -0,0 +1,9 @@
+K_BRAWLING_DT kaempferboni
+K_BRAWLING_MSG kaempferboni
+K_BRAWLING_WC kaempferboni
+K_CRITICAL_HIT kaempferboni
+K_DISTRACTING_WEAPON kaempferboni
+K_KO kaempferboni
+K_NO_HONING kaempferboni
+K_THROWING_WEAPON kaempferboni
+K_WEAPON_SHATTER kaempferboni
diff --git a/doc/props/gildenprops/P_GLOVE_FINGERLESS b/doc/props/gildenprops/P_GLOVE_FINGERLESS
new file mode 100644
index 0000000..64faec6
--- /dev/null
+++ b/doc/props/gildenprops/P_GLOVE_FINGERLESS
@@ -0,0 +1,16 @@
+P_GLOVE_FINGERLESS
+
+NAME:
+     P_GLOVE_FINGERLESS                     "fingerfreie_handschuhe"
+
+DEFINIERT IN:
+     /p/katzenkrieger/kkrieger.h
+
+BESCHREIBUNG:
+     So gekennzeichnete Handschuhe sind fingerlos und koennen
+     waehrend "krallenschlag" getragen werden.
+
+SIEHE AUCH:
+     Verwandt:	P_ARMOUR_TYPE, AT_GLOVE
+
+10.Okt 2006 Gloinson
\ No newline at end of file
diff --git a/doc/props/gildenprops/P_Z_AUTOSHIELD b/doc/props/gildenprops/P_Z_AUTOSHIELD
new file mode 100644
index 0000000..f69b9ad
--- /dev/null
+++ b/doc/props/gildenprops/P_Z_AUTOSHIELD
@@ -0,0 +1,26 @@
+P_Z_AUTOSHIELD
+
+NAME:
+     P_Z_AUTOSHIELD				"z_autoshield"
+
+DEFINIERT IN:
+     /p/zauberer/wiznpc.h
+
+BESCHREIBUNG:
+     Mit dieser Property  kann man einen automatischen 
+     Schutzzauber in Zauberer-NPCs einstellen, dessen 
+     Vorhandensein dann in jeder Kampfrunde ueberprueft
+     wird, z.B. "schutz","schutzhuelle","zauberschild".
+
+BEMERKUNGEN:
+     "zauberschild" ist ein Magisterspruch und kann nur in 
+     bestimmten Zeitabstaenden benutzt werden. Wer also als
+     Autoshield nur Zauberschild benutzt, blockiert damit
+     alle anderen Spells, solange der Magisterspruch nicht
+     gesprochen werden kann.
+     Abhilfe: _query_next_master_spell_time()  return 0; }
+
+SIEHE AUCH:
+     /p/zauberer/text/wiznpc.doku
+
+21.Okt 2006 Chagall
diff --git a/doc/props/gildenprops/P_Z_INFO b/doc/props/gildenprops/P_Z_INFO
new file mode 100644
index 0000000..d82d38a
--- /dev/null
+++ b/doc/props/gildenprops/P_Z_INFO
@@ -0,0 +1,53 @@
+P_Z_INFO
+
+NAME:
+     P_Z_INFO						"z_info"
+
+DEFINIERT IN:
+     /p/zauberer/wiznpc.h
+
+BESCHREIBUNG:
+     Diese Property muss gesetzt werden, wenn man den
+     Zauberergilden-Standard-NPC nutzt. Sie setzt die
+     Grundeinstellungen des NPCs und generiert das 
+     Newskills-Mapping. 
+
+     Die Property ist wie folgt aufgebaut:
+
+     * MIN (minimale Skillability im Bereich von 0 - 10000)
+     * MAX (maximale Skillability im Bereich von 0 - 10000)
+     * LEV (Gildenlevel)
+     * ZWEIG (Gildenzweig)
+
+
+BEMERKUNGEN:
+     Fuer die Argumente LEV und ZWEIG stehen folgende Auswahl-
+     moeglichkeiten zur Verfuegung.
+
+     LEV:
+        Z_ANFAENGER	0
+	Z_LEHRLING	1
+	Z_MEISTER	2
+	Z_ERZMEISTER	3
+
+     ZWEIG:
+        ZZW_ANGRIFF		  1
+	ZZW_ABWEHR		  2
+	ZZW_ILLUSION		  4
+	ZZW_BEHERRSCHUNG	  8
+	ZZW_HELLSICHT		 16
+	ZZW_VERWANDLUNG		 32
+	ZZW_SCHWARZ		 64	INAKTIV
+	ZZW_WEISS		128
+	ZZW_ALLE		511
+
+BEISPIEL:
+     SetProp(P_Z_INFO, ({9000, 9500, Z_ERZMEISTER, ZZW_ANGRIFF|ZZW_ABWEHR}));
+     erzeugt einen Erzmagister-PC, der alle Lehrlings- sowie die Magister und
+     Erzmagister-Sprueche Angriff und Abwehr mit 90-95% beherrscht.
+
+
+SIEHE AUCH:
+     /p/zauberer/text/wiznpc.doku
+
+21.Okt 2006 Chagall
diff --git a/doc/props/gildenprops/P_Z_NO_MATERIAL b/doc/props/gildenprops/P_Z_NO_MATERIAL
new file mode 100644
index 0000000..4b040a0
--- /dev/null
+++ b/doc/props/gildenprops/P_Z_NO_MATERIAL
@@ -0,0 +1,18 @@
+P_Z_NO_MATERIAL
+
+NAME:
+     P_Z_NO_MATERIAL                     "npc_braucht_keine_kmp"
+
+DEFINIERT IN:
+     /p/zauberer/zauberer.h
+
+BESCHREIBUNG:
+     Setzt man diese Property in einem NPC, so benoetigt er fuer die
+     Sprueche der Zauberergilde keine Komponenten.
+
+BEMERKUNGEN:
+     NIEMALS diese Property einfach so in einem Spieler setzen.
+
+SIEHE AUCH:
+
+21.Okt 2006 Chagall
diff --git a/doc/props/gildenprops/P_Z_NO_NOCONN b/doc/props/gildenprops/P_Z_NO_NOCONN
new file mode 100644
index 0000000..332dd14
--- /dev/null
+++ b/doc/props/gildenprops/P_Z_NO_NOCONN
@@ -0,0 +1,22 @@
+P_Z_NO_NOCON
+
+NAME:
+     P_Z_NO_NOCON					"no_nocon"
+
+DEFINIERT IN:
+     /p/zauberer/wiznpc.h
+
+BESCHREIBUNG:
+     Der Standardzauberergildennpc setzt SI_NO_CONSEQUENCES, damit
+     die Gildenpcs nicht den negativen Auswirkungen beim Misslingen
+     der Sprueche geschuetzt sind. Setzt man diese Property vor
+     P_Z_INFO auf 0, wird das Flag nicht gesetzt.
+
+
+BEMERKUNGEN:
+     Muss vor P_Z_INFO gesetzt werden, damit es wirksam ist.
+
+SIEHE AUCH:
+     /p/zauberer/text/wiznpc.doku, P_Z_INFO
+
+21.Okt 2006 Chagall
diff --git a/doc/props/gildenprops/P_Z_NO_SPELL_SUPPORT b/doc/props/gildenprops/P_Z_NO_SPELL_SUPPORT
new file mode 100644
index 0000000..4a1ab28
--- /dev/null
+++ b/doc/props/gildenprops/P_Z_NO_SPELL_SUPPORT
@@ -0,0 +1,25 @@
+P_Z_NO_SPELL_SUPPORT
+
+NAME:
+     P_Z_NO_SPELL_SUPPORT	"zauberer_ruestung_unterstuetzt_noch_nicht"
+
+DEFINIERT IN:
+     /p/zauberer/zauberer.h
+
+BESCHREIBUNG:
+     Normalerweise unterstuetzt eine Ruestung den Zauberer, sobald sie im
+     entsprechenden Ruestungsmaster eingetragen ist. Moechte man allerdings
+     die Unterstuetzung an bestimmte Bedingungen knuepfen, z.B. das loesen
+     einer Miniquest, so kann man diese Property auf 1 setzen. Die Ruestung
+     unterstuetzt dann nicht. Um die Unterstuetzung wieder zu aktivieren,
+     setzt man die Property wieder auf 0.
+
+BEMERKUNGEN:
+     NIEMALS diese Property einfach so in fremden Zaubererruestungen 
+     setzen. Sollte der Gildenmagier erfahren, dass z.B. ein NPC
+     einfach so die Unterstuetzung der Ruestungen ausschaltet, wird
+     diese Property wieder deaktiviert.
+
+SIEHE AUCH:
+
+21.Okt 2006 Chagall
diff --git a/doc/props/gildenprops/kaempferboni b/doc/props/gildenprops/kaempferboni
new file mode 100644
index 0000000..50e4be5
--- /dev/null
+++ b/doc/props/gildenprops/kaempferboni
@@ -0,0 +1,264 @@
+
+Kaempferboni und deren Implementation
+-------------------------------------
+-------------------------------------
+
+Bei den Kaempfern gibt es einige Properties, die, in Waffen oder Ruestungen
+gesetzt, der Kampfverlauf eines Spielers erheblich beeinflussen koennen.
+
+Zu beachten ist, dass die Abnahme von Waffen oder Ruestungen mit Kaempferboni
+allein der Balance obliegt. Der Gildenmagier der Kaempfer steht aber gerne
+mit Rat und Tat zur Seite.
+
+
+Abschnitt A
+-----------
+
+In Waffen koennen nachfolgende, in /p/kaempfer/kaempfer.h definierten,
+Properties gesetzt werden. Die meisten davon fungieren als 'Boni' und werden
+dem Spieler auch mittels 'schaetz <waffe>' angezeigt:
+
+
+1 Waffenschlagbonus - K_BRAWLING_WC (INT) - "k_brawling_wc"
+
+  Wenn die Waffe eine zusaetzlich gefaehrliche Stelle besitzt - z.B. einen
+  harten Dorn am Stielende, eine Spitze am Ruecken einer Axtklinge, Zacken
+  am Dolchgriff - kann man der Waffe einen Waffenschlagbonus geben.
+  Dies bedeutet, dass der Waffenschlag um ein paar Prozente verstaerkt wird,
+  da der Spieler natuerlich versucht, immer genau mit diesem 'feature'
+  den Waffenschlag auszufuehren (der Waffenschlag ist kurz gesagt ein
+  unerwarteter Schlag, der nicht mit dem 'normalen' Waffenende ausgefuehrt
+  wird, der Gegner wird dadurch ueberrascht -> mehr Schaden).
+  Da solch ein 'feature' doch recht auffaellig ist, sollte es in der
+  Langbeschreibung der Waffe auf jeden Fall erwaehnt werden.
+
+  Interessant zu wissen waere noch, dass Zweihandwaffen einen generellen
+  zusaetzlichen Bonus auf den Waffenschlag bekommen und dass es eine
+  Abstufung gibt, nach der die Waffengattungen die Hoehe des Basiswertes
+  gesetzt bekommen, wobei Speere den hoechsten und Messer den niedrigsten
+  besitzen:
+
+  Speere - Kampfstaebe - Aexte - Keulen - Schwerter - Messer
+
+  Der max. Bonus fuer diese Property betraegt 30, wobei 1-10 -> geringer
+  Bonus, 11-20 -> guter Bonus, 21-30 -> sehr guter Bonus.
+
+  Bitte beachten: ein Zweihand-Speer mit max. P_WC und max. K_BRAWLING_WC
+  haut entsprechend gut rein und sollte nur schwer zu ergattern sein, bzw.
+  noch andere Auflagen haben (ggf. unique, personalisiert, etc.)
+
+
+2 Waffenschlagschaden - K_BRAWLING_DT (STRING) - "k_brawling_dt"
+
+  Wenn die Waffe, mit der der Kaempfer einen Waffenschlag ausfuehrt, ein
+  'feature' hat, mit dem er diesen Schlag ausfuehrt, kann dieses 'feature'
+  einen anderen Waffenschlagschaden besitzen. Z.B. kann ein Schwert, welches
+  normalerweise DT_SLASH macht, besonders lange und spitze Parierstangen
+  besitzen, die vielleicht auch noch vergiftet sind. Dann kann der Magier
+  ({DT_PIERCE,DT_POISON}) setzen, so dass beim Waffenschlag immer ein
+  Mischschaden aus Stiche und Gift erfolgt.
+
+
+3 Waffenschlagsmeldung - K_BRAWLING_MSG (STRING/STRING*) - k_brawling_msg"
+
+  In diese Property kann man hineinschreiben, mit welchem Teil der Waffe
+  der Waffenschlag ausgefuehrt wird. Angenommen, es bietet sich an, mit
+  einer Waffe stets den Waffenschlag mit einem grossen Knauf am Griff
+  auszufuehren, wird schlicht und einfach "mit einem grossen Knauf am
+  Griff der Schlachtaxt" in die Property gesetzt.
+  Sollte sich bei der Programmierung ergeben, dass es sich anbietet, der
+  Waffe mehr als nur eine guenstige Stelle anzudichten mit der man den
+  Waffenschlag ausfuehren kann, so setzt man ein Array, z.B. ({"mit einem
+  grossen Knauf am Griff der Schlachtaxt","mit der breiten Seite der "
+  "Schlachtaxtklinge"}). Insgesamt ist darauf zu achten, dass die Meldungen
+  'vollstandig' sind. Das Array kann beliebige Groesse annehmen, es wird
+  dann zufaellig eine Meldung beim Schlag ausgesucht.
+
+  Es empfiehlt sich, jede Waffe mit dieser Property zu schmuecken, die
+  K_BRAWLING_WC gesetzt haben, da die Waffenschlagmeldungen damit im Kampf
+  'individualisiert' werden. In der Praxis wird es jedoch daran scheitern,
+  dass es viel zu viele alte Waffen gibt, die keiner mehr anfassen moechte.
+  Daher wird auf Standardmeldungen zurueckgegriffen, sollte diese Property
+  nicht gesetzt sein.
+
+
+4 Waffenbruchbonus - K_WEAPON_SHATTER (INT) - "k_weapon_shatter"
+
+  Waffen, die besonders fuer den Waffenbruch konstruiert wurden, koennen
+  einen Bonus einbringen, der in dieser Property angegeben wird. Natuerlich
+  eignen sich die verschiedenen Waffentypen wieder unterschiedlich gut fuer
+  einen Waffenbruch: Keulen (meist aufgrund ihres Gewichts) am besten, Messer
+  am schlechtesten, alle anderen dazwischen (Axt - Schwert - Stab - Speer).
+  Dabei kriegen alle Waffen, die u.a. Schlagschaden verursachen, nochmal
+  einen kleinen Bonus obendrauf.
+
+  Der max. Bonus fuer diese Property betraegt 50, wobei 1-10 -> geringer
+  Bonus, 11-30 -> guter Bonus, 31-50 -> sehr guter Bonus.
+
+  Bei gut gelungenem Waffenbruch wird die Waffe des Gegners beschaedigt, wenn
+  die Technik sehr gut gelingt, kann es auch sein, dass dem Gegner die Waffe
+  aus der Hand geschlagen wird (der Spieler kann sie allerdings nicht
+  aufheben und der NPC zueckt sie nach ein paar Kampfrunden wieder).
+
+
+5 Bonus fuer Finte/Waffentrick - K_DISTRACTING_WEAPON (INT) -
+  "k_distracting_weapon"
+
+  Waffen, die fuer den Gegner aufgrund ihrer Bauweise besonders irritierend
+  sein koennen, koennen einen Bonus fuer Finte und Waffentrick haben. Dabei
+  wird der Gegner bei einer Finte bzw. einem Waffentrick NOCH mehr verwirrt,
+  als er es ohnehin schon nur durch die angewandte Technik wird.
+  Ein gutes Beispiel hierfuer ist z.B. der Kriegshamster: ein Hamster, der
+  auf einem Holzstab aufgespiesst ist, sollte fuer den Gegner schon SEHR
+  irritierend sein ;).
+  Die Waffengattung hat nur wenig Einfluss auf Finte/Waffentrick.
+
+  Der max. Bonus fuer diese Property betraegt 50, wobei 1-10 -> geringer
+  Bonus, 11-30 -> guter Bonus, 31-50 -> sehr guter Bonus.
+
+
+6 Todesstossbonus - K_CRITICAL_HIT (INT) - "k_critical_hit"
+
+  Man stelle sich eine Waffe mit besonders spitzer, langer Klinge vor oder
+  eine magische Waffe, die dem geschwaechten Gegner die Seele entreisst.
+  Diese Eigenschaften verleihen dem Spieler beim Todesstoss einen
+  entsprechenden Bonus von bis zu 100%.
+
+  Es ist moeglich, dass ein und dasselbe 'feature' sowohl dem Waffenschlag
+  als auch dem Todesstoss den Bonus stellt, z.B. zwei Hiebklingen auf dem
+  Klingenruecken einer grossen Axt. Auch dies sollte man deutlich aus der
+  Langbeschreibung herauslesen koennen.
+
+  Der max. Bonus fuer diese Property betraegt 100, wobei 100 eine Verdopplung
+  der P_WC beim Todesstoss bedeutet!
+  Ansonsten bedeutet 1-20 -> geringer Bonus, 21-60 -> guter Bonus,
+  61-100 -> sehr guter Bonus.
+
+
+7 Waffenwurfbonus - K_THROWING_WEAPON (INT) - "k_throwing_weapon"
+
+  Wenn eine Waffe besonders gut zum Werfen geeignet ist, z.B. ein Wurfdolch,
+  dann kann diese Property gesetzt werden. Natuerlich ist der Grundwert wieder
+  von der Waffengattung abhaengig. Es gilt, dass man Messer und Speere
+  grundsaetzlich am besten werfen - und dabei gut Schaden machen - kann, am
+  schlechtesten schneiden Keulen und Kampfstaebe ab.
+
+  Der max. Bonus fuer diese Property betraegt 50, wobei 1-20 -> geringer
+  Bonus, 21-40 -> guter Bonus, 31-50 -> sehr guter Bonus.
+
+  Zu beachten ist hierbei, dass ein sehr hoher Bonus nur bei Waffen mit etwas
+  geringerer P_WC vergeben werden sollte. Ein reines Wurfmesser ist nunmal im
+  normalen Kampf nicht die gefaehrlichste aller Waffen (speziell
+  ausbalanciert, keinen richtigen Griff, etc.).
+  Natuerlich kann es einen Wurfspeer mit max. P_WC und sehr hohem
+  Waffenwurfbonus geben, allerdings mit den ueblich hohen Restriktionen.
+
+
+8 KO-Schlag-Bonus - K_KO (INT) - "k_ko"
+
+  Waffen, die besonders fuer einen KO-Schlag geeignet sind, koennen einen
+  Bonus mit dieser Property bekommen. Eine entsprechende Waffe koennte z.B.
+  ein lederumwickelter Pruegel sein, denn man will den Gegner ja nur KO
+  schlagen und nicht gleich toeten.
+
+  Der max. Bonus fuer diese Property betraegt 50, wobei 1-20 -> geringer
+  Bonus, 21-30 -> guter Bonus, 31-50 -> sehr guter Bonus.
+
+
+9 Kein Waffenschaerfen - K_NO_HONING (INT) - "k_no_honing"
+
+  Wenn eine Waffe aus irgendeinem Grund nicht geschaerft werden kann oder
+  darf, muss man diese Property auf 1 setzen.
+  Eine Erklaerung dafuer sollte in der P_LONG bzw. P_INFO erfolgen.
+
+
+Abschnitt B
+-----------
+
+Die beiden Properties, P_EFFECTIVE_AC und P_EFFECTIVE_WC, welche in
+<combat.h> definiert sind, sind eigentlich nur dazu da, um Ruestungen und
+Waffen, die eine DefendFunc() bzw. HitFunc() besitzen, korrekt vom Spieler
+einschaetzen lassen zu koennnen.
+
+Das Kaempferspellbook verwendet diese Properties darueberhinaus wie folgt:
+
+
+1 Schutzboni in Waffen - P_EFFECTIVE_AC (INT) - "effective_ac"
+
+  Ist diese Property in einer Waffe gesetzt, geht das Kaempferspellbook
+  davon aus, dass diese Waffe mehr oder weniger die Faehigkeit besitzt,
+  auch wie eine Ruestung schuetzen zu koennen. Da man eine Waffe aber nicht
+  anziehen, sondern nur vor sich hertragen kann, kann auch der max.
+  Ruestungsschutz einer Waffe nur gleich dem max. Ruestungsschutz eines
+  Schildes entsprechen.
+  Eine gesetzte P_EFFECTIVE_AC in einer Waffe wird dem Spieler als mehr
+  oder weniger gute 'Paradewaffe' im 'schaetz' angezeigt und geht sowohl bei
+  der Waffenparade als auch beim Block als Bonus mit ein.
+
+  Z.B. koennte ein leichtes Schwert, was aufgrund seiner Bauweise mehr fuer
+  den defensiven Kampf ausgelegt ist (extralange Parierstangen, verstaerkter
+  Handschutz im Griffbereich, ...) wie ein maessiges Schild wirken. Die
+  Vorteile liegen auf der Hand: der Spieler bekommt verstaerkten Schutz,
+  kann aber weiterhin eine Zweihandwaffe fuehren.
+
+  Der max. Bonus fuer diese Property betraegt 40, wobei 1-20 -> geringer
+  Bonus, 21-30 -> guter Bonus, 31-40 -> sehr guter Bonus.
+
+  Zu beachten ist hier, dass sehr gute Parierwaffen mit P_EFFECTIVE_AC > 30
+  moeglichst deutlich unter der max. WC liegen sollten.
+
+  Anmerkungen:
+  Eine gesetzte P_EFFECTIVE_AC in einem Schild kann den Bonus fuer die
+  Schildparade nach oben oder unten beeinflussen. Moechte man ein Schild
+  herstellen, welches speziell bei der Schildparade der Kaempfer besser
+  als 'normal' schuetzt, sollte man hier einen Wert eintragen, der deutlich
+  groesser als die P_AC des Schildes ist.
+
+  Eine gesetzte P_EFFECTIVE_AC in einer anderen Ruestung hat nur den Nutzen,
+  auf deren erhoehten (und nicht sofort sichtbaren) Verteidigungswert
+  hinzuweisen, der durch eine DefendFunc() realisiert wird.
+
+
+2 Angriffsboni in Ruestungen - P_EFFECTIVE_WC (INT) - "effective_wc"
+
+  Fuer die Kaempfer koennen folgende Ruestungstypen modifiziert werden:
+  AT_TROUSERS (Hosen), AT_HELMET (Kopfbedeckung), AT_BOOT (Fusskleidung),
+  AT_ARMOUR (Koerperruestung), AT_SHIELD (Schilde).
+  Ist in einer dieser Typen P_EFFECTIVE_WC gesetzt, so macht diese Ruestung
+  bei einem Angriff mit einer Spezialattacke (Kniestoss, Kopfstoss, Fusstritt,
+  Ellbogenschlag und Schildstoss) entsprechend mehr bzw. weniger Schaden als
+  ohne diese Property. Eine entsprechende Begruendung fuer eine Verstaerkung
+  oder Schwaechung sollte auch hier fuer den Spieler offensichtlich sein
+  (Dornen am Schild, verstaerkter Kniebereich, Zacken am Helm, etc.).
+
+  Wenn man der Ruestung einen Bonus geben moechte, muss man darauf achten,
+  dass P_EFFECTIVE_WC hoeher ist als die P_AC der Ruestung! Sollte
+  P_EFFECTIVE_WC niedriger als P_AC sein, wird dennoch P_EFFECTIVE_WC als
+  Angriffswert genommen. Dies stellt natuerlich eine Schwaechung der
+  Spezialattacke dar. Moeglicherweise ist aber genau das gewollt, wenn eine
+  Ruestung, die sehr gut schuetzt, nur geringen Kaempferbonus aufweisen soll.
+
+  Beispiel: ein Schild aus Hartgummi kann recht gut Schlaege aller Art
+  abfangen (-> P_AC 35). Will der Kaempfer jedoch einen Schildstoss damit
+  machen, fehlt ihm aufgrund der Beschaffenheit die Wucht, eher daempft es
+  den Schildstoss noch ein wenig (-> P_EFFECTIVE_WC 25).
+
+  Der Maximalwert fuer die P_EFFECTIVE_WC bei Kaempfern ist der jeweils
+  doppelte maximale P_AC-Wert (s. 'man ruestungen').
+
+  Die Angabe eines Schadenstyps (P_DAM_TYPE) in einer Ruestung kann dann
+  sinnvoll sein, wenn bei der Spezialattacke ein spezieller Schaden gemacht
+  werden soll. Beispielsweise sollten Flammenstiefel logischerweise DT_FIRE
+  und DT_BLUDGEON oder DT_PIERCE bei einem Kampftritt verursachen. Es MUSS
+  (logischerweise) mindestens ein physikalischer Schadenstyp enthalten sein.
+  Wird kein Schadenstyp angegeben, wird auf Standardtypen zurueckgegriffen.
+
+
+SIEHE AUCH:
+     Waffen:     P_WC, P_TOTAL_WC, P_EFFECTIVE_WC, HitFunc()
+     Ruestungen: P_AC, P_TOTAL_AC, P_EFFECTIVE_AC, DefendFunc()
+     Files:      /std/weapon.c, /std/weapon/combat.c
+     Balance:    waffen, ruestungen, properties
+
+-----------------------------------------------------------------------------
+26.10.2012, Gabylon
diff --git a/doc/props/obsolete/P_BALANCED_WEAPON b/doc/props/obsolete/P_BALANCED_WEAPON
new file mode 100644
index 0000000..e785f2c
--- /dev/null
+++ b/doc/props/obsolete/P_BALANCED_WEAPON
@@ -0,0 +1,35 @@
+********************* UNGENUTZTE PROPERTY *****************************
+* Diese Property wird von der Mudlib NICHT ausgewertet und kann       *
+* als veraltet gelten.                                                *
+* Momentan ist auch keine Gilde bekannt, die mehr macht, als sie      *
+* auszugeben.                                                         *
+***********************************************************************
+NAME:
+        P_BALANCED_WEAPON  "balanced_weapon"
+
+DEFINIERT IN:
+        /sys/weapon.h
+
+BESCHREIBUNG:
+        Die Property gibt an, ob eine Waffe ausbalanciert ist oder nicht.
+        Die beiden moeglichen Werte sind logischerweise:
+
+                WP_BALANCED       balanciert
+                WP_UNBALANCED     unbalanciert
+
+        Die WP_* sind ebenfalls in <weapon.h> definiert.
+
+BEISPIELE:
+        a) Eine ausbalancierte Waffe ist z.B. ein Kampfstab.
+
+            SetProp(P_BALANCED_WEAPON,WP_BALANCED);
+
+        b) Eine nicht ausbalancierte Waffe ist z.B. eine Keule.
+
+            SetProp(P_BALANCED_WEAPON,WP_UNBALANCED);
+
+SIEHE AUCH:
+        P_TECHNIQUE, /std/weapon/combat.c
+
+LETZTE AeNDERUNG:
+15.02.2009, Zesstra
diff --git a/doc/props/obsolete/P_DEFAULT_INFO b/doc/props/obsolete/P_DEFAULT_INFO
new file mode 100644
index 0000000..814928c
--- /dev/null
+++ b/doc/props/obsolete/P_DEFAULT_INFO
@@ -0,0 +1,28 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte nicht mehr in neuem Code nutzen. *
+***********************************************************************
+
+NAME:
+    P_DEFAULT_INFO                "default_info"
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Default-Antwort eines Npc, wenn er auf das Schluesselwort durch den
+    Spieler kein AddInfo parat hat.
+
+BEMERKUNG:
+    Diese Property sollte nicht mehr benutzt werden. Stattdessen bitte
+    AddInfo(DEFAULT_INFO,...) verwenden.
+    Dem in dieser Prop angegeben String wird immer der Name des Npc
+    vorausgestellt. Will man dies verhindern, muss man sie ueberschreiben.
+
+BEISPIEL:
+    SetProp(P_DEFAULT_INFO,"bohrt gelangweilt in der Nase.\n");
+
+SIEHE AUCH:
+    AddInfo
+
+----------------------------------------------------------------------------
+17.08.2010, Zesstra
diff --git a/doc/props/obsolete/P_EXTRA_LOOK b/doc/props/obsolete/P_EXTRA_LOOK
new file mode 100644
index 0000000..3777a25
--- /dev/null
+++ b/doc/props/obsolete/P_EXTRA_LOOK
@@ -0,0 +1,35 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte benutzt sie NICHT mehr, sondern  *
+* stattdessden AddExtraLook().                                        *
+***********************************************************************
+
+NAME:
+	P_EXTRA_LOOK			"extralook"
+
+DEFINIERT IN:
+	/sys/living/description.h
+
+BESCHREIBUNG:
+	Diese Property enthaelt einen String. Sie wird entweder in Lebewesen
+	direkt oder in Objekten gesetzt wird, die im Besitz von Lebewesen
+	sein koennen.
+	Diese Strings erscheinen dann zusaetzlich in der Langbeschreibung
+	des Lebewesens bzw. des Besitzers (wenn das Objekt sich direkt im
+	 Lebewesen befindet, jedoch nicht in einem Behaelter im Lebewesen).
+	Fuer den Zeilenumbruch muss man selbst sorgen.
+
+BEISPIEL:
+	Ein Spieler hat eine Pfeife im Mund. In dieser Pfeife setzt man z.B.
+	in der Funktion zum Pfeife Rauchen folgendes:
+	  SetProp(P_EXTRA_LOOK,break_string(
+	 this_player()->Name(WER)+" ist ganz umnebelt.",78);
+
+BEMERKUNG:
+  BITTE NICHT MEHR BENUTZEN!
+
+SIEHE AUCH:
+	long(), /std/living/description.c, /std/player/base.c
+  AddExtraLook(), RemoveExtraLook()
+
+----------------------------------------------------------------------------
+13.05.2007, Zesstra
diff --git a/doc/props/obsolete/P_LAST_KILLER b/doc/props/obsolete/P_LAST_KILLER
new file mode 100644
index 0000000..27eea8f
--- /dev/null
+++ b/doc/props/obsolete/P_LAST_KILLER
@@ -0,0 +1,20 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet und wird bald aus der Mudlib entfernt.  *
+***********************************************************************
+
+NAME:
+    P_LAST_KILLER                 "last_killer"                 
+
+DEFINIERT IN:
+    /sys/player.h
+
+BESCHREIBUNG:
+     Letzter Moerdes des Wesens.
+     Diese Property wurde nur in Spielern gesetzt und auch dann nicht immer.
+     Bitte stattdessen P_KILLER abfragen, welche in NPC und Spielern gesetzt
+     wird.
+
+SIEHE AUCH:
+    P_KILLER, die()
+
+05.09.2008, Zesstra
diff --git a/doc/props/obsolete/P_LAST_PEACE_TIME b/doc/props/obsolete/P_LAST_PEACE_TIME
new file mode 100644
index 0000000..762233e
--- /dev/null
+++ b/doc/props/obsolete/P_LAST_PEACE_TIME
@@ -0,0 +1,27 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet und wird bald aus der Mudlib entfernt.  *
+***********************************************************************
+PROPERTY
+
+	P_LAST_PEACE_TIME	"last_peace_time"
+
+DEFINIERT IN
+
+	/std/living/combat.c
+
+BESCHREIBUNG
+
+	Diese Property gibt an, wann zuletzt versucht wurde, einen NPC zu
+	befrieden. Bitte nach Moeglichkeit nur lesend verwenden. Des weiteren
+	wird sie nur im ueblichen Verhalten von QueryPacify gesetzt, und nur
+	dann, wenn P_ACCEPT_PEACE nicht gesetzt ist.
+
+SIEHE AUCH
+
+	QueryPacify, P_ACCEPT_PEACE
+
+LETZTE AENDERUNG
+
+	2004-03-17, 14:30 von Humni
+	
+
diff --git a/doc/props/obsolete/P_LOG_FILE b/doc/props/obsolete/P_LOG_FILE
new file mode 100644
index 0000000..1eafe40
--- /dev/null
+++ b/doc/props/obsolete/P_LOG_FILE
@@ -0,0 +1,45 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property wird nicht mehr ausgewertet.                         *
+***********************************************************************
+NAME:
+    P_LOG_FILE                   "log_file"
+
+DEFINIERT IN:
+    /sys/thing/properties.h
+
+BESCHREIBUNG:
+    Enthaelt einen String auf einen Filenamen. 
+
+    Werden zu dem Objekt (Raum, Monster, ...) Fehlermeldungen abgesetzt, 
+    werden diese in das angegebene File umgeleitet. Die Eintragung in
+    die per Default fuer Fehlermeldungen vorgesehenen Dateien erfolgt
+    nicht.
+
+BEMERKUNGEN:
+    P_LOG_FILE wird ausgewertet wie log_file().
+
+    Das heisst, es wird AUF JEDEN FALL nach /log geschrieben!
+
+    Direkt in /log kann NICHT geschrieben werden, es muss also ein 
+    Unterverzeichnis mit Eurem Magiernamen vorhanden sein.
+
+BEISPIELE:
+    SetProp(P_LOG_FILE,"tilly_log");          // FALSCH, es wuerde versucht, 
+                                                 das File /log/tilly_log 
+                                                 anzulegen
+    SetProp(P_LOG_FILE,"/log/tilly_log");     // FALSCH, es wuerde versucht, 
+                                                 das File /log/log/tilly_log
+                                                 anzulegen
+    SetProp(P_LOG_FILE,"/d/ebene/tilly_log"); // FALSCH, s.o.
+
+    SetProp(P_LOG_FILE,"tilly/tilly_log");    // RICHTIG!
+
+    Im letzten Beispiel werden alle Eintraege in das File tilly_log ge-
+    schrieben, das sich im Verzeichnis /log/tilly/ befindet.
+
+    Das Unterverzeichnis /tilly in /log muss zuvor angelegt werden.
+
+SIEHE AUCH:
+    P_LOG_INFO, write_file(), log_file(),
+
+Letzte Aenderung: 13.09.04 Tilly@MorgenGrauen
diff --git a/doc/props/obsolete/P_NEXT_SPELL_TIME b/doc/props/obsolete/P_NEXT_SPELL_TIME
new file mode 100644
index 0000000..4742456
--- /dev/null
+++ b/doc/props/obsolete/P_NEXT_SPELL_TIME
@@ -0,0 +1,30 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte nicht mehr in neuem Code nutzen. *
+***********************************************************************
+
+NAME:
+    P_NEXT_SPELL_TIME             "next_spell"
+
+DEFINIERT IN:
+    /sys/new_skills.h
+
+BESCHREIBUNG:
+    Wann kann das naechste Mal gezaubert werden?
+    Dies ist eine globale Spruchermuedung/-Sperre.
+    Flexiblere Sperren koennen mittels SetSpellFatigue/CheckSpellFatigue()
+    verwaltet werden.
+
+    Diese Property ist keine echte Property, sondern liefert nur das
+    Ergebnis von von CheckSpellFatigue() zurueck bzw. ruft beim Setzen
+    SetSpellFatigue(<spruchsperre>, 0) auf.
+    Diese Prop sollte _nicht_ mittels Query- oder Setmethoden manupuliert
+    werden, da sonst Inkonsistenzen zum Ergebnis von CheckSpellFatigue()
+    auftreten.
+
+SIEHE AUCH:
+    SetSpellFatigue(L), CheckSpellFatigue(L)
+    spruchermuedung
+
+ZULETZT GEAeNDERT:
+14.03.2010, Zesstra
+
diff --git a/doc/props/obsolete/P_READ_MSG b/doc/props/obsolete/P_READ_MSG
new file mode 100644
index 0000000..5c79fdc
--- /dev/null
+++ b/doc/props/obsolete/P_READ_MSG
@@ -0,0 +1,32 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte nicht mehr in neuem Code nutzen. *
+***********************************************************************
+NAME:
+    P_READ_MSG                "read_msg"                
+
+DEFINIERT IN:
+    /sys/properties.h
+
+BESCHREIBUNG:
+    Diese Property ist veraltet. Ihre Funktion wird von
+    AddReadDetail(SENSE_DEFAULT, ...) uebernommen.
+    
+    Hier koennen Informationen gespeichert werden, die beim Lesen
+    des Objektes ausgegeben werden.
+     
+    Fuer das Identifizieren des zu lesenden Objektes wird der gleiche
+    Mechanismus benutzt wie fuer lesbare und andere Details.
+
+    Die Benutzung von process_string() ist in dieser Prop nicht mehr erlaubt.
+
+BEISPIEL:
+    AddId(({"rolle", "schriftrolle"}));
+    SetProp(P_READ_MSG,
+       "Du oeffnest die Rolle und liest: LOREM IPSUM ...\n");
+     
+SIEHE AUCH:
+    Details:   AddReadDetail(), RemoveReadDetail(), P_READ_DETAILS
+    Sonstiges: break_string()
+
+09.12.2012, Zesstra
+
diff --git a/doc/props/obsolete/P_TECHNIQUE b/doc/props/obsolete/P_TECHNIQUE
new file mode 100644
index 0000000..1657027
--- /dev/null
+++ b/doc/props/obsolete/P_TECHNIQUE
@@ -0,0 +1,44 @@
+********************* UNGENUTZTE PROPERTY *****************************
+* Diese Property wird von der Mudlib NICHT ausgewertet und kann       *
+* als veraltet gelten.                                                *
+* Momentan ist auch keine Gilde bekannt, die mehr macht, als sie      *
+* auszugeben.                                                         *
+***********************************************************************
+NAME:
+	P_TECHNIQUE				"technique"
+
+DEFINIERT IN:
+	/sys/weapon.h
+
+BESCHREIBUNG:
+        Die Technik(en), mit denen eine Waffe im Kampf eingesetzt werden
+        kann. Folgende Techniken stehen zur Verfuegung:
+
+                TQ_STROKE       Streichtechnik
+                TQ_THRASH       Schlagtechnik
+                TQ_THRUST       Stosstechnik
+                TQ_WHIP         Peitschtechnik
+
+        Die Techniken sind ebenfalls in <weapon.h> definiert und auf der
+        man-page 'techniken' naeher erlaeutert.
+
+BEMERKUNGEN:
+        Man kann einer Waffe eine oder mehrere Techniken zuweisen.
+
+BEISPIELE:
+        a) Eine Waffe, die nur mit einer Peitschtechnik eingesetzt wird,
+           also typischerweise eine Peitsche, aber auch ein Morgenstern:
+
+            SetProp(P_TECHNIQUE,TQ_WHIP);
+
+        b) Eine Waffe, die sowohl mit der Schlag- als auch der Stosstechnik
+           eingesetzt wird, also z.B. eine Hellebarde:
+
+            SetProp(P_TECHNIQUE,({TQ_THRASH,TQ_THRUST}));
+
+SIEHE AUCH:
+        techniken, P_BALANCED_WEAPON, /std/weapon/combat.c
+
+LETZTE AeNDERUNG:
+15.02.2009, Zesstra
+
diff --git a/doc/props/obsolete/P_TMP_ATTACK_HOOK b/doc/props/obsolete/P_TMP_ATTACK_HOOK
new file mode 100644
index 0000000..bdc8152
--- /dev/null
+++ b/doc/props/obsolete/P_TMP_ATTACK_HOOK
@@ -0,0 +1,73 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte nicht mehr in neuem Code nutzen. *
+***********************************************************************
+P_TMP_ATTACK_HOOK
+
+NAME:
+    P_TMP_ATTACK_HOOK             "attack_hook"
+
+DEFINIERT IN:
+    /sys/new_skills.h
+
+BESCHREIBUNG:
+     Mittels dieser Property koennen die Attacken eines Livings ggf.
+     abgebrochen werden noch bevor Waffen oder Skills zum ausgewertet
+     wurden.
+
+     Es wird an dem Living die Property als mindestens 3-elementiges Array:
+     ({zeitpunkt, objekt, methode, ...})
+     gesetzt und die Methode 'methode' wird dann waehrend des Attack() des
+     Lebewesens in 'objekt' aufgerufen, solange time()<'zeitpunkt'.
+
+     Der Methode wird als Parameter der Gegner uebergeben.
+
+     Gibt die Methode 0 als Rueckgabewert zurueck, wird die Attacke sofort
+     kommentarlos abgebrochen.
+
+BEMERKUNGEN:
+     - Bitte das neuere Hooksystem (s. Manpage std/hooks) benutzen.
+     - falls die Zeit abgelaufen oder das Objekt zerstoert ist, wird die
+       Property auf 0 gesetzt
+     - vor dem Setzen immer auf die Existenz eines gueltigen Hooks
+       pruefen, einfaches Ueberschreiben fuehrt einerseits zu Fehlern
+       im Code anderer und ist andererseits unfair gegenueber ihnen
+
+BEISPIELE:
+     *** der Spieler erhaelt eine Verwundung, die ihn manchmal behindert ***
+     if(!pointerp(tmp=TP->QueryProp(P_TMP_ATTACK_HOOK)) ||
+        sizeof(tmp)<3 || tmp[0]<=time()) {
+       TP->SetProp(P_TMP_ATTACK_HOOK,
+		   ({time()+3600, this_object(), "test_hurt"}));
+     ...
+
+     // die entsprechende Methode, die bei jedem Angriff ueber Attack()
+     // gerufen wird ...
+     int test_hurt(object enemy) {
+
+       // mit 10% Chance generell und 20% Chance bei groesseren Gegnern
+       // bricht der Angriff ab ... previous_object() ist natuerlich
+       // der Angreifer
+       if(!random(10) ||
+          (enemy->QueryProp(P_SIZE)>previous_object()->QueryProp(P_SIZE) &&
+           !random(5)) {
+
+          tell_object(previous_object(),
+            "Deine Wunde schmerzt dich zu sehr um anzugreifen.\n");
+          tell_room(environment(previous_object()),
+            previous_object()->Name(WER,1)+" zuckt vor Schmerzen zusammen.\n",
+            ({previous_object()}));
+          return 0;
+       }
+
+       // ansonsten geht der Angriff weiter
+       return 1;
+     }
+
+SIEHE AUCH:
+     Angriff:	Attack(L)
+     Schutz:    Defend(L)
+     Verwandt:  InternalModifyAttack(L), P_TMP_ATTACK_MOD	
+     Hooks:	P_TMP_DIE_HOOK, P_TMP_MOVE_HOOK, P_TMP_DEFEND_HOOK
+     neue Hooks: std/hooks
+
+08.12.2008, Zesstra
diff --git a/doc/props/obsolete/P_TMP_ATTACK_MOD b/doc/props/obsolete/P_TMP_ATTACK_MOD
new file mode 100644
index 0000000..3491c0c
--- /dev/null
+++ b/doc/props/obsolete/P_TMP_ATTACK_MOD
@@ -0,0 +1,112 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte nicht mehr in neuem Code nutzen. *
+***********************************************************************
+P_TMP_ATTACK_MOD
+
+NAME:
+     P_TMP_ATTACK_MOD              "attack_mod"
+
+DEFINIERT IN:
+     /sys/new_skills.h
+
+BESCHREIBUNG:
+     Mittels dieser Property koennen die Attacken eines Livings temporaer
+     veraendert werden.
+
+     Es wird an dem Living die Property als mindestens 3-elementiges Array
+     ({zeitpunkt, objekt, methode, ...})
+     gesetzt und die Methode 'methode' wird dann waehrend des Attack() des
+     Lebewesens in 'objekt' aufgerufen, solange time()<'zeitpunkt'.
+
+     Der Methode wird beim Aufruf ein Kopie des Mappings uebergeben, in dem
+     die bisherigen Werte des Angriffes vermerkt sind.
+     Aufbau von Mapping 'ainfo':
+     ([ SI_ENEMY :           object Angreifer,			(-> Defend)
+        SI_SPELL :           0/1/array Spellparameter,		(-> Defend)
+        P_WEAPON :           - oder Waffe,
+        SI_SKILLDAMAGE_MSG:  string Angriffsmeldungsende an Raum,
+        SI_SKILLDAMAGE_MSG2: string Angriffsmeldungsende an Kaempfende,
+        SI_SKILLDAMAGE:      int Schaden in Zehntel HP (Skills bis auf Rasse
+			     drin!)				(-> Defend),
+        SI_SKILLDAMAGE_TYPE: string/string* Schadenstypen,	(-> Defend)
+        P_WEAPON_TYPE:       string Waffentyp (combat.h),
+        P_WC:		     - oder int WC der Waffe/Hand,
+        P_NR_HANDS:	     - oder int Hands der Waffe/Hand,
+     ]);
+
+     Gibt die Methode:
+     - 0 oder kein Mapping zurueck, fuehrt das zum Abbruch der Attacke
+       -> da inzwischen Waffen abgefragt wurden, koennen schon Meldungen
+          von diesen ausgegeben worden sein
+     - ein leeres Mapping ( ([]) ) zurueck, fuehrt das zu keiner Modifikation
+     - ein Mapping mit veraenderten Werten zurueck, werden diese in das
+       Angriffsmapping kopiert
+       Die geaenderten Werte werden teilweise von SkillResTransfer() in
+       den eigentlichen Angriff uebernommen.
+
+BEMERKUNGEN:
+     - falls die Zeit abgelaufen oder das Objekt zerstoert ist, wird die
+       Property auf 0 gesetzt
+     - vor dem Setzen immer auf die Existenz eines gueltigen Modifiers
+       pruefen, einfaches Ueberschreiben fuehrt einerseits zu Fehlern
+       im Code anderer und ist andererseits unfair gegenueber ihnen
+
+BEISPIELE:
+     *** ein besonder heisser Segen modifiziert die Attacken des Spielers ***
+     int action_segen() {
+       ...
+       mixed *tmp;
+
+       // pruefen, ob nicht ein anderer Modifier existiert
+       if(!pointerp(tmp=TP->QueryProp(P_TMP_ATTACK_MOD)) ||
+          sizeof(tmp)<3 || tmp[0]<=time()) {
+
+         object wield;
+         wield=TP->QueryProp(P_WEAPON);
+
+         write(break_string(
+           "Der Priester der Flamme weiht "+
+           (wield?wield->name(WEN,1):"deine Haende")+".", 78));
+
+         // setzen des Modifiers .. 30-40 Sekunden gueltig
+         TP->SetProp(P_TMP_ATTACK_MOD,
+	              ({time()+30+random(10), this_object(), "modfun"}));
+        } else ...
+        ...
+      return 1;
+     }
+
+     // die eigentlich Methode, die waehrend des Angriffs gerufen wird
+     mapping modfun(mapping ainfo) {
+       mapping ret;
+
+       // Returnwert ist immer ein Mapping, damit die Attacke weitergeht
+       ret=m_allocate(0,1);
+
+       // magische Waffen oder Sprueche werden nicht verbessert
+       if(ainfo[P_WEAPON_TYPE]!=WT_MAGIC) {
+         // sonst Verbesserungen ... Feuer addieren ...
+         ret[SI_SKILLDAMAGE_TYPE]=(ainfo[SI_SKILLDAMAGE_TYPE]||({}))+
+				({DT_FIRE});
+	 // ... und bei Waffe Meldungen anpassen
+         if(ainfo[P_WEAPON]) {
+           ret[SI_SKILLDAMAGE_MSG]=
+             " mit sengendem "+ainfo[P_WEAPON]->name(RAW);
+           ret[SI_SKILLDAMAGE_MSG2]=
+             " mit sengendem "+ainfo[P_WEAPON]->name(RAW);
+         }
+       }
+
+       return ret;
+     }
+
+SIEHE AUCH:
+     Angriff:	Attack(L)
+     Schutz:    Defend(L)
+     Verwandt:  InternalModifyAttack(L)
+		P_TMP_ATTACK_HOOK
+		P_TMP_DEFEND_HOOK
+     Sonstiges: SkillResTransfer(L)
+     Hooks:	P_TMP_DIE_HOOK, P_TMP_MOVE_HOOK
+
+10.Feb 2005 Gloinson
diff --git a/doc/props/obsolete/P_TMP_DEFEND_HOOK b/doc/props/obsolete/P_TMP_DEFEND_HOOK
new file mode 100644
index 0000000..986e63a
--- /dev/null
+++ b/doc/props/obsolete/P_TMP_DEFEND_HOOK
@@ -0,0 +1,110 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte nicht mehr in neuem Code nutzen. *
+***********************************************************************
+P_TMP_DEFEND_HOOK
+
+NAME:
+     P_TMP_DEFEND_HOOK             "defend_hook"
+
+DEFINIERT IN:
+     /sys/new_skills.h
+
+BESCHREIBUNG:
+     Mittels dieser Property koennen die Abwehren eines Livings temporaer
+     veraendert werden.
+
+     Es wird an dem Living die Property als mindestens 3-elementiges Array
+     ({zeitpunkt, objekt, methode, ...})
+     gesetzt und die Methode 'methode' wird dann waehrend des Defend() des
+     Lebewesens in 'objekt' aufgerufen, solange time()<'zeitpunkt'.
+
+     Der Methode werden die Parameter der Defend() uebergeben:
+     int dam, mixed dam_type, mixed spell, object enemy
+     - spell ist definitiv ein Mapping - ein an Defend() uebergebener
+       int-Wert wurde aequivalent umgesetzt.
+     - dam_type ist definitiv ein Array von Schadenswerten oder einem Wert
+
+     Zudem findet der Aufruf der Methode nach dem Abarbeiten der P_DEFENDERS
+     statt, diese koennen also weitere Modifikationen vorgenommen haben.
+
+     Gibt die Funktion:
+     - 0 zurueck, wird Defend() abgebrochen (und damit der Schaden voellig
+       abgefangen) - nur noch die Flucht wird geprueft
+     - ein 3-elementiges Array ({schaden, schadenstypen, spell}) zurueck,
+       werden diese Werte in der Defend() an Stelle der uebergebenen Werte
+       verwendet
+     - weder noch zurueck, wird das Ergebnis ignoriert und die Defend laeuft
+       regulaer weiter
+
+BEMERKUNGEN:
+     - Bitte das neuere Hooksystem (s. Manpage std/hooks) benutzen.
+     - falls die Zeit abgelaufen oder das Objekt zerstoert ist, wird die
+       Property auf 0 gesetzt
+     - vor dem Setzen immer auf die Existenz eines gueltigen Hooks
+       pruefen, einfaches Ueberschreiben fuehrt einerseits zu Fehlern
+       im Code anderer und ist andererseits unfair gegenueber ihnen
+
+BEISPIEL:
+     *** ein gruener Schutzzauber ***
+     // Setzen der Prop
+     ...
+     tmp=TP->QueryProp(P_TMP_DEFEND_HOOK);
+
+     // ein etwas ausfuehrlicher Check, ob wir ueberschreiben koennen,
+     // Existenz && Gueltigkeit
+     if(pointerp(tmp) && sizeof(tmp) && intp(tmp[0]) && (time()<tmp[0]))
+      write("Der Zauber klappt nicht!\n");
+     else {
+      // der Zauber gilt eine Stunde
+      TP->SetProp(P_TMP_DEFEND_HOOK,({time()+3600,TO,"abwehrfun");
+      write("Ein Zauber legt sich auf dich.\n");
+     }
+     ...
+
+     // die gerufene Methode
+     mixed abwehrfun(int dam, string* dam_type, mapping spell, object en) {
+      // keine rekursiven Schaeden abfangen ... mindestens ein magischer
+      // muss auch dabei sein
+      if((!mappingp(spell) || !spell[SP_RECURSIVE]) &&
+         sizeof(filter(dam_type,MAGICAL_DAMAGE_TYPES))) {
+
+       // mit 10% Whkeit schuetzt der Zauber total
+       if(!random(10)) {
+        tell_object(previous_object(),
+          "Dein Zauber gleisst rund um dich gruen auf.\n");
+        tell_room(environment(previous_object()), break_string(
+          previous_object()->Name(WESSEN)+" Haut gleisst rund um "+
+          previous_object()->QueryPronoun(WEN)+" gruen auf.",78),
+          ({previous_object()}));
+
+        // manchmal geht der Zauber dabei endgueltig kaputt
+        if(!random(10)) previous_object()->SetProp(P_TMP_DEFEND_HOOK, 0);
+
+        return 0;			// volles Abfangen des Angriffs
+       }
+
+       // der Zauber schuetzt auf jeden Fall immer ein bischen
+       tell_object(previous_object(),
+         "Dein Zauber flackert rund um dich gruen auf.\n");
+       tell_room(environment(previous_object()), break_string(
+         previous_object()->Name(WESSEN)+" Haut flackert rund um "+
+         previous_object()->QueryPronoun(WEN)+" gruen auf.",78),
+         ({previous_object()}));
+       dam=(7+random(2))*dam/10;	// Schaden reduzieren
+
+       return(({dam, dam_type, spell}));
+      }
+
+      // der Zauber schuetzt dann gar nicht ...
+      return 1;
+     }
+
+SIEHE AUCH:
+     Angriff:	Attack(L)
+     Schutz:    Defend(L)
+     Verwandt:	InternalModifyDefend(L), P_TMP_ATTACK_MOD
+     Hooks:	P_TMP_DIE_HOOK, P_TMP_MOVE_HOOK, P_TMP_ATTACK_HOOK
+     neue Hooks: std/hooks
+
+08.12.2008, Zesstra
+
diff --git a/doc/props/obsolete/P_TMP_DIE_HOOK b/doc/props/obsolete/P_TMP_DIE_HOOK
new file mode 100644
index 0000000..cd18917
--- /dev/null
+++ b/doc/props/obsolete/P_TMP_DIE_HOOK
@@ -0,0 +1,70 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte nicht mehr in neuem Code nutzen. *
+***********************************************************************
+P_TMP_DIE_HOOK
+
+NAME:
+    P_TMP_DIE_HOOK                "die_hook"
+
+DEFINIERT IN:
+    /sys/new_skills.h
+
+BESCHREIBUNG:
+     Mittels dieser Property kann der Tod eines Livings abgewendet werden.
+
+     Es wird an dem Living die Property als mindestens 3-elementiges Array
+     ({zeitpunkt, objekt, methode, ...})
+     gesetzt und die Methode 'methode' wird dann waehrend des die() des
+     Lebewesens in 'objekt' aufgerufen, solange time()<'zeitpunkt'.
+     Bei Geistern wird der Hook nicht gerufen.
+
+     Der Methode wird ein int uebergeben, ob das Living Opfer von Gift
+     (P_POISON) war.
+
+     Gibt die Funktion einen Wert != 0 zurueck, wird die() sofort abgebrochen
+     und das Living stirbt nicht.
+
+BEMERKUNGEN:
+    - Bitte das neuere Hooksystem (s. Manpage std/hooks) benutzen.
+    - falls die Zeit abgelaufen oder das Objekt zerstoert ist, wird die
+      Property auf 0 gesetzt
+    - vor dem Setzen immer auf die Existenz eines gueltigen Hooks
+      pruefen, einfaches Ueberschreiben fuehrt einerseits zu Fehlern
+      im Code anderer und ist andererseits unfair gegenueber ihnen
+
+BEISPIELE:
+     *** ein besonderer Giftschutz .. wirkt beim Tod ***
+     // pruefen, ob nicht ein anderer Modifier existiert
+     if(!pointerp(tmp=TP->QueryProp(P_TMP_DIE_HOOK)) ||
+        sizeof(tmp)<3 || tmp[0]<=time()) {
+       TP->SetProp(P_TMP_DIE_HOOK,
+	           ({time()+120+random(10), this_object(), "prevent_die"}));
+
+     // die gerufene Methode
+     int prevent_die(int poison) {
+       int ret;
+
+       if(poison) {
+         tell_object(previous_object(),
+           "Ein Zauber reinigt im Moment des Todes dein Blut!\n");
+         tell_object(environment(previous_object()),
+           previous_object()->Name(WER,1)+" wird von Lichtern umhuellt.\n",
+           ({previous_object()}));
+
+         ret=1;
+       }
+
+       // wir helfen nur einmal ... und ein Tod vernichtet die Hilfe auch
+       previous_object()->SetProp(P_TMP_DIE_HOOK, 0);
+
+       return ret;
+     }
+
+SIEHE AUCH:
+     Tod:	die(L)
+     Sonstiges: P_POISON, P_KILLS, P_GHOST
+     Hooks:	P_TMP_MOVE_HOOK, P_TMP_ATTACK_HOOK, P_TMP_DEFEND_HOOK
+     neue Hooks: std/hooks
+
+08.12.2008, Zesstra
+
diff --git a/doc/props/obsolete/P_TMP_MOVE_HOOK b/doc/props/obsolete/P_TMP_MOVE_HOOK
new file mode 100644
index 0000000..c28a067
--- /dev/null
+++ b/doc/props/obsolete/P_TMP_MOVE_HOOK
@@ -0,0 +1,42 @@
+********************* VERALTETE PROPERTY ******************************
+* Diese Property ist veraltet. Bitte nicht mehr in neuem Code nutzen. *
+***********************************************************************
+NAME:
+    P_TMP_MOVE_HOOK             "move_hook"
+
+DEFINIERT IN:
+    /sys/new_skills.h
+
+BESCHREIBUNG:
+    Mindestens 3-elementiges Array ({zeitpunkt, objekt, funktion, ...}).
+    Die Funktion wird im 'objekt' mit den gleichen Parametern wie move()
+    nach der Abfrage auf P_NO_TPORT aufgerufen, wenn der 'zeitpunkt'
+    noch nicht ueberschritten ist. Wenn die Funktion etwas anderes als ein
+    5-elementiges Array ({dest, methods, direction, textout, textin})
+    oder -1 zurueckgibt, wird move() normal ausgefuehrt, ansonsten werden die
+    5 move-Parameter durch die Array-Eintraege ersetzt bzw. wird bei einem
+    Rueckgabewert von -1 das move() abgebrochen. In letzterem Fall ist
+    die Funktion dafuer verantwortlich, eine entspr. Meldung an den
+    Spieler auszugeben!
+
+HINWEIS:
+    Falls man einem Spieler einen Move-Hook setzt, ist es ratsam, im
+    Move-Hook zu pruefen, ob das Spielerobjekt nach Abarbeitung der Hook-
+    Funktion noch lebt. Ansonsten wird ein doppeltes move() ausgefuehrt:
+    in den Todesraum und direkt wieder zurueck zur Leiche.
+
+BEMERKUNGEN:
+     - Bitte das neuere Hooksystem (s. Manpage std/hooks) benutzen.
+     - falls die Zeit abgelaufen oder das Objekt zerstoert ist, wird die
+       Property auf 0 gesetzt
+     - vor dem Setzen immer auf die Existenz eines gueltigen Hooks
+       pruefen, einfaches Ueberschreiben fuehrt einerseits zu Fehlern
+       im Code anderer und ist andererseits unfair gegenueber ihnen
+
+SIEHE AUCH:
+     Bewegung:	move(L), NotifyMove(), PreventMove()
+     Hooks:	P_TMP_DIE_HOOK, P_TMP_DEFEND_HOOK, P_TMP_ATTACK_HOOK
+     neue Hooks: std/hooks
+
+----------------------------------------------------------------------------
+08.12.2008, Zesstra
diff --git a/doc/props/skill_info_liste b/doc/props/skill_info_liste
new file mode 100644
index 0000000..011f616
--- /dev/null
+++ b/doc/props/skill_info_liste
@@ -0,0 +1,315 @@
+SI_*
+DEFINIERT IN:
+    /sys/newskills.h
+
+BESCHREIBUNG:
+    Die folgende Liste der SI-Typen ist grob nach Gueltigkeit fuer Skills
+    und Spells sortiert.
+    
+    Anwendungsorte der SI_-Werte sind:
+    - /std/living/combat und von dort gerufene Skills (Kampf)
+    - /std/gilden_ob und in Gilden lernbare Spells/Skills
+    - /std/spellbook und von Spellbooks ausgefuehrte Spells
+    - /std/living/life und von dort gerufene Skills (Alkohol)
+    - /std/shells/* und entsprechende Rassenskills
+
+    Im Skillsystem unter /std/living/skills wird vor auf Informationen
+    aus dem Teil #1 Ruecksicht genommen. Einige dieser Werte
+    werden auch permanent im Spieler gespeichert (wie zB die
+    SI_SKILLABILITY).
+
+AKTUELLE LISTE: (5. Oktober 2011)
+ #1 Skills und Spells:
+    SI_SKILLFUNC: string
+     Beinhaltet den Namen der Methode, die die eigentliche Funktionalitaet
+     des Skills/Spells implementiert.
+     Falls nicht angegeben, wird bei Spells durch UseSpell() das Verb, das
+     der Spieler eingegeben hat, als Spell-Methodenname angenommen.
+     Im Gildenobjekt kann hier abweichend von Spell-Namen stehen, wie die
+     Spellfunktion im Spellbook heisst.
+
+    SI_CLOSURE: closure
+     Optimiert den Zugriff fuer den internen Gebrauch, indem die gefundene
+     Spell/Skillfunktion darin direkt gespeichert wird und so lange gueltig
+     ist, bis das/die Objekt(e)/Closure(s) zerstoert sind.
+     Kann theoretisch auch fuer externe Skills durch (Autoload-)Objekte
+     benutzt werden.
+
+    SI_SKILLABILITY: int
+     Faehigkeit, den Spell/Skill zu benutzen. Normal ist von
+     -MAX_ABILITY bis MAX_ABILITY.
+
+    SI_SKILLDAMAGE_TYPE: string*
+     Art des Schadens eines Angriffs: siehe Schadenstypen in /sys/combat.h
+
+    SI_SKILLDAMAGE_MSG: string
+     Meldung anstatt der Waffe oder Haende-Meldung.
+    SI_SKILLDAMAGE_MSG2: string
+     Meldung anstatt der Waffe oder Haende-Meldung fuer den Raum.
+
+    SI_INHERIT: string
+     Enthaelt den Namen des Skills/Spells, von dem geerbt wird. Das
+     bedeutet einerseits, das LearnSkill() auch diesen uebergeordneten
+     Skill beeinflusst und andererseits, dass bei Skills auch dieser
+     uebergeordnete Skill im Rahmen einer Skill-Anwendung gerufen wird.
+
+    SI_DIFFICULTY: int / [Spells: mixed]
+     Schwierigkeit eines Skills/Spells. Beeinflusst die jeweils oberen
+     Schranken fuer das Lernen eines Skills/Spells in Abhaengigkeit 
+     von Spielerlevel.
+     Wenn in einem Spell-Info-Mapping kein Wert steht wird bei Spells
+     automatisch SI_SPELLCOST genommen, der Wert im Spell-Info-Mapping
+     geht beim Lernen aber immer vor Parametern.
+    FACTOR(SI_DIFFICULTY): int / mixed
+    OFFSET(SI_DIFFICULTY): int / mixed
+     Nur fuer Spellbooks/Spells. Der mixed-Parameter kann Funktionen
+     enthalten. Siehe unten bei SI_SPELLCOST.
+
+    SI_LASTLIGHT: int
+     Zeitpunkt, bis wann der Standardskills SK_NIGHTVISION den Spieler
+     sehen laesst.
+
+    SI_TESTFLAG: int
+     Wenn gesetzt, dann soll der Skill nicht genutzt, sondern nur getestet
+     werden, ob er erfolgreich waere. Entspricht also in etwa dem Aufruf
+     von SpellSuccess() in Spellbooks, wird aber bei UseSkill() als
+     Skill-Parameter uebergeben.
+     Der Skill muss entsprechend implementiert sein!
+
+    SI_GUILD: string
+     Angabe der Gilde, aus der der Skill stammt. Sinnvoll, wenn der Skill
+     nicht aus der aktuellen P_GUILD stammt. Fuer generelle Skills/Spells
+     zB waere das "ANY".
+     Gilt nicht fuer Spells!
+
+    SI_ENEMY: object
+     Aktuelles Feindesobjekt, wird bei Skill-Anwendung aus dem Kampf heraus
+     von std/living/combat.c an den Skill uebergeben.
+     Beispiel: Standardwaffenskills, SK_MAGIC_DEFENSE, SK_MAGIC_ATTACK,
+               SK_TWOHANDED, SK_SPELL_DEFEND, SK_INFORM_DEFEND und
+               SK_DEFEND_OTHER.
+
+    SI_FRIEND: object
+     Zu verteidigendes Freundesobjekt, wird bei Skill-Anwendung aus dem
+     Kampf heraus von std/living/combat.c an den Skill uebergeben.
+     Beispiele: SK_INFORM_DEFEND und SK_DEFEND_OTHER.
+
+    SI_MAGIC_TYPE: string*
+     Enthaelt ein Array der Magietypen, die zum Einsatz kommen. Die Angabe
+     geschieht zB im Spellbook und beeinflusst SpellDefend().
+
+    SI_LAST_USE: int (eventuell obsolet)
+     Letzte Nutzung des Skills.
+    
+    SI_LEARN_PROB: int (eventuell obsolet)
+     Lernwahrscheinlichkeit.
+
+    SI_SKILLDURATION: int
+     Dauer des Skills/Spells. Momentan nicht allzu verbreitet in Nutzung.
+
+ #2 nur fuer Spells:
+    SI_SPELLBOOK: string
+     Kann direkt das enthaltende Spellbook fuer einen Spell enthalten.
+
+    SM_RACE: mapping
+      Mapping, das als Key die Rasse und als Value ein Mapping X
+      enthaelt. Dieses Mapping X wird direkt zu sinfo hinzugefuegt und
+      ueberschreibt damit bei Bedarf Defaultwerte durch rassenspezifische
+      Werte.
+
+    SI_SPELLCOST: int / mixed
+    FACTOR(SI_SPELLCOST): int / mixed
+    OFFSET(SI_SPELLCOST): int / mixed
+     Beinhaltet die Werte, die fuer die Berechnung der Spellkosten
+     zustaendig sind.
+     Dabei gilt: Realkosten = OFFSET(COST) + (COST * FACTOR(COST))/100
+     Die einzelnen Eintraege koennen anstatt eines fixen Wertes auch den
+     Verweis auch eine Funktion in Form von Closure/Methodenname/Array mit
+     Objekt/Objektname und Methodenname enthalten. Siehe dazu auch
+     execute_anything().
+
+    SI_TIME_MSG: string
+     Meldung, die dem Spieler mitteilt, dass er noch nicht wieder einen
+     Spell casten kann. Falls dieser Eintrag nicht gesetzt ist, wird
+     ein Standardtext ausgegeben.
+
+    SI_SP_LOW_MSG: string
+     Meldung, die dem Spieler mitteilt, dass er zu wenige
+     Konzentrationspunkte besitzt, um den Spell zu casten. Falls dieser
+     Eintrag nicht gesetzt ist, wird ein Standardtext ausgegeben.
+
+    SI_PREPARE_MSG: string
+     Meldung, die dem Spieler ausgegeben werden soll, wenn er einen Spell
+     vorbereitet. Ansonsten wird ein Standardtext ausgegeben.
+
+    SI_PREPARE_BUSY_MSG: string
+     Meldung, die dem Spieler ausgegeben werden soll, wenn er schon diesen
+     Spell vorbereitet. Ansonsten wird ein Standardtext ausgegeben.
+
+    SI_PREPARE_ABORT_MSG: string
+     Meldung, die dem Spieler ausgegeben werden soll, wenn er die
+     Vorbereitung dieses Spells durch einen anderen Spell unterbricht.
+     Ansonsten wird ein Standardtext ausgegeben.
+
+    SI_NOMAGIC: int
+     Wert zwischen 0 und 100 (oder mehr), der gegen die P_NOMAGIC-Wirkung
+     eines Raumes wirkt.
+     Je hoeher der Wert ist, desto unwahrscheinlicher ist es, dass ein
+     Raum den Spell durch Antimagie stoert. Ein Raum sollte nur Werte
+     zwischen 0 und 100 gesetzt haben. Ist der Wert des Raums groesser
+     als der hier angegeben, dann blockiert er Magie mit einer gewissen
+     eben seiner angegebenen Wahrscheinlichkeit.
+
+    SI_NOMAGIC_MSG: string
+     Meldung, die bei Fehlschlag durch P_NOMAGIC des Raumes ausgegeben
+     wird. Ansonsten wird ein Standardtext ausgegeben.
+      
+    SI_SPELLFATIGUE: int / mixed
+    FACTOR(SI_SPELLFATIGUE): int / mixed
+    OFFSET(SI_SPELLFATIGUE): int / mixed
+     Werte, die fuer die Berechnung der Wieder-Cast-Zeit benutzt werden.
+     Die Berechnung und die moeglichen Angaben (Closure etc.) sind
+     identisch zu SI_SPELLCOST.
+     Das Spellbook gibt bei Nicht-Wieder-Bereitschaft SI_TIME_MSG aus.
+
+    SI_X_SPELLFATIGUE: mapping mit ([string key: int val])
+     Werte, die fuer die Berechnung der Wieder-Cast-Zeit benutzt werden.
+     Spellbook-Casten: Mapping wird durch Aufruf von CheckSpellFatigue(<key>)
+     am Caster gefiltert. Nur wenn das resultierende Mapping leer ist (kein
+     <key> hat einen gueltigen Fatigue-Eintrag), ist Spell castbar, sonst
+     Ausgabe von SI_TIME_MSG.
+     Nach Spellbook-Casten: Setzen der Fatigue fuer alle <val> > 0 mit <key>.
+
+    SI_SKILLLEARN: int / mixed
+    FACTOR(SI_SKILLLEARN): int / mixed
+    OFFSET(SI_SKILLLEARN): int / mixed
+     Werte, die fuer die Berechnung der Lerngeschwindigkeit benutzt
+     werden, normalerweise pro A_INT/2 je 0.01% (also 1 von MAX_ABILITY).
+     Die Berechnung und die moeglichen Angaben (Closure etc.) sind
+     identisch zu SI_SPELLCOST.
+
+    SI_LEARN_ATTRIBUTE: mapping
+     Mapping, welches die Attribute, nach denen gelernt werden soll
+     als Keys enthaelt. Der Value legt die Gewichtung fest, denn bei
+     mehreren Attributen wird ein Mittelwert gebildet.
+     Der Normalfall entspraeche ([A_INT: 1]) fuer SI_LEARN_ATTRIBUTE.
+
+    SI_NO_LEARN
+     Wenn man (temporaer!) nicht will, dass dieser Skill gelernt wird.
+     Muss von den Spellbooks beachtet werden.
+     Sollte niemals im Spieler abgespeichert werden. Oder permanent in
+     Gilde/Spellbook gesetzt sein. Sondern im Laufe einesr Nutzung in der
+     jew. Kopie von sinfo gesetzt werden, die gerade genutzt wird.
+    
+     SI_SKILLARG: string
+     Beinhaltet den Text, den der Spieler nach dem Spellkommando eingegeben
+     hat. Z.B. stuende bei "krallenschlag ork 2" der Text "ork 2" im
+     Parameter.
+
+    SI_SKILLRESTR_USE: mixed
+     Einschraenkungen fuer das Nutzen des Spells.
+     Wird normalerweise direkt im Spellbook fuer den Spell eingetragen.
+     Die einzelnen Moeglichkeiten werden in der manpage zu
+     "check_restrictions" erlaeutert.
+     
+    SI_SKILLRESTR_LEARN: mixed
+     Einschraenkungen fuer das Lernen des Spells.
+     Wird normalerweise direkt im Gildenobjekt fuer den Spell
+     eingetragen.
+     Die einzelnen Moeglichkeiten werden in der manpage zu
+     "check_restrictions" erlaeutert.
+
+    SI_SKILLINFO: string
+    SI_SKILLINFO_LONG: string
+     Beschreibung des Spells. Wird im Gildenobjekt eingetragen und
+     SI_SKILLINFO wird von SkillListe angezeigt.
+
+    SI_SKILLDAMAGE: int / mixed
+    FACTOR(SI_SKILLDAMAGE): int / mixed
+    OFFSET(SI_SKILLDAMAGE): int / mixed
+     Werte, die fuer die Schadenshoehenberechnung des Spells benutzt
+     werden (random ueber den Gesamtwert normalerweise).
+     Die Berechnung und die moeglichen Angaben (Closure etc.) sind
+     identisch zu SI_SPELLCOST.
+
+    SI_SKILLDAMAGE_BY_ROW
+     Ein Mapping mit Boni fuer den Angriff aus bestimmten Kampfreihen.
+     Funktioniert nur bei Verwendung von TryDefaultAttackSpell-Spells
+     aus dem Spellbook.
+     Der Key steht fuer eine bestimmte Reihe, sein Wert fuer den
+     randomisierten Bonus fuer Lebewesen, die aus dieser Reihe casten.
+    OFFSET(SI_SKILLDAMAGE_BY_ROW)
+     Ein Mapping mit fixem Wert fuer Row-Boni im Kampf.
+
+     Beispiel: AddSpell("feuerball", 20,
+                        ([SI_SKILLDAMAGE:50,
+                          OFFSET(SI_SKILLDAMAGE):100,
+                          SI_SKILLDAMAGE_BY_ROW:([2:40,3:20}),
+                          OFFSET(SI_SKILLDAMAGE_BY_ROW):([2:20]), ...
+     gibt
+      Reihe 1: random(50)+100;
+      Reihe 2: random(50)+100+random(40)+20
+      Reihe 3: random(50)+100+random(20)
+     ACHTUNG: Hier gilt nicht die selbe Struktur wie bei SI_SPELLCOST!
+
+    SI_SPELL: mapping
+     Dieser Eintrag enthaelt verschiedene Unterwerte, die den Spell
+     gerade fuer Angriffs-Spells genauer beschreiben. Siehe Defend()
+     fuer eine Beschreibung der verschiedenen Eintraege (die so auch
+     in das Spellbook uebernommen werden koennen).
+
+    SI_COLLATERAL_DAMAGE: int
+     Hiermit kann man einen Prozentwert von SI_SKILLDAMAGE (inklusive
+     Offsets und Factor) fuer Kollateralschaden an Freunden im definierten
+     Bereich eines Flaechenspells (TryGlobalAttackSpell()) angeben.
+     10 bedeutet bei OFFSET(SI_SKILLDAMAGE)=100 zB 10% von 100 = 10 = 1 LP
+     an mit reduce_hit_points() verursachtem Schaden.
+    
+    SI_NUMBER_ENEMIES, SI_NUMBER_FRIENDS: int
+     Wird von TryGlobalAttackSpell() im Spell gesetzt und enthaelt die
+     Anzahl der im angegebenen Bereich befindlichen Feinde und Freunde.
+     Ist dementsprechend von informativem Nutzen fuer den Angegriffenen
+     und das Spellbook NACH Aufruf von TryGlobalAttackSpell().
+    
+    SI_DISTANCE, SI_WIDTH, SI_DEPTH: int
+     Limitiert die Entfernung, Tiefen und Breite der Wirkung eines
+     TryGlobalAttackSpell()
+
+    SI_SKILLHEAL: int
+     Konvention fuer Spells im Spellbook, dort den Heilwert zu hinterlegen,
+     hat keine Auswirkungen unter /std/.
+
+    SI_USR: mixed
+     Fuer selbst definierte Infos, spellbookabhaengig.
+
+    SI_PREPARE_TIME: int
+     Dauer der Zeit fuer zu praeparierende Spells.
+
+    SI_ATTACK_BUSY_MSG: string
+     Meldung, die dem Spieler mitteilt, dass er schon zu beschaeftigt
+     mit einem Angriff ist, um einen Spell zu casten. Falls dieser
+     Eintrag nicht gesetzt ist, wird  ein Standardtext ausgegeben.
+
+    SI_NO_ATTACK_BUSY: int
+     Enthaelt als Flag NO_ATTACK_BUSY_QUERY wenn der Spell NICHT wie
+     eine Spezialwaffe die Aktionen einschraenkt. Siehe P_ATTACK_BUSY.
+
+    SI_ATTACK_BUSY_AMOUNT: int
+     Menge des P_ATTACK_BUSY fuer diesen Spell. Falls dieser Wert nicht
+     gesetzt ist, aber auch SI_NO_ATTACK_BUSY nicht mit
+     NO_ATTACK_BUSY_QUERY ausgezeichnet ist wird 1 angenommen.
+
+SIEHE AUCH:
+    Skills Lernen:  LearnSkill, ModifySkill, LimitAbility
+    * Nutzung:      UseSpell, UseSkill
+    * Abfragen:     QuerySkill, QuerySkillAbility
+    * Modifikation: ModifySkillAttribute, QuerySkillAttribute,
+                    QuerySkillAttributeModifier, RemoveSkillAttributeModifier
+      * Properties: P_SKILL_ATTRIBUTES, P_SKILL_ATTRIBUTE_OFFSETS
+    * sonstig:      spruchermuedung
+    * Properties:   P_NEWSKILLS
+    Spellbook:      UseSpell, Learn, SpellSuccess
+    Gilden:         gilden-doku
+    Kampf:          Defend
+
+7. Nov 2012 Gloinson
diff --git a/doc/props/svn-commit.tmp b/doc/props/svn-commit.tmp
new file mode 100644
index 0000000..24ffe76
--- /dev/null
+++ b/doc/props/svn-commit.tmp
@@ -0,0 +1,6 @@
+
+--This line, and those below, will be ignored--
+
+M    P_FUEL
+M    P_LIGHTDESC
+M    P_DO_DESTRUCT
diff --git a/doc/scmd/.readme b/doc/scmd/.readme
new file mode 100644
index 0000000..b4d69ca
--- /dev/null
+++ b/doc/scmd/.readme
@@ -0,0 +1,6 @@
+Hier befinden sich die Hilfeseiten, die fuer Seher interessant sind:
+
+ * Beschreibung der neuen Befehle
+ * allgemeine Informationen zum Bau eines Seherhauses
+ * Beschreibung der Befehle, die die Seherhaeuser zur Verfuegung stellen
+
diff --git a/doc/scmd/.synonym b/doc/scmd/.synonym
new file mode 100644
index 0000000..256e3b7
--- /dev/null
+++ b/doc/scmd/.synonym
@@ -0,0 +1,3 @@
+r: remote
+r; remote
+
diff --git a/doc/scmd/aendere b/doc/scmd/aendere
new file mode 100644
index 0000000..e2447ef
--- /dev/null
+++ b/doc/scmd/aendere
@@ -0,0 +1,52 @@
+
+aendere
+-------
+
+ SEHERHAUSKOMMANDO:
+    aendere <haus> lang
+    aendere detail <det>
+    aendere lesbares detail <det>
+    aendere befehl <bef>
+    aendere <truhe>
+    aendere meldungen
+
+ ARGUMENTE:
+
+     <haus>
+        eine gueltige Bezeichnung des Hauses. Gueltige Bezeichnungen sind
+        innerhalb des Hauses "haus" und "raum", ausserhalb des Hauses die
+        Begriffe, mit denen sich das Haus ansprechen laesst.
+     <det>
+        Name des zu aendernden (lesbaren) Details. Es kann immer nur ein
+        (lesbares) Detail gleichzeitig geaendert werden!
+     <bef>
+        Name des zu aendernden Befehls (Verb + Parameter)
+     <truhe>
+        eine gueltige Bezeichnung der Truhe.
+
+ BESCHREIBUNG:
+    Mit diesem Befehl ist es moeglich, schon vorhandene Beschreibungen zu
+    aendern. Dies ist zum Beispiel noetig, wenn man (oder ein Spieler) einen
+    Tippfehler gefunden hat, oder wenn man eine Beschreibung noch ein wenig
+    erweitern moechte.
+
+    Bei zu aendernden (lesbaren) Details und Befehlen werden alle mehrfach
+    auftretenden Texte gleichzeitig geaendert (d.h. wenn man die Details
+    "wand" und "waende" mit den gleichen Beschreibungen versehen hat, wird bei
+    aendere detail wand auch der Text von "waende" geaendert).
+
+    Geaendert werden koennen die Langbeschreibungen des Hauses (innen und
+    aussen), die Langbeschreibung der Truhe, Details, lesbare Details, Befehle
+    sowie die Liste der Rueckmeldungen von Spielern (also typo, fehler und
+    idee). Das ist recht nuetzlich, damit man die Meldungen, die man schon
+    abgearbeitet hat, wieder los wird.
+
+    Der zu aendernde Text wird in den Editor geladen und kann wie gewohnt
+    bearbeitet werden. Der Cursor befindet sich dabei zu Beginn ganz am Ende
+    des Textes.
+
+ SIEHE AUCH:
+    beschreibe, befehl, loesche, kopiere, meldungen, uebersicht, notiz
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/ausgang b/doc/scmd/ausgang
new file mode 100644
index 0000000..2b950d6
--- /dev/null
+++ b/doc/scmd/ausgang
@@ -0,0 +1,53 @@
+
+ausgang
+-------
+
+ SEHERHAUSKOMMANDO:
+    ausgang <richtung> <nr>
+    ausgang <richtung> <name> <nr>
+
+ ARGUMENTE:
+
+     <richtung>
+        Richtung des gewuenschten Ausgangs. Es sind nur die acht
+        Himmelsrichtungen sowie "oben" und "unten" erlaubt. Die Richtung muss
+        ausgeschrieben werden, d.h. es muss heissen ausgang suedwesten 2 statt
+        ausgang sw 2!
+     <nr>
+        Nummer des Zielraumes, zu dem der Ausgang gehen soll.
+     <name>
+        Name des Sehers, zu dessen Haus der Ausgang fuehren soll. Dies ist
+        nicht ohne weiteres moeglich, s.u.!
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kann man dem Raum, in dem man gerade steht, einen
+    weiteren Ausgang hinzufuegen. Im Zielraum entsteht dabei automatisch ein
+    Ausgang in die Rueckrichtung.
+
+    Es sind folgende Regeln zu beachten:
+
+     * es darf in diesem Raum noch keinen Ausgang in die Zielrichtung geben!
+     * es darf im Zielraum noch keinen Ausgang in die Rueckrichtung geben (die
+       Rueckrichtung erhaelt man, wenn man in der Hinrichtung "osten" und
+       "westen", "norden" und "sueden" sowie "oben" und "unten" jeweils
+       gegeneinander austauscht)!
+     * wenn der Ausgang ins eigene Haus geht, darf <nr> nicht die Nummer des
+       Raumes sein, in dem man gerade steht!
+     * es muss in dem Haus natuerlich schon ein Raum mit der Nummer <nr>
+       existieren!
+
+    Will man sein Haus mit einem anderen Haus verbinden, so ist zusaetzlich
+    folgendes zu beachten:
+
+     * das Zielhaus muss sich im gleichen Raum befinden wie das eigene Haus!
+     * der Besitzer des Zielhauses hat Dir mit erlaube den Zugriff auf sein
+       Haus gewaehrt!
+
+    Die Nummer des Raumes, in dem Du stehst, wird bei dem Kommando uebersicht
+    mit ausgegeben (wenn Du ueber mehr als einen Raum verfuegst).
+
+ SIEHE AUCH:
+    sperre, uebersicht
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/befehl b/doc/scmd/befehl
new file mode 100644
index 0000000..4f99b3c
--- /dev/null
+++ b/doc/scmd/befehl
@@ -0,0 +1,207 @@
+
+befehl
+------
+
+ SEHERHAUSKOMMANDO:
+    beschreibe befehl <bef>
+
+ ARGUMENTE:
+
+     <bef>
+        Liste der zu beschreibenden Befehle. Bei mehreren Befehlen muessen
+        diese durch Kommata voneinander getrennt sein. Es duerfen nur Verben
+        angegeben werden, ohne Parameter!
+
+ BESCHREIBUNG:
+    Beginnt mit der Beschreibung des Befehles <bef> (oder mehrere, falls es
+    sich bei <bef> um eine Liste von Verben handelt).
+
+    Die Standard-Hauskommandos (beschreibe, loesche, etc.) duerfen NICHT
+    beschrieben werden! Einzige Ausnahmen: "oeffne", "schliesse" und
+    "schliess".
+
+    Ausgangsbefehle (Himmelsrichtungen, "oben", "unten" und "raus") koennen
+    beschrieben werden; aber nur dann, wenn es auch einen entsprechenden
+    Ausgang gibt. Sperrt man hinterher einen Ausgang, zu dem es einen Befehl
+    gibt, so wird der Befehl wieder geloescht!
+
+    Anschliessend wird man nach den Parametern fuer den Befehl gefragt. Auch
+    hier koennen mehrere Parameter durch Kommata voneinander getrennt werden;
+    ausserdem kann man hier mehrere Woerter benutzen (siehe dazu auch das
+    Beispiel unten). Man kann allerdings auch ganz auf Parameter verzichten
+    und einfach <RETURN> druecken.
+
+    Schliesslich wird man nach dem Text gefragt, der als Reaktion auf den
+    Befehl ausgegeben werden soll. Dazu steht wieder der Editor zur
+    Verfuegung. Man gibt in einem Rutsch sowohl den Text fuer denjenigen ein,
+    der den Befehl ausfuehrt, als auch den Text fuer die Leute, die sich im
+    gleichen Raum befinden. Die Texte werden durch eine Zeile mit einem @@
+    voneinander getrennt.
+
+    In den Texten sind verschiedene Platzhalter moeglich, um in den einzelnen
+    Befehlen differenziertere Aktionen zuzulassen:
+
+     * Der Name des/der Ausfuehrenden laesst sich mit @WER, @WESSEN, @WEM und
+       @WEN einbauen (jeweils im entsprechenden Fall).
+     * Personalpronomina sind mit @PWER, ... moeglich. Es ist dabei jedoch zu
+       beachten, dass sie *kleingeschrieben* eingefuegt werden! Man sollte sie
+       also nicht unbedingt am Satzanfang benutzen.
+     * Possessivpronomina: Das ist etwas komplizierter, denn hier muessen noch
+       Geschlecht und Anzahl des Objektes angegeben werden, auf das sich das
+       Possessivpronomen bezieht. Der Aufbau des Platzhalters:
+       @B, gefolgt von M, F oder N fuer das Geschlecht des Bezugsobjektes
+       (Maskulinum, Femininum oder Neutrum), S oder P fuer die Anzahl
+       (Singular oder Plural) und schliesslich WER, WESSEN, WEM oder WEN fuer
+       den Fall des Pronomens an sich.
+       Das fuehrt dann zu Konstruktionen wie @BMSWER oder @BFPWEN. Am besten,
+       man probiert es einfach mal aus (siehe aber auch die Beispiele).
+       Auch hier gilt uebrigens wieder: Die Pronomina werden kleingeschrieben
+       eingefuegt!
+
+    Weitere Moeglichkeiten sind rassen-, namens- und geschlechtsspezifische
+    Ausgaben.
+ 
+    Als Trenner dienen @G fuer geschlechtsspezifische Ausgaben und @RE (fuer
+    Elfen), @RH (fuer Hobbits), @RM (fuer Menschen), @RZ (fuer Zwerge), 
+    @RF (fuer Felinen), @RD (fuer Dunkelelfen) sowie @RG (fuer Goblins) fuer 
+    rassenspezifische Ausgaben.
+
+    Als spezielle "Rasse" gibt es darueberhinaus noch @RA fuer Ausgaben, die
+    nur die Spieler gehen, die im Haus besondere Rechte haben (siehe erlaube).
+
+    Darueberhinaus kann man Ausgaben fuer bestimmte Spieler vorsehen. Der
+    Trenner hierfuer ist @NAME:spieler, wobei 'spieler' fuer den Namen des
+    entsprechenden Spielers steht.
+
+    Aehnlich wie bei der Trennung zwischen dem Text fuer den Ausfuehrenden und
+    dem Text fuer die Umstehenden muessen die Trenner in einer Extrazeile
+    stehen.
+
+    Bei @G wird der Text ueber dem Trenner bei maennlichen und der Text unter
+    dem Trenner bei weiblichen Befehlsausfuehrern ausgegeben.
+
+    Bei den Rassen- und Namenstrennern wird der Text unterhalb des Trenners
+    ausgegeben, der der Rasse bzw. dem Namen des Ausfuehrenden entspricht.
+
+    Wenn fuer eine Rasse kein eigener Text angegeben ist, wird der Text vor
+    dem ersten Rassen- bzw. Namenstrenner ausgegeben (und wenn gar kein
+    Rassentrenner angegeben wurde, wird der Text fuer alle Rassen
+    ausgegeben ;)
+
+    Innerhalb der rassenspezifischen Texte kann wieder mit @G
+    geschlechtsspezifisch unterschieden werden.
+
+    Um eine etwas andere Meldung als "Wie bitte?" zu bekommen, wenn ein Befehl
+    mit einem ungueltigen Parameter eingegeben wurde, kann man den speziellen
+    Parameter @nf@ angeben. In den Text kann der ungueltige Parameter mit dem
+    Platzhalter @PARA integriert werden.
+
+    Wenn die Umstehenden keine Meldung bekommen sollen, kann man den @@ und
+    den zweiten Text einfach weglassen.
+
+ BEISPIELE:
+    Zunaechst ein ganz einfacher Text:
+
+      beschreibe befehl drueck, druecke
+      => Bitte Parameter eingeben.
+      ]knopf, auf knopf
+      => Bitte Text eingeben, der fuer diesen Befehl ausgegeben werden soll.
+      ]Du drueckst auf den Knopf, aber nichts passiert.
+      ].
+
+    (Wenn jemand nun "druecke knopf" eingibt, erhaelt er die Meldung "Du
+    drueckst auf den Knopf, aber nichts passiert." Andere Spieler, die sich im
+    gleichen Raum aufhalten, bekommen keine Meldung)
+
+    Jetzt ein Befehl mit Ausgabe an die Umstehenden:
+
+      beschreibe befehl zieh, ziehe
+      => Bitte Parameter eingeben.
+      ]faden, an faden
+      => Bitte Text eingeben, der fuer diesen Befehl ausgegeben werden soll.
+      ]Du ziehst an dem Faden. Es gibt einen lauten Knall, und Du siehst nur
+      ]noch wirbelnde Punkte.
+      ]@@
+      ]Es gibt einen lauten Knall, und die Konfettikanone huellt @WEN in
+      ]eine wirbelnde Konfettiwolke.
+      ].
+
+    (Wenn Wargon an dem Faden zieht, bekommt er die obere Meldung, und die
+    Umstehenden bekommen "Es gibt einen lauten Knall, und die Konfettikanone
+    huellt Wargon in eine wirbelnde Konfettiwolke.")
+
+    Hier jetzt ein Beispiel mit Geschlechtertrennung:
+
+      beschreibe befehl schau
+      => Bitte Parameter eingeben.
+      ]in spiegel
+      => Bitte Text eingeben...
+      ]Hm, Du muesstest Dich mal wieder rasieren.
+      ]@G
+      ]Dein MakeUp ist ziemlich verschmiert.
+      ].
+
+    (Schaut ein Spieler in den Spiegel, wird er auf seine Rasur hingewiesen;
+    eine Spielerin dagegen auf ihr MakeUp.)
+
+    Etwas komplexer: Rassentrenner und Possessivpronomen:
+
+      beschreibe befehl schau
+      => Bitte Parameter eingeben.
+      ]auf tisch
+      => Bitte Text eingeben...
+      ]Du siehst einen Haufen Papiere auf dem Tisch liegen.
+      ]@RZ
+      ]Der Tisch ist zu hoch fuer Dich.
+      ]@@
+      ]@WER untersucht den Tisch.
+      ]@RZ
+      ]@WER versucht verzweifelt, einen Blick auf den Tisch zu werfen,
+      ]aber @BMSWER kleiner Koerperbau laesst das nicht zu.
+      ].
+
+    (Keine Chance fuer Zwerge! ;) @BMSWER wird bei maennlichen Zwergen durch
+    "sein" und bei weiblichen Zwergen durch "ihr" ersetzt.)
+
+    Das gleiche Beispiel wie gerade, diesmal jedoch zusaetzlich mit speziellen
+    Texten fuer Wargon und Saphis:
+
+      beschreibe befehl schau
+      => Bitte Parameter eingeben.
+      ]auf tisch
+      => Bitte Text eingeben...
+      ]Du siehst einen Haufen Papiere auf dem Tisch liegen.
+      ]@NAME:Wargon
+      ]Ein Haufen Papier. Schaff doch mal wieder Ordnung!
+      ]@NAME:Saphis
+      ]Ein Haufen Papier. Sag Deinem Chef mal, er soll hier wieder Ordnung
+      ]schaffen!
+      ]@RZ
+      ]Der Tisch ist zu hoch fuer Dich.
+      ]@@
+      ]@WER untersucht den Tisch.
+      ]@NAME:Wargon
+      ]Wargon untersucht den Tisch und seufzt.
+      ]@RZ
+      ]@WER versucht verzweifelt, einen Blick auf den Tisch zu werfen,
+      ]aber @BMSWER kleiner Koerperbau laesst das nicht zu.
+      ].
+
+    Und zum Schluss ein Beispiel fuer ein geaendertes "Wie bitte?"
+
+      beschreibe befehl drueck,druecke
+      => Bitte Parameter eingeben.
+      ]@nf@
+      => Bitte Text eingeben...
+      ]Wieso willst Du denn @PARA druecken?
+      ].
+
+    (Wenn man jetzt zB. "druecke hand" eingibt, und dieser Befehl noch nicht
+    beschrieben wurde, kommt als Meldung: "Wieso willst Du denn Hand
+    druecken?")
+
+ SIEHE AUCH:
+    aendere, beschreibe
+
+ LETZTE AeNDERUNG:
+    Sun, 03.12.2000, 18:30:00 von Wargon
diff --git a/doc/scmd/beschreibe b/doc/scmd/beschreibe
new file mode 100644
index 0000000..12cd000
--- /dev/null
+++ b/doc/scmd/beschreibe
@@ -0,0 +1,195 @@
+
+beschreibe
+----------
+
+ SEHERHAUSKOMMANDO:
+    beschreibe <haus> lang
+    beschreibe <haus> kurz
+    beschreibe detail <det>
+    beschreibe lesbares detail <det>
+    beschreibe befehl <bef> - Siehe befehl!
+    beschreibe haustuer
+    beschreibe tuerzustand
+    beschreibe truhe
+
+ ARGUMENTE:
+
+     <haus>
+        eine gueltige Bezeichnung des Hauses. Gueltige Bezeichnungen sind
+        innerhalb des Hauses "haus" und "raum", ausserhalb des Hauses die
+        Begriffe, mit denen sich das Haus ansprechen laesst.
+     <det>
+        Liste der zu beschreibenden (lesbaren) Details. Bei mehreren Details
+        muessen diese durch Kommata voneinander getrennt sein!
+
+ BESCHREIBUNG:
+    Dieses Kommando dient zur allgemeinen Beschreibung des Hauses. Von den
+    moeglichen Anwendungen ist beschreibe haustuer nur draussen erlaubt.
+    beschreibe <haus> lang ist sowohl innen als auch aussen benutzbar; alle
+    anderen Anwendungen gelten nur innerhalb des Hauses.
+
+    Nach Eingabe des Kommandos befindet man sich bei den meisten Arten in dem
+    selben Editor, wie man ihn auch von der Post oder der Zeitung gewohnt ist.
+    Man hat also auch hier die Moeglichkeit, sich mit "~h" eine Hilfeseite des
+    Editors mit allen moeglichen Kommandos anzeigen zu lassen.
+
+    Falls es vorkommen sollte, dass waehrend der Beschreibung die Verbindung
+    zum MUD zusammenbricht, sperrt der Editor! In diesem Fall kann man mit
+    "~r" die unterbrochene Beschreibung wieder aufnehmen. (Das ~r muss als
+    Befehl im Haus angegeben werden!)
+
+    Hier nun die Moeglichkeiten zur Beschreibung:
+
+     beschreibe <haus> lang
+        Hiermit wird die Langbeschreibung des Hauses begonnen. Es gibt zwei
+        Faelle: Befindet man sich innerhalb des Hauses, so gibt man jetzt den
+        Text ein, den man beim Betreten des Hauses (bei eingeschaltetem
+        Lang-Modus) und bei einem schau im Haus bekommt. Befindet man sich
+        ausserhalb des Hauses, so gibt man jetzt den Text ein, den man beim
+        Untersuchen des Hauses bekommt. An den Text fuer die
+        Aussenbeschreibung wird immer eine Zeile mit dem aktuellen Zustand der
+        Haustuer angehaengt.
+
+     beschreibe <haus> kurz
+        Beginnt die Eingabe der Kurzbeschreibung des Hauses. Dies ist der
+        Text, den man mit eingeschaltetem Kurz-Modus beim Betreten des Hauses
+        bekommt.
+
+        Die Kurzbeschreibung kann nur im Inneren des Hauses geaendert werden.
+        Sie darf nicht laenger sein als eine Zeile!
+
+        Wenn Dein Haus auch von aussen anders aussehen soll, wende Dich bitte
+        an Wargon.
+
+     beschreibe detail <det>
+        Beginnt die Beschreibung des Details <det>. Als Details sollten
+        moeglichst alle Substantive beschrieben werden, die in der
+        Langbeschreibung des Hausinneren und in den anderen Details vorkommen
+        (natuerlich nur, soweit das sinnvoll ist). Den Text der Details
+        bekommt man bei dem Kommando "untersuche <det>" ausgegeben.
+
+     beschreibe lesbares detail <det>
+        Beginnt die Beschreibung eines lesbaren Details. Der Text wird bei dem
+        Kommando "lies <det>" ausgegeben.
+
+     beschreibe befehl <bef>
+        Da dies mittlerweile recht komplex geworden ist, gibt es eine
+        Extrahilfeseite. Du erreichst sie mit "hilfe befehl".
+
+     beschreibe haustuer
+        Erlaubt die Beschreibung der Haustuer. Hier ist nur eine Zeile
+        erlaubt. Diese Zeile wird an die Langbeschreibung des Hauses von
+        aussen angehaengt. Wenn dort keine Haustuer erscheinen soll (was zB.
+        bei einem See oder einer Hoehle wenig Sinn macht), kann man hier mit
+        einem Leerstring (direkt <RETURN> druecken) die Tuer unsichtbar
+        machen.
+
+        Mit dem Platzhalter %s wird der aktuelle Zustand der Haustuer in die
+        Beschreibung eingebaut (in der Form "geoeffnet", "geschlossen" oder
+        "abgeschlossen").
+
+     beschreibe tuerzustand
+        Auch den Zustand der Haustuer (geoeffnet, geschlossen, abgeschlossen)
+        kann man in eigene Worte fassen.
+
+        Die Zustaende muessen in der oben angegebenen Reihenfolge eingegeben
+        werden, und zwar in EINER Zeile, durch Kommata getrennt!
+        Es muessen immer ALLE drei Zustaende angegeben werden!
+        Man sollte nach Moeglichkeit nur ein Wort pro Zustand verwenden!
+
+     beschreibe truhe
+        Beginnt die Beschreibung der Truhe. Im Gegensatz zu den anderen
+        Beschreibungen erfolgt die Beschreibung der Truhe in mehreren
+        Schritten. Will man die jeweiligen Vorgaben nicht aendern, so genuegt
+        es, <RETURN> zu druecken.
+
+        Zuerst wird man nach dem Geschlecht der Truhe gefragt. Hier muss man
+        den passenden Buchstaben angeben (m fuer maennlich, w fuer weiblich
+        oder s fuer saechlich).
+
+        Nun wirst Du nach dem Namen gefragt, der zum Beispiel beim Oeffnen
+        oder Schliessen der Truhe ausgegeben wird. Falls der Name
+        unregelmaessig dekliniert wird, muessen alle vier Faelle in der
+        Reihenfolge Nominativ, Genitiv, Dativ, Akkusativ, durch Kommata
+        getrennt, eingegeben werden.
+
+        Schliesslich kannst Du noch Adjektive angeben, die zusammen mit dem
+        Namen ausgegeben werden.
+
+        Aus den bisher eingegebenen Daten wird nun die Kurzbeschreibung der
+        Truhe erstellt. Entspricht sie nicht Deinen Vorstellungen, gelangst Du
+        wieder in die Geschlechtsabfrage.
+
+        Ansonsten wird nun nach den IDs gefragt, mit denen sich die Truhe
+        ansprechen lassen soll. Mehrere IDs muessen mit Kommata voneinander
+        getrennt werden. Es koennen auch IDs verwendet werden, die aus
+        mehreren Wortern bestehen. Die Vorgaben koennen wieder mit <RETURN>
+        uebernommen werden.
+        Da einige Spezialisten es immer wieder schafften, hier schon die
+        Langbeschreibung einzugeben (und somit hinterher die Truhe nicht mehr
+        ansprechen konnten), laesst sich die Truhe fuer den
+        `beschreibe'-Befehl immer als `truhe' ansprechen. Zum Ansehen, Oeffnen
+        etc. muss man allerdings die hier angegebenen IDs verwenden.
+
+        Nun erfolgt die Langbeschreibung der Truhe. Bei dieser steht wieder
+        der Editor zur Verfuegung. Bei Abbruch oder einem Leerstring wird die
+        alte Langbeschreibung nicht geaendert.
+
+        Zum guten Schluss kann man auch noch das Material der Truhe aendern.
+        Im Hauptmenue kann man eine Materialgruppe waehlen, und dort dann das
+        gewuenschte Material.
+
+        Die Beschreibung der Truhe kann natuerlich nur geaendert werden, wenn
+        man im gleichen Raum steht wie die Truhe. ;-)
+
+ BEISPIELE:
+    Ein lesbares Detail wird beschrieben:
+
+      beschreibe lesbares detail zettel, notiz
+      => Bitte Beschreibung fuer 'zettel, notiz' eingeben.
+      ]Bin gerade metzeln. Blutsaugerschwerter bitte an der Pforte
+      ]abgeben.
+      ].
+
+    Die Truhe soll in eine kleine Kiste aus Holz umgewandelt werden:
+
+      beschreibe truhe
+      => Beschreibung der Truhe
+      => Wenn die Vorgaben nicht geaendert werden sollen, einfach weiter
+      => mit <RETURN>.
+
+      =>Geschlecht (m, w, s): [w]
+      ]w
+      => Das Geschlecht ist jetzt weiblich.
+      => Nun musst Du den Namen eingeben. ...
+      => Name: [Truhe]
+      ]Kiste, Kiste, Kiste, Kiste
+      => Der Name ist jetzt 'Kiste, Kiste, Kiste, Kiste'
+      => Du kannst jetzt noch Namensadjektive angeben. ...
+      => Namensadjektive: []
+      ]klein
+      => Namensadjektive lauten klein.
+      => Die Kurzbeschreibung lautet damit:
+      => Eine kleine Kiste (geschlossen).
+      => Falls das Ergebnis nicht Deinen ...
+      => Stimmt die Kurzbeschreibung so? (j/n)
+      ]j
+
+      =>IDs (durch Kommata getrennt):
+      =>[truhe,holztruhe]
+      ]kiste
+      => OK, IDs lauten 'kiste'
+
+      => Bitte Langbeschreibung angeben...
+      ]In dieser Kiste lagert Wargon wichtige Dinge.
+      ].
+
+      => Bitte das Material der Kiste betimmen:
+      ...
+
+ SIEHE AUCH:
+    editor,
+    aendere, befehl, loesche, kopiere, meldungen, uebersicht, notiz, licht
+
+ LETZTE AeNDERUNG:
+    Thu, 25.09.1997, 17:40:30 von Wargon
diff --git a/doc/scmd/echo b/doc/scmd/echo
new file mode 100644
index 0000000..22b6294
--- /dev/null
+++ b/doc/scmd/echo
@@ -0,0 +1,34 @@
+
+echo
+----
+
+ SEHERKOMMANDO:
+    echo <text>
+
+ ARGUMENTE:
+
+     <text>
+        ein beliebiger Text
+
+ BESCHREIBUNG:
+    Der Text <text> wird an alle Spieler im selben Raum gesendet.
+
+    Bei Sehern verbraucht dieses Kommando 50 Magiepunkte. Fuer Magier ist es
+    kostenlos.
+
+    ACHTUNG: Die Benutzung dieses Befehls wird geloggt! D.h. dass er nicht
+    zur Benutzung geeignet ist, wenn man nicht moechte, dass der gesendete
+    Text von Magiern nachgelesen werden kann. Dies ist aufgrund von Missbrauch
+    leider notwendig. In diesem Zusammenhang sei auch nochmal darauf 
+    hingewiesen, dass Echos in fremdem Namen nicht erlaubt sind und mit
+    dem Entzug der echo-Faehigkeit (plus (r)emote als Bonus) geahndet
+    werden koennen.
+
+BEMERKUNGEN:
+    Die Faehigkeit wird erst nach der Loesung des Quest "Hilf dem
+    Architekten." freigeschaltet.
+
+ SIEHE AUCH:
+    sag, emote
+
+1. Maerz 2013 Gloinson
diff --git a/doc/scmd/erlaube b/doc/scmd/erlaube
new file mode 100644
index 0000000..1e2916a
--- /dev/null
+++ b/doc/scmd/erlaube
@@ -0,0 +1,31 @@
+
+erlaube
+-------
+
+ SEHERHAUSKOMMANDO:
+    erlaube <name>
+
+ ARGUMENTE:
+
+     <name>
+        Ein oder mehrere Namen (durch Kommata getrennt).
+
+ BESCHREIBUNG:
+    Der Spieler <name> erhaelt die Erlaubnis, Dein Haus auf- und abschliessen
+    zu duerfen. Weiterhin darf dieser Spieler auch die Truhe in Deinem Haus
+    oeffnen.
+
+    Auch wenn ein Nachbar sein Haus mit Deinem verbinden will, muss ihm das
+    mit diesem Kommando erlaubt werden.
+
+    Dieser Befehl funktioniert nur im Eingangsraum des Hauses, und die Liste
+    der Leute mit erteilter Erlaubnis wird auch nur im Eingangsraum bei dem
+    Befehl uebersicht mit ausgegeben; die Liste gilt bei Ausgaengen jedoch
+    fuer das gesamte Haus (man kann also nicht selektiv Raeume zur Verbindung
+    freigeben).
+
+ SIEHE AUCH:
+    verbiete, uebersicht, ausgang
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/extralook b/doc/scmd/extralook
new file mode 100644
index 0000000..260f8ec
--- /dev/null
+++ b/doc/scmd/extralook
@@ -0,0 +1,29 @@
+
+extralook
+---------
+
+ SEHERKOMMANDO:
+    extralook <text>
+
+ ARGUMENTE:
+
+     <text>
+        Die Beschreibung.
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kannst Du Deine Beschreibung um zusaetzlichen Text
+    erweitern.
+
+    Der Text erscheint nach Deiner normalen Langbeschreibung und vor der
+    Auflistung Deines Inventars.
+
+    Gibst Du als <text> nur ein '?' an, wird Dir ein aktueller Extralook
+    ausgegeben.
+    Laesst Du <text> ganz weg, oeffnet sich ein Editor, in dem Du Deinen neuen
+    Extralook eingeben kannst.
+
+ SIEHE AUCH:
+    untersuche
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/fehlermeldung b/doc/scmd/fehlermeldung
new file mode 100644
index 0000000..6785e0e
--- /dev/null
+++ b/doc/scmd/fehlermeldung
@@ -0,0 +1,20 @@
+
+fehlermeldung
+-------------
+
+ SEHERKOMMANDO:
+    fehlermeldung [<text>]
+
+ ARGUMENTE:
+
+     <text>
+        Text der neuen Fehlermeldung (optional)
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kannst Du Dir eine neue Fehlermeldung anstelle des
+    ueblichen "Wie bitte?" setzen.
+
+    Laesst Du <text> weg, wird wieder auf "Wie bitte?" zurueckgeschaltet.
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/fluchtrichtung b/doc/scmd/fluchtrichtung
new file mode 100644
index 0000000..3b9a565
--- /dev/null
+++ b/doc/scmd/fluchtrichtung
@@ -0,0 +1,40 @@
+
+fluchtrichtung
+--------------
+
+ SEHERKOMMANDO:
+    fluchtrichtung <befehl>
+
+ ARGUMENTE:
+
+     <befehl>
+        Der Befehl fuer die bevorzugte Fluchtrichtung.
+
+ BESCHREIBUNG:
+    Setzt die bevorzugte Fluchtrichtung fuer den Vorsichtsmodus.
+
+    Diese Richtung wird bei der Flucht mit einer gewissen Wahrscheinlichkeit
+    als erstes ausprobiert, falls moeglich. Die Wahrscheinlichkeit betraegt
+    60% bei Stufe 30 und nimmt mit jeder weiteren Stufe um ca. 1,3 Prozent-
+    punkte zu.
+
+    Falls die Flucht in diese Richtung nicht gelingt, werden die anderen
+    Richtungen wie bisher ausprobiert.
+
+ BEISPIELE:
+    Wenn man bevorzugt nach Osten fliehen will:
+
+    > fluchtrichtung osten
+        oder
+    > fluchtrichtung o
+
+    Wenn man "traditionell" fluechten will, dies aber kommentieren moechte,
+    kann man auch folgendes nehmen:
+
+    > fluchtrichtung sag Oh, shit!
+
+ SIEHE AUCH:
+    vorsicht, report
+
+ LETZTE AeNDERUNG:
+    Mit, 07.01.2004,  von Rikus
diff --git a/doc/scmd/hausbau b/doc/scmd/hausbau
new file mode 100644
index 0000000..eae04f7
--- /dev/null
+++ b/doc/scmd/hausbau
@@ -0,0 +1,40 @@
+
+Allgemeines zum Hausbau
+=======================
+
+ ALLGEMEIN:
+    Um ein Haus zu bauen, muss man sich in die Filiale der MorgenGrauen-Bank
+    (Der Bank in Ihrem Ruecken) begeben und am Antragschalter einen
+    Bausparvertrag erwerben. Hat man diesen unterzeichnet (ebenfalls am
+    Antragschalter), kann man sich an die Finanzierung seines Hauses begeben.
+    Alles weitere hierzu ist im Vertrag beschrieben.
+
+    Solltest Du es Dir dann doch noch einmal anders ueberlegen, kannst Du den
+    Vertrag jederzeit zerreissen. Schon eingezahlte Raten sind allerdings
+    unwiderruflich verloren!
+
+    Hast Du die Finanzierungsphase hinter Dich gebracht, kannst Du Dir am
+    Ausgabeschalter ein Instanthaus abholen. Dann kannst Du Dich auf die Suche
+    nach einem geeigneten Bauplatz machen. Das weitere Vorgehen ist mit "hilfe
+    instanthaus" erfahrbar.
+
+    Soll das Haus spaeter um neue Raeume erweitert werden, musst Du Dich
+    wieder zum Antragschalter begeben. Nun musst Du jedoch einen Ausbauvertrag
+    beantragen. Das Sparen erfolgt auf die gleiche Weise wie beim Hausbau,
+    allerdings wird der Ausbau nach Aufbringen der Summe ohne eigenes Zutun
+    vorgenommen (es gibt also keinen Instantraum).
+
+    Man kann neun weitere Raeume dazukaufen, so dass man maximal ueber ein
+    10-Zimmer-Haus verfuegen kann.
+
+    Es ist allerdings auch moeglich, sein Haus mit einem Nachbarhaus zu
+    verbinden (natuerlich nur in gegenseitigem Einverstaendnis). Naeheres
+    hierzu erfaehrt man mit "hilfe ausgang".
+
+ SIEHE AUCH:
+    instanthaus, seherhaus,
+    aendere, ausgang, beschreibe, erlaube, kopiere, licht, loesche, meldungen,
+    notiz, schiebe, sperre, spion, uebersicht, verbiete, werfe
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/instanthaus b/doc/scmd/instanthaus
new file mode 100644
index 0000000..e3d2f2b
--- /dev/null
+++ b/doc/scmd/instanthaus
@@ -0,0 +1,31 @@
+
+Allgemeines zum Instanthaus
+===========================
+
+ ALLGEMEIN:
+    Das Instanthaus ist die Keimzelle Deines Seherhauses. Wenn Du meinst, eine
+    geeignete Stelle gefunden zu haben, kannst Du es fallenlassen und giessen,
+    damit es zu einem richtigen Haus wird.
+
+    Wenn die Stelle nicht als Bauplatz gekennzeichnet ist, bekommst Du eine
+    Meldung, an welchen Magier Du Dich wenden kannst. Dieser entscheidet dann,
+    ob Du dort bauen darfst oder ob Du Dir besser eine andere Stelle suchen
+    solltest.
+
+ KOMMANDOS:
+    Das Instanthaus stellt folgende zwei Befehle zur Verfuegung:
+
+     lass haus fallen
+        Du laesst das Haus fallen. Das geht allerdings nur "draussen" und nur,
+        wenn Deine Umgebung als Bauplatz gekennzeichnet ist. Du kannst es
+        probehalber fallenlassen, um herauszufinden, an wen Du Dich fuer die
+        Kennzeichnung wenden musst.
+     giesse haus
+        Wenn Du das Haus erfolgreich abgestellt hast, kannst Du es durch das
+        Giessen zu einem "richtigen" Haus erwecken.
+
+ SIEHE AUCH:
+    hausbau, seherhaus, regionen
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/kopiere b/doc/scmd/kopiere
new file mode 100644
index 0000000..c167780
--- /dev/null
+++ b/doc/scmd/kopiere
@@ -0,0 +1,72 @@
+
+kopiere
+-------
+
+ SEHERHAUSKOMMANDO:
+    kopiere detail <det1> nach <det2>
+    kopiere lesbares detail <det1> nach <det2>
+    kopiere befehl <bef1> nach <bef2>
+    kopiere befehl <bef1> <para1> nach <bef2>
+    kopiere befehl <bef1> <para1> nach <bef2> <para2>
+
+ ARGUMENTE:
+
+     <det1>
+        (lesbares) Detail, dessen Text kopiert werden soll
+     <det2>
+        Liste der zu kopierenden (lesbaren) Details. Bei mehreren Details
+        muessen diese durch Kommata voneinander getrennt sein!
+     <bef1>
+        Zu kopierender Befehl. Dies darf nur ein einzelnes Verb sein!
+     <bef2>
+        Verb oder Liste von Verben fuer den Zielbefehl.
+     <para1>
+        Parameter, die den zu kopierenden Befehl genauer angeben.
+     <para2>
+        Parameter, die den Zielbefehl genauer angeben.
+
+ BESCHREIBUNG:
+
+     kopiere detail <det1> nach <det2>
+     kopiere lesbares detail <det1> nach <det2>
+        Dieser Befehl beschreibt das (lesbare) Detail <det2> mit dem Text von
+        <det1>. Sehr nuetzlich, wenn man nachtraeglich ein Detail mit einem
+        weiteren Namen ansprechbar machen will und keine Lust hat, den Text
+        nochmal zu tippen.
+
+     kopiere befehl <bef1> nach <bef2>
+        Kopiert den Befehl <bef1> zu dem Befehl <bef2> mit allen Parametern.
+        Wenn es <bef2> schon gab, so wird dessen Parameterliste um neue
+        Parameter ergaenzt.
+
+     kopiere befehl <bef1> <para1> nach <bef2>
+        Kopiert nur den angegebenen Parameter von <bef1> nach <bef2>.
+
+     kopiere befehl <bef1> <para1> nach <bef2> <para2>
+        Wie oben, allerdings kann der Parameter auch geaendert werden.
+
+ BEISPIELE:
+    Das Detail "wand" soll sich auch als "waende" ansprechen lassen:
+
+    > kopiere detail wand nach waende
+
+    Alle "drueck"-Befehle sollen sich auch mit "druecke" ansprechen lassen:
+
+    > kopiere befehl drueck nach druecke
+
+    Statt "druecke hebel" soll man jetzt auch "ziehe hebel" verwenden koennen.
+    "druecke knopf" soll jedoch nicht durch "ziehe knopf" ergaenzt werden:
+
+    > kopiere befehl druecke hebel nach ziehe
+        oder
+    > kopiere befehl druecke hebel nach ziehe hebel
+
+    Der Text von "druecke hebel" wird jetzt auch bei "ziehe faden" ausgegeben:
+
+    > kopiere befehl druecke hebel nach ziehe faden
+
+ SIEHE AUCH:
+    aendere, beschreibe, loesche, uebersicht
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/licht b/doc/scmd/licht
new file mode 100644
index 0000000..e3c576b
--- /dev/null
+++ b/doc/scmd/licht
@@ -0,0 +1,20 @@
+
+licht
+-----
+
+ SEHERHAUSKOMMANDO:
+    licht an | aus
+
+ BESCHREIBUNG:
+    "licht aus" verdunkelt den Raum. Dabei wird der Lichtlevel des Raumes so
+    gesetzt, dass der Gesamtlichtlevel (berechnet sich aus dem des Raumes und
+    dem aller anwesenden Lichtquellen) gerade 0 ergibt.
+
+    "licht an" macht gerade das Gegenteil: der Lichtlevel des Raumes wird so
+    gesetzt, dass der Raum gerade einen Gesamtlichtlevel von 1 hat.
+
+ SIEHE AUCH:
+    beschreibe
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/loesche b/doc/scmd/loesche
new file mode 100644
index 0000000..c70b063
--- /dev/null
+++ b/doc/scmd/loesche
@@ -0,0 +1,64 @@
+
+loesche
+-------
+
+ SEHERHAUSKOMMANDO:
+    loesche detail <det>
+    loesche lesbares detail <det>
+    loesche befehl <bef>
+    loesche alles
+    loesche alle <was>
+
+ ARGUMENTE:
+
+     <det>
+        Liste der zu loeschenden (lesbaren) Details.
+     <bef>
+        Liste der zu loeschenden Befehle.
+     <was>
+        `befehle', `details' oder `lesbare details'
+
+ BESCHREIBUNG:
+    Dieser Befehl dient zum Loeschen von Details und Befehlen. Die einzelnen
+    Anwendungen:
+
+     loesche detail <det>
+     loesche lesbares detail <det>
+        Loescht das (lesbare) Detail <det>. Es koennen auch mehrere (lesbare)
+        Details auf einmal geloescht werden; man muss sie dann mit Kommata
+        voneinander trennen.
+
+     loesche befehl <bef>
+        Loescht den Befehl <bef>. Wenn es sich bei <bef> um ein einfaches Verb
+        handelt, werden alle Befehle zu diesem Verb geloescht. Handelt es sich
+        um ein Verb mit Parameter, so wird nur dieser ganz spezielle Befehl
+        geloescht.
+
+     loesche alles
+        Es werden ALLE Details, lesbaren Details und Befehle auf einen Schlag
+        geloescht. Dazu muss man noch die nachfolgende Sicherheitsabfrage mit
+        `ja' beantworten.
+
+     loesche alle [befehle|details|lesbaren details]
+        Es werden alle Beschreibungen der jeweiligen Sparte geloescht. Auch
+        hier gibt es eine Sicherheitsabfrage, die mit `ja' beantwortet werden
+        muss.
+
+ BEISPIELE:
+    Die Details `wand' und `waende' sollen geloescht werden:
+
+    > loesche detail wand, waende
+
+    Alle druecke-Befehle sollen geloescht werden:
+
+    > loesche befehl druecke
+
+    Nur die Befehle druecke knopf und druecke platte sollen geloescht werden:
+
+    > loesche befehl druecke knopf, druecke platte
+
+ SIEHE AUCH:
+    aendere, beschreibe
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/meldungen b/doc/scmd/meldungen
new file mode 100644
index 0000000..812ff72
--- /dev/null
+++ b/doc/scmd/meldungen
@@ -0,0 +1,28 @@
+
+meldungen
+---------
+
+ SEHERHAUSKOMMANDO:
+    meldungen
+    meldungen <nr>
+    meldungen hier
+
+ ARGUMENTE:
+
+     <nr>
+        Eine Raumnummer Deines Hauses
+
+ BESCHREIBUNG:
+    "meldungen" gibt die eingegangenen Rueckmeldungen von Spielern in Deinem
+    Haus aus (also Typo-, Idee- und Fehlermeldungen).
+
+    "meldungen <nr>" gibt nur die Meldungen aus Raum <nr> aus.
+
+    "meldungen hier" gibt nur die Meldungen aus dem Raum aus, in dem Du gerade
+    stehst.
+
+ SIEHE AUCH:
+    aendere, beschreibe
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/notiz b/doc/scmd/notiz
new file mode 100644
index 0000000..230ce0e
--- /dev/null
+++ b/doc/scmd/notiz
@@ -0,0 +1,31 @@
+
+notiz
+-----
+
+ SEHERHAUSKOMMANDO:
+    notiz <text>
+
+ ARGUMENTE:
+
+     <text>
+        Eine kurze Mitteilung
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kannst Du eine kurze Notiz an der Haustuer anbringen.
+    Aus diesem Grund funktioniert dieser Befeh auch nur aussen!
+
+    Ohne Parameter wird die aktuelle Notiz geloescht.
+
+    Die Notiz wird in der Form
+
+    An der Tuer befindet sich eine Notiz: '<text>'.
+
+    an die Langbeschreibung des Hauses angehaengt.
+
+    Die Notiz wird uebrigens nicht mit gespeichert.
+
+ SIEHE AUCH:
+    beschreibe
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/presay b/doc/scmd/presay
new file mode 100644
index 0000000..c72ff21
--- /dev/null
+++ b/doc/scmd/presay
@@ -0,0 +1,26 @@
+
+presay
+------
+
+ SEHERKOMMANDO:
+    presay <text>
+
+ ARGUMENTE:
+
+     <text>
+        Der Text fuer das Presay.
+
+ BESCHREIBUNG:
+    Das Presay wird in der Kurzbeschreibung des Charakters vor den Namen
+    gesetzt.
+
+    `presay' ohne <text> loescht das momentan gesetzte Presay.
+
+    Magier koennen erreichen, dass ihr Presay auch bei den
+    Kommunikationsbefehlen mit ausgegeben wird.
+
+ SIEHE AUCH:
+    titel, showpresay (nur Magier)
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/remote b/doc/scmd/remote
new file mode 100644
index 0000000..701328b
--- /dev/null
+++ b/doc/scmd/remote
@@ -0,0 +1,53 @@
+
+remote
+------
+
+ SEHERKOMMANDO (erst nach Bestehen der Kristallkugelquest verfuegbar):
+    remote <spieler> <text>
+    r: <spieler> <text>
+    r; <spieler> <text>
+
+ ARGUMENTE:
+
+     <spieler>
+        Name des Ziels.
+     <text>
+        Ein beliebiger Text.
+
+ BESCHREIBUNG:
+    Der Text <text> wird an den Spieler <spieler> ausgegeben. Dem Text wird
+    dabei der eigene Name vorangestellt, und zwar bei `remote' und `r:' im
+    Nominativ und bei `r;' im Genitiv.
+
+    Die Ausgabe erfolgt in folgender Form:
+
+    <eigener Name> text aus der Ferne.
+
+    Das "aus der Ferne" laesst sich durch den Platzhalter # auch an beliebiger
+    Stelle in <text> einbauen.
+
+    Wenn man statt des "aus der Ferne" lieber ein "in der Ferne" haben moechte,
+    so kann man den Platzhalter ^ verwenden.
+
+    Falls man den Platzhalter selber ausgeben moechte, kann man ihn einfach
+    verdoppeln. Aus ## wird dann # und aus ^^ wird ^.
+
+ BEISPIELE:
+    Wenn Wargon mit seinem Tester Saphis unzufrieden ist, kommt es ab und an
+    zu folgenden unschoenen Szenen:
+
+    Wargons Eingaben:
+    > r; saphis Zorn trifft Dich
+    > r: saphis gibt Dir # einen Tritt
+    > r: saphis aergert sich ^ ueber Dich
+
+    Und die Ausgaben bei Saphis:
+    > Wargons Zorn trifft Dich aus der Ferne.
+    > Wargon gibt Dir aus der Ferne einen Tritt.
+    > Wargon aergert sich in der Ferne ueber Dich.
+
+ SIEHE AUCH:
+    emote, echo, verben
+
+ LETZTE AeNDERUNG:
+    Mon, 02.07.2001, 19:00:00 von Tiamak
diff --git a/doc/scmd/review b/doc/scmd/review
new file mode 100644
index 0000000..fa31665
--- /dev/null
+++ b/doc/scmd/review
@@ -0,0 +1,24 @@
+
+review
+------
+
+ SEHERKOMMANDO:
+    review
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Es werden die Meldungen ausgegeben, die Anwesende erhalten, wenn Du einen
+    Raum betrittst oder verlaesst, sowie die Meldungen, wenn Du einen Gegner
+    mit blossen Haenden angreifst.
+
+    Bei Magiern werden ausserdem noch die Meldungen angezeigt, die von den
+    Befehlen clone und destruct ausgegeben werden.
+
+ SIEHE AUCH:
+    setmin, setmout, setmmin, setmmout, sethands
+    Nur Magier: setcmsg, setdmsg
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/schiebe b/doc/scmd/schiebe
new file mode 100644
index 0000000..ac891aa
--- /dev/null
+++ b/doc/scmd/schiebe
@@ -0,0 +1,27 @@
+
+schiebe
+-------
+
+ SEHERHAUSKOMMANDO:
+    schiebe <truhe> nach <richtung>
+
+ ARGUMENTE:
+
+     <truhe>
+        Ein gueltiger Bezeichner der Truhe
+     <richtung>
+        Die Richtung, in die die Truhe geschoben werden soll.
+
+ BESCHREIBUNG:
+    Mit diesem Befehl kann man seine Truhe innerhalb seines Hauses frei
+    verschieben.
+
+    Der Zielraum muss zum eigenen Haus gehoeren; auch wenn man ein
+    benachbartes Seherhaus mitnutzt, kann die Truhe dort nicht hingeschoben
+    werden!
+
+ SIEHE AUCH:
+    beschreibe
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/seherhaus b/doc/scmd/seherhaus
new file mode 100644
index 0000000..5610607
--- /dev/null
+++ b/doc/scmd/seherhaus
@@ -0,0 +1,58 @@
+
+Allgemeines zu Seherhaeusern
+============================
+
+ ALLGEMEIN:
+    Die eigenen vier Waende! Wer traeumt nicht davon? Eine Insel der
+    Privatsphaere in der laermenden Oeffentlichkeit des MorgenGrauen, ganz
+    nach eigenem Geschmack einricht- und ausbaubar!
+
+    Und wer hat sich nicht schon immer einmal gewuenscht, sich mit `ende'
+    ausloggen zu duerfen, ohne Angst um seine Ausruestung zu haben?
+
+    Ein weiterer Vorteil: Nach dem Ausloggen (also per `ende' oder nach einem
+    Reboot) betritt man beim naechsten Einloggen das Spiel in den eigenen vier
+    Waenden und nicht mehr am Startpunkt seiner Rasse.
+
+ SPEZIELLES:
+    Im Eingangsraum des Hauses befindet sich eine Truhe, in der man wichtige
+    Gegenstaende aufbewahren kann, ohne befuerchten zu muessen, dass sie von
+    zufaellig vorbeischauenden Spielern entwendet werden. Man sollte
+    allerdings nicht vergessen, die Truhe auch wieder zu schliessen, nachdem
+    man Sachen hineingelegt hat... ;^)
+
+    Sowohl Gegenstaende in der geschlossenen Truhe wie auch im abgeschlossenen
+    Haus sind zwar vor fremdem Zugriff geschuetzt, aber nach einem Reboot wie
+    ueblich verloren (und wie man leicht einsehen kann, gibt es dafuer auch
+    KEINE Entschaedigung!).
+
+    Erwirbt man im Laufe der Zeit weitere Raeume, um sein Haus auszubauen, so
+    wird die Numerierung der Raeume wichtig:
+    Der Eingangsraum hat die Nummer 0, die weiteren Raeume sind fortlaufend
+    von 1 bis 9 durchnumeriert.
+    Die Nummer des Raumes, in dem man sich gerade befindet, wird bei dem
+    Befehl `uebersicht' angezeigt.
+
+    Wenn man das Haus abgeschlossen hat, kann es niemand mehr betreten. Es ist
+    allerdings NICHT moeglich, jemanden im Haus einzusperren!
+
+    Beschreibungen etc. sind nur im *eigenen* Haus moeglich! Die einzige
+    Aenderung, die man an einem anderen Haus vornehmen kann, ist das Schaffen
+    einer Verbindung (siehe dazu das `ausgang'-Kommando).
+
+    Typo- und Ideemeldungen, die in Deinem Haus von anderen Spielern abgesetzt
+    werden, landen in einer Reportdatei, die Du mit dem Befehl `meldungen'
+    ansehen und mit dem `aendere'-Befehl bearbeiten kannst.
+
+    Jeder Raum des Seherhauses darf maximal 100 einzelne Objekte beinhalten.
+    Dabei gibt es zwei Unterscheidungen:
+       345 Muenzen.         --> Das ist ein Objekt.
+       Ein Titanring. (4)   --> Das sind 4 Objekte.
+
+ SIEHE AUCH:
+    aendere, ausgang, beschreibe, erlaube, hausbau, instanthaus, kopiere,
+    licht, loesche, meldungen, notiz, schiebe, sperre, spion, uebersicht,
+    verbiete, werfe
+
+ LETZTE AeNDERUNG:
+    Thu, 21.07.1997, 20:00:00 von Zook.
diff --git a/doc/scmd/sethands b/doc/scmd/sethands
new file mode 100644
index 0000000..bcc62fb
--- /dev/null
+++ b/doc/scmd/sethands
@@ -0,0 +1,25 @@
+
+sethands
+--------
+
+ SEHERKOMMANDO:
+    sethands <text>
+
+ ARGUMENTE:
+
+     <text>
+        Der Text, der beim Kaempfen mit "den blossen Haenden" erscheinen soll.
+
+ BESCHREIBUNG:
+    Normalerweise erscheint beim Kaempfen ohne Waffen eine Meldung:
+
+    >  Du greifst <Gegner> mit blossen Haenden an.
+                           ^=================^
+
+    Diesen Text kann man durch <text> ersetzen.
+
+ SIEHE AUCH:
+    review
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/setmin b/doc/scmd/setmin
new file mode 100644
index 0000000..69f87a0
--- /dev/null
+++ b/doc/scmd/setmin
@@ -0,0 +1,24 @@
+
+setmin
+------
+
+ SEHERKOMMANDO:
+    setmin [<text>]
+
+ ARGUMENTE:
+
+     <text> (optional)
+        Die neue Eingangsmeldung.
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kann die Meldung definiert werden, die andere Spieler
+    sehen, wenn man in den Raum hineingeht. Dabei wird dem Text <text> noch
+    Dein Name vorangestellt.
+
+    Ohne <text> wird wieder die Defaultmeldung aktiv.
+
+ SIEHE AUCH:
+    setmout, setmmin, setmmout, review
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/setmmin b/doc/scmd/setmmin
new file mode 100644
index 0000000..408141c
--- /dev/null
+++ b/doc/scmd/setmmin
@@ -0,0 +1,24 @@
+
+setmmin
+-------
+
+ SEHERKOMMANDO:
+    setmmin [<text>]
+
+ ARGUMENTE:
+
+     <text> (optional)
+        Die neue Eingangsmeldung.
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kann die Meldung definiert werden, die andere Spieler
+    sehen, wenn man in den Raum teleportiert wird. Dabei wird dem Text <text>
+    noch Dein Name vorangestellt.
+
+    Ohne <text> wird auf die Defaultmeldung zurueckgeschaltet.
+
+ SIEHE AUCH:
+    setmin, setmout, setmmout, review
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/setmmout b/doc/scmd/setmmout
new file mode 100644
index 0000000..9fa1567
--- /dev/null
+++ b/doc/scmd/setmmout
@@ -0,0 +1,24 @@
+
+setmmout
+--------
+
+ SEHERKOMMANDO:
+    setmmout [<text>]
+
+ ARGUMENTE:
+
+     <text> (optional)
+        Die neue Ausgangsmeldung.
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kann die Meldung definiert werden, die andere Spieler
+    sehen, wenn man aus dem Raum teleportiert wird. Dabei wird dem Text <text>
+    noch Dein Name vorangestellt.
+
+    Laesst man <text> weg, wird wieder die Defaultmeldung verwendet.
+
+ SIEHE AUCH:
+    setmout, setmmin, setmin, review
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/setmout b/doc/scmd/setmout
new file mode 100644
index 0000000..be7614a
--- /dev/null
+++ b/doc/scmd/setmout
@@ -0,0 +1,27 @@
+
+setmout
+-------
+
+ SEHERKOMMANDO:
+    setmout [<text>]
+
+ ARGUMENTE:
+
+     <text> (optional)
+        Die neue Ausgangsmeldung.
+
+ BESCHREIBUNG:
+    Mit diesem Kommando kann die Meldung definiert werden, die andere Spieler
+    sehen, wenn man aus dem Raum herausgeht. Dabei wird dem Text <text> noch
+    Dein Name vorangestellt.
+
+    Enthaelt <text> ein #, so wird dieses Zeichen in der Meldung durch die
+    jeweilige Richtung ersetzt.
+
+    Ohne <text> wird wieder die Defaultmeldung verwendet.
+
+ SIEHE AUCH:
+    setmmout, setmin, setmmin, review
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/sperre b/doc/scmd/sperre
new file mode 100644
index 0000000..804512c
--- /dev/null
+++ b/doc/scmd/sperre
@@ -0,0 +1,22 @@
+
+sperre
+------
+
+ SEHERHAUSKOMMANDO:
+    sperre <richtung>
+
+ ARGUMENTE:
+
+     <richtung>
+        Eine der acht Himmelsrichtungen, "oben" oder "unten".
+
+ BESCHREIBUNG:
+    Der Ausgang, der in die angegebene Richtung fuehrt, wird entfernt. Der
+    entsprechende Ausgang vom Zielraum zurueck verschwindet dabei automatisch
+    mit.
+
+ SIEHE AUCH:
+    ausgang, uebersicht
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/spion b/doc/scmd/spion
new file mode 100644
index 0000000..1390e77
--- /dev/null
+++ b/doc/scmd/spion
@@ -0,0 +1,22 @@
+
+spion
+-----
+
+ SEHERHAUSKOMMANDO:
+    spion
+
+ ARGUMENTE:
+    keine
+
+ BESCHREIBUNG:
+    Der Tuerspion: Dieses Kommando zeigt, wer oder was sich vor Deiner
+    Haustuer tummelt. Recht nuetzlich, wenn jemand anklopft und man sich
+    vergewissern will, ob man ihn auch einlassen will.
+
+    Dieses Kommando ist nur im Eingangsraum verfuegbar.
+
+ SIEHE AUCH:
+    seherhaus
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/titel b/doc/scmd/titel
new file mode 100644
index 0000000..ff00511
--- /dev/null
+++ b/doc/scmd/titel
@@ -0,0 +1,29 @@
+
+titel
+-----
+
+ SEHERKOMMANDO:
+    titel <text>
+    titel 0
+
+ ARGUMENTE:
+
+     <text>
+        Der Titeltext.
+
+ BESCHREIBUNG:
+    Der Text wird als neuer Titel gesetzt. Dabei sollte der Titel nicht mit
+    einem Spielertitel identisch oder einem solchen sehr aehnlich sein. Der
+    uebergebene Text darf ein Backspace (\b) am Anfang enhalten, wenn
+    darauf ein Komma (,) oder ein Hochkomma (') folgt.
+
+    Wird kein Argument uebergeben, so wird der aktuelle Titel geloescht.
+
+    Wird 0 als Argument uebergeben, so wird der Titel durch den aktuellen
+    Gildentitel ersetzt.
+
+ SIEHE AUCH:
+    stufen, presay
+
+ LETZTE AeNDERUNG:
+    Sat, 30.09.2000, 01:34:00 von Bierchen
diff --git a/doc/scmd/uebersicht b/doc/scmd/uebersicht
new file mode 100644
index 0000000..6e30063
--- /dev/null
+++ b/doc/scmd/uebersicht
@@ -0,0 +1,25 @@
+
+uebersicht
+----------
+
+ SEHERHAUSKOMMANDO:
+    uebersicht
+
+ ARGUMENTE:
+    uebersicht [erlaubt]
+
+ BESCHREIBUNG:
+    Dieses Kommando zeigt, in welchem Raum seines Hauses man sich gerade
+    befindet, welche Details und lesbaren Details man hier beschrieben hat,
+    und welche Ausgaenge wohin fuehren.
+
+    Steht man im Eingangsraum seines Hauses, wird zusaetzlich die Liste
+    derjenigen Leute ausgegeben, die das Haus und die Truhe oeffnen bzw.
+    (ab)schliessen duerfen. Gibt man im Eingangsraum den Parameter "erlaubt"
+    an, wird nur diese Liste ausgegeben.
+
+ SIEHE AUCH:
+    beschreibe, loesche, kopiere, ausgang, sperre, erlaube, verbiete
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/verbiete b/doc/scmd/verbiete
new file mode 100644
index 0000000..a7e88c4
--- /dev/null
+++ b/doc/scmd/verbiete
@@ -0,0 +1,23 @@
+
+verbiete
+--------
+
+ SEHERHAUSKOMMANDO:
+    verbiete <name>
+
+ ARGUMENTE:
+
+     <name>
+        Ein oder mehrere Name(n) (durch Kommata getrennt).
+
+ BESCHREIBUNG:
+    Dem Spieler <name> wird die Erlaubnis, Dein Haus auf- und abschliessen
+    sowie die Truhe oeffnen zu duerfen, wieder entzogen.
+
+    Dieser Befehl ist nur im Eingangsraum des Hauses verfuegbar!
+
+ SIEHE AUCH:
+    erlaube, uebersicht
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/scmd/werfe b/doc/scmd/werfe
new file mode 100644
index 0000000..154041d
--- /dev/null
+++ b/doc/scmd/werfe
@@ -0,0 +1,33 @@
+
+werfe
+-----
+
+ SEHERHAUSKOMMANDO:
+    werfe <was> raus
+    werfe alle raus
+    werfe alles raus
+
+ ARGUMENTE:
+
+     <was>
+        Das aus dem Haus zu werfende Objekt.
+
+ BESCHREIBUNG:
+    Wenn Dir in Deinem Haus jemand fuerchterlich auf die Nerven geht, kannst
+    Du ihn mit diesem Kommando vor die Haustuer komplimentieren.
+
+    Falls Dir alle Anwesenden auf die Nerven gehen, kannst Du sie auch alle
+    auf einen Schlag entsorgen.
+
+    Die dritte Alternative dagegen dient dazu, saemtliche leblosen
+    Gegenstaende aus dem Haus zu werfen (obwohl das Anlegen wilder Muellkippen
+    vor dem Haus nicht gerade zum guten Ton gehoert ;)
+
+    Das Kommando wirkt uebrigens nur in dem Raum, in dem es angewendet wird,
+    und nicht etwa im ganzen Haus.
+
+ SIEHE AUCH:
+    seherhaus
+
+ LETZTE AeNDERUNG:
+    Thu, 24.07.1997, 09:00:00 von Wargon
diff --git a/doc/sefun/CountUp b/doc/sefun/CountUp
new file mode 100644
index 0000000..5515780
--- /dev/null
+++ b/doc/sefun/CountUp
@@ -0,0 +1,25 @@
+FUNKTION:
+	public varargs string CountUp( string *s, string sep, string lastsep );
+
+ARGUMENTE:
+	*s
+	  Array von Strings mit Woertern.
+  sep
+    String, der zwischen den Woerten in der Aufzaehlung eingefuegt wird.
+    Standard: ", "
+  lastsep
+    String, der zwischen dem vorletzten und letzten Element eingefuegt wird.
+    Standard: " und "
+
+BESCHREIBUNG:
+	Die Woerter Wort_1 bis Wort_n aus dem Stringaray werden als
+	Aufzaehlung in der Form
+	  Wort_1<sep>Wort_2, ... Wort_n-1<lastsep>Wort_n
+	zusammengesetzt. Mit Standardwerten also:
+	  Wort_1, Wort_2, ... Wort_n-1 und Wort_n
+
+RUeCKGABEWERT:
+	String als Aufzaehlung der einzelnen Woerter.
+
+----------------------------------------------------------------------------
+15.03.2008, Zesstra
diff --git a/doc/sefun/_notify_fail b/doc/sefun/_notify_fail
new file mode 100644
index 0000000..84aa4de
--- /dev/null
+++ b/doc/sefun/_notify_fail
@@ -0,0 +1,18 @@
+simul_efun::_notify_fail(E)
+FUNKTION:
+     void _notify_fail(string str)
+
+ARGUMENTE:
+     str
+	umgebrochener Fehlermeldungsstring
+
+BESCHREIBUNG:
+     Identisches Verhalten zu notify_fail(E), bis darauf, dass bei bereits
+     gesetzter Fehlermeldung _keine_ neue Fehlermeldung gesetzt wird.
+
+SIEHE AUCH:
+     notify_fail(E), P_ACTUAL_NOTIFY_FAIL
+     add_action(E), AddCmd(L), AddAction(L),
+     query_verb(E)
+
+24 Maerz 2004 Gloinson
diff --git a/doc/sefun/break_string b/doc/sefun/break_string
new file mode 100644
index 0000000..52d4d7b
--- /dev/null
+++ b/doc/sefun/break_string
@@ -0,0 +1,90 @@
+FUNKTION:
+    string break_string(string str)
+    string break_string(string str, int width)
+    string break_string(string str, int width, string indent)
+    string break_string(string str, int width, int space)
+    string break_string(string str, int width, string indent, int flags)
+    string break_string(string str, int width, int space, int flags)
+
+ARGUMENTE:
+    str    - umzubrechender String
+    width  - optional: maximale Zeilenlaenge (default 78)
+    indent - optional: String, der vor jeder umgebrochenen Zeile erscheint
+    space  - optional: Anzahl der Leerzeichen vor jeder umgebrochenen Zeile
+    flags  - optional: hiermit laesst sich das Verhalten von break_string()
+             aendern; moegliche Flags siehe Punkt 'Beschreibung'
+
+BESCHREIBUNG:
+    In der ersten Form wird der String 'str' durch Einfuegen von "\n" so um-
+    gebrochen, dass bei einer anschliessenden Ausgabe keine Zeile laenger
+    als 'width' Zeichen ist. Eventuell schon in 'str' vorhandene "\n" werden
+    dabei vorher entfernt.
+
+    Gibt man zusaetzlich noch einen String 'indent' an, so wird dieser vor
+    jede der umgebrochenen Zeilen gesetzt.
+
+    Analog wird bei der Angabe der Zahl 'space' ein String mit 'space' Leer-
+    zeichen vor jede umgebrochene Zeile gesetzt.
+
+    Zusaetzlich gibt es folgende optionale Flags, die man beliebig kombinieren
+    kann:
+
+        BS_LEAVE_MY_LFS  -  schon im Text vorhandene "\n" werden beibehalten
+        BS_SINGLE_SPACE  -  doppelte Leerzeichen sowie Leerzeichen nach Zeilen-
+                            umbruechen werden entfernt
+        BS_BLOCK         -  der Text wird im Blocksatz formatiert
+        BS_NO_PARINDENT  -  bei Blocksatz mit vorgegebenen Zeilenumbruechen
+                            (BS_BLOCK|BS_LEAVE_MY_LFS) werden Zeilen nach "\n"
+                            normalerweise mit einem Leerzeichen begonnen.
+                            Um das Einfuegen des fuehrenden Leerzeichens zu
+                            unterdruecken, muss BS_NO_PARINDENT angegeben werden
+        BS_INDENT_ONCE   -  die erste Zeile des Textes wird mit vorangestelltem
+                            'indent' ausgegeben; alle folgenden Zeilen bekommen
+                            einen Leerstring vorangestellt
+        BS_PREPEND_INDENT - der Ident wird dem Text vorangestellt sofern der 
+                            Indent + Text laenger als eine Zeile ist. Der Text
+			    wird um ein Leerzeichen eingerueckt, was mittels
+                            BS_NO_PARINDENT verhindert werden kann.
+
+RUECKGABEWERT:
+    Der umgebrochene Text.
+
+    Laufzeit-Fehler, wenn der Indent laenger ist als die vorgegebene Breite.
+
+BEISPIELE:
+    write(break_string("Dies ist ein laengerer Text. Nur so als Beispiel.",27));
+
+        => Dies ist ein laengerer
+           Text. Nur so als Beispiel.
+
+    write(break_string("Mit indent sieht das so aus", 30, "Wargon sagt: "));
+
+        => Wargon sagt: Mit indent sieht
+           Wargon sagt: das so aus
+
+    write(break_string("Mit indent sieht das so aus", 30, "Wargon sagt: ",
+                        BS_INDENT_ONCE));
+
+        => Wargon sagt: Mit indent sieht
+                        das so aus
+
+    write(break_string("Mit Leerzeichen sieht das so aus", 30, 2));
+
+        =>   Mit Leerzeichen sieht das so
+             aus...
+
+    write(break_string("Ich will es\naber vorformatiert!",60,
+                        "Wargon sagt: ", BS_LEAVE_MY_LFS));
+
+        => Wargon sagt: Ich will es
+           Wargon sagt: aber vorformatiert!
+
+    write(break_string("Ich will es\naber vorformatiert!",30,
+                        "Wargon sagt: ", BS_PREPEND_INDENT));
+
+        => Wargon sagt:
+            Ich will es aber 
+            vorformatiert!
+
+SIEHE AUCH:
+    senderwiederholung
diff --git a/doc/sefun/broken_count_bits b/doc/sefun/broken_count_bits
new file mode 100644
index 0000000..09e56b8
--- /dev/null
+++ b/doc/sefun/broken_count_bits
@@ -0,0 +1,29 @@
+SYNOPSIS
+        int count_bits (string str)
+
+DESTRIPTION
+        Count the number of set bits in bitstring <str> and return the number
+        as result.
+
+NOTE
+	Bitstrings store 6 Bits per Character. Consequently, the functions for
+	manipulating bitstrings (see below) do generally not work on most
+	strings. An exception is this (s)efun. It accepts strings which are
+	not correct bitstrings (like getuid(PL)), BUT: It does NOT work
+	correctly on them! The results are NOT the correct number of bits!
+	Additionally, count_bits() in LDMud rejects such strings with an error
+	instead of returning false results, as all the other functions for
+	bitstrings do as well.
+
+EXAMPLES
+        string s;
+
+        s = set_bit("", 3); s = set_bit(s, 15);
+
+        count_bits(s) --> returns 2
+
+SEE ALSO
+        clear_bit(E), set_bit(E), test_bit(E), next_bit(E), last_bit(E),
+        or_bits(E), xor_bits(E), invert_bits(E), copy_bits(E)
+
+19.12.2006, Zesstra
diff --git a/doc/sefun/cindent b/doc/sefun/cindent
new file mode 100644
index 0000000..72119b3
--- /dev/null
+++ b/doc/sefun/cindent
@@ -0,0 +1,9 @@
+SYNOPSIS:
+        int cindent(string file)
+
+DESCRIPTION:
+        Indent a file using an LPC-enhanced version of the GNU indent
+	program, which is modelled after the Berkeley indent(1).
+
+SEE ALSO:
+	ed(E)
diff --git a/doc/sefun/debug_info b/doc/sefun/debug_info
new file mode 100644
index 0000000..18747b0
--- /dev/null
+++ b/doc/sefun/debug_info
@@ -0,0 +1,490 @@
+DEPRECATED
+SYNOPSIS
+        #include <debug_info.h>
+
+        mixed debug_info(int flag)
+        mixed debug_info(int flag, mixed arg)
+        mixed debug_info(int flag, mixed arg2, mixed arg3)
+
+BESCHREIBUNG
+        Sammelt entsprechend den Angaben in <flag> gewisse intere Debuginfos
+        des Treibers. <flag> kann dabei folgende in debug_info.h definierte
+        Werte enthalten:
+
+        DINFO_OBJECT   (0): Angezeigt werden Informationen zum in <arg>
+            spezifizierten Objekt, zum Beispiel heart_beat,
+            enable_commands etc. Die Funktion liefert 0 zurueck.
+
+        DINFO_MEMORY   (1): Angezeigt werden Informationen zu
+            Speicherbelegung und -ausnutzung des in <arg> spezifizierten
+            Objekts, zum Beispiel Anzahl Strings, Variablen, geerbte Files,
+            Objektgroesse etc. Die Funktion liefert 0 zurueck.
+
+        DINFO_OBJLIST  (2): debug_info() liefert Objekte aus der globalen
+            Objektliste. Wenn <arg2> nicht angegeben wird, wird das erste
+            Element aus der Objektliste gelierfert, wenn <arg2> eine Zahl n
+            ist, das n-te Element. Ist <arg2> ein Objekt, werden die
+            nachfolgenden Objekte in der Objektliste zurueck geliefert.
+            Das optionale Argument <arg3> bezeichnet die Anzahl zurueck
+            gelieferter Objekte. Wenn <arg3> 0 ist, wird ein einzelnes
+            Objekt zurueck geliefert. Wenn <arg3> eine Zahl m enthaelt, wird
+            ein Array mit hoechstens m Elementen zurueck geliefert. Auf
+            diese Weise kann ein Array mit saemtlichen Objekten im Spiel
+            erzeugt werden, wenn fuer <arg3> __INT_MAX__ gesetzt wird (eine
+            entsprechende maximale Arraygroesse vorausgesetzt).
+
+        DINFO_MALLOC   (3): Entsprichend der Eingabe des 'malloc'-Kommandos.
+            Es muessen keine weiteren Argumente angegeben werden.
+
+        DINFO_STATUS   (4): Angezeigt wird die Statusinformation des Drivers.
+            Optional kann das Argument <arg> die Werte 0, "tables", "swap",
+            "malloc" oder andere vom Driver akzeptierte Argumente enthalten.
+            Das Resultat ist ein druckbarer String, der die Statusinformation
+            enthaelt, oder 0, wenn ein ungueltiges Argument angegeben wurde.
+
+        DINFO_DUMP     (5): Die durch <arg2> angeforderte Information wird
+            in ein File geschrieben, das man mit <arg3> angeben kann. Wird
+            <arg3> nicht angegeben, wird eine Standarddatei verwendet.
+            debug_info() ueberprueft mittels master->valid_write(), ob es
+            das File schreiben kann. Falls bereits eine entsprechende Datei
+            existiert, wird diese ueberschrieben. Die Funktion liefert 1
+            bei Erfolg, 0 sonst.
+
+            <arg2> == "objects": liefert Informationen ueber alle Objekte im
+                Spiel und schreibt diese standardmaessig in die Datei
+                /OBJ_DUMP, dem valid_write() wird 'objdump' uebergeben.
+                Die Datei enthaelt fuer jedes Objekt eine Zeile, in der
+                jeweils folgende Informationen aufgelistet sind:
+                  - Name des Objekts (object_name)
+                  - Groesse im Speicher, gemeinsamer genutzter Speicher nur
+                    einmal gezaehlt
+                  - Groesse im Speicher, wenn es keine gemeinsam genutzte
+                    Daten geben wuerde
+                  - Anzahl Referenzen
+                  - 'HB', wenn das Objekt einen heart_beat hat, sonst nichts.
+                  - der Name der Umgebung oder '--', wenn das Objekt keine
+                    Umgebung hat
+                  - in Klammern die Anzahl der durch das Objekt verursachten
+                    Verarbeitungsschritten (execution ticks)
+                  - der Swap-Status:
+                      > nichts, wenn das Objekt nicht geswapt wurde
+                      > 'PROG SWAPPED', wenn nur das Programm geswapt wurde
+                      > 'VAR SWAPPED', wenn nur die Variablen geswapt wurden
+                      > 'SWAPPED', wenn beide geswapt wurden
+                  - die Zeit, zu der das Objekt geladen wurde.
+
+            <arg2> == "destructed": liefert Informationen ueber alle
+                zerstoerten Objekte und schreibt diese standardmaessig in
+                die Datei /DEST_OBJ_DUMP, dem valid_write() wird 'objdump'
+                uebergeben. Die Datei enthaelt fuer jedes Objekt eine Zeile,
+                in der jeweils folgende Informationen aufgelistet sind:
+                  - Name des Objekts (object_name)
+                  - Anzahl der Referenzen
+                  - 'NEW', wenn das Objekt in diesem Verarbeitungszyklus
+                    zerstoert wurde, nichts wenn es bereits fruehre zerstoert
+                    worden war.
+
+            <arg2> == "opcodes": liefert Nutzungsinformationen ueber die
+                opcodes. Standardmaessig wird in die Datei /OPC_DUMP
+                geschrieben. valid_write() wird 'opcdump' uebergeben.
+
+            <arg2> == "memory": liefert eine Liste aller allokierten
+                Speicherbloecke.
+                Standardmaessig wird in die Datei /MEMORY_DUMP geschrieben;
+                valid_write() wird 'memdump' uebergeben.  Existiert die
+                Datei bereits, werden die neuen Daten angehaengt.
+                Wenn der Allokator einen Speicherabzug nicht unterstuetzt,
+                wird keine Datei geschrieben und immer 0 zurueckgegeben.
+                Diese Funktion ist am nuetzlichsten wenn der Allokator
+                mit MALLOC_TRACE und MALLOC_LPC_TRACE kompiliert
+                wurde.
+
+
+        DINFO_DATA    (6): Liefert Rohdaten ueber gewisse, durch <arg2>
+            spezifizierte Aspekte des Treibers. Das Resultat der Funktion ist
+            ein Array mit der Information oder 0, falls <arg2> keinen
+            gueltigen Wert enthalten hat.
+            Ist <arg3> eine Zahl, die kleiner ist als die Anzahl Elemente im
+            Resultat-Array, liefert die Funktion nur das entsprechende
+            Element zurueck.
+            Zulaessige Werte fuer <arg2> sind: DID_STATUS, DID_SWAP und
+            DID_MALLOC.
+
+            <arg2> == DID_STATUS (0): Liefert die "status" und "status table"
+                Information. Folgende Indizes sind definiert:
+                  - int DID_ST_BOOT_TIME
+                        die Zeit (time()), zu der das Mud gestartet wurde
+                  - int DID_ST_ACTIONS
+                  - int DID_ST_ACTIONS_SIZE
+                        die Anzahl und Groesse im Speicher der allozierten
+                        Actions.
+                  - int DID_ST_SHADOWS
+                  - int DID_ST_SHADOWS_SIZE
+                        Anzahl und Groesse im Speicher aller allozierten
+                        Shadows.
+                  - int DID_ST_OBJECTS
+                  - int DID_ST_OBJECTS_SIZE
+                        Anzahl und Groesse im Speicher aller Objekte.
+                  - int DID_ST_OBJECTS_SWAPPED
+                  - int DID_ST_OBJECTS_SWAP_SIZE
+                        Anzahl und Groesse im Speicher der geswapten
+                        Variablenbloecke der Objekte
+                  - int DID_ST_OBJECTS_LIST
+                        Anzahl Objekte in der Objektliste
+                  - int DID_ST_OBJECTS_NEWLY_DEST
+                        Anzahl der frisch zerstoerten Objekte (d.h. Objekte,
+                        die in diesem Verarbeitungszyklus zerstoert wurden)
+                  - int DID_ST_OBJECTS_DESTRUCTED
+                        Anzahl der zerstoerten, aber noch immer referenzierten
+                        Objekte, ohne die unter DID_ST_OBJECTS_NEWLY_DEST
+                        bereits gezaehlten.
+                  - int DID_ST_OBJECTS_PROCESSED
+                        Anzahl der gelisteten Objekte, die im letzten
+                        Verarbeitungszyklus verarbeitet wurden.
+                  - float DID_ST_OBJECTS_AVG_PROC
+                        Durchschnittlicher Anteil der pro Zyklus verarbeiteten
+                        Objekte, ausgedrueckt in Prozent (0 .. 1.0)
+                  - int DID_ST_OTABLE
+                        Anzahl eingetragener Objekte in der Objekttabelle
+                  - int DID_ST_OTABLE_SLOTS
+                        Anzahl von Hashplaetzen, die von jeder Objekttabelle
+                        bereitgestellt werden
+                  - int DID_ST_OTABLE_SIZE
+                        Durch die Objekttabelle belegter Speicher
+                  - int DID_ST_HBEAT_OBJS
+                        Anzahl Objekte mit einem heart_beat()
+                  - int DID_ST_HBEAT_CALLS
+                        Anzahl aktiver heart_beat() Zyklen bisher (d.h.
+                        Zyklen, in denen mindestens eine heart_beat() Funktion
+                        aufgerufen wurde)
+                  - int DID_ST_HBEAT_CALLS_TOTAL
+                        Gesamtzahl von heart_beat() Zyklen bisher.
+                  - int DID_ST_HBEAT_SLOTS
+                  - int DID_ST_HBEAT_SIZE
+                        Anzahl und Groesse aller allozierten Eintraege in der
+                        heart_beat() Tabelle.
+                  - int DID_ST_HBEAT_PROCESSED
+                        Anzahl heart_beat()s im letzten Zyklus
+                  - float DID_ST_HBEAT_AVG_PROC
+                        Durchschnittlicher Anteil der pro Zyklus aufgerufenen
+                        heart_beat()s, ausgedrueckt in Prozent (0 .. 1.0)
+                  - int DID_ST_CALLOUTS
+                        Anzahl und Groesse aller laufenden call_out()s
+                  - int DID_ST_ARRAYS
+                  - int DID_ST_ARRAYS_SIZE
+                        Anzahl und Groesse aller Arrays
+                  - int DID_ST_MAPPINGS
+                  - int DID_ST_MAPPINGS_SIZE
+                        Anzahl und Groesse aller Mappings
+                  - int DID_ST_PROGS
+                  - int DID_ST_PROGS_SIZE
+                        Anzahl und Groesse aller Programme
+                  - int DID_ST_PROGS_SWAPPED
+                  - int DID_ST_PROGS_SWAP_SIZE
+                        Anzahl und Groesse der geswapten Programme
+                  - int DID_ST_USER_RESERVE
+                  - int DID_ST_MASTER_RESERVE
+                  - int DID_ST_SYSTEM_RESERVE
+                        Momentane Groesse der drei Speicherreserven
+                  - int DID_ST_ADD_MESSAGE
+                  - int DID_ST_PACKETS
+                  - int DID_ST_PACKET_SIZE
+                        Anzahl Aufrufe von add_message(), Anzahl und Groesse
+                        der versendeten Pakete.
+                        Wenn der Driver nicht mit COMM_STAT kompiliert wurde,
+                        liefern alle drei Werte immer -1 zurueck.
+                  - int DID_ST_APPLY
+                  - int DID_ST_APPLY_HITS
+                        Anzahl Aufrufen von apply_low(), und wie viele davon
+                        Cache-Treffer waren. Wenn der Driver nicht mit
+                        APPLY_CACHE_STAT kompiliert wurde, liefern beide
+                        Werte immer -1.
+                  - int DID_ST_STRINGS
+                  - int DID_ST_STRING_SIZE
+                        Anzahl unterschiedlicher Strings in der Stringtabelle,
+                        sowie ihre Groesse
+                  - int DID_ST_STR_TABLE_SIZE
+                        Groesse der String Tabelle
+                  - int DID_ST_STR_REQ
+                  - int DID_ST_STR_REQ_SIZE
+                        Gesamte Anzahl von String Allokationen, und ihre
+                        Groesse
+                  - int DID_ST_STR_SEARCHES
+                  - int DID_ST_STR_SEARCH_LEN
+                        Anzahl Suchvorgaenge in der Stringtabelle und die
+                        Gesamtlaenge des Suchstrings
+                  - int DID_ST_STR_FOUND
+                        Anzahl erfolgreicher Suchvorgaenge
+                  - int DID_ST_STR_ENTRIES
+                        Anzahl Eintraege (Hash Ketten) in der String Tabelle
+                  - int DID_ST_STR_ADDED
+                        Anzahl zur String Tabelle bisher hinzugefuegter
+                        Strings
+                  - int DID_ST_STR_DELETED
+                        Anzahl aus der String Tabelle bisher geloeschter
+                        Strings
+                  - int DID_ST_STR_COLLISIONS
+                        Anzahl zu einer existierenden Hash Kette hinzugefuegte
+                        Strings
+                  - int DID_ST_RX_CACHED
+                        Anzahl gecacheter regulaerer Ausdruecke (regular
+                        expressions)
+                  - int DID_ST_RX_TABLE
+                  - int DID_ST_RX_TABLE_SIZE
+                        Anzahl Plaetze in der Regexp Cache Tabelle und
+                        Speicherbedarf der gecacheten Ausdruecke
+                  - int DID_ST_RX_REQUESTS
+                        Anzahl Anfragen fuer neue regexps
+                  - int DID_ST_RX_REQ_FOUND
+                        Anzahl gefundener regexps in der regexp Cache Tabelle
+                  - int DID_ST_RX_REQ_COLL
+                        Anzahl angefragter regexps, die mit einer bestehenden
+                        regexp kollidierten
+                  - int DID_ST_MB_FILE
+                        Die Groesse des 'File' Speicherpuffers
+                  - int DID_ST_MB_SWAP
+                        Die Groesse des 'Swap' Speicherpuffers
+
+            <arg2> == DID_SWAP (1): Liefert "status swap"-Information:
+                  - int DID_SW_PROGS
+                  - int DID_SW_PROG_SIZE
+                        Anzahl und Groesse der geswappten Programmbloecke
+                  - int DID_SW_PROG_UNSWAPPED
+                  - int DID_SW_PROG_U_SIZE
+                        Anzahl und Groesse der nicht geswappten Bloecke
+                  - int DID_SW_VARS
+                  - int DID_SW_VAR_SIZE
+                        Anzahl und Groesse der geswappten Variablenbloecke
+                  - int DID_SW_FREE
+                  - int DID_SW_FREE_SIZE
+                        Anzahl und Groesse der freien Bloecke in der
+                        Auslagerungsdatei
+                  - int DID_SW_FILE_SIZE
+                        Groesse der Auslagerungsdatei
+                  - int DID_SW_REUSED
+                        Gesamter wiederverwendeter Speicherplatz in der
+                        Auslagerungsdatei
+                  - int DID_SW_SEARCHES
+                  - int DID_SW_SEARCH_LEN
+                        Anzahl und Gesamtlaenge der Suchvorgaenge nach
+                        wiederverwendbaren Bloecken in der Auslagerungsdatei
+                  - int DID_SW_F_SEARCHES
+                  - int DID_SW_F_SEARCH_LEN
+                        Anzahl und Gesamtlaenge der Suchvorgaenge nach einem
+                        Block, der frei gemacht werden kann.
+                  - int DID_SW_COMPACT
+                        TRUE wenn der Swapper im Compact-Modus laeuft
+                  - int DID_SW_RECYCLE_FREE
+                        TRUE wenn der Swapper gerade einen freien Block
+                        wiederverwendet
+
+            <arg2> == DID_MEMORY (2): Liefert die "status malloc"-Information:
+                  - string DID_MEM_NAME
+                        Der Name des Allokators: "sysmalloc", "smalloc",
+                        "slaballoc"
+                  - int DID_MEM_SBRK
+                  - int DID_MEM_SBRK_SIZE
+                        Anzahl und Groesse der Speicherbloecke, die vom
+                        Betriebssystem angefordert wurden (smalloc, slaballoc)
+                  - int DID_MEM_LARGE
+                  - int DID_MEM_LARGE_SIZE
+                  - int DID_MEM_LFREE
+                  - int DID_MEM_LFREE_SIZE
+                        Anzahl und Groesse der grossen allozierten bzw.
+                        freien Bloecke (smalloc, slaballoc)
+                  - int DID_MEM_LWASTED
+                  - int DID_MEM_LWASTED_SIZE
+                        Anzahl und Groesse der unbrauchbaren grossen
+                        Speicherfragmente (smalloc, slaballoc)
+                  - int DID_MEM_CHUNK
+                  - int DID_MEM_CHUNK_SIZE
+                        Anzahl und Groesse kleiner Speicherbloecke (chunk
+                        blocks; smalloc, slaballoc)
+                  - int DID_MEM_SMALL
+                  - int DID_MEM_SMALL_SIZE
+                  - int DID_MEM_SFREE
+                  - int DID_MEM_SFREE_SIZE
+                        Anzahl und groesse der allozierten bzw. freien
+                        kleinen Speicherbloecke (smalloc, slaballoc)
+                  - int DID_MEM_SWASTED
+                  - int DID_MEM_SWASTED_SIZE
+                        Anzahl und Groesse der unbrauchbar kleinen
+                        Speicherfragmente (smalloc, slaballoc)
+                  - int DID_MEM_MINC_CALLS
+                  - int DID_MEM_MINC_SUCCESS
+                  - int DID_MEM_MINC_SIZE
+                        Anzahl Aufrufe von malloc_increment(), Anzahl der
+                        erfolgreichen Aufrufe und die Groesse des auf diese
+                        Art allozierten Speichers (smalloc, slaballoc)
+                  - int DID_MEM_PERM
+                  - int DID_MEM_PERM_SIZE
+                        Anzahl und Groesse permanenter (non-GCable)
+                        Allokationen (smalloc, slaballoc)
+                  - int DID_MEM_CLIB
+                  - int DID_MEM_CLIB_SIZE
+                        Anzahl und Groesse der Allokationen durch Clib
+                        Funktionen (nur smalloc, slaballoc mit SBRK_OK)
+                  - int DID_MEM_OVERHEAD
+                        Overhead fuer jede Allokation (smalloc, slaballoc)
+                  - int DID_MEM_ALLOCATED
+                        Der Speicher, der durch die Speicherverwaltung
+                        alloziert wurde, inklusive den Overhead fuer die
+                        Speicherverwaltung (smalloc, slaballoc)
+                  - int DID_MEM_USED
+                        Der Speicher, der durch den Driver belegt ist, ohne
+                        den durch die Speicherverwaltung belegten Speicher
+                        (smalloc, slaballoc)
+                  - int DID_MEM_TOTAL_UNUSED
+                        Der Speicher, der vom System zur Verfuegung gestellt,
+                        aber vom Treiber nicht benoetigt wird.
+                  - int DID_MEM_AVL_NODES          (smalloc, slaballoc)
+                        Anzahl der AVL-Knoten, die zur Verwaltung der
+                        freien grossen Speicherbloecke verwendet werden
+                        (nur smalloc). Dieser Wert kann in Zukunft
+                        wieder verschwinden.
+                  - mixed * DID_MEM_EXT_STATISTICS (smalloc, slaballoc)
+                        Detaillierte Statistiken des Allokators sofern
+                        diese aktiviert wurden; 0 anderenfalls.
+
+                        Dieser Wert kann in Zukunft wieder verschwinden.
+
+                        Das Array enthaelt NUM+2 Eintraege, wobei NUM
+                        Anzahl der verschiedenen 'kleinen'
+                        Blockgroessen ist. Eintrag [NUM] beschreibt
+                        die uebergrossen 'kleinen' Bloecke, Eintrag
+                        [NUM+1] beschreibt summarisch die 'grossen'
+                        Bloecke. Jeder Eintrag ist ein Array mit
+                        diesen Feldern:
+
+                        int DID_MEM_ES_MAX_ALLOC:
+                          Maximale Anzahl allokierter Bloecke dieser
+                          Groesse.
+
+                        int DID_MEM_ES_CUR_ALLOC:
+                          Derzeitige Anzahl allokierter Bloecke dieser
+                          Groesse.
+                          Current number of allocated blocks of this size.
+
+                        int DID_MEM_ES_MAX_FREE:
+                          Maximale Anzahl freier Bloecke dieser
+                          Groesse.
+
+                        int DID_MEM_ES_CUR_FREE:
+                          Derzeitige Anzahl freier Bloecke dieser
+                          Groesse.
+
+                        float DID_MEM_ES_AVG_XALLOC:
+                          Durchschnittliche Zahl von Allokationen pro
+                          Sekunde.
+
+                        float DID_MEM_ES_AVG_XFREE:
+                          Durchschnittliche Zahl von Deallokationen pro
+                          Sekunde.
+
+                      Die Durchschnittsstatistiken schliessen interne
+                      Umsortierungen der Blocklisten nicht ein.
+
+
+        DINFO_TRACE    (7): Liefert die 'trace' Information aus dem
+            Call Stack entsprechend der Spezifikation in <arg2>. Das Resultat
+            ist entweder ein Array (dessen Format nachstehend erlaeutert ist)
+            oder ein druckbarer String. Wird <arg2> weggelasen entspricht
+            dies DIT_CURRENT.
+
+            <arg2> == DIT_CURRENT (0): Momentaner Call Trace
+                   == DIT_ERROR   (1): Letzter Fehler Trace (caught oder
+                        uncaught)
+                   == DIT_UNCAUGHT_ERROR (2): Letzer Fehler Trace, der nicht
+                        gefangen werden konnte (uncaught)
+
+            Die Information wird in Form eines Array uebergeben.
+
+            Die Fehlertraces werden nur geaendert, wenn ein entsprechender
+            Fehler auftritt; ausserdem werden sie bei einem GC (Garbage
+            Collection) geloescht. Nach einem Fehler, der nicht gefangen
+            werden konnte (uncaught error), weisen beide Traces auf das
+            gleiche Array, sodass der ==-Operator gilt.
+
+            Wenn das Array mehr als ein Element enthaelt, ist das erste
+            Element 0 oder der Name des Objekts, dessen heart_beat() den
+            laufenden Zyklus begonnen hat; alle nachfolgenden Elemente
+            bezeichnen den Call Stack, beginnen mit der hoechsten
+            aufgerufenen Funktion.
+
+            Alle Eintraege im Array sind wiederum Arrays mit folgenden
+            Elementen:
+              - int[TRACE_TYPE]: Der Typ der aufrufenden Funktion
+                    TRACE_TYPE_SYMBOL (0): ein Funktionssymbol (sollte nicht
+                                           vorkommen)
+                    TRACE_TYPE_SEFUN  (1): eine simul-efun
+                    TRACE_TYPE_EFUN   (2): eine Efun Closure
+                    TRACE_TYPE_LAMBDA (3): eine lambda Closure
+                    TRACE_TYPE_LFUN   (4): eine normale Lfun
+              - int[TRACE_NAME]
+                    _TYPE_EFUN    : entweder der Name der Funktion oder der
+                                    Code einer Operator-Closure
+                    _TYPE_LAMBDA  : die numerische Lambda-ID
+                    _TYPE_LFUN    : der Name der Lfun
+              - string[TRACE_PROGRAM]:  Der Name des Programms mit dem Code
+              - string[TRACE_OBJECT]:   Der Name des Objekts, fuer das der
+                                        Code ausgefuehrt wurde
+              - int[TRACE_LOC]:
+                    _TYPE_LAMBDA  : Der Offset des Programms seit Beginn des
+                                    Closure-Codes
+                    _TYPE_LFUN    : Die Zeilennummer.
+
+            <arg2> == DIT_STR_CURRENT (3): Liefert Informationen ueber den
+                momentanen Call Trace als druckbarer String.
+
+            <arg2> == DIT_CURRENT_DEPTH (4): Liefert die Zahl der Frames auf
+                dem Control Stack (Rekursionstiefe).
+
+        DINFO_EVAL_NUMBER (8): gibt die Nummer der aktuellen Berechnung
+            zurueck. Diese Nummer wird fuer jeden vom driver initiierten
+            Aufruf von LPC-Code erhoeht, also bei Aufruf von:
+              - Kommandos (die per add_action hinzugefuegt wurden)
+              - heart_beat, reset, clean_up
+              - Aufrufe durch call_out oder input_to
+              - master applies, die auf externe Ereignisse zurueckgehen
+              - driver hooks genauso
+              - Rueckrufen von send_erq
+              - logon in interaktiven Objekten
+
+           Dieser Zaehler kann z.B. benutzt werden, um zu verhindern, dass
+           bestimmte Aktionen mehrfach innerhalb eines heart_beat()
+           ausgefuehrt werden. Eine andere Anwendungsmoeglichkeit sind
+           Zeitstempel zur Sortierung zur Sortierung von Ereignissen.
+
+           Es ist zu beachten, dass der Zaehler ueberlaufen kann, insbesondere
+           auf 32-bit-Systemen. Er kann demzufolge auch negativ werden.
+
+
+GESCHICHTE
+        Seit 3.2.7 liefert DINFO_STATUS die Information zurueck, anstatt sie
+            nur auszugeben.
+        DINFO_DUMP wurde in 3.2.7 eingefuehrt.
+        LDMud 3.2.8 fuegte die Datengroesse des Objekts zum Resultat von
+            DINFO_MEMORY hinzu, ausserdem die DINFO_DATA Abfrage und die
+            verschiedenen DID_MEM_WASTED Statistiken.
+        LDMud 3.2.9 fuegte DINFO_TRACE, das Indizierungs-Feature von
+            DINFO_DATA, den 'destructed'-DINFO_DUMP, die DID_MEM_CLIB*,
+            die DID_MEM_PERM*, ausserdem DID_ST_OBJECTS_NEWLY_DEST,
+            DID_ST_OBJECTS_DEST, DID_MEM_OVERHEAD, DID_MEM_ALLOCATED,
+            DID_MEM_USED, DID_MEM_TOTAL_UNUSED, DID_ST_HBEAT_CALLS_TOTAL
+            und die found / added / collision Stringstatistiken.
+        LDMud 3.2.10 fuegte die Erzeugungszeit zu DINFO_DUMP:"objects" hinzu,
+            entfernte DID_MEM_UNUSED aus DINFO_DATA:DID_MEMORY, fuegte
+            DINFO_DATA:DID_STATUS DID_ST_BOOT_TIME, DID_ST_MB_FILE und
+            DID_ST_MB_SWAP hinzu und entfernte DID_ST_CALLOUT_SLOTS daraus,
+            fuegte das dritte Argument zu DINFO_OBJLIST hinzu, und veraenderte
+            die Bedeutung von DID_ST_CALLOUT_SIZE und DID_ST_HBEAT_SIZE
+            bzw. _SLOTS.
+        LDMud 3.3.533 fuegte DID_MEM_AVL_NODES zu DINFO_DATA:DID_MEMORY
+            hinzu.
+        LDMud 3.3.603 fuegte DID_MEM_EXT_STATISTICS zu DINFO_DATA:DID_MEMORY
+            hinzu.
+        LDMud 3.3.718 fuegte DIT_CURRENT_DEPTH to DINFO_TRACE hinzu.
+        LDMud 3.3.719 fuegte DINFO_EVAL_NUMBER hinzu.
+
+SIEHE AUCH
+        trace(E), traceprefix(E), malloc(D), status(D), dumpallobj(D)
diff --git a/doc/sefun/deep_present b/doc/sefun/deep_present
new file mode 100644
index 0000000..78c0983
--- /dev/null
+++ b/doc/sefun/deep_present
@@ -0,0 +1,21 @@
+FUNKTION:
+        object deep_present(string what)
+        object deep_present(object what)
+        object deep_present(string what, object ob)
+        object deep_present(object what, object ob)
+
+ARGUMENTE:
+        what - Objekt oder ID des Objektes, nach dem gesucht werden soll
+        ob - Objekt, in dem gesucht werden soll
+
+BESCHREIBUNG:
+        deep_present() sucht in this_object() (oder in ob, falls angegeben)
+        nach dem Objekt what oder einem Objekt, das auf what anspricht.
+        Im Gegensatz zu present() wird aber das komplette Inventory berueck-
+        sichtigt (also zB. auch der Inhalt von Beuteln).
+
+RUECKGABEWERT:
+        das gefundene Objekt oder 0
+
+SIEHE AUCH:
+        present(E)
diff --git a/doc/sefun/dtime b/doc/sefun/dtime
new file mode 100644
index 0000000..6624642
--- /dev/null
+++ b/doc/sefun/dtime
@@ -0,0 +1,24 @@
+FUNKTION:
+	string dtime(int time)
+
+ARGUMENTE:
+	time - Umzuwandelndes Datum in Sekunden seit 1.1.1970, 0:0:0h
+
+BESCHREIBUNG:
+	Wandelt das Datum time in einen deutschsprachigen String der Form
+	"<wtag>, <tag>. <mon> <jahr>, <std>:<min>:<sek>" um.
+
+RUECKGABEWERT:
+	Der String mit dem umgewandelten Datum.
+
+BEMERKUNGEN:
+	Als time wird meistens das Ergebnis von time() benutzt.
+  strftime() stellt eine wesentlich flexiblere Moeglichkeit der Ausgabe von
+  Zeiten dar.
+
+BEISPIELE:
+	datum = dtime(time());
+        => datum = "Mon,  6. Mar 1994, 15:00:08"
+
+SIEHE AUCH:
+	ctime(E), strftime(E), time(E)
diff --git a/doc/sefun/dump_netdead b/doc/sefun/dump_netdead
new file mode 100644
index 0000000..c73b2c0
--- /dev/null
+++ b/doc/sefun/dump_netdead
@@ -0,0 +1,13 @@
+FUNKTION:
+        string *dump_netdead()
+
+BESCHREIBUNG:
+        Gibt ein Array mit den Namen aller zur Zeit netztoten Spieler
+        zurueck.
+
+RUECKGABEWERT:
+        Ein Stringarray mit den Namen der netztoten Spieler.
+        gibt.
+
+SIEHE AUCH:
+        find_netdead(E)
diff --git a/doc/sefun/enable_commands b/doc/sefun/enable_commands
new file mode 100644
index 0000000..6508b5f
--- /dev/null
+++ b/doc/sefun/enable_commands
@@ -0,0 +1,26 @@
+SYNOPSIS
+        void enable_commands();
+
+BESCHREIBUNG
+        Erlaubt dem Objekt, Kommandos zu verwenden, die normalerweise Usern
+        zugaenglich sind. Der Aufruf markiert das Objekt als "living". Dies
+        wird fuer Spieler und alle von /std/npc abgeleiteten Objekte
+        bereits von der Mudlib erledigt und sollte nicht nochmals gemacht
+        werden.
+
+        Diese Funktion darf nicht ausserhalb von create() (oder reset(0) im
+        Compat-Modus) aufgerufen werden, weil der Kommandogeber auf dieses
+        Objekt gesetzt wird.
+
+BEISPIEL
+        void create()
+        {
+            enable_commands();
+            ...
+        }
+
+        Dies markiert das Objekt als "living".
+
+SIEHE AUCH
+        command(E), living(E), disable_commands(E), native(C), hooks(C)
+        set_living_name(E)
diff --git a/doc/sefun/file_time b/doc/sefun/file_time
new file mode 100644
index 0000000..6c24baa
--- /dev/null
+++ b/doc/sefun/file_time
@@ -0,0 +1,5 @@
+FUNKTION:
+	int file_time(string filename);
+
+Liefert den Zeitpunkt der letzten Modifikation des Files in Sekunden seit
+dem 1.1.1970, 0:00. Kann per ctime() in ein lesbares Format gebracht werden.
diff --git a/doc/sefun/find_living b/doc/sefun/find_living
new file mode 100644
index 0000000..106dd63
--- /dev/null
+++ b/doc/sefun/find_living
@@ -0,0 +1,22 @@
+SYNOPSIS:
+        object find_living(string str)
+
+BESCHREIBUNG:
+        Findet das erste "lebende" Objekt, welches per set_living_name() den
+        Namen <str> setzte.
+        
+        Das Objekt muss ausserdem per enable_commands() als Lebewesen
+        markiert worden sein. Dies ist fuer alle von /std/npc erbenden NPCs
+        _automatisch_ der Fall und sollte daher nicht nochmal explizit gemacht
+        werden.
+
+BEISPIEL:
+        object ob;
+        ob = find_living("Public Enemy");
+
+SIEHE AUCH:
+        find_player(E), enable_commands(E), set_living_name(E)
+
+LETZTE AeNDERUNG:
+09.10.2011, Zesstra
+
diff --git a/doc/sefun/find_livings b/doc/sefun/find_livings
new file mode 100644
index 0000000..cc9228f
--- /dev/null
+++ b/doc/sefun/find_livings
@@ -0,0 +1,24 @@
+FUNKTION:
+        object *find_livings(string name)
+
+ARGUMENTE:
+        name - der living_name der gesuchten Lebewesen
+
+BESCHREIBUNG:
+        Diese Funktion liefert ein Array mit allen Lebewesen, die den gleichen
+        living_name haben.
+
+RUECKGABEWERT:
+        Array mit den Lebewesen oder 0, wenn es kein Lebewesen diesen Namens
+        gibt.
+
+BEISPIELE:
+        ob = find_livings("herkules");
+        => ob = ({ [/human:herkules], 
+                   [/d/inseln/wargon/luftschloss/mon/herkules] })
+
+SIEHE AUCH:
+        find_living(E), set_living_name(E), find_player(E), find_netdead(E)
+
+LETZTE AENDERUNG:
+19. Okt. 2015, Arathorn
diff --git a/doc/sefun/find_netdead b/doc/sefun/find_netdead
new file mode 100644
index 0000000..d44ee9e
--- /dev/null
+++ b/doc/sefun/find_netdead
@@ -0,0 +1,25 @@
+FUNKTION:
+        object find_netdead(string name)
+
+ARGUMENTE:
+        name - Name des gesuchten Spielers
+
+BESCHREIBUNG:
+        Falls der Spieler name netztot ist, liefert diese Funktion das Spieler-
+        objekt zurueck.
+
+        Akzeptiert auch die UUID statt einer UID. In diesem Fall erfolgt aber
+        nur eine Pruefung, ob die UID des gefundenen Spielers zur angegebenen
+        UUID passt (d.h. "jof_-1" wuerde dann ggf. auch das Spielerobjekt Jof
+        zurueckliefern, wenn das die UUID "Jof_1234" hat).
+
+
+RUECKGABEWERT:
+        Der netztote Spieler oder 0, falls es keinen Netztoten diesen Namens
+        gibt.
+
+SIEHE AUCH:
+        find_living(E), find_player(E)
+
+LETZT AeNDERUNG:
+06.01.2009, Zesstra
diff --git a/doc/sefun/find_player b/doc/sefun/find_player
new file mode 100644
index 0000000..57c85f3
--- /dev/null
+++ b/doc/sefun/find_player
@@ -0,0 +1,42 @@
+FUNKTION:
+        object find_player(string uid)
+
+BESCHREIBUNG:
+        Findet den Spieler mit dem Namen bzw. der User-ID <uid>.
+        
+        Akzeptiert auch die UUID statt einer UID. In diesem Fall erfolgt aber
+        nur eine Pruefung, ob die UID des gefundenen Spielers zur angegebenen
+        UUID passt (d.h. "jof_-1" wuerde dann ggf. auch das Spielerobjekt Jof
+        zurueckliefern, wenn das die UUID "Jof_1234" hat).
+
+        Rueckgabewert ist das Spielerobjekt (wenn Spieler anwesend),
+        ansonsten 0.
+
+BEISPIEL:
+
+        object ob;
+        ob = find_player("deepthought");
+
+        if(ob)
+          tell_object(ob,"Tach Du!\n");
+
+        oder auch 
+
+        if(ob = find_player("deepthought"))
+          tell_object(ob,"Tach Du!\n");
+
+ANMERKUNGEN:
+
+        Via find_player() werden auch unsichtbare Magier gefunden. In 
+        Objekten, die fuer Spieler gedacht sind, muss dies dann extra
+        per Abfrage auf if(ob->QueryProp(P_INVIS)) getestet werden.
+
+        Netztote Spieler und Monster werden nicht gefunden da find_player
+        den Namen aus set_living_name() verwendet, der in player.c ge-
+        setzt wird.
+        
+SIEHE AUCH:
+        find_living(E), set_living_name(E), find_object(E), find_netdead(E)
+
+----------------------------------------------------------------------------
+Letzte Aenderung: 06.01.2009, Zesstra 
diff --git a/doc/sefun/getuuid b/doc/sefun/getuuid
new file mode 100644
index 0000000..5b34343
--- /dev/null
+++ b/doc/sefun/getuuid
@@ -0,0 +1,17 @@
+SYNOPSIS:
+    string getuuid(object ob)
+
+DESCRIPTION:
+    Liefert eine eindeutige (get unique uid) UID fuer einen Spieler.
+    Wird zusammengesetzt aus der UID des Spielers und seinem
+    Erstlogin-Datum.
+
+    Nach einer Selbstloeschung und neuem Login erhaelt der Spieler eine
+    neue UUID, bei einer Restaurierung behaelt er seine alte UUID.
+
+    Wenn die Funktion ohne Parameter aufgerufen wird, wird per Default
+    this_object() genommen.
+    
+
+SEE ALSO:
+        getuid(E)
diff --git a/doc/sefun/iso2ascii b/doc/sefun/iso2ascii
new file mode 100644
index 0000000..fe7757a
--- /dev/null
+++ b/doc/sefun/iso2ascii
@@ -0,0 +1,17 @@
+FUNKTION:
+	public string iso2ascii( string str );
+
+ARGUMENTE:
+	str
+	  String, in welchem Zeichen ersetzt werden sollen.
+
+BESCHREIBUNG:
+	In dem String werden alle Nicht-ASCII-Zeichen durch ASCII-Zeichen
+	ersetzt, und zwar Umlaute in der bekannten Form und alle anderen
+	durch ein Fragezeichen.
+
+RUeCKGABEWERT:
+	String mit ASCII-Zeichen.
+
+----------------------------------------------------------------------------
+Last modified: Fri Jul  6 19:36:09 2001 by Patryn
diff --git a/doc/sefun/log_file b/doc/sefun/log_file
new file mode 100644
index 0000000..cf7e03b
--- /dev/null
+++ b/doc/sefun/log_file
@@ -0,0 +1,31 @@
+FUNKTION:
+	int log_file(string file, string text)
+  int log_file(string file, string text, int size_to_break)
+
+ARGUMENTE:
+	file - Name der Datei, in die geschrieben werden soll
+	text - Der Text, der geschrieben werden soll
+	size_to_break - Groesse, ab der ein neues File begonnen wird (optional)
+
+BESCHREIBUNG:
+	log_file schreibt den Text text in die Datei /log/file.
+
+RUECKGABEWERT:
+	1 bei Erfolg oder 0, falls ein Fehler beim Schreiben auftrat.
+
+BEMERKUNGEN:
+	Wenn die Groesse von file vor dem Schreiben 50000 Bytes ueberschreitet,
+	wird sie in file.old umbenannt. Eine schon vorhandene Datei file.old
+	wird dabei geloescht. Der Text wird nach dem Umbenennen geschrieben.
+	Wird 'size_to_break' angegeben und ist dies > 0, wird dieser Wert (in 
+	Bytes) statt der 50000 Bytes zum Rotieren des Logfiles benutzt.
+
+BEISPIELE:
+	log_file( "report/wargon.rep", "TYPO von bla in blubb:\ntest\n");
+	In /log/report/wargon.rep finde ich nun die neueste Typomeldung... ;)
+
+SIEHE AUCH:
+	write_file(E)
+
+09.06.2014, Zesstra
+
diff --git a/doc/sefun/lowerchar b/doc/sefun/lowerchar
new file mode 100644
index 0000000..0ec62bf
--- /dev/null
+++ b/doc/sefun/lowerchar
@@ -0,0 +1,20 @@
+FUNKTION:
+	int lowerchar(int char)
+
+ARGUMENTE:
+	char - Das umzuwandelnde Zeichen
+
+BESCHREIBUNG:
+	Wenn char ein Grossbuchstabe ist, so wird es in einen Kleinbuchstaben
+	umgewandelt. Andere Zeichen werden von dieser Funktion nicht beein-
+        flusst.
+
+RUECKGABEWERT:
+	Das umgewandelte Zeichen.
+
+BEISPIELE:
+	printf("%c\n", lowerchar('A')); => a
+	printf("%c\n", lowerchar('1')); => 1
+
+SIEHE AUCH:
+	lower_case(E), lowerstring(E), upperstring(E), capitalize(E)
diff --git a/doc/sefun/lowerstring b/doc/sefun/lowerstring
new file mode 100644
index 0000000..30748fc
--- /dev/null
+++ b/doc/sefun/lowerstring
@@ -0,0 +1,20 @@
+FUNKTION:
+	string lowerstring(string str)
+
+ARGUMENTE:
+	str - Der umzuwandelnde String.
+
+BESCHREIBUNG:
+	Alle Grossbuchstaben in str werden in Kleinbuchstaben umgewandelt.
+
+RUECKGABEWERT:
+	Der umgewandelte String.
+
+BEMERKUNGEN:
+	lowerstring ist mit lower_case identisch!
+
+BEISPIELE:
+	s = lowerstring("So, McLaud...\n"); => s = "so, mclaud...\n"
+
+SIEHE AUCH:
+	lower_case(E), lowerchar(E), upperstring(E), capitalize(E)
diff --git a/doc/sefun/m_copy_delete b/doc/sefun/m_copy_delete
new file mode 100644
index 0000000..cb1c97b
--- /dev/null
+++ b/doc/sefun/m_copy_delete
@@ -0,0 +1,43 @@
+FUNKTION:
+	mapping m_copy_delete(mapping map, mixed key)
+
+ARGUMENTE:
+	map - das Mapping, aus dem geloescht werden soll.
+	key - der zu loeschende Eintrag
+
+BESCHREIBUNG:
+	Aus dem Mapping map wird der Eintrag key geloescht (wenn er in map vor-
+	handen ist). map wird dabei nicht veraendert.
+
+RUECKGABEWERT:
+	Eine (flache !) Kopie von map ohne den Eintrag key, d.h. enthaltene
+	Mappings/Arrays werden nicht kopiert.
+
+BEMERKUNGEN:
+	Das urspruengliche Mapping wird bei dieser Operation nicht veraendert!
+	Wenn man nur einen Wert aus dem Mapping loeschen will und die Kopie nicht
+	braucht, bietet sich efun::m_delete(mapping,key) sehr an, da die Erstellung
+  einer Kopie sehr aufwendig sein kann.
+
+BEISPIELE:
+	mapping m1, m2;
+
+        m1 = ([ "a":1, "b":2, "c":3 ]);
+
+        m2 = m_copy_delete(m1, "b");
+           => m1 = ([ "a":1, "b":2, "c":3 ])
+	      m2 = ([ "a":1, "c":3 ])
+
+        m_copy_delete(m1, "a");
+           => (es hat sich nichts geaendert)
+
+        m1 = m_copy_delete(m1, "a");
+           => m1 = ([ "b":2, "c":3 ])
+
+        Im letzten Fall sollte aber besser efun::m_delete(m1, "a") benutzt 
+        werden, da ansonsten das Mapping unnoetig kopiert wird und Rechen-
+        leistung frisst. 
+
+SIEHE AUCH:
+  efun::m_delete(E), mappingp(E), mkmapping(E), m_indices,(E) m_values(E),
+  sizeof(E), widthof(E)
diff --git a/doc/sefun/match_living b/doc/sefun/match_living
new file mode 100644
index 0000000..44801a8
--- /dev/null
+++ b/doc/sefun/match_living
@@ -0,0 +1,30 @@
+match_living(sefun)
+FUNKTION:
+     varargs mixed match_living( string str, int players_only,
+				 string *exclude)
+
+ARGUMENTE:
+     string str		- Kuerzel, nach dem die living_names durchsucht
+			  werden soll
+     int players_only	- 1, um nur Spieler (Interactives) zu suchen
+     string *exlude	- welche Namen sollen ignoriert werden
+
+
+BESCHREIBUNG:
+     Sucht alle Lebewesen, deren Namen mit str beginnen.
+
+RUECKGABEWERT:
+     Ein String, falls es ein Lebewesen mit dem Namen str gibt (der Name
+     muss genau passen).
+     -1, wenn es mehrere Lebewesen gibt, deren Namen mit str beginnen.
+     -2, wenn es kein Lebewesen gibt, dessen Name mit str beginnt.
+
+BEISPIELE:
+     match_living("wargon"); => "wargon", wenn Wargon eingeloggt ist.
+     match_living("war");    => "wargon", wenn es kein anderes Lebewesen
+                                gibt, dessen Name mit "war" beginnt.
+
+SIEHE AUCH:
+     find_living(E), find_player(E), find_netdead(E)
+
+27. Mai 2004 Gloinson
diff --git a/doc/sefun/md5 b/doc/sefun/md5
new file mode 100644
index 0000000..1e65090
--- /dev/null
+++ b/doc/sefun/md5
@@ -0,0 +1,30 @@
+DEPRECATED
+SYNOPSIS
+        string md5 (string arg [ , int iterations ] )
+        string md5 (int *  arg [ , int iterations ] )
+
+BESCHREIBUNG
+        Berechnet den MD5-Hashwert von <arg>.
+        Das Argument kann ein String, oder ein Array von Zahlen sein (von
+        welchen nur das unterste Byte betrachted wird).
+
+        Das Ergebnis wird als 32-stelliger Hexadezimalwert geliefert.
+
+        Ist das <iterations> Argument eine Zahl groesser 0, berechnet der
+        Driver den Digest mit diese Anzahl an Wiederholungen. Fehlt die
+        Angabe, fuehrt der Driver die Digest-Berechnung einmal aus.
+
+BEISPIEL
+        string s;
+
+        s = md5("Hallo");
+        s = md5( ({ 'H', 'e', 'l', 'l', 'o' }) )
+        s = md5( ({ 'H', 'e', 'l', 'l', 'o' }), 2 )
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.9
+        LDMud 3.2.12 fuehrte Zaehlenarrays als Argument ein, also auch
+          die Anzahl der Wiederholungen.
+
+SIEHE AUCH
+        crypt(E), md5_crypt(E), sha1(E), hash(E), hmac(E)
diff --git a/doc/sefun/mkdirp b/doc/sefun/mkdirp
new file mode 100644
index 0000000..a05d4e6
--- /dev/null
+++ b/doc/sefun/mkdirp
@@ -0,0 +1,21 @@
+FUNKTION:
+        int mkdirp(string dir)
+
+ARGUMENTE:
+        dir - Name des zu erstellenden Verzeichnisses (absolut)
+
+BESCHREIBUNG:
+        Erzeugt das Verzeichnis <dir>. Dies muss als abs. Pfad angegeben
+        werden.
+        Wenn noetig, wird die ganze Verzeichnishierarchie rekursiv erstellt.
+        
+RUECKGABEWERT:
+        0 - Verzeichnis konnte nicht erstellt werden
+        1 - Verzeichnis wurde erstellt oder existierte bereits
+
+SIEHE AUCH:
+        mkdir(E)
+
+LETZT AeNDERUNG:
+26.01.2013, Zesstra
+
diff --git a/doc/sefun/notify_fail b/doc/sefun/notify_fail
new file mode 100644
index 0000000..1970367
--- /dev/null
+++ b/doc/sefun/notify_fail
@@ -0,0 +1,85 @@
+FUNKTION:
+     #include <notify_fail.h>
+
+     varargs void notify_fail(string str, int prio)
+     varargs void notify_fail(closure cl, int prio)
+
+ARGUMENTE:
+     str   Meldung die an den Spieler anstatt des 'Wie bitte' ausgegeben
+           werden soll
+     cl    Closure, die bei Fehlschlag ausgefuehrt werden soll
+     prio  Prioritaet dieses Objekts bei diesem Setzen der Meldung
+
+BESCHREIBUNG:
+     Merkt sich den angegebenen str und gibt ihn im Falle einer inkorrekten
+     Eingabe des Spielers anstatt eines 'Wie bitte' aus.
+
+     Gedacht ist notify_fail, um dem Spieler eine bessere Hilfestellung
+     bei Kommandos / Eingaben zu geben, um ihn u.U. auf die richtige
+     Syntax hinzuweisen.
+
+     Wird notify_fail mehrfach (durch verschiedene Objekte o.ae.) auf-
+     gerufen, wird der letzte erfolgreiche Aufruf gewertet. Eine Meldung wird
+     dann tatsaechlich gesetzt, wenn die Prioritaet dieses Objekts gleich
+     gross oder groesser ist als die Prioritaet des Objekts, was das bisher
+     gueltige notify_fail() gesetzt hat. Folgende Prioritaeten sind
+     vordefiniert und werden automatisch ermittelt:
+     NF_NL_OWN    100         // eigenes Objekt (soul) ueberschreibt kaum was
+     NF_NL_THING  100000
+     NF_NL_ROOM   1000000     // Raeume ueberschreiben sonstigen Krams
+     NF_NL_LIVING 10000000    // Lebewesen ueberschreiben auch Raeume
+     2 weitere vordefinierte koennen von Magier angegeben werden:
+     NF_NL_NONE   -1          // wird von allem ueberschrieben
+     NF_NL_MAX    __INT_MAX__ // hoechste Prioritaet, ueberschreibt alles
+
+     Wird eine Closure als Argument gegeben, wird sie im Fehlerfall
+     (also erst wenn ein Kommando endgueltig fehlgeschlagen hat)
+     ausgefuehrt und hat die Fehlermeldung als Resultat
+     zurueckzugeben. Die Closure erhaelt als Argument den
+     originalen Befehlsgeber; in der Regel dies ist this_player(),
+     was aber vom MODIFY_CMD hook geaendert werden kann.
+
+     notify_fail() erkennt verschachtelte Kommandos (siehe Efun
+     command()), und ein notify_fail() in einem Unterkommando
+     hat keinen Einfluss auf das uebergeordnete Kommando.
+
+BEMERKUNGEN:
+     - solange man sich nicht absolut sicher ist, dass ein bestimmtes Objekt
+       mit dem Kommando gemeint ist (Identifikation ueber id()), sollte man
+       - notify_fail(str); return 0;
+       nutzen anstatt mit
+       - write(str) return 1;
+       die Kommandoauswertung abzubrechen (und anderen Objekten die Chance
+       zu nehmen das Kommando zu erfuellen)
+     - Kommandos werden uebrigens oft erst vom betretenen Raum, dann von den
+       Objekten abgearbeitet (je nachdem wann diese dazukamen)
+     - die Prioritaet wird momentan nicht gespeichert, sie ist nur beim Setzen
+       relevant. Will spaeter ein anderes Objekt eine Meldung setzen, wird
+       fuer das eigene Objekt die Standardprioritaet ermittelt, auch wenn man
+       eine andere hier uebergeben hat
+     - Die NF_NL_* sind in /sys/notify_fail.h defniert.
+
+BEISPIELE:
+     Ein Raum erwartet die korrekte Eingabe von 'iss suppe':
+
+     int iss_cmd(string str){
+       // zu Anfang der Funktion das notify_fail definieren
+       notify_fail("Moechtest Du vielleicht von der Suppe essen?\n");
+
+       // Spieler hat nur 'iss' ohne Parameter eingegeben oder einen anderen
+       // Parameter angegeben ... Abbruch!
+       // Falls kein weiteres Objekt das Kommando erfuellt oder das
+       // notify_fail() mit einer eigenen Meldung ueberschreibt, wird obige
+       // Meldung an den Spieler ausgegeben.
+
+       if(!str || str!="suppe") return 0;
+       // ab hier ist die Eingabe dann wirklich 'suppe' und die Funktion
+       // kann beliebig fortgefuehrt werden
+       ...
+       return   1;
+
+SIEHE AUCH:
+     add_action(E), AddCmd(L), AddAction(L),
+     query_verb(E), query_notify_fail(E)
+
+8.Aug 2007 Gloinson
diff --git a/doc/sefun/object_info b/doc/sefun/object_info
new file mode 100644
index 0000000..3945651
--- /dev/null
+++ b/doc/sefun/object_info
@@ -0,0 +1,129 @@
+DEPRECATED
+SYNOPSIS
+        #include <objectinfo.h>
+
+        mixed * object_info(object ob, int what)
+        mixed * object_info(object ob, int what, int index)
+
+DESCRIPTION
+        Returns some internal information about object <ob>, collected
+        in an array. Argument <what> determines which information is
+        returned.
+
+        The result is usually an array. However, if <index> is specified,
+        the result is the value from position <index> of the array which
+        would have been returned normally.
+
+        The possible values of <what>, and the indices of the returned
+        arrays are defined in the include file <objectinfo.h>, and may
+        change in future versions of the driver!
+
+
+        <what> == OINFO_BASIC:
+
+          This call returns basic information about <ob>:
+
+          int [OIB_HEART_BEAT]:       1 if <ob> has a heart_beat, 0 else.
+          int [OIB_IS_WIZARD]:        1 if <ob> has the wizard flag set,
+                                        0 else.
+            This entry is always 0 when set_is_wizard() is not available.
+          int [OIB_ENABLE_COMMANDS]:  1 if <ob> can give commands, 0 else.
+          int [OIB_CLONE]:            1 if <ob> is a clone, 0 else.
+          int [OIB_DESTRUCTED]:       1 if <ob> is destructed, 0 else.
+          int [OIB_SWAPPED]:          1 if <ob> is swapped, 0 else.
+          int [OIB_ONCE_INTERACTIVE]: 1 if <ob> was once interactive, 0 else.
+          int [OIB_RESET_STATE]:      1 if <ob> is (still) reset, 0 else.
+          int [OIB_WILL_CLEAN_UP]:    1 if <ob> will call clean_up(), 0 else.
+          int [OIB_LAMBDA_REFERENCED]: 1 if <ob> has lambdas, 0 else.
+          int [OIB_SHADOW]:           1 if <ob> has a shadow structure tied
+                                        to it, 0 if not.
+          int [OIB_REPLACED]:         1 if the program for <ob> was replaced,
+                                      0 else.
+          int [OIB_NEXT_RESET]:   time of the next reset
+          int [OIB_TIME_OF_REF]:  time of the last call to <ob>
+          int [OIB_NEXT_CLEANUP]: time of the next data cleanup
+          int [OIB_REF]:          number of references to <ob>
+          int [OIB_GIGATICKS] and [OIB_TICKS]: together, these numbers
+            give the accumulated evaluation cost spend in <ob>
+          int [OIB_SWAP_NUM]:     the swap number for <ob>s program,
+                                  or -1 if not swapped.
+          int [OIB_PROG_SWAPPED]: 1 if <ob>'s program is swapped, 0 else.
+          int [OIB_VAR_SWAPPED]:  1 if <ob>'s variables are swapped, 0 else.
+          int [OIB_NAME]:         <ob>'s object name.
+          int [OIB_LOAD_NAME]:    <ob>'s load name.
+          object [OIB_NEXT_ALL]:  next object in the object list.
+          object [OIB_PREV_ALL]:  previous object in the object list.
+
+
+        <what> == OINFO_POSITION:
+
+          This call returns information about <ob>'s position in the
+          global list of objects:
+
+          object [OIP_NEXT]: next object in the object list.
+          object [OIP_PREV]: previous object in the object list.
+          int    [OIP_POS]:  position of <ob> in list, counting from 0 up.
+
+          This call can be expensive in computing time.
+
+
+        <what> == OINFO_MEMORY:
+
+          This call returns information about the program <ob> uses:
+
+          int    [OIM_REF]:            number of references to the program.
+          string [OIM_NAME]:           name of program.
+          int    [OIM_PROG_SIZE]:      size of the program.
+          int    [OIM_NUM_FUNCTIONS]:  number of functions in the program.
+          int    [OIM_SIZE_FUNCTIONS]: size needed for the function structs.
+          int    [OIM_NUM_VARIABLES]:  number of variables in the program.
+          int    [OIM_SIZE_VARIABLES]: size needed for the variable structs.
+          int    [OIM_NUM_STRINGS]:    number of strings in the program.
+          int    [OIM_SIZE_STRINGS]:   size needed for the string pointers.
+          int    [OIM_SIZE_STRINGS_DATA]: size needed for the string data,
+                                       scaled down according to the extend of
+                                       data sharing.
+          int    [OIM_SIZE_STRINGS_TOTAL]: unmodified size needed for the
+                                       string data.
+          int    [OIM_NUM_INCLUDES]:   number of included files in the program.
+          int    [OIM_NUM_INHERITED]:  number of inherited programs.
+          int    [OIM_SIZE_INHERITED]: size needed for the inherit structs.
+          int    [OIM_TOTAL_SIZE]:     total size of the program.
+          int    [OIM_DATA_SIZE]:      total size of the values held in the
+                                       object's variables, scaled down
+                                       according to the extend of data
+                                       sharing.
+          int    [OIM_DATA_SIZE_TOTAL]: unmodified total size of the values
+                                       held in the object's variables
+          int    [OIM_NO_INHERIT]:     1 if the program can't be inherited.
+          int    [OIM_NO_CLONE]:       1 if the program/blueprint can't be
+                                       cloned.
+          int    [OIM_NO_SHADOW]:      1 if the program's functions can't be
+                                       shadowed.
+          int    [OIM_SHARE_VARIABLES]:  1 if clones of this program share
+                                       their initial variable values with
+                                       the blueprint.
+
+          This call swaps in the program if necessary.
+          Note that the OIM_SIZE_xxx entries only give the size spent on
+          the structures and pointers, not the size of the variable data,
+          function code, and strings themselves.
+
+HISTORY
+        Introduced in LDMud 3.2.6.
+        Changes in LDMud 3.2.7:
+          - new basic result OIB_REPLACED.
+          - basic result OIB_IS_WIZARD is always 0 if set_is_wizard()
+              is not available.
+          - basic result OIB_APPROVED is gone.
+        LDMud 3.2.8 added OIM_DATA_SIZE to the result of OINFO_MEMORY.
+        LDMud 3.2.9 added the index mechanism, OIM_NUM_INCLUDES,
+          OIM_NO_INHERIT, OIM_NO_SHADOW, OIM_NO_CLONE, OIM_SIZE_STRINGS_DATA,
+          OIM_SIZE_STRINGS_TOTAL, and OIM_DATA_SIZE_TOTAL to the result
+          of OINFO_MEMORY.
+        LDMud 3.3.378 added the OIM_SHARE_VARIABLES to the result
+          of OINFO_MEMORY.
+        LDMud 3.3.654 added the OIB_NEXT_CLEANUP to the result of OINFO_BASIC.
+
+SEE ALSO
+        debug_info(E)
diff --git a/doc/sefun/obsolete/exclude_alist b/doc/sefun/obsolete/exclude_alist
new file mode 100644
index 0000000..a967a14
--- /dev/null
+++ b/doc/sefun/obsolete/exclude_alist
@@ -0,0 +1,4 @@
+SYNOPSIS:
+	mixed *exclude_alist(int i, mixed *alist)
+
+Remove element i from alist.
diff --git a/doc/sefun/obsolete/remove_alist b/doc/sefun/obsolete/remove_alist
new file mode 100644
index 0000000..cf9bc61
--- /dev/null
+++ b/doc/sefun/obsolete/remove_alist
@@ -0,0 +1,3 @@
+mixed *remove_alist(mixed key, mixed *alist)
+
+Removes element associated by key key from alist.
diff --git a/doc/sefun/old_explode b/doc/sefun/old_explode
new file mode 100644
index 0000000..6b13d8e
--- /dev/null
+++ b/doc/sefun/old_explode
@@ -0,0 +1,28 @@
+FUNKTION:
+	string *old_explode(string str, string del)
+
+ARGUMENTE:
+	str - Der String, der aufgespaltet werden soll.
+	del - Der String, nach dem str aufgespalten werden soll.
+
+BESCHREIBUNG:
+	Durch Ausschneiden von del wird der String str in ein Array von Strings
+	zerlegt. Dieses Array wird anschliessend zuruckgegeben.
+
+RUECKGABEWERT:
+	Das Array mit den Bestandteilen der Zerlegung.
+
+BEMERKUNGEN:
+	Das Verhalten von old_explode() entspricht dem dem explode()-Verhalten,
+	das in /doc/efun/explode als "altes" Verhalten bezeichnet wird, d.h.
+	Leerstrings an Anfang und Ende des zerlegten Strings werden entfernt!
+
+BEISPIELE:
+	strs = explode( "nimm alles", " "); => strs = ({ "nimm", "alles" })
+	strs = explode( "abc", "abc" );     => strs = ({ })
+	strs = explode( "ein test", "" );   => strs = ({ "ein test" })
+	strs = explode( "a b", "a");        => strs = ({ " b" });
+
+SIEHE AUCH:
+	explode(E), new_explode(E), efun::explode(E), sscanf(E)
+        implode(E), regexplode(E)
diff --git a/doc/sefun/process_call b/doc/sefun/process_call
new file mode 100644
index 0000000..c00a039
--- /dev/null
+++ b/doc/sefun/process_call
@@ -0,0 +1,21 @@
+simul_efun::process_call(E)
+FUNKTION:
+     int process_call()
+
+BESCHREIBUNG:
+     Gibt zurueck, ob die Ausfuehrung zum derzeitigen Zeitpunkt durch
+     process_string() ausgerufen wurde.
+
+BEISPIELE:
+     process_string("@@current_long@@");
+     ...
+     string current_long() {
+      if(process_call())
+       return("Dieser String wurde durch ein process_string eingefuegt.");
+      else return("Du hast die Funktion direkt gerufen!");
+     }
+
+SIEHE AUCH:
+     notify_fail(E), process_string(E), replace_personal(E)
+
+28. Maerz 2004 Gloinson
diff --git a/doc/sefun/process_string b/doc/sefun/process_string
new file mode 100644
index 0000000..75c9290
--- /dev/null
+++ b/doc/sefun/process_string
@@ -0,0 +1,57 @@
+process_string(E)
+FUNKTION:
+     string process_string(string str)
+     string process_string(closure cl)
+
+BESCHREIBUNG:
+     Durchsucht den String str nach Vorkommnissen von Substrings, die "Wert
+     durch Funktionsaufruf zu ersetzen" andeuten. Die Form ist: @@, gefolgt
+     durch einen impliziten Funktionsaufruf.
+
+     Der zu ersetzenden Substring hat die Form:
+     @@function[:filename][|argument1|argument2]@@
+
+     Die entsprechende Funktion muss einen String zurueckgeben, oder der
+     process_string() uebergebene String str wird nicht modifiziert.
+
+     process_string() arbeitet nicht rekursiv, object_name und argument sind
+     optionale Werte.
+
+     Falls eine Closure angegeben wurde, wird diese lediglich gerufen
+     und nicht gefiltert.
+
+ANMERKUNGEN:
+     - Die Funktion, die gerufen werden soll, _muss_ mit einem Buchstaben
+		   anfangen, '_' ist nicht moeglich!
+     - folgendes Properties und Details werden bei der Abfrage ueber
+       process_string() gefiltert:
+       P_LONG, P_SHORT, P_READ_MSG, AddReadDetail()-Details und NPC-Chats
+       P_INT_LONG ueber int_long(), P_INT_SHORT ueber int_short()
+     - die Nutzung kann zu Sicherheitsproblemen fuehren, siehe auch
+       process_call()
+
+BEISPIEL:
+     // komplette Ersetzung ...
+     SetProp(P_LONG,"@@current_long@@");
+     ...
+     string current_long() {
+      if(x) return(break_string("Die Beschreibung."));
+      else return(break_string("Die andere Beschreibung."));
+     }
+
+     -> bei Abfrage: "Die Beschreibung." oder "Die andere Beschreibung."
+
+
+     // Teilersetzung
+     SetProp(P_SHORT, "Ein @@farbenfun|huebsch@@ Ding");
+     ...
+     string farbenfun(string str) {
+      return(str+" "+"gelbes");
+     }
+
+     -> bei Abfrage: "Ein huebsch gelbes Ding."
+
+SIEHE AUCH:
+     notify_fail(E), process_call(E), replace_personal(E)
+
+22. Nov. 2006 Arathorn
diff --git a/doc/sefun/query_editing b/doc/sefun/query_editing
new file mode 100644
index 0000000..010c98e
--- /dev/null
+++ b/doc/sefun/query_editing
@@ -0,0 +1,13 @@
+DEPRECATED
+SYNOPSIS
+        mixed query_editing(object ob);
+
+BESCHREIBUNG
+        Liefert 1, wenn <ob> interaktiv ist (das heisst, es gibt einen realen
+        Benutzer mit einer Socketverbindung zum Mud) und gerade mit ed() eine
+        Datei bearbeitet. Wenn ed() mit einem Funktionsnamen als zweites
+        Argument aufgerufen wird, wird das Objekt, aus dem ed() aufgerufen
+        wurde, geliefert, sonst 0.
+
+SIEHE AUCH
+        ed(E)
diff --git a/doc/sefun/query_idle b/doc/sefun/query_idle
new file mode 100644
index 0000000..7c0a0a5
--- /dev/null
+++ b/doc/sefun/query_idle
@@ -0,0 +1,8 @@
+SYNOPSIS
+        int query_idle(object ob);
+
+BESCHREIBUNG
+        Gibt an, seit wie vielen Sekunden ein Player Objekt <ob> idle ist.
+
+SIEHE AUCH
+        interactive(E)
diff --git a/doc/sefun/query_input_pending b/doc/sefun/query_input_pending
new file mode 100644
index 0000000..8033cec
--- /dev/null
+++ b/doc/sefun/query_input_pending
@@ -0,0 +1,11 @@
+DEPRECATED
+SYNOPSIS
+        object query_input_pending(object ob);
+
+BESCHREIBUNG
+        Wenn <ob> interaktiv und ein input_to() haengig ist, so liefert die
+        Efun das Objekt zurueck, welches den input_to() aufgerfuen hat. Ist
+        kein input_to() haengig, liefert die Funktion 0.
+
+SIEHE AUCH
+        input_to(E), find_input_to(E), input_to_info(E), remove_input_to(E)
diff --git a/doc/sefun/query_ip_name b/doc/sefun/query_ip_name
new file mode 100644
index 0000000..d16298f
--- /dev/null
+++ b/doc/sefun/query_ip_name
@@ -0,0 +1,12 @@
+GESCHUETZT
+SYNOPSIS
+        string query_ip_name(object ob);
+
+BESCHREIBUNG
+        Liefert den IP-Namen des Users <ob> oder des aktuellen Benutzers, wenn
+        <ob> nicht angegeben wurde. Der IP-Name wird durch den asynchronen
+        Prozess hname ermittelt. Wenn der IP-Name nicht ermittelt werden kann,
+        liefert query_ip_name() die IP-Nummer zurueck.
+
+SIEHE AUCH
+        query_ip_number(E)
diff --git a/doc/sefun/query_ip_number b/doc/sefun/query_ip_number
new file mode 100644
index 0000000..a462aba
--- /dev/null
+++ b/doc/sefun/query_ip_number
@@ -0,0 +1,24 @@
+GESCHUETZT
+SYNOPSIS
+        string query_ip_number(object ob);
+        string query_ip_number(mixed & ob);
+
+BESCHREIBUNG
+        Liefert die IP-Nummer des Benutzers <ob> oder des aktuellen Benutzers,
+        wenn <ob> nicht angegeben wurde.
+
+        Wenn <ob> als Referenz angegeben wird (dann muss es ein gueltiges
+        Objekt sein), wird dieses bei der Ausgabe auf die struct sockaddr_in
+        gesetzt. struct sockaddr_in ist ein Integer-Array, mit einem Integer
+        pro Adressbyte:
+
+            ob[0 .. 1] : sin_family
+            ob[2 .. 3] : sin_port
+            ob[4 .. 7] : sin_addr
+            ob[8 ..15] : nicht definiert.
+
+AENDERUNGEN
+        Die Rueckgabe von struct sockaddr_in wurde in 3.2.1@81 eingefuehrt.
+
+SIEHE AUCH
+        query_ip_name(E)
diff --git a/doc/sefun/query_limits b/doc/sefun/query_limits
new file mode 100644
index 0000000..954577a
--- /dev/null
+++ b/doc/sefun/query_limits
@@ -0,0 +1,56 @@
+DEPRECATED
+SYNOPSIS
+        #include <sys/rtlimits.h>
+
+        int *query_limits();
+        int *query_limits(int default);
+
+BESCHREIBUNG
+        Liefert ein Array mit den momentan gueltigen Laufzeit Limiten bzw.
+        die standardmaessigen Laufzeit Limiten, wenn <default> wahr ist.
+        Die Eintraege im gelieferten Array bedeuten:
+
+        int[LIMIT_EVAL]:        die maximalen Eval Kosten
+        int[LIMIT_ARRAY]:       die maximale Anzahl Array Eintraege
+        int[LIMIT_MAPPING]:     die maximale Anzahl Mapping Eintraege
+        int[LIMIT_BYTE]:        die maximale Anzahl Bytes, die mit read_bytes()
+                                /write_bytes() bearbeitet werden koennen
+        int[LIMIT_FILE]:        die maximale Anzahl Bytes, die mit read_file()
+                                /write_file() bearbeitet werden koennen
+        int[LIMIT_CALLOUTS]:    die maximale Anzahl gleichzeitiger call_out()s
+        int[LIMIT_COST]:        wie die aktuellen Kosten einzurechnen sind
+
+        Ausser fuer LIMIT_COST ein Limit von '0' (auch LIMIT_UNLIMITED)
+        bedeutet 'keine Limit'.
+
+        LIMIT_COST hat diese Bedeutungen:
+          
+          wert > 0: Maximal <wert> fuer als Kosten fuer die aktuelle Ausfuehrung
+                    verwendet, ungeachtet wie lange sie tatsaechlich dauert.
+               = 0: ist die derzeite LIMIT_EVAL groesser als die vorherige
+                    LIMIT_EVAL, kostet die aktuelle Ausfuehrung nur 10
+                    Ticks; andernfalls werden die gesamten Kosten angerechnet.
+                < 0: (-wert)% der aktuellen Ausfuehrungskosten werden
+                     angerechnet.
+
+BEMERKUNGEN:
+        "Aktuelle Kosten" bei LIMIT_COST hat im Falle der Benutzung von
+        limited() die Bedeutung von "im limited verbrauchte Kosten", steuert
+        also, wieviel der im Durchlaufen der Funktion im limited()
+        verbrauchten Ticks mit dem Ende von limited() angezogen wird.
+
+BEISPIELE
+        query_limits()
+        --> liefert die momentan gueltigen Laufzeit Limiten.
+        query_limits(1)
+        --> liefert die standardmaessigen Laufzeit Limiten.
+
+AENDERUNGEN
+        Eingefuehrt in LDMud 3.2.7.
+        LIMIT_CALLOUTS wurde in LDMud 3.2.9 eingefuehrt.
+
+SIEHE AUCH
+        limited(E), set_limits(E)
+
+16.05.2007, Zesstra
+
diff --git a/doc/sefun/query_mud_port b/doc/sefun/query_mud_port
new file mode 100644
index 0000000..2e5c6d2
--- /dev/null
+++ b/doc/sefun/query_mud_port
@@ -0,0 +1,23 @@
+DEPRECATED
+SYNOPSIS
+        int query_mud_port(void)
+        int query_mud_port(object user)
+        int query_mud_port(int num)
+
+DESCRIPTION
+        Returns the port number the parser uses for user connections.
+
+        If no argument is given, the port for this_player() is
+        returned. If this_player() is not existing or not interactive,
+        the first port number open for connections is returned.
+
+        If an user object is given, the port used for its connection
+        is returned.
+        If a positive number is given, the <num>th port number the
+        parser uses for connections is returned (given that there are
+        that many ports).
+        If -1 is given, the number of ports open for connections is
+        returned.
+
+SEE ALSO
+        query_udp_port(E)
diff --git a/doc/sefun/query_next_reset b/doc/sefun/query_next_reset
new file mode 100644
index 0000000..03bbd7e
--- /dev/null
+++ b/doc/sefun/query_next_reset
@@ -0,0 +1,27 @@
+simul_efun::query_next_reset(E)
+FUNKTION:
+     varargs int query_next_reset(object ob)
+
+ARGUMENTE:
+     ob - das interessierende Objekt; wenn nicht angegeben, wird 
+          this_object() verwendet
+
+BESCHREIBUNG:
+     Diese sefun gibt den Zeitpunkt des naechsten Resets des Objektes ob 
+     zurueck. Die Angabe erfolgt in Sekunden, die seit dem 01. Januar 1970 
+     00:00:00 GMT verstrichen sind, analog zu time().
+
+     In der Regel erfolgt der Reset im naechsten Backend-Zyklus nach dem 
+     Faelligkeitszeitpunkt,  d.h. momentan in den nachfolgenden 2s.
+     Allerdings kann dies auch mal nen Zyklus laenger dauern (4s), wenn der
+     Driver viel zu tun hat.
+
+BEMERKUNGEN:
+     Diese sefun ist object_info()-Abfragen vorzuziehen, da die Parameter und
+     Rueckgabewerte von object_info() bei verschiedenen Gamedriverversionen
+     variieren koennen.
+
+SIEHE AUCH:
+     call_out(E), object_info(E), reset(L), set_next_reset(E), time(E)
+
+28.07.2014 Arathorn
diff --git a/doc/sefun/query_once_interactive b/doc/sefun/query_once_interactive
new file mode 100644
index 0000000..c794223
--- /dev/null
+++ b/doc/sefun/query_once_interactive
@@ -0,0 +1,8 @@
+SYNOPSIS
+        int query_once_interactive(object obj);
+
+BESCHREIBUNG
+        Wahr, wenn <obj> interaktiv ist oder dies einmal war.
+
+SIEHE AUCH
+        remove_interactive(E)
diff --git a/doc/sefun/query_shadowing b/doc/sefun/query_shadowing
new file mode 100644
index 0000000..3ce5d6a
--- /dev/null
+++ b/doc/sefun/query_shadowing
@@ -0,0 +1,18 @@
+DEPRECATED
+query_shadowing(E)
+FUNKTION:
+     object query_shadowing(object obj)
+
+BESCHREIBUNG:
+     Die Funktion gibt das derzeit vom Objekt <obj> beschattete Objekt
+     victim oder 0 zurueck.
+
+BEISPIELE:
+     // B beschattet A
+     query_shadowing(find_object(B)) == A
+
+SIEHE AUCH:
+     Generell:	     shadow(E), unshadow(E)
+     Rechte:	     query_allow_shadow(M), query_prevent_shadow(L)
+
+23.02.2016, Zesstra
\ No newline at end of file
diff --git a/doc/sefun/query_snoop b/doc/sefun/query_snoop
new file mode 100644
index 0000000..4da8838
--- /dev/null
+++ b/doc/sefun/query_snoop
@@ -0,0 +1,10 @@
+DEPRECATED
+SYNOPSIS
+        object query_snoop(object victim)
+
+DESCRIPTION
+        Returns the user who currently snoops victim. The calling
+        object must be privileged by the master object.
+
+SEE ALSO
+        snoop(E)
diff --git a/doc/sefun/query_wiz_grp b/doc/sefun/query_wiz_grp
new file mode 100644
index 0000000..c45cfe1
--- /dev/null
+++ b/doc/sefun/query_wiz_grp
@@ -0,0 +1,15 @@
+FUNKTION:
+        query_wiz_grp(string wiz)
+        query_wiz_grp(object wiz)
+
+ARGUMENTE:
+        wiz - Spieler, dessen Magierlevelgruppe ermittelt werden soll
+
+BESCHREIBUNG:
+        Diese Funktion ermittelt die Magiergruppe, der der Spieler wiz angehoert.
+
+RUECKGABEWERT:
+        Die Magierlevelgruppe des Spielers.
+
+SIEHE AUCH:
+        /secure/wizlevels.h
diff --git a/doc/sefun/query_wiz_level b/doc/sefun/query_wiz_level
new file mode 100644
index 0000000..03e89cb
--- /dev/null
+++ b/doc/sefun/query_wiz_level
@@ -0,0 +1,43 @@
+FUNKTION:
+	int query_wiz_level(object ob)
+	int query_wiz_level(string ob)
+
+ARGUMENTE:
+	ob - Der Spieler/das Objekt, dessen Magierlevel ermittelt werden soll.
+       Es kann auch eine UID (z.B. "zesstra", "d.inseln.zesstra") als String
+       uebergeben werden.
+
+BESCHREIBUNG:
+	query_wiz_level() liefert den Magierlevel des Objekts ob zurueck.
+	Normale Spieler haben einen Magierlevel von 0, Seher normalerweise
+  einen von 1 (auf jeden Fall < 10).
+  Objekte bekommen folgende Level:
+  /d/           - 25
+  /p/           - 21
+  /obj/         - 0
+  /std/         - 0
+  /gilden/      - 30
+  /spellbooks/  - 30
+  /players/     - entsprechend Magier, 20 - 111
+  /secure/      - 100
+
+RUECKGABEWERT:
+	Der Magierlevel des Spielers/Objekts.
+
+BEMERKUNGEN:
+	Wird als Parameter ein String mit einem Spielernamen uebergeben, so 
+	kann auch der Magierlevel eines nicht eingeloggten Spielers heraus-
+	gefunden werden.
+
+BEISPIELE:
+	lv = query_wiz_level(find_player("jof"))
+	   => lv = 111, falls Jof eingeloggt ist.
+	lv = query_wiz_level("jof")
+           => lv = 111 in jedem Fall.
+
+SIEHE AUCH:
+	/secure/wizlevels.h
+
+LETZTE AeNDERUNG:
+15.10.2007, Zesstra
+
diff --git a/doc/sefun/replace_personal b/doc/sefun/replace_personal
new file mode 100644
index 0000000..2a18dc7
--- /dev/null
+++ b/doc/sefun/replace_personal
@@ -0,0 +1,84 @@
+FUNKTION:
+     varargs string replace_personal(string str, mixed *obs [, int caps]);
+
+DEFINIERT IN:
+     /secure/simul_efun.c
+
+ARGUMENTE:
+     str    - zu bearbeitender String
+     obs    - Liste von Objekt1, Objekt2, ..., Objekt9
+              (Objekte oder Strings)
+     caps   - 1 fuer Grossschreibung des Ersetzten nach Satzenden (.,?,!,")
+              0 sonst
+
+BESCHREIBUNG:
+     Ersetzt in Strings
+     @WERx, @WESSENx, @WEMx, @WENx durch
+        Objectx->name(<casus>, 1);
+     @WERUx, @WESSENUx, @WEMUx, @WENUx durch
+        Objectx->name(<casus>);
+     @WERQPx, @WESSENQPx, @WEMQPx, @WENQPx durch
+        Objectx->QueryPronoun(<casus>);
+     @WERQAx, @WESSENQAx, @WEMQAx, @WENQAx durch
+        Objectx->QueryArticle(<casus>, 1, 1);
+     @WERQPPGNx, @WESSENQPPGNx, @WEMQPPGNx, @WENQPPGNx durch
+        Objectx->QueryPossPronoun(<gender>, <casus>, <number>);
+     oder den entsprechenden String bei "Objektx".            
+
+BEMERKUNGEN:
+     x steht fuer die Position des Objekts/Strings in *obs, beginnend bei 1.
+     
+     Besonderheiten beim Possessivpronomen (@WERQPPGNx):
+     G muss durch das Geschlecht (M, F oder N) und N durch den Numerus (S 
+     oder P) ersetzt werden. 
+     Alle Angaben, auch der CASUS, beziehen sich dabei auf das Objekt, welches
+     besessen wird, nicht auf den Besitzer! Dieser ist bereits durch x 
+     bestimmt.
+     
+RUeCKGABEWERT:
+     durchersetzter String 
+     
+Beispiele:
+
+     replace_personal("@WER1", ({find_player("gloinson")}))
+     == "Gloinson"
+     
+     replace_personal("@WEMQP1", ({find_player("gloinson")}))
+     == "ihm"     
+     
+     // unbestimmter und bestimmter Artikel:
+     replace_personal("@WER1 zueckt @WENU2 und verhaut @WEN3.", 
+                      ({find_player("gloinson"),
+                        find_object("/obj/mpa"), 
+                        find_object("/obj/wanderer")}))
+     == "Gloinson zueckt eine Zeitung und verhaut den Wanderer."
+     
+     // Beim Possessivpronomen beziehen sich WEN, F und P (Akkusativ,
+     // Femininum, Plural) auf die Taschen, nicht auf Kessa:
+     replace_personal("@WER1 steckt @WESSEN2 Turnschuhe in @WENQPPFP1 "
+                      "Taschen.", 
+                      ({find_player("kessa"), 
+                        find_player("gloinson")}))
+     == "Kessa steckt Gloinsons Turnschuhe in ihre Taschen."
+
+     // Ein Beispiel mit laengerem *obs:
+     replace_personal("@WER1 zieht @WENQPPMP1 neuen Turnschuhe an. @WER2 ist "
+                      "so beeindruckt, dass @WERQP2 @WEMQP1 @WENU3 auf die "
+                      "@WEN4 haut und die Schuhe in @WEMQPPFS2 Tasche "
+                      "verschwinden laesst. @WERU5 schaut zu und kichert "
+                      "irre. Wenn das @WER6 gesehen haette!",
+                      ({find_player("gloinson"), 
+                        find_player("kessa"),
+                        find_object("/obj/mpa"),                        
+                        "Birne",
+                        find_object("/obj/wanderer"),
+                        find_netdead("jof")}),1)
+     == "Gloinson zieht seine neuen Turnschuhe an. Kessa ist so beeindruckt, "
+        "dass sie ihm eine Zeitung auf die Birne haut und die Schuhe in ihrer "
+        "Tasche verschwinden laesst. Ein Wanderer schaut zu und kichert "
+        "irre. Wenn das Jof gesehen haette!"
+
+SIEHE AUCH:
+     AddCmd(L)
+
+05. September 2015, Arathorn
diff --git a/doc/sefun/save_object b/doc/sefun/save_object
new file mode 100644
index 0000000..b1743b1
--- /dev/null
+++ b/doc/sefun/save_object
@@ -0,0 +1,19 @@
+SYNOPSIS
+        mixed save_object(string name);
+
+BESCHREIBUNG
+        Diese Simul-Efun unterscheidet sich in einigen Details von der
+        Driver-Efun save_object() (s. auch dort! Wichtig!).
+        1. diese sefun speichert auch die mit F_SAVE markierten Properties
+        eines Objektes ab (was die efun des Driver nicht tut!).
+        2. das Format, in dem gespeichert wird, kann bei der sefun nicht
+        ausgewaehlt werden (ist aber auch nicht noetig!), sondern ein
+        mudlib-weiter Standard wird benutzt.
+        3. will man nicht in einem File speichern, sondern das, was im File
+        stehen wurde, als String zurueckhaben, muss man 0 als 'name'
+        uebergeben.
+
+SIEHE AUCH
+        save_object(E), restore_object(E), save_value(E)
+03.08.2007, Zesstra
+
diff --git a/doc/sefun/send_room b/doc/sefun/send_room
new file mode 100644
index 0000000..24b05fa
--- /dev/null
+++ b/doc/sefun/send_room
@@ -0,0 +1,30 @@
+FUNKTION:
+varargs void send_room(object|string room, string msg, int msg_type,
+                       string msg_action, string msg_prefix,
+                       object *exclude, object origin)
+
+BESCHREIBUNG:
+        Sendet msg an alle Objekte in room durch Aufruf von ReceiveMsg() mit
+        den uebergebenen Argumenten.
+        Zur Bedeutung der Argumente siehe Manpage von ReceiveMsg().
+
+        Wenn das Raumobjekt mit seinem Namen angegeben ist, wird das Objekt
+        unter diesem Namen gesucht und und geladen, falls notwendig.
+
+        Mit dem Array <*exclude> kann man verhindern, dass die Nachricht an
+        die darin enthaltenen Objekte gesendet wird.
+        Das ist sinnvoll, wenn zB ein Spieler Ausloeser einer Meldung ist
+        und diese selbst nicht erhalten soll.
+
+        origin gibt an, welches Objekt die Meldung ausloest (muss nicht das
+        sendende Objekt selber) und wird vor allem fuer die Ignorierepruefung
+        verwendet. Default ist das sendende Objekt.
+
+        Letztendlich ist die sefun vergleichbar zu tell_room().
+
+SIEHE AUCH
+        ReceiveMsg(L)
+        tell_object(E), tell_room(E), say(E), write(E)
+
+13.03.2016, Zesstra
+
diff --git a/doc/sefun/set_heart_beat b/doc/sefun/set_heart_beat
new file mode 100644
index 0000000..837759e
--- /dev/null
+++ b/doc/sefun/set_heart_beat
@@ -0,0 +1,23 @@
+SYNOPSIS
+        int set_heart_beat(int flag);
+
+BESCHREIBUNG
+        Schaltet den Heartbeat ein (1) oder aus (0). Der Treiber wendet die
+        Lfun heart_beat() auf das aktuelle Objekt alle __HEARTBEAT_INTERVAL__
+        Sekunden an, wenn der Heartbeat eingeschaltet ist. Ein Shadow
+        auf der Lfun wird ignoriert.
+        
+        Der Heartbeat sollte immer ausgeschaltet werden, wenn er nicht
+        gebraucht wird. Das reduziert die Systemauslastung.
+
+        Liefert '1' bei Erfolg, '0' bei Fehler.
+
+        Das Abschalten eines bereits abgeschalteten Heartbeats (und umgekehrt
+        das Einschalten eines bereits eingeschalteten Heartbeats) zaehlt
+        als Fehler.
+
+BEMERKUNGEN
+        __HEARTBEAT_INTERVAL__ ist in MG = 2 Sekunden
+
+SIEHE AUCH
+        heart_beat(A), call_out(E)
diff --git a/doc/sefun/set_light b/doc/sefun/set_light
new file mode 100644
index 0000000..62390c4
--- /dev/null
+++ b/doc/sefun/set_light
@@ -0,0 +1,17 @@
+SYNOPSIS:
+        int set_light(int n)
+
+DESCRIPTION:
+        An object is by default dark. It can be set to not dark by
+        calling set_light(1). The environment will then also get this
+        light. The returned value is the total number of lights in
+        this room. So if you call set_light(0) it will return the
+        light level of the current object.
+        
+        Note that the value of the argument is added to the light of
+        the current object.
+
+BUGS:
+	This handling of light by the parser is inappropriate for most
+	purposes: If you put a burning candle into a safe, the safe
+	will start to emit light.
diff --git a/doc/sefun/set_living_name b/doc/sefun/set_living_name
new file mode 100644
index 0000000..360a3ce
--- /dev/null
+++ b/doc/sefun/set_living_name
@@ -0,0 +1,25 @@
+SYNOPSIS:
+        void set_living_name(string name)
+
+BESCHREIBUNG:
+        Setzt einen "Lebewesennamen" fuer das Objekt, indem Name und Objekt in
+        eine Tabelle eingetragen werden, welche von find_living() durchsucht 
+        wird. Nach Setzen des Namens kann das Objekt per find_living() 
+        gefunden werden.
+
+        Das Objekt muss ausserdem per enable_commands() als Lebewesen
+        markiert worden sein. Dies ist fuer alle von /std/npc erbenden NPCs
+        _automatisch_ der Fall und sollte daher nicht nochmal explizit gemacht
+        werden.
+
+        Alle von /std/npc erbenden NPCs setzen ebenfalls automatisch einen
+        LivingName, der lower_case(P_NAME) entspricht.
+
+        Ein Objekt kann nur einen Namen haben, mit dem es per find_living()
+        gesucht werden kann.
+
+SIEHE AUCH:
+        find_living(E), find_livings(E), find_player(E), enable_commands(E)
+
+LETZTE AeNDERNG:
+19.10.2015, Arathorn
diff --git a/doc/sefun/set_object_heart_beat b/doc/sefun/set_object_heart_beat
new file mode 100644
index 0000000..a7ba4ef
--- /dev/null
+++ b/doc/sefun/set_object_heart_beat
@@ -0,0 +1,15 @@
+FUNKTION:
+        int set_object_heart_beat(object ob, int on)
+
+ARGUMENTE:
+        ob - Objekt, dessen heart_beat veraendert werden soll
+        on - Soll der heart_beat ein- oder ausgeschaltet werden?
+
+BESCHREIBUNG:
+        Der heart_beat des Objektes wird ein- (on=1) oder aus- (on=0) geschaltet.
+
+RUECKGABEWERT:
+        1, wenn das Setzen geklappt hat, ansonsten 0.
+
+SIEHE AUCH:
+        set_heart_beat(E), heart_beat(L), call_out(E)
diff --git a/doc/sefun/sha1 b/doc/sefun/sha1
new file mode 100644
index 0000000..00bb6cc
--- /dev/null
+++ b/doc/sefun/sha1
@@ -0,0 +1,22 @@
+DEPRECATED
+SYNOPSIS
+        string sha1 (string arg)
+        string sha1 (int *  arg)
+
+BESCHREIBUNG
+        Berechnet den SHA1-Hashwert von <arg>.
+        Das Argument kann ein String, oder ein Array von Zahlen sein (von
+        welchen nur das unterste Byte betrachted wird).
+
+BEISPIEL
+        string s;
+
+        s = sha1("Hello");
+        s = sha1( ({ 'H', 'e', 'l', 'l', 'o' })
+
+HISTORY
+        Eingefuehrt in LDMud 3.3.523.
+        LDMud 3.3.712 fuehrte Zaehlenarrays als Argument ein.
+
+SIEHE AUCH
+        crypt(E), md5(E)
diff --git a/doc/sefun/shadow b/doc/sefun/shadow
new file mode 100644
index 0000000..9309dea
--- /dev/null
+++ b/doc/sefun/shadow
@@ -0,0 +1,143 @@
+FUNKTION:
+     object shadow(object ob, int flag)
+
+ARGUMENTE:
+     object ob		- das vom shadow betroffene Objekt
+     int flag		- 0 fuer eine Shadow-Existenzabfrage
+                      1 fuer Shadow durch previous_object()
+
+BESCHREIBUNG:
+     Wenn <flag> nicht 0 ist, wird das aktuelle Objekt dem Objekt obj
+     als Shadow uebergeworfen. Bei Erfolg wird das geshadowte Objekt
+     zurueckgegeben, sonst 0.
+     Wenn <flag> 0 ist, wird entweder 0 oder das geshadowte Objekt
+     zurueck gegeben.
+
+     Wenn ein Objekt A ein Objekt B beschattet, werden alle call_other() fuer
+     B auf A umgeleitet. Wenn die an B gerufene Funktion in A existiert, so
+     wird sie in A gerufen, bei Nichtexistenz in B.
+     A ist das einzige Objekt, welche die beschatteten Funktionen mit 
+     call_other() in B aufrufen kann, selbst B kann nicht per call_other() 
+     diese Funktion rufen.
+     Alle intern verwendeten Funktionen arbeiten jedoch weiterhin normal.
+
+     Das aufrufende Objekt muss vom Master-Objekt die Erlaubnis haben,
+     als Shadow zu wirken.
+
+     Es gibt folgende Kriterien fuer eine erfolgreiche Beschattung:
+     - das zu beschattende Objekt ob:
+       - ist weder ein access_rights-Objekt noch ein ROOT-Objekt
+       - gibt beim Aufruf von query_prevent_shadow(beschatter) eine 0
+         zurueck
+       - beschattet selbst niemanden
+       - hat kein '#pragma no_shadow' gesetzt
+     - der Beschatter:
+       - wird nicht selbst (direkt) beschattet
+       - beschattet noch niemanden (sonst folgt direkter Abbruch)
+       - hat kein environment()
+       - definiert/beschattet keine Methode, die im beschatteten Objekt ob 
+         als nomask definiert ist
+
+     Beschattet man ein Objekt A mit einem Objekt B und dann das Objekt A
+     zusaetzlich mit einem Objekt C, so wird eine Beschattungshierarchie
+     erstellt:
+
+     B macht shadow(A, 1)
+     B->A
+     C macht shadow(A, 1)
+     C->B->A
+
+BEISPIELE:
+     // wenn: B beschattet A, dann
+     shadow(find_object(A), 0) == B
+
+
+     // 3 Objekte beschatten in Hierarchie (liegt auch im Pfad)
+     --- aa.c ---
+     void fun() {
+         printf("%O [a] fun()\n", this_object());
+     }
+
+     void fun3() {
+         printf("%O [a] fun3()\n", this_object());
+     }
+
+     --- bb.c ---
+     int fun() {
+         printf("%O [b] fun()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun();
+     }
+
+     void fun2() {
+         printf("%O [b] fun2()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun3();
+         this_object()->fun3();
+     }
+
+     void do_shadow(object target) { shadow(target, 1); }
+
+     --- cc.c ---
+     int fun() {
+         printf("%O [c] fun()\n", this_object());
+         find_object("/doc/beispiele/shadow/aa")->fun();
+     }
+
+     void fun3() {
+         printf("%O [c] fun3()\n", this_object());
+     }
+
+     void do_shadow(object target) { shadow(target, 1); }
+
+     // darauf arbeitender Code
+
+     object a, b, c;
+
+     destruct("/doc/beispiele/shadow/aa");
+     a = load_object("/doc/beispiele/shadow/aa");
+     destruct("/doc/beispiele/shadow/bb");
+     b = load_object("/doc/beispiele/shadow/bb");
+     destruct("/doc/beispiele/shadow/cc");
+     c = load_object("/doc/beispiele/shadow/cc");
+
+     b->do_shadow(a);
+     c->do_shadow(a);
+     printf("--- a->fun() ---\n");
+     a->fun();
+     printf("--- b->fun() ---\n");
+     b->fun();
+     printf("--- c->fun() ---\n");
+     c->fun();
+     printf("--- b->fun2() ---\n");
+     b->fun2();
+
+     // ... und seine Ausgabe:
+
+     --- a->fun() ---
+     /doc/beispiele/shadow/cc [c] fun()
+     /doc/beispiele/shadow/bb [b] fun()
+     /doc/beispiele/shadow/aa [a] fun()
+     --- b->fun() ---
+     /doc/beispiele/shadow/cc [c] fun()
+     /doc/beispiele/shadow/bb [b] fun()
+     /doc/beispiele/shadow/aa [a] fun()
+     --- c->fun() ---
+     /doc/beispiele/shadow/cc [c] fun()
+     /doc/beispiele/shadow/bb [b] fun()
+     /doc/beispiele/shadow/aa [a] fun()
+     --- b->fun2() ---
+     /doc/beispiele/shadow/bb [b] fun2()
+     /doc/beispiele/shadow/aa [a] fun3()
+     /doc/beispiele/shadow/cc [c] fun3()
+
+     // Der erste Aufruf von b::fun2() in a findet sofort a::fun3()! Der
+     // Driver nimmt an, dass alle Shadows ab c bei Rufen von b nach a
+     // schon ihre Chance hatten.
+     // Der zweite Aufruf allerdings ist auf b und wird beim Durchgeben
+     // an a von c uebernommen.
+
+SIEHE AUCH:
+     Generell:	     shadow(E)
+     Rechte:	     query_allow_shadow(M), query_prevent_shadow(L)
+     Informationen:  query_shadowing(E)
+
+8.Aug 2007 Gloinson
\ No newline at end of file
diff --git a/doc/sefun/shout b/doc/sefun/shout
new file mode 100644
index 0000000..ead266f
--- /dev/null
+++ b/doc/sefun/shout
@@ -0,0 +1,69 @@
+FUNKTION:
+     varargs void shout( string text, mixed where )
+
+DEFINIERT IN:
+     /secure/simul_efun.c
+
+ARGUMENTE:
+     text
+          Der Text, der ausgegeben werden soll
+
+     where [optional]
+          Wo soll man den Text ueberall hoeren koennen?
+
+BESCHREIBUNG:
+     Der Text 'text' wird an alle Spieler in einem Gebiet ausgegeben.
+     Wird der Parameter 'where' weggelassen bzw. ist er null, so geht der
+     Text an alle Spieler im Mud. Das catch_tell() von NPCs wird nicht
+     ausgeloest.
+
+     Ist 'where' eine Zahl != 0, so wird der Text nur an Spieler ausgegeben,
+     die sich im selben Gebiet aufhalten wie this_player(). Dabei wird die
+     Zugehoerigkeit zum selben Gebiet an den ersten zwei Ebenen des Pfades
+     der Raeume festgemacht. Befindet sich this_player() z.B. in
+     "/d/ebene/irgendwo", so geht der Text an alle Spieler, deren Aufenthalts-
+     orte in "/d/ebene/*" liegen.
+
+     Fuer 'where' kann auch direkt ein Pfad angegeben werden. So wuerde ein
+     'shout( txt, "/players/" )' an alle Spieler gehen, die sich in
+     (eigentlich nicht erwuenschten) Raeumen in /players/* befinden.
+
+     Um mit einem Aufruf gleich mehrere Pfade abzudecken, kann auch ein Array
+     von Strings uebergeben werden. Alle Pfade werden als 'regular expression'
+     interpretiert. Dadurch ist es moeglich, die Zielraeume auf einfache Art
+     sehr genau einzuschraenken.
+
+     HINWEIS: Bitte ueberleg vor jedem shout() genau, ob es wirklich noetig
+     ist, dass _jeder_ etwas davon mitbekommt oder ob es nicht vielleicht
+     sinnvoller ist, das Zielgebiet etwas einzuschraenken. Im Zweifelsfall
+     sollte der zustaendige RM aufpassen, dass die Spieler nicht durch allzu
+     zahlreiche shouts belaestigt werden.
+
+RUeCKGABEWERT:
+     keiner
+
+BEISPIELE:
+     shout( "Du spuerst, wie ein Zittern durch das MorgenGrauen geht.\n" );
+        Der allseits bekannte Text wird an alle Spieler im MG ausgegeben.
+
+     shout( "Du hoerst eine gewaltige Explosion.\n", 1 );
+        Von der Explosion bekommen alle Spieler in derselben Gegend etwas mit,
+        aber nicht am anderen Ende des Muds.
+
+     shout( "Irgendwo ist ein Baum umgefallen.\n", "/d/vland/" );
+        ... gibt eine Meldung aus, die keinen wirklich interessiert. Aber es
+        trifft eh nur Leute in einem unwichtigen Teil des MorgenGrauen. ;-)
+
+     shout( "Aufwachen Du Idler!\n", "/players/.*/workroom" );
+        Mit Hilfe von regular expressions kann man recht einfach z.B. alle
+        Workrooms auf einmal adressieren.
+
+     shout( "Halloooooo, Echoooooo!\n", ({ "/d/gebirge/", "/d/ebene/" }) );
+        Wenn der Spieler hoch oben auf dem Berg laut genug ruft, hoert man
+        ihn auch noch weit in der Ebene.
+
+SIEHE AUCH:
+     write(), say(), tell_object(), tell_room(), regexp()
+
+----------------------------------------------------------------------------
+Last modified: Sun Nov 28 03:00:00 1999 by Tiamak
diff --git a/doc/sefun/time2string b/doc/sefun/time2string
new file mode 100644
index 0000000..4dae719
--- /dev/null
+++ b/doc/sefun/time2string
@@ -0,0 +1,53 @@
+FUNKTION:
+	string time2string( string format, int time )
+	
+ARGUMENTE:
+	format: String, der das Format der Zeitausgabe festlegt.
+	time: Eine Anzahl von Sekunden, die ausgegeben werden soll.
+
+ERGEBNIS:
+	Zeit in String-Form.
+
+BESCHREIBUNG:
+	Der Formatstring wird zurueckgegeben, wobei bestimmte Ersetzungs-
+	symbole durch passende Daten, die aus der Zeit berechnet werden,
+	ersetzt werden. Die Ersetzungssymbole funktionieren aehnlich
+	denen aus 'printf' bekannten Symbolen. Insbesondere kann eine
+	Feldbreite mit angegeben werden.
+
+	Folgende Ersetzungssymbole sind erlaubt:
+	%%	wird durch ein Prozent (%) ersetzt.
+	%n, %w, %d, %h, %m, %s
+		  werden durch die Anzahl der Monate, Wochen, Tage, Stunden, Minuten oder
+      Sekunden ersetzt. Die Funktion erkennt, welches die groesste benutzte
+		  Zeiteinheit ist und rechnet die keineren so um, dass sie zwischen 0 und
+      jeweiligen Maximum der Zeiteinheit liegen (59, 23 etc.) liegen.
+ 	%N	wird durch die Worte 'Woche' oder 'Wochen' ersetzt,
+      je nachdem welchen Wertd %n haette.
+ 	%W	wird durch die Worte 'Woche' oder 'Wochen' ersetzt,
+		  je nachdem welchen Wert %w haette.
+	%D	wird durch die Worte 'Tag' oder 'Tage' ersetzt,
+		  je nachdem welchen Wert %d haette.
+	%H,%M,%S
+		  werden durch die Worte 'Stunde(n)', 'Minute(n)' bzw. 'Sekunde(n)'
+      ersetzt.
+	%X	wird durch die groesste Zeiteinheit ersetzt, die nicht Null ist. Wenn
+      bei %X die Feldbreite 0 angegeben wird (also %0X), dann wird nicht der
+      ausgeschriebene Name, sonder eine Abkuerzung fuer die Zeiteinheit
+      ausgegeben. (Das sind dann 'd','h','m' oder 's'.)
+	%x	wird durch den numerischen Wert dieser Zeiteinheit
+		  ersetzt.
+			
+BEISPIELE:
+	time2string( "%m %M", 60 ) -> "1 Minute"
+	time2string( "%m %M", 120 ) -> "2 Minuten"
+	time2string( "%s %S", 125 ) -> "125 Sekunden"
+	time2string( "%m %M und %s %S" ) -> "2 Minuten und 5 Sekunden"
+	time2string( "%d:%02h:%02m:%02s", 10000 ) -> "0:02:46:40"
+	time2string( "%x %X", 3600 ) -> "1 Stunde"
+	time2string( "%x %0X", 3600 ) -> "1 h"
+	time2string( "%x %X", 360000 ) -> "4 Tage"
+	time2string( "%x %0X", 360000 ) -> "4 d"
+
+SIEHE AUCH:
+	sprintf(E)
diff --git a/doc/sefun/update_actions b/doc/sefun/update_actions
new file mode 100644
index 0000000..b28cf9f
--- /dev/null
+++ b/doc/sefun/update_actions
@@ -0,0 +1,38 @@
+FUNKTION:
+        void update_actions()
+
+ARGUMENTE:
+        keine
+
+BESCHREIBUNG:
+        Falls eine Aktion ein add_action() ausgeloest hat, werden mit dieser
+        Funktion die neuen Befehle bei allen Lebewesen im aufrufenden Objekt
+        bzw. in der Umgebung des aufrufenden Objektes aktiv.
+
+RUECKGABEWERT:
+        keiner
+
+BEMERKUNGEN:
+        Diese Funktion wird eigentlich nur benoetigt, wenn man mit add_action()
+        anstelle von AddCmd() arbeitet (zB. bei Objekten, die nicht
+        /std/thing/commands inheriten).
+
+BEISPIELE:
+        /* Normalerweise sollte man es SO gerade nicht machen. Stattdessen
+         * sollte die "kletter"-Funktion pruefen, ob die Luke geoeffnet ist, 
+         * und sich im Fehlerfall beschweren.
+         * So aber dient es als schoenes Beispiel fuer update_actions() ;)
+         */
+        int oeffne(string str)
+        {
+          if( str == "luke" ) {
+            write( "Du oeffnest die Luke. Du kannst jetzt nach unten klettern.\n");
+            add_action("kletter", "kletter", 1);
+            update_actions();
+            return 1;
+          }
+          return 0;
+        }
+
+SIEHE AUCH:
+  add_action(E), AddCmd(L), RemoveCmd(L)
diff --git a/doc/sefun/upperstring b/doc/sefun/upperstring
new file mode 100644
index 0000000..665ed16
--- /dev/null
+++ b/doc/sefun/upperstring
@@ -0,0 +1,17 @@
+FUNKTION:
+	string upperstring(string str)
+
+ARGUMENTE:
+	str - Der umzuwandelnde String.
+
+BESCHREIBUNG:
+	Alle Kleinbuchstaben in str werden in Grossbuchstaben umgewandelt.
+
+RUECKGABEWERT:
+	Der umgewandelte String.
+
+BEISPIELE:
+	s = upperstring( "Na, Sterblicher!\n") => s = "NA, STERBLICHER!\n"
+
+SIEHE AUCH:
+	lowerstring(E), lower_case(E), capitalize(E)
diff --git a/doc/sefun/uptime b/doc/sefun/uptime
new file mode 100644
index 0000000..ee7a536
--- /dev/null
+++ b/doc/sefun/uptime
@@ -0,0 +1,16 @@
+FUNKTION:
+        string uptime()
+
+ARGUMENTE:
+        keine
+
+BESCHREIBUNG:
+        Liefert die aktuelle Uptime des MorgenGrauens.
+
+RUECKGABEWERT:
+        Die Uptime als Zeitstring.
+
+BEISPIELE:
+        ut = uptime() => ut = "14 Tage, 9 Stunden, 3 Minuten und 7 Sekunden."
+
+SIEHE AUCH:
diff --git a/doc/sefun/wizlist b/doc/sefun/wizlist
new file mode 100644
index 0000000..a2ba7bd
--- /dev/null
+++ b/doc/sefun/wizlist
@@ -0,0 +1,66 @@
+SYNOPSIS:
+  varargs void wizlist(string name, int sortkey ) 	
+
+DESCRIPTION:
+  wizlist() liefert eine Liste mit verschiedenen Verbrauchsdaten 
+	zu Magiern. Es werden dabei normalerweise 21 Eintraege ausgegeben:
+  10 vor <name>, <name> selbst und 10 nach <name>.
+
+  Die Liste ist dabei folgendermassen aufgebaut:
+
+	1. WL_NAME
+	   Gesammelt werden die Daten pro UID. Hierbei zaehlt aber jede EUID, nicht
+     nur die von Magiern.
+     Das heisst, Objekte unter /d/polar/vanion/eispalast
+	   werden nicht unter "vanion" sondern unter "d.polar.vanion"
+	   abgerechnet.
+
+	2. WL_COMMANDS
+     Anzahl der diesem Objekt zugeordneten commands.
+
+	3. WL_COMMANDS * 100 / total_cmd 
+     Prozentualer Anteil an den gesamt verbrauchten commands.
+
+	4. WL_COST (links in der eckigen Klammer)
+     Anzahl der verbrauchten eval ticks. Dies ist zeitlich gewichtet, d.h.
+     nimmt im Lauf der Zeit ab, wenn nichts mehr dazu kommt.
+
+  5. WL_TOTAL_GIGACOST (rechts in der eckigen Klammer)
+     Anzahl der insgesamt verbrauchten eval ticks in Giga-Ticks.
+     Nicht zeitlich gewichtet.
+
+	6. WL_HEART_BEATS
+     Anzahl der ausgeloesten heart beats.
+  
+  7. WL_ARRAY_TOTAL
+
+  8. WL_MAPPING_TOTAL
+
+PARAMETERS: 
+  Wird name angegeben, wird erzwungen, dass die erwaehnte EUID mit
+  in der Liste dargestellt wird. Wird name nicht angegeben, wird es
+  automatisch auf this_player()->query_real_name() gesetzt.
+
+  Wird als name "TOP100" angegeben, wird die Top-100-Liste ausgegeben.
+
+  Wird als name "ALL" angegeben, wird die vollstaendige Liste aus-
+  gegeben.
+
+  Durch Angabe von sortkey kann die Liste nach einer der Spalten 
+  sortiert werden. Gueltige Werte sind die in /sys/wizlist.h ange-
+  gebenen Defines.
+	
+EXAMPLE: 
+  > xeval wizlist("vanion", WL_HEART_BEATS)
+      Erzwingt Vanions Eintrag in der Liste und sortiert die Liste anhand
+      der durch die EUIDs ausgefuehrten heart beats.
+
+  > xeval wizlist("ALL", WL_EVAL_COST)
+      Zeigt die komplette Liste nach eval ticks-Verbauch sortiert an.
+
+SEE ALSO:
+      wizlist_info(E)
+
+LAST UPDATED:
+  09.05.2015, Zesstra
+
diff --git a/doc/sefun/wizlist_info b/doc/sefun/wizlist_info
new file mode 100644
index 0000000..2a5c127
--- /dev/null
+++ b/doc/sefun/wizlist_info
@@ -0,0 +1,39 @@
+GESCHUETZT
+SYNOPSIS
+        #include <sys/wizlist.h>
+
+        *mixed wizlist_info();
+
+BESCHREIBUNG
+        Liefert ein Array mit Eintraegen aus der Wizlist (der internen
+        Magierliste). Die Benutzung muss durch das Masterobjekt erlaubt
+        werden.
+
+        Das Resultat ist ein Array mit einem Eintrag fuer jeden Magier (uid).
+        Jeder Eintrag enthaelt wiederum ein Array mit folgenden Elementen:
+
+            string  w[WL_NAME]          Name des Magiers
+            int w[WL_COMMANDS]          Gewichtete Anzahl Kommandi, die von
+                                        Objekten dieses Gottes ausgefuehrt
+                                        wurden
+            int w[WL_COSTE]             Gewichtete Summe der Eval-Kosten
+            int w[WL_GIGACOST]          Gewichtete Summe der Eval-Kosten
+            int W[WL_TOTAL_COST]        Totale Summe der Eval-Kosten
+            int w[WL_TOTAL_GIGACOST]    Totale Summe der Eval-Kosten
+            int w[WL_HEART_BEAT]        Gewichtete Anzahl der heat_beat()s
+            int w[WL_CALL_OUT]          Reserviert fuer call_out()s
+                                        (bisher nicht implementiert)
+            int w[WL_ARRAY_TOTAL]       Totale Groesse aller Arrays in
+                                        Elementen
+            mixed w[WL_EXTRA]           Die eigentliche Wizlist-Info
+
+        Die "gewichteten" Werte verfallen pro Stunde um 10%.
+
+AENDERUNGEN
+        LDMud 3.2.10 trennte das alte WL_EVAL_COST in WL_COST und WL_GIGACOST,
+        um laengeren Uptimes gerecht zu werden. Ausserdem wurde
+        WL_TOTAL_COST und WL_TOTAL_GIGACOST eingefuehrt.
+
+SIEHE AUCH
+        privilege_violation(M), set_extra_wizinfo_size(E),
+        get_extra_wizinfo(E), set_extra_wizinfo(E)
diff --git a/doc/std/.synonym b/doc/std/.synonym
new file mode 100644
index 0000000..508ee32
--- /dev/null
+++ b/doc/std/.synonym
@@ -0,0 +1,9 @@
+armours armour
+ruestung armour
+ruestungen armour
+weapons weapon
+waffen weapon
+waffe weapon
+units unit
+vc virtual_compiler
+ringbuffer util
diff --git a/doc/std/armour b/doc/std/armour
new file mode 100644
index 0000000..9721cfc
--- /dev/null
+++ b/doc/std/armour
@@ -0,0 +1,87 @@
+ STANDARDKLASSE:
+	"/std/armour"
+ 
+ BENUTZUNG:
+        inherit "/std/armour";
+ 
+        #include <properties.h>
+        #include <combat.h>
+
+ PROPERTIES:
+     Grundlegend:
+	P_AC		setzbar: Ruestungsklasse == Schutz
+	P_ARMOUR_TYPE	setzbar: Ruestungstyp
+
+     Besondere Attribute und Anforderungen fuer Traeger:
+	P_RESTRICTIONS	setzbar: Anforderungen an Traeger
+	P_M_ATTR_MOD	setzbar: Attributmodifikator fuer Traeger
+	P_RESISTANCE_STRENGTHS
+			setzbar: Resistenzmodifikator fuer Traeger
+	P_NR_HANDS	setzbar: notwendige Handanzahl (zB Schilde)
+	P_CURSED	setzbar: Verfluchung (nicht ausziehbar)
+
+     Meldungen und Zeitpunkte:
+	P_EQUIP_TIME	enthaelt den Zeitpunkt des Anziehens
+	P_LAST_USE	enthaelt den Zeitpunkt des letzten Treffers
+	P_WORN		enthaelt den Traeger
+	P_WEAR_MSG	setzbar: eigene Anziehmeldungen
+	P_UNWEAR_MSG	setzbar: eigene Ausziehmeldungen
+
+     Dynamisches Verhalten in Kampf und beim Anziehen:
+	P_WEAR_FUNC	setzbar: Objekt mit Anziehfunktion "WearFunc()"
+	P_REMOVE_FUNC	setzbar: Objekt mit Ausziehfunktion "RemoveFunc()"
+	P_DEFEND_FUNC	setzbar: Objekt mit Defensivfunktion "DefendFunc()"
+
+     Zusaetzliche Eigenschaften:
+	P_DAMAGED	enthaelt den Ausmass des Schadens an Waffe
+	P_QUALITY	setzbar: Qualität/Haltbarkeit der Waffe
+	P_EFFECTIVE_AC	setzbar: falls DefendFunc AC nicht sichbar aendert
+	P_DAM_TYPE	setzbar: interessant bei Kaempferangriffen
+
+     Zusaetzlich sind alle Properties aus /std/thing verfuegbar, also
+     bitte auch folgende setzen:
+	P_MATERIAL	setzbar: Zusammensetzung
+	P_SIZE		setzbar: Groesse
+	P_WEIGHT	setzbar: Gewicht
+
+ MAKROS:
+     Gueltige Ruestungstypen (definiert in "/sys/combat.h").
+ 
+ ERLAEUTERUNG:
+     Basisklasse fuer alle Ruestungen im Spiel. Sie ist von "/std/clothing"
+     abgeleitet und enthaelt alle zusaetzliche Funktionalitaet
+     fuer den Kampf.
+
+     Vor der Programmierung von Ruestungen sollte /doc/MG/waffen_werte
+     gelesen werden. Die Regeln darin sind verbindlich und sollten nur
+     in Ausnahmefaellen und mit Absprache mit dem Erzmagier fuer 
+     Waffen/Ruestungen/Monster ueberschritten werden.
+     Gerade in DefendFuncs sollte auf die korrekte Behandlung der
+     uebergebenen Spellflags geachtet werden - insbesondere SP_RECURSIVE
+     und SP_NO_ACTIVE_DEFENSE.
+
+     Die Maximalwerte und Werte fuer Zerstoerung bei Verkauf sind
+     /sys/combat.h zu entnehmen: VALID_ARMOUR_CLASS/KEEP_ARMOUR_CLASS.
+
+ VERERBUNGSBAUM:
+     [/std/armour]
+     ..... [/std/thing/properties]
+     ..... [/std/thing/language]
+     ..... [/std/thing/commands]
+     ..... [/std/thing/restrictions]
+     ..... [/std/thing/envchk]
+     ..... [/std/armour/description]
+     .......... [/std/clothing/description]
+     .............. [/std/thing/description]
+     ..... [/std/armour/wear]
+     .......... [/std/clothing/wear]
+     ..... [/std/clothing/moving]
+     .......... [/std/thing/moving]
+     ..... [/std/armour/combat]
+
+ SIEHE AUCH:
+     P_ARMOURS, P_LAST_WEAR_ACTION, P_TOTAL_AC
+     Attack(), Defend(), /doc/wiz/ruestungen, balance
+
+03.08.2007, Zesstra
+
diff --git a/doc/std/clothing b/doc/std/clothing
new file mode 100644
index 0000000..91ccb55
--- /dev/null
+++ b/doc/std/clothing
@@ -0,0 +1,77 @@
+ STANDARDKLASSE:
+	"/std/clothing"
+ 
+ BENUTZUNG:
+        inherit "/std/clothing";
+ 
+        #include <properties.h>
+        #include <clothing.h>
+
+ PROPERTIES:
+
+     Besondere Attribute und Anforderungen fuer Traeger:
+	P_RESTRICTIONS	setzbar: Anforderungen an Traeger
+	P_CURSED	setzbar: Verfluchung (nicht ausziehbar)
+
+     Meldungen und Zeitpunkte:
+	P_EQUIP_TIME	enthaelt den Zeitpunkt des Anziehens
+	P_WORN		enthaelt den Traeger
+	P_WEAR_MSG	setzbar: eigene Anziehmeldungen
+	P_UNWEAR_MSG	setzbar: eigene Ausziehmeldungen
+
+     Dynamisches Verhalten in Kampf und beim Anziehen:
+	P_WEAR_FUNC	setzbar: Objekt mit Anziehfunktion "WearFunc()"
+	P_REMOVE_FUNC	setzbar: Objekt mit Ausziehfunktion "RemoveFunc()"
+
+     Zusaetzlich sind alle Properties aus /std/thing verfuegbar, also
+     bitte auch folgende setzen:
+	P_MATERIAL	setzbar: Zusammensetzung
+	P_SIZE		setzbar: Groesse
+	P_WEIGHT	setzbar: Gewicht
+
+ 
+ ERLAEUTERUNG:
+     Basisklasse fuer alle Kleidungen im Spiel. Sie ist von "/std/thing"
+     abgeleitet.
+     Kleidung belegt niemals einen Ruestungsslot und ist nur fuer Kram
+     gedacht, der keine kampfrelevante Funktionalitaet beeinhaltet.
+     Momentan ist die Anzahl an Kleidungsstuecken, die ein Spieler anziehen
+     kann, nicht begrenzt.
+     Kleidung sind im Prinzip Ruestungen ohne alle in den Ruestungen
+     enthaltene kampfrelevante Funktionalitaet.
+     (BTW: Kleidungen koennen allerdings, sofern unbedingt notwendig, mittels
+      P_SENSITIVE, P_SENSITIVE_ATTACK, etc. auch indirekt am Kampf teilnehmen,
+      in dem Sinne, dass sie auf eingehenden Schaden reagieren. Hierbei darf
+      allerdings in keinem Fall in den Kampfverlauf eingegriffen werden.)
+
+     Spezielle Properties:
+     SetProp(P_WEAR_FUNC, ob)
+	Setzt das Objekt, in dem die Funktion WearFunc() definiert
+	wird. WearFunc() wird beim Versuch die Kleidung anzuziehen
+	aufgerufen, gibt sie 0 zurueck so scheitert der Versuch.
+     SetProp(P_REMOVE_FUNC, ob)
+	Setzt das Objekt, in dem die Funktion RemoveFunc() definiert
+	ist. Die Funktion wird beim Versuch die Kleidung auszuziehen
+	aufgerufen, gibt sie 0 zurueck, so scheitert der Versuch.
+
+
+ VERERBUNGSBAUM:
+     [/std/clothing]
+     ..... [/std/thing/properties]
+     ..... [/std/thing/language]
+     ..... [/std/thing/commands]
+     ..... [/std/thing/restrictions]
+     ..... [/std/thing/envchk]
+     ..... [/std/clothing/description]
+     .......... [/std/thing/description]
+     ..... [/std/clothing/moving]
+     .......... [/std/thing/moving]
+     ..... [/std/clothing/wear]
+
+ SIEHE AUCH:
+     armours,
+     FilterClothing, FilterArmours, Wear(), Unwear(), WearArmour(),
+     WearClothing(), UnwearArmour(), UnwearClothing() 
+
+15.02.2009, Zesstra
+
diff --git a/doc/std/container b/doc/std/container
new file mode 100644
index 0000000..667078a
--- /dev/null
+++ b/doc/std/container
@@ -0,0 +1,49 @@
+OBJECT:
+	container 
+
+
+DESCRIPTION:
+	A cointainer is a special object which can contain other objects.
+	It provides the same functions as the thing(S) class, but adds
+	some functions for the handling of contents. It defines some
+	properties related to what and how much is contained in it.
+
+	The following additional properties are defined for a container:
+	P_MAX_WEIGHT, P_WEIGHT_CONTENTS
+
+	Note that the weight of a container is handled especially:
+	SetProp(P_WEIGHT,weight) sets the weight of the container
+	without contents, while QueryProp(P_WEIGHT) returns the total
+	weight of the container plus contents.
+
+	For now, you may use the following function to add or remove
+	weight from the container.
+
+	AddWeight(weight)
+	  Adds <weight> to the container. If its OK, 1 is returned,
+	  otherwise 0. Only if the weight fits into the container, the
+	  weight is adjusted.
+
+	MayAddWeight(weight)
+	  Like AddWeight, but if the weight fits inside the container,
+	  the total weight is NOT updated. You may use this function to
+	  test if an object fits into a container.
+
+	NOTE: Currently, these functions may be called from outside.
+	In a alter stage, movement of objects will be done by calling
+	the move() function in the object to be moved. The move()
+	function of that object will then call (May)AddWeight() itself
+	to determine if it may enter the container.
+
+
+INHERITANCE TREE:
+	container
+	  |-thing/moving
+	  |-thing/properties
+	  |-container/description
+	  |   `-thing/description
+	  `-container/restrictions
+
+
+SEE ALSO:
+	thing(S)
diff --git a/doc/std/corpse b/doc/std/corpse
new file mode 100644
index 0000000..d4e2d47
--- /dev/null
+++ b/doc/std/corpse
@@ -0,0 +1,76 @@
+OBJEKT:
+      corpse
+
+
+SYNOPSIS:
+      inherit "std/corpse";
+
+
+BESCHREIBUNG:
+      Die Standardleiche ist ein spezieller Container. Er beinhaltet die
+      zurueckgelassene Ausruestung gestorbener NPCs und Spieler.
+      Die Standardleiche verfault mit der Zeit und stellt ein paar
+      Funktionalitaeten zur Verfuegung, naemlich das Essen der Leiche
+      und das Verspotten auf dem Moerderkanal.
+      Die Funktion
+        void Identify( object ob );
+      wird im die() eines Livings aufgerufen, damit die Leiche Informationen
+      aus dem Living auslesen kann, ehe dieser endgueltig stirbt. Schreibt
+      man eine eigene Leiche, dann ist dies die geeignete Moeglichkeit, der
+      Leiche Informationen zukommen zu lassen.
+
+
+BEISPIELE:
+      // Eine eigene Leiche.
+      #inherit "std/corpse";
+
+      void create()
+      {
+        ::create();
+        // Irgendwas eigenes...
+      }
+
+      /*
+       * Dieser Funktion wird der getoetete Living uebergeben.
+       */
+      void Identify(object ob)
+      {
+        ::Identify(ob);
+        if (ob)
+        {
+          ob->QueryProp("meine_tolle_property");
+        }
+      }
+
+      /*
+       * Das ist die für "iss leiche" aufgerufene Funktion.
+       */
+      int mampf( string str )
+      {
+        notify_fail("Was willst Du essen?\n");
+        if (!str || !id(str) ) return 0;
+        tell_object(this_player(), "Diese Leiche kann man nicht essen.\n");
+        return 1;
+      }
+
+
+
+BEMERKUNG:
+      Man kann eigene Leichen schreiben, die von der Standardleiche erben
+      oder auch nicht. Man sollte dann aber die im die() aufgerufenen
+      Funktionen implementieren:
+        corpse->Identify(object ob);
+	corpse->SetProp(***); // Fuer P_HEAL
+	corpse->move(***); // Um sie ins environment() des Toten zu bekommen.
+      Die Leiche sollte, muss aber kein Container sein, damit die Ausruestung
+      hineinbewegt werden kann.
+      Wenn man nicht von der Standardleiche erbt, kommt sie nicht auf -Moerder
+      und man kann sie nicht verspotten. Damit dies geht, muss (!) man von der
+      Standardleiche erben.
+
+SIEHE AUCH:
+      P_NOCORPSE, P_CORPSE, P_HEAL, QueryHealInfo()
+
+
+----------------------------------------------------------------------------
+Letzte Aenderung: 31.03.2008, Arathorn
diff --git a/doc/std/hooks b/doc/std/hooks
new file mode 100644
index 0000000..de308bd
--- /dev/null
+++ b/doc/std/hooks
@@ -0,0 +1,278 @@
+Das neue Hooksystem
+(Implementierung von Muadib, ueberarbeitet von Zesstra)
+
+EINLEITUNG
+==========
+Das neue Hooksystem baut nicht mehr auf der Eintragung eines Hooks in einer
+Property auf. Dadurch wird es moeglich, dass nicht nur ein Objekt sich als
+Hook eintraegt.
+
+Es gibt verschiedenen Arten von Hooks, die man eintragen kann:
+* Listener (H_LISTENER)
+            diese Hooks werden ueber ein Ereignis nur informiert,
+            koennen aber nicht eingreifen oder aendern.
+            max. Anzahl: 5
+* Data-Modifier (H_DATA_MODIFICATOR)
+            diese Hooks duerfen die Daten eines Ereignisses aendern.
+            max. Anzahl: 3
+* Hook-Modifier (H_HOOK_MODIFICATOR)
+            diese Hooks duerfen die Daten des Ereignisses aendern und
+            zusaetzlich das Ereignis auch abbrechen.
+            max. Anzahl: 2
+* Surveyor (H_HOOK_SURVEYOR)
+            diese Hooks duerfen alles oben beschriebene. Zusaetzlich werden
+            sie aber auch gefragt, wenn andere Objekte einen Hook eintragen
+            wollen, einen Hook abbrechen wollen oder Daten aendern wollen.
+            Oder anders: Surveyorhooks entscheiden, was andere duerfen.
+            Kein normales Objekte sollte diese Art von Hook eintragen. Der RM
+            muss die Verwendung eines Surveyors genehmigen.
+            max. Anzahl: 1
+
+Ausserdem lassen sich Hooks noch mit unterschiedlicher Prioritaet eintragen,
+welche dann in der entsprechenden Reihenfolge abgearbeitet werden. Wenn ein
+neuer Hook eingetragen wird, aber eigentlich die max. Anzahl schon erreicht
+wird, wird der Konsument mit der niedrigsten Prioritaet geloescht. In diesem
+Fall wird die superseededHook() im verdraengten Konsumenten gerufen.
+
+Um das neue Hook-System zu realisieren, gibt es zwei wesentliche Klassen.
+Die Objekte, die die Eintragung von Hooks erlauben, erben hierzu von
+hook_provider. Objekte, die einen Surveyor-Hook eintragen wollen, sollten von
+der Klasse hook_surveyor erben. Objekte mit normalen Hooks brauchen nichts zu
+erben.
+
+
+Welche Hooks gibt es zur Zeit in der Basis-Mudlib?
+=================================================
+* H_HOOK_MOVE
+  Bei Bewegung eines Objektes ausgeloest. Kann Bewegung beeinflussen oder
+  abbrechen.
+* H_HOOK_DIE
+  Beim Tod eines Lebewesens ausgeloest. Kann den Tod abbrechen oder
+  <poisondeath> abaendern.
+* H_HOOK_DEFEND
+  Im Defend() eines Lebenwesens ausgeloest. Kann das Defend() abbrechen und
+  Daten des Defend() aendern.
+* H_HOOK_ATTACK
+  Im Attack() eines Lebenwesens ausgeloest. Kann das Attack() abbrechen.
+* H_HOOK_HP
+  Bei Veraenderung der HP (LP) eines Lebewesens gerufen. (Zur Zeit keine
+  Datenveraenderung moeglich)
+* H_HOOK_SP
+  Bei Veraenderung der SP (KP) eines Lebewesens gerufen. (Zur Zeit keine
+  Datenveraenderung moeglich)
+* H_HOOK_ATTACK_MOD
+  Wird im Attack() ausgeloest, nachdem die fuer den Angriff wichtigen Daten
+  ermittelt und berechnet wurden. Diese koennen dann vom Hookonsumenten
+  nochmal geaendert werden. Auch ein Abbruch des Attack() ist hier noch
+  moeglich.
+* H_HOOK_ALCOHOL
+  Bei Veraenderung von P_ALCOHOL im Lebewesens gerufen.
+* H_HOOK_FOOD
+  Bei Veraenderung von P_FOOD im Lebewesens gerufen.
+* H_HOOK_DRINK
+  Bei Veraenderung von P_DRINK im Lebewesens gerufen.
+* H_HOOK_POISON
+  Bei Veraenderung von P_POISON im Lebewesens gerufen.
+* H_HOOK_CONSUME
+  Beim Konsumieren von Speisen und Getraenken in Kneipen im Lebewesens
+  gerufen.
+* H_HOOK_TEAMROWCHANGE
+  Bei Teamreihenwechsel vom Lebewesen ausgeloest.
+* H_HOOK_INSERT
+  Wird von Spielerobjekten ausgeloest, wenn ein Objekt ins Spielerinventar
+  bewegt wird. (Keine Datenveraenderung moeglich)
+* H_HOOK_EXIT_USE
+  Wird von einem Raum ausgeloest, wenn ein Lebewesen einen Ausgang benutzt.
+  Abbruch und Aenderung der Daten des Ausgangs moeglich.
+
+HOOK-KONSUMENTEN
+================
+Der Hook-Provider ruft bei Ausloesen des Hooks in allen Konsumenten eine
+bestimmte Methode auf. Wenn bei der Registrierung eines Objekts keine Closure
+angeben wurde, die in diesem Fall gerufen werden, wird standardmaessig die
+lfun HookCallback() gerufen (gibt man eine Closure an, bekommt sie die
+gleichen Argumente und es werden die beschriebenen Rueckgabewerte erwartet):
+  * mixed HookCallback(object hookSource, int hookid, mixed hookData)
+  Diese Methode wird in jedem Hook-Konsumenten eines Hook-Providers
+  aufgerufen, solange die Verarbeitung nicht vorher abgebrochen wurde.
+  Die Reihenfolge der Abarbeitung wird nach Liste (Surveyor,
+  Hook-Modifikator, Data-Modifikator, Listener) und dort nach Prioritaet
+  durchgefuehrt.
+  Ein Surveyor-Hook kann verhindern, dass Hooks bestimmte Aenderungen
+  durchfuehren.
+
+  Rueckgabewert ist ein Array, das die folgenden Werte beinhaltet.
+
+  H_RETCODE Gibt an, welcher Hook-Typ verwendet wurde.
+      H_NO_MOD => Nichts wurde veraendert.
+      H_ALTERED => Daten wurden veraendert.
+      H_CANCELLED => Hook-Kette soll abgebrochen werden.
+                  => Ausserdem soll die Hook-ausloesende Stelle
+                     abgebrochen werden. Z.B. wird das Defend()
+                     abgebrochen, wenn ein H_HOOK_DEFEND
+                     mit cancelled beantwortet wird.
+  H_RETDATA Gibt die (evtl. geaenderten) Daten an.
+      mixed-Objekt, das wie der Parameter hookData aufgebaut ist.
+
+Ein Objekt darf sich mehrfach fuer den gleichen Hook registrieren. Allerdings
+ist fuer jede Registrierung eine andere Closure noetig.
+
+  * void superseededHook(int hookid, object hookprovider)
+    Wird gerufen, wenn der Konsument von einem anderen mit hoeherer Prioritaet
+    verdraengt wurde.
+
+
+HOOK-PROVIDER
+=============
+  Der Hook-Provider bietet eine Menge von Methoden an, die eine Konfiguration
+  ermoeglichen und die Eintragung von Hook-Konsumenten erlauben. Im
+  Normalfall sollte er geerbt und nicht modifiziert werden (ausser natuerlich,
+  die vom Objekte bereitgestellten Hooks einzutragen).
+
+  * int* HListHooks();
+  Diese Methode liefert eine Liste von Hooktypen, fuer die das Objekt
+  Eintragungen annimmt. Hier koennte beispielsweise eine Liste mit den
+  Eintraegen fuer Attack-, Defend- und Move-Hooks stehen.
+
+
+  * protected void offerHook(int hookid, int offerstate);
+  Diese Methode dient dazu, einen bestimmten Hook (z.B. H_HOOK_MOVE)
+  anzubieten. Nur Hooks, die hiermit angeboten wurden, stehen zur
+  Registrierung zur Verfuegung.
+  'offerstate': 0 (nicht verfuegbar), 1 (verfuegbar/angeboten)
+
+
+  * int HRegisterToHook(int hookid, mixed consumer, int hookprio,
+                       int consumertype, int timeInSeconds);
+  Registriert ein Objekt oder eine Closure als Hook-Konsument.
+  Parameter:
+  'hookid'        gibt den Hook-Typ an, z.B. den Defend-Hook.
+                  Man kann sich nur fuer Hooktypen eintragen, die die Methode
+                  HListHooks() angeboten hat.
+  'consumer'      Wenn ein Objekt, wird das Objekt eingetragen und spaeter
+                  HookCallback() gerufen.
+                  Wenn eine Closure, wird das Objekt der Closure eingetragen
+                  und spaeter diese Closure gerufen.
+  'hookprio'      Gibt die Prioritaet an, mit der der Hook laufen soll.
+                  Diese Angabe bestimmt die Reihenfolge, in der die Hooks
+                  in der Liste der Hooks eingetragen werden. Die Prioritaet
+                  ist H_HOOK_LIBPRIO(x), H_HOOK_GUILDPRIO(x) oder
+                  H_HOOK_OTHERPRIO(x). x darf 0, 1 oder 2 sein (je niedriger,
+                  desto hoeher die Prioritaet).
+  'consumertype'  Gibt an, um welche Art von Hook es sich handelt.
+                  Es gibt vier festgelegten Typen, die fuer alle Hooks
+                  existieren koennen. Die Methode HConsumerTypeIsAllowed()
+                  gibt Aufschluss darueber, welche Hook-Typen existieren.
+                  Die Hook-Typen sind in hook.h definiert.
+  'timeInSeconds' gibt die Laufzeit des Hooks an. Falls 0 eingetragen wird,
+                  laeuft der Hook ewig.
+  Rueckgabewerte:
+    1 - Registrierung erfolgreich
+  <=0 - Registrierung fehlgeschlagen:
+        -1 : Hook unbekannt
+        -2 : consumer ist keine closure und es konnte kein Callback auf
+             HookCallback im consumer erstellt werden.
+        -3 : consumer ist bereits registriert
+        -4 : consumertyp ist nicht erlaubt
+        -5 : hookprio ist nicht erlaubt
+        -6 : Surveyor hat Registrierung nicht erlaubt
+        -7 : zuviele Hooks registriert / kein Hookeintrag frei
+
+  * int HUnregisterFromHook(int hookid, mixed consumer);
+  Hebt die Registrierung von <consumer> fuer einen bestimmten Hook-Typ wieder
+  auf.
+  Parameter:
+  'hookid'    Die Kennung des Hook-Typs, z.B. die Kennung des Attack-Hooks.
+  'consumer'  Das Objekt oder die Closure, die/das nicht mehr registriert sein
+              soll. Bei einer Closure wird genau diese ausgetragen. Bei der
+              Angabe eines Objekts wird versucht, die Closure auf
+              HookCallback() in diesem Objekt auszutragen.
+  Rueckgabewerte:
+  0 - 'consumer' nicht als Konsument gefunden
+  1 - Austragen erfolgreich
+
+  * int HConsumerTypeIsAllowed(int type, object consumer);
+  Diese Methode liefert 1 zurueck, wenn ein bestimmter Konsumenten-Typ
+  (fuer diesen Konsumenten) erlaubt wird.
+  Die Standardmethode liefert immer 1 (true) zurueck. Erbende Objekte
+  koennen diese Methode ueberschreiben, wenn sie nicht alle Hooktypen
+  anbieten.
+
+
+  * int HPriorityIsAllowed(int prio, object consumer);
+  Diese Methode gibt an, ob eine bestimmte Prioritaet (fuer den angegebenen
+  Konsumenten) erlaubt ist. Die Standardmethode liefert immer 1 (true)
+  zurueck. Erbende Objekte koennen diese Methode ueberschreiben, wenn
+  sie die verfuegbaren Hook-Prioritaeten einschraenken wollen.
+
+
+  * int HIsHookConsumer(int hookid, mixed consumer);
+  Ist <consumer> ein Objekt, liefert die Methode die Anzahl, wie oft dieses
+  Objekt (mit verschiedenen Closures) fuer den Hook <hookid> eingetragen ist.
+  Ist <consumer> eine Closure, liefert diese Methode 1, wenn diese
+  Closure fuer den Hook <hookid> eingetragen ist.
+
+
+  * protected mapping HCopyHookMapping();
+  Diese Methode liefert eine Kopie des Hook-Mappings.
+  ACHTUNG: diese Daten sollten das Objekt NIEMALS verlassen. (Ausser fuer
+           Debugzwecke)
+
+
+
+HOOK-SURVEYOR
+=============
+  Objekte mit Surveyorhooks muessen eine Menge von Methoden definieren, die
+  der Hookprovider aufruft:
+
+  * status HookRegistrationCallback(
+                object registringObject,
+                int hookid,
+                object hookSource,
+                int registringObjectsPriority,
+                int registringObjectsType)
+  Diese Methode wird vom Hook-Provider aufgerufen, wenn der Hook-Konsument
+  als Surveyor eingetragen ist und ein weiterer Hook eingetragen werden soll.
+  Gibt diese Methode 0 zurueck, dann verbietet der Konsument, dass der
+  andere Konsument als Hook eingetragen wird.
+
+  * int HookCancelAllowanceCallback(
+                object cancellingObject,
+                int hookid,
+                object hookSource,
+                int cancellingObjectsPriority,
+                mixed hookData)
+  Diese Methode wird aufgerufen, um herauszufinden, ob ein bestimmter
+  anderer Hook die Ausfuehrung der Hook-Kette unterbrechen darf.
+  Nur Hooks im Bereich H_HOOK_MODIFICATOR werden der Methode uebergeben.
+
+  * int HookModificationAllowanceCallback(
+                object modifyingObject,
+                int hookid,
+                object hookSource,
+                int modifyingObjectsPriority,
+                mixed hookData)
+  Diese Methode wird aufgerufen, um herauszufinden, ob ein bestimmter
+  anderer Hook die Daten des Hooks veraendern darf oder nicht.
+  Es werden die Hooks in den Bereichen H_HOOK_MODIFICATOR und
+  H_DATA_MODIFICATOR (in dieser Reihenfolge) aufgerufen.
+
+
+WAS KOSTET DAS?
+  Das Ausloesen eines Hooks per HookFlow() kostet 111 Ticks und ca. 7 us, wenn
+  es gar keinen gibt, der drauf lauscht (sozusagen Fixkosten).
+  Pro H_LISTENER kommen dann 31 Ticks und ca. 2 us dazu.
+
+  Gibts einen Surveyor-Hook (der wird dann gefragt, ob andere Objekte die
+  Daten des Hooks aendern oder die Hookverarbeitung abbrechen duerfen):
+  Fixkosten: 155 Ticks, 11 us.
+  Plus pro Data-Modifier:
+  106 Ticks, 5.6 us
+  Plus pro Hook-Modifier, der aber nur Daten aendert:
+  112 Ticks, 6.4 us
+  Und ein Hook-Modifier, der den Hook abbricht:
+  76 Ticks, 4 us
+
+  (Macht der Surveyor natuerlich irgendwas anderes als 'return 1;', wirds
+  natuerlich entsprechend teurer.)
+
diff --git a/doc/std/living b/doc/std/living
new file mode 100644
index 0000000..89d47bd
--- /dev/null
+++ b/doc/std/living
@@ -0,0 +1,120 @@
+
+OBJECT:
+	living 
+
+
+SYNOPSIS:
+	inherit "std/living";
+
+	#include <properties.h>
+	#include <living.h>
+
+
+DESCRIPTION:
+	This is the generic living object which 'lives', can move,
+	can fight.
+
+	It has a number of 'stats', also called 'attributes' in
+	the new system. These include the former stats 
+	strength, dexterity, intelligence and constitution.
+	These attributes determine the life functions and
+	variables like hitpoints and spellpoints, but also the
+	ability to perform certain actions like spellcasting or
+	swordfighting. Attributs are implemented as a property
+	P_ATTRIBUTES. Attributes can be set by using the functions
+
+	SetAttribute(string attribute, int value)
+	  Sets <attribute> to <value>. Certain restrictions might
+	  exist, and the requested attribute might not be set.
+	  Attributes are integer values, and are in the range
+	  of 1 (very bad) to 20 (excellent and highest possible
+	  for a normal human).
+
+	int QueryAttribute(string attribute)
+	  Returns value of <attribute>
+
+	Abilities. A living creature may have special abilities
+	to perform certain actions. These may be very different
+	types of actions, like fighting with a sword, casting
+	a fireball or climbing up a tree. Abilities are
+	implemented as the P_ABILITIES property. An ability may
+	be accompanied by an object which may define special
+	actions and which uses the values of P_ABILITES, for 
+	example a spellbook will store spell levels there or
+	a weapon uses a weapon ability (skill). The abilities
+	can be manipulated:
+
+	SetAbility(string ability, int value)
+	  Sets <ability> to <value>.
+
+	int QueryAbility(string ability)
+	  Ask the value of <ability>.
+
+	Equipment. Weaponclass and armourclass are defined. Unless
+	a weapon is used, the wc is 0. Unless an armour is used,
+	the ac is 0. (P_WC and P_AC)
+
+	Live variables. A living creature has several needs just
+	because it is alive. The complex life functions are
+	reducced to some crucial factors.
+
+	P_HP
+	  These are mainly determined by the constitution and give
+	  the ability of the body to absorb damage. If the
+	  hitpoints go below zero, the creature is dead.
+
+	P_SP
+	  Spellpoints (sometimes called mana) describe the magical
+	  (spiritual) capability of the creature. It is mainly
+	  determined by Intelligence and Wisdom. It is up to the
+	  creature how good it uses the spellpoint resource.
+	  Spellpoints will go down when supernatural actions are
+	  performed by the creature.
+
+	P_MAX_SP, P_MAX_HP
+	  Readonly variable which are computed from attributes.
+
+	P_FOOD, P_DRINK, P_ALCOHOL, (P_POISON)
+	  These three variables describe hunger, thirst and
+	  intoxication by alcohol. The max is dependent on the
+	  constitution of the living, and of the weight.
+	  These variables automatically decrease with time.
+	  When food or drink goes below zero, the creature
+	  suffers hunger or thirst and will lose hitpoints.
+
+	P_MAX_FOOD, P_MAX_DRINK, P_MAX_ALCOHOL
+	  Readonly variables which are computed from attributes.
+
+	P_WEIGHT, P_SIZE
+	  These variables describe the physical proportions of
+	  the creatures body. Both variables are standard properties
+	  and are also used in normal objects.
+
+	P_MAX_WEIGHT 
+	  This is a readonly variable which describes how much
+	  a living creature may carry around.
+
+	P_GENDER
+	  This is obvious. Gender may be MALE, FEMALE or NEUTER,
+	  as defined in <living.h>. Player gender may be only
+	  MALE or FEMALE.
+
+	P_RACE
+	  A string which defines the race.
+
+	P_ALIGNMENT
+	  The alignment of the living, ranging frO
+
+	P_AGE
+	  The age of the living creature in seconds
+	
+
+INHERITANCE TREE:
+	living
+	  |-thing/moving
+	  |-thing/properties
+	  `-thing/description
+
+
+SEE ALSO:
+	properties(C), units(C)
diff --git a/doc/std/obsolete/door b/doc/std/obsolete/door
new file mode 100644
index 0000000..15bad30
--- /dev/null
+++ b/doc/std/obsolete/door
@@ -0,0 +1,22 @@
+****************************************************************************
+************************* VERALTETE LFUN ***********************************
+************************* DO NOT USE!    ***********************************
+****************************************************************************
+
+BITTE STATT DER FUNKTION Door() IMMER  NewDoor() BENUTZEN.
+
+	AddDoor(string command, string roomfile, string doorname,
+		string doordesc, string keyname, int status)
+	  Creates a door which leads in direction <command> to the
+	  room <roomfile>. The door has the short description
+	  <doorname> and the long description <doordesc>, when you
+	  look at it. If a door with the same <doorname> exists in
+	  the other room, the open/close/locked status will be
+	  the same in both rooms at all time. Doors are locked on
+	  reset() if keyname is not 0. If <keyname> is given, the
+	  door is locked and can be opened only with a key which
+	  matches <keyname> with its id(). <status> can be set
+	  to an initial value of DOOR_STATUS_OPEN, DOOR_STATUS_CLOSED
+	  or DOOR_STATUS_LOCKED. These status codes are defined in
+	  <doors.h>.
+
diff --git a/doc/std/pub b/doc/std/pub
new file mode 100644
index 0000000..21544a7
--- /dev/null
+++ b/doc/std/pub
@@ -0,0 +1,95 @@
+Um die Funktionalitaet einer Kneipe nutzen zu koennen, muss der Raum eine
+der folgenden Dateien importieren:
+
+'/std/pub.c'         - die Komplettloesung inclusive der Abhaengigkeit zu
+                       '/std/room'
+
+'/std/room/pub.c'    - die Mindestloesung, bei der man selbst die Abhaengig-
+                       keit zu einem Raum definieren muss
+
+------------------------------------------------------------------------------
+Eine Zusammenfassung der Pub-Properties (fuer genaueres siehe manpages)
+aus '/sys/pub.h'
+
+P_NPC_FASTHEAL       - NPCs tanken hier auf die "schnelle" Art
+
+P_NO_STD_DRINK       - Der Pub soll keine Standard-Getraenke anbieten
+
+P_PUB_UNAVAILABLE    - Meldung, wenn etwas nicht mehr vorhanden ist
+
+P_PUB_NOT_ON_MENU    - Meldung, wenn etwas nicht im Menue steht
+
+P_PUB_NO_MONEY       - Meldung, wenn Spieler nicht genug Geld hat
+
+P_PUB_NO_KEEPER      - Meldung, wenn der P_KEEPER nicht anwesend ist
+
+aus '/sys/room/description.h'
+
+P_KEEPER             - Id des Kneipeninhabers, der anwesend sein muss, 
+                       damit die Kneipe genutzt werden kann
+
+------------------------------------------------------------------------------
+Methoden zur Manipulation des Menues (fuer genaueres siehe manpages)
+
+AddToMenu            - fuegt einen Eintrag zum Menue hinzu
+
+RemoveFromMenu       - entfernt einen Eintrag aus dem Menue
+
+------------------------------------------------------------------------------
+Ablauf und Manipulationsmoeglichkeiten in einer Kneipe
+
+Wunsch wurde ueber 'kaufe', 'bestelle' oder 'spendiere' abgegeben:
+
+search_what()        - prueft, dass nicht mehrere Wuensche auf einmal
+                       geaeussert werden und ruft consume_something() auf
+
+consume_something()  - prueft die Anwesenheit der beteiligten Personen
+                     - prueft die Anwesenheit des Kneipenbesitzers
+                     - prueft das Ignorieren beim Spendieren
+                     - prueft die Verfuegbarkeit von genuegend Geld beim
+                       Besteller ( check_solvency() )
+                     - prueft die Verfuegbarkeit des Gewuenschten
+                       ( CheckAvailability() )
+                     - prueft, ob der Empfaenger in der Lage ist, das
+                       Bestellte zu konsumieren
+                       ( ueber empfaenger->consume(testonly) )
+
+                     - fuehrt die Bezahlung durch ( do_pay() )
+                     - fuehrt die Vergabe von FPs durch ( GiveEP() )
+                     - entnimmt das Bestellte aus der Menge des Angebotes
+                       ( DecreaseAvailibility() )
+                     - prueft, ob eine Verzoegerung der Lieferung erfolgen
+                       soll und uebergibt im Negativfall gleich an
+                       do_deliver()
+                     - Ausgabe der Meldungen zur Bestellung
+                     - verzoegerter Aufruf von do_deliver()
+                     
+do_deliver()         - prueft nochmal die Anwesenheit des Empfaengers
+                     - prueft, ob Heilung erlaubt ist (ueber Pubmaster)
+                     - prueft P_NPC_FASTHEAL und korrigiert die Angaben, die
+                       aus dem Menueeintrag kommen
+                     - fuehrt das Konsumieren beim Empfaenger durch
+                       ( empfaenger->consume() )
+                     - Ausgabe der Meldung zum Konsumieren
+
+pub_init()           - Moeglichkeit fuer Magier, die Werte der angebotenen
+                       Speisen und Getraenke zu ueberpruefen
+                     - erweiterte Moeglichkeiten zum Pruefen von korrekten
+                       Menueeintraegen bietet das Pub-Tool
+                       ( '/obj/tools/pubtool.c' )
+
+Hinweis: Um diese Pruefungen und Aktionen sicher zu gewaehrleisten, sollte
+         man consume_something oder do_deliver NICHT ueberschreiben!
+         Das fuehrt bei Aenderungen mit grosser Wahrscheinlichkeit zu
+         Problemen!
+         Ueberschreibt besser die Methoden, die die Funktionalitaet
+         beinhaltet, die ihr wirklich anpassen wollt.
+         Falls das nicht geht, sprecht lieber mit einem RM+, ob eine Loesung
+         dafuer gefunden werden kann. Der Standard-Pub wurde in der
+         Vergangenheit so immer modularer und besser.
+
+
+SIEHE AUCH: AddToMenu, RemoveFromMenu, consume, QueryMoney, AddMoney 
+
+------------------------------------------------------------------------------
+Last modified: Son Apr 11 19:28:00 2010 by Caldra
diff --git a/doc/std/random b/doc/std/random
new file mode 100644
index 0000000..489214d
--- /dev/null
+++ b/doc/std/random
@@ -0,0 +1,71 @@
+Es gibt im MG zwei Quellen von Pseudo-Zufallszahlen.
+
+1) random()
+  Diese efun liefert eine Zufallszahl aus dem Pseudo-Zufallszahlengenerator
+  (PRNG) des Drivers. (s. Manpage).
+  Wenn keine besonderen Gruenden vorliegen, sollte immer diese verwendet
+  werden.
+
+
+2) /std/util/rand-glfsr.c
+  Falls jemand aus irgendeinem Grund eine Sequenz von Pseudo-Zufallszahlen
+  braucht, die spaeter reproduzierbar sein soll (d.h. der Seed muss
+  konfigurierbar sein), gibt es unter /std/util/rand-glfsr.c einen simplen,
+  nicht allzu guten und sehr ineffizienten Pseudo-Zufallszahlengenerator.
+
+Interface:
+* public varargs void init(int seed, int newp)
+  Setzt das Seed (und das Erzeugungspolynom, wenn gewuenscht, wovon ich
+  aber abraten wuerde). Der Seed darf nicht 0 sein.
+* public void InitWithUUID(string uuid)
+  Berechnet einen Seed aus der uuid und initialisiert den PRNG damit (und dem
+  Default-Polynom).
+* public int nextbit()
+  Liefert ein zufaelliges Bit (also 0 oder 1).
+* public int nextbits(int count)
+  Liefert <count> Bits (max 64) in einem int.
+* public int random(int n)
+  Liefert eine Zufallszahl zwischen 0 und n-1, in welcher 32 bits an 
+  Pseudozufall stecken.
+  Das Seed von der Blueprint wird vermutlich staendig veraendert (d.h.
+  verlasst euch nicht drauf, dass es konstant bleibt), wollt ihr eine
+  'private' Instanz mit eurem Seed, clont das Objekt (aber verliert den Clone
+  nicht).
+
+  Und um es nochmal zu sagen:
+  Die IMHO einzige sinnvolle Anwendung ist, wenn man aus irgendeinem Grund
+  das seed selber waehlen muss, damit man die Sequenz von Pseudozufall immer
+  wieder reproduzieren kann.
+  In allen anderen Faellen nehmt besser das random() vom Driver.
+
+Der PRNG benutzt ein Linear Feedback Shift Register (in Galois-Variante). Die
+Periodenlaenge des per Default benutzten Erzeugngspolynoms ist 2^32 - 1, d.h.
+nach 4294967295 Bits wiederholt sich die Sequenz.
+Das Default-Polynom ist:
+x^32 + x^31 + x^28 + x^27 + x^24 + x^23 + x^20 + x^19 + x^16 + x^15 + x^12
+     + x^11 + x^8 + x^7 + x^5 + x^3 + 1
+(Zahlenwert: 0x1999999a8)
+
+Wer ein anderes Polynom will, kann das per init() konfigurieren, sollte sich
+aber schlau machen, welche sinnvoll nutzbar sind.
+
+
+Ein paar statistische Daten eines Stroms von 40960 Bits:
+Value Char Occurrences Fraction
+  0            20474   0.499854
+  1            20486   0.500146
+
+Total:         40960   1.000000
+
+Entropy = 1.000000 bits per bit.
+
+Optimum compression would reduce the size
+of this 40960 bit file by 0 percent.
+
+Chi square distribution for 40960 samples is 0.00, and randomly
+would exceed this value 95.27 percent of the times.
+
+Arithmetic mean value of data bits is 0.5001 (0.5 = random).
+Monte Carlo value for Pi is 3.109026964 (error 1.04 percent).
+Serial correlation coefficient is -0.008399 (totally uncorrelated = 0.0).
+
diff --git a/doc/std/room b/doc/std/room
new file mode 100644
index 0000000..94e575f
--- /dev/null
+++ b/doc/std/room
@@ -0,0 +1,143 @@
+STANDARDOBJEKT FUER RAEUME:
+
+BENUTZUNG:
+      inherit "/std/room";
+      
+      #include <properties.h>
+      #include <rooms.h>            // Fuer AddItem() und NewDoor()
+
+BESCHREIBUNG:
+      Ein Raum ist ein Objekt, das von Spielern oder anderen Lebewesen
+      betreten werden kann. Er hat Lang- und Kurzbeschreibungen von
+      innen und aussen (zum Beispiel Schiffe oder aehnliche Raeume in
+      Raeumen), die sich der Spieler je nach seinen Beduerfnissen
+      anzeigen lassen kann (kurz/lang-Modus).
+
+   Properties:
+
+      P_INT_SHORT
+            Kurzbeschreibung innerhalb des Raumes
+      P_INT_LONG
+            Langbeschreibung innerhalb des Raumes
+      P_SHORT
+            Kurzbeschreibung von aussen (nur noetig, wenn man den Raum
+            auch wirklich von aussen sehen kann)
+      P_LONG
+            Langbeschreibung von aussen (siehe P_SHORT)
+      Um Situationsbezogene Beschreibungen zu bekommen, kann man 
+      Querymethoden auf die jeweiligen Properties setzen, siehe Dokumentation
+      zu Set().
+
+      P_LIGHT
+            Lichtlevel des Raums (0 dunkel, 1 hell)
+      P_LIGHT_TYPE
+            Lichtart, mit der der Raum beleuchtet ist, zB LT_SUNLIGHT
+      P_INDOORS
+            Wenn es sich um einen Aussenraum handelt, 0. 1 fuer Innenraeume.
+      P_TRANSPARENT
+            Ist ungleich 0, wenn man in den Raum von aussen reinschauen
+            kann, oder von innen nach aussen
+      P_NO_TPORT
+            Zum verhindern von Teleportversuchen in oder aus dem Raum
+      P_NOMAGIC
+            Im Raum kann nicht gezaubert werden.
+  P_WATER
+    Im Raum kann geangelt werden, und man kann ggf. sogar Fische fangen.
+
+   Funktionen:
+
+  AddExit(string|string* kmnd, string zielraum)
+            <kmnd> kann ein String sein oder eine Liste von Strings
+            mit den Kommandos mit denen der Spieler in <zielraum>
+            landen soll.
+      RemoveExit(string|string* kmnd)
+            <kmnd> ist ein String oder eine Liste von Strings, deren
+            Ausgaenge entfernt werden sollen. Dabei muss man etwas vor-
+            sichtig sein, da ein Spieler, der zum Zeitpunkt des Aufrufs
+            im Raum ist, die Aktion fuer sich noch definiert hat.
+            Also: Nur benutzen, wenn man weiss, was man tut!
+      AddSpecialExit(string|string* kmnd, string funktion)
+            <funktion> wird aufgerufen, wenn der Spieler das Kommando
+            <kmnd> tippt (oder eins der Kommandos, wenn <kmnd> eine
+            Liste ist). Nuetzlich zum Beispiel um einen Spieler nur
+            durchzulassen, wenn ein Waechter nicht da ist.
+            P_AERIAL_HELPERS/P_AQUATIC_HELPERS
+              Sollte es gewuenscht sein, dass bestimmte Raeume z.B. nur 
+              fliegend erreicht werden koennen, oder dass man fuer einen 
+              bestimmten Ausgang tauchen koennen muss, sind diese 
+              Properties hilfreich, die im Spielerobjekt definiert sind 
+              und die dort aktuell registrierten Hilfsobjekte fuers 
+              Fliegen/Segeln und Tauchen enthalten.
+      RemoveSpecialExit(string|string* kmnd)
+            siehe RemoveExit()
+      NewDoor()
+            Fuegt dem Raum eine Tuer hinzu, die in einen zweiten Raum fuehrt,
+            und die der Spieler (ggf. mit einem Schluessel) oeffnen und 
+            schliessen kann.
+      
+      Um Raeume interessanter zu machen, kann man ihnen Details, die 
+      vom Spieler angeschaut werden koennen, einbauen:
+
+      AddDetail(string|string* keys, string descr)
+            Eine Beschreibung von Details, die vom Spieler angeschaut
+            werden koennen wird dem Raum gegeben. <keys> kann ein
+            String sein oder eine Liste von Strings. <descr> ist
+            die Beschreibung, die der Spieler erhaelt.
+      RemoveDetail(string|string* keys)
+            Entfernt ein Detail aus einem Raum. <keys> kann ein String
+            sein oder eine Liste von Strings.
+      AddSpecialDetail(string|string* keys, string function)
+            Im Prinzip wie AddDetail(), nur wird als zweites Argument
+            kein fester String angegeben, sondern eine Funktion, die
+            einen String zurueckgeben muss. Damit kann man variable
+            Details programmieren.
+      RemoveSpecialDetail(string|string* keys)
+            siehe RemoveDetail()
+      AddReadDetail(string|string* keys, string desc)
+            <desc> wird ausgegeben, wenn ein Spieler den <key> liest.
+            <keys> kann wieder ein String oder eine Liste von Strings
+            sein.
+      RemoveReadDetail(string|string* keys)
+            siehe RemoveDetail()
+      AddRoomMessage(string* msg, int prob, string|mixed *func)
+            Alle <prob> Sekunden wird aus einer Liste von Meldungen
+            (<msg>) zufaellig eine ausgesucht, die dann im Raum er-
+            scheint. Wenn das Argument <func> angegeben ist, wird
+            eine Funktion diesen Namens aufgerufen, der der Index
+            der ausgegebenen Meldung als Argument uebergeben wird.
+            Func darf auch einen Array von Funktionen enthalten.
+
+      AddCmd(string|string* cmd, string func, int flag)
+            Im Raum wird beim Kommando <cmd> (oder einem der Kommandos)
+            die Funktion <func> aufgerufen. <func> muss 1 zurueck-
+            geben, wenn die Funktion die Kombination aus Kommando
+            und Argumenten akzeptiert, ansonsten 0. Alles was ein
+            Spieler hinter <cmd> noch angibt, wird der Funktion als
+            Argument uebergeben. Wenn <flag> gesetzt ist, wird jedes
+            Kommando, das mit <cmd> beginnt akzeptiert.
+      RemoveCmd(string|string* cmd)
+            Entfernt ein Kommando aus dem Raum.
+            ACHTUNG: Bei Spielern, die zum Zeitpunkt des Funktions-
+            aufrufs noch im Raum sind, ist das Kommando noch definiert.
+            Also: Nur benutzen, wenn man genau weiss, was man tut.
+
+      AddItem(string filename, int refresh)
+            Ein Objekt mit Pfad <filename> wird erzeugt und in den
+            Raum bewegt, dabei gibt es vier verschiedene Modi, die
+            ueber das Argument <refresh> angegeben werden:
+            REFRESH_NONE: Das Objekt wird nur beim allerersten mal
+                  erzeugt, und dann nie wieder (erst beim reboot)
+            REFRESH_DESTRUCT: Ein neues Objekt wird erst erzeugt, 
+                  wenn das alte zerstoert ist. So kann man sicher
+                  gehen, dass nur ein Exemplar im Spiel ist.
+            REFRESH_REMOVE: Beim reset wird ein neues Objekt erzeugt,
+                  wenn sich das alte nicht mehr im Raum befindet.
+            REFRESH_ALWAYS: Bei jedem reset wird ein neues Objekt 
+                  erzeugt. VORSICHT: Kann zu riesigen Mengen von
+                  Objekten fuehren, wenn ein Raum lange nicht be-
+                  sucht wird.
+            Die Konstanten REFRESH_* sind in <rooms.h> definiert.
+
+      Auf die Properties P_EXITS, P_SPECIAL_EXITS, P_DETAILS, 
+      P_SPECIAL_DETAILS, P_READ_DETAILS, P_COMMANDS und P_ITEMS
+      sollte NICHT direkt zugegriffen werden.
diff --git a/doc/std/room.doku b/doc/std/room.doku
new file mode 100644
index 0000000..e1774c6
--- /dev/null
+++ b/doc/std/room.doku
@@ -0,0 +1,132 @@
+STANDARDOBJEKT FUER RAEUME:
+
+BENUTZUNG:
+	inherit "std/room";
+	
+	#include <properties.h>
+	#include <rooms.h>		// Fuer AddItem() und NewDoor()
+
+BESCHREIBUNG:
+	Ein Raum ist ein Objekt, dass von Spielern oder anderen Lebewesen
+	betreten werden kann. Er hat Lang- und Kurzbeschrreibungen von
+	innen und aussen (zum Beispiel Schiffe oder aehnliche Raeume in
+	Raeumen), die sich der Spieler je nach seinen Beduerftnissen
+	anzeigen lassen kann (kurz/lang-Modus).
+
+   Properties:
+
+	P_INT_SHORT
+		Kurzbeschreibung innerhalb des Raumes
+	P_INT_LONG
+		Langbeschreibung innerhalb des Raumes
+	P_SHORT
+		Kurzbeschriebung von aussen (nur noetig, wenn man den Raum
+		auch wirklich von aussen sehen kann)
+	P_LONG
+		Langbeschreibung von aussen (siehe P_SHORT)
+	Um Situationsbezogene Beschreibungen zu bekommen, kann man 
+	int_short(), int_long(), short(), long() ueberschreiben, oder
+	den process_string Mechanismus verwenden (siehe entsprechende
+	Dokumentation)
+
+	P_LIGHT
+		Lichtlevel des Raums (0 dunkel, 1 hell)
+	P_INDOORS
+		1 Wenn der Raum nicht im Freien ist
+	P_TRANSPARENT
+		Ist ungleich 0, wenn man in den Raum von aussen reinschauen
+		kann, oder von innen nach aussen
+	P_NO_TPORT
+		Zum verhindern von Teleportversuchen in oder aus dem Raum
+		(siehe auch /doc/properties.h)
+	P_NOMAGIC
+		Im Raum kann nicht gezaubert werden.
+
+   Funktionen:
+	AddExit(string|string* kmnd, string zielraum)
+		<kmnd> kann ein String sein oder eine Liste von Strings
+		mit den Kommandos mit denen der Spieler in <zielraum>
+		landen soll.
+	RemoveExit(string|string* kmnd)
+		<kmnd> ist ein String oder eine Liste von Strings, deren
+		Ausgaenge entfernt werden sollen. Dabei muss man etwas vor-
+		sichtig sein, da ein Spieler, der zum Zeitpunkt des Aufrufs
+		im Raum ist, die Aktion fuer sich noch definiert hat.
+		Also: Nur benutzen, wenn man weiss, was man tut!
+	AddSpecialExit(string|string* kmnd, string funktion)
+		<funktion> wird aufgerufen, wenn der Spieler das Kommando
+		<kmnd> tippt (oder eins der Kommandos, wenn <kmnd> eine
+		Liste ist). Nuetzlich zum Beispiel um einen Spieler nur
+		durchzulassen, wenn ein Waechter nicht da ist.
+	RemoveSpecialExit(string|string* kmnd)
+		siehe RemoveExit()
+	NewDoor()
+		siehe /doc/std/door
+	
+	Um Raeume interessanter zu machen, kann man ihnen Details, die 
+	vom Spieler angeschaut werden koennen, einbauen:
+
+	AddDetail(string|string* keys, string descr)
+		Eine Beschreibung von Details, die vom Spieler angeschaut
+		werden koennen wird dem Raum gegeben. <keys> kann ein
+		String sein oder eine Liste von Strings. <descr> ist
+		die Beschreibung, die der Spieler erhaelt.
+	RemoveDetail(string|string* keys)
+		Entfernt ein Detail aus einem Raum. <keys> kann ein String
+		sein oder eine Liste von Strings.
+	AddSpecialDetail(string|string* keys, string function)
+		Im Prinzip wie AddDetail(), nur wird als zweites Argument
+		kein fester String angegeben, sonder eine Funktion, die
+		einen String zurueckgeben muss. Damit kann man variable
+		Details programmieren.
+	RemoveSpecialDetail(string|string* keys)
+		siehe RemoveDetail()
+	AddReadDetail(string|string* keys, string desc)
+		<desc> wird ausgegeben, wenn ein Spieler den <key> liest.
+		<keys> kann wieder ein String oder eine Liste von Strings
+		sein.
+	RemoveReadDetail(string|string* keys)
+		siehe RemoveDetail()
+	AddRoomMessage(string* msg, int prob, string|string *func)
+		Alle <prob> Sekunden wird aus einer Liste von Meldungen
+		(<msg>) zufaellig eine ausgesucht, die dann im Raum er-
+		scheint. Wenn das Argument <func> angegeben ist, wird
+		eine Funktion diesen Namens aufgerufen, der der Index
+		der ausgegebenen Meldung als Argument uebergeben wird.
+		func darf auch einen Array von Funktionen enthalten. Es wird
+		dann zufaellig eine ausgewaehlt.
+
+	AddCmd(string|string* cmd, string func, int flag)
+		Im Raum wird beim Kommando <cmd> (oder einem der Kommandos)
+		die Funktion <func> aufgerufen. <func> muss 1 zurueck-
+		geben, wenn die Funktion die Kombination aus Kommando
+		und Argumenten akzeptiert, ansonsten 0. Alles was ein
+		Spieler hinter <cmd> noch angibt, wird der Funktion als
+		Argument uebergeben. Wenn <flag> gesetzt ist, wird jedes
+		Kommando, das mit <cmd> beginnt akzeptiert.
+	RemoveCmd(string|string* cmd)
+		Entfernt ein Kommando aus dem Raum.
+		ACHTUNG: Bei Spielern, die zum Zeitpunkt des Funktions-
+		aufrufs noch im Raum sind, ist das Kommando noch definiert.
+		Also: Nur benutzen, wenn man genau weiss, was man tut.
+
+	AddItem(string filename, int refresh)
+		Ein Objekt mit Pfad <filename> wird erzeugt und in den
+		Raum bewegt, dabei gibt es vier verschiedene Modi, die
+		ueber das Argument <refresh> angegeben werden:
+		REFRESH_NONE: Das Objekt wird nur beim allerersten mal
+			erzeugt, und dann nie wieder (erst beim reboot)
+		REFRESH_DESTRUCT: Ein neues Objekt wird erst erzeugt, 
+			wenn das alte zerstoert ist. So kann man sicher
+			gehen, dass nur ein Exemplar im Spiel ist.
+		REFRESH_REMOVE: Beim reset wird ein neues Objekt erzeugt,
+			wenn sich das alte nicht mehr im Raum befindet.
+		REFRESH_ALWAYS: Bei jedem reset wird ein neues Objekt 
+			erzeugt. VORSICHT: Kann zu riesigen Mengen von
+			Objekten fuehren, wenn ein Raum lange nicht be-
+			sucht wird.
+		Die Konstanten REFRESH_* sind in <rooms.h> definiert.
+
+	Auf die Properties P_EXITS, P_SPECIAL_EXITS, P_DETAILS, 
+	P_SPECIAL_DETAILS, P_READ_DETAILS, P_COMMANDS und P_ITEMS
+	sollte NICHT direkt zugegriffen werden.
diff --git a/doc/std/schluessel b/doc/std/schluessel
new file mode 100644
index 0000000..5a23db2
--- /dev/null
+++ b/doc/std/schluessel
@@ -0,0 +1,24 @@
+STANDARDOBJEKT FUER SCHLUESSEL:
+
+BENUTZUNG
+	inherit "/d/unterwelt/std/schluessel"
+
+BESCHREIBUNG   
+	Du erzeugst einen Schluessel der nur auf eine bestimmte Tuer
+	passt.
+
+    Funktionen:
+
+	create():
+		setzt ein paar Defaultwerte.
+
+	SetDoorKey( string str):
+		gibt den Schluessel eine spezielle Beschreibung, die 
+		auf die Tuer passen muss.
+
+	QueryDoorKey()
+		fragt den string des Schluessels ab.
+
+SIEHE AUCH:
+	tuer
+
diff --git a/doc/std/sequencer b/doc/std/sequencer
new file mode 100644
index 0000000..d9b17a3
--- /dev/null
+++ b/doc/std/sequencer
@@ -0,0 +1,58 @@
+Version 2.0 des Sequencers von Don Rumata 2.7.93
+
+Manchmal soll ein NPC (Monster) eine Serie von Taetigkeiten
+hintereinander weg ausgefuerht werden. Dieses kann man
+mit diesem Mudul relativ einfach realisieren.
+
+Folgende Ereignisse koennen eine Sequenz ausloesen:
+
+	TellEvent: Es wird etwas in dem Raum, in dem der npc sich
+		befindet, gesagt.
+	GiveEvent: Es wird dem npc etwas gegeben.
+
+Weitere Ereignisse koennen durch den Befehl Load() selber
+programmiert werden.
+
+Wie sieht ein Programm aus?
+
+	Ein Programm ist eine Liste von Befehlen.
+	Jeder Befehl ist eine Liste, bestehend aus einem Kommando
+	und einer Zahl.
+	Das Kommendo wird aehnlich der Befehle, die ein Spieler ein-
+	gibt ausgefuehrt.
+	Vorsicht: NPCs koennen nur einen Teil der Befehle, die ein
+	Spieler kann, dafuer aber immer 'echo' und 'emote'.
+	Die Zahl gibt die Anzahl der Sekunden an, in der der naechste
+	Befehl ausgefuehrt wird.
+
+Folgende Funktionen sind im Modul implementiert:
+
+	Vorbereiten von Funktionen, die eine Sequenz ausloesen:
+
+	RegisterTell( funktion, programm )
+		Wenn dem npc etwas gesagt wird, so wird die gesagte Meldung
+		an die Funktion uebergeben. Gibt die Funktionen nicht 0
+		zurueck, wird das Programm gestartet.
+		
+	RegisterGive( funktion, programm )
+		Wird dem npc etwas gegeben, so wird das Objekt an die
+		Funktion uebergeben. Gibt die Funktion nicht 0 zurueck, so
+		wird das Programm gestartet.
+
+	Load( programm )
+		Starte das angegebene Programm.
+
+Anederungen an bestehenden Std-Funktionen:
+
+	give_notify() gibt eine 1 zurueck, wenn das Objekt akzeptiert
+		wurde. (Es muss - falls gewuenscht - dann von Hand zuruech-
+		gegeben werden. (give_obj(ob,this_player())) in dieser
+		Funktion.
+
+	Mittels add_action() kann man im create() des NPCs eigene
+	Verben fuer den NPC einfuehren.
+
+Es kann immer nur eine Funktion (egal ob via Tell, Give oder Load) angemeldet
+sein. Es kann immer nur ein Programm gleichzeitig laufen.
+
+Ideen und Bugreports an Rumata
diff --git a/doc/std/thing b/doc/std/thing
new file mode 100644
index 0000000..445b462
--- /dev/null
+++ b/doc/std/thing
@@ -0,0 +1,205 @@
+STANDARD KLASSE:
+	"/std/thing" 
+
+BENUTZUNG:
+	inherit "/std/thing";
+
+	#include <thing.h>
+	#include <properties.h>
+
+PROPERTIES:
+	<thing/commands>
+		P_COMMANDS	-- Befehle assoziiert mit dem Objekt
+	<thing/description>
+		P_NAME		-- Name
+		P_NAME_ADJ	-- Namensadjektiv
+		P_SHORT		-- Kurzbeschreibung
+		P_LONG		-- Langbeschreibung
+		P_IDS		-- Identifikatoren (Feld von Zeichenketten)
+		P_ADJECTIVES	-- Adjektive zur Beschreibung
+	<thing/language>
+		P_ARTICLE	-- Artikel des Objekts
+		P_GENDER	-- Geschlecht des Objekts
+	<thing/moving>
+		P_NODROP	-- Kann nicht fallengelassen werden
+		P_NOGET		-- Kann nicht genommen werden
+	<thing/properties>
+		P_UID		-- User ID
+		P_EUID		-- Effektive User ID
+	<thing/restrictions>
+		P_WEIGHT	-- Gewicht des Objekts
+		P_TOTAL_WEIGHT	-- Gewicht inklusive des Inhalts
+	
+MAKROS:
+	<thing/properties>
+		F_VALUE		-- Propertywert
+		F_MODE		-- Propertymodus umschalten
+		F_MODE_AS	-- Propertymodus setzen
+		F_MODE_AD	-- Propertymodus loeschen
+		  SAVE		  -- Property wird gespeichert
+		  PROTECTED	  -- Property is geschuetzt
+		  SECURED	  -- Property kann nie mehr geaendert werden
+		  NOSETMETHOD	  -- Property besitzt keine Setzfunktion
+		F_SET_METHOD	-- Funktion zum setzen der Property
+		F_QUERY_METHOD	-- Funktion zum lesen der Property
+	<thing/language>
+		MALE, FEMALE, NEUTER 	-- Geschlechter
+		WER, WESSEN, WEM, WEN 	-- Fall
+		RAW 			-- fuer Namen ohne Artikel
+		SINGULAR, PLURAL 	-- Zeiten
+	
+FUNKTIONEN:
+	"/std/thing/commands":
+		varargs void AddCmd(mixed cmd, mixed func, int flag);
+		varargs void RemoveCmd(mixed cmd);
+	"/std/thing/description":
+		varargs int id(string str, int lvl);
+		void AddId(mixed str);
+		void AddAdjective(mixed str);
+		string name(int casus,int demon);
+	"/std/thing/language":
+		varargs string QueryArticle(int casus, int dem, int force);
+		varargs int SuggestArticle(string id);
+		varargs string QueryPossPronoun(mixed what, int casus, 
+		                                int number);
+		string QueryPronoun(int casus);
+		varargs string QueryDu(int casus,int gender, int zahl);
+		string QueryGenderString();
+		varargs string DeclAdj(string adj, int casus, int demon);
+	"/std/thing/properties":
+		varargs mixed Set(string name, mixed Value, int Type); 
+		varargs mixed Query(string name, int Type);
+		mixed SetProp(string name, mixed Value);
+		mixed QueryProp(string name);
+		void SetProperties(mapping props);
+		mapping QueryProperties();
+	"/std/thing/moving":
+		int move(mixed dest,int method);
+		varargs int remove();
+
+ERLAEUTERUNG:
+	"/std/thing" ist eine generelle Klasse fuer Objekte aller Art.
+	Es bietet generelle Funktionalitaet zur Erstellung von neuen
+	Klassen und Objekten. Sie kann mittels der zur Verfuegung
+	stehenden Funktionen konfiguriert werden:
+
+	** "/std/thing/commands":
+	varargs void AddCmd(mixed cmd, mixed func, int flag);
+	  Um dem Objekt die Moeglichkeit zu geben, auf Befehle zu reagieren,
+	  kann mit AddCmd() Kommandos definiert werden, die eine bestimmte
+	  Funktion (func) aufrufen. flag entscheidet darueber, ob das Kommando
+	  (cmd) abgekuerzt werden kann (flag = 1) oder nicht (flag = 0).
+
+	varargs void RemoveCmd(mixed cmd);
+	  Man kann die Kommandos jederzeit wieder mit der Funktion RemoveCmd()
+	  entfernen.
+
+	** "/std/thing/description":
+	varargs int id(string str, int lvl);
+	  Die Funktion id() behandelt die Identifikatoren eines Objektes, 
+	  welche in der Property P_IDS gespeichert sind. Jedesmal, wenn ein
+	  Objekt durch Kommandos wie "nimm", "lass fallen" etc referenziert
+	  werden soll, wird id() mit dem Namen des Objektes aufgerufen. Dabei
+	  werden dann die Elemente von P_IDS mit str verglichen und das Ergeb-
+	  nis (WAHR/FALSCH == 1/0) zurueckgegeben. lvl ist fuer die Behandlung
+	  von Lebewesen notwendig, siehe living.
+	
+	void AddId(mixed str);
+	  Mittels dieser Funktion kann ein oder mehrere neue Identifikatoren
+	  der Liste der bestehenden, Standard ist "ding", hinzugefuegt werden.
+
+	void AddAdjective(mixed str);
+	  Um den Objekten die Moeglichkeit zu geben, sich besser zu beschreiben
+	  oder zur besseren Identifizierung, kann man mit AddAdjective() dem
+	  Objekt naeher beschreibende Adjektive hinzufuegen. Diese sind in
+	  P_ADJECTIVES gespeichert.
+
+	string name(int casus,int demon);
+	  Diese Funktion liefert den Namen des Objektes mit allen zusaetzlichen
+	  Attributen im gewuenschten Fall (casus), demonstrativ (demon = 1) 
+	  oder nicht demonstrativ (demon = 0).
+
+	** "/std/thing/language":
+	varargs string QueryArticle(int casus, int dem, int force);
+	  Artikel im passenden Fall sowie demonst. bzw undemonst. zurueck-
+	  geben. force ueberschreibt das SetArticle-Flag.
+
+	varargs int SuggestArticle(string id);
+	  Empfehle einen Artikel fuer das Objekt, getestet wird, ob ausser
+	  diesem Objekt sich ein anderes Objekt mit der id im selben
+	  Raum befindet.
+
+	varargs string QueryPossPronoun(mixed what, int casus, int number);
+	  Gib ein Pronomen zurueck, das ausdrueckt, das ein Objekt diesem
+	  Objekt gehoert. Dabei ist what das Geschlecht des Objektes.
+
+	string QueryPronoun( casus );
+	  Er/Sie/Es u.ae. zurueckgeben.
+
+	varargs string QueryDu(int casus,int gender, int zahl);
+	  Du im passenden Fall zurueckgeben (siehe QueryArticle()).
+
+	string QueryGenderString();
+	  Gibt das Geschlecht in Worten zurueck.
+
+	varargs string DeclAdj(string adj, int casus, int demon); 
+	  Dekliniere Adjektive adj mit Casus casus.
+
+	** "/std/thing/properties":
+	varargs mixed Set(string name, mixed Value, int Type); 
+	  Setze einen Wert einer Property direkt, wobei der Typ des Wertes
+	  (Value) durch F_VALUE, F_MODE, F_SET_METHOD, F_QUERY_METHOD (Type)
+	  angegeben wird. 
+	  F_VALUE -- darf ein beliebiger Wert sein
+	  F_MODE  -- muss eine Zahl sein (SAVE, PROTECTED, SECURED, 
+	             NOSETMETHOD)
+	  F_SET_METHOD, F_QUERY_METHOD -- 0 oder eine Closure
+
+	varargs mixed Query(string name, int Type);
+	  Lies den Wert einer Property aus. Dabei gibt Type an, welchen Wert
+	  (F_VALUE, F_MODE, F_SET_METHOD, F_QUERY_METHOD) man auslesen will.
+
+	mixed SetProp(string name, mixed Value);
+	  Setze den Wert einer Property. Dabei wird, falls vorhanden, der Wert
+	  noch durch die F_SET_METHOD behandelt (z.B. Typueberpruefung).
+	  Dies sollte die Standardmethode zum Setzen einer Property sein!
+  
+	mixed QueryProp(string name);
+	  Lies den Wert einer Property, wobei der eigentliche Wert durch die,
+	  falls vorhanden, F_QUERY_METHOD behandelt wird. Als Beispiel dient
+	  hier die Behandlung des Gesamtgewichts, welches durch Abfragen von
+	  P_TOTAL_WEIGHT ausgelesen werden kann; hierbei errechnet die 
+	  F_QUERY_METHOD von P+_TOTAL_WEIGHT erst das totale Gewicht.
+	  Dies sollte die Standardmethode sein um eine Property auszulesen!
+
+	void SetProperties(mapping props);
+	  Diese Funktion kann die in props gespeicherten Properties im Objekt
+	  unterbringen. Dabei werden schon vorher als PROTECTED oder SECURED
+	  gekennzeichnete Properties NICHT ueberschrieben.
+
+	mapping QueryProperties();
+	  Liefert ein mapping, welches von SetProperties() behandelt werden
+	  kann.
+
+	** "/std/thing/moving":
+	int move(mixed dest,int method);
+	  Jedesmal, wenn ein Objekt bewegt werden soll, wird die Funktion
+	  move() aufgerufen, welche dann das eigentliche Bewegen ausfuehrt.
+	  Dazu muss der Funktion ein Ziel (dest) als Zeichenkette oder als
+	  Objekt und eine Methode der Bewegung uebergeben werden.
+	
+	varargs int remove();
+	  Wird ein Objekt zerstoert, wird die Funktion remove() aufgerufen.
+	  Rueckgabewert 1 bedeutet Erfolg und 0 Misserfolg der Zerstoerung.
+
+VERERBUNGSBAUM:
+	thing
+	  |-thing/commands
+	  |-thing/description
+	  |-thing/language
+	  |-thing/moving
+	  |-thing/properties
+	  `-thing/restrictions
+
+SIEHE AUCH:
+	properties, closures 
diff --git a/doc/std/transport b/doc/std/transport
new file mode 100644
index 0000000..3000c97
--- /dev/null
+++ b/doc/std/transport
@@ -0,0 +1,264 @@
+> FUNKTIONSWEISE VON TRANSPORTERN <
+Version 1.0 (04.05.1993) von Rumata
+===================================
+
+
+INHALT:
+======
+
+	1.	Allgemeines
+	2.	Properties
+	3.	Haltestellen
+	4.	Steuerung
+	5.	Betreten und verlassen
+	6.	Extras
+	7.	Kommandos in Trnasportern
+
+
+1. ALLGEMEINES
+==============
+
+	Ein Transporter ist ein Raum mit besonderen Eigenschaften.
+	Waehrend normale Raume miteinnder starr verbunden sind,
+	kann dieser Raum seine Verbindung zu anderen Raeumen mit
+	der Zeit aendern.
+
+	Jeder Transporter besitzt einen 'Kurs' den er abfaehrt; nach der
+	letzten 'Haltestelle' beginnt der Kurs wieder von Vorne.
+	Will man einen Kurs setzen, der entlang einer Strecke hin-
+	und zurueck fuehrt, so muss man jede Haltestelle einmal fuer
+	den Hinweg und einmal fuer den Rueckweg einfuegen.
+
+	Ein Beispiel, wie man einen solchen Transporter programmiert,
+	ist in /doc/beispiele/wolke.c zu sehen (und zu laden :-).
+
+2. PROPERTIES
+=============
+
+	P_ENTERMSG
+		Array mit zwei Meldungen in der Art von msgin und
+		msgout.  Die erste Meldung ist fuer den Raum, den der
+		Spieler verlaesst, und die zweite fuer den Transporter,
+		in den er geht.
+
+	P_LEAVEMSG
+		Array mit zwei Meldungen, eine fuer den Transporter, den
+		er verlaesst, und eine fuer den Raum, in den er kommt.
+
+	P_ENTERFAIL
+		Meldung an ein Wesen, wenn den vollen Transporter
+		betreten will. Ist die Prop. ein Array, so wird das erste
+		Element als Meldung an das Wesen, das zweite als Meldung
+		an die Mitspieler im Raum geschickt. Ist die Property
+		eine Closure, wird diese ausgefuehrt, wenn ein Spieler
+		vergeblich versucht, den Transporter zu betreten.
+
+	P_LEAVEFAIL
+		Meldung an ein Wesen, wenn es ausserhalb der Anlegezeiten
+		den Transporter verlassen will. Ist die Prop. ein Array,
+		so wird das erste Element als Meldung an das Wesen, das
+		zweite als Meldung an die Mitspieler im Transporter
+		geschickt. Ist die Property eine Closure, wird diese
+		ausgefuehrt, wenn ein Spieler vergeblich versucht, den
+		Transporter zu verlassen.
+
+	P_ARRIVEMSG
+		Ein Array mit zwei Meldungen. Das erste Element ist die
+		Meldung, die die Wesen im Transporter bekommen. Die
+		zweite Meldung ist fuer die Wesen in dem Raum, an dem
+		der Transporter anlegt. 
+
+	P_DEPARTMSG
+		Dito fuer das Ablegen.
+
+	P_MAX_PASSENGERS
+		Numerischer Wert fuer die maximale Anzahl von Wesen, die
+		sich in dem Transporter aufhalten duerfen.
+		0 bedeutet unbeschaenkte Spielerzahl.
+
+
+3. HALTESTELLEN
+===============
+
+	Es gibt 3 Sorten von Haltestellen:
+
+	1.) Raeume als Haltestellen.
+
+	FUNKTION:
+	
+		AddRoute( raum, verweil, next );
+		oder
+		AddRoute( raum, verweil, next, code );
+
+	PARAMETER:
+
+		raum	- Raum, an dem der Transporter halten soll.
+		verweil	- Zeit in Sekunden, die der Transporter in dem
+			  Raum verbleibt, bis er weiterfaehrt.
+		next	- Zeit in Sekunden bis zur naechsten Halte-
+			  stelle.
+
+		code	- Text, der von der Funktion QueryArrived
+			  zurueckgegeben wird, wenn der Transporter
+			  an dieser Haltestelle angelegt hat.
+			  Wird dieser Parameter nicht angegeben, wird
+			  ein leerer String als code gesetzt.
+
+	2.) Meldungen als Haltestellen.
+
+	FUNKTION:
+
+	      AddMsg( text, next );
+
+	PARAMETER:
+
+		text	- Text, der Meldung, die in dem Transporter
+			  ausgegeben wird.
+		next	- Zeit in Sekunden bis zur naechsten Halte-
+			  stelle.
+
+	3.) Funktionsaufrufe als Haltestellen.
+
+	FUNKTION:
+
+		AddFun( fun, next );
+
+	PARAMETER:
+
+		fun	- Name einer Funktion, die im Transporter
+			  aufgerufen wird.
+		next	- Zeit in Sekunden bis zur naechsten Halte-
+			  stelle.
+
+4. STEUERUNG
+============
+
+	FUNKTION
+
+		Start();
+		oder
+		Start(nummer);
+
+	BESCHREIBUNG:
+
+		Der Transporter soll sofort an der Haltestelle mit
+		der angegebenen Nummer (keine Nummer heisst an der ersten)
+		anlegen und von da ab seinen Kurs fahren.
+
+	FUNKTION:
+
+		Halt();
+
+	BESCHREIBUNG:
+
+		Halte die Fahrt an. Der Transporter bleibt stehen, wo
+		er ist.
+
+
+5. BETRETEN UND VERLASSEN
+=========================
+
+	Der Transporter hat keine Verben programmiert, mit denen man
+	den Transporter betreten oder verlassen kann.
+	Dafuer muessen mit AddCmd() Verben eingefuehrt werden, die
+	auf selbstgeschriebene Funktionen zugreifen.
+
+	FUNKTION:
+
+		Enter();
+
+	BESCHREIBUNG:
+
+		Teste, ob fuer dun aktuellen Spieler (this_player())
+		noch Platz im Transporter ist und ob er sich ausserhalb
+		des Transporters befindet. Wenn ja, bewege ihn in den
+		Transporter. Wenn der Transporter eine Reaktion (Bewegen des
+		Spielers oder Ueberlauf), so gib eine 1 zurueck sonst eine 0.
+
+		Wenn der Transporter nicht da (also unsichtbar) ist, tue fuer
+		die Spieler ausserhalb des Transporters so,
+		als ob das Verb nicht definiert wurde.
+
+		Dieser Wert kann im allgemeinen direkt als returnwert benutzt
+		werden.
+
+	FUNKTION:
+
+		Leave();
+
+	BESCHREIBUNG:
+
+		Wenn der Momentane Spieler nicht im Transporter ist, so gib
+		eine Fehlermeldung aus. Anderenfalls teste, ob der
+		Transporter an einen Raum angelegt hat. Wenn nein, gebe
+		die LEAVEFAIL Meldung aus; und wenn alles ok ist, so
+		bewege den Spieler aus dem Transporter.
+
+6. EXTRAS
+=========
+
+	FUNKTION:
+
+		QueryArrived();
+
+	BESCHREIBUNG:
+
+		Gebe den Code des Raumes zurueck, an dem der Transporter
+		gerade anliegt. Hat der Raum keinen Code, gebe einen
+		Leerstring zurueck. Liegt der Transporter an keinem Raum
+		an, so gebe 0 zurueck.
+
+		Diese Funktion bietet sich an um mittels process_string
+		die Ankunfts- und Abfahrtsmeldungen abwechslungsreich
+		zu gestalten.
+
+	FUNKTION:
+
+		QueryPassengers(),
+
+	BESCHREIBUNG:
+
+		Gebe eine Liste mit allen Lebewesen, die sich auf/in dem
+		Transporter befinden, zurueck.
+
+	FUNKTION:
+
+		RemoveRoute();
+
+	BESCHREIBUNG:
+
+		Halte den Transporter an und loesche dessen Kurs.
+
+7. KOMMANDOS IN TRANSPORTERN
+============================
+
+	Da sich der Transporter in dem Raum befindet, in dem er angelegt
+	hat, sind alle Kommandos des Transporters auch dort verfuegbar.
+	Selbst wenn der Transporter abgelegt hat, steht er noch immer
+	unsichtbar dort herum.
+
+	Deshabl muss in den Kommandos vorsorge grtroffen werden, dass nur
+	die richtigen Spieler (die drinnen und die draussen) die richtigen
+	Kommandos ausfuehren koennen.
+
+	KOMMANDOS FUER SPIELER AUSSERHALB:
+
+		Es muss abgetestet werden, ob der Spieler nicht im
+		Transporter ist, und ob der Transporter angelegt hat.
+
+		if( environment(this_player())==this_object() 
+			|| !QueryArrived() ) return 0;
+
+	KOMMANDOS FUER SPIELER INNERHALB:
+
+		Abtesten, ob der Spieler wirklich im Transport ist.
+
+		if( environment(this_player())!=this_object() )
+			return 0;
+
+		Vorsicht auch bei AddExits innerhalb des Transporters,
+		aber daran arbiete ich noch... :-)
+
+	Die Funktionen Enter() und Leave() haben diese Funktionalitaet
+	eingebaut.
+
diff --git a/doc/std/tuer b/doc/std/tuer
new file mode 100644
index 0000000..489fd84
--- /dev/null
+++ b/doc/std/tuer
@@ -0,0 +1,42 @@
+STANDARDOBJEKT FUER TUEREN:
+
+BENTUZUNG:
+	inherit "std/tuer";
+
+	#include <tuer.c>
+	
+BESCHREIBUNG:
+	Basisklasse fuer alle Tueren im Spiel. Sie ist von /std/thing
+	abgeleitet.
+
+    Funktionen:
+
+	AddDoor2( strin short,
+		  string long,
+		  mixed id,
+		  mixed dest,
+		  string com,
+		  int flags,
+		  string key,
+		  string func,
+		  object obj )
+
+		Erzeugt eine neue Tuer, wobei die Parameter folgendes angeben:
+
+		short 	= Kurzbeschreibung der Tuer
+		long	= Ausfuehrliche Beschreibung der Tuer
+		id	= Name[n] der Tuer
+		dest	= Kommando zum Durchschreiten der Tuer, z.B. 'norden'
+
+		Optionale Parameter:
+
+		flags	= Flags aus tuer.h
+		key	= String, der im Schluessel definiert sein muss, damit
+			  er 'passt'.
+		func	= Funktion die beim Durchschreiten der Tuer in obj
+			  aufgerufen werden soll.
+		obj	= Objekt in dem func aufgerufen werden soll.
+
+SIEHE AUCH:
+	schluessel
+
diff --git a/doc/std/unit b/doc/std/unit
new file mode 100644
index 0000000..3c75059
--- /dev/null
+++ b/doc/std/unit
@@ -0,0 +1,102 @@
+Units
+
+DEFINIERT IN: 
+        /std/unit.c
+
+BESCHREIBUNG:
+        Das Unit-Objekt kann dazu verwendet werden, um groessere Mengen
+        eines Objektes - wie Muenzen - zu erzeugen.
+
+        Das grundlegende Konzept ist, das Unit-Objekte nicht mehr nur 
+        ueber ihre Namen, sondern auch ueber ihre Menge angesprochen 
+        werden kann.
+
+        So wird das id() der Muenzen nicht nur 'muenzen' sondern auch 
+        '3 muenzen' verstehen und auswerten koennen.
+
+        move() kann Teile des ganzen Unit-Objekts bewegen, ein neuer
+        Clone wird erzeugt und diesem der verbleibende Rest der Menge
+        zugewiesen. Nach erfolgreichem move() schaut das Unit-Objekt am
+        Zielort, ob dort evtl. bereits Units des gleichen Typs vorhanden
+        sind und vereinigt sich ggf. mit ihnen, in dem das alte Unit-
+        Objekt zerstoert wird.
+
+        Unit-Objekte werden in einigen Dinger anders programmiert, dazu
+        gehoert folgendes:
+
+        P_SHORT                 ES WIRD KEINE P_SHORT GESETZT!
+
+        P_AMOUNT                Die Menge des Unit-Objekts 'von Haus aus',
+                                also beim Clonen (daher meistens 1)
+
+        P_NAME                  Bei Unit-Objekten kann hier ein String-Array
+                                in der Form ({ SINGULAR_NAME,PLURAL_NAME })
+                                angegeben werden
+
+        SetCoinsPerUnits        Wieviel ist eine bestimmte Menge wert
+        NICHT P_VALUE
+
+        SetGramsPerUnits        Wieviel wiegt eine bestimmte Menge
+        NICHT P_WEIGHT
+
+        AddSingularId		String-Array mit den Singular-IDs 
+        AddPluralId		String-Array mit den Plural-IDs
+
+        zusaetzlich koennen natuerlich IDs per AddId vergeben werden
+
+        Weiterhin verfuegen Unit-Objekte ueber die Moeglichkeit eines
+        automatischen Zerfalls. Dieser ist steuerbar ueber die Props
+        P_UNIT_DECAY_INTERVAL, P_UNIT_DECAY_QUOTA, P_UNIT_DECAY_FLAGS,
+        P_UNIT_DECAY_MIN. Hierbei wird der Zerfall von der Blueprint des
+        Unit-Objektes gesteuert, was als Zerfallsmaster fungiert, weil Clones
+        nicht unbedingt immer nen Reset haben muessen. Die entsprechenden
+        Props sollten daher in der Blueprint konfiguriert werden. (s. Manpages 
+        und Beispiel)
+
+BEISPIELE:
+        Wir basteln uns ein ganz einfaches Unit-Objekt:
+
+        inherit "/std/unit";
+
+        protected void create()
+        {
+          if(!clonep(this_object())) {
+              set_next_reset(-1);
+              return;
+          }
+          ::create();
+          SetProp(P_LONG,"Das ist die kleine Leiche einer Ameise.\n");
+          SetProp(P_NAME,({ "Ameisenleiche","Ameisenleichen" }));
+          SetProp(P_AMOUNT,1);       // es handelt sich um 1 einziges Objekt
+          SetCoinsPerUnits(20,10);   // 10 Objekte sind 20 Muenzen wert
+          SetGramsPerUnits(1,10);    // 10 Objekte wiegen 1 Gramm
+          
+          AddSingularId( ({ "leiche","ameisenleiche" }) );
+          AddPluralId( ({ "leichen","ameisenleichen" }) );
+          
+          AddId("\n-MeineAmeisenleiche");
+        }
+
+        Wir basteln nun ein Unitobjekt, was zerfallen soll:
+        inherit "/std/unit";
+        protected void create() {
+            // Konfig s.o. ...
+            if (!clonep()) {
+              // Zerfall alle 3h
+              SetProp(P_UNIT_DECAY_INTERVAL, 3*3600);
+              // es zerfallen jeweils 10%
+              SetProp(P_UNIT_DECAY_QUOTA, 1000);
+              // es sollen min. 10 Einheiten jeweils uebrigbleiben
+              SetProp(P_UNIT_DECAY_MIN, 10);
+            }
+        }
+
+SIEHE AUCH:
+        P_AMOUNT, P_NAME, P_UNIT_DECAY_INTERVAL, P_UNIT_DECAY_QUOTA, 
+        P_UNIT_DECAY_MIN, P_UNIT_DECAY_FLAGS
+        DoDecay(), doDecayMessage(), SetGramsPerUnits(), SetCoinsPerUnits(), 
+        AddSingularId(), AddPluralId(), QueryCoinsPerUnits(),
+        QueryGramsPerUnits()
+        /std/unit.c
+
+14.10.2007, Zesstra
diff --git a/doc/std/util b/doc/std/util
new file mode 100644
index 0000000..8bf3527
--- /dev/null
+++ b/doc/std/util
@@ -0,0 +1,34 @@
+DEFINIERT IN: 
+     /std/*.c
+
+BESCHREIBUNG:
+     Diese Mangepage beschreibt kein Einzelobjekt, sondern eine Sammlung von
+     Programmen.
+     Im Verzeichnis /std/util/ liegen mehrere Helferklassen, die Funktionen
+     bereitstellen, die nicht nur einem Objekt verwendet werden.
+
+     Momentan sind dies:
+     executer.c   - stellt eine Funkton execute_anything() beret.
+     input.c      - stellt eine Funtion intput() bereit, welche inptu_to()
+                    kapselt.
+     pager.c      - Stellt die Funktion More() und ihre Helfer bereit.
+     ringbuffer.c - Stellt einen Ringpuffer und die notwendigen Verwaltungs-
+                    funktionen bereit.
+
+     Ringbuffer.c:
+     ------------
+     Dies ist ein Puffer (Array) einer bestimmten Groesse. Sobald er voll ist
+     wird automatisch die jeweils aeltesten Daten ueberschrieben, sobald etwas
+     neues hineingeschrieben wird. Ein Ringpuffer mit einer Groesse von 30
+     speichert also die letzten 30 hineingeschriebenen Objekte.
+     * CreateRingBuffer(): erstellt einen neuen Ringpuffer.
+     * ResizeRingBuffer(): aendert die Groesse eines Ringpuffers.
+     * RingBufferPut(): schreibt ein neues Datum in den Puffer.
+     * RingBufferGet(): liefert die Daten des Ringpuffers zurueck.
+
+SIEHE AUCH:
+     CreateRingBuffer, ResizeRingBuffer, RingBufferPut, RingBufferGet
+
+LETZTE AeNDERUNG:
+23.05.2008, Zesstra
+
diff --git a/doc/std/vererbungsbaeume b/doc/std/vererbungsbaeume
new file mode 100644
index 0000000..2df21cc
--- /dev/null
+++ b/doc/std/vererbungsbaeume
@@ -0,0 +1,293 @@
+
+  Vererbungsbaeume der Basis-MUDlib
+  =================================
+
+Einfache Gegenstaende
+---------------------
+
+Die einfachsten Objekte der Basis-MudLib. Die Module, die von thing.c
+geerbt werden, enthalten die wichtigsten Funktionen und treten auch in
+den anderen Standardobjekten immer wieder auf.
+
+Da die Ausgabe des Namens eines Objektes (dieser wird in den
+description-Modulen definiert) immer mit einer Deklination verbunden ist,
+findet man in jedem Objekt, welches ein description.c erbt, auch
+thing/language.
+
+thing
+  |- thing/properties    | Verwaltungsfunktionen des Property-Systems
+  |- thing/description   | Aussehen, Name, IDs des Objektes
+  |- thing/moving        | Bewegen und Zerstoeren des Objektes
+  |- thing/language      | Deklination von Namen, Adjektiven etc.; Pronomina
+  |- thing/commands      | vom Objekt definierte Kommandos
+  `- thing/restrictions  | Gewicht: standardmaessig 1Kg
+
+
+Ruestungen
+----------
+
+Bis auf thing/restrictions.c verfuegt armour.c ueber saemtliche Funktionalitaet
+die auch thing.c zur Verfuegung stellt. Zusaetzlich gibt es noch ein Modul,
+welches die Ruestung erst zur Ruestung macht: armour/combat.c
+
+armour                  | evtl. ein "(angezogen") an Kurzbeschreibung haengen
+  |- thing/properties   | Auch Ruestungen haben Eigenschaften
+  |- thing/description  | Aussehen, Name, IDs der Ruestung
+  |- thing/commands     | Kommandos sind auch moeglich
+  |- armour/moving      | Beim Bewegen/Zerstoeren: Ruestung ausziehen...
+  |    `- thing/moving  | ...und dann erst Bewegen/Zerstoeren
+  |- armour/combat      | Ruestungsklasse/-typ, Kampffunktion
+  `- thing/language     | und noch was zum deklinieren.
+
+
+Waffen
+------
+
+Wie Ruestungen, unterscheiden sich Waffen von einfachen Gegenstaenden im
+wesentlichen nur durch die Kampffunktionen.
+
+weapon                  | evtl. ein "(gezueckt)" an Kurzbeschreibung haengen
+  |- weapon/moving      | Waffe beim Bewegen/Zerstoeren erst wegstecken...
+  |    `- thing/moving  | ...und dann erst bewegen/zerstoeren
+  |- thing (s.o.)       | Ansonsten alle thing-Eigenschaften
+  `- weapon/combat      | Waffenklasse/-art, Schadenstyp, Kampffunktion
+
+
+Lichtquellen
+------------
+
+Lichtquellen sind (im Sinne der MudLib) normale Gegenstaende, die zusaetzlich
+die Eigenschaft haben, dass sie leuchten koennen (und auch verbrennen koennen).
+
+lightsource       | Alles, was zum Leuchten noetig ist
+  `- thing (s.o.) | ansonsten ein ganz normaler Gegenstand
+
+
+unit-Objekte
+------------
+
+unit-Objekte sind Gegenstaende, bei denen es sinnvoll ist, dass ein einzelnes
+Objekt eine gewisse Anzahl von gleichartigen Objekten repraesentiert. Das
+beste Beispiel hierfuer ist das liebe Geld: statt 1000 einzelner Muenzen im
+Inventory zu haben, hat man nur ein einziges Geldobjekt, das einer Menge von
+1000 Muenzen entspricht (die bei Kauf-/Verkaufsaktionen um eine entsprechende
+Menge erniedrigt oder erhoeht wird).
+Hierdurch wird a) die Uebersichtlichkeit erhoeht und b) natuerlich massig
+Speicher gespart.
+
+unit               | alle unit-Eigenschaften (Gewicht, Menge, Bewegen, ...)
+  `- thing (s.o.)  | ansonsten sind es normale Gegenstaende
+
+
+Spellbooks
+----------
+
+Fuer Gildenprogrammierer ist dies das Grundobjekt fuer das Zauberverzeichnis
+der Gilde.
+ACHTUNG: Obwohl thing.c geerbt wird, ist das Spellbook nicht zum clonen und
+"unter den Arm klemmen" gedacht! Vielmehr stellt thing.c hier im wesentlichen 
+nur das Property- und das Sprachmodul zur Verfuegung!
+
+spellbook                | Allgemeine Funktionen fuer Zaubersprueche
+  |- thing (s.o.)        | hier nur wg. Properties und Deklinationen
+  `- restriction_checker | fuer Einschraenkungen beim Zaubern
+
+
+Behaelter
+---------
+
+Die bisher beschriebenen Objekte kann man zwar mit sich herumtragen (ausser
+Spellbooks), aber man kann nichts hineinstecken. Hierzu sind einige weitere
+Funktionen noetig, die container.c zur Verfuegung stellt.
+Im wesentlichen sind das in container/restrictions.c Funktionen zum Aus-
+waehlen von Objekten im Behaelter, zum Testen, ob der Behaelter noch weitere
+Objekte aufnehmen kann (gewichtsabhaengig) und zur Ermittlung des Gesamt-
+gewichts des Behaelters.
+In container/description.c wird der Inhalt des Behaelters in eine Beschreibung
+umgewandelt.
+
+container
+  |- thing/properties        | DAS zentrale Modul...
+  |- thing/moving            | Bewegen/Zerstoeren des Behaelters
+  |- thing/commands          | Kommandos sind moeglich
+  |- container/description   | Beschreibung des Inhalts
+  |    `- thing/description  | Lang- und Kurzbeschreibung
+  |- thing/language          | Deklinationsmodul
+  `- container/restrictions  | Gesamtgewicht, Objektauswahl
+       `- thing/restrictions | Standardgewicht: 1Kg
+
+Leichen
+-------
+
+Leichen sind Behaelter mit der zusaetzlichen Eigenschaft, dass sie mit der
+Zeit zerfallen. Ausserdem geben sie ggf. noch eine Meldung ueber den
+Moerderkanal aus
+
+corpse                | Zerfallen, Moerdermeldung
+  `- container (s.o.) | sonst normaler Behaelter
+
+
+Raeume und ihre Abkoemmlinge
+----------------------------
+
+Raeume sind prinzipiell Behaelter mit Lang- und Kurzbeschreibung von INNEN
+und weiteren untersuchbaren Details (auch lesbare Details) sowie
+Ausgaengen und der Moeglichkeit vordefinierte Objekte im Raum zu plazieren.
+
+room
+  |- thing/properties     | Eigenschaften des Raumes
+  |- thing/language       | das obligatorische Sprachmodul
+  |- room/moving          | nur Zerstoeren; KEIN(!) Bewegen
+  |- room/restrictions    | Raeume werden nie voll
+  |    `- container/restrictions  | sonst die gleiche Funktionalitaet wie
+  |	    `- thing/restrictions | beim normalen Behaelter
+  |- room/description     | Raumbeschreibung, Details, etc.
+  |    `- container/description   | Beschreibung des Inhalts
+  |	    `- thing/description  | Beschreibung von aussen (selten sichtbar)
+  |- room/exits           | Verwaltung der Ausgaenge
+  |- room/commands        | notify_fail()s fuer "lies", "suche", "such"
+  |    `- thing/commands  | sonst normale Kommandobehandlung
+  |- room/items           | Verwaltung von Objekten, die im Raum sein sollen
+  `- room/doors           | Tueren (besondere Ausgaenge)
+
+
+Die Kneipe erweitert den Standardraum um Funktionen zur Definition der
+Speisen und Getraenke sowie um Befehle zum Bestellen und Ausgeben.
+
+pub
+  `- room (s.o.)
+
+
+Auch der Laden baut direkt auf dem Standardraum auf. Hier werden noch die
+ueblichen Ein- und Verkaufsbefehle zur Verfuegung gestellt.
+Jeder Laden benoetigt zusaetzlich einen Speicher, in dem verkaufte Objekte
+gelagert werden. Wenn der Laden schon beim ersten Betreten ueber ein
+gewisses Warensortiment verfuegen soll, kann man die mit AddItem()-Aufrufen
+im Speicher bewerkstelligen.
+
+laden
+  `- room (s.o.)
+
+store
+  |- thing/properties  | noetig fuer room/items.c
+  `- room/items        | vordefinierte Objekte im Speicher
+
+
+Die Post ist von der Programmierung her genau so zu behandeln wie ein
+normaler Raum. Die Postkabinen werden automatisch zur Verfuegung gestellt;
+man braucht sich in der Hinsicht um nichts zu kuemmern.
+
+post
+  `- (...) room
+
+
+Schiffe und aehnliche Transporter werden durch "bewegliche" Raeume realisiert.
+So hat man alle Beschreibungsmoeglichkeiten eines Raumes zur Verfuegung und
+kann (wie bei der Jolle geschehen) Ausgaenge in weitere Raume des Transporters
+legen (diese sind normale Raeume, KEINE Transporter!).
+Desweiteren sind Transporter die einzigen (Standard-)Raume, bei denen man
+auch die aeussere Lang- und Kurzbeschreibung zu sehen bekommt, weil man
+nicht nur in einem Transporter sein kann, sondern auch daneben stehen kann.
+
+transport         | Funktionen zur Festlegung der Route, An- und Ablegen
+  |- room (s.o.)  | die normalen Raumfunktionen
+  `- thing/moving | und hier steckt die Beweglichkeit
+
+
+Gilden
+------
+
+Gilden gibt es in zwei Ausfuehrungen: einmal als einfaches Gildenobjekt, dann
+aber auch als Gildenraum (wie zB. die Abenteurergilde).
+Waehrend das Gildenobjekt (gilden_ob) Funktionen zum Lernen von Faehigkeiten
+und Zauberspruechen, dem Gildenein- und -austritt sowie zum gildeninternen
+Aufstieg zur Verfuegung stellt (was zB. auch von einem NPC ausgeuebt werden
+koennte), verfuegt der Gildenraum zusaetzlich noch ueber Funktionen zum
+normalen Stufenaufstieg aufgrund von Abenteuer- und Erfahrungspunkten, die
+Questliste und die Kostenabfrage.
+
+gilden_ob                | Ein-/Austritt, Lernen, Gildenaufstieg
+  `- restriction_checker | Beschraenkungen bei obigen Aktionen
+
+gilden_room
+  |- gilde               | Stufenaufstieg, Questliste, Kosten
+  |    `- room (s.o.)    | normale Raumfunktionen
+  `- gilden_ob (s.o.)    | Gildenaufstieg etc.
+
+NPCs
+----
+
+Das Opfer. Zumindest meistens...
+
+npc
+  |- thing/properties            | Eigenschaften des NPC
+  |- living/description          | Ausgabe des Gesundheitszustandes...
+  |    `- container/description  | ...zusaetzlich zu seinem Inhalt...
+  |	    `- thing/description | ...und seiner Beschreibung
+  |- living/life                 | Die Lebensfunktionen, Essen, Trinken, Gift
+  |- living/attributes           | Die Verwaltung der Stats
+  |- living/moving               | Bewegen von Lebewesen
+  |- living/skills               | Funktionen fuer Faehigkeiten und Sprueche
+  |    `- living/std_skills      | und einige Standardfaehigkeiten
+  |- npc/combat                  | NPC-spezifische Kampffunktionen
+  |    `- living/combat          | der Kampf an sich
+  |- npc/chat                    | Sprueche a la Andy
+  |- npc/comm                    | Basiskommunikation: "sag", "echo", "emote"
+  |- container/restrictions      | wie bei Behaeltern
+  |    `- thing/restrictions
+  |- thing/language              | obligatorisch...
+  |- npc/info                    | Antworten auf Fragen
+  |- npc/put_and_get             | Reaktion auf erhaltene Gegenstaende
+  |    `- living/put_and_get     | Geben und Nehmen von Objekten
+  `- npc/guard                   | fuer Wach-NPCs
+
+Der intelligente NPC befindet sich noch in der Entwicklung.
+
+inpc
+  |- npc (s.o.)  | Erst mal ein ganz normaler NPC...
+  |- inpc/nobank | ...der gegen Bankzweitis vorgehen kann...
+  |    `- player/moneyhandler | ...und selbst Geld mitschleppt; ...
+  |- select      | ...die beste Ausruestung erkennt und auch benutzt...
+  `- boozing     | ...und in der Kneipe die beste Heilmoeglichkeit findet!
+
+
+Spieler- und Magiershell
+------------------------
+
+shells/magier                  | Hier auch noch Spielershells:
+  |- player/base               | Einloggen, Grundfunktionen
+  |    |- player/restrictions  | Maximale Zuladung (Staerke), InsertHooks
+  |    |    `- container/restrictions   | Maximalgewicht, Zuladungstest
+  |    |	 `- thing/restrictions  | Defaultgewicht
+  |    |- living/attributes    | Stats
+  |    |- living/combat        | Kampffunktionen
+  |    |- living/put_and_get   | Nehmen und Geben von Objekten
+  |    |- thing/properties     | DAS zentrale Modul...
+  |    |- thing/language       | Deklinationen
+  |    |- player/description   | Waffe/Ruestungen ausgeben
+  |    |    `- living/description           | Gesundheitszustand anzeigen
+  |    |	 `- container/description   | Ermittlung des Inhalts
+  |    |	      `- thing/description  | Kurz- und Langbeschreibung; IDs
+  |    |- player/moving        | Bewegen/Zerstoeren: Zusatzchecks
+  |    |    `- living/moving   | Bewegen/Zerstoeren von Lebewesen
+  |    |- player/life          | Zusatzchecks bei Lebensfunktionen
+  |    |    `- living/life     | allgemeine Lebensfunktionen
+  |    |- player/comm          | allgemeine Kommunikation
+  |    |    `- player/channel  | Kommunikation ueber die Kanaele
+  |    |- player/moneyhandler  | Geldverwaltung (auch fuer NPCs geeignet)
+  |    |- player/command       | Aliase, History, Parser
+  |    |- living/skills        | allg. Faehigkeitsfunktionen
+  |    |    `- living/std_skills | Standardfaehigkeiten
+  |    |- player/quests        | Verwaltung geloester Abenteuer
+  |    |- player/potion        | Verwaltung gefundener Zaubertraenke
+  |    |- player/soul          | Seelenkommandos (hilfe verben ;)
+  |    |- player/viewcmd       | Untersuchen etc.
+  |    |- more                 | More() fuer lange Texte
+  |    `- user_filter          | Hilfsmodul fuer "kwer in muenster" etc.
+  |                               | Ab hier: Magiershell
+  |- shells/filesys/filesys         | allgemeines Modul zur Dateibehandlung
+  |    |- shells/filesys/manual     | der "hilfe"-Befehl der Magier
+  |    |- shells/filesys/primitives | low-level-Routinen
+  |    |- shells/filesys/asynchron  | zur Vermeidung von Lags
+  |    `- shells/filesys/make       | komfortables updaten von Objekten
+  `- player/objects                 | Objekte clonen, updaten, zerstoeren
diff --git a/doc/std/virtual_compiler b/doc/std/virtual_compiler
new file mode 100644
index 0000000..ac8ec3d
--- /dev/null
+++ b/doc/std/virtual_compiler
@@ -0,0 +1,82 @@
+Was sind 'virtuelle Objekte'?
+=============================
+Virtuelle Objekte sind Objekte fuer die es keine explizite Quelldatei gibt.
+Ansonsten sind die Objekte (fast) genauso wie alle anderen auch.
+
+Was macht ein Virtual Compiler?
+===============================
+Wenn der Driver ein Objekt "/pfad/objekt" laden soll, guckt er erstmal nach,
+ob es so ein File (/pfad/objekt.c) auf der Platte gibt. Wenn ja, laedt er es
+ganz normal. Wenn nicht, passiert folgendes:
+
+1. Der Driver fragt den Master der Mudlib nach dem Objekt.
+2. Der Master guckt im Verzeichnis "/pfad/" nach, ob es ein virtual_compiler.c
+   dort gibt. Wenn ja, wird dieses virtual_compiler.c gefragt, ob es sich 
+   dafuer zustaendig fuehlt, ein Objekt mit dem Namen "/pfad/objekt" zu 
+   erzeugen.
+3. Wenn sich der VC fuer zustaendig fuehlt, clont er ein Objekt (z.B. sein
+   Standardobjekt, "stdob.c"), konfiguriert es evtl. noch ein bisschen und 
+   gibt es an den Master zurueck. Das erzeugte Objekt heisst an dieser Stelle
+   z.B. "/pfad/stdob#42" (weil es ein Clon von "/pfad/stdob" ist).
+4. Der Master gibt dieses erzeugte Objekt an den Driver zurueck.
+5. Der Driver benennt das vom Master erhaltene Objekt "/pfad/stdob#42" um in
+   das gewuenschte Objekt "/pfad/objekt". Von diesem Moment an ist es, als ob
+   es ein File "/pfad/objekt.c" gaebe, was dieses Objekt definiert.
+
+Das ist grundsaetzlich das, was ein VC macht.
+
+Was macht der VC in /std/?
+==========================
+Erstmal das oben beschriebene. Fuer welchen Pfad sich dieser VC zustaendig
+fuehlt und welches Objekt er jeweils clonen soll, wird per P_COMPILER_PATH und
+P_STD_OBJECT konfiguriert.
+Zusaetzlich fuehrt er besagte Liste seiner erzeugten Objekte, damit bei einem
+'ls' auf das Verzeichnis diese Objekte mit angezeigt werden.
+Weiterhin zerstoert er alle diese Objekte in seinem eigenen Remove.
+Ausserdem hat er 2 Funktionen, mit denen er entscheiden kann, ob er fuer ein
+bestimmtes angefragtes Objekt zustaendig ist, Validate() und
+QueryValidObject() und eine Funktion CustomizeObject(), die einem frisch
+geclonten Objekt sagen kann, welchen Namen es spaeter einmal haben soll (s.
+jeweilige Manapages).
+
+Wie baut man sich seinen eigenen VC?
+====================================
+Sagen wir, ihr wollt einen VC bauen, der jedem Spieler seinen eigenen Raum
+gibt, damit jeder Spieler in diesem Raum ein Monster allein erlegen muss,
+ohne dass andere Spieler mit drin sind.
+Dann braucht ihr zuerst mal einen Raum, der die Vorlage fuer alle VC-Raeume
+sein soll, z.B. std_arena.c. Diesen legt ihr in das Verzeichnis, wo der VC hin
+soll, z.B. /d/region/magier/vc/.
+In diesem Verzeichnis legt ihr nun ein File virtual_compiler.c an, welches
+/std/virtual/v_compiler erbt.
+Im create() setzt ihr nun P_COMPILER_PATH auf "/d/region/magier/vc/" und
+P_STD_OBJECT auf "/d/region/magier/vc/std_arena".
+Soll euer VC keine Para-Raeume erzeugen, setzt ihr P_PARA auf ({}).
+Sodann muesst ihr ein Validate() formulieren (s. Manpage), welches prueft, ob
+ein spaeter gewuenschtes Objekt den richtigen Namen (ohne Pfad) hat, z.B.
+'arena|spielername' und in diesem Fall genau diesen Namen zurueckliefert und
+in anderen Faellen 0.
+Das wars. Zumindest in diesem einfachen Fall seid ihr im wesentlichen fertig.
+Ihr koennt einen Spieler nun mit
+  pl->move("/d/region/magier/vc/arena|spielername",M_GO)
+in 'seinen' persoenlichen Raum bewegen.
+
+Bitte beachtet allerdings noch die Hinweise und Beschreibungen in den Manpages
+zu den einzelnen Funktionen und Properties.
+
+
+Beispiele:
+==========
+1. /doc/beispiele/virtual/zesstra/virtual_compiler.c
+   VC, der jedem Spieler einen eigenen Raum gibt. Da hier der Inhalt aller
+   Raeume gleich ist (alle Spieler sollen gleiche Bedingungen haben), ist
+   keine Konfigurierung mit Hilfe von CustomizeObject() noetig.
+
+2. /doc/beispiele/virtual/hate/vr_compiler.c
+   Dies ist ein Beispiel fuer einen sehr allgemeinen VC, der es 
+   erlaubt anzugeben in welchem Bereich sich die x und y Koordinaten befinden
+   und dann Raeume erzeugt, welche Ausgaenge in alle vier Himmelsrichtungen 
+   haben.
+
+-----------------------------------------------------------------------------
+27.10.2007, Zesstra
diff --git a/doc/std/weapon b/doc/std/weapon
new file mode 100644
index 0000000..3894c02
--- /dev/null
+++ b/doc/std/weapon
@@ -0,0 +1,78 @@
+ STANDARDKLASSE:
+	"/std/weapon"
+
+ BENUTZUNG:
+        inherit "std/weapon";
+
+	#include <properties.h>
+	#include <combat.h>
+
+ PROPERTIES:
+     Grundlegend:
+        P_WC		setzbar: Waffenklasse == Angriffsstaerke
+	P_WEAPON_TYPE	setzbar: Waffentyp
+	P_DAM_TYPE	setzbar: Schadenstypen
+	P_NR_HANDS	setzbar: Anzahl benoetigter Haende
+
+     Besondere Attribute und Anforderungen fuer Traeger:
+	P_RESTRICTIONS	setzbar: Anforderungen an Traeger
+	P_M_ATTR_MOD	setzbar: Attributmodifikator fuer Traeger
+	P_CURSED	setzbar: Verfluchung (nicht wegsteckbar)
+	P_PARRY		setzbar: Parierwaffe ?
+	P_AC		setzbar: Schutzfaktor einer Parierwaffe
+
+     Meldungen und Zeitpunkte:
+	P_EQUIP_TIME	enthaelt den Zeitpunkt des Anziehens
+	P_LAST_USE	enthaelt den Zeitpunkt des letzten Angriffs damit
+	P_WIELDED	enthaelt den Traeger
+	P_WIELD_MSG	setzbar: eigene Zueckmeldung
+	P_UNWIELD_MSG	setzbar: eigene Wegsteckmeldung
+
+     Dynamisches Verhalten in Kampf und beim Anziehen:
+	P_WIELD_FUNC	setzbar: Objekt mit Zueckfunktion "WieldFunc()"
+	P_UNWIELD_FUNC	setzbar: Objekt mit Wegsteckfunktion "UnwieldFunc()"
+	P_HIT_FUNC	setzbar: Objekt mit Angriffsfunktion "HitFunc()"
+
+     Zusaetzliche Eigenschaften:
+	P_DAMAGED	enthaelt den Ausmass des Schadens an Waffe
+	P_QUALITY	setzbar: Qualität/Haltbarkeit der Waffe
+	P_EFFECTIVE_AC	setzbar: falls HitFunc WC nicht sichbar aendert
+	P_EFFECTIVE_WC	setzbar: falls Parieren AC nicht sichbar aendert
+
+     Zusaetzlich sind alle Properties aus /std/thing verfuegbar, also
+     bitte auch folgende setzen:
+	P_MATERIAL	setzbar: Zusammensetzung
+	P_SIZE		setzbar: Groesse
+	P_WEIGHT	setzbar: Gewicht
+
+ MAKROS:
+     Gueltige Waffen- und Schadenstypen (definiert in "/sys/combat.h").
+
+ BESCHREIBUNG:
+     Basisklasse fuer alle Waffen im Spiel. Sie ist von /std/thing
+     abgeleitet und enthaelt alle zusaetzliche Funktionalitaet
+     fuer den Kampf.
+
+     Vor der Programmierung von Waffen sollte /doc/wiz/waffen
+     gelesen werden. Die Regeln darin sind verbindlich und sollten nur
+     in Ausnahmefaellen und mit Absprache mit dem Erzmagier fuer 
+     Waffen/Ruestungen/Monster ueberschritten werden.
+
+ VERERBUNGSBAUM:
+     [/std/weapon]
+     ..... [/std/thing/properties]
+     ..... [/std/thing/language]
+     ..... [/std/thing/commands]
+     ..... [/std/thing/restrictions]
+     ..... [/std/weapon/moving]
+     .......... [/std/thing/moving]
+     ..... [/std/weapon/description]
+     .......... [/std/thing/description]
+     ..... [/std/weapon/combat]
+
+
+ SIEHE AUCH:
+     P_WEAPON, P_PARRY_WEAPON, P_TOTAL_WC, P_TOTAL_AC, P_UNWIELD_TIME
+     Attack(), Defend(), /doc/wiz/waffen
+
+ 20 Maerz 2004 Gloinson
diff --git a/doc/wiz/.readme b/doc/wiz/.readme
new file mode 100644
index 0000000..40d049c
--- /dev/null
+++ b/doc/wiz/.readme
@@ -0,0 +1,2 @@
+Hier sind allgemeine Themen und Regelungen fuer Magier beschrieben.
+
diff --git a/doc/wiz/.synonym b/doc/wiz/.synonym
new file mode 100644
index 0000000..6c9523f
--- /dev/null
+++ b/doc/wiz/.synonym
@@ -0,0 +1,17 @@
+sponsor befoerderungen
+sponsoring befoerderungen
+befoerderung befoerderungen
+npc npcs
+materialien material
+flueche gift
+fluch gift
+gifte gift
+vergiftung gift
+krankheit gift
+krankheiten gift
+armour ruestungen
+armours ruestungen
+ruestung ruestungen
+weapon waffen
+weapons waffen
+waffe waffen
diff --git a/doc/wiz/anfaenger b/doc/wiz/anfaenger
new file mode 100644
index 0000000..d240909
--- /dev/null
+++ b/doc/wiz/anfaenger
@@ -0,0 +1,116 @@
+Anfaengergebiete
+
+Vielleicht eruebrigt es sich, einen laenglichen Leitfaden zu schreiben,
+weil dies eigentlich Gebiete wie viele andere sein sollten:
+ausreichend beschrieben, logisch durchdacht, balanciert, was NPC und
+Objekte wie Waffen und Ruestungen betrifft, kurzum, es muss Spass fuer
+Spieler machen.
+
+Einiges unterscheidet aber ein solches Gebiet von anderen, denn wie der
+Name schon sagt, sollte man dort eher hauptsaechlich Anfaenger (einmal
+willkuerlich als Spielstufe 1-5 bezeichnet) erwarten.
+
+1. Erreichbarkeit
+Viele Anfaengergebiete befinden sich natuerlich in unmittelbarer Naehe
+einer Rasse, z.B. die Hochebene bei den Zwergen, der Park der Freunde
+bei den Elfen oder der kleine Dschungel im NW von Katzmandu. Hierbei
+ist die Naehe fuer eine Rasse gegeben, so dass zumindest die kleinen
+Spieler dieser Rasse das Gebiet leicht erreichen koennen. Natuerlich
+ist es fuer andere Rassen nicht unbedingt einfach, einige weit entfernt
+gelegene Anfaengergebiete zu erreichen, ohne Dutzende von Raeumen zu
+durchlaufen.
+Man kann auch nicht sofort davon ausgehen, dass sich ein Anfaenger von
+Anfang an eine Karte fuer Wege anlegt. Insofern ist es sinnvoll, wenn
+es Anfaengergebiete in unmittelbarer Naehe zu den Startpunkten der
+Rassen gibt. Die koennen dann entweder unter dem Ebenenpfad oder auch
+unter /d/anfaenger stehen.
+Allgemein zugaengliche Anfaengergebiete sollten zumindest ohne grossen
+Aufwand vom Startpunkt der Rassen aus zu erreichen sein. Das koennte
+durch spezielle Hilfsmittel geschehen, durch NPC, die einen den Weg
+dorthin weisen (vielleicht durch Ueberarbeitung von bestehenden Files)
+oder durch teleportierende Objekte, die nur fuer Anfaenger benutzbar
+sind. Ziel ist es nicht, den Spielern das Laufen und selbststaendige
+Erkunden abzunehmen, sondern nur die Gefahr, sich ueber laengere
+Strecken hin zu "verfransen".
+
+2. Bekanntheitsgrad
+Diesem Punkt sollte man ein wenig Zeit widmen. Am einfachsten ist die
+Bekanntheit zu erreichen, wenn im Gebiet eine Quest spielt, da dann
+frueher oder spaeter zwangslaeufig eine Frage gestellt wird. Ist es
+eine Miniquest, koennte eine Erfolgsmeldung ueber die Ebene Anfaenger
+flimmern statt ueber die Ebene Abenteuer. Wenn es passt, koennten
+auch diverse NPC mit Informationen versorgt werden, oder andere Objekte,
+die man an prominenter Stelle plaziert (Notizen, Buecher, Aufzeichnungen
+oder aehnliches).
+
+3. NPC
+Auch wenn es nur "kleine" NPC sind, kann man in sie mindestens so viel
+Energie fuer Informationen, Verhalten und Details stecken wie fuer
+"grosse". Sie sollten keinesfalls aggressiv sein. Hoher Body (~ >70)
+oder hohe Hands (~ >100) sind zu vermeiden, da man als Anfaenger noch
+kein Gefuehl dafuer hat, was die Schadensmeldungen "hart", "krachende
+Knochen" oder "kitzelt Dich" in etwa an Schaden machen. Dementsprechend
+waere es auch sinnvoll, die NPC zu schreiben. Bedrohlich aussehende
+Drachen, die immer verfehlen, sind eigentlich ebenso wenig plausibel
+wie kleine Ameisen, die einen mit der Saeure immer sehr hart treffen.
+Im Zweifel einfach einen Lvl 1 Testspieler anlegen und ausprobieren,
+mal ganz ohne Waffe (wie komme ich als "nackter" Neuling an meine erste
+Waffe?), mal mit einer schwachen, mal mit einer etwas besseren Waffe.
+Als Ausnahme darf hier gerne auch mal ein eigentlich schwacher NPC
+Killstufenpunkte (Killstupse) vergeben.
+
+4. Cleaning Up
+Hoffentlich besuchen dann auch viele das Gebiet. Eventuell empfiehlt es
+sich dann (wie bei vielen anderen Gebieten aber auch) zu ueberlegen,
+was passiert, wenn eine Unzahl geschriebener Objekte, die viele dann
+doch nicht gebrauchen/mitnehmen, im Raum herumliegt. Bei Ruestungen und
+Waffen sind die Argumente CLONE_WIELD und CLONE_WEAR in der Funktion
+AddItem vorteilhaft, bei anderen Objekten koennte man in deren Reset
+nachsehen, ob sie laengere Zeit in einem Raum des Gebiets oder im Gebiet
+selbst "herumgammeln". Es bleibt zwar zu hoffen, dass sie irgendwann
+dem Ausswappen des Raumes anheimfallen, aber es sieht im allgemeinen
+nicht schoen aus, wenn Objekte oder gar quest-/miniquestrelevante Teile
+sich in einem oder mehreren Raeumen stapeln.
+
+5. ZTs
+Sie helfen, das Gebiet bekannter zu machen (siehe Punkt 2), sollten
+aber einfach zu finden sein (Detail, einfacher Befehl) und nicht gleich
+eine ganze Miniquest beinhalten.
+
+6. Unterstuetzung von wichtigen Standarditems
+Dazu gehoeren immer noch Seil, Fackel oder Schaufel. Eventuell braucht
+man sie fuer die eine oder andere Aufgabe, ihre Benutzung und die damit
+verbundene Syntax sollte dem Anfaenger danach gelaeufig sein.
+
+7. Unterstuetzung von weit verbreiteten Befehlen
+Dazu zaehlen "oeffne", "nimm", "suche/durchsuche", "schliesse", etc.,
+also das, was in vielen Quests auch mitunter gefragt ist.
+
+8. Vielfalt in dem, was man "tun" kann, einfache Umsetzung
+Man koennte diesen Punkt auch unter "einfacher Code fuer Anfaenger"
+zusammenfassen, das ginge aber manchmal zu weit. Wichtig in diesem
+Zusammenhang ist auch, dem Anfaenger spielerisch im Text, durch Details
+oder Infos von NPC die Syntaxen, wenn sie denn einmal abseits der so
+ueblichen Kommandos sind, ein wenig in den Mund zu legen:
+(Spieler weiss, dass in diesem Raum ein ZT fuer ihn ist, es hat was mit
+dem Baum zu tun, vor dem er steht)
+"unt baum" ->
+"Der Baum ist recht beeindruckend und hoch. Dennoch koenntest Du ohne
+ weiteres auf ihn klettern." ->
+"kletter auf baum/baum hoch" ->
+Erfolg
+
+9. Belohnungen
+Sie duerfen ruhig grosszuegig sein: ZTs (Zaubertraenke), FP (Forscher-
+punkte), EK (Erstkills/Killstupse), AP (Abenteuerpunkte/Questpunkte)
+und MQP (Miniquestpunkte) sind wohl dosiert und abwechslungsreich zu
+verteilen und sollen dem Spieler helfen, den anfangs langen Weg bis
+zum naechsten Level zu verkuerzen.
+
+Wie ueberhaupt hilft eine gute Dokumentation auch einem Anfaenger unter
+den Magiern, selbst schnell eine eigene Referenzsammlung fuer einfache
+Dinge in LPC zu erstellen. Man koennte also sagen, wie der Spieler im
+Anfaengergebiet waechst auch der Magier, der es geschrieben hat.
+
+-----------------------------------------------------------------------
+Last modified: Tue Mar 21 01:46:35 2006 by Ark
diff --git a/doc/wiz/angriff b/doc/wiz/angriff
new file mode 100644
index 0000000..a1ee7b8
--- /dev/null
+++ b/doc/wiz/angriff
@@ -0,0 +1,18 @@
+--------Angreifer
+Attack()
+	Holt die Waffe des Spielers.
+	Berechnet den Angriffstyp und gibt die
+	Angriffsmeldung aus.
+
+	Aufruf von:
+
+--------Verteidiger     
+Defend( hp, typ )
+	Gibt die Verteidigungsmeldung aus.
+	Berechnet die Anzahl der HP die abgezogen wird.
+
+	Aufruf von:
+
+do_damage( hp )
+
+	Berechnen der HP. Gegebenenfalls sterben etc.
diff --git a/doc/wiz/artillerie b/doc/wiz/artillerie
new file mode 100644
index 0000000..349cec4
--- /dev/null
+++ b/doc/wiz/artillerie
@@ -0,0 +1,61 @@
+Regeln fuer Artillerie-Objekte
+==============================
+
+1. Definition von Artillerie
+----------------------------
+
+Unter dem Begriff "Artillerie" fasst man alle Objekte zusammen, die
+zusaetzlich zu den vorhandenen Gildenfaehigkeiten durch ein vom
+Spieler initiiertes Kommando direkt Schaden an einem oder mehreren
+Gegnern verursachen.
+
+Waffen und Ruestungen, welche per Kommando Schaden verursachen (z. B.
+Eisstab, Ring vom Schlammdrachen), fallen unter diese
+Definition. Waffen und Ruestungen, die "von sich aus" (ueblicherweise
+per Hit-/DefendFunc) Schaden verursachen (z. B. Todesdrachenpanzer,
+Goblinring), fallen nicht unter diese Definition, sind aber natuerlich
+nach wie vor genehmigungspflichtig.
+
+2. Basisanforderungen
+---------------------
+ 
+Solche Artillerie muss folgenden Anforderungen genuegen:
+
+ a. Artillerie _muss_ P_ATTACK_BUSY beachten (setzen/abfragen).
+ b. Artillerie _muss_ bei Verwendung Konzentrationspunkte 
+    verbrauchen.
+ c. Artillerie darf nicht (bzw. nur begrenzt) gehortet werden
+    koennen.
+ d. Artillerie darf bei Paralyse nicht angewendet werden koennen
+    (P_DISABLE_ATTACK).
+ e. Artillerie muss durch Setzen der Property P_IS_ARTILLERY 
+    gekennzeichnet sein. 
+ f. Artillerie, die Munition benutzt oder selbst Munition ist (wie z.B.
+    Wurfsterne), muss das Unitobjekt und den dortigen Mechanismus zum
+    Zerfall von Objekten nutzen. Dabei sind P_UNIT_DECAY_INTERVAL und
+    P_UNIT_DECAY_QUOTA so zu setzen, dass die Munition eine Halbwertszeit
+    zwischen 5 und 10  Tagen hat, der ihrer Verfuegbarkeit angemessen
+    ist. Dies laesst sich durch geeignetes Einstellen des
+    Prozentsatzes und/oder der Resetzeit erreichen.
+
+    Beispiele:
+    Setzt man p=1% Zerfall pro Reset an, dann muss der Reset
+    fuer eine Halbwertszeit von 5 Tagen dann 
+    t=ln(0.5)/ln(0,99)*5*24*3600 s dauern, das sind 6224 s.
+
+    Moechte man lieber den normalen Reset, der im Mittel 45 min, d.h. 160
+    Resets in 5 Tagen betraegt, so erhaelt man folgenden Prozentsatz:
+    p = 1-0,5^(1/160) d.h. ca. 0,43%.
+
+Details werden fallweise entschieden.
+
+
+3. Inkraftreten
+---------------
+
+Diese Regeln treten am 5. August 2003 in Kraft.
+Revision am 5. April 2008
+Revision am 7. April 2011
+
+--------------------------------------------------------------------------
+Letzte Aenderung: Sam,  7. April 2011 von Humni
diff --git a/doc/wiz/autoload b/doc/wiz/autoload
new file mode 100644
index 0000000..f3cd444
--- /dev/null
+++ b/doc/wiz/autoload
@@ -0,0 +1,32 @@
+AUTO_LOADING:
+	Rumata 26.08.92
+
+	DER NEUE AUTOLOAD-MECHANISMUS
+
+FUNKTIONEN:
+	void SetProp( P_AUTOLOADOBJ, mixed wert );
+	mixed QueryProp( P_AUTOLOADOBJ );
+
+ERLAEUTERUNG:
+	Es gibt jetzt eine Property P_AUTOLOADOBJ, die jedes Objekt
+	setzen kann. Ist der Wert dieser Property nicht 0, so gilt
+	das Objekt als Autoloading-Objekt. 
+	WICHTIG: Auch Werte wie "" oder ({ }) sind nicht 0.
+
+	Mit der Funktion QueryProp( P_AUTOLOADOBJ ) kann dieser Wert
+	abgefragt werden.
+
+BEMERKUNGEN:
+	Die Property P_AUTOLOADOBJ sollte nicht mit der
+	Property P_AUTO_LOAD verwechselt werden. Diese speichert
+	die Autoload-Informationen im Spieler.
+
+	Die Property P_AUTOLOADOBJ kann selbstverstaendlich auch als
+	Built-in-Property implementiert werden.
+
+BEISPIEL:
+	Ein einfaches Beispiel steht in ***
+	Ein leistungsfaehiges Beispiel steht in /obj/tools/muschel.c
+
+SIEHE AUCH:
+	"doc/MG/properties"
diff --git a/doc/wiz/balance b/doc/wiz/balance
new file mode 100644
index 0000000..efea050
--- /dev/null
+++ b/doc/wiz/balance
@@ -0,0 +1,78 @@
+Beurteilung und Genehmigung von Waffen und Ruestungen im MG
+===========================================================
+
+    
+    Was bedeutet Balance im Morgengrauen? Die Balance (bzw. ihr Fehlen)
+    wird vor allem dann wahrgenommen, wenn Spieler sich gelangweilt durch
+    Gebiete zappen, die vor zwei oder drei Jahren noch als anspruchsvoll
+    galten, oder wenn ein Magier feststellen muss, dass sein schoenes 
+    Riesenmonster nichtmal dazu kommt, seine ausgefeilten Zaubersprueche
+    anzuwenden, weil es nach durchschnittlich zweieinhalb Runden schon
+    tot ist. Fehlentwicklungen dieser Art zu verhindern ist Aufgabe der 
+    Balance. Sie stellt universelle Grenzwerte und Masstaebe, die als
+    gemeinsamer Nenner fuer alle Magier in diesem Mud eine gewisse 
+    Ausgewogenheit garantieren. Anhand dieser Werte kann jeder Magier auf
+    der einen Seite einschaetzen, wie begehrt ein neues Objekt sein wird,
+    und auf der anderen weiss er ungefaehr, was auf seine armen Monster
+    zukommen wird, wenn Spieler mit den Objekten anderer Magier angreifen.
+    
+    Diese Aufgabe zu bewaeltigen kann jedoch in einem so riesigen Mud keine 
+    Instanz allein leisten. Ein grosse Verantwortung lastet auch auf den 
+    Regionsmagiern, die innerhalb ihres Verantwortungsbereichs dafuer Sorge
+    tragen sollten, dass aussergewoehnliche Objekte in Gebieten nicht zu
+    gehaeuft auftreten und nicht zu leicht zu erreichen sind.
+
+    Wie laeuft nun eine Genehmigung durch die Balance ab? 
+    Zuallererst sollte sich ein Magier ueber den aktuellen Stand der Balance-
+    regeln informieren. Zum einen weiss er dann sofort, welche Ideen ohnehin
+    keine Chance auf Genehmigung haben, zum anderen inspirieren vielleicht 
+    sogar die zahlreichen Hinweise und technischen Details das ein oder 
+    andere Objekt. Als naechstes steht eine kritische Pruefung der eigenen
+    Ideen an. Braucht das Mud wirklich den 132. Panzer, der gegen Feuer
+    schuetzt? Gibt es nicht irgendwo ohnehin schon eine Waffe dieses Typs
+    mit fast identischen Werten? Addiert sich die Wirkung eines geplanten
+    Kampfobjekts vielleicht irgendwie mit vorhandenen Objekten? Diese und
+    aehnliche Fragen frueh zu klaeren kann spaeter viel Frust vermeiden. Das
+    Balanceteam kann auch zu diesem Zeitpunkt schon ein Ansprechpartner sein,
+    da seine Mitglieder einen guten Ueberblick ueber die meisten heraus-
+    ragenden Objekte im Mud haben und gerne als Berater zur Verfuegung 
+    stehen. Die Magier des Teams koennen natuerlich auch zu programmier-
+    technischen Fragen den einen oder anderen Tip geben.
+
+    Sind die Objekte dann programmiert und ist auch der Regionsmagier mit
+    ihnen einverstanden, wird schliesslich der Antrag gestellt. (Per
+    "mail balance"). Der Antrag sollte folgenden Informationen enthalten:
+
+    - Name des Objekts
+    - Vollstaendiger Filename
+    - Alle relevanten Werte: AC bzw. WC, P_NR_HANDS, Gewicht, Wert, ...
+    - Defend/HitFuncs, in Form einer praezisen Beschreibung der 
+      Funktionsweise und des Wertebereichs.
+    - Alle sonstigen Informationen ueber Eigenschaften, die den Kampf 
+      beeinflussen oder dem Spieler von Nutzen sind
+    - Fundort und subjektive Einschaetzung des Aufwands, um diesen 
+      Gegenstand zu ereichen.
+
+    Die Genehmigung erfolgt dann per mail, es sei denn es gibt begruendete
+    Einwaende. In diesem Fall kommt die Genehmigung mit leicht geaenderten
+    Werten oder sogar eine Ablehnung. Im letzteren Fall steht es dem Magier
+    natuerlich frei, das Objekt zu veraendern und neu zu beantragen.
+    Normalerweise ergibt sich dann auch schnell im persoenlichen Gespraech
+    mit Mitgliedern der Balance, wo das Problem genau liegt und welche 
+    Alternativen es gibt. 
+
+    Anzumerken bleibt noch, dass Objekte, die nach der Genehmigung noch in
+    irgendeiner Weise positiv veraendert werden, natuerlich neu genehmigt
+    werden muessen. Bei kleineren Aenderungen (Gewicht o.ae.) reicht
+    unter Umstaenden eine informelle Anfrage beim Balanceteam.
+
+ SIEHE AUCH
+
+     balanceantrag, ruestungen, waffen, fernwaffen, uniques, npcs, objects,
+     attributsveraenderungen, resistenzen, kampfobjekte, grenzwerte,
+     nachteile
+
+
+------------------------------------------------------------------------------
+ LETZTE AENDERUNG:
+    Son, 18.10.2005, 18:54:00 von Miril
diff --git a/doc/wiz/balanceantrag b/doc/wiz/balanceantrag
new file mode 100644
index 0000000..6124640
--- /dev/null
+++ b/doc/wiz/balanceantrag
@@ -0,0 +1,133 @@
+Hilfe zu Balanceantraegen
+=========================
+
+Um die Arbeit der Balance zu erleichtern und damit die Wartezeit fuer die
+Magier zu verkuerzen, gibt es einige Dinge zu beachten. Das Ganze liest sich
+auf den ersten Blick sehr buerokratisch, ist es aber nicht. Die Anleitung soll
+nur so ausfuehrlich wie moeglich sein, um Missverstaendnissen vorzubeugen.
+Zuerst einmal gibt es grundsaetzlich zwei Arten von Antraegen:
+
+1. Eine Vorabanfrage
+
+Viele Magier scheuen die Arbeit, ein Objekt zu programmieren, das anschliessend
+nicht von der Balance genehmigt wird. Das ist verstaendlich und Vorabanfragen
+werden nicht minder beachtet als konkrete Antraege. Trotzdem sollte man so eine
+Anfrage sorgfaeltig formulieren. Sie sollte das Problem klar umreissen und
+moeglichst eindeutig sein. Auch ein Hinweis darauf, wo der Magier Probleme mit
+der Balancierung erwartet und in welchem Wertebereich eventuelle Zahlen
+erwartet werden, sollte nicht vergessen werden.
+
+Eine Antwort auf eine Vorabanfrage ist allerdings keine Genehmigung eines
+Objekts. Es ist lediglich als Information zu sehen, ob die Balancemitglieder 
+so ein Objekt ueberhaupt fuer genehmigungfaehig halten, gegebenenfalls mit
+angepassten Werten oder leicht veraenderten Eigenschaften. Mit einer Antwort
+auf eine Vorabanfrage wollen wir dem Wunsch der Magier entsprechen, zu
+erfahren, ob es sich lohnt, Arbeit in das Objekt zu investieren, bindend ist
+so eine Antwort allerdings nicht.
+
+2. Ein Antrag
+
+Hier geht es um die Festschreibung aller kampfrelevanten Eigenschaften,
+trotzdem sollten alle Eigenschaften, die Einfluss auf das Spielgeschehen haben,
+mit angegeben werden, auch wenn die Objektbalance nicht direkt fuer diese
+Eigenschaft zustaendig ist. Eine Waffe, die den Traeger ab und zu heilt,
+muss auch bei der Heilungsbalance beantragt werden, trotzdem darf diese
+Eigenschaft nicht vor der Objektbalance verschwiegen werden. Alle Werte
+sollten tabellarisch aufgefuehrt werden. Eine Uebersicht, ueber die von der
+Balance benoetigten Werte:
+
+Kurzbeschreibung:        P_SHORT
+Pfadangabe:              momentan und nach Anschluss
+Typ des Objekt:          Schwert, Hose, Ring...
+Waffen/Ruestungsklasse:  P_WC, P_AC
+Schadensart:             P_DAM_TYPE
+Benoetigte Haende:       P_NR_HANDS
+Wert:                    P_VALUE
+Gewicht:                 P_WEIGHT
+HitFunc:                 Mit Erlaeuterung der Umstaende,
+                         Begruendung und Werte/Wahrscheinlichkeiten
+Andere Boni:             Kaempfer, Zauberer, Heilungen, Resistenzen
+                         evtl mit rollensp. Begruendung
+Restriktionen:           P_RESTRICTIONS, Paralyse, Zeitbeschraenkungen 
+
+Eine Begruendung sollte die Eigenschaft rollenspieltechnisch einbetten und
+nicht beschreiben, warum das MG diese Eigenschaft in einem Objekt unbedingt
+noch braucht. Weiterhin sollte man die Erreichbarkeit kurz umreissen und die
+Haeufigkeit, mit der das Objekt an Spieler gelangt. Auch hierbei gilt, dass
+man das Objekt moeglichst kurz, aber eindeutig beschreibt.
+
+Die Genehmigung oder Ablehnung eines Antrags durch die Objektbalance ist
+bindend. Eigenschaften, die in der Antwort aufgefuehrt sind, sind
+festgeschrieben und beduerfen bei Aenderung eines Neuantrages (das geht in
+der Regel recht schnell, wenn der Magier nicht das Objekt komplett umkrempelt).
+Sollten nicht festgeschriebene Eigenschaften, die das Spielgeschehen
+beeinflussen (die es eigentlich nicht geben sollte), geaendert werden, muss die
+Balance informiert werden. Bei jeglichem Mailverkehr zu einem Objekt, sollte
+die btop Nummer angegeben werden, die in der ersten Mail zu dem Objekt
+angegeben sein sollte. Ist dies nicht der Fall, erfrage diese Nummer bitte bei
+einem der Teammitglieder. Nach Genehmigung des Objektes, sollte diese Nummer
+auch in den Kopf der Datei(en) geschrieben werden.
+
+Bei einem Antrag kommt es immer wieder zu Misverstaendnissen oder
+Zweideutigkeiten. Daher ist es die Regel, dass noch mal nachgefragt wird,
+wie denn genau etwas ablaufen oder implementiert werden soll. Eine schnelle
+Beantwortung dieser Fragen beschleunigt natuerlich auch den
+Genehmigungsprozess. Missfallen dem Balanceteam einzelne Eigenschaften,
+Implementierungen oder Werte, werden haeufig Vorschlaege gemacht, die die
+Akzeptanz eines Objektes durch die Balance entscheidend verbessern. Die
+Mitglieder bemuehen sich, den Genehmigungsprozess so reibungslos und
+konfliktarm wie moeglich ablaufen zu lassen. Solche Aenderungsvorschlage sind
+weder Belehrungen noch boese gemeint, sondern sollen dazu dienen die
+Balancierung zu vereinfachen, zu beschleunigen und Bedenken von
+Balancemitgliedern entgegenzukommen.
+
+Zum Schluss noch ein Antrag, wie er aussiehen koennte:
+
+Antrag fuer ein Zweihandschwert
+-------------------------------
+
+Name: Der Perforator
+Pfad: /d/region/magier/gebiet/obj/perforator.c
+      /d/region/magier/gebiet/obj/loch.c
+P_WEAPON_TYPE:  WT_SWORD
+P_WC:           200
+P_NR_HANDS:     2
+P_VALUE:        15000
+P_WEIGHT:       1500
+P_DAM_TYPE:     ({DT_PIERCE, DT_UNHOLY})
+HitFunc:        unter Umstaenden random(50)
+K_BRAWLING_WC:  25
+K_CRITICAL_HIT: 80
+
+Pseudo-Unique: Es gibt 10 Stueck, wird ein Elftes gebraucht, wird
+das mit der aeltesten Clonezeit zerstoert.
+
+Restriktionen: MiniQuest, Seher, Beteiligung beim Ermetzeln
+
+Beschreibung: Der Perforator perforiert den Gegner. Ist noch kein Loch
+in dem Gegner, wird eins reingepiekt und macht dabei zusaetzlich random(50)
+Schaden. Danach ist ein Loch im Gegner und er verliert jede Runde 10 +
+random(10) HP durch Blutverlust per reduce_hit_points() fuer 10 Runden.
+Ist der Traeger des Schwerts noch im Raum, bekommt er diesen Schaden
+gutgeschrieben, weil das Schwert das Blut trinkt. Ist das Loch weg, gibt es
+kein weiteres.
+
+Das Schwert hat ein schweres, mit Dornen versehenes Heft (BRAWLING_WC) und
+ist rasiermesserscharf, so dass es sich fuer einen Todesstoss gut eignet.
+Das Schwert hat einen Fluch, der es blutdurstig macht und DT_UNHOLY erklaert.
+
+Um das Schwert zu bekommen, braucht man eine Miniquest, die ca 20 AP geben
+wuerde. Am Ende kommt man an einen Endgegner, den man im Team hauen muss,
+alle Mitglieder muessen die Miniquest gerade machen. Zuecken kann das Schwert
+nur jemand, der die Miniquest schon hat und mindestens 20% des Schadens gemacht
+hat. Von dem Schwert gibt es immer nur 10 Stueck, das aelteste wird beim
+clonen des NPC zerstoert und ein Neues erschaffen.
+
+-----------------------------------
+
+ SIEHE AUCH
+
+ ruestungen, waffen, fernwaffen, uniques, npcs, objects, balance
+ attributsveraenderungen, resistenzen, kampfobjekte, grenzwerte, nachteile
+------------------------------------------------------------------------------
+letze Aenderung: 18.10.2005 23:41 - Miril
diff --git a/doc/wiz/befoerderungen b/doc/wiz/befoerderungen
new file mode 100644
index 0000000..f680c08
--- /dev/null
+++ b/doc/wiz/befoerderungen
@@ -0,0 +1,66 @@
+Eine kleine Uebersicht ueber die Befoerderungspolitik im MG
+-----------------------------------------------------------
+
+ Level 1 -> 15:
+     WANN:
+        Man muss Seher sein. (s. auch "hilfe magier")
+     WER:
+        26+ (siehe auch "hilfe vertrag")
+     RECHTE:
+        Eingeschraenkte Leserechte auf der Lib.
+
+ Level 15 -> 20:
+     WANN:
+        Mindestens eine Woche seit dem Anstieg auf 15, damit
+        Einsprueche gegen den Charakter nicht uebergangen werden.
+        Konzept fuer GS
+     WER:
+        Prinzipiell 66+
+        Normalerweise aber EM Gesellenstuecke und Zook
+     RECHTE:
+        Leserechte auf allgemeine Verzeichnisse, eigenes Verzeichnis, Clonen.
+
+ _Alternativ_ gibt es weitere Moeglichkeit:
+ Level 0 -> 20:
+     WANN:
+        Man muss einen Seher als Erstie und ein von den EMs genehmigtes
+        Konzept fuer ein GS haben. Desweiteren verpflichtet man sich, das
+        GS innerhalb von 6 Monaten fertigzustellen. (s. "hilfe magier")
+     WER:
+        EMs (siehe auch "hilfe vertrag")
+     RECHTE:
+        Eingeschraenkte Leserechte auf der Lib.
+
+
+ Level 20 -> 21:
+     WANN:
+        nach GS-Abnahme
+     WER:
+        EM fuer Gesellenstuecke.
+     RECHTE:
+        Normale Leserechte.
+
+ Level 21 -> 25:
+     WANN:
+        Magier hat etwas fuer eine Region geproggt, was angeschlossen
+        wurde/wird.
+     WER:
+        45
+     RECHTE:
+        Schreibrechte in der Domain. Vergabe durch zustaendigen RM.
+
+ Level 25 -> 26+:
+     WANN:
+        Magier wird fuer faehig und selbststaendig gehalten.
+     WER:
+        45
+     RECHTE:
+        Kann nun selbst Spieler sponsoren.
+ 
+ Vorsicht: dieses Dokument ist im stetigen Wandel und stellt nur die
+ allgemeine Politik dar - sich drauf berufen gilt nicht.
+
+SIEHE AUCH:
+     erzmagier, balance
+
+27.10.2009, Zesstra
\ No newline at end of file
diff --git a/doc/wiz/benennung b/doc/wiz/benennung
new file mode 100644
index 0000000..fe94ebc
--- /dev/null
+++ b/doc/wiz/benennung
@@ -0,0 +1,158 @@
+AUTOR   MG, den 22.08.92, Don Rumata
+	This file is part of the Morgengrauen-Mudlib from Jof and Rumata
+
+VERSION 1.1
+
+AKTUALISIERT: MG, den 14.10.93, Chris
+UEBERARBEITET: am 24.08.94 von Viper
+
+THEMA   BENENNUNG VON OBJEKTEN IM MorgenGrauen
+
+INHALT:
+	I.      Einleitung
+	II.     Funktionen, die alle Objekte besitzen muessen
+	III.    Unterstuetzung der Funktionen durch die MG_mudlib
+	IV.     Benennung von Raeumen
+	V.      Benennung von Monstern
+
+I.      EINLEITUNG
+
+	Jedes Objekt in der Mudlib muss auf folgende Weisen identifiziert
+	werden koennen:
+
+	1.)     Es muss einen Namen haben, der innerhalb eines Satzes das
+		Objekt bezeichnen kann.
+
+	2.)     Es muss eine Kurzbeschreibung besitzen.
+
+	3.)     Es muss eine ausfuehrliche Beschreibung besitzen.
+
+	4.)     Es muss eine Menge von Synonymen kennen, mit denen ein
+		Spieler das Objekt "ansprechen" kann.
+
+II.     FUNKTIONEN, DIE ALLE OBJEKTE BESITZEN MUESSEN
+
+	Jedes Objekt im MorgenGrauen sollte folgende Funktionen 
+	implementiert haben:
+
+	1.)     name( fall, dem )
+
+	Diese Funktion soll den Namen des Objektes im jeweiligen
+	Fall mit Artikel (wenn es einen besitzt) zurueckgeben, so
+	dass der Rueckgabewert in einen Satz eingearbeitet werden
+	kann.
+
+	"fall" dient zur Deklination des Objektnamens.
+
+	"dem" bestimmt, welche Artikel benutzt werden sollen.
+	Moegliche Werte fuer "dem":
+
+	0       Benutze unbestimmte Artikel.
+	
+	1       Benutze bestimmte Artikel.
+	
+	2       Benutze bestimmte Artikel, wenn sich mit dem Objekt
+		kein gleichartiges Objekt im selben Raum befindet,
+		sonst benutze einen unbestimmten.
+
+		Statt der 2 kann auch ein String uebergeben werden.
+		In diesem Fall wird getestet, ob sich ein Objekt mit
+		dem String als id im selben Raum befindet.
+
+	2.)     short()
+
+	Diese Funktion liefert eine Beschreibung, die ausgegeben
+	wird, wenn der Raum, in dem das Objekt sich befindet,
+	betrachtet wird.
+
+	3.)     long()
+
+	Diese Funktion liefert eine Beschreibung, die ausgegeben
+	wird, wenn das Objekt angeschaut wird. Im Unterschied zur
+	2.4.5 Mudlib wird die Beschreibung jedoch nicht ausgegeben,
+	sondern als return-Wert zurueckgegeben.
+
+	4.)     id( str )
+
+	Diese Funktion soll 1 zurueckgeben, wenn str eine Zeichen-
+	folge ist, die das Objekt bezeichnen koennte. Diese Zeichen-
+	folge wird in kleinen Buchstaben uebergeben.
+
+	5.)     _query_invis()
+
+	Wenn ein Objekt unsichtbar ist, soll es beim Aufruf dieser
+	Funktion 1 zurueckgeben. Sichtbare Objekte brauchen diese
+	Funktion nicht zu implementieren.
+
+III.    UNTERSTUETZUNG DER FUNKTIONEN DURCH DIE MG_MUDLIB
+
+	Wenn ein eigenes Objekt aus den Standardobjekten abgeleitet
+	wird, sind alle diese Funktionen bereits fertig definiert.
+	Es muessen beim Erzeugen der Objekte nur noch die entsprechenden
+	Werte mitgeteilt werden. Dieses geschieht mit folgenden Funk-
+	tionen, die am besten im create() aufgerufen werden.
+
+	1.)     SetProp( P_NAME, string );
+
+	In name() wird der uebergebene String dekliniert und automatisch
+	mit Artikeln versehen.  Diese Funktion bedenkt auch Faelle, an 
+	die ihr wahrscheinlich nie gedacht habt. Der Genitiv von der 
+	Lahme ist z.B. des Lahmen! Auch fuer andere Faelle bietet diese 
+	Funktion maechtige Unterstuetzung.
+
+	Wenn der String nicht mit Artikeln versehen werden soll, so kann
+	man das mittels der Funktion "SetProp(P_ARTICLE, 0 )" erreichen.
+
+	Damit die Funktion name() ueberhaupt den richtigen Artikel 
+	auswaehlen kann, muss man mit "SetProp( P_GENDER, gender)" das
+	Gechlecht des Objektes bekannt machen. Als gender kann man 
+	MALE oder 1, FEMALE oder 2 und NEUTER oder 0 verwenden.
+
+	Ist das Objekt unsichtbar, so darf string trotzdem nicht 0 sein;
+	stattdessen ist "SetProp( P_INVIS, 1 )" aufzurufen. (Die Zeile
+	"#include <properties.h>" nicht vergessen. :-))
+
+	Da dieses Verfahren sehr fehleranfaellig ist, ist fuer den Namen
+	ein Array von Namen zugelassen, so dass fuer jeden Fall ein Wort
+	uebergeben werden kann. Beispiel.:
+	SetProp( P_NAME, ({ "Mensch", "Menschen", "Menschen", "Menschen" }) );
+
+	2.)     SetProp( P_SHORT, string )
+	
+	In short() wird der uebergebene String ausgegeben. Mittels des
+	process_string-Mechanismus (siehe /doc/efun/process_string)
+	koennen auch varibale Teile in dem String vorkommen.
+	string braucht fuer unsichtbare Objekte nicht auf 0 gesetzt
+	werden.
+
+	3.)     SetProp( P_LONG, string )
+
+	Dito.
+
+	4.)     AddId( string );
+
+	Nehme den String in die Menge der Zeichenketten auf, auf die die
+	eingebaute id-Funktion mit 1 antworten soll.
+
+	5.)     Es reicht, SetProp( P_INVIS, 1 ) aufzurufen, wenn das
+	Objekt unsichtbar wird, und SetProp( P_INVIS, 0 ), wenn es wieder
+	sichtbar wird.
+
+IV.     BENENNUNG VON RAEUMEN
+
+	Bei Raeumen wird die long() bzw. short()-Beschreibung nur dann
+	benutzt, wenn der Raum *von aussen* angeschaut wird. Fuer eine
+	Beschreibung des Raumen von innen sind folgende Funktionen
+	bereitgestellt:
+
+	1.)     SetProp( P_INT_SHORT, string );
+
+	Gebe eine Beschreibung des Raumes fuer den "kurz"-Modus aus.
+
+	2.)     SetProp( P_INT_LONG, string );
+
+	Gebe eine ausfuehrliche Beschreibung des Raumes zurueck.
+
+V.      BENENNUNG VON MONSTERN
+
+	Siehe oben unter /doc/MG/BANISH.
diff --git a/doc/wiz/called_by_player b/doc/wiz/called_by_player
new file mode 100644
index 0000000..897f546
--- /dev/null
+++ b/doc/wiz/called_by_player
@@ -0,0 +1,8 @@
+void BecomesNetDead(object player) wird im Raum aufgerufen, wenn dort ein
+	Spieler netztot wird. player ist der Spieler.
+
+void PlayerQuit(object player) wird im Raum aufgerufen, wenn darin ein
+	Spieler quittet.
+
+void exit() wird im Raum aufgerufen, wenn ein Lebewesen rausgemoved wird.
+	Das Lebewesen ist previous_object()
diff --git a/doc/wiz/enttanken b/doc/wiz/enttanken
new file mode 100644
index 0000000..9a47d47
--- /dev/null
+++ b/doc/wiz/enttanken
@@ -0,0 +1,99 @@
+Enttanken
+=========
+
+                               Generelles:
+                               **********
+
+ALLE Enttank-Moeglichkeiten MUESSEN ortsabhaenig sein.
+Ausnahmen KANN es fuer Questbelohnungen geben.
+
+Toiletten
+---------
+Toiletten rufen die Methoden "defuel_drink" bzw. "defuel_food" im Spieler auf.
+Es werden keine Parameter uebergeben. Rueckgabewerte sind entweder die Fehler
+NO_DEFUEL, wenn man nichts zu Enttanken hat, DEFUEL_TOO_LOW, wenn man nicht
+genug im Magen/Blase hat, DEFUEL_TOO_SOON, wenn man noch nicht
+wieder enttanken darf, ODER der enttankte Wert.
+Beispiel hierzu siehe "man defuel_food".
+
+Man darf DANN enttanken, wenn man mindestens den Fuellwert P_DEFUEL_LIMIT_FOOD
+bzw. P_DEFUEL_LIMIT_DRINK hat und das letzte Enttanken mindestens
+P_DEFUEL_TIME_FOOD bzw. P_DEFUEL_TIME_DRINK her ist.
+Ist dies der Fall, kann man P_DRINK/FOOD*P_DEFUEL_AMOUNT_DRINK/FOOD enttanken,
+wobei dies zur Haelfte ueber ein Random geglaettet wird.
+
+Wer regulaer ueber "defuel_drink" enttankt, enttankt auch automatisch eine
+gewisse Menge an Alkohol. Diese Menge ist von der enttankten Menge, von dem
+im Koerper sich befindenen Alkohol und vom Gewicht des Spielers abhaengig.
+
+Alle genannten Props sind rassenabhaengig.
+Die Berechnungen sind gekapselt in "defuel_food/drink".
+
+Andere Objekte
+--------------
+
+Hier bietet sich an, die zeitliche Nutzung der Enttanke spielerbezogen 
+mittels der Methode  check_and_update_timed_key zu steuern. Dabei sollte
+der zeitliche Abstand nicht zu knapp sein, in der Regel im Bereich von 
+ca. einer Stunde. Der eigentliche Enttankvorgang im Spieler geschieht 
+mittels eat_food, drink_soft oder drink_alcohol durch Uebergabe negativer 
+Werte. Der Betrag dieses Wertes sollte der Erreichbarkeit angemessen sein,
+d.h. leichter erreichbare Enttanken sollten auch nicht zu viel enttanken,
+wenn sie den Spieler komplett enttanken sollen, muessen sie entsprechend
+schwer zu erreichen sein.
+Da die Enttanken ortsabhaengig sind und in der Regel erst erforscht 
+werden muessen, ist eine weitere Begrenzung momentan nicht vorgesehen. 
+
+                              Spezifisches:
+                              ************
+
+----------------------------
+Rassenbeschreibungen fuer Berechnungen in "defuel_food/drink":
+----------------------------
+
+MENSCHEN
+sind wie immer nichts Besonderes und definieren das absolute Mittelmass.
+
+ZWERGE
+koennen mehr in Blase und Magen haben und koennen auch so richtig abladen.
+Dafuer muessen sie laenger warten, bis es sich lohnt, zu enttanken.
+
+ELFEN
+sind inkontinent und Kleinmengengeber.
+
+DUNKELELFEN
+sind von den Werten her in etwa wie Elfen.
+
+HOBBITS
+koennen essen bis zum Umfallen. Sie laden dann richtig ab, muessen aber auch
+entsprechend warten.
+
+FELINEN
+sind den Menschen aehnlich.
+
+ORKS
+sind auch nichts Besonderes. 
+
+Wer die genauen Werte einsehen moechte, moege in den shells nachgucken.
+
+                                Logisches:
+                                *********
+
+Jede (!) Moeglichkeit zur Enttankung, muss dem zustaendigen Magier
+fuer Heilungs-Balance gemeldet und von diesem genehmigt werden. Wer
+diesen Posten momentan innehat, kann dem MailAlias "heilungs_balance"
+entnommen werden.
+
+Siehe auch:
+----------
+     Tanken:    consume, drink_alcohol, eat_food, drink_soft
+     Heilung:   heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp, buffer_sp
+     Timing:    check_and_update_timed_key
+     Enttanken: defuel_drink, defuel_food
+     Props:     P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_DRINK
+     Konzepte:  heilung, food
+
+----------------------------------------------------------------------------
+Last modified: 02.11.2005 - Miril
diff --git a/doc/wiz/familien b/doc/wiz/familien
new file mode 100644
index 0000000..39bf831
--- /dev/null
+++ b/doc/wiz/familien
@@ -0,0 +1,24 @@
+Eine Familie umfasst den Erstie und alle Zweities, sprich alle diese haben den
+gleichen "Familiennamen". Dieser Name ist in der Regel die UUID des Ersties
+dieser Familie. Falls aber der Erstie sich aendern sollte (z.B. Magierwerdung
+eines Zweities) und sich der Familienname nicht aendern soll, dann koennen
+wir den Namen dieser Familie beibehalten (d.h. alter Erstie).
+
+Will man wissen, welcher Familie ein Char angehoert (egal, ob Erstie oder
+Zweitie), dann geht das mit:
+# xcall /secure/zweities->QueryFamilie(player_object)
+
+Des Weiteren liefert dieses Objekt auch noch zu jedem Zweitie den Erstie und
+zu jedem Erstie die Liste aller bekannten Zweities:
+# xcall /secure/zweities->QueryErstieName(player_object)
+# xcall /secure/zweities->QueryErstieUUID(player_object)
+# xcall /secure/zweities->QueryZweities(player_object)
+
+Der Datenbestand ist (noch) nicht vollstaendig, daher fehlen da noch viele
+Chars. Die werden aber in absehbarer Zeit dort nachgetragen.
+
+Die Familie wird in Zukunft genutzt, um Dinge zu personalisieren, welche fuer
+den Spieler, aber nicht fuer den Char individuell sein sollen. Sprich:
+personalisiert man irgendwas ueber die Familie, koennen alle Chars dieser
+Familie das irgendwas nutzen.
+
diff --git a/doc/wiz/fehlerteufel b/doc/wiz/fehlerteufel
new file mode 100644
index 0000000..7b0b916
--- /dev/null
+++ b/doc/wiz/fehlerteufel
@@ -0,0 +1,181 @@
+Der Fehlerteufel
+================
+
+die Mudlib speichert die aufgetretenen Fehler und Warnungen. Dabei werden 
+folgende Daten mitgespeichert:
+- Zeit (erstes Mal, zuletzt)
+- In welchem Objekt und welchem Programm der Fehler war
+- Zeilenr.
+- Fehlermeldung
+- Objekt, dessen Heartbeat, den Fehler ausloeste
+- this_interactive() bzw. this_player()
+- den Befehl, den TI eingegeben hat
+- das Environment von TI oder TP
+- wie oft der Fehler schon auftrat
+- der Backtrace
+- ob der Fehler in einem catch() auftrat
+
+Zusaetzlich werden von Spielern per "bug", "fehler" oder "sonnenfehler"
+gemeldete Fehler gespeichert.
+
+Der Fehlerteufel dient nun dazu, sich diese Infos darstellen zu lassen. Nach 
+dem Clonen von /obj/tools/fehlerteufel habt ihr folgende Moeglichkeiten:
+
+- fehlerliste <auswahl s. Kommando fehlermodus>
+  Dieser Befehl stellt euch eine Liste aller bekannten Fehler dar, die unter
+  einer UID auftraten, fuer die ihr zustaendig seid (z.B. "zesstra", 
+  "d.inseln.zesstra", "GUILD.magierpack", s. auch QueryUIDsForWizard()). Die
+  Liste umfasst die eindeutige Fehler-ID, den Ladenamen des fehlerausloesenden
+  Objekts und die UID.
+  Je nach Argument werden div. Fehler oder Warnungen ausgegeben. Wird keins 
+  von beiden angegeben, wird je nach Einstellung von 'fehlermodus' aufgelistet.
+
+- fehlerabfrage <id>
+  Hiermit lassen sich die Detail-Informationen zu <id> anzeigen. <id> bekommt
+  ihr entweder aus "fehlerliste" oder von -debug/-entwicklung/-warnungen, dort
+  werden diese IDs mit ausgegeben. Ohne Angabe der <id> wird der letzte
+  betrachtete Fehler ausgegeben.
+  Neben der numerischen ID ist hierbei auch die Hash-ID moeglich.
+  Es kann auch der Ladename eines Objekts angegeben werden, dann werden alle
+  zu diesem Objekt gehoerenden Eintraege auf einmal angezeigt, z.B.
+    fehlerabfrage /d/unterwelt/raeume/wald3
+  Der Ladename muss mit einem / beginnen.
+
+- fehlerloeschen <id>
+  Fehler mit der ID <id> zum Loeschen markieren (z.B. wenn gefixt). Die 
+  eigentlich Loeschung findet innerhalb von 24h statt. Die Fehler werden nach 
+  diesem Befehl nicht mehr in der Fehlerliste angezeigt. Ohne Angabe der <id>
+  wird der letzte benutzte Fehler geloescht.
+  Wiederholt man den Befehl, wird die Loeschmarkierung wieder entfernt.
+  Es kann auch der Ladename eines Objekts angegeben werden, dann werden alle
+  zu diesem Objekt gehoerenden Eintraege auf einmal geloescht, z.B.
+    fehlerloeschen d/unterwelt/raeume/wald3
+
+- fehlereingabe <objekt>
+  Hiermit laesst sich per Hand ein Eintrag fuer das angegebene Objekt im
+  Fehlerteufel erstellen. Das Objekt kann mit einer seiner IDs oder seinem
+  vollstaendigen Objektnamen angegeben werden. Wird kein Objekt angegeben,
+  wird die Umgebung des Magiers als Objekt genutzt. Bsp:
+    fehlereingabe seil
+    fehlereingaeb /obj/seil#5635
+
+- fehlerrefresh
+  Der Fehlerteufel hat einen Zwischenspeicher fuer die Fehlerliste. Dieser 
+  Befehl loescht diesen Zwischenspeicher und holt die Fehlerliste neu.
+
+- fehlerfilter
+  Hiermit laesst sich ein Filter fuer UIDs einstellen. (s.u.) Ist er aktiv, 
+  werden per 'fehlerliste' keine Fehler mehr angezeigt, die im Filter
+  eingetragen wurden.
+
+- fehlermodus <fehler|warnungen>
+  Einstellen, welche Arten von Eintraegen im Fehlerteufel vom Kommando
+  'fehlerliste' ausgegeben werden soll:
+    laufzeitfehler: Laufzeitfehler werden ausgegeben (-debug, -entwicklung)
+    laufzeitwarnungen: Laufzeitwarnungen werden ausgegeben (-warnungen)
+    ladezeitfehler: Fehler beim Laden eines Objekts werden ausgegeben  
+    ladezeitwarnungen: Warnungen beim Laden eines Objekts werden ausgegeben
+    fehlerhinweise: Fehler, die Spieler/Magier abgesetzt haben
+    ideen: Ideen, die Spieler/Magier abgesetzt haben
+    typos: Typos, die Spieler/Magier abgesetzt haben
+    md: Fehlende Details, die Spieler/Magier abgesetzt haben
+    fehler: alle moeglichen Fehler werden ausgegeben
+    warnungen: alle moeglichen Warnungen werden ausgegeben
+    alle: alle Fehler + Warnungen werden ausgegeben
+    
+    Ohne Argument: aktuellen Modus ausgeben.
+
+- fehlermonitor
+  Hiermit lassen sich UIDs angeben, die man zusaetzlich zu den eigenen
+  auch noch beobachten will.
+  Hierbei sind auch einige UID-Aliase moeglich, z.B. 'magier', 'region', 
+  'p.service', 'p' oder 'gilde'.
+  BTW: nach Aenderung dieser Liste sollte man "fehlerrefresh" aufrufen.
+
+- flock <id> <bemerkung>
+  So markierte Fehler werden nicht mehr automatisch (nach 31 Tagen ohne
+  Aenderung) geloescht. ABER: Solcherart gesperrte Fehler werden momentan
+  _niemals_ automatisch geloescht, deshalb denkt bitte daran, sie entweder
+  selber zu loeschen oder sie wieder freizugeben, wenn ihr sie nicht mehr
+  braucht.
+
+- funlock <id> <bemerkung>
+  Gibt den Fehler wieder zum automatischen Loeschen frei.
+
+- ffix <id> <bemerkung zum fix>
+  Fehler wird als "gefixt" markiert und eine Mail an alle fuer das buggende
+  Objekte zustaendigen Magier geschickt (soweit bekannt). Anschliessend 
+  werden die Fehler vom Fehlerteufel nicht mehr angezeigt.
+  Im Falle von durch Spieler berichteten Fehlern wird dem jeweiligen Spieler
+  beim Fixen ebenfalls eine Mail geschickt.
+  Als gefixt markierte Fehler werden nach einiger Zeit geloescht.
+  Es empfiehlt sich fuer eigene Fehler, diese nach Beheben einfach zu
+  Loeschen, wenn man keine Mail ueber den Fehler erhalten moechte.
+
+- funfix <id> <bemerkung warum der Bugfix scheisse war ;)>
+  Wenn ihr bis zu der "Archivierung" gefixter Fehler feststellt, dass ihr den 
+  Fehler wohl doch nicht gefixt habt, koennt ihr das wieder rueckgaengig 
+  machen.
+
+- fnotiz <id> <bemerkung>
+  Wenn euch an so einem Fehler was auffaellt oder ihr eine Idee habt, koennt ihr
+  das so also "verewigen". Notizen kann jeder Magier an Fehler dranhaengen,
+  dafuer braucht man keine besonderen (Schreib)Rechte. Die Notizen werden vom
+  Fehlerteufel ausgegeben und stehen auch im CHANGELOG.
+  Anmerkung: Es gibt (absichtlich) keine Moeglichkeit, Notizen wieder zu
+  loeschen.
+
+- fuebertrage <id> <newuid> <bemerkung>
+  Wenn ihr einen Fehler habt, fuer den ihr nicht zustaendig seid, weil der
+  Ursprung des Fehlers nicht in einem eurer Files liegt, koennt ihr diesen
+  Fehler an eine andere UID mit einer Bemerkung uebertragen. Danach ist der
+  Magier von <newuid> zustaendig und hat Schreibrechte auf den Fehler.
+  <newuid> kann z.B. sowas wie 'd.inseln.zesstra' oder 'zesstra' sein. Liegt
+  der Fehler in einem Objekt in /d/, solltet ihr auf jeden Fall
+  d.region.magier benutzen, damit ggf. der RM der Region auch zustaendig wird.
+
+UID-Filter:
+  a) fehlerfilter an
+     Schaltet den Filter ein
+  b) fehlerfilter aus
+     schaltet den Filter aus
+  c) fehlerfilter alle
+     schaltet den Filter ein _und_ schreibt alle UIDs, fuer die man zustaendig
+     ist, in den Filter, es wird dann nichts mehr angezeigt.
+  d) fehlerfilter keine
+     schaltet den Filter ein _und_ loescht den Filter, d.h. es wird trotzdem
+     erstmal noch nix gefiltert..
+  e) fehlerfilter +zesstra +d.inseln.zesstra -d.ebene.zesstra
+     Fuegt "zesstra" und "d.inseln.zesstra" den aktuellen Filtereinstellungen
+     hinzu und loescht "d.ebene.zesstra" aus dem Filter.
+     Beliebige Kombinationen moeglich. Ohne - oder + am Anfang wird jeweils
+     invertiert, also hinzugefuegt, wenn noch nicht drin und entfernt, wenn
+     schon in der Liste.
+
+Fehler-Monitor:
+  a) fehlermonitor keine
+     Loescht alle beobachteten UIDs
+  b) fehlermonitor +atamur -d.polar.atamur
+     Fuegt "atamur" der Beobachtungsliste hinzu und entfernt "d.polar.atamur".
+     Beliebige Kombinationen moeglich. Ohne - oder + am Anfang wird jeweils
+     invertiert, also hinzugefuegt, wenn noch nicht drin und entfernt, wenn
+     schon in der Liste.
+
+Zugriffsrechte:
+  - Lesen und Anhaengen (Notizen, Loeschsperren) darf jeder Magier
+  - Loeschen, Fixen und UID neu zuordnen duerfen fuer die UID zustaendige Magier
+  - Fixes zurueckziehen darf jeder Magier (solange issue nicht expired)
+  - EM+ duerfen alles
+
+Randbemerkung:
+  Moechte man nicht, dass vom Magier selbst ausgeloeste Fehler in /players/
+  protokolliert werden, kann der Magier _in sich_ die Prop P_DONT_LOG_ERRORS
+  (aus /secure/errord.h) auf 1 setzen.
+  ACHTUNG: das bedeutet, dass ueber Fehler keine Informationen mehr
+  vorliegen, die beim Fixen helfen koennen. Bedenkt das bitte, wenn ihr die
+  Prop setzt.
+ 
+
+SIEHE AUCH:
+ QueryUIDsForWizard(), QueryWizardForUID()
+
diff --git a/doc/wiz/fernkampfwaffen b/doc/wiz/fernkampfwaffen
new file mode 100644
index 0000000..f8dd285
--- /dev/null
+++ b/doc/wiz/fernkampfwaffen
@@ -0,0 +1,128 @@
+Zusammenfassung zu Fernkampfwaffen
+==================================
+
+  Schusswaffe:
+  ============
+    Standardobjekt: /std/ranged_weapon.c
+
+    P_WC:           gibt den Schaden im Nahkampf an (wenn man damit auf einen
+                    Gegner einpruegelt. Default 30.
+    P_QUALITY:      nur beim Nahkampf relevant. Default 100.
+    P_NR_HANDS:     Boegen und Armbrueste sind in jedem Fall zweihaendig.
+    P_SHOOTING_WC:  Die Basis-Waffenklasse der Fernwaffe.
+    P_RANGE:        Reichweite der Waffe. Default 50.
+    P_STRETCH_TIME: Anzahl der Runden, die zum Laden/Spannen der Waffe
+                    benoetigt werden. Default 1.
+    P_AMMUNITION:   Benoetigter Munitionstyp.
+
+    Eine HitFunc wirkt sich auf die P_WC aus, nicht auf P_SHOOTING_WC!
+
+    Methoden:
+    static int cmd_shoot(string str);
+    * Befehlsauswertung und Schussvorbereitung, wird durch
+      AddCmd( ({"schiess", "schiesse"}), "cmd_shoot");
+      verknuepft
+
+    static int shoot_dam(mapping shoot);
+    * Schadensermittlung
+
+    static string FindRangedTarget(string str, mapping shoot);
+    * Gegnerermittlung
+
+  Munition:
+  =========
+    Standardobjekt: Nutzung von /std/unit ist empfohlen
+
+    P_SHOOTING_WC: legt die Munitionsstaerke fest
+    P_DAM_TYPE:    legt die Schadensart des Schussangriffs fest
+
+    Eine HitFunc in der Munition wirkt sich auf P_SHOOTING_WC aus!
+
+  Allgemeines:
+  ============
+    In der Waffe legt man ueber P_AMMUNITION fest, welche Art Munition
+    damit verschossen werden kann. In der Munition muss diese Munition
+    auch als ID gesetzt werden.
+
+    Ueber P_STRETCH_TIME legt man fest, alle wieviel Runden die
+    Fernkampfwaffe abgefeuert werden kann (default: 1).
+
+    Der verursachte Schaden wird aus der Staerke der Fernkampfwaffe
+    und der Staerke der Munition bestimmt. In beiden wird diese in der
+    Property P_SHOOTING_WC angegeben.
+
+    Zusaetzlich kann man in P_RANGE die Reichweite der Fernkampfwaffe
+    festlegen. Hat man einen Raum A, der sich innerhalb eines anderen
+    Raumes befindet (z.B. Transporter), so kann man mittels P_SHOOTING_AREA
+    dessen 'Groesse' festlegen. Mit einer Waffe, deren P_RANGE mindestens
+    gleich diesem Zahlenwert ist, kann aus diesem Raum heraus geschossen
+    werden.
+    Alternativ kann man in A einen anderen Raum B)in die Property
+    P_TARGET_AREA schreiben.
+
+BEISPIEL:
+    // #1 siehe auch /doc/beispiele/fernwaffen fuer ladbaren Code
+
+    // #2 eine einfache, aber gute Schleuder
+    inherit "/std/ranged_weapon";
+
+    void create() {
+      if (!clonep(this_object())) return;
+      ::create();
+
+      SetProp(P_SHORT, "Eine Schleuder");
+      SetProp(P_INFO,
+        "Die Syntax lautet: schleuder <geschoss> auf <ziel>\n");
+      // sonstige Objektprops ...
+
+      RemoveCmd(({"schiess", "schiesse"})); // entferne Default-Kommando
+      AddCmd(({"schleuder", "schleudere"}), #'cmd_shoot);
+
+      SetProp(P_WC, 10);          // eine Schleuder ist erstmal harmlos
+      SetProp(P_DAM_TYPE, DT_WHIP);
+
+      SetProp(P_SHOOTING_WC, 90); // ziemlich gute Schleuder
+      SetProp(P_NR_HANDS, 1);     // einhaendig
+      SetProp(P_WEAPON_TYPE, WT_RANGED_WEAPON);
+      SetProp(P_AMMUNITION, MUN_STONE);
+      SetProp(P_STRETCH_TIME, 1);
+      SetProp(P_RANGE, 30);       // 30 weit kann man damit nur schleudern
+    }
+
+    // #3 passende Munition
+    inherit "/std/unit";
+
+    void create() {
+      if (!clonep(this_object())) return;
+      ::create();
+
+      SetProp(P_NAME, ({"Schleuderstein", "Schleudersteine"}) );
+      SetProp(P_LONG, break_string(
+        "Hervorragend geformte Schleudersteine aus Murmelnit.", 78));
+      SetProp(P_GENDER, MALE);
+      SetProp(P_AMOUNT, 1);
+      SetProp(P_SHOOTING_WC, 50);
+      SetProp(P_DAM_TYPE, ({DT_BLUDGEON}));
+      SetProp(P_WEAPON_TYPE, WT_AMMU);
+      SetProp(P_MATERIAL, MAT_STONE);
+
+      SetGramsPerUnits(60,1);
+      SetCoinsPerUnits(25,1);
+
+      AddId(MUN_STONE);
+      AddSingularId(({"stein", "schleuderstein"}));
+      AddPluralId(({"steine", "schleudersteine"}));
+      AddClass(CL_AMMUNITION);
+    }
+
+SIEHE AUCH:
+    Generell:  P_SHOOTING_WC, P_STRETCH_TIME, P_AMMUNITION
+    Methoden:  FindRangedTarget(L), shoot_dam(L)
+    Gebiet:    P_RANGE, P_SHOOTING_AREA, P_TARGET_AREA
+    Waffen:    P_WEAPON_TYPE, P_WC, P_EQUIP_TIME, P_NR_HANDS
+    Kampf:     Attack(L), Defend(L), P_DISABLE_ATTACK, P_ATTACK_BUSY
+    Team:      PresentPosition(L)
+    Sonstiges: P_NOGET
+    Balance:   fernwaffen, waffen, balance
+
+29.Jul 2014 Gloinson
\ No newline at end of file
diff --git a/doc/wiz/fernwaffen b/doc/wiz/fernwaffen
new file mode 100644
index 0000000..947c517
--- /dev/null
+++ b/doc/wiz/fernwaffen
@@ -0,0 +1,118 @@
+
+ FERNWAFFEN
+
+  a. Allgemeines
+     Fernwaffen sind eine relativ neue Ergaenzung zum Kampfsystem dieses Muds, 
+     die mit der Einfuehrung des Teamkampfes erst moeglich wurde.
+     Schon bisher gab es einzelne Fernwaffen (z.B. Robins Bogen), die aber
+     Inselloesungen und Sonderfaelle waren. Das neue Standardobjekt fuer 
+     Fernwaffen ist nun /std/ranged_weapon.c, das die noetige Funktionalitaet 
+     bietet und leicht ueber Properties zu konfigurieren ist. Mit Fernwaffen 
+     sind uebrigens ausnahmslos Waffen gemeint, die Munition benoetigen, 
+     nicht etwa Speere oder dergleichen.
+
+  ** Bisher sind alle Fernwaffen ausnahmslos genehmigungspflichtig, das  **
+  ** gilt auch fuer jegliche Munition.                                   **
+     
+  b. Properties
+     P_WC
+        Vorsicht mit dieser Property. Bei Fernwaffen gibt sie _nur_ den
+        Schaden bei Zweckentfremdung der Waffe als Knueppel an. 
+        Dementsprechend ist dieser Wert extrem niedrig zu halten.
+        Standardwert ist hier 30, der auch nur in Ausnahmefaellen 
+        ueberschritten werden sollte. Kaum eine Armbrust oder ein Bogen 
+        taugt nunmal als grossartige Nahkampfwaffe.
+
+     P_QUALITY
+        Wird nur beim Nahkampf mit der Waffe beachtet. Standardmaessig auf
+        100 gesetzt, da Boegen und Armbrueste leicht beschaedigt werden,
+        wenn man damit auf jemanden einpruegelt.
+
+     P_HIT_FUNC 
+        HitFunc fuer den _Nahkampf_. Hat beim Schuss mit der Waffe keinen
+        Einfluss. 
+                
+     P_NR_HANDS
+        Boegen und Armbrueste sind in jedem Fall zweihaendig. Einhaendige
+        Fernwaffen sind aber denkbar (Schlingen zum Schleudern kleiner 
+        Steine z.B.)
+        
+     P_SHOOTING_WC
+        Die Basis-Waffenklasse der Fernwaffe. Zu ihr wird die Waffenklasse
+        der Munition addiert, um den endgueltigen Angriffswert beim Schuss
+        zu berechnen.
+     
+     P_RANGE 
+        Reichweite der Waffe in Metern. Wichtig, wenn aus Containern 
+        (Wachtuermen, Schiffen, etc.) nach aussen geschossen wird.
+        Damit das funktioniert, muss dieser Wert hoeher sein als der
+        im Container definierte (steht dort in der P_SHOOTING_AREA).
+    
+     P_STRETCH_TIME
+        Anzahl der Runden, die zum Laden/Spannen der Waffe benoetigt
+        werden. 1 ist hier der Standardwert, das bedeutet, es kann jede
+        Runde geschossen werden.
+     
+     P_AMMUNITION
+        Benoetigter Munitionstyp. Hier ist eine der moeglichen Konstanten
+        (MUN_*) einzusetzen (z.B. MUN_ARROW fuer Boegen).
+     
+     P_NOGET
+        Hat bei Fernwaffen eine zusaetzliche Bedeutung. Wenn gesetzt, muss
+        die Waffen nicht gezueckt werden, um sie abfeuern zu koennen. Das
+        ist z.B. fuer Katapulte gedacht, die im Raum stehen.
+        
+     Fuer die Munition gibt es kein Standardobjekt. Wichtig ist nur, dass 
+     die entsprechenden Properties gesetzt sind. Normalerweise sollte die 
+     Munition natuerlich eine Unit sein, aber auch Einzelobjekte (ein
+     besonderer Pfeil oder ein grosser Stein fuer ein Katapult) sind 
+     moeglich.
+
+     Properties fuer die Munition sind:
+     
+     P_SHOOTING_WC
+        Die Waffenklasse der Munition. Wird zur WC der Waffe addiert.
+        
+     P_DAM_TYPE
+        Schadenstyp der Munition. Sollte normalerweise DT_PIERCE fuer 
+        Pfeile aller Art und DT_BLUDGEON fuer stumpfe Munition wie Steine
+        sein. Magische Schadensarten sind aber natuerlich moeglich.
+        
+     P_HIT_FUNC
+        HitFunc, die beim Schuss mit der Munition benutzt wird.
+        
+     Ausserdem muss in der Munition mittels AddId() der entsprechende
+     Munitionstyp gesetzt werden, z.B. MUN_ARROW.
+
+  c. Spezialwaffen/Fernwaffen mit Sonderfunktionen
+  
+     Siehe Hinweise zu entsprechenden Nahkampfwaffen.
+     
+  d. Genehmigungsgrenzen
+     Alle Waffen dieser Art sind grundsaetzlich genehmigungspflichtig.
+     Folgende Werte sollten allerdings Obergrenzen darstellen, die
+     im Normalfall nicht zu Ueberschreiten sind:
+     
+     Waffe kann jede Runde abgefeuert werden:  P_SHOOTING_WC 100
+     Waffe braucht eine Ladezeit            :  P_SHOOTING_WC 130
+     
+     Die Obergrenze fuer Munition liegt bei :  P_SHOOTING_WC 60.
+
+  e. Nachbemerkung
+     Seid bitte vorsichtig mit P_SHOOTING_AREA in Raeumen/Containern. 
+     Bisher ist dieses Schiessen von Raum zu Raum weitestgehend ungetestet,
+     und es ist nicht klar, welche Probleme das verursachen kann. Wenn 
+     eventuelle Ziele keine Moeglichkeit haben, sich zu wehren oder 
+     wegzulaufen, ist schnell jegliche Balance dahin. Die Regionsmagier
+     haben bei Abnahme von Gebieten darauf zu achten, dass diese Property
+     nur in wenigen, gut begruendeten Raeumen gesetzt wird.
+  
+ SIEHE AUCH
+
+     balance, ruestungen, waffen, uniques, npcs, grenzwerte,
+     attributsveraenderungen, resistenzen, kampfobjekte,
+     fernkampfwaffen
+
+------------------------------------------------------------------------------
+ LETZTE AeNDERUNG:
+    Don, 10.08.2000, 22:30:00 von Paracelsus
diff --git a/doc/wiz/food b/doc/wiz/food
new file mode 100644
index 0000000..698e3f6
--- /dev/null
+++ b/doc/wiz/food
@@ -0,0 +1,223 @@
+FOOD, DRINK & ALCOHOL
+=====================
+
+    Es wird empfohlen, jede tragbare Heilung ueber "/std/food"
+    zu implementieren. Hier braucht man nur wenige Properties setzen, um
+    sicherzugehen, dass die Heilung korrekt verlaeuft.
+
+    Bitte bei der Realisierung von tragbaren Tanken IMMER mit der Balance
+    sprechen. Die Heilung unterliegt genauer Kontrolle. Ewig haltbare Speisen
+    sind sowieso genehmigungspflichtig und nur mit guter Begruendung und
+    strengen Auflagen erlaubt.
+
+FEATURES:
+    Unterstuetzt wird das Konsumieren von Speisen per Essen oder Trinken auch
+    in mehreren Portionen. Die Speisen verderben und werden vernichtet.
+    Es sind Lebensmittel mit Behaelter moeglich, so dass dieser leer
+    zurueckbleibt, wenn der Inhalt gegessen oder vernichtet wurde.
+    Die Wirkung von Speisen kann neben der Zufuehrung von Lebens- und Konzen-
+    trationspunkten erweitert werden. Die Wirkung verdorbener Speisen kann 
+    getrennt definiert werden.
+    Wert und Gewicht der Speise werden in Abhaengigkeit der Restmengen immer
+    korrekt berechnet.
+
+REALISIERUNG:
+    Die Realisierung der Timer laeuft ueber die Resets der Speise. Callouts
+    werden lediglich verwendet, um den Aufruf des Resets zu garantieren.
+    Es wird auch geprueft, dass der Aufruf der Resets per Hand nichts
+    durcheinander bringt.
+
+    Des Weiteren ist sichergestellt, dass der Spieler nicht mit Futter in
+    Beruehrung kommt, dessen Timer zum Verderben initialisiert ist.
+
+    Das Konzept ist dem Heilungskonzept der Kneipen angepasst worden.
+    Dem entsprechend sind die Properties sehr aehnlich.
+
+PROPERTIES:
+
+      P_PORTIONS : Anzahl der Portionen (wie oft kann man abbeissen / 
+                   einen Schluck nehmen)
+
+          P_FOOD : Fuellgrad der Speise pro Portion, muss gesetzt sein, wenn
+                   P_DRINK nicht gesetzt ist
+         P_DRINK : Fuellgrad der Fluessigkeit pro Portion, muss gesetzt sein,
+                   wenn P_FOOD nicht gesetzt ist
+       P_ALCOHOL : Alkohollevel pro Portion 
+
+        P_WEIGHT : Gewicht pro Portion (bei QueryProp(P_WEIGHT) wird das
+                   komplette Gewicht aller Portionen + eventuell Behaelter 
+                   zurueckgegeben)
+         P_VALUE : Wert pro Portion  (bei QueryProp(P_VALUE) wird der
+                   komplette Wert aller Portionen + eventuell Behaelter 
+                   zurueckgegeben)
+
+            P_HP : Anzahl der LP, die prop Portion geheilt/geschwaecht werden
+            P_SP : Anzahl der KP, die prop Portion geheilt/geschwaecht werden
+  P_DISTRIBUTION : Verteilung der Heilung auf die Heartbeats
+                   (siehe Hilfe zu H_DISTRIBUTION in consume)
+
+      P_LIFETIME : Zeit in Sekunden, bis die Speise verdirbt (>0)
+                   Zaehlt ab der ersten Inbesitznahme durch einen Spieler
+P_RESET_LIFETIME : Zeit in Resets, bis die Speise verdirbt (>0)
+                   Die Laenge der einzelnen Resets wird wie ueblich berechnet
+                   und P_LIFETIME entsprechend auf durchschnittlich
+                   P_RESET_LIFETIME * 45 * 60 gesetzt.
+                   (existiert, da bisher meistens in Resets gerechnet wurde)
+                   Sollte sinnvollerweise nur als SetProp(P_RESET_LIFETIME)
+                   verwendet werden, kann aber auch abgefragt werden
+
+   P_EMPTY_PROPS : Mapping mit Werten des Behaelters
+                   Alle hier angegebenen Werte (ausser P_PORTIONS) werden
+                   in der Speise gesetzt, wenn die letzte Portion konsumiert
+                   wurde. Wenn diese Prop leer ist, wird das Objekt zerstoert,
+                   wenn keine Portionen mehr da sind.
+                   Achtung: es werden keine closures unterstuetzt! 
+           P_IDS :   Wert in P_EMPTY_PROPS
+                     Liste der IDs des leeren Behaelters
+                     Achtung: es werden keine closures unterstuetzt!
+    P_ADJECTIVES :   Wert in P_EMPTY_PROPS
+                     Liste der Adjektive des leeren Behaelters
+                     Achtung: es werden keine closures unterstuetzt!
+         P_VALUE :   Wert in P_EMPTY_PROPS
+                     Wert des leeren Behaelters
+        P_WEIGHT :   Wert in P_EMPTY_PROPS
+                     Gewicht des leeren Behaelters
+
+        P_NO_BAD : Flag, ob die Speise verderben kann
+                   Darf nur in Absprache mit der Balance auf 1 gesetzt werden!
+
+   P_DESTROY_BAD : Wert, was beim Verderben mit dem Object passiert
+                   DESTROY_BAD   = Die Speise wird beim Verderben zerstoert
+                                   bzw. der Behaelter wird geleert (default)
+                   DESTROY_NEVER = Die Speise wird beim Verderben nicht
+                                   zerstoert
+                   pos. integer  = Anzahl der Sekunden, die zwischen Verderben
+                                   und Zerstoeren der Speise liegen sollen
+
+MESSAGES: (durchlaufen replace_personal() und koennen somit Platzhalter
+          fuer Speise (1. Argument) und Konsument (2. Argument) enthalten)
+
+   P_CONSUME_MSG : fuer den Raum, wenn konsumiert wird
+     P_EATER_MSG : an den Konsumenten
+     P_EMPTY_MSG : wenn leere Behaelter konsumiert werden
+    P_NOFOOD_MSG : wenn Getraenke gegessen werden
+   P_NODRINK_MSG : wenn Futter getrunken wird
+       P_BAD_MSG : wenn Speisen verderben
+    P_REMOVE_MSG : wenn Speisen vernichtet werden
+                   (nur wenn sie nicht beim Verderben vernichtet werden)
+       P_ENV_MSG : wenn im Raum liegende Speisen konsumiert werden
+                   (ist diese Prop leer, geht das sogar!)
+ P_FOOD_FULL_MSG : wenn man nix mehr essen kann
+P_DRINK_FULL_MSG : wenn man nix mehr trinken kann
+  P_ALC_FULL_MSG : wenn man keinen Alkohol mehr vertraegt
+
+METHODEN:
+             consume : wird beim Konsumieren aufgerufen, wenn klar ist,
+                       dass was zum Konsumieren da ist.
+                       gibt das Ergebnis von try_consume() zurueck
+         try_consume : bereitet die Daten auf und fuehrt living->consume() aus
+                       kann zur Pruefung mit testonly-Flag aufgerufen werden
+                       gibt das Ergebnis von living->consume() zurueck
+     success_consume : wird von consume() aufgerufen, wenn Konsumieren klappt
+                       gibt die Meldungen zum Konsumieren aus
+      failed_consume : wird aufgerufen, wenn Konsumieren nicht klappt
+                       gibt den Grund fuer den Fehlschlag aus
+                       (je nach Ergebnis von living->consume())
+                       
+         consume_bad : Aendert die Daten fuer living->consume(), wenn eine
+                       verdorbene Speise konsumiert wird
+                       Standard: Heilung wirkt nicht, Vergiftung +1
+            make_bad : wird aufgerufen, wenn die Speise gerade verdirbt
+                       Gibt die Meldungen beim Verderben aus
+                       Vernichtet das Objekt, wenn das gewollt ist 
+                       Die Methode wird auch aufgerufen, wenn nur noch der
+                       Behaelter existiert! Also den Test is_not_empty() nicht
+                       vergessen!
+        make_destroy : wird aufgerufen, wenn die Speise bereits verdorben ist
+                       und die Zeit aus P_DESTROY_BAD abgelaufen ist.
+                       Gibt die Meldung zum Zerstoeren aus und ruft
+                       make_empty aus, um die Speise bzw. den Inhalt des
+                       Behaelters zu zerstoeren. Ausserdem wird der Reset
+                       abgeschaltet.
+                       Die Methode wird auch aufgerufen, wenn nur noch der
+                       Behaelter existiert! Also den Test is_not_empty() nicht
+                       vergessen!
+                       
+          make_empty : wird aufgerufen, wenn die letzte Portion konsumiert wird
+                       Macht aus einem vollen Behaelter einen leeren oder
+                       vernichtet das Objekt. Der Behaelter verdirbt also im
+                       Normalfall nicht!
+
+                init : Startet den Timer zum Verderben der Speise
+                       (start_lifetime()), wenn sich das Objekt in einem
+                       Spieler befindet.
+                       Prueft, ob Laufzeiten fehlerhafterweise nicht beendet
+                       wurden und holt es dann nach
+          NotifyMove : Startet den Timer zum Verderben der Speise
+                       (start_lifetime()) auch, wenn die Speise in einen
+                       Spieler bewegt wird, ohne dass init() aufgerufen
+                       wurde.
+               reset : wird fuer 3 Situationen verwendet:
+                       1: Das Futter wurde bewegt, der Timer aber noch nicht 
+                          initialisiert -> es wird geprueft, ob der Timer
+                          gestartet werden muss.
+                       2: Der Timer ist abgelaufen ->
+                          laesst die Speise verderben und vernichtet sie
+                          gegebenenfalls
+                       3: Der Timer nach dem Verderben ist abgelaufen ->
+                          vernichtet die Speise
+                       Es wird immer geprueft, ob die Resets zeitgerecht
+		       aufgerufen wurden und die Aktionen nicht zur falschen
+		       Zeit passieren
+
+        is_not_empty : Flag, ob noch Portionen vorhanden sind
+        is_drinkable : Flag, ob Speise trinkbar ist
+                       (nur wenn P_DRINK gesetzt und P_FOOD NICHT gesetzt ist)
+          is_eatable : Flag ob Speise essbar ist
+                       (wenn P_FOOD gesetzt (P_DRINK ist egal))
+              is_bad : Flag, ob Speise verdorben ist
+
+get_current_lifetime : Zeit in Sekunden, wie lange der Timer zum Verderben
+                       laeuft (ist immer 0, wenn P_NO_BAD gesetzt ist)
+      start_lifetime : startet den Timer zum Verderben der Speise falls keine
+                       Gruende dagegen sprechen, wird intern aufgerufen, kann
+                       aber in speziellen Situationen auch manuell aufgerufen
+                       werden (siehe oben unter REALISIERUNG)
+             message : es werden Meldungen zu Statusaenderungen verarbeitet
+                       und korrekt ausgegeben. Es wird der Name der auszu-
+                       gebenen Property uebergeben.
+                       Es werden alle notwendigen Ersetzungen per
+                       replace_personal gemacht und geprueft, ob dem Besitzer
+                       oder dem Raum die Meldung ausgegeben werden muss.
+                       Hierueber sollten nur Meldungen ausgegeben werden, die
+                       durch Aenderungen an der Speise im Reset ausgeloest
+                       werden, also im reset selbst und in den make_*-Methoden.
+
+
+STANDARD:
+    Wenn man nichts in seinem Futter ueberschreibt, dann hat es
+    folgendes Standardverhalten.
+    Es muss immer P_FOOD oder P_DRINK explizit groesser 0 gesetzt werden,
+    sonst laesst sich das Lebensmittel nicht konsumieren!
+
+    - Haltbarkeit: 1 Reset (30 + random(30) Minuten)
+    - der Ablauf der Haltbarkeit startet, sobald ein Spieler die Speise nimmt
+    - Wenn die Speise schlecht wird, wird sie zerstoert
+    - Die Speise hat keinen Behaelter
+    - Es gibt nur einen Schluck/Bissen, dann ist die Speise weg
+    - Gewicht: 50 Gramm / Wert: 10 Muenzen
+    - Man heilt weder LP noch KP
+    - Man wuerde ansonsten 5 LP/KP pro Heartbeat heilen
+    - Man kann die Speise nur konsumieren, wenn man sie in der Hand haelt
+    - Wenn man die verdorbene Speise konsumieren koennte, wuerde man nicht
+      heilen sondern vergiftet werden (P_POISON+1)
+
+BEISPIELE:
+    Beispiele zu tragbaren Speisen und Getraenken kann man unter
+    doc/beispiele/food/ nachschauen
+
+SIEHE AUCH:
+    consume, wiz/heilung, 
+
+LETZTE AeNDERUNG:
+    25.09.2010, Caldra
diff --git a/doc/wiz/forscherpunkte b/doc/wiz/forscherpunkte
new file mode 100644
index 0000000..a7f84d1
--- /dev/null
+++ b/doc/wiz/forscherpunkte
@@ -0,0 +1,65 @@
+
+Forscherpunkte
+==============
+
+ FORSCHERPUNKTE:
+    Damit die Spieler beim Erkunden neuer Gebiete auch an Ortskenntnis
+    gewinnen, muessen an bestimmten Stellen Forscherpunkte (FP) vergeben
+    werden. Dazu ist in den meisten Faellen keine Aenderung an den Objekten
+    selbst noetig, die Punkte muessen jedoch von einem Erzmagier in die
+    FP-Liste eingetragen werden.
+
+    DIE FORSCHERPUNKTE MUESSEN EINGETRAGEN WERDEN, BEVOR DAS GEBIET DEN
+    SPIELERN ZUGAENGLICH GEMACHT WIRD!
+
+    Die Testphase ist eine gute Gelegenheit, sich darueber Gedanken zu machen,
+    wo welche FP vergeben werden koennten.
+
+    Fuer das Eintragen der Forscherpunkte ist derzeit Miril zustaendig.
+
+ WAS FUeR FP KANN ICH VERGEBEN?
+    Folgende Typen von Forscherpunkten stehen zur Verfuegung:
+
+     * Details. Darunter fallen auch SpecialDetails.
+     * ReadDetails.
+     * Sounds und Smells.
+     * Kommandos, soweit sie mit AddCmd() angemeldet werden.
+       Kommandos, die mit add_action() angemeldet werden, koennen aus
+       technischen Gruenden nicht beruecksichtigt werden.
+       Kommandos, die als FPs eingetragen sind, geben genau dann den
+       FP, wenn 1 zurueckgegeben wird.
+     * Ausgaenge bei Raeumen. Darunter fallen auch SpecialExits.
+     * Infos bei NPCs. Das Defaultinfo laesst sich allerdings nicht ohne
+       weiteres verwenden.
+     * Getraenke und Speisen in Kneipen.
+     * Besondere Aktionen sind auch moeglich, dazu muss jedoch noch etwas am
+       Code hinzugefuegt werden. Diese Art von Forscherpunkten sollte man nach
+       Moeglichkeit meiden.
+
+    Pro Objekt laesst sich nur ein FP vergeben. Die FP-Dichte sollte etwa bei
+    einem FP pro zehn Raeume liegen.
+
+    In Questgebieten sollten die FP NICHT fuer Details oder Aktionen vergeben
+    werden, die einen direkt in der Quest weiterbringen, sondern eher fuer
+    solche, die zu den entscheidenen Stellen fuehren. Damit werden Spieler,
+    die sich alles genau ansehen, belohnt, wohingegen Komplettloeser, die nur
+    das noetigste eingeben, leer ausgehen.
+
+ WIE SAG ICHS MEINEM ERZMAGIER?
+    Um die FP eintragen zu koennen, brauchen die Erzmagier eine Liste mit den
+    noetigen Informationen. Zu den noetigen Informationen gehoeren:
+
+     * der Dateiname des Objektes
+     * die Art des FP
+     * die Schluesselwoerter, mit denen der FP angesprochen werden soll
+
+    Die Schluesselwoerter sind normalerweise die Schluessel, die bei den
+    jeweiligen AddXXX()-Aufrufen im Objekt angegeben werden.
+
+    Beispiel:
+
+    /players/wargon/workroom: detail wand, waende
+    /players/wargon/mon/errol: info drachen
+
+ LETZTE AeNDERUNG:
+	Thu, 2013-04-04 von Humni
diff --git a/doc/wiz/ftp b/doc/wiz/ftp
new file mode 100644
index 0000000..bca4c5a
--- /dev/null
+++ b/doc/wiz/ftp
@@ -0,0 +1,41 @@
+FTP-Zugang fuer Magier (Zesstra, 12. Dez 2010, 23:17:52):
+Ok, wie in bekanntmachungen geschrieben, waren unsere (und die anderer Muds)
+Versuche bislang erfolglos, das mod_mud-Modul fuer den proftpd wieder ans
+Laufen zu bringen und ich habe als Zwischenloesung zumindest erstmal was
+anderes gebaut.
+
+Allerdings kann die aktuelle Loesung nicht 'live' beim Dateizugriff das Mud
+fragen, ob der User das auch darf. Daher sind alle Magier leider erstmal auf
+ihr Homeverzeichnis beschraenkt - dort duerfen sie natuerlich alles schreiben
+und lesen. Von dort/dorthin muss man dann im Mud mit cp/mv arbeiten.
+
+Wer seinen FTP-Zugang aktivieren will, muss - bis ich das in die Magiershell
+eingebaut habe - folgende zwei Schritte durchfuehren:
+1) xeval master()->update_ftp_access(getuid(this_interactive()), 1)
+   (Deaktivieren mit update_ftp_access(getuid(this_interactive()), 0)
+2) mit passwd ein neues PW setzen
+3) bis zur naechsten vollen Stunde warten
+
+Schritt 2) ist leider zwingend noetig, da wir das PW nicht im Klartext
+speichern und pure-ftpd unsere verschluesselten/gehashten Passwoerter nicht
+versteht. Deswegen muessen wir fuer FTP das PW anders speichern, was wir nur
+beim Neusetzen eines PWs koennen.
+
+Ich moechte euch noch um eins bitten: Wenn ihr was per FTP hin- und
+herschiebt, was dann weiter (z.B. nach /d) verschoben wird (oder von dort ihr
+euer Homeverzeichnis): loescht bitte den Kram aus eurem /players/<magier>
+wieder, denn a) geht das alles sonst ueberfluessig ins Backup und b) wird die
+Uebersicht deutlich schlechter, wenn man x Kopien des gleichen Krams im Mud
+verteilt hat.
+
+BTW: Dieser FTP-Zugang wird deaktiviert, falls sich ein Magier laenger als 2
+Wochen nicht im Mud einloggt, dann muesst ihr die Prozedur da oben
+wiederholen.
+
+Sorry fuer die Unannehmlichkeiten, aber so ists erstmal besser als gar nix.
+Falls wider Erwarten jemand beim mod_mud aushelfen mag, ist er uebrigens
+herzlich willkommen.
+
+Zesstra
+Stand: Februar 2011
+
diff --git a/doc/wiz/gift b/doc/wiz/gift
new file mode 100644
index 0000000..a2c4d9e
--- /dev/null
+++ b/doc/wiz/gift
@@ -0,0 +1,132 @@
+Krankheiten, Gifte und Flueche
+==============================
+
+     Einmal abgesehen vom einfachen Setzen von P_POISON im Spieler lassen 

+     sich Gifte und Krankheiten auch als Objekte ausprogrammieren, die dem 

+     Spieler in mehr oder weniger regelmaessigen Abstaenden Lebenspunkte 

+     abziehen. Auch Flueche koennen nicht nur als P_CURSED in Waffen und 

+     Ruestungen, sondern auch als Objekte vorliegen, und dem Spieler das 

+     Leben schwermachen
+
+     Um ein Objekt als Gift zu kennzeichnen, wird die Klasse CL_POISON 

+     gesetzt, fuer eine Krankheit ist CL_DISEASE und fuer einen Fluch 

+     CL_CURSE zu setzen (mit AddClass, siehe dort). Zusaetzlich wird die 

+     Schwere der Erkrankung bzw. Vergiftung in der Property P_LEVEL 

+     abgelegt, wobei P_LEVEL einen Wert zwischen 1 und 100 haben sollte. 

+     Mitglieder der Klerikergilde und andere Heiler koennen dann je nach 

+     P_LEVEL den betroffenen Spieler mehr oder weniger gut heilen. (Kleriker 

+     koennen CL_POISON-Vergiftungen heilen, einige Heiler jedoch nicht.)
+
+     Eine eindeutige Unterscheidung zwischen Giften, Krankheiten und 

+     Fluechen zu treffen, ist schwer, denn die Grenzen verschwimmen. 

+     Trotzdem hier eine grobe Klassifizierung:
+
+     Gifte : bringt der Spieler sich meist selbst bei (in dem er z.B.
+             einen giftigen Pilz isst). Oft auch sind die Stellen, wo
+             ein Spieler sich vergiften kann, irgendwie gekennzeichnet,
+             so dass eine Vergiftung umgangen werden kann.
+
+             Bei Giften wird durch das Heilen der Level des Giftobjekts
+             abhaengig vom Erfolg gesenkt. Ist der Level <= 0, wird das
+             Objekt vom Kleriker-Spellbook entfernt. Heiler sollten das
+             aehnlich machen. Logisch waere es daher, den Schaden, den das
+             Objekt macht, vom momentanen Level abhaengig zu machen.
+
+     Krankheit: werden dem Spieler durch Fremdeinwirkung beigebracht, auch
+             durch Ansteckung bei einem anderen Spieler oder NPC.
+             Bei ansteckenden Krankheiten ist auf die Ansteckrate zu achten
+             und darauf, dass die Krankheit mit der Zeit auch wieder
+             ausstirbt. Also entweder bei jeder Generation der Krankheit
+             das Ansteckungsrisiko senken oder einmal infizierte Spieler
+             immunisieren. Es sollten sich 2 idelnde Spieler nicht immer
+             wieder gegenseitig bis in alle ewig anstecken koennen. Auch
+             ist darauf zu achten, dass Netztote nicht angesteckt werden
+             koennen bzw. Netztote niemanden anstecken, da sich sonst die
+             Krankheit im Netztotenraum verbreiten kann.
+
+             Das Heilen geschieht im Kleriker-Spellbook wie bei Gift.
+
+     Flueche: werden wie Krankheiten durch Fremdeinwirkung beigebracht
+             (der Spieler wird halt verflucht). Ausserdem ist die Wirkung 

+             von Fluechen oft nicht auf einfaches Abziehen von Lebenspunkten 

+             beschraenkt, sondern der Spieler kann z.B. nicht mehr richtig 

+             sprechen (Sprachfluch ueber P_PERM_STRING), ist in der Bewegung 

+             eingeschraenkt oder greift wahllos NPCs an.
+
+             Hier ist das Entfluchen durch einen Kleriker anders. Findet
+             das Spellbook ein CL_CURSE-Objekt im Inv des Spielers, wird
+             gegen das Level des Objekt gewuerfelt. Bei Erfolg wird das
+             Objekt entfernt, bei Misserfolg passiert nichts!
+
+             Als Anhaltspunkte fuer den Level:
+             - < Level 10 sind einfach zu entfluche
+             - 10 - 20 sind fuer kleine Kleriker schon enorm schwierig
+               fuer max. Kleriker gut zu entfluchen.
+             - ueber 20 gelingt es auch einem max. Kleriker nicht immer
+               beim ersten mal.
+             - ab 30 muss der max. Kleriker schon mal tanken gehen
+             - Ueber Level 40 liegt die Chance schon im Promillebereich!!!
+             - Level 100 laesst sich ueberhaupt nicht mehr entfluchen.
+
+             Will man dem Spieler also eine reelle (und nicht nur 

+             mathematische) Chance lassen, sollte der Fluchlevel unter 40 

+             bleiben.
+
+     Das Schadensobjekt selbst ist unsichtbar, meist autoload und loest die 

+     Schadensfunktion ueber Callouts aus.
+
+ BEISPIEL:
+     Hier ein Beispiel fuer einen Giftpilz (gefunden bei Silvana, in
+     /d/dschungel/silvana/weg/obj/pilz.c):
+     ----------------------------------------------------------------------
+     #pragma strong_types
+     #include "../pfad.h"
+
+     inherit "/std/thing";
+
+     void create() {
+       if(!clonep(TO)) {
+           set_next_reset(-1);
+           return;
+       }
+       ::create();
+
+       SetProp(P_SHORT,0);
+       SetProp(P_INVIS,1);
+       SetProp(P_LONG,0);
+       SetProp(P_NODROP,1);
+       SetProp(P_NEVERDROP,1);
+       SetProp(P_AUTOLOADOBJ,1);
+       SetProp(P_WEIGHT,0);
+       SetProp(P_NAME,"Pilzvergiftung");
+       SetProp(P_KILL_NAME,"Eine Pilzvergiftung");
+       SetProp(P_GENDER,FEMALE);
+       SetProp(P_ARTICLE,1);
+       SetProp(P_LEVEL,10);
+       call_out("next_step",2);
+       AddClass(CL_POISON);
+     }
+
+     void next_step();
+
+     void next_step() {
+       object pl;
+       if(!(pl=TOE) || !query_once_interactive(pl) ||
+          pl->QueryProp(P_GHOST)){
+         remove();
+         return ;
+       }
+       call_out(#'next_step ,5);
+       if(!interactive(pl)) return;
+       tell_object(pl,
+       		   "Dein Bauch schmerzt. Du windest Dich in Kraempfen.\n");
+       if(ENV(pl)) tell_room(ENV(pl),
+        pl->Name()+" windet sich vor Schmerzen am Boden.\n",({ pl }));
+       pl->do_damage(QueryProp(P_LEVEL)*2 + random(10),TO);
+     }
+
+ SIEHE AUCH:
+    P_POISON, P_CURSED, P_PERM_STRING
+
+ LETZTE AeNDERUNG:
+   11.08.2007, Zesstra
diff --git a/doc/wiz/gilden-doku b/doc/wiz/gilden-doku
new file mode 100644
index 0000000..08e3aa7
--- /dev/null
+++ b/doc/wiz/gilden-doku
@@ -0,0 +1,496 @@
+Gilden 
+*******
+
+Gilden sind dazu da, Spielern besondere Faehigkeiten zu verleihen. Dies
+koennen Zaubersprueche (Spells) sein, es kann aber auch andere Faehigkeiten
+(Skills) geben. Als Spell gilt jede Faehigkeit, die ein Spieler mit einem
+Befehl direkt aufrufen muss. Damit auch andere Gilden die gleichen
+Zaubersprueche verwenden koennen, muessen die Sprueche in eigenen
+Spellbooks abgelegt werden. Eine Gilde kann Sprueche aus beliebigen
+Spellbooks verwenden und diese ggf. leicht modifizieren. 
+
+Gildenobjekt 
+=============
+
+Eine Gilde muss ein Objekt haben, bei dem der Spieler der Gilde beitreten
+bzw. austreten und die Faehigkeiten der Gilde erwerben kann. Gewoehnlich
+ist dies ein Raum, der "/std/gilden_room" inheritet, es kann aber auch ein
+anderes Objekt sein, fuer diesen Fall ist "/std/gilden_ob" vorgesehen. 
+
+Die Beitrittsbedingungen fuer die Gilde werden in Form eines 
+Restriction-Mappings in der Property P_GILDEN_RESTRICTIONS
+abgelegt. 
+
+Das Spellbook, in dem die Spells der Gilde stehen, muss in
+P_GUILD_DEFAULT_SPELLBOOK genannt sein. Es wird automatisch
+"/spellbooks/" vorne an den Namen angefuegt. Die Spells, die aus diesem
+Spellbook verwendet werden sollen, koennen dann einfach mit
+AddSpell(name) ausgewaehlt werden. Wenn ein Spruch modifiziert werden
+soll so kann ein Mapping mit zusaetzlichen Informationen als zweites
+Argument angegeben werden. In diesem kann man dann auch ein anderes
+Spellbook als das Default-Spellbook mit ([SI_SPELLBOOK:name])
+angeben. In P_GLOBAL_SKILLPROPS kann ein Mapping angegeben
+werden, das alle Spells und Skills modifiziert. P_GLOBAL_SKILLPROPS
+und P_GILDEN_DEFAULT_SPELLBOOK muessen uebrigens gesetzt
+werden bevor mit AddSpell/Skill Spells oder Skills hinzugefuegt werden. 
+
+Fuer andere Faehigkeiten sind AddSkill und LearnSkill vorgesehen.
+LearnSkill wird im Gegensatz zu LearnSpell jedoch nicht automatisch vom
+/std/gilden_room mit "lerne" aufgerufen, weil i.A. diese Faehigkeiten auf
+andere Art erworben werden, z.B. beim Gildeneintritt oder durch
+Trainingsstunden. Mit LearnSkill kann man nur solche Faehigkeiten
+erwerben, die mit AddSkill angefuegt wurden. 
+
+Skills werden ueblicherweise durch den Aufruf von UseSkill im Spieler
+verwendet. Wenn der Spieler in einer Gilde ist und eine Funktion unter
+SI_SKILLFUNC zu finden ist, so wird diese im Gildenobjekt aufgerufen,
+sonst wird versucht StdSkill_Name im Spieler aufzurufen. Wenn auch das
+fehlschlaegt wird nur der Wert unter SI_ABILITY zurueckgegeben. 
+
+Es stehen folgende Funktionen zur Benutzung zur Verfuegung: 
+
+ o QuerySpell(name)
+   Liefert die Informationen zu diesem Spell 
+ o QuerySkill(name)
+   Liefert die Informationen zu dieser Faehigkeit 
+ o AddSpell(name,info)
+   Spell wird hinzugefuegt 
+ o AddSkill(name,info)
+   Faehigkeit wird zugefuegt 
+ o LearnSpell(name)
+   Spieler lernt den angegebenen Spell, falls moeglich. Liste der Spells
+   wird ausgegeben, falls keiner angegeben ist. 
+ o LearnSkill(name)
+   Spieler erwirbt diese Faehigkeit, falls moeglich. Liste aller
+   Faehigkeiten wird ausgegeben, falls keine angegeben ist. 
+ o GildenName()
+   Liefert den Namen dieser Gilde. 
+ o InitialSkillAbility(info,spieler)
+   Rechnet den Anfangswert fuer SI_SKILLABILITY aus. 
+ o SkillListe(x)
+   Es wird angezeigt, welche Spells/Skills der Spieler lernen kann.
+   Dabei bedeutet x: 
+    o 1: Nur Spells anzeigen 
+    o 2: Nur Skills anzeigen 
+    o 3: Beides anzeigen 
+
+Von diesen Funktionen stehen in /std/gilden_room automatisch
+bei_oder_austreten und LearnSpell dem Spieler zur Verfuegung. 
+
+Spellbook 
+==========
+
+Spellbooks stellen die Spells zur Verfuegung, die Spieler oder Monster
+verwenden koennen. Alle Spellbooks sollten /std/spellbook inheriten. In der
+einfachsten Form kann ein Spell wie folgt hinzugefuegt werden: 
+AddSpell(verb,kosten,level)
+Dabei ist "verb" sowohl der Name des Verbs, mit dem der Spruch
+aufgerufen werden soll, wie auch der Name der Funktion, die dabei
+aufgerufen wird. "kosten" sind die Magiepunkte, die fuer den Spruch
+benoetigt werden und "level" ist der Spielerlevel, der noetig ist, um diesen
+Spruch zu lernen. 
+
+In der flexibleren Form werden Spells mit 
+AddSpell(verb,kosten,info)
+hinzugefuegt. Dabei ist "info" ein Mapping, in dem alle anderen 
+Spell-Informationen stehen. Dabei kann z.B. eine andere Funktion als das
+Verb als Eintrag 
+SI_SKILLFUNC:name
+angegeben werden. Wenn zum Lernen eine bestimmte Stufe erforderlich ist
+so muss 
+SI_SKILLRESTR_LEARN:([P_LEVEL:level])
+eingetragen sein. Es sollten alle Werte, von denen ein Spell abhaengt, in dem
+Mapping eingetragen sein. Dadurch haben Gilden die Moeglichkeit, Spells
+mit Offsets und Faktoren zu modifizieren. 
+
+In P_GLOBAL_SKILLPROPS kann ein Mapping stehen, dass bei jedem
+Spell zum Info addiert wird. Dieses sollte gesetzt werden, bevor die Spells
+mit AddSpell hinzugefuegt werden. 
+
+Die Benutzung von Spells laeuft wie folgt ab: 
+
+ o Zuerst wird ueberprueft, ob der Spieler den Spruch verwenden darf.
+   Dazu wird die Funktion CanTrySpell aufgerufen. Diese prueft
+   normalerweise, ob der Spieler kein Geist ist und ob er die
+   Einschraenkungen erfuellt, die als SI_SKILLRESTR_USE
+   angegeben sind. 
+ o Als naechstes wird geprueft, ob der Spieler noch genug Magiepunkte
+   hat. Diese stehen im Mapping unter SI_SPELLCOST. 
+ o Als letztes wird geprueft, ob der Spieler noch erschoepft ist von
+   seinem letzten Spruch. 
+ o Nun wird die eigentliche Funktion des Spells aufgerufen, wenn es die
+   Umgebung zulaesst. Die Funktion muss einen positiven Wert
+   zurueckgeben, wenn der Spruch gelungen ist, und einen negativen,
+   wenn er misslungen ist. Falls der Spruch aus irgend einem Grund
+   nicht anwendbar ist soll 0 zurueckgegeben werden. 
+ o Bei Erfolg oder Misserfolg werden die Magiepunkte abgezogen und
+   der Spieler ist fuer die naechste Zeit erschoepft. Die Zeitspanne ist
+   im Mapping unter SI_SPELLFATIGUE zu finden. 
+ o Bei Erfolg wird die Funktion "Erfolg" aufgerufen, bei Misserfolg
+   die Funktion "Misserfolg" 
+ o Die Funktion "Misserfolg" ruft normalerweise die Funktion "Learn"
+   auf, damit der Spieler aus seinen Fehlern lernt. 
+
+Die eigentliche Spellfunktion sollte, falls der Spell anwendbar ist, mit
+SpellSuccess pruefen, ob er erfolgreich ist oder nicht. Dabei gelten Werte
+groesser Null als Erfolg. In der Spellfunktion sollten, falls moeglich, 
+SkillAttribute des Spielers sowie Faktoren und Offsets beruecksichtigt
+werden. Fuer beides stehen einfach zu handhabende Funktionen zur
+Verfuegung. Dies ist zwar etwas mehr Arbeit, dafuer geschehen dann Dinge
+wie Interaktionen zwischen den Spells fast automatisch. 
+
+Folgende Funktionen stellt das Standard-Spellbook zur Verfuegung: 
+
+ o QuerySpell(name)
+   Liefert Informations-Mapping zu diesem Spell. 
+ o AddSpell(name,kosten,info)
+   Fuegt Spell mit angegebenen Kosten und dem
+   Informations-Mapping ins Spellbook ein. 
+ o TryAttackSpell(opfer,schaden,typen,is_spell,caster,info)
+   Versucht den Angriffs-Spruch auf den Gegner anzuwenden. Die
+   mittleren 4 Werte sind die, die auch bei Defend uebergeben werden.
+   Dabei wird die Abwehrfaehigkeit des Gegners gegen Magie und das
+   Skill-Attribut SA_DAMAGE automatisch beruecksichtigt. 
+ o TryDefaultAttackSpell(opfer,caster,info,is_spell)
+   Wie TryAttackSpell, nur werden Schaden und Schadenstypen
+   automatisch aus dem Informations-Mapping entnommen. Bei beiden
+   Funktionen sollte als is_spell uebrigens ein String stehen, z.B.
+   "Feuerball", damit es leichter moeglich ist, Monster zu schreiben, die
+   auf diese reagieren. 
+ o SpellSuccess(caster,info)
+   Ermittelt, ob der Spell funktioniert oder fehlschlaegt. Dabei wird
+   auch eine evtl. vorhandene Spellcasting-Faehigkeit (SK_CASTING)
+   beruecksichtigt. Ohne Spellcasting-Faehigkeit liegt das Ergebnis
+   zwischen -MAX_ABILITY und +MAX_ABILITY, mit dieser
+   Faehigkeit koennen die Werte zwischen -2*MAX_ABILITY und
+   +2*MAX_ABILITY liegen. Werte kleiner oder gleich Null sollen
+   als Fehlschlag interpretiert werden. 
+   Wer will, kann Werte ueber +MAX_ABILITY als besonders gut
+   gelungene Spells interpretieren und bei Werten unter
+   -MAX_ABILITY unangenehme Wirkungen ausloesen, z.B. kann
+   sich der Spell dann gegen den Spieler richten... 
+   Wenn ein Spieler die Spellcasting-Faehigkeit hat und ein Spruch
+   besonders gut gelingt, so freut er sich und verbessert diese
+   Faehigkeit. 
+ o CanTrySpell(caster,info)
+   Ermittelt, ob der Spieler den Spruch anwenden darf. Normalerweise
+   ist diese der Fall, wenn er kein Geist ist und die Bedingungen
+   erfuellt, die unter SI_SKILLRESTR_USE im Mapping eingetragen
+   sind. 
+ o Learn(caster,spell,info)
+   Diese Funktion wird normalerweise bei Misserfolg aufgerufen,
+   damit der Spieler aus seinen Fehlern lernt. Dabei wird
+   ueblicherweise die Intelligenz des Spielers beruecksichtigt. Fuer je 2
+   Stufen A_INT bekommt der Spieler SI_SKILLLEARN hinzu. 
+
+   Moechte man ein anderes Attribut zum lernen verwenden kann man dies
+   in Form eines Mappings in SI_LEARN_ATTRIBUTE tun.
+
+   SI_LEARN_ATTRIBUTE:([A_STR:1]) macht das Lernen rein staerkeabhaengig,
+   SI_LEARN_ATTRIBUTE:([A_STR:1,A_INT:2]) bildet den gewichteten Mittelwert
+   von STR und zweifacher INT.  
+
+ o Erfolg(caster,spell,info)
+   Diese Funktion wird bei Erfolg aufgerufen. 
+ o Misserfolg (caster,spell,info)
+   Diese Funktion wird bei Misserfolg aufgerufen. 
+ o FindVictim(wen,spieler,msg)
+   "wen" wird in der Umgebung des Spielers gesucht. Falls diese
+   Variable Null ist wird zufaellig ein Feind ausgewaehlt. Falls
+   niemand gefunden wird, so wird "msg" ausgegeben. 
+ o FindLivingVictim(wen,spieler,msg)
+   Wie FindVictim, nur wird zusaetzlich ueberprueft, ob es ein
+   Lebewesen ist. 
+ o FindEnemyVictim(wen,spieler,msg)
+   Wie FindLivingVictim, nur der Spieler selbst wird ausgenommen
+   und wenn es vorher noch kein Feind war, so wird Kill aufgerufen
+   damit es hinterher garantiert einer ist. 
+ o FindGroup(spieler,wen)
+   Bei Spielern findet die Funktion alle Monster im Raum, wenn "wen"
+   negativ ist, alle Spieler wenn "wen" positiv ist und alle Lebewesen
+   wenn "wen" Null ist. Bei Monstern ist es genau umgekehrt. Es sollte
+   jedoch FindGroupP mit 100% verwendet werden. 
+ o FindGroupN(spieler,wen,n)
+   Wie FindGroup, jedoch maximal n Personen. Das Skill-Attribut
+   SA_EXTENSION wird automatisch beruecksichtigt. 
+ o FindGroupP(spieler,wen,prozent)
+   Wie FindGroup, jedoch jede Person mit der angegebenen
+   Wahrscheinlichkeit. Das Skill-Attribut SA_EXTENSION wird
+   automatisch beruecksichtigt. 
+
+Neue Funktionen im Living 
+==========================
+
+ o QuerySkillAttribute(name)
+   Hiermit kann das Skill-Attribut mit dem angegebenen Namen
+   abgefragt werden. 
+ o SetSkillAttribute(caster,name,wert,dauer,func)
+   Hiermit kann das angegebene Skill-Attribut vom caster fuer die
+   angegebene Dauer auf einen Wert gesetzt werden. Es kann eine
+   Funktion angegeben werden, die den Wert statt dessen liefern soll. 
+ o QuerySkill(name)
+   Dies liefert die spielerspezifischen Skill-Informationen. 
+ o QuerySkillAbility(name)
+   Dies liefert von den Skill-Informationen nur SI_ABILITY. 
+ o ModifySkill(name,info,diff)
+   Modifiziert die Skill-Informationen. Wenn "info" ein Mapping ist,
+   so wird es zu dem alten Mapping "addiert" (also die angegebenen
+   Werte geaendert), wenn nur ein Wert angegeben ist, wird
+   angenommen dass es sich dabei um SI_ABILITY handelt. 
+ o LearnSkill(name,add,diff)
+   Addiert den angegebenen Wert zu SI_ABILITY. Dabei ist "diff" der
+   Schwierigkeitsgrad von diesem Spell/Skill. Durch den
+   Schwierigkeitsgrad SI_ABILITY abhaengig vom Level begrenzt. 
+ o UseSpell(arg,spell)
+   Das Lebewesen benutzt den Spell mit den angegebenen Argumenten.
+   Wenn kein Spell angegeben ist, so wird query_verb() verwendet. 
+ o UseSkill(skill,arg)
+   Das Lebewesen benutzt die Faehigkeit. 
+
+Neue Properties/Funktionen in Living/Combat 
+============================================
+
+Einige Sprueche erfordern es, das Verhalten bei Attack und Defend ziemlich
+weitreichend zu aendern. Dafuer wurden folgende Properties und
+Funktionen eingebaut: 
+
+ o P_TMP_ATTACK_HOOK
+   Hier kann ein Array der Form ({Endzeitpunkt,Objekt,Funktion})
+   stehen. Solange der Endzeitpunkt noch nicht ueberschritten wurde
+   und das angegebene Objekt existiert, wird anstelle von Attack die
+   Funktion in dem Objekt aufgerufen. Wenn die Funktion 0 liefert
+   wird der Rest von Attack nicht mehr ausgefuehrt. 
+ o P_TMP_DEFEND_HOOK
+   Wie P_ATTACK_HOOK, nur mit Defend. Damit sind z.B.
+   Sprueche moeglich, die fuer kurze Zeit eine magische Schutzhuelle
+   erschaffen. Wenn die Funktion 0 liefert wird der Rest von Defend
+   nicht mehr ausgefuehrt. Wenn es ein Array der Form
+   ({damage,dt,is_spell}) ergibt wird es wie bei DefendOther
+   interpretiert. 
+ o P_DEFENDERS
+   Liste von Lebewesen, die mit InformDefend(enemy) informiert
+   werden sollen, sobald ein neuer Feind hinzukommt. Bei einem
+   zufaellig ausgewaehltem Lebewesen aus dieser Liste wird ausserdem
+   DefendOther mit den Argumenten von Defend aufgerufen. 
+ o AddDefender(friend)
+   Fuegt Lebewesen in P_DEFENDERS ein, wenn es noch nicht in der
+   Liste ist. 
+ o InformDefend(enemy)
+   Siehe oben. 
+ o DefendOther(dam,dt,is_spell,enemy)
+   Mit dieser Funktion kann man Lebewesen erschaffen, die Schaden
+   von anderen abwenden oder modifizieren. Wenn diese Funktion ein
+   Array ({dam,dt,is_spell}) zurueckgibt so werden bei dem zu
+   verteidigenden Lebewesen diese Werte genommen anstelle der alten.
+   Man kann also z.B. ein Monster erschaffen, das ein
+   feuerempfindliches anderes Monster verteidigt, indem es z.B.
+   Feuerbaelle in Eishagel verwandelt. 
+
+Standard-Skills 
+================
+
+Folgende Faehigkeiten werden schon beruecksichtigt und sind auch
+vordefiniert. Wenn sie unveraendert uebernommen werden sollen muss nur
+SI_ABILITY gesetzt werden. 
+
+ o SK_SWORDFIGHTING
+   Schwertkampf. Bis zu 33+A_STR+A_DEX Aufschlag bei
+   Schwertern, wenn jemand diese Faehigkeit zu 100% hat. 
+ o SK_WEAPONLESS
+   Kampf mit blossen Haenden. Bis zu 100+A_STR+3*A_DEX
+   Aufschlag. 
+ o SK_TWOHANDED
+   Kampf mit zweihaendigen Waffen. Bis zu 33+A_STR Aufschlag. 
+ o SK_NIGHTVISION
+   Wer diese Faehigkeit zu 100% hat braucht 20 Sekunden pro
+   fehlendem Lichtlevel um sich an die Dunkelheit zu gewoehnen. 
+ o SK_BOOZE
+   Mit 100% dieser Faehigkeit wird bei jedem alkoholischen Getraenk
+   80% vom Alkoholgehalt abgezogen. 
+
+Folgende Faehigkeiten werden beruecksichtigt, sind aber nicht vordefiniert: 
+
+ o SK_MAGIC_ATTACK
+   Wenn diese Faehigkeit vorhanden ist, wird die Funktion unter
+   SI_SKILLFUNC im Gildenobjekt aufgerufen, falls der Spieler sonst
+   mit blossen Haenden angreifen wuerde. Wenn dabei ein Mapping
+   zurueckgegeben wird, so werden die Werte von
+   SI_SKILLDAMAGE, SI_SKILLDAMAGE_TYPE und
+   SI_SKILLDAMAGE_MSG genommen anstelle der Werte in
+   P_HANDS. 
+ o SK_MAGIC_DEFENSE
+   Wenn hier unter SI_SKILLFUNC eine Funktion eingetragen ist, so
+   wird sie bei Defend im Gildenobjekt aufgerufen und bekommt im
+   Informations-Mapping SI_SKILLDAMAGE,
+   SI_SKILLDAMAGE_TYPE und SI_SPELL uebergeben. Wenn sie
+   ein Mapping zurueckgibt werden hieraus SI_SKILLDAMAGE und
+   SI_SKILLDAMAGE_TYPE entnommen und ersetzen die alten
+   Werte von "dam" und "dam_type". 
+ o FIGHT(Waffentyp)
+   Falls diese Faehigkeit vorhanden ist wird der entsprechenden
+   Funktion in SI_SKILLDAMAGE der bisherige Schaden uebergeben.
+   Falls sie ein Mapping zurueckliefert wird an dieser Stelle auch der
+   neue Schaden erwartet. 
+ o SK_FIGHT
+   Wie Fight(Waffentyp), nur wird diese Faehigkeit, falls vorhanden,
+   bei jeder Waffe benutzt und kann auch zusaetzlich andere Werte fuer
+   SI_SKILLDAMAGE_TYPE ergeben. Waffe und Waffentyp werden
+   uebrigens in SI_WEAPON und SI_WEAPON_TYPE uebergeben. 
+ o SK_CASTING
+   Spellcasting. Die Wahrscheinlichkeit, dass der Spell gelingt, steigt
+   bei 100% dieser Faehigkeit auf das Doppelte. Nur mit dieser
+   Faehigkeit ist es moeglich, ueber die Maximalgrenzen zu kommen,
+   so dass dann auch Spells besonders gut gelingen koennen. 
+
+Temporaere Property-Aenderungen 
+================================
+
+Oft muessen Spells irgendwo Properties fuer kurze Zeit veraendern, wie
+z.B. P_LIGHT oder P_NOMAGIC in Raeumen. Fuer diesen Zweck kann
+man in /obj/tmp_prop_master die Funktion SetTmpProp aufrufen. Diese
+Funktion erwartet das Objekt, in dem die Property zu setzen ist, den Namen
+der Property, den zeitweiligen Wert und den Zeitpunkt, bis zu dem diese
+Aenderung gelten soll. 
+
+Skill Informationen 
+++++++++++++++++++++
+
+In den Informationsmappings zu den Spells/Skills sollten alle (zusaetzlich)
+noetigen Informationen stehen, denn nur wenn z.B. ein Feuerball in einem
+Spellbook als Schaden 300 eingetragen hat und diesen Wert dem Mapping
+entnimmt, kann eine andere Gilde diesen Spruch recyclen und mit Schaden
+400 anbieten, natuerlich sollte er dann auch in der Gilde mehr kosten. 
+
+SIEHE AUCH: skill_info_liste
+
+Faktoren und Offsets 
+---------------------
+
+Man kann in dem Informations-Mapping zu jedem numerischen Wert
+"Name" noch zwei zusaetzliche Werte FACTOR("Name") und
+OFFSET("Name") eintragen und diese Werte automatisch zur eigentlichen
+Wertbestimmung beruecksichtigen. Mit folgenden Funktionen sollte man
+im Spellbook dem Mapping Werte entnehmen: 
+
+ o GetValue(name,map,spieler) 
+ o GetOffset(name,map,spieler)
+   OFFSET(name). 
+ o GetFactor(name,map,spieler)
+   Ergibt FACTOR(name), falls ungleich Null, sonst 100. 
+ o GetFValue(name,map,spieler)
+   Ergibt (Wert*Faktor)/100. 
+ o GetValueO(name,map,spieler)
+   Ergibt Wert+Offset. 
+ o GetFValueO(name,map,spieler)
+   Ergibt (Wert*Faktor)/100+Offset. 
+
+Nach Moeglichkeit sollte man davon im Spellbook GetFValueO benutzen,
+wenn es angebracht ist. Auf jeden Fall sollten von den drei Werten
+moeglicht viele auf eine angemessene Weise beruecksichtigt werden, denn
+dadurch bekommt das Gildenobjekt feinere Kontrollmoeglichkeiten, wenn
+ein Spruch modifiziert werden soll. Es ist dann fuer die Gilde aeusserst
+einfach festzulegen, dass z.B. Zwerge bei allen Angriffsspruechen 20%
+mehr Schaden verursachen und beim Feuerball Elfen einen hoeheren
+garantierten Wert hinzubekommen. 
+
+Funktionen 
+-----------
+
+Wenn ein Spellbook eine der oben angesprochenen Funktionen benutz, um
+einen numerischen Wert zu ermitteln und anstelle des Wertes steht etwas,
+das als Funktion interprtiert werden kann, so wird diese Funktion
+ausgewertet und das Ergebnis als Wert genommen. Als Funktion
+interpretiert werden kann: 
+
+ o Eine Closure 
+ o Ein Array ({objekt,funktionsname}) oder ({objektname,funktionsname}) 
+ o Ein Funktionsname. Hierbei sollte man sich jedoch darueber im
+   klaren sein, in welchem Objekt versucht wird die Funktion
+   aufzurufen. Ueblicherweise geschieht dies im Spellbook, jedoch
+   werden SI_DIFFICULTY, SI_SKILLLEARN und SI_SPELLCOST
+   auch beim Lernen benoetigt und dies geschieht vom Gildenobjekt
+   aus. Wenn bei diesen 3 Eintraegen eine Funktion den Wert liefern
+   soll, so muss sie in eine der drei anderen Formen eingetragen werden,
+   damit das richtige Objekt ermittelt werden kann. 
+
+SIEHE AUCH: execute_anything
+   
+Fuer nicht-numerische Werte kann man GetData verwenden. Dabei werden
+jedoch nur closures automatisch ausgewertet. 
+
+Skill Attribute 
+++++++++++++++++
+
+Skill-Attribute sind Attribute, die alle anderen Skills beeinflussen koennen.
+Normalerweise sind alle Skill-Attribute 100%, sie koennen jedoch fuer
+kurze Zeit auf andere Werte zwischen 10% und 1000% gesetzt werden. Bei
+der Abfrage der Attribute werden 3 Werte beruecksichtigt: 
+
+ o Wert, der vom Lebewesen selbst gesetzt wurde. 
+ o Wert, der von einem anderen unter 100% gesetzt wurde. Wenn
+   mehrere andere Lebewesen den Wert unter 100% gesetzt haben so
+   gilt die Aenderung von dem mit dem hoechsten Level. Eine solche
+   Aenderung wird ueblicherweise von einem Gegner veranlasst. 
+ o Wert, der von einem anderen ueber 100% gesetzt wurde. Auch hier
+   gilt die Aenderung von dem Lebewesen mit dem hoechsten Level. 
+
+Wenn z.B. ein Spieler seine Geschwindigkeit fuer zwei Minuten auf 200%
+und ein Monster sie fuer eine Minute auf 25% setzt, so ist sie eine Minute
+lang 50% und die naechste Minute 200% bevor sie wieder auf 100% gesetzt
+wird. 
+
+SIEHE AUCH: ModifySkillAttribute
+
+Restriction Mappings 
++++++++++++++++++++++
+
+Mit Restriction Mappings koennen Einschraenkungen auesserst einfach
+angegeben werden. In dem Mapping wird einfach nur angegeben, was durch
+welchen Wert eingeschraenkt werden soll. Wenn z.B. mindestens Level 15
+und Intelligenz 10 verlangt wird, so ist das Mapping
+([P_LEVEL:15,A_INT:10]). Folgende Einschraenkungen koennen verlangt
+werden: 
+
+SIEHE AUCH: check_restrictions
+
+Einschraenkungen werden mit check_restrictions(spieler,mapping)
+ueberprueft. Die Funktion liefert 0 zurueck wenn der Spieler alle
+Einschraenkungen erfuellt und einen String mit der Begruendung, falls eine
+Einschraenkung nicht erfuellt ist. 
+
+Programmierrichtlinien 
+=======================
+
+ o In Spellbooks moeglichst oft Faktoren und Offsets beruecksichtigen. 
+ o Die Skill-Attribute beruecksichtigen, falls moeglich. 
+ o Alles Spells muessen eine Verzoegerungszeit haben, in der kein
+   weiterer Spell anwendbar ist. Hiervon kann es Ausnahmen geben, wenn
+   das Gildenkonzept es anders vorsieht (z.B. bei den Kaempfern) oder
+   sonst reguliert.
+ o Kostenlose Spells sollte es nicht geben. Falls doch, dann nur mit sehr
+   hoher Verzoegerungszeit, sonst lassen die Leute nur ihr Frontend
+   spielen. 
+ o Jeder Skill sollte eine levelabhaengige maximale Faehigkeit haben.
+   D.h., wenn SI_DIFFICULTY gesetzt ist sollte der Wert groesser als
+   -100 sein. 
+ o Spells duerfen nicht Monster beliebig hoher Staerke einfach
+   umhauen. Es sollte nur bis zu einer Maximalstaerke moeglich sein. 
+ o Der Schaden, den ein Spruch bewirkt, darf von der Staerke nicht
+   groesser sein, als der, den eine Waffe mit WC 25*SP bewirken
+   wuerde. Auch hier sollte man ein wenig gesunden Menschenverstand
+   spielen lassen - es kommt auch immer drauf an, ob ein Angriff
+   magisch ist oder physikalisch.
+ o Die Heilung sollte nicht die dafuer noetigen SP ueberschreiten. 
+   Ausnahmen fuer explizite Heilgilden (Klerus) kann es geben.
+
+Auswirkung von SI_DIFFICULTY 
+-----------------------------
+
+Folgende Maximalwerte sind fuer SI_ABILITY bei den angegebenen Leveln
+moeglich, wenn SI_DIFFICULTY auf den Wert in der linken Spalte gesetzt
+ist. 
+
+SIEHE AUCH: LimitAbility oder /std/living/skills::LimitAbility
+
+5. Okt 2011 Gloinson
+ 
diff --git a/doc/wiz/git b/doc/wiz/git
new file mode 100644
index 0000000..7200ff3
--- /dev/null
+++ b/doc/wiz/git
@@ -0,0 +1,23 @@
+Nutzung von Git im MorgenGrauen
+===============================
+
+Was ist Git?
+  Git ist eine Software zur (verteilten) Versionsverwaltung von Dateien.
+  (http://git-scm.com/, http://de.wikipedia.org/wiki/Git)
+  Fuer Windows gibt es ein Paket, welches auch die Integration in den Explorer
+  anbietet:
+  https://code.google.com/p/gitextensions/
+
+
+SIEHE AUCH
+  git-repositories: Repository-Verwaltung im Mud
+  git-howto: Wie git benutzt wird
+  git-workflow: Ein simples Beispiel eines Arbeitsflusses mit Git
+  git-kooperation: Erweiterung fuer Fortgeschrittene zu git-workflow
+  git-sync: Wie die Synchronisierung zw. git-Repos und Mudlib ablaeuft
+  git-faq: haeufig gestellte Fragen/Probleme
+  git-links: Verweise ins WWW
+
+LETZTE AeNDERUNG:
+  25.03.2011, Zesstra
+
diff --git a/doc/wiz/git-exclude b/doc/wiz/git-exclude
new file mode 100644
index 0000000..439b5db
--- /dev/null
+++ b/doc/wiz/git-exclude
@@ -0,0 +1,27 @@
+Beim Import von Verzeichnissen aus dem Mud in ein git Repository und bei der
+Synchronisierung zwischen Repositories und Mudlib werden die folgenden
+Verzeichnisse und Dateien komplett ignoriert.
+
+# fuer div. SCMs benutzte Verzeichnisse
+- .svn/
+- .git/
+- .gitignore
+- CVS/
+# Savefiles
+- *.o
+# logs and rep files
+- *.log
+- log/
+- *.rep
+- *.err
+# backups of editors
+- *~
+- *.swp
+# this should als never be imported - marks a directory to be imported.
+- git-mud-import
+# keine gepackten Archive
+- *.gz
+- *.bz2
+- *.zip
+- *.tar
+
diff --git a/doc/wiz/git-faq b/doc/wiz/git-faq
new file mode 100644
index 0000000..7ed4826
--- /dev/null
+++ b/doc/wiz/git-faq
@@ -0,0 +1,83 @@
+Haeufig gestellte Fragen zum Thema Git im Morgengrauen
+======================================================
+
+* Was muss ich machen, damit mein Git-Repo automatisch mit dem MG
+* synchronisiert wird?
+  Eine Synchronisation findet automatisch statt, wenn man einen Import eines
+  Verzeichnisses aus dem Mud durchfuehrt.
+  Macht man dies nicht, sondern erstellt sich unabhaengig vom Mud das Repo,
+  muss man sich an einen Erzmagier mit Shellzugang wenden.
+
+* Aufnahme als Regionsmitarbeiter/Regionsmagier/Weiser/Erzmagier/Gott
+  Dies ist zurzeit nur durch einen EM moeglich.
+
+* Wie benutze ich Git unter Windows?
+  GitHub hat eine Anleitung fuer msysgit, welche im wesentlichen auch fuers MG
+  brauchbar ist:
+  http://help.github.com/win-set-up-git/
+  Eine weitere Moeglichkeit ist hier angeben:
+  http://rogerdudler.github.io/git-guide/
+  Einige in Frage kommende Git-Pakete sind hier kurz vorgestellt:
+  http://www.makeuseof.com/tag/5-windows-git-clients-git-job/
+  Eine Anleitung fuer die Nutzung von Putty als SSH-Client unter Windows
+  findet sich in contrib/putty.mkd auf https://github.com/sitaramc/gitolite/
+
+* Wie kann ich mir die Geschichte meines Repos graphisch anzeigen lassen?
+  Da gibt es verschiedene Loesungen, vor allem auch abhaengig vom
+  Betriebssystem. Auf allen geht vermutlich 'gitk' und 'git gui'.
+  Auf MacOS gibt es auch 'GitX'.
+
+* Kann man Aenderungen/Diffs/ farbig markiert anzeigen?
+  > git log -p --color-words
+  Alternativ kann man .git/config folgende Parameter setzen:
+  [color]
+  	color.diff=auto
+	color.grep=auto
+	color.status=auto
+
+  Wenn man es generell bunt haben will, setzt man einfach
+  [color]
+  	color.ui=auto
+
+  in die Konfigurationsdatei.
+
+* Warum soll ich denn die color-Einstellungen auf auto und nicht true setzen?
+  Der Wert auto bewirkt, dass git nur dann die Ausgaben einfaerbt, wenn diese
+  nach STDOUT gehen. Ansonsten bekommt man den ASCII-kodierten Farbstring in
+  die Ausgabedatei geschrieben.
+
+* Wie kann ich eine Repository loeschen?
+  Zur Zeit ist dies nur durch einen EM mit Shellzugang auf dem MG-Rechner
+  moeglich.
+
+* Kann ich an einem Gebiet, fuer das ich keinen Schreibzugriff habe, helfen
+* einen Bug zu fixen?
+  Ja - sofern Du Leserechte auf das Repository hast. Du kannst das Repo dann
+  forken, d.h. eine Kopie erstellen. Die beste Methode hierfuer ist
+  > ssh git@mg.mud.de fork d/gebirge/zook/wald players/zesstra/public/zwald
+  Hierbei wird ein Clone des Repos erstellt und sich gemerkt, welches das
+  Original war. In Deinem Repo kannst Du nun einen Bugfix machen. Bist Du
+  fertig, sagst Du dem Gebietsmagier (oder einem zustaendigen RM) Bescheid und
+  bittest ihn, den entsprechenden Branch (z.B. syntax_bugfix) zu pullen.
+
+* Wie vermeide ich einen 'merge commit', wenn ich lokale Aenderungen in einem
+* Zweig habe, in den ich Aenderungen aus dem MG pullen moechte?
+  Eine Moeglichkeit hierfuer ist das Pullen mit 'git pull --rebase', um git
+  einen implizites Rebase beim Pull durchfuehren zu lassen.
+
+
+Was ist git?
+Wo krieg ich git her?
+Wie kann ich das Repository clonen?
+Wie kann ich ein Changelog anzeigen lassen?
+Wie kann ich ein Changelog mit Diff anzeigen lassen?
+
+SIEHE AUCH:
+  git-repositories: Repository-Verwaltung im Mud
+  git-howto: Wie git benutzt wird
+  git-workflow: Ein simples Beispiel eines Arbeitsflusses mit Git
+  git-sync: Wie die Synchronisierung zw. git-Repos und Mudlib ablaeuft
+  git-links: Verweise ins WWW
+
+10.03.2015 Amaryllis
+
diff --git a/doc/wiz/git-howto b/doc/wiz/git-howto
new file mode 100644
index 0000000..8a6acdd
--- /dev/null
+++ b/doc/wiz/git-howto
@@ -0,0 +1,111 @@
+Git-Benutzung im MorgenGrauen
+=============================
+
+0. Einleitung
+  Hier soll kurz beschrieben werden, wie man nun an die Repositories auf dem
+  Mudrechner rankommt.
+  Es wird an dieser Stelle vorausgesetzt, dass der Leser/Magier
+  grundsaetzlich weiss, was Git ist und wie es benutzt wird. Hier sollen
+  lediglich Besonderheiten im Zusammenhang mit dem MG erlaeutert werden.
+  Ebenso wird vorausgesetzt, dass der Magier Git und einen SSH-Client auf
+  seinem Rechner installiert hat.
+
+  Wer jetzt noch nix von Git weiss, sei auf die reichhaltig im Netz
+  verfuegbare Doku verwiesen: s. a. git-links.
+
+
+1. Zugriffsrechte auf Git-Repositories
+  Zunaechst muss man sich als Git-Nutzer eintragen lassen. Hierzu braucht man
+  ein SSH-Schluesselpaar, welches man z.B. mittels ssh-keygen erstellen
+  kann. Den _oeffentlichen_ Schluessel (.pub am Ende) legt man dann als
+  <magier>.pub in sein Homeverzeichnis und spricht einen EM (z.B. Zesstra)
+  an.
+
+  Mittels des Befehls
+  > ssh git@mg.mud.de info
+  kann man sich anzeigen lassen, auf welche existierenden Repositories man
+  welche Zugriffsrechte hat (R: lesen, W: schreiben). Beispiel:
+    R   W   (zesstra) d/inseln/zesstra/vulkanweg
+  In diesem Fall hat der Benutzer Lese- und Schreibrechte auf
+  d/inseln/zesstra/vulkanweg. Das Repository gehoert zesstra.
+
+  Zusaetzlich umfasst die Ausgabe auch die Zugriffsrechte aller _moeglichen_
+  (aber noch nicht existierenden) Repos.
+  Wichtig ist hier das Erstellungsrecht (C). Beispiel:
+  C  R   W  d/unterwelt/zesstra/[a-zA-Z]{1}[a-zA-Z0-9_.\-]*
+  Hier hat der Benutzer auf alle Repos unterhalb von d/unterwelt/zesstra/
+  (wobei alle diese Repos mit einem Buchstaben beginnen und ansonsten nur
+   Buchstaben, Zahlen, _, . und - enthalten duerfen) Lese-, Schreib- und
+  Erstellungsrechte.
+
+2. Ein existierendes Repository clonen
+  Dies erfolgt ganz simpel mit dem Befehl:
+  > git clone git@mg.mud.de:players/zesstra/testgebiet <zielverzeichnis>
+  Das Zielverzeichnis ist hierbei beliebig. Empfehlung: alle MG-Repos in
+  einem Verzeichnis sammeln und dort die Verzeichnisstruktur aus dem Mud
+  beibehalten:
+  > git clone git@mg.mud.de:players/zesstra/testgebiet
+    players/zesstra/testgebiet
+  Damit Aenderungen spaeter auch Euren Magiernamen tragen, geht nun bitte in
+  Euer geclontes Repo und setzt Namen und eMail-Adresse:
+  > git config user.name "Magier"
+  > git config user.email "user@example.com"
+  
+3. Ein neues Repository erstellen.
+    Voraussetzung: das Verzeichnis im Mud existiert.
+    Dies geht, wenn ihr Schreibzugriff auf das Verzeichnis im Mud habt. Legt
+    einfach in dem Verzeichnis eine Datei namens "git-mud-import" an (Inhalt
+    ist egal) und wartet bis zur naechsten vollen Stunde.
+    ACHTUNG: das Verzeichnis im Mud darf NICHT leer sein, sondern muss min.
+    eine Datei (ggf. in einem Unterverzeichnis) enthalten!
+ 
+  Anmerkungen:
+  Existiert ein Repo bereits, ist ein automatischer Import aus dem Mud nicht
+  mehr moeglich.
+  Bei einem "git clone" auf ein noch nicht existierendes Repo wird das 
+  das Repo automatisch angelegt - dieses Repo wird dann aber nicht mit
+  dem Mud synchronisiert!
+  Daher: erst (erfolgreich) importieren, dann clonen. 
+
+4. Arbeiten mit dem Repo
+  Hierzu sei zuerst einmal auf die allgemein im Netz verfuegbare Dokumentation
+  zu Git und natuerlich seine Manpages verwiesen.
+  Einen beispielhaften Arbeitsablauf findet sich in der Manpage git-workflow.
+
+5. Synchronisation mit dem Mud
+  Repos koennen bei einem 'git push' von aussen automatisch die Aenderungen
+  des master-Branches ins Mud uebertragen. Desweiteren koennen Aenderungen
+  aus dem Mud automatisch in das Repo importiert werden.
+  Auf diese Weise ist das Verwenden von FTP fast ueberfluessig.
+  Details sind in der Manpage git-sync angegeben.
+
+6. Loeschen von Repositories
+  Git-Repos, die von euch selber GEHOEREN (Schreibrechte allein reichen nicht)
+  koennen geloescht und - zumindest eine Weile auch wieder restauriert werden.
+
+6.1. Loeschen
+  > ssh git@mg.mud.de D trash players/caldra/nebelberge
+  players/caldra/nebelberge moved to trashcan.
+
+6.2. Muelleimer anzeigen
+  > ssh git@mg.mud.de D list-trash
+  players/caldra/nebelberge/2011-11-28_22:35:55
+
+6.3. Restaurieren
+  > ssh git@mg.mud.de D restore players/caldra/nebelberge/2011-11-28_22:35:55
+  players/caldra/nebelberge/2011-11-28_22:35:55 restored to
+  players/caldra/nebelberge
+
+  Es versteht sich von selbst, dass Ihr mit diesem Mittel sehr zurueckhaltend
+  umgehen solltet. Bei Missbrauch wird ggf. ein Backup eingespielt und diese
+  Moeglichkeit wieder geloescht.
+
+SIEHE AUCH:
+  git-repositories: Repository-Verwaltung im Mud
+  git-workflow: Ein simples Beispiel eines Arbeitsflusses mit Git
+  git-sync: Wie die Synchronisierung zw. git-Repos und Mudlib ablaeuft
+  git-faq: haeufig gestellte Fragen/Probleme
+  git-links: Verweise ins WWW
+
+29.01.2013 Gloinson
+Letzte Aenderung: 02.07.2014 Notstrom
diff --git a/doc/wiz/git-kooperation b/doc/wiz/git-kooperation
new file mode 100644
index 0000000..acbda6e
--- /dev/null
+++ b/doc/wiz/git-kooperation
@@ -0,0 +1,68 @@
+Erweiterung zum Git-Workflow:
+=============================
+
+Bei manchen Projekten will man mit anderen Magiern kooperieren, aber:
+* die Dateien im MUD fuer die Spieler unveraendert lassen
+* in einem ordentlichen Zweig zusammenarbeiten
+
+Dazu kann man Zweige auch remote, also im MUD erstellen. Da nur der
+'master'-Zweig in das MUD selbst synchronisiert wird, kann man ueber
+das MUD so die Repositories auf mehr als einen Computer/mehr als einer
+Person synchronisieren, ohne die Spieler mit seiner Entwicklungsarbeit
+zu behelligen:
+
+# Alternativen in/zu Schritt 4: Kooperation in einem remote Zweig.
+Falls ich mit anderen Leuten meinen Code teilen will, dieser aber nicht im
+MUD im 'master'-Zweig auftauchen (also als Dateiaenderung fuer alle Spieler
+gelten) soll, kann ich auch nur meinen Zweig selbst ins MUD schicken:
+> git checkout neue_kampftaktik
+> git push -u git@mg.mud.de:/dings/bums neue_kampftaktik
+
+Als Antwort duerfte sowas wie:
+ * [new branch]      neue_kampftaktik -> neue_kampftaktik
+dort stehen.
+
+Mit
+> git pull
+koennen wir uns diese Aenderungen am MUD-Repository holen. Der Zweig
+'neue_kampftaktik' ist jetzt ein Zweig auch im MUD und alle Leute,
+die sich jetzt das Repository /dings/bums clonen, steht genau dieser
+Zweig mit all unseren Aenderungen jetzt auch zur Verfuegung.
+
+Unser lokaler Zweig 'neue_kampftaktik' bekommt aber die Aenderungen
+an diesem Zweig anderer eventuell noch nicht ganz mit. Mit
+> git branch --set-upstream neue_kampftaktik remotes/origin/neue_kampftaktik
+sagen wir dem lokalen Zweig, dass er ab jetzt mit dem remotes-Zweig
+'neue_kampftaktik' verbunden ist.
+
+Damit bekommen wir etwaige remote-Aenderungen in diesem Zweig nach einem
+> git pull
+bei einem folgenden
+> git checkout neue_kampftaktik
+direkt mitgeteilt, eventuell in der Form:
+  Your branch is behind 'origin/neue_kampftaktik' by 1 commit, and can be
+  fast-forwarded.
+Das ist sehr einfach durch ein
+> git merge origin/neue_kampftaktik
+korrigierbar und schon koennen wir selber wieder an dem aktualisierten Zweig
+arbeiten und Aenderungen pushen. Siehe Schritt 5.
+
+Ziel einer solchen Zusammenarbeit ist natuerlich immer, irgendwann auch
+wieder den aus Schritt 4 bekannten Merge gegen den Zweig 'master' durchzu-
+fuehren, damit die Spieler was davon haben.
+Wenn wir also irgendwann diesen Merge durchgefuehrt haben und der Zweig
+'neue_kampftaktik' unnoetig geworden ist, koennen wir ihn auf der Seite
+des MUDs mit:
+> git push git@mg.mud.de:/dings/bums :neue_kampftaktik
+aufraeumen. Der einzige Unterschied zum Erstellen des Zweiges auf MUD-Seite
+ist tatsaechlich der ':' vor dem Namen des Zweigs.
+Achtung: das geht momentan (noch) nicht und auf 'master' ohnehin nie.
+
+SIEHE AUCH
+  git-repositories: Repository-Verwaltung im Mud
+  git-howto: Wie git benutzt wird
+  git-workflow: Ein simples Beispiel eines Arbeitsflusses mit Git
+  git-sync: Wie die Synchronisierung zw. git-Repos und Mudlib ablaeuft
+  git-faq: haeufig gestellte Fragen/Probleme
+
+02. Feb 2013 Gloinson
diff --git a/doc/wiz/git-links b/doc/wiz/git-links
new file mode 100644
index 0000000..02592a2
--- /dev/null
+++ b/doc/wiz/git-links
@@ -0,0 +1,38 @@
+Liste von nuetzlichen und weiterfuehrenden Links im Netz
+========================================================
+
+  * Das 'offizielle' Tutorial
+    http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html
+  * Git - SVN Crash Course (fuer Leute, die SVN kennen)
+    http://git.or.cz/course/svn.html
+  * Everyday git with 20 commands or so
+    http://www.kernel.org/pub/software/scm/git/docs/everyday.html
+    (sortiert nach Developers, Integrators, Admins)
+  * Das git Community Book (sehr empfehlenswert)
+    http://book.git-scm.com/
+  * Understanding git conceptually
+    http://www.eecs.harvard.edu/~cduan/technical/git/
+  * Git cheat sheets
+    http://help.github.com/git-cheat-sheets/
+    http://jan-krueger.net/development/git-cheat-sheet-extended-edition
+    https://github.com/AlexZeitler/gitcheatsheet/blob/master/gitcheatsheet.pdf
+    http://www.cheat-sheets.org/saved-copy/git-cheat-sheet.pdf
+    http://cheat.errtheblog.com/s/git
+  * Guides/Howtos von GitHub
+    http://help.github.com/
+  * Difference of merge and pull
+    http://longair.net/blog/2009/04/16/git-fetch-and-merge/
+  * Div. Tips und Tricks
+    http://longair.net/blog/2009/04/25/a-few-git-tips/
+  * Git fuer Windows
+    https://code.google.com/p/gitextensions/
+    (Mit Integration in den Explorer)
+  * Git-Benutzung unter Windows
+    http://rogerdudler.github.io/git-guide/
+    http://help.github.com/win-set-up-git/
+  * Git-Interna verstaendlich erklaert:
+    Git For Ages 4 And Up 
+    https://www.youtube.com/watch?v=1ffBJ4sVUb4
+
+10.03.2015 Amaryllis
+
diff --git a/doc/wiz/git-repositories b/doc/wiz/git-repositories
new file mode 100644
index 0000000..9ed7c33
--- /dev/null
+++ b/doc/wiz/git-repositories
@@ -0,0 +1,72 @@
+Git-Repositories im MorgenGrauen
+================================
+
+Die folgenden Repositories stehen fuer die Benutzung durch Magier bereit bzw.
+lassen sich durch Magier bei Bedarf (leer oder durch Import von Verzeichnissen
+aus dem Mud) anlegen:
+
+* /d/region/magier/*
+  Verzeichnisse unterhalb der Magierebene in den Regionen lassen sich in
+  git-Repos aufnehmen.
+  Anlegen: Regionsmitarbeiter, Magier mit Schreibzugriff auf den Pfad
+  Schreibzugriff: Eigentuemer (Magier), Regionsmagier dieser Region, Weise
+  Lesezugriff: s. Schreibzugriff (wegen secure/)
+
+* /p/service/magier/*
+  Anlegen: Weise, Magier mit Schreibzugriff auf den Pfad
+  Schreibzugriff: Eigentuemer (Magier), Weise
+  Lesezugriff: alle Magier (>= 20)
+  
+* /players/magier/*
+  Anlegen: Magier selber, Magier mit Schreibzugriff auf den Pfad
+  Schreibzugriff: Magier selber
+  Lesezugriff: Magier selber
+
+* /players/magier/public/*
+  Anlegen: Magier selber, Magier mit Schreibzugriff auf den Pfad
+  Schreibzugriff: Magier selber, Weise
+  Lesezugriff: jeder Magier (>= 20)
+
+* playground/magier/*
+  Spielwiese zum Testen von Magiern. Soll zum Rumspielen und Testen von Git
+  dienen.
+  Diese Repos werden NICHT mit dem Mud synchronisiert.
+  Diese Repos werden automatisch geloescht, wenn sie laenger als 14 Tage nicht
+  veraendert werden.
+  Anlegen: jeder Magier
+  Schreibzugriff: Magier selber, Weise
+  Lesezugriff: jeder Lehrling (und hoeher) (>= 15)
+
+Uebrigens geht es explizit NICHT, sein gesamtes ~ in ein Repo zu fassen.
+
+Wenn man sein kompletten Regionsverzeichnis (/d/region/magier) in ein Repo
+importiert, sind anschliessend keine einzelnen Repos unterhalb dieses
+Verzeichnisses moeglich (bzw. fuehren zu Problemem)! Ebenso kann das komplette
+Magierverzeichnis nicht mehr als Repo importiert werden, wenn es unter ihm
+schon Repos gibt.
+
+Erzmagier und Goetter haben uebrigens auf _alle_ Repositories Lese- und
+Schreibzugriff. Sie sind auch die einzigen, die in den Repositories einen sog.
+Rewind durchfuehren koennen - d.h. die Versionsgeschichte im Nachhinein
+aendern.
+Eine Beruecksichtigung von access_rights.c, ACCESS_RIGHTS etc. findet hierbei
+derzeit NICHT statt.
+
+Zum Loeschen von Repositories siehe Punkt 6 in git-howto.
+
+Ein (automatischer) Import bestehender Verzeichnisse aus dem Mud ist
+moeglich. In diesem Fall werden das so erstellte Repository und die Mudlib
+automatisch synchronisiert, wenn jemand von aussen in das Repository pusht.
+Hierbei wird _versucht_ etwaige gleichzeitige Aenderung im Git-Repo und in der
+Mudlib sinnvoll zu 'mergen' - im Falle von Konflikten ist dies nicht immer
+moeglich, weswegen Magier auf das Ergebnis solcher automatisierter Merges ein
+Auge werfen sollten.
+
+SIEHE AUCH:
+  git-howto: Wie git benutzt wird
+  git-workflow: Ein simples Beispiel eines Arbeitsflusses mit Git
+  git-sync: Wie die Synchronisierung zw. git-Repos und Mudlib ablaeuft
+  git-faq: haeufig gestellte Fragen/Probleme
+  git-links: Verweise ins WWW
+
+29.01.2013 Gloinson.
diff --git a/doc/wiz/git-sync b/doc/wiz/git-sync
new file mode 100644
index 0000000..87c5d9f
--- /dev/null
+++ b/doc/wiz/git-sync
@@ -0,0 +1,49 @@
+Synchronisation zwischen git-Repositories und Mud
+=================================================
+
+I. Push von aussen ins Mud.
+
+Am Ende es Pushes (im sog. post-update hook) wird ein Script gestartet,
+was folgendes macht:
+
+1) Wenn fuer die Synchronisation mit dem Mud aktiv ist, wird mit der Mudlib
+   gesynct. Wenn nicht: Ende
+2) Zunaechst wird in einem lokalen Clone des git-Repositories ein temporaerer
+   Branch zum Mergen von Aenderungen aus dem Mud angelegt (auto-mud-sync),
+   welcher bei dem Tag last-auto-mud-sync startet und dieser Branch
+   ausgecheckt.
+3) Mit Hilfe von rsync werden alle Aenderungen aus der Mudlib hereinkopiert.
+4) Wenn Aenderungen existieren, wird ein neuer Commit auf dem Branch gemacht.
+5) Anschliessend wird Branch master ausgecheckt.
+6) Wenn es Aenderungen gab, die in 4) commitet wurden, wird jetzt der Branch
+   auto-mud-sync mit diesem Commit in master gemergt.
+   Kommt es hierbei zu Konflikten, werden die _automatisch_ zugunsten des
+   Standes der git-Repositories aufgeloest, d.h. es gehen ggf. Aenderungen aus
+   dem Mud verloren. Es kann hierbei daher passieren, dass von 8 im Mud
+   geaenderten Zeilen nur 6 uebernommen werden, weil 2 Zeilen in Konflikt mit
+   den Aenderungen im git-Repository stehen. Daher ist es wichtig, das
+   Ergebnis dieses Merges im Nachhinein zu pruefen und ggf. zu korrigieren!
+7) Falls es Aenderungen gab, wird jetzt der in 7) erstellte Merge-Commit ins
+   git-Repository gepusht.
+8) Der jetzt gemergte Stand wird per rsync ins Mud kopiert.
+9) Das Tag last-auto-mud-sync wird aktualisiert.
+
+
+II. Automatischer regelmaessiger Commit vom Mud
+
+Jeden Tag um 05:11 wird via cronjob und das Script ~/scripts/git-autocommit
+fuer jedes Repo in ~/git-repositories/ das unter I. beschriebene Script
+~/scripts/git-sync2lib ausgefuehrt.
+
+
+III. Import von Verzeichnissen aus dem Mud
+
+Zu jeder vollen Stunde wird in allen Verzeichnissen unter /d/, /p/ und
+/players/ die Datei 'git-mud-import' gesucht. Alle Verzeichnisse, in denen
+diese existiert, werden in gitolite importiert und gleichzeitig auch ein Clone
+in ~/git-repositories/ erstellt, d.h. dass die Synchronisationsmassnahmen
+unter I. und II. fuer dieses neue git-Repository aktiv sind.
+
+LETZTE AeNDERUNG:
+05.04.2011, Zesstra
+
diff --git a/doc/wiz/git-workflow b/doc/wiz/git-workflow
new file mode 100644
index 0000000..655c76d
--- /dev/null
+++ b/doc/wiz/git-workflow
@@ -0,0 +1,151 @@
+Typischer Arbeitsablauf
+=======================
+
+(Es gibt andere Arbeitsweisen, aber dies hier ist eine, die sich bewaehrt
+ hat.)
+
+Nehmen wir an, ich moechte etwas neues einbauen, einen Bug fixen etc.
+Alle der folgenden Schritt werden auf eurem eigenen Rechner in eurem lokalen
+Clone des jeweiligen Repositories durchgefuehrt.
+
+# Schritt 1: Repository clonen und/oder updaten
+> git clone git@mg.mud.de:/dings/bums
+> git checkout master
+> git pull
+Zuerst einmal wird ein checkout des Zweiges 'master' gemacht. Und in diesen
+Zweig hol ich mir erstmal den aktuellen Stand aus dem Mud (pull).
+
+Jetzt moechte ich alle Aenderungen erstmal in einem separaten Zweig machen.
+Warum? Weil dann der 'master' (das ist der aktive Zweig im Mud!) immer in
+einem benutzbaren Zustand ist. Desweiteren kann man einen Zweig einfach
+wegwerfen, wenn irgendwas groesseres schiefgelaufen ist...
+Ausserdem ist es dann einfacher, zwischenzeitliche Aenderungen aus dem Mud zu
+integrieren.
+
+# Schritt 2: Neuen Zweig erstellen
+> git checkout -b neue_kampftaktik
+Hiermit wird  ein neuer Zweig erstellt und gleichzeitig in ihn gewechselt.
+
+Hier mach ich jetzt alle moeglichen Arbeiten und Basteleien, die ich fuer die
+neue Kampftaktik brauche. Tipps dazu:
+* Viele und haeufige Commits machen! Je kleiner einzelne Commits sind, desto
+  besser kann man Aenderungen spaeter verfolgen (was z.B. super ist, wenn
+  jemand was abnehmen muss!) und desto besser kann man einzelne Aenderungen
+  spaeter bei Bedarf auch rueckgaengig machen, wenn man merkt, dass man
+  stellenweise Unsinn gebaut hat. ;-)
+* Thematisch unterschiedliche Dinge in verschiedene Commits packen. Also zB
+  erst Syntaxfehler editieren und commiten, dann eine neue Methode fuer
+  etwas ganz andere schreiben und commiten.
+
+# Schritt 3.1: Aenderungen pruefen
+> git status
+Hiermit lasse ich mir anzeigen, welche Dateien nicht-committete Aenderungen
+enthalten (oder neu sind/geloescht wurden).
+
+> git diff
+Dies zeigt mir alle nicht-committeten Aenderungen an - zeilenweise verglichen
+mit dem vorherigen Zustand.
+
+# Schritt 3.2: Aenderungen in lokales Repository commiten
+> git add <file>                    // einzelne Files auswaehlen
+ODER
+> git add -A ./                     // alle Files auswaehlen
+Hiermit merke alle gemachten Aenderungen fuer den naechsten Commit vor.
+Ich koennte hier aber auch einzelne Dateien auswaehlen oder sogar nur
+bestimmte Teile der Aenderungen in einer Datei. (Hierzu bitte die
+Git-Doku bemuehen.)
+
+> git commit
+Hiermit erstelle ich einen Commit, der die bisherigen Aenderungen umfasst.
+Dabei wird ein Editor geoeffnet, in den ich eine informative Nachricht ueber
+meine Aenderungen hinterlassen kann. Das ist besonders wichtig, wenn ich in
+fremden Gebieten arbeite, aber auch fuer mich und einen etwaigen abnehmenden
+Magier sehr sinnvoll.
+Anregung: Die erste Zeile ist das sog. Betreff des Commits - vergleichbar mit
+dem Betreff einer eMail. Anschliessend sollte eine leere Zeile folgen und
+danach eine laengere Beschreibung eingeben werden, sofern noetig/sinnvoll.
+
+Wenn ich an diesem Punkt mit dem Bugfix oder Feature noch nicht fertig bin:
+einfach die letzten 4 Befehle aus Schritt 3 beliebig oft wiederholen, d.h.
+beliebig viele weitere Commits machen.
+
+# Schritt 4: Aenderungen in lokalen Master-Zweig mergen
+Bin ich dann schliesslich aber mal fertig, gehe ich erstmal zurueck zum
+master-Zweig:
+
+> git checkout master
+Huch! Ploetzlich sind alle Dateien auf dem alten Stand! Keine Sorge,
+unsere Aenderungen sind im Zweig 'neue_kampftaktik' sicher verwahrt.
+
+Achtung: wenn ihr mit anderen zusammen arbeitet, koennte jemand
+anderes im MUD Aenderungen vorgenommen haben. Ein einfaches
+> git pull
+um die Dateien im 'master'-Zweig auf den neuesten Stand zu bringen,
+zeigt euch auch Aenderungen. Wenn da jetzt
+  'Already up-to-date.'
+steht, ist alles in Butter, ansonsten siehe unten bei 4.1.extra.
+
+> git merge neue_kampftaktik
+Mit diesem Kommando hole ich nun alle Aenderungen aus meinem Zweig
+'neue_kampftaktik' in den Zweig 'master' (merge).
+
+# Schritt 5: Aenderungen in das MUD-Repository uebertragen
+Jetzt bin ich bereit, die Aenderungen ins Mud zu uebertragen:
+> git push 
+Job done!
+Hier kommen jetzt div. Ausgaben vom Mud, die etwas ueber den Erfolg und
+Misserfolg des Pushes sagen. ;-)
+Wenn am Ende steht
+  'Your changes were copied to the mudlib.'
+ist alles erfolgreich.
+
+Steht am Ende ein
+  'Your changes were merged successfull with changes in the mudlib and the
+   merged state was copied to the mudlib. Do not forget to pull the merge
+   commit!" 
+ist an sich auch alles gut. Aber dann gab es im Mud eben doch noch
+Aenderungen, die es nicht im Git-Repo gab, die gemerged wurden. In diesem
+Fall sollte man den aktuellen Zustand sich nochmal holen:
+> git pull
+Und dann anschauen, dieser Merge auch das richtige gemacht hat:
+> git log -p
+Hiermit kriege ich eine schoene Liste aller Commits angezeigt und -p sorgt
+dafuer, dass dabei alle Aenderungen angezeigt werden, nicht nur die
+Commit-Nachricht.
+
+# Sonderfaelle und erweiterte Moeglichkeiten
+# Schritt 4.1.extra: Zwischenzeitliche Aenderungen im MUD beruecksichtigen
+
+Es koennte sein, dass man fuer den Branch ne ganze Weile gebraucht hat -
+und dass waehrend meiner Arbeit jemand anders Aenderungen (im Mud oder
+Repo) gemacht hat.
+
+Diese Aenderungen sollte man sich wie geschrieben als erstes nach dem
+Umschalten zum master-Zweig holen:
+> git pull
+
+Jetzt geh ich wieder in meinen Zweig (ohne -b)
+> git checkout neue_kampftaktik
+und mache ein sog. Rebase. Damit verschiebe ich sozusagen, den Punkt,
+an dem mein Zweig vom 'master' abzweigt und tue so, als ob die eben
+geholten Aenderungen schon da gewesen waeren, als ich den Zweig erstellte.
+(Andere Sichtweise: ich nehme meine Zweig und setz ihn auf den aktuellen
+ 'master' dran.)
+> git rebase master
+
+Der Vorteil ist: wenn jetzt was kaputt gegangen ist, es also Konflikte gibt,
+dann gibt es die nur in meinem Zweig 'neue_kampftaktik' und dort kann ich
+sie in aller Ruhe reparieren. Sowohl der 'master' im MUD als auch mein
+lokaler 'master' sind intakt.
+
+Und jetzt geht es wie oben weiter.
+
+SIEHE AUCH
+  git-repositories: Repository-Verwaltung im Mud
+  git-howto: Wie git benutzt wird
+  git-kooperation: Ein ueber git-workflow hinausgehendes Beispiel zur
+                   Synchronisation bzw Kooperation mehrerer Magier/Rechner
+  git-sync: Wie die Synchronisierung zw. git-Repos und Mudlib ablaeuft
+  git-faq: haeufig gestellte Fragen/Probleme
+
+02. Feb 2013 Gloinson
diff --git a/doc/wiz/hausbau b/doc/wiz/hausbau
new file mode 100644
index 0000000..6c9c2a5
--- /dev/null
+++ b/doc/wiz/hausbau
@@ -0,0 +1,40 @@
+Hilfeseite fuer Magier: Hausbau im MorgenGrauen
+-----------------------------------------------
+
+Als Magier wird man desoefteren von Spielern gebeten, Ihnen beim
+Hausbau behilflich zu sein. Diese Bitte erfolgt meistens als
+
+1) 'Kannst Du hier in dem Raum wo ich bin, es mal so einrichten,
+    dass ich mein Haus abstellen und giessen kann'
+
+und 
+
+2) 'Ich moecht hier gerne mein Haus abstellen, aber es soll un-
+    sichtbar sein, eine andere Kurzbeschreibung haben und man 
+    soll es nicht mit <betrete> betreten koennen, oder .... '.
+
+
+Fuer 1) ist es relativ einfach. Man begebe sich als Magier in den 
+Raum, zuecke sein MG-Tool und tippe ein 
+
+              'xcall $h->SetProp(P_HAUS_ERLAUBT,1)'.
+
+Dann fordere man den Spieler auf, sein Haus abzustellen und gies-
+sen und setze diese Property wieder auf 0.
+
+ACHTUNG: Das Abstellen eines Hauses muss unbedingt vorher mit dem 
+-------  Magier abgesprochen werden, dem dieser Raum gehoert! Bei 
+         inaktiven Magier ist dies der zustaendige Regionsmagier.
+
+Bei 2) verfaehrt man, wie fuer den Fall 1) geschildert. Jedoch sind 
+dazu noch andere Dinge notwendig. Da diese den Rahmen einer Hilfe-
+seite sprengen, liegt unter 
+
+                       /doc/beispiele/misc/seherhaus.c
+
+ein File, in dem alles ausfuehrlich dokumentiert ist.
+
+SIEHE AUCH: P_HAUS_ERLAUBT
+
+------------------------------------------------------------------------------
+LETZTE AeNDERUNG: Sam, 19.05.2001, 23:00:00 von Tilly
diff --git a/doc/wiz/heilung b/doc/wiz/heilung
new file mode 100644
index 0000000..3d1b6c8
--- /dev/null
+++ b/doc/wiz/heilung
@@ -0,0 +1,156 @@
+Heilung von Spielern durch Objekte, Raeume, portable Heilung
+============================================================
+
+                               Generelles:
+                               **********
+
+Neben den bekannten Heilstellen fuer Spieler (den Kneipen sowie gildeninterne
+Faehigkeiten) gibt es noch die Moeglichkeit, den Spielern Heilung durch Ver-
+wendung der LFUNs "heal_self", "restore_hit_points", "restore_spell_points",
+"buffer_hp" und "buffer_sp" Heilung zukommen zu lassen.
+
+Dies wird meist ueber Raeume gemacht, in denen der Spieler ein bestimmtes
+Kommando ausfuehren muss oder ueber Objekte, die der Spieler mit sich tragen
+kann ('tragbare Tanken'), um Heilung zu erfahren.
+
+ES WIRD EMPFOHLEN, jede mobile Heilung ueber "/std/food" zu implementieren.
+Dort muessen lediglich ein paar Properties gesetzt werden, um sicherzugehen,
+dass diese Heilungsregeln eingehalten werden.
+Gleichzeitig wird auch sichergestellt, dass z.B. Props von Containern, die
+Heilung enthalten, nach Leerung korrekt gesetzt werden.
+
+Neben diesen Moeglichkeiten gibt es auch noch Enttankungen, also die
+Moeglichkeit, im Spieler eine der Properties P_DRINK, P_FOOD oder P_ALCOHOL
+ueber die LFUNs "defuel_food/drink" oder "reduce_food/drink/alcohol" zu
+mindern. Dies ist eine Form der Heilung, da der Spieler danach wieder
+regulaer essen und trinken kann. Sie muss allerdings ortsgebunden sein.
+
+Grundsaetzlich kann eine Heilstelle natuerlich auch Schaden in einem Spieler
+verursachen. Das macht dann Sinn, wenn er z.B. der - fuer diese Heilstelle -
+'falschen' Gilde oder Rasse angehoert. Dabei MUSS fuer den Spieler aber
+vorher deutlich erkennbar gewesen sein, dass diese 'Heilstelle' fuer ihn
+nicht geeignet ist.
+
+                              Spezifisches:
+                              ************
+
+Bei jeder Form von Heilung MUSS "eat_food" (bei Essen) oder "drink_soft" (bei
+Trinken) und ggf. "drink_alcohol" verwendet werden! Diese Funktionen sorgen
+fuer einen unkomplizierten Ablauf der Heilung, da sie pruefen, ob der Spieler
+noch genuegend Tankkapazitaeten hat und wenn ja, die entsprechenden Properties
+(P_DRINK, P_FOOD oder P_ALCOHOL) automatisch raufsetzen.
+
+"drink_alcohol" ist in diesem Zusammenhang besonders wichtig, da es auf einen
+evtl. vorhandenen Saufskill prueft!
+
+Die Heilung selber muss dann aber noch ueber "heal_self", "restore_hit_points",
+"restore_spell_points", "buffer_hp" oder "buffer_sp" geschehen!
+
+Ortsgebundene Heilung:
+---------------------
+Kneipen: Hier ist klar, dass, je hoeher die Heilung ist, umso teurer die
+         Heilung sein muss. Ausserdem MUSS "buffer_hp" verwendet werden.
+         Ausnahme hiervon ist die Kneipe bei den Eistrollen im Warok.
+         Mit dem Pubtool ("/obj/tools/pubtool") kann man pruefen, ob die
+         Werte der Kneipe in Ordnung gehen.
+
+Raeume:  Es gibt viele ortsgebundene Heilungsstellen im MG, welche in erster
+         Linie dazu da sind, den Spielern *in diesem Gebiet* eine Tankmoeg-
+         lichkeit zur Verfuegung zu stellen (-> Drakonien). Hierfuer sollte
+         man die Property P_LAST_XP benutzen, was aber allerdings keine
+         Pflicht ist, wenn man moechte, dass auch "gebietsfremde" Spieler
+         hier tanken gehen koennen (-> SSP). Dann wiederum sollte man aber
+         darauf achten, dass sie nicht zu gut sind, u.U. schwer zu erreichen
+         sind (-> T'emong), Blockmonster den Weg versperren (-> SSP) etc.
+
+         In jedem Fall aber MUSS eine Begrenzung der Tankmoeglichkeit sicher-
+         gestellt werden; entweder erfolgt die Limitierung durch Reset oder
+         durch Zeitbegrenzung (-> check_and_update_timed_key).
+
+         "eat_food" bzw. "drink_soft" MUSS bei den Tanken gesetzt werden, die
+         den Spieler darauf schliessen lassen, Nahrung aufgenommen zu haben
+         (-> "iss beeren", "trinke schleim", etc.).
+         Bei allen anderen (-> "rieche blume", etc.) sollten Qualitaet und
+         Quantitaet im Rahmen bleiben.
+         Diese ortsgebundenen Heilungen duerfen Instant-Tanken sein.
+
+Tragbare Heilung:
+----------------
+Tragbare Heilung sollte nach max 5 Resets verderben, die Wirkung vermindern
+oder verloren gehen. Sie sollte nicht beliebig im Spieler oder anderswo
+hortbar sein. Eine begrenzte Anzahl pro Reset kommt hierbei auch immer gut
+(gute Beispiele hierfuer: Drops von Twingi, Heilblaetter von Zook).
+
+Richtwerte fuer Aufloesung oder Wirkungsminderung von tragbarer Heilung:
+
+                        Heilung         Reset-Zeit
+                          > 200    :     30- 60 min
+                      150 - 200    :     60-120 min
+                      100 - 150    :     90-180 min
+                       50 - 100    :    120-240 min
+                          <  50    :    150-300 min
+
+Diese Richtwerte sind gute Anhaltspunkte, koennen aber bei Bedarf mit dem
+Erzmagier der Heilungs-Balance individuell abgestimmt werden.
+
+'Wirkungsminderung' ist hierbei im Sinne von *deutlich* gemeint.
+
+*** NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU  ***
+
+   Tragbare Heilungen, die im weitesten Sinne aus Lebensmitteln bestehen,
+  duerfen nicht mehr instant sein, sondern MUESSEN "buffer_hp/sp" verwenden!
+
+*** NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU - NEU  ***
+
+Bei tragbaren Heilungsmoeglichkeiten, die weder aus Essbarem, noch aus Trink-
+barem besteht (bei denen es also nicht logisch waere, "buffer_hp/sp" zu
+benutzen), MUSS "check_and_update_timed_key" verwendet werden, da sie sonst zu
+kritisch werden. Dann darf es natuerlich auch sowas geben. Beispielsweise kann
+man solche Objekte gut als (Mini-)Questbelohnung integrieren.
+
+Hier gilt: Je hoeher die Heilung, um so hoeher die Zeitdauer, nach der der
+Spieler diese Moeglichkeit wieder in Anspruch nehmen darf.
+(Richtwerte: heal_self(50): ~ 1800 sec., heal_self(150): ~ 3600 sec.)
+
+Auch bei diesen Objekten ist es ein MUSS, die Heilungsmoeglichkeiten einmal
+erschoepfen zu lassen, sie also entweder 'verderben' oder sich verabschieden
+(-> Dschinn) zu lassen oder sie 'stillegen', da sie dann einfach eine zeitlang
+Ruhe brauchen, um sich neu 'aufzuladen'.
+
+Questbelohnungen:
+----------------
+Diese Objekte stellen eine Ausnahme unter den tragbaren Heilungen dar. Hier
+kann auf "buffer_hp/sp" verzichtet werden; dafuer muessen aber andere Regeln
+beachtet werden: das Objekt darf pro Reset nur begrenzt heilen bzw. nach der
+Anwendung sich selber zerstoeren (-> gelber Stein). Oder es muss vorher eine
+erhebliche Menge LP/KP investiert werden, um das Objekt zu nutzen
+(-> Infernoblock).
+
+Enttanken:
+---------
+Die Moeglichkeit zur Enttankung MUSS an einen festen Ort gebunden sein. Sie
+darf also nicht durch tragbare Objekte hervorgerufen werden koennen. Ein
+Beispiel hierfuer sind die Toiletten von Wurzel in Wilhelmsburg oder die
+Fleischreste in der SSP. Weiteres hierzu siehe -> "man enttanken".
+
+                                 Logisches:
+                                 *********
+
+Jede (!) Moeglichkeit zur Heilung, abgesehen von regulaeren Kneipen, muss dem
+zustaendigen Magier fuer Heilungs-Balance gemeldet und von diesem genehmigt
+werden. Wer diesen Posten momentan innehat, kann dem MailAlias
+"heilungs_balance" entnommen werden.
+
+Siehe auch:
+----------
+     Tanken:    consume, drink_alcohol, eat_food, drink_soft
+     Heilung:   heal_self, restore_spell_points, restore_hit_points, 
+                buffer_hp, buffer_sp
+     Timing:    check_and_update_timed_key
+     Enttanken: defuel_drink, defuel_food
+     Props:     P_DRINK, P_FOOD, P_ALCOHOL, P_SP, P_HP,
+                P_DEFUEL_TIME_DRINK
+     Konzepte:  enttanken, food
+
+----------------------------------------------------------------------------
+17.09.2010, Zesstra
diff --git a/doc/wiz/kampfobjekte b/doc/wiz/kampfobjekte
new file mode 100644
index 0000000..39d6e28
--- /dev/null
+++ b/doc/wiz/kampfobjekte
@@ -0,0 +1,60 @@
+ SONSTIGE KAMPFOBJEKTE:
+
+    Hierzu zaehlen alle Sachen, die irgendeinen Einfluss auf den Kampf nehmen
+    und weder `/std/weapon.c' noch `/std/armour.c' sind. Also die sogenannte
+    Artillerie, Eisstab und artverwandtes, Wurfsterne, Parasteine, Bumis...
+    sowie saemtliche tragbaren Heilmoeglichkeiten und unterstuetzende NPC.
+
+    Prinzipiell sind alle diese Sachen genehmigungspflichtig.
+    Auto-Selbstfahrer, also Sachen, die ohne Eingriff des Spielers agieren,
+    sind unerwuenscht und sollten vermieden werden. Sorry fuer die
+    Laggeplagten...
+
+    Kampfobjekte sollten P_ATTACK_BUSY setzen und auch vor der Anwendung
+    abfragen, damit sie nicht unbegrenzt hintereinander genutzt werden
+    koennen. Magische Sachen sollten entweder aufgeladen werden muessen oder
+    ihre magische Energie verlieren, damit sie nicht unendlich haltbar sind.
+    Ausserdem hat Magie normalerweise auch unerwuenschte Nebenwirkungen. Die
+    Spieler sollen die moeglichen Vorteile gegen Nachteile oder Nebenwirkungen
+    des Gegenstands abwaegen. Auch bei diesen Objekten *muss* P_INFO gesetzt
+    werden, um eine Begruendung fuer die besondere Wirkung und z.B. einen
+    Hinweis auf die Benutzung zu liefern.
+    Sie sollten keinesfalls kaeuflich erworben werden koennen.
+
+    Tragbare Heilstellen sollten aeusserst spaerlich verwendet werden. Handelt
+    es sich um irgendeine Form von Fressalien (Brot, Pfirsich,
+    Schnellhaerter...) so muss P_FOOD oder P_DRINK und evtl. P_ALCOHOL gesetzt
+    werden. Ansonsten sollten solche Dinge wenigstens irgendwelche
+    Auswirkungen auf den Spieler haben ausser der Heilung. Ein sogenanntes
+    "Restrisiko" waere nicht verkehrt...
+
+    Sie sollten niemals unbegrenzt erworben werden koennen, schon gar nicht
+    kaeuflich! Ausserdem ist eine gewisse Verfallszeit sehr sinnvoll und
+    erhoeht die Chancen auf Genehmigung. Richtwerte: erhoehtes Risiko nach 1.
+    Reset, unbrauchbar nach 2-3 Resets.
+
+    Objekte, die Auskunft ueber ein- und/oder ausgehende Schaeden geben, 
+    sind genehmigungspflichtig. Solche Objekte sollten nach Moeglichkeit
+    eine Waffe oder Kleidungsstueck - dies jedoch nicht AT_MISC - sein.
+    Dass solche Objekte auch ueber Luecken in der Angabe der Schaeden und
+    Nachteile verfuegen sollten, ist eigentlich klar. 
+    Solche Nachteile liessen sich ueber eine Mindest-Schadenshoehe oder
+    random realisieren. Informationen ueber mehrere Schadenstypen durch 
+    ein und das selbe Objekt sind nicht erwuenscht.
+
+    Ebenfalls genehmigungspflichtig sind alle Objekte, die in irgend einer
+    Weise Einfluss auf spezifische Gildenfaehigkeiten oder Besonderheiten
+    nehmen. Hierzu sollte neben der Balance auch noch der Gildenmagier
+    befragt werden. 
+    
+    Hinsichtlich Komponenten der Zauberer ist der Gildenchef der
+    Ansprechpartner.
+    
+ SIEHE AUCH
+
+     balance, ruestungen, waffen, fernwaffen, uniques, npcs, objects,
+     attributsveraenderungen, resistenzen, grenzwerte, artillerie
+
+------------------------------------------------------------------------------
+ LETZTE AeNDERUNG:
+    So, 26.01.2003, 18:50:00 von Humni
diff --git a/doc/wiz/katzenkrieger.testspieler b/doc/wiz/katzenkrieger.testspieler
new file mode 100644
index 0000000..33c2ac9
--- /dev/null
+++ b/doc/wiz/katzenkrieger.testspieler
@@ -0,0 +1,37 @@
+Magier-Manpage
+
+Gildentestie "Katzenkrieger".
+
+
+Es gibt in der Katzenkriegergilde eine Funktion, mit der man einen
+Testspieler erschaffen kann, welcher der Katzenkriegergilde angehoert.
+Die Funktion heisst "make_testplayer" und erwartet als einzigen Parameter
+ein Spieler-Objekt.
+
+
+
+Die Funktion verhaelt sich wie folgt.
+
+Der Spieler muss ein Testspieler sein.
+Der Spieler sollte in die Gilde eintreten koennen.
+Der Spieler lernt alle Spells und Skills der Gilde, die er auf seinem
+derzeitigen Spielerlevel lernen kann.
+Die Spells haben je den hoechstmoeglichen Skillwert, den der Spieler auf
+seinem Level erreichen kann, es sei denn, er kannte den Spell zuvor schon.
+Dann bleibt der Spell unveraendert.
+
+
+
+Um einen Testspieler zu erschaffen, geht man wie folgt vor.
+
+Man nehme einen (eigenen!) Testspieler, z.B. "bambs".
+Man setze ihm das gewuenschte Spielerlevel, z.B. 11
+  xcall bambs->SetProp(P_LEVEL, 11);
+Man gehe in den Gildenraum der Katzenkrieger.
+  goto /gilden/katzenkrieger
+Man rufe die Funktion auf, die einen Katzenkrieger aus dem Testspieler macht.
+  xcall $h->make_testplayer(find_player("bambs"));
+Der Testspieler sollte nun Katzenkrieger sein.
+
+******************************************************************************
+Letzte Aenderung: Tue Jan  7 23:03:16 2003 durch Bambi
\ No newline at end of file
diff --git a/doc/wiz/knete b/doc/wiz/knete
new file mode 100644
index 0000000..e4d1f3e
--- /dev/null
+++ b/doc/wiz/knete
@@ -0,0 +1,81 @@
+NAME:
+		*** KNETE ***
+
+BESCHREIBUNG:
+	Die Knete ist ein in LPC geschriebener Lisp-Interpreter. Dieser hat
+	die besondere Eigenschaft, die Lisp-Quellen direkt in den vom 
+	Amylaar GameDriver angebotenen closures zu uebersetzen. Dadurch ist
+	mit der Knete alles das moeglich, was auch mit LPC moeglich ist.
+	Es ist ein generisches, frei programmierbares Hilfsmittel.
+
+	Die Knete befindet sich unter: "/obj/tools/lisp"
+
+FUNKTIONSBESCHREIBUNG:
+	Die Knete kann im Prinzip fast alles, was ein einfacher Lisp-
+	Interpreter kann. Ausnahmen sind Tupel (Bsp: (1 . 2)), welche nicht
+	implementiert sind. Die Grundlegenden Funktionen, wie define, setq,
+	cons, cdr, car etc werden beim Laden der Knete angezeigt. Je nach
+	Zeit, werden eventuelle auch weitere Standardfunktionen hinzu-
+	kommen, um die Knete moeglichst common-lisp kompatibel zu machen.
+
+BENUTZUNG:
+	Zu allererst sollte man wissen, dass dies hier keine Einfuehrung in
+	Lisp ist oder sein soll! Die wichtigsten Merkmal der Knete werden
+	aufgefuehrt an einigen kleinen Beispielen. Wer Lisp kennenlernen
+	moechte kann dies mit den handelsueblichen Buechern tun.
+
+	Wer dennoch basteln moechte: Lisp ist eine Sprache in Prefixnotation,
+	d.h. der Funktionsname steht immer als erstes und dann kommen die
+	Argumente. Ein Ausdruck ist mit den ihn umgebenden Klammern komplett.
+	  Beispiel: (+ 1 1) ;;; errechnet die Summe aus 1 und 1
+	Solche Klammerausdruecke koennen beliebig geschachtelt werden.
+	  Beispiel: (+ 1 (+ (+ 1 1) 1))
+
+	Es stehen alle efuns, sowie einige lfuns zur Verfuegung! Zu den efuns
+	gehoeren auch +,-,*,/,%,!,[,[<,[<.. etc, also alle Operatoren von LPC.
+
+	Die Knete hat zwei Modi:
+		a) Laden von Lisp aus einer Datei
+		b) Verarbeiten von Eingaben aus der Kommandozeile
+
+	Zu a)
+	  Mit der Funktion "load" koennen Dateien eingelesen und interpretiert
+	  werden. Die Funktion hat nur ein Argument, und das ist der Dateiname.
+
+	  Beispiel: (load "/players/hate/lisp.l")
+	
+	Zu b)
+	  Wenn die Knete gecloned wurde, koennen jederzeit Lispausdruecke
+	  eingegeben werden, welche dann interpretiert werden. Dabei sollte
+	  beachtet werden, dass die aeusserste Klammer nicht notwendig ist!
+
+	  Beispiel: (+ 1 (+ 1 1)) koennte man auch schreiben als:
+	            + 1 (+ 1 1)
+
+	  Dies ist vor allem dann interessant, wenn man die Moeglichkeiten
+	  der Knete als alias-Werkzeug in betracht zieht. Somit ist es
+	  moeglich, eine Funktion zu schreiben und diese dann wie ein alias
+	  zu benutzen.
+
+	  Beispiel: (defun who () (users)) ;;; gibt das users array aus
+	             Jetzt muss nur noch who eingegeben werden und das
+		     array wird ausgegeben.
+
+	  Da Lisp wesentlich komplexere Ausdruecke ermoeglicht, als der
+	  normale alias-Interpreter, liegen die Vorteile auf der Hand.
+
+KONFIGURATION:
+	Die Knete laesst sich fuer jeden Nutzer konfigurieren, indem sie eine
+	Datei "/players/<name>/lisp.l" aus dessen Heimatverzeichnis laedt.
+
+	Ein Beispiel, was man damit machen kann befindet sich unter:
+	  "/players/hate/lisp.l"
+	Die MUD Spezifischen Teile und Abfragen koennen ignoeriert werden.
+
+BUGS:
+	Es gibt momentan noch ein Problem, wenn auf der Kommandozeile
+	Klammern fehlen. Dann kommt eine Meldung: "*Missing 2 )"
+	In diesem Fall einfach zweimal hintereinander ) auf jeweils einer
+	einzelnen Zeile eingeben! Dieses Problem tritt vor allem dann auf,
+	wenn man zum Beispiel ein :( eingibt.
+
diff --git a/doc/wiz/laden b/doc/wiz/laden
new file mode 100644
index 0000000..2de2ea3
--- /dev/null
+++ b/doc/wiz/laden
@@ -0,0 +1,15 @@
+LAEDEN IM MORGENGRAUEM
+----------------------
+
+Laeden im MorgenGrauen sollten grundsaetzlich /std/shop erben.
+
+Des Weiteren benoetigt man einen StorageRoom, also einen Raum, in dem der
+Laden seine Gegenstaende verwaltet. Dieser wird mit "SetStorageRoom"
+gesetzt. Die Hilfeseite zu diesem Befehl hat auch ein Beispiel.
+
+Objekte, die der Laden immer verkaufen soll, kann man mit "AddFixedObject"
+setzen.
+
+Siehe auch: SetStorageRoom, AddFixedObject, QuerySellValue
+
+Letzte Aenderung: Humni, 2015-06-17
diff --git a/doc/wiz/leitfaden b/doc/wiz/leitfaden
new file mode 100644
index 0000000..7d806c1
--- /dev/null
+++ b/doc/wiz/leitfaden
@@ -0,0 +1,487 @@
+
+
+ACHTUNG: DIESER LEITFADEN IST FURCHTBAR VERALTET! :-(
+
+
+DER LEITFADEN 'WIE SCHLIESSE ICH ERFOLGREICH MEIN GEBIET AN'.
+(in sieben Schritten zum Erfolg, von Tsunami und Feuerwehr)
+-------------------------------------------------------------
+
+Dieser Leitfaden ist absolut unverbindlich und kein Reglement. Die 
+Reihenfolge muss nicht eingehalten werden, und auch die Anmerkungen 
+zu den einzelnen Punkten sind nicht zwingend zu befolgen.
+
+Fuer Schnellleser:
+
+1) Raeume/Objekte/NPCs proggen
+2) Alles Testen und Mail an die Regionsmagier (RM) schicken.
+3) RMs pruefen Code und weisen auf moegliche Probleme hin.
+4) Antrag Balance verfassen ('goto /players/paracelsus/office').
+5) Forscherpunkte beantragen (hilfe erzmagier).
+6) Mail an RMs, dass nun alles i.O. ist.
+7) RMs schliessen Gebiet an.
+
+Nun etwas ausfuehrlicher.
+
+-------------------------------------------------------------
+P H A S E 1
+-------------------------------------------------------------
+Du bist nun also Magier, voller Ideen und Tatendrang. Bevor Du wild drauflos
+programmierst, ein paar Tips, um Dir und den zustaendigen RMs das Leben zu 
+erleichtern:
+
+Fertige Dir eine ASCII-Karte an, und schreibe einen kurzen Text, der Dein 
+neues Gebiet beschreibt. Frage schon mal Deinen RM, wo ungefaehr dieses
+neue Gebiet angeschlossen werden koennte. So kannst Du Dir ein paar Gedanken
+machen, wie die Anschlussraeume ausschauen koennten.
+
+Erstelle sinnvolle Unterverzeichnise: es hat sich folgendes bewaehrt:
+Ein Hauptverzeichnis mit dem Namen des Gebietes (kurz, wenns geht). Dort
+kommen dann die Unterverzeichnise rein: z.B. '+/doc +/mon +/obj +/rooms'. 
+In das '+/doc' kommen dann Deine Karten und Texte. Falls Du mit 
+'NotifyPlayerDeath()' Deine Kerben loggen willst, oder andere wichtige 
+Sachen loggen moechtest, dann schreibe diese Files in das '/log/<deinname>/' 
+Verzeichnis. 
+In das '+/mon' Verzeichnis kommen alle NPCs usw.
+
+Wenn Du ein Textfile aufrufen willst, dass den Inhalt der Unterverzeichnise
+beschreibt, so lege einfach eine '.readme' Datei im entsprechenden 
+Verzeichnis an. Dieses File wird bei jedem 'cd' aufgerufen.
+
+Bevor Du jetzt losschlaegst, ueberlege Dir ein Define-File, worin Du die
+ganzen Pfade definierst. Denn wenn Du zuerst alles in Deinem Player-
+Verzeichnis proggst, und vor Anschluss wird das Gebiet in das Regions-
+verzeichnis gemoved, will niemand die ganzen Pfadnamen abaendern.
+Ein Beispiel: in Dein 'gebiet.h' (gib ihm einen praktischen Namen der zu 
+Deinem Gebiet passt: eismine.h, hoehle.h oder keller.h usw) kaeme sowas 
+in der Art:
+
+#define EISMINE(x) ("/d/polar/tsunami/eismine/"+x)
+#define ROOM(x) (EISMINE("rooms/"+x))
+#define MON(x) (EISMINE("mon/"+x))
+#define OBJ(x) (EISMINE("obj/"+x))
+
+Dein Raum included dann das File: #include "../gebiet.h"
+Dein Ausgang in einen anderen Raum machst Du dann folgendermassen:
+AddExit("norden", ROOM("raum02"));
+
+Ein NPC wuerde somit folgendermassen in den Raum gestellt:
+AddItem(MON("eiself"), REFRESH_DESTRUCT);
+
+Wenn spaeter aus irgend einem Grund Dein Gebiet verschoben werden muss, dann
+kann der RM einfach die erste Zeile in 'gebiet.h' abaendern. Das spart Zeit
+und Nerven.
+
+Weiter bietet das Define-File die Moeglichkeit, laengere Befehle zu
+verkuerzen. Ein Beispiel: Du moechtest Namen des Spielers (gross geschrieben)
+ausgeben. Der Befehl dazu waere: this_player()->Name(WER)
+Das ist ziemlich lang. Definiere in Deinem Define-File doch einfach:
+#define TPN this_player()->Name(WER)
+und schon wird Dein Code etwas uebersichtlicher. Die Anwendung waere z.B.
+say(TPN+" popelt in der Nase.\n");
+
+Wenn Du automatische Zeilenumbrueche moechtest, dann schreibe folgendes
+in Dein Define File:
+#define BS(x) break_string(x, 78 , "", BS_LEAVE_MY_LFS)
+BS_LEAVE_MY_LFS bewirkt, dass Du immer noch selbst Zeilenumbrueche einbauen
+kannst mit \n. Und so wird BS dann benutzt:
+AddDetail( ({"wand","waende"}),BS(
+  "Die Waende bestehen wie alles hier aus purem Saphir. In die noerdliche "+
+  "Wand wurde ein schrecklich gezacktes und scharfkantiges Loch gesprengt."));
+
+Um dies zu benutzen musst Du allerdings noch #include <break_string.h> in das 
+Headerfile setzen (vor die #define BS(x)...)-Zeile), sonst kennt der 
+Precompiler den Ausdruck BS_LEAVE_MY_LFS nicht.
+
+Du wirst Dein Gebiet evtl. in Deinem Home-Verzeichnis (/players/...)
+schreiben, da Du noch nicht den Sprung zu Level 21 geschafft hast. Du
+solltest aber wissen, dass Deine RegionsmagierInnen nur Gebiete annehmen
+werden, welche im Regionsverzeichnis /d/.../dein_name/ gespeichert sind. Das
+ist wichtig, denn in Deinem Heim-Verzeichnis koennen sie nicht schreiben und
+so keine Fehler korrigieren. Denke daran! Benutze unbedingt die Defines,
+denn vor dem Anschluss wirst Du das Gebiet in das Regionsverzeichnis
+schieben muessen.
+
+Viele Spieler 'loggen', also speichern gerne Tode oder Aktionen von Spielern
+in ihren Heim-Verzeichnissen. Dieses Schreiben funktioniert nicht von
+Regionsverzeichnissen in Heim-Verzeichnisse. Benutze auch hier ein define!
+
+Nun kommen wir zum proggen. Falls Du noch nie programmiert hast, ist es
+sinnvoll, sich Beispielfiles anzuschauen. Wuehl Dich durch das '/doc'
+Verzeichnis oder noch besser: frag Deinen Papimagier/Deine Mamimagierin oder
+den RM, ob er Dir ein paar seiner Files zuschickt. Hast Du diese Huerde
+ueberwunden, kann es losgehen. Wenn Du anfaengst zu proggen und nicht weisst, 
+wie man einen bestimmten Befehl benutzt, kannst Du die 'man page' konsultieren 
+(das Manual = Online Hilfe). Tipp einfach 'man <befehl>' und schon kommt die 
+entsprechende Hilfeseite, falls vorhanden.
+
+Ein paar Worte zu den Raeumen: Details sind hier sehr wichtig.
+Mach viele Details und beschreibe sie nett. 'unt boden' -> 'Der ist unter Dir.'
+ist nicht sehr interessant. Ein Raum mit weniger als 20 Details wird
+mittlerweile als ungenuegend angesehen, auch wenn es noch ein paar Gebiete
+im MG gibt, wo die Raeume fast keine Details haben (diese Zahl schwankt
+natuerlich von Region zu Region -- trotzdem: je mehr Details, desto besser). 
+AddSmells und AddSounds solltest Du ebenfalls nicht vergessen. Der Spieler 
+von Welt will auch riechen und hoeren koennen. Wenn Du einen Raum erstellst, 
+ueberlege Dir auch witzige und/oder sinnvolle Befehle, die man in dem Raum 
+ausfuehren kann. Bei laengeren Prozeduren ist es fuer den RM hilfreich, wenn 
+Du im jeweiligen Raum einen kurzen Kommentar absetzt.
+
+Schau, dass Du ein atmosphaerisch schoenes Gebiet programmierst. Schau,
+dass es sich mit seiner Umgebung vertraegt. Bevor Du ein abgestuerztes
+Raumschiff von der Vega programmierst, frage lieber Deinen RM, denn
+wahrscheinlich passt es thematisch nicht in seine Region (welche Region auch
+immer es ist :-)).
+
+Achte darauf, dass die Toedlichkeit Deines Gebiets sich mit Deiner Umgebung
+vertraegt. Ueber-Schwere-Mega-Monster sollten von kleinen Spielern nicht
+problemlos erreicht werden koennen. Benutze nicht ganz so toedliche
+'Block-Monster', welche den Zugang versperren. So muss ein Spieler erst
+seine Wuerdigkeit beweisen, bevor er an die harten Monster kommt. Tigonen im
+Glockenwald sind KEINE gute Idee.
+
+Viele Magier finden es lustig, Spieler in ihren Gebieten durch Fallen
+sterben zu lassen. Das sind z.B. Knoepfe, die man drueckt, und die dann sofort
+this_player()->die() aufrufen. Nachdem vor einiger Zeit die Todesfolgen
+verschaerft wurden, sind derartige Fallen nicht mehr gern gesehen. Vermeide
+sie wenn moeglich. Spieler machen jeden Muell, aber lass sie nicht dafuer
+sterben, wenn Du es anders regeln kannst. Jede Todesfalle ist dem RM
+aufzuzueigen.
+
+Die Objekte: dazu gehoeren auch Waffen und Ruestungen, sowie alle anderen
+schraengen Dinge, die Dir noch so einfallen werden. Bevor Du Dir Deine
+erste Mega-Super-Alles-Kaputtschlag-Axt oder den Alle-Schaeden-Abwehr-Panzer
+zusammenbastelst, setz Dich hin, atme ruhig durch und tipp dann 'man balance'.
+Dort stehen alle wichtigen Eckdaten, die Du befolgen solltest. Und denk daran,
+nicht zuviele exklusiven Waffen und/oder Ruestungen in einem einigen Gebiet.
+Wenn Du grosse Objekte schreibst, ist hier auch wieder ein kleiner Kommentar
+im File sehr hilfreich fuer den RM. Denk daran, Du bist vielleicht irgendwann
+einmal nicht mehr erreichbar und dann ist es gut, wenn im File geschrieben
+steht, was das Programm ungefaehr macht.
+
+Jetzt kommen wir zu ein paar haeufigen Problemen:
+Erzeugst Du ein Objekt, das in einen Spieler geschoben wird, musst Du 
+unbedingt den Return-Wert abfragen, ob der Spieler das noch tragen kann:
+Ein Beispiel: Eine eigene Funktion 'nehmen'.
+In das create() vom Raum kommt:
+AddCmd(({"nimm","nehm","nehme"}),"nehmen");
+
+Die Funktion 'nehmen' erzeugt eine Zigarre. Sie prueft, ob einen Zigarre
+schon im Raum liegt, dann nimmt der Spieler diese. Falls keine Zigarre
+rumliegt, wird eine neue erzeugt und in den Spieler geschoben. 
+Damit ein Spieler nicht hunderte Zigarren erzeugen kann, wurde eine
+globale Variable 'int zaehler; zaehler=5; oben im create() vom Raum erstellt. 
+Nach einem Raumreset steht der Zaehler wieder auf 5, wenn man das in der
+reset() Funktion (siehe unten) definiert.
+
+nehmen(string str)
+{
+  object ob;
+
+   notify_fail("Was moechtest Du nehmen?\n");
+   if(!str) return 0;
+   if(str=="zigarre") {
+   if(present("zigarre",this_object())) return 0; 
+   // so wird die Zigarre IM Raum genommen
+
+     if (zaehler) {   
+       write(BS("Du nimmst eine Zigarre aus dem Fach."));
+       say(TPN+" nimmt eine Zigarre aus einem Fach.\n",this_player());
+       // TPN: siehe oben, Abschnitt 'Defines'
+       ob=clone_object(OBJ("zigarre"));
+       if (ob->move(this_player(),M_GET) !=1) {
+       // dieses '!=1' faengt ME_TOO_HEAVY, ME_TOO_MANY_OBJECTS, 
+       // und ME_CANT_BE_INSERTED ab
+
+           write("Du kannst die Zigarre nicht mehr tragen. Sie faellt zu "+
+           "Boden.\n");
+           ob->move(environment(TP),M_PUT);
+           }
+         zaehler--;
+         return 1;
+         }
+     write(BS("So ein Pech. Jemand hat die besten Stuecke bereits genommen."));
+     return 1;
+     }
+  // und damit man auch andere Sachen als Zigarren im Raum nehmen kann:
+  return 0;
+  
+}
+
+reset()
+{
+    ::reset();
+    // nach 30-45 min kann man wieder 5 neue Zigarren nehmen
+    zaehler=5;
+}
+
+Die NPCs. Es gibt (noch) keine Vorschrift, wie stark maximal NPCs sein duerfen,
+aber schau Dir trotzdem 'man balance' zu diesem Thema an.
+NPCs werden oft schmerzlich von ihren Magiern vernachlaessigt. Oft
+steht der grosse Drache auf dem Speicher, kann Dich in einem Schlag umhaun,
+weiss aber nicht einmal seinen Namen und besitzt nicht ein Detail. Kuemmer
+Dich um Deine NPCs. Gib ihnen eine schoene Beschreibung, lass sie etwas
+ueber sich erzaehlen, gib ihnen Details, gib ihnen Kleidung.
+
+Oft will man NPCs durch Gebiete laufen lassen, so dass sie mal Land und
+Leute kennenlernen. Das ist etwas rechnerlastig, und auch wenn wir jetzt
+jede Menge Power unter der Haube haben, sollte man einige Dinge beachten:
+* Es gibt einige sehr schoene Standard-Lauf-NPCs. Es bietet sich an, diese
+  zu benutzen. Sie haben alle noetigen Eigenschaften, unter anderem, dass sie 
+  stehen bleiben, wenn sie keine Spieler mehr antreffen. Das spart 
+  Performance. Ausserdem werden sie oft von einem Master gesteuert, und das 
+  spart call_outs.
+* Aufwendig ist besonders das Bewegen von NPCs. Rennende NPCs sind doch
+  oede. Lass sie sich langsam bewegen. Jedes schoene Gespraech mit einem NPC 
+  geht in die Hose, wenn der NPC staendig vor einem weglaeuft.
+
+Denke generell daran, uebersichtlich zu programmieren. Benutze nicht
+mehr als 78 Zeichen pro Zeile, fuege ruhig Leerzeilen ein, um die Struktur
+zu unterstreichen. Ruecke in Schleifen den Code ein paar (z.B. 3) Zeichen
+ein. Kommentare machen Deinen RM gluecklich! Wenn Du einst vielleicht nicht
+mehr da bist, wird irgend jemand Deinen Code warten muessen. Denk an den
+armen Kerl! Fuege bei Deinen Objekten einen Hinweis darauf ein, wovon und
+wofuer sie benutzt werden! Wenn Du die Wahl hast, Code in einer
+fuerchterlich effizienten, aber unuebersichtlichen Weise zu schreiben, oder
+etwas weniger effizient, aber intuitiv und einleuchtend, nimm die
+einleuchtende Weise. 
+
+Zaubertraenke, Gildenobjekte, Gildenquests
+
+Zaubertraenke
+
+Zaubertraenke sind wichtig, und obwohl es sie schon an vielen Stellen im MG
+gibt, sind sie immer noch gefragt. Man sollte beim Einbauen von ZTs daran
+denken, sie nicht tief in Quest-Gebieten zu verstecken, so dass ein Spieler
+keine Quest nochmal spielen muss, nur um den ZT zu bekommen. Ausserdem
+sollten sie nicht zu schwer versteckt werden. Ein Zaubertrank in einem Buch
+bekommt man z.B. durch:
+
+create() {
+...
+AddReadDetail("buch","@@det_buch@@");
+}
+
+string det_buch() 
+{
+ if (this_player()->FindPotion("Du findest Macht in diesem Buch...\n")) 
+   return "";
+ else
+   return "Du findest keine Macht in diesem Buch. Wie schade...\n";
+}
+
+Denke daran, auch einen Vers zu schreiben, welcher im Orakel den Tip fuer
+diesen ZT darstellt. Du kennst diese Verse sicher schon zur Genuege :-).
+Du musst den Zaubertrank spaeter zusammen mit den Forscherpunkten anmelden.
+
+Gilden- und Miniquests.
+
+Gildenquests sind kleine Aufgaben, nicht gross genug fuer richtige Quests,
+welche von den Mitgliedern einer Gilde geloest werden muessen, bevor sie
+aufsteigen koennen. Die Dinger sind voll im Kommen. Zauberer-, Kaempfer-
+oder Chaos-Gildenmagier sind immer hinter denen her. Quests wie 'Finde das
+verschollene Buch' oder 'Befreie den Verurteilten' lassen sich oft ohne
+grossen Aufwand in Gebiete einbauen. Sie garantieren auch eine gewisse
+permanente Besucherzahl im Gebiet :-)). Bevor man diese Quests einbaut,
+sollte man das prinzipielle OK der Gildenmagier holen, nachher muss man
+ihnen die Quest vorstellen, damit sie sie bewerten und freigeben.
+
+Will man eine kleine Aufgabe nicht gildenabhaengig, sondern fuer alle
+Spieler einbauen und dafuer Stufenpunkte vergeben, dann kann man die Aufgabe
+auch als Miniquest eintragen lassen, und zwar beim gleichen EM, der auch die
+FPs eintraegt. Es folgen Code-Beispiele fuer die Vergabe der Quests...
+
+int befreie(string wen) 
+{
+  notify_fail("Wen moechtest Du befreien?\n");
+  if (wer != "gefangener") 
+    return 0;
+  
+  // Hier werden die Stufenpunkte fuer die Miniquest vergeben...
+  // Falls man keine Miniquest angemeldet hat, laesst man das natuerlich weg
+  SCOREMASTER->GiveMiniQuest(this_player());
+
+  // Hier sind die Kaempfer. Der Code kann variieren...
+  call_other("/p/kaempfer/std/k_master","SetzeAufgabe",getuid(this_player()),
+    "Befreie den Gefangenen");
+
+  // Letztes Beispiel: Hier sind die Zauberer:
+  call_other("/p/zauberer/npc/test","GiveQuest",this_player(),
+    "Befreie den Gefangenen");
+  ...
+}
+
+Gildenobjekte
+
+Gildenobjekte wirken noch besser als Gildenquesten, um Spieler in Gebiete zu
+locken :-). Dies sollte jedoch kein Anlass sein, ein Gebiet mit derartigen
+Dingen zu ueberladen aber dafuer die Details und die Atmosphaere zu
+vergessen. Ganz generell gilt: Maessige Dich! Weniger ist mehr!
+
+Ganz generell sind Gildenobjekte z.B. Utensilien der Zauberer, Waffen mit
+Kaempfer-Boni fuer Kaempfer oder Kreiden etc. fuer Chaoten. Diese Objekte
+muessen natuerlich von den Gildenmagiern genehmigt werden, bevor das Gebiet
+angeschlossen wird. Sprecht frueh genug mit den Gildenmagiern. Sie werden
+euch sicher genug Beispiele fuer derartige Objekte geben, weshalb hier auf
+derartiges verzichtet wird.
+
+-------------------------------------------------------------
+P H A S E 2
+-------------------------------------------------------------
+Du hast nun alle Raeume/Objekte/NPCs erstellt. Nun geht es in die Testphase.
+Erzeuge Dir einen Testspieler, damit Du Deine Raummeldungen wie z.B. mittels
+tell_room() auf ihre Richtigkeit ueberpruefen kannst. Schau Dir in Ruhe
+Deine Sachen an und versuche, die unsinnigsten Sachen darin zu tun. Das werden
+die Spieler naemlich nachher auch machen. Ist Deiner Meinung nach alles OK,
+schreib eine Email an Deine zustaendigen RMs. Sehr hilfreich (fuer die RMs)
+waere eine zusaetzliche Liste (siehe auch Phase 4) mit:
+
+1) allen NPCs (welche Objekte tragen sie) und allfaellige Sonderfunktionen
+   ganz kurz erlaeutert.
+2) Eine Liste aller Objekte. Bei komplizierten Objekten eine kurze Beschreibung
+3) Eine Liste, in welchem Raum liegt welches Objekt/ZT/Heilstelle/NPC
+
+Diese Liste kannst Du natuerlich in Dein /doc Verzeichnis legen, was dann auch
+spaeter sehr hilfreich sein kann.
+
+Falls sich Deine RMs nicht melden, sprich sie an, mail ihnen nochmal.
+Vielleicht haben sie Deine Mail vergessen. RMs sind prinzipiell vergesslich.
+Sie unterhalten sich jedoch sicherlich gern mit Dir. Keine falsche
+Bescheidenheit, ran an den Feind.
+
+- Testspieler -   oder   - Zwischen Legalitaet und Wahnsinn -
+
+Kaum ein Magier kann die merkwuerdigen, oft widersinnigen und kranken
+Gedankengaenge eines Spielers nachvollziehen. Deshalb ist es eine gute
+Sache, sein Gebiet von Spielern testen zu lassen. Sie koennen die Staerke
+der NPCs gut einschaetzen und korrigieren, kennen die geheimen Kniffe der
+Gilden und machen generell das, woran man nie gedacht hat.
+
+Spielertesties sind so eine Sache. Als erstes muss man kompetente Spieler
+finden, welche bereit sind, das Gebiet zu testen. Dies ist nicht einfach,
+denn die wirklich guten Tester sind oft hoffnungslos ueberbelegt. Hat man
+einen willigen Spieler gefunden, kreiert man sich einen Testspieler, indem
+man einen neuen Spieler einloggt und im P_TESTPLAYER auf den eigenen Namen
+setzt. Das kannst Du z.B. so machen: 
+xcall testi->SetProp(P_TESTPLAYER,"<Magier>") wobei <Magier> Dein Name ist.
+
+Danach darf man ihn wild in Gilden eintreten lassen, ihm seine 
+Werte setzen und ihm Ausruestung clonen. Es gibt einige schoene
+Testspieler-Tools, mit denen sich Testies Ruestungen setzen und sich heilen
+koennen.
+
+Hat man Spieler und Testspieler, so kommt man an die legalen Probleme. Alles
+wichtige erfaehrt man durch 'hilfe testspieler'. Dort steht, dass
+Testspieler bei Erzmagiern angemeldet werden muessen, welche sie dann in ein
+Ueberwachungstool eintragen, so dass seine Handlungen geloggt werden. 
+Tatsache ist, dass sich aber kaum einer seine Testspieler bei einem
+Erzmagier anmeldet und die meisten EMs das selbst nicht tun. (Testies neuer
+Gilden moegen hier eine Ausnahme bilden).
+
+Generell beachte folgendes: Mach keine Spieler zu Testspielern, denen Du nicht
+traust oder die Du nicht kennst. Wenn ein Spieler mit seinen Tools durchs MG
+laeuft und Unsinn anstellt, bist Du mit Schuld, egal ob der Testie
+angemeldet ist oder nicht. Wenn Du einen Spieler durch ein Gebiet laufen
+laesst, bevor die FPs eingetragen wurden, dann ist das nicht legal, aber es
+wird keiner meckern, wenn Du ihn ueberwachst und somit aufpasst, dass er
+keinen Unsinn ausserhalb des Gebiets anstellt. Wenn Du einen Spieler durch
+ein Gebiet mit FPs laufen laesst und der Spieler die von ihm gefundenen FPs
+bekommen will, so musst Du ihn bei einem Erzmagier anmelden, denn FPs kann
+nur ein Erzmagier setzen.
+
+Oh, und schreibe Dir die Namen und Passwoerter Deiner Testspieler auf. Falls
+man mehrere hat, vergisst man verflucht schnell die Namen :-).
+
+-------------------------------------------------------------
+P H A S E 3
+-------------------------------------------------------------
+Die RMs schauen alle Files an, die Du erzeugt hast. Danach werden sie Dir
+eine Liste zurueckschicken mit allen Problemfaellen, die sie gefunden haben.
+Je nach Umfang Deines Gebietes kann das natuerlich etwas dauern.
+Hast Du die Informationen zurueckbekommen, kannst Du Dich an den Feinschliff
+machen. In der Zwischenzeit solltest Du Phase 4 und Phase 5 erledigen.
+
+-------------------------------------------------------------
+P H A S E 4
+-------------------------------------------------------------
+Falls Du Objekte hast, die genehmigungspflichtig sind (man balance), so musst
+Du einen Antrag an das Balanceteam stellen. In der Zwischenzeit sollte Dein
+Magierlevel so hoch sein, dass Du den Befehl 'goto' benutzen kannst. Es
+gibt einen Extra Raum fuer die Balanceantraege: 
+goto /players/paracelsus/office
+Dort gibt es dann eine gute Hilfeseite.
+Wichtiges zum Antrag: mach bitte nicht fuer jedes Objekt einen eigenen
+Antrag, sondern schreibe Dir einen grossen Antrag, in den alle Deine
+Objekte reinkommen, die der Balance vorgelegt werden muessen (siehe Phase 2:
+aus der Liste, die Du erstellt hast). Dazu solltest Du jedes Objekt kurz 
+beschreiben. Dazu kommen die wichtigsten Werte, bei Waffen z.B. Waffenart, 
+P_WC, P_NR_HANDS, P_DAM_TYPE, P_WEIGHT, und eine kurze Beschreibung der 
+Sonderfunktionen.
+Das Bewilligen Deiner Objekte kann eine ziemlich lange Zeit in Anspruch
+nehmen (Wochen). Hier nicht ungeduldig sein. Das dauert seine Zeit.
+Wenn Du Objekte proggst, die bestimmt durch die Balance muessen, gib doch
+Deinem RM fruehzeitig Bescheid, dass er sich das anguckt. Dann kannst Du 
+die Sachen bereits beantragen, und in der Zeit, bis die Antraege 
+bewilligt wurden, die anderen Dinge proggen. Dieser Ansatz gilt aber eher
+fuer Magier, die bereits etwas angeschlossen haben und neue Gebiete 
+erstellen. Fuer den Neuling ist es empfehlenswerter, alles fertigzumachen
+und dann zu beantragen. Grund: siehe oben: So kannst Du vorweisen, dass Du
+Dir Muehe gegeben hast, tolle Sachen auf die Beine zu stellen, und nicht
+einfach einen NPC in die Welt stellen willst, mit hunderten toller Objekte.
+
+-------------------------------------------------------------
+P H A S E 5
+-------------------------------------------------------------
+Gleichzeitig solltest Du die Forscherpunkte beantragen. Welcher Erzmagier
+dafuer zustaendig ist, findest Du mit 'man erzmagier' heraus. Die 
+Faustregel lautet: etwa 1 FP pro 10 Raeume. Vermeide FP fuer Details, damit
+die 'Untersuche-Skripte' keine Chance haben. Geh lieber so vor: 
+Detail: 'gras' -> 'Du wuerdest Dich am liebsten ins Gras legen.'
+Wenn der Spieler dann eintippt 'lieg ins gras' oder so aehnlich, gib dafuer
+den FP, aber nicht fuers Untersuchen vom Gras.
+Wofuer Du alles Forscherpunkte eintragen kannst, erfaehrst Du durch
+'hilfe forscherpunkte'.
+Mache ein paar Vorschlaege, und schick sie dann dem zustaendigen Erzmagier.
+Der wird aus Deinen Vorschlaegen ein paar rauspicken und anschliessen.
+Aber bevor Du das tust, muss Dein Gebiet zwingend schon im Regionsverzeichnis 
+liegen, damit keine FPs aus /players eingetragen werden.
+
+Gleichzeit mit den FPs meldest Du auch MiniQuests und Zaubertraenke
+bei diesem Erzmagier an. Du musst angeben, wieviele Stufenpunkte die
+Miniquest bringen soll und in welche der 3 Kategorien einfach/mittel/schwer
+Deine Zaubertraenke fallen.
+
+Denke daran, spaetestens jetzt die Gildenquests und Gildenobjekte bei den
+Gildenmagiern anzumelden. Unangemeldetes darf nicht angeschlossen werden.
+Wende Dich also frueh genug an diese Leute.
+
+-------------------------------------------------------------
+P H A S E 6
+-------------------------------------------------------------
+Ist alles von der Balance genehmigt worden, und sind die FP angeschlossen,
+solltest Du Deine RMs informieren. Falls Dein Gebiet immer noch im
+Heimverzeichnis liegt, wird es nun in dein Regionsverzeichnis
+verschoben. Du stehst nun kurz vor dem Anschliessen. Ueberleg Dir doch
+schon eine nette Botschaft, die Du dann in der MPA veroeffentlichen wirst.
+
+-------------------------------------------------------------
+P H A S E 7
+-------------------------------------------------------------
+GRATULATION! Du hast es geschafft! Aber jetzt nicht auf den Lohrbeeren
+ausruhen. Die ersten Spieler werden sich einfinden, und viele sind
+wandelnde Konversationslexikons, die auch den kleinsten Grammatikfehler 
+in Deinen Beschreibungen finden. Andere Spieler werden Dir neue Vorschlaege
+fuer commands zusenden, die in die entsprechenden Raeume passen wuerden.
+In /log/report/<magiername>.rep wird automatisch Dein Report-File erzeugt,
+in das die Spieler die gefundenen Typos, Bugs und sonstige Ideen reinschreiben.
+Schau Dir Dein Repfile an, und arbeite es ab so gut es geht.
+Nur so wird das Gebiet zu einem wirklich 'gepflegten' Gebiet.
+Denke daran, das rep-File nach dem Abarbeiten zu loeschen, sonst wird
+es zu voll.
+
+
+SIEHE AUCH:
+    balance, hilfe magier, /doc/wiz/
+
+----------------------------------------------------------------------------
+Last modified: 16:00 2003-02-22 by Humni
diff --git a/doc/wiz/licht b/doc/wiz/licht
new file mode 100644
index 0000000..d995a23
--- /dev/null
+++ b/doc/wiz/licht
@@ -0,0 +1,34 @@
+Eine Zusammenfassung aller Lichtproperties (fuer genaueres siehe manpages)
+
+P_LIGHT              - gibt an wie stark eine Lichtquelle selbst leuchtet.
+
+P_TOTAL_LIGHT        - gibt das Lichtlevel an, das von einem Objekt ausgeht,
+                       dieses kann != P_LIGHT sein, z.B. weil eine Fackel in
+                       einem Paket liegt.
+
+P_INT_LIGHT          - Lichtlevel in einem Objekt, z.B. ein Raum
+                       gibt an wie gut dieses Objekt ausgeleuchtet ist.
+
+P_PLAYER_LIGHT       - gibt an mit welchem Lichtlevel der Spieler gerade sieht
+
+P_LIGHT_MODIFIER     - veraendert den Lichtlevel der von einem Spieler
+                       wahrgenommen wird, z.B. eine Sonnenbrille
+
+P_LIGHT_ABSORPTION   - Wieviel Licht wird vom Raum geschluckt? wirkt sich
+                       direkt auf P_INT_LIGHT des Raumes aus. Andere Spieler
+                       profitieren von den Lichtquellen ihrer Mitspieler
+                       weniger bei hoeheren Werten. Default: 1.
+
+P_LIGHT_TRANSPARENCY - Wieviel Licht schluckt ein Container und wieviel
+                       Licht dringt nach aussen. Defaulttransparenz: 2
+
+Hinweis: Alle Objekte mit Lichtlevel <0 und >2 sowie alle Objekte, die
+         P_LIGHT_MODIFIER oder Closures setzen sind genehmigungspflichtig!
+         Dafuer sind die Regionsmagier zustaendig.
+
+
+SIEHE AUCH: P_LIGHT
+
+------------------------------------------------------------------------------
+ LETZTE AeNDERUNG:
+    2002-11-21, 17.30 von Zook
diff --git a/doc/wiz/lupe b/doc/wiz/lupe
new file mode 100644
index 0000000..28e23fe
--- /dev/null
+++ b/doc/wiz/lupe
@@ -0,0 +1,209 @@
+ALLGEMEINES:
+	Die Lupe benutzt einen Stapel (Stack), um Objekte zu bearbeiten.
+	Einige Befehle schieben Objekte auf den Stapel, andere wiederum
+	holen sie wieder vom Stapel herunter und benutzen sie fuer die
+	verschiedensten Zwecke.
+	Man kann in einer Zeile mehrere Kommandos gleichzeitig angeben
+	(durch Leerzeichen getrennt).
+	Eine Zeile wird immer von links nach rechts abgearbeitet.
+
+SCHREIBWEISEN:
+	<arg>	- Eine Reihe von Zeichen, die weder Leerzeichen noch Punkte
+		  (.) enthaelt. Falls doch Leerzeichen oder Punkte in <arg>
+		  auftauchen, muss man die Zeichenkette zwischen "...",
+		  '...' oder |...| einschliessen.
+	<nr>	- Eine (positive oder negative) ganze Zahl.
+	<filename> - Ein Dateiname. Fuer ihn gilt das Gleiche wie fuer <arg>:
+		  Wenn er Punkte enthaelt, muss man ihn zwischen "...",
+		  '...' oder |...| einschliessen.
+		  Es sind alle Variationen moeglich, die man auch aus der
+		  Magiershell kennt: absolute Dateinamen (beginnen mit "/"),
+		  Dateinamen relativ zum eigenen Homeverzeichnis ("~/")
+		  oder zum Homeverzeichnis eines anderen Magiers ("~name/"),
+		  Dateinamen in einer Region ("+region/") und Dateinamen
+		  relativ zum aktuellen Verzeichnis (alles andere ;).
+	<func>	- Name einer LPC-Funktion.
+	TOS	- Das Objekt ganz oben auf dem Stapel (Top Of Stack).
+
+DER STAPEL:
+	Bei dem Stapel handelt es sich um einen LIFO-Stapel (Last In - First
+	Out), d.h. das Objekt, das zuletzt auf den Stapel geschoben wurde,
+	wird als erstes bearbeitet.
+	Bei der Bearbeitung wird der TOS in der Regel vom Stapel entfernt
+	(Ausnahmen: =, stk und #), der Stapel wird also im Laufe der Zeit
+	wieder kleiner.
+	Der Stapel kann maximal zehn Elemente aufnehmen. Dieses Limit wird
+	man bei "normalem Betrieb" allerdings selten erreichen.
+	Sollte es trotzdem einmal eng werden, stehen einem noch zehn
+	Variablen zur Verfuegung, in denen man zusaetzlich Objekte (vom
+	Stapel) ablegen kann.
+
+BEFEHLE:
+	Es gibt drei unterschiedliche Befehlsgruppen:
+	a) Befehle, die ein Objekt auf den Stapel schieben;
+	b) Befehle, die mit Objekten auf dem Stapel arbeiten;
+	c) Befehle, die ohne den Stapel auskommen.
+	Einige Befehle setzen voraus, das der TOS ein Lebewesen oder gar ein
+	Spielerobjekt ist; andere Befehle sind erst ab einem bestimmten
+	Magierlevel zugaenglich. Dies ist bei den entsprechenden Befehlen
+	jeweils vermerkt.
+
+    Diese Befehle schieben ein neues Objekt auf den Stapel:
+	creat <filename> Macht das Gleiche wie 'new', das Objekt wird aller-
+			dings nicht in Dein Inventory gesteckt.
+	here		Das Objekt, in dem man gerade steht, auf den Stapel
+			schieben.
+	lv <arg>	Schiebt das Lebewesen mit dem living_name <arg> auf
+			den Stapel. ACHTUNG! Das muss dann nicht unbedingt
+			das Lebewesen sein, das man dort eigentlich haben
+			will! Es wird einfach das erste Objekt genommen,
+			dessen living_name passt! Wenn man etwas mit einem
+			NPC vorhat, der im gleichen Raum steht, spricht man
+			ihn besser mit here.name an.
+	me		Sich selbst auf den Stapel schieben.
+	new <filename>	Cloned das mit <filename> angegebene Objekt und
+			schiebt es auf den Stapel. Anschliessend befindet es
+			sich in Deinem Inventory.
+	ob <filename>	Laedt das Objekt, das mit <filename> angegeben ist,
+			und schiebt es auf den Stapel.
+	pl <arg>	Schiebt das Spielerobjekt mit dem Namen <arg> auf den
+			Stapel.
+			Es werden auch netztote Spieler berucksichtigt.
+	push <filename> Schiebt das Objekt, das mit <filename> angegeben ist,
+			auf den Stapel.
+	<filename>	Macht das gleiche wie 'ob', falls <filename> mit "/"
+			oder "~" beginnt.
+
+    Die naechsten Befehle schalten Optionen der Lupe an/aus/um:
+	desc		Die zusaetzliche Angabe der Kurzbeschreibung des
+			aktuellen Objektes wird unterdrueckt.
+	rec		Schaltet in den "rekursiv"-Modus um. Dieser Modus
+			wird von folgenden Befehlen genutzt:
+			'inv', 'cln' und 'clnof'
+			Nach Ausfuehrung eines dieser Befehle wird der
+			"rekursiv"-Modus automatisch wieder abgestellt.
+	norec		Stellt den "rekursiv"-Modus "von Hand" ab.
+
+    Diese Befehle schieben ebenfalls ein neues Objekt auf den Stapel. Sie
+    arbeiten dabei allerdings relativ zum TOS. Man muss also schon mindestens
+    ein Objekt auf den Stapel geschoben haben. Der alte TOS wird dabei in der
+    Regel entfernt.
+	.<nr>		Schiebt das <nr>te Objekt im Inventory des TOS auf den
+			Stapel.
+	.<arg>		Schiebt das Objekt mit der ID <arg> im Inventory des
+			TOS auf den Stapel.
+	<<nr>		Schiebt die Variable <nr> auf den Stapel. Als <nr>
+			sind Werte zwischen 0 und 9 moeglich.
+	@<nr>		Schiebt das <nr>te Objekt von oben noch einmal auf den
+			Stapel. Der alte TOS hat die Nummer 0. Weder der alte
+			TOS noch das verschobene Objekt werden vom Stapel ent-
+			fernt.
+			@1 ist analog zu 'over'.
+	copy		Legt eine Kopie des TOS an (inkl. aller Propertywerte)
+			und schiebt diese Kopie auf den Stapel. Die Kopie
+			befindet sich danach in Deinem Inventory.
+	dup		Schiebt den TOS doppelt auf den Stapel.
+	env		Schiebt das Objekt, in dem sich der TOS befindet, auf
+			den Stapel.
+	over		Schiebt das Objekt, das sich unter dem TOS befindet,
+			nochmal auf den Stapel. Dabei werden weder der alte
+			TOS noch das Objekt unter ihm entfernt.
+	result		Wenn in einem Objekt eine Funktion aufgerufen wurde,
+			und diese Funktion wieder ein Objekt zurueckgegeben
+			hat, so wird dieses Objekt auf den Stapel geschoben.
+	swap		Tauscht TOS und das darunter liegende Element gegen-
+			einander aus.
+
+    Die naechsten Befehle arbeiten mit den auf dem Stapel liegenden Objekten.
+    Dabei werden die bearbeiteten Objekte in der Regel vom Stapel entfernt.
+	><nr>		Speichert den TOS in der Variablen <nr>. Als <nr>
+			sind Werte zwischen 0 und 9 moeglich.
+	=		Zeigt den TOS. Dieser bleibt dabei unveraendert.
+	#		Der Stack bleibt ueber das naechste Kommando hinaus
+			erhalten.
+	inv		Zeigt das Inventory des TOS. Der TOS bleibt dabei
+			unveraendert.
+	cln		Entfernt alle Objekte aus dem Inventory des TOS. Es
+			werden allerdings keine Spieler entfernt.
+	clnof <arg>	Entfernt alle Objekte, die auf die ID <arg> anspre-
+			chen, aus dem Inventar des TOS.
+	clr		Loescht den gesamten Stack.
+	Dest		Der TOS wird zerstoert. Das geht allerdings NICHT,
+			wenn der TOS ein Spielerobjekt oder die Lupe selbst
+			ist.
+	dest		Wie Dest, allerdings wird zuerst TOS->remove() auf-
+			gerufen, um dem TOS die Moeglichkeit zu geben, noch
+			hinter sich aufzuraeumen.
+	dinfo		Gibt einige GameDriver-interne Informationen wie zB.
+			die Zeit des naechsten reset()-Aufrufs oder die an-
+			gesammelte evalcost des TOS aus.
+	disco		Unterbricht die Verbindug des TOS (muss ein aktiver
+			Spieler sein) zum MG (disconnect).
+	hl		Zeigt die Historyliste des TOS an (hierbei muss es
+			sich um einen Spieler handeln).
+			Dieser Befehl steht ab ELDER_LVL (50) zur Verfuegung.
+			!!!Fuer die Benutzung gilt das Gleiche wie fuer das
+			Snoopen!!!
+	idle		Gibt an, wie lange der TOS schon idlet. (Der TOS
+			sollte dabei natuerlich ein Spieler sein).
+	info		Gibt einige Informationen ueber den TOS aus.
+	inherit_list	Gibt den Vererbungsbaum des TOS aus (allerdings nicht
+			sehr baumfoermig ;)
+	inv		Zeigt das Inventory des TOS an.
+
+	make		Fuehrt ein Update des TOS durch. Geht nicht bei
+			Spielern! Dafuer gibt es renew.
+	minfo		Gibt einige Informationen ueber den Speicherverbrauch
+			des TOS aus.
+	move, mov, mo	Das Objekt, das unter dem TOS steht, wird in den TOS
+			gemoved. Beide Objekte werden dabei vom Stapel ent-
+			fernt.
+	_move, _mov, _mo, _mv
+			Das Objekt, das unter dem TOS steht, wird in den TOS
+			gemoved, ohne dass dort init() aufgerufen wird. Beide
+			Objekte werden dabei vom Stapel entfernt.
+			Dieser Befehl steht ab ARCH_LVL (60) zur Verfuegung.
+	pop		Entfernt den TOS.
+	renew		Aehnlich wie 'make', der TOS muss allerdings ein
+			Spieler sein. ACHTUNG! Man sollte nicht "einfach so"
+			Spieler 'renew'en, sondern nur dann, wenn es wirklich
+			gerechtfertigt ist!
+	scan, sc	Kombiniert 'stat' und finger. Der TOS muss ein Lebe-
+			wesen sein.
+	stat		Gibt Informationen ueber Zustand, Ausruestung, ge-
+			loeste Quests etc. des TOS aus. Der TOS muss dabei
+			ein Lebewesen sein.
+	stk		Zeigt den gesamten Stack. Dieser bleibt dabei unver-
+			aendert.
+	[<func>]	Ruft im TOS die Funktion <func> ohne Parameter auf.
+			Falls diese Funktion ein Objekt zurueckgibt, kann man
+			dieses anschliessend mit result auf den Stapel
+			schieben.
+	[<func> <arg1> ... <argn>]
+			Ruft im TOS die Funktion <func> mit den Parametern
+			<arg1> bis <argn> auf. Die Parameter sind mit Leer-
+			zeichen zu trennen. Enthalten die Parameter selbst
+			Leerzeichen, so sind sie in "...", '...' oder |...|
+			einzuschliessen.
+			Mittels @<nr> kann man auch Objekte, die sich auf dem
+			Stapel befinden, als Argumente angeben.
+
+    Die folgenden Befehle kommen ohne Objekte auf dem Stack aus:
+	call_out	Gibt eine Liste aller Objekte mit einem laufenden
+			call_out aus.
+	dump		Schreibt die Listen aller Objekte mit aktivem
+			heart_beat und aller Objekte mit laufendem call_out
+			in die Datai LISTS.LUPE in Dein Homeverzeichnis.
+	dumphists	Schreibt die Befehlshistory aller momentan einge-
+			loggten Spieler nach /log/ARCH/HD.
+			Dieser Befehl steht erst ab ARCH_LVL (60) zur
+			Verfuegung.
+	heart_beat	Gibt eine Liste aller Objekte mit aktivem heart_beat
+			aus.
+	rusage		Zeigt einige Infos ueber den Ressourcenge-/-verbrauch
+			des Muds an.
+	swho		Zeigt (so gut wie) alle aktiven Snoops.
+	vars		Zeigt die belegten Variablen an.
+
+----------------------------------------------------------------------------
+Last modified: Wed Jun 26 14:49:02 1996 by Wargon
\ No newline at end of file
diff --git a/doc/wiz/material b/doc/wiz/material
new file mode 100644
index 0000000..cbf8022
--- /dev/null
+++ b/doc/wiz/material
@@ -0,0 +1,98 @@
+Materialien
+===========
+
+     Materialien in Morgengrauen koennen ueber die Property P_MATERIAL jedem 
+     Objekt im Spiel zugeordnet werden. Ueber die Materialiendatenbank 
+     stehen dafuer jede Menge Materialien zur Verfuegung. Wenn moeglich, 
+     sollten diese auch benutzt werden, es werden Defaultmaterialien 
+     gesetzt, diese entsprechen aber selten eurer Realitaet.
+
+     Die Materialiendatenbank /secure/materialdb.c haelt saemtliche 
+     Informationen ueber die verwendbaren Materialien, die unter 
+     /sys/thing/material.h aufgefuehrt sind. Es empfiehlt sich SEHR, Verweise
+     auf die MatDB nur in Form von MATERIALDB zu formulieren.
+     Sie verwaltet auch die Eigenschaften einzelner Materialien. Es gibt 
+     diverse Materialiengruppen wie "entflammbar", "Metall", "biologisches 
+     Material", denen die Materialien entsprechend zugeordnet sind. Diese 
+     Informationen koennen mit entsprechenden Methoden abgerufen/ausgewertet 
+     werden.
+     Darueber hinaus sind Materialien bei der Erkennung mit anderen 
+     Materialien verwechselbar. Wie das genau funktioniert, ist in "man 
+     materialerkennung" ausgefuehrt.
+
+     P_MATERIAL:
+       Die Property P_MATERIAL ist grundsaetzlich ein Mapping, in dem zu 
+       jedem Material der Anteil an dem Objekt stehen sollte, Z.B. kann 
+       ein Speer zu 80% aus Holz und zu 20% aus Metall (Speerspitze) 
+       bestehen:
+
+	SetProp(P_MATERIAL, ([MAT_MISC_METAL:20,MAT_MISC_WOOD:80]))
+
+       (Zur Vereinfachung ist es erlaubt, bei SetProp ein einzelnes Material 
+        oder ein Array aus Materialien anzugeben, beides wird automatisch 
+        umgewandelt in ein Mapping mit gleichen Anteilen aller Materialien.)
+
+     Defaults für P_MATERIAL:
+	Waffen generell:	   ([MAT_MISC_METAL:100])
+	Schwerter:		   ([MAT_MISC_METAL:100])
+    	Messer:			   ([MAT_MISC_METAL:80, MAT_MISC_WOOD:20])
+	Aexte:			   ([MAT_MISC_METAL:50, MAT_MISC_WOOD:50])
+	Speere:			   ([MAT_MISC_METAL:20, MAT_MISC_WOOD:80])
+	Keulen:			   ([MAT_MISC_WOOD:100])
+	Ruestungen generell:	   ([MAT_LEATHER:100])
+	Koerperruestungen, Helme,
+	Ringe, Amulette, Schilde:  ([MAT_MISC_METAL:100])
+	Umhaenge, Hosen:	   ([MAT_CLOTH:100])
+	Handschuhe, Schuhe:	   ([MAT_LEATHER:100])
+	andere Dinge:		   ([MAT_MISC:100])
+
+      Uebersicht ueber die Methoden an Objekten (/std/thing/description):
+	int QueryMaterial(string mat):
+	- gibt % des Materialanteils von mat am Objekt zurueck
+	int QueryMaterialGroup(string grp):
+	- gibt % des Materialgruppenanteils von grp am Objekt zurueck
+	string MaterialList(int casus, mixed idinf):
+	- gibt String mit Zusammensetzung des Objektes zurueck
+
+      Uebersicht ueber die Methoden am Master (MATERIALDB):
+	string *GetMatMembership(string mat):
+	- alle Gruppen, in denen das Material mat ist
+	string *GetGroupMembers(string grp):
+	- alle Materialien, die in der Gruppe grp sind
+	string MaterialName(string mat, int casus, mixed idinf):
+	- ergibt die spielerlesbare Angabe eines Materials mat
+	string GroupName(string grp):
+	- ergibt spielerlesbare Angabe der Gruppe grp
+	string ConvMaterialList(mixed mats, int casus, mixed idinf):
+  	- wird von MaterialList() mit den Materialien des Objektes gerufen
+	void Dump():
+  	- schreibt Materialien und Gruppen in /p/daemon/save/MATERIALS
+	string *AllMaterials():
+	- Liste aller aktuellen Materialien
+	string *AllGroups():
+	- Liste aller aktuellen Gruppen
+
+      Falls euch ein Material fehlt:
+	- falls es kein genau passendes Material gibt, sollte man das am 
+	  ehesten passende MAT_MISC-Material verwenden.
+	- falls es sich lohnen wuerde, das bisher noch nicht definierte 
+	  Material einzubauen (wenn es haeufig genug verwendet wird), bitte 
+	  Mail an einen EM (-> man AddMaterial() )
+	- verschiedene Eigenschaften lassen sich kombinieren. Z.B. besteht 
+	  ein (unbekanntes) explosives Gas zu 100% aus Gas und zu 100% aus 
+	  explosivem Material. Insofern kann man es mit
+          SetProp(P_MATERIAL, ([MAT_MISC_GAS:100, MAT_MISC_EXPLOSIVE:100]))
+          zusammensetzen.
+
+SIEHE AUCH:
+     Konzepte:	  materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterial(), QueryMaterialGroup(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
diff --git a/doc/wiz/materialerkennung b/doc/wiz/materialerkennung
new file mode 100644
index 0000000..976106f
--- /dev/null
+++ b/doc/wiz/materialerkennung
@@ -0,0 +1,79 @@
+Materialerkennung
+=================
+
+     Bei MaterialName(mat,casus,idinf) und MaterialList(casus,idinf) id der 
+     Parameter <idinf> als Angabe dafuer gedacht, wie gut Materialien 
+     erkannt werden sollen. Es sind folgende Arten von Angaben moeglich:
+
+      - Ein Array
+	Die einzelnen Arrayelemente werden nach untenstehenden Regeln 
+	behandelt und deren Ergebnisse addiert.
+      - Ein Objekt
+	In diesem Fall wird
+	ob->QueryProp(P_MATERIAL_KNOWLEDGE)
+	nach untenstehenden Regeln behandelt.
+	Diese Property ist fuer rassenabhaengige Faehigkeiten gedacht.
+      - Eine Zahl
+	In diesem Fall wird der Wert direkt als Faehigkeit angesehen, das 
+	Material erkennen zu koennen.
+      - Eine Closure
+	In diesem Fall wird der Returnwert von
+	funcall(closure,material,gruppen_in_denen_diese_material_ist)
+	genommen.
+      - Ein Mapping
+	In einem Mapping sind 3 Arten von Eintraegen moeglich:
+	- Ist im Mapping unter <mat> eine Zahl eingetragen, wird diese 
+	  genommen und die weiteren Eintraege nicht weiter ausgewertet.
+        - Die Werte von allen Gruppen im Mapping, zu denen das Material
+          gehoert, werden addiert.
+        - Falls das Mapping einen Eintrag MATERIAL_SYMMETRIC_RECOGNIZABILITY 
+          hat, der ein Array von der 	  Form
+		({gruppe1, wert1, gruppe2, wert2, ...})
+	  ist, wird fuer jede dieser Gruppen der zugehoerige Wert 
+	  addiert, falls das Material in der Gruppe ist, und sonst 
+	  abgezogen.
+          Im Beispiel: ({MATGROUP_BIO: 5}) gibt einen Erkennbonus von 5% auf 
+          alle biologischen Materialien, aber einen Malus von -5% auf alle 
+          nichtbiologischen Materialien.
+
+     Schwer erkennbare Materialien haben in der Materialdatenbank eine 
+     zusaetzliche Angabe der Form
+	({mat1, wert2, mat3, wert4, mat5, ... wert(n-1), mat(n)})
+     wobei mat(n) das Material selber ist.
+
+     Das erkannte Material ist das Material mat(k), bei dem die
+	wert(k-1) <= Erkennungsfaehigkeit < wert(k+1)
+     ist. Bei Erkennungsfaehigkeit 100 oder mehr wird das Material auf jeden 
+     Fall erkannt.
+
+     Der Wert fuer Durchschnittsspieler ist 0.
+
+BEISPIEL:
+     Angenommen, bei Platin waere die Angabe in der Datenbank
+	({Metall, -20, Silber, 20, Platin})
+     Ein Spieler ohne besondere Erkennungsfaehigkeiten (also Wert 0) wuerde 
+     also Platin fuer Silber halten, jemand, der von Metallen keine Ahnung 
+     hat (beispielsweise mit der Angabe ([MATGROUP_METAL:-25]) in 
+     P_MATERIAL_KNOWLEDGE) sieht nur noch, dass es ein Metall ist und jemand 
+     mit ueberdurchschnittlicher Faehigkeit erkennt Platin als das, was es 
+     ist.
+
+     P_MATERIAL_KNOWLEDGE koennte z.B. fuer Rassen wie folgt gesetzt werden:
+	Elf:   ([MATGROUP_WOOD:30])
+	Zwerg: ([MATGROUP_STONE:30])
+     oder etwas komplexer
+	Zwerg: ([MATGROUP_STONE:30,
+		 MATERIAL_SYMMETRIC_RECOGNIZABILITY: ({MATGROUP_BIO: -5})])
+
+SIEHE AUCH:
+     Konzepte:	  material
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterial(), QueryMaterialGroup(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste, materialgruppen
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/wiz/materialgruppen b/doc/wiz/materialgruppen
new file mode 100644
index 0000000..5201bae
--- /dev/null
+++ b/doc/wiz/materialgruppen
@@ -0,0 +1,53 @@
+Materialgruppen
+===============
+
+  Die ebenfalls kommentierte Liste unter /sys/thing/material.h ist immer
+  aktueller als diese hier.
+
+  MATGROUP_SOLID          feste Dinge
+  MATGROUP_FLUID          Fluessigkeiten
+  MATGROUP_GAS            Gase
+
+  MATGROUP_WOOD           Hoelzer
+  MATGROUP_DECIDUOUS_WOOD Laubhoelzer
+  MATGROUP_CONIFER_WOOD   Nadelhoelzer
+  MATGROUP_TROPICAL_WOOD  Tropenhoelzer
+  MATGROUP_JEWEL          Edelsteine
+  MATGROUP_MINERAL        Mineralien
+  MATGROUP_STONE          Steine
+  MATGROUP_METAL          Metalle
+  MATGROUP_PRECIOUS_METAL Edelmetalle
+  MATGROUP_PAPER          Papier und Aehnliches
+  MATGROUP_CLOTH          Stoffe
+
+  MATGROUP_ELEMENTAL      (altertuemliche) Elemente
+  MATGROUP_BIO            Alles, was lebt oder lebte
+  MATGROUP_LIVING         Lebewesen
+  MATGROUP_HERBAL         Pflanzliches
+  MATGROUP_DEAD           Ueberreste von Lebewesen
+  MATGROUP_DRUG           Drogen, Heiltraenke
+
+  MATGROUP_INFLAMMABLE    Entflammbares
+  MATGROUP_EXPLOSIVE      Explosives
+  MATGROUP_POISONOUS      Giftiges
+  MATGROUP_MAGIC          Magisches
+  MATGROUP_RADIOACTIVE    Radioaktives
+  MATGROUP_ELECTRICAL     Elektrisches
+  MATGROUP_MAGNETIC       Magnetisches
+  MATGROUP_ACIDIC         Saures
+  MATGROUP_EATABLE        Essbares
+  MATGROUP_FLEXIBLE       Biegsames
+  MATGROUP_INVIS          Unsichtbares
+
+SIEHE AUCH:
+     Konzepte:	  material, materialerkennung
+     Grundlegend: P_MATERIAL, /sys/thing/material.h
+     Methoden:    QueryMaterial(), QueryMaterialGroup(), MaterialList(),
+     Listen:	  AllMaterials(), AllGroups(), Dump()
+		  materialliste
+     Master:	  AddMaterial(), ConvMaterialList(), MaterialGroup(),
+		  GroupName(), MaterialName(),
+		  GetGroupMembers(), GetMatMembership()
+     Sonstiges:	  P_MATERIAL_KNOWLEDGE
+
+7. Mai 2004 Gloinson
\ No newline at end of file
diff --git a/doc/wiz/mudlib-codestyle b/doc/wiz/mudlib-codestyle
new file mode 100644
index 0000000..77b4baa
--- /dev/null
+++ b/doc/wiz/mudlib-codestyle
@@ -0,0 +1,36 @@
+Wollt ihr Code in der allgemeinen, oeffentlichen Mudlib anschliessen, bitte
+beachtet die folgenden Hinweise zum Codestyle (nicht erschoepfend):
+
+* Einrueckungen per Leerzeichen, nicht Tabs
+* Einrueckung von 2 Leerzeichen pro Ebene
+* praegnante und viele Kommentare
+* keine lambdas
+* Bei inline-closures die function-Syntax statt der (: :)-Syntax verwenden.
+* else, else if in eine eigene Zeile
+* { am Beginn von Bloecken soll in eine eigene Zeile.
+* Nach ifs, Loops & Co: umfasst der davon kontrollierte Code mehr als eine
+  physische Zeile Code, einen Block mit { } formulieren.
+* keine return fun(), 0;
+* (type) Casts sollten vermieden werden (Ausnahme: (type)call_other).
+  (type) konvertieren nur, wenn die Typen zur Compilezeit bekannt und
+  unterschiedlich sind. Daher bei gewuenschten Konversionen to_type() nehmen.
+* Pfade, die absolut sind, sollen auch mit / beginnen, z.B. 
+  inherit "/std/thing", nicht inherit "std/thing"
+
+Benennung von Properties:
+* der interne Name von Properties in der Basis-Mudlib beginnt immer mit
+  "p_lib_". Niemand sonst sollte Properties mit diesem Praefix erstellen.
+
+Sonstiges:
+* In der Mudlib wird keine neue Funktion(alitaet) angeschlossen, bevor die
+  Dokumentation dafuer fertig ist.
+  Am liebsten ist mir, bei der Konzeptentwicklung zuerst die fertige
+  Dokumentation (Manpage) fuer Nutzer/Spieler zu entwickeln, bevor ein Magier
+  ueberhaupt eine Zeile Code schreibt.
+* Patches muessen eine Zusammenfassung haben, welche kurz erlaeutert,
+  was dieser Patch fixen/aendern/verbessern soll und auf welche Weise
+  diese umgesetzt wird. (Anders gesagt: eine Commit-Message)
+
+LETZTE AeNDERUNG:
+  15.8.2015, Zesstra
+
diff --git a/doc/wiz/muster_raum.c b/doc/wiz/muster_raum.c
new file mode 100644
index 0000000..74e4c99
--- /dev/null
+++ b/doc/wiz/muster_raum.c
@@ -0,0 +1,82 @@
+/*
+ *----------------------------------------------------------------------
+ * Ein kleiner Beispielraum.
+ * Er laesst sich als /obj/doc/muster_raum ansprechen.
+ *
+ * Dieses File ist Teil der MorgenGrauen-Mudlib von Jof und Rumata
+ * Letzte Aenderung: 17.08.92
+ * #include eingefuegt: Rumata 10.11.98
+ *----------------------------------------------------------------------
+ */
+#pragma strong_types,rtt_checks
+
+inherit "/std/room";
+	/* Diese Zeile deutet an, dass der Raum aus der Standard mudlib */
+	/* abgeleitet wird. Diese Zeile sollte in JEDEM Raum vorkommen. */
+
+#include <properties.h>
+	/* Diese Zeile definiert die grossbuchstabigen Namen, die in den */
+	/* SetProp-Befehlen benutzt werden. Es gibt noch weitere *.h     */
+	/* Dateien, die andere nuetzliche Dinge definieren.              */
+
+protected void create()
+{
+	::create();
+		/* Diese Zeile initialisiert die Standard-attribute. */
+		/* Sie darf nicht fehlen ! */
+
+	SetProp(P_INT_SHORT, "Muster-raum" );
+		/* Die Beschreibung des Raumes fuer Spieler, die den */
+		/* kurz/brief-Modus eingestellt haben. */
+
+	SetProp(P_INT_LONG, "Dieses ist ein Musterraum, der nur zur Erlaeuterung\n"
+		+ "dient. Ein unangenehmer Raum voller Sterne und schraeger\n"
+		+ "Striche. Im Sueden kannst Du in vertrautere Raeume fliehen.\n"
+		+ "Im Norden ist etwas seltsames.\n" );
+		/* Diese Beschreibung bekommen Spieler, die den kurz- */
+		/* Modus nicht benutzen, oder wenn sie "schau" eingeben. */
+
+	SetProp(P_LIGHT, 1 );
+		/* Diese Zahl ist 1 fuer Raeume, in denen man ohne */
+		/* Lichtquelle etwas sehen kann und 0 fuer Raeume, */
+		/* in denen man eine Solche braucht. */
+
+	AddExit( "sueden", "room/adv_guild" );
+		/* Baue einen Ausgang nach Sueden, er wird mittels des */
+		/* Kommandos "exits" angezeigt. */
+
+	AddSpecialExit( "norden", "go_nord" );
+		/* Wenn der Spieler versucht, diesen Ausgang zu */
+		/* benutzen, so wird er nicht in einen anderen Raum */
+		/* bewegt, sondern es wird im Raum die angegebene */
+		/* Funktion aufgerufen. */
+
+	AddCmd( "hilfe", "gib_hilfe" );
+		/* Dieses Kommando ruft die Funktion "gib_hilfe" auf, */
+		/* wenn der Spieler das Kommando "hilfe" eingibt. */
+		/* Das Kommando taucht nicht in der "exits-liste" auf. */
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ * So jetzt ist der Raum fetig.
+ * Wirklich? Nein, fast.
+ * Die oben angegebenen Funktion fehlen noch, aber das sind bereits
+ * "Extras".
+ *----------------------------------------------------------------------
+ */
+
+int go_nord()
+{
+	write( "Hmm das war wohl doch nur die Wand.\n" );
+	return 1;
+		/* Das Kommando wirde erfolgeich beendet. */
+}
+
+int gib_hilfe()
+{
+	write( "Gehe nach Sueden, und Du kommst in die Abenteurer-Gilde.\n" );
+	return 1;
+}
+
diff --git a/doc/wiz/nachteile b/doc/wiz/nachteile
new file mode 100644
index 0000000..d37e56f
--- /dev/null
+++ b/doc/wiz/nachteile
@@ -0,0 +1,51 @@
+----------------------------------------------------------------------------
+NACHTEILE
+----------------------------------------------------------------------------
+Bei der Genehmigung von Objekten im Balanceteam kommt immer wieder die Frage
+auf, welche Nachteile das Objekt denn hat, wenn es schon so viele Vorteile
+besitzt. Generell gilt, dass starke Objekte nur dann genehmigt werden, wenn
+sie auch ueber entsprechend grosse Nachteile verfuegen.
+
+Daher hier mal eine kleine Auflistung dessen, was als solcher betrachtet
+wird:
+
+- Gewicht (nicht bei Keulen fuer Kleriker)
+
+- Anfaelligkeiten gegen Schadenarten
+
+- LP-KP-Abzug (Obergrenzen, jede Runde, jeder Reset)
+- Absenken der Maxwerte von LP, KP
+- Absenken von Attributen
+- Absenken von SA_SPEED, SA_QUALITY usw.
+
+- Schaden/Nutzen abhaengig vom Alignment
+- Generelle Restriktionen
+
+- Objekt muss an einer bestimmten Stelle (z.B. durch das Toeten einen NPC)
+  aufgeladen werden
+- wiederkehrende Kosten (ausser LP/KP auch sowas wie Geld/Items/Aufgabe)
+
+- Behinderung anderer Objekte
+- Belegung von Slots (Set)
+
+- Skillobjekt
+
+- Begrenzte Haltbarkeit
+- Abnutzung (z.B. P_QUALITY, oder einfach durch Zeit/Nichtbenutzung)
+- Umstaende, die das Objekt zerstoeren
+- Begrenzte Wirkung (z.B. Waffe wirkt nur gegen eine Rasse)
+
+- Unique
+- Unique mit begrenzter Anzahl
+
+Generell sollten Paraobjekte die Restriktion Seher besitzen, da sie auch nur
+von Sehern geholt werden koennen. Aehnliche Restriktionen sollten fuer 
+Objekte aus Gebieten gelten, die erst ab einer gewissen Stufe betreten 
+werden koennen.
+
+Objekte, die nur in eng begrenzten Gebieten wirken (z.B. Questitems wie der 
+Spinnentoeter) muessen bei der Balance nicht beantragt werden, selbst wenn
+sie Werte besitzen, die die Balancegrenzen ueberschreiten.
+
+----------------------------------------------------------------------------
+Letzte Aenderung: 18.10.2005 - Miril
diff --git a/doc/wiz/netz b/doc/wiz/netz
new file mode 100644
index 0000000..2dd8cf4
--- /dev/null
+++ b/doc/wiz/netz
@@ -0,0 +1,27 @@
+Stand: 17.08.92
+Ueberarbeitet am 24.08.94 von Viper
+
+Die Netzphilosophie im MorgenGrauen
+-----------------------------------
+
+Die wichtigen Wege und Verbindungen in MorgenGrauen sollen eine Art
+Netzstruktur  besitzen, d.h. es wird nicht am Rand angebaut (wie im 
+alten NF), sondern mitten drin.
+
+Beispiel:
+
+Man stelle sich eine Strasse aus 6 Raeumen vor. Am Anfang verlaeuft
+die Strasse von Osten nach Westen ohne besondere Details am  Weges-
+rand. Mit der Zeit bauen einige Magier aus dieser Region  noerdlich
+und suedlich ihre Raeume und Quests an. Irgendwann jedoch sind alle 
+Raeume ausgeschoepft. Dann kann  der  Erzmagier der Region ZWISCHEN 
+die bestehenden Raeume der Strasse weitere Strassenraeume einfuegen. 
+Dort kann dann wieder Noerdlich und Suedlich angebaut werden. In den 
+neuen Strassenteilen  sollten natuerlich keine Monster oder Hinder-
+nisse aufgestellt werden, so dass die Strasse fuer die SpielerInnen 
+lediglich etwas laenger wird, dort aber keine neuen Probleme auf ihn
+/sie warten.
+
+Zusaetzliche Hindernisse sollten nur nach Absprache mit einem Erz-
+magier (das sind die Magier ab Level 60) in bestehende Strassen
+eingebaut werden.
diff --git a/doc/wiz/npcs b/doc/wiz/npcs
new file mode 100644
index 0000000..0242e4c
--- /dev/null
+++ b/doc/wiz/npcs
@@ -0,0 +1,121 @@
+ HINWEISE ZU NPCS:
+
+  a. Allgemeines / Hinweise / Tipps
+
+     Dies sind Richtlinien, keine Vorschriften!!!!
+
+     Nicht jeder NPC braucht einen living_name. Nur in besonderen NPCs
+     sollte man einen solchen setzen. Alles andere ist unsinnig und belastet
+     nur unnoetig den Speicher.
+
+     Ein Monster sollte niemals zu viel Zeug mit sich herumtragen. Ein bis
+     zwei Sachen reichen im Normalfall.
+
+     Niemals sollte ein Monster allein mit mehreren Top-Qualitaets-Sachen
+     (sehr gute Waffe plus gute Ruestung[en]) ausgestattet sein. Das waere
+     doch zu einfach.
+
+     Die Haerte der Monster ist im Prinzip egal; pflastert die Gebiete ruhig
+     mit Hydren.
+     Nur: Anfaengern oder kleineren Spielern zugaengliche Gebiete sollten
+     keine Autoattackmonster enthalten, die die "Kleinen" gleich umnieten.
+     Solche Gegenden sollten entweder mit Wachen bestueckt oder mit einigen
+     zunehmend haerteren Monstern einen "Vorgeschmack" bieten, damit man
+     nicht unbedarft reinrennt. Unfaelle wird's dennoch geben. Was soll's,
+     Rochus liebt seine Statistik... :)
+
+     Auch bei NPCs kann die Property P_INFO gesetzt werden, dies sollte
+     insbesondere bei starken und speziellen NPCs gemacht werden.
+
+     Bei NPCs, die besondere Spells benutzen, sollten die RMs darauf achten,
+     dass nicht ploetzlich die ganze Gegend von NPCs wimmelt, von denen
+     jeder seinen Gegner blind oder taub macht oder vergiftet.
+
+     Nur als Tipp:
+     Monster mit Attack-Chats sind erheblich kniffliger zu killen und machen
+     auch um ihrer Selbst willen mehr Spass als bloede Hau-Drauf-Monster,
+     die zwar ueber unendlich HP verfuegen, aber im Prinzip nur Geduld
+     brauchen, um sie zu besiegen. Phantasie ist gefragt.
+
+  b. Eigenschaften
+      Fuer einfache Monster bitte create_default_npc() benutzen!
+
+      Ansonsten:
+      P_HANDS
+	Bei Monstern ohne Waffen sollte die Property P_HANDS in allen drei
+	Werten dem Erscheinungsbild des Monsters entsprechen, also in Text,
+	Schadenshoehe und Schadensart.
+	Auch bei Monstern mit einer Waffe sollte P_HANDS vernuenftig gesetzt
+	werden, also nicht zu hoch. Darauf zu achten ist Aufgabe der RMs.
+
+      P_BODY
+	Monster sollten nicht ueber undurchdringliche Bodies verfuegen, weil
+	sie dann nur magisch zu schlachten sind. Bodies ueber 150 (oder
+	P_TOTAL_AC ueber 150 incl. Ruestungen!) sind kaum noch
+	"herkoemmlich" zu killen. Normale Monster, also nicht-magische, sind
+	eigentlich immer anfaellig gegen die physikalischen Schadenstypen.
+	Also bitte da keine P_RESISTANCE setzen.
+
+      P_RESISTANCE/P_VULBERABILITY/P_RESISTANCE_STRENGTHS
+      P_NOMAGIC
+	Die RESISTANCE der Monster sollte sich auf ein oder zwei
+	Schadenstypen begrenzen, und die sollten auch begruendbar sein. Ein
+	normales Wesen gegen BLUDGEON, SLASH oder PIERCE unempfindlich zu
+	machen ist unlogisch und sollte vermieden werden. Gleiches gilt fuer
+	Empfindlichkeiten.
+	Ebenso sollte es Gruende geben, warum ein Monster eine Magie
+	unwirksam macht.
+
+      P_XP
+	Der Toetungsbonus in XP, die der Killer erhaelt, betragen 1/100 des
+	Wertes, der in P_XP angegeben wird. Der Wert selbst sollte der
+	Haerte des Monsters angemessen sein, als Faustregel fuer
+	'gewoehnliche' NPCs gilt:
+
+	  P_XP = 5 * WC * MAX_HP
+
+	Die RMs sollten darauf achten, dass hier keine ueberhoehten Werte
+	gesetzt werden.
+
+	Fuer Attack-Spells und aehnlich fieses kann ein Bonus gegeben
+	werden. Fuer questrelevante NPCs oder "Informations-NPCs", die nicht
+	unbedingt als Metzelobjekte herumstehen, kann man auch die EP
+	senken, um sie fuer EP-Sammler uninteressant zu machen.
+
+      P_MURDER_MSG/P_KILL_MSG
+	Nicht jeder NPC braucht seine eigene Moerder- oder Killermeldung.
+	Bei normalen 	NPCs sollte man also darauf verzichten.
+
+      P_DIE_MSG/P_NOCORPSE
+	Wenn ein NPC ein wenig anders umfaellt als sonst, traegt das auch
+	zum Spiel bei.
+
+      P_GUARD
+	Wenn der NPC nichts bewacht und nicht uebermaessig stark ist, sollte
+	man ihn auch fortlocken koennen. Setzt P_GUARD entsprechend und
+	lasst den NPC mit AddItem und REFRESH_MOVE_HOME erzeugen.
+
+      AddClass
+	Wenn ihr euren NPC in den definierten Klassen einordnen koennt, dann
+	macht das bitte. Besitzer von Spezialwaffen oder Ruestungen werden
+	es euch danken.
+
+  c. Hilfs-/Begleit-NPCs
+
+      Bei solchen NPC wird auf Ausgewogenheit Wert gelegt, der Programmierer
+      sollte sich schon vor Antrag-Stellung an die Balance Gedanken darueber
+      machen, wie sich der NPC selber verhaelt.
+      Beispiel waere hier Unvertraeglichkeit mit anderen NPCs,
+      Aggressivitaet gegenueber anderen NPCs / Spielern, Wankel- muetigkeit,
+      Unzuverlaessigkeit, zeitliche Begrenzung, Schutz oder Schaden in
+      Abhaengigkeit von Align, Gilde des Spielers, Angriff, vom Ort des
+      Geschehens oder der Begabung des Spielers fuer Magie u.ae. Der
+      Phantasie sind hier keine Grenzen gesetzt.
+
+SIEHE AUCH:
+     Verwandt:    balance, ruestungen, waffen, fernwaffen, uniques,
+                  grenzwerte, attributsveraenderungen, resistenzen,
+                  kampfobjekte, begleitnpcs
+     Funktionen:  create_default_npc
+
+14.Feb 2007 Gloinson
diff --git a/doc/wiz/obj_geruest b/doc/wiz/obj_geruest
new file mode 100644
index 0000000..fc1f955
--- /dev/null
+++ b/doc/wiz/obj_geruest
@@ -0,0 +1,134 @@
+/*
+ *----------------------------------------------------------------------
+ * obj_geruest
+ * Dieses File ist Teil der Morgengrauen-Mudlib.
+ * Dieses File wird optimal formatiert, wenn Tabulatoren 4 Zeichen breit
+ * sind.
+ *
+ * Allgemeines Geruest fuer ein Objekt. Wer eigene Objekte schreibt,
+ * sollte sie nicht ganz so intensiv kommentieren wie dieses hier, aber
+ * hier sollen gleichzeitig, die grundlegenden Mechanismen erlaeutert
+ * werden.
+ *
+ * 16.08.92 Rumata
+ * Ueberarbeitet am 24.08.94 von Viper
+ *----------------------------------------------------------------------
+ */
+inherit "std/thing";            /* Leite aus den std-Objekten ab */
+
+#include <language.h>           /* Stelle Namen der Faelle und der Geschlechter */
+							/* dem Objekt zur Verfuegung. */
+
+create()
+{
+	::create();
+		/* Diese Zeile NIEMALS vergessen!!! */
+
+	AddId( "ball" );        
+	AddId( "strandball" );
+		/* Unter diesen Bezeichnungen fuehlt der Ball sich "angesprochen" */
+		/* Mann sollte mit Ids nicht sparen, damit die Spieler nicht ewig  */
+		/* nur nach dem richtigen Namen eines Objektes suchen muessen. */
+
+	SetProp( P_NAME, "Ball" );
+	SetProp( P_GENDER, MALE );
+	SetProp( P_ARTICLE, 1 );
+		/* Diese Meldungen ermoeglichen es der Mudlib, das Objekt richtig */
+		/* zu deklinieren. SetProp(P_ARTICLE, 1) kann wegfallen, da 1 Default ist. */
+
+	SetProp( P_SHORT, "Ein bunter Ball" );
+	SetProp( P_LONG, "Was fuer ein huebscher kleiner Strandball.\n"
+			+"Wem koenntest Du den mal zuwerfen?\n" );
+		/* Beschreibungen zur Betrachtung des Balls. */
+
+	SetProp( P_VALUE, 10 );
+	SetProp( P_WEIGHT, 250 );
+		/* Bei diesen Werten sollte die Verhaeltnismaessigkeit */
+		/* nicht aus den Augen gelassen werden. */
+}
+
+init()
+{
+	::init();
+		/* NICHT VERGESSEN */
+		/* Wenn keine eigenen Aktionen definiert werden sollen, so kann die */
+		/* Funktion init ganz weggelassen werden. Ein init, das nur */
+		/* ::init() aufruft ist ueberfluessig. */
+
+	add_action( "wurf", "werf", 1 );
+	add_action( "wurf", "wirf" );
+		/* werfe, werf oder wirf jemandem den Ball zu. Man sollte darauf */
+		/* achten, dass natuerliche Saetze als Eingabe akzeptiert werden. */
+}
+
+/*************************************************************************/
+/************* Die grundlegenden Funktionen enden hier *******************/
+/*************************************************************************/
+
+
+/* Eine Beispielaktion fuer den Ball. */
+wurf( argument )
+{
+	/* "werf ball rumata zu" wird als Argument "ball rumata zu" bekommen. */
+	string arg1, arg2;
+	string ziel;
+	object zielObj;
+
+	if ( sscanf( argument, "%s %s zu", arg1, arg2 ) != 2 ) return 0;
+		/* Rueckgabe von 0 bedeutet, dass dieses Objekt mit der Eingabe */
+		/* nichts anfangen konnte, und dass der Gamedriver das naechste */
+		/* Objekt befragen soll. */
+
+	if ( id( arg1 ) )
+			/* Welches der Argumente spricht den Ball an ? */
+			/* Das andere muss dann das Ziel des Balls sein. */
+		ziel = arg2;
+	else if ( id( arg2 ) )
+		ziel = arg1;
+	else
+		return 0;
+			/* Keines der Argumente war der Ball. */
+
+	zielObj = present( ziel, environment() );
+		/* Suche ein Objekt, das sich als Ziel angesprochen fuehlt. */
+
+	if ( ! zielObj )
+	{
+		write( "Hier ist kein \"" + ziel + "\".\n" );
+		return 1;
+			/* Hier wird 1 zurueckgegeben, da der Ball das Kommando den  */
+			/* Befehl bearbeiten konnte. Er hat zwar kein Ziel gefunden, */
+			/* aber man kann ja nicht alles haben. :-) */
+	}
+	
+	if( !living( zielObj ) )
+	{
+		write( "Und wie soll " + zielObj->name(WER,1) + " den Ball fangen?\n" );
+		return 1;
+			/* Nur lebende Wesen sollen Baelle fangen koennen. */
+	}
+
+	write( "Du wirfst " + zielObj->name(WEN,1) + " den Ball zu.\n" );
+			/* Mitteilung an den Werfer */
+	say( PL->name(WER,2) + " wirft " + zielObj->name(WEM,2)
+		+ " einen Ball zu.\n", zielObj );
+			/* Mitteilung an alle Wesem im selben Raum. */
+	tell_object( zielObj, "Hoppla, " + PL->name(WER,2)
+		+ " wirft Dir einen Ball zu.\n" );
+			/* Mitteilung an den Beworfenen */
+
+	if ( move( zielObj ) ) return 1;
+		/* Es hat geklappt. */
+
+	move( environment() );
+		/* Im Fehlerfall soll der Ball zu Boden fallen. */
+
+	write( "Aber " + zielObj->QueryPronoun(WER)
+		+ " kann ihn nicht fangen.\nDer Ball plumpst zu Boden.\n" );
+	say( "Aber " + zielObj->QueryPronoun(WER)
+		+ " kann ihn nicht fangen.\nDer Ball plumpst zu Boden.\n", zielObj );
+	tell_object( zielObj,
+		"Aber Du kannst ihn nicht fangen.\nDer Ball plumpst zu Boden.\n" );
+
+	return 1;
+}
diff --git a/doc/wiz/pararaeume b/doc/wiz/pararaeume
new file mode 100644
index 0000000..9263da6
--- /dev/null
+++ b/doc/wiz/pararaeume
@@ -0,0 +1,84 @@
+Para-Raeume
+
+    Grundsaetzlich wird ein Para-Raum dadurch gekennzeichnet, dass an den 
+    Dateinamen ein ^n angehaengt wird, n gibt die Dimension an. Ein Raum in 
+    Para 1 wuerde also raum^1.c heissen.
+
+    Man muss sich nicht selbst darum kuemmern, dass Spieler in den richtigen
+    Para-Raum bewegt werden, das passiert im move().
+
+    Damit man bei gleichen Raeumen, die sich nur durch beispielsweise die
+    Anwesenheit eines fiesen Monsters unterscheiden nicht alles doppelt
+    beschreiben muss, sollte man das bekannte Konzept der Vererbung
+    verwenden. Hierfuer gibt es zwei Ansaetze:
+
+LOESUNG 1:
+    Habe ich einen Raum, der in Para exakt so ist wie in Normal, wo nur eine
+    Sache hinzugefuegt wird, schreibe ich meinen Raum in normal so wie ich es
+    immer tun wuerde, erbe diesen im Para-Raum und setze mein fieses Monster
+    hinein.
+    Einziger Unterschied im Normal-Raum: Damit er immer initialisiert wird,
+    muss ich create_super() erstellen und darin create aufrufen. Sonst buggt
+    der Normalraum beim Betreten, falls der Pararaum zuerst betreten wurde,
+    weil der Normalraum dann zwar geladen aber selbst nicht initialisiert
+    wurde.
+
+    Beispiel:
+
+    raum.c:
+    inherit "/std/room";
+
+    protected void create() {
+      ::create();
+      ...
+    }
+
+    protected void create_super() {
+      create();
+    }
+
+    raum^1.c:
+    inherit "raum";
+
+    protected void create() {
+      ::create();
+      AddItem("fieses_monster",REFRESH_REMOVE);
+    }
+
+LOESUNG 2:
+    Habe ich einen Raum, wo auch in Normal Dinge existieren, die es nicht in
+    Para geben soll, kann ich einen Raum mit der Dimensionsnummer 0 erstellen.
+    Dieser wird niemals automatisch betreten, ausser ein Ausgang fuehrt
+    explizit dort hin.
+
+    Beispiel:
+
+    raum^0.c:
+    inherit "/std/room";
+
+    protected void create() {
+      ::create();
+      ...
+    }
+
+    raum.c:
+    inherit "raum^0";
+
+    protected void create() {
+      ::create();
+      AddItem("harmloses_monster",REFRESH_REMOVE);
+    }
+
+    raum^1.c:
+    inherit "raum^0";
+
+    protected void create() {
+      ::create();
+      AddItem("fieses_monster",REFRESH_REMOVE);
+    }
+
+
+SIEHE AUCH:
+    move(L), create_super(L), P_PARA(P)
+
+Letzte Aenderung: 18.01.2015, Bugfix
diff --git a/doc/wiz/parierwaffen b/doc/wiz/parierwaffen
new file mode 100644
index 0000000..64cb9bc
--- /dev/null
+++ b/doc/wiz/parierwaffen
@@ -0,0 +1,18 @@
+==============================================================================
+                 Regeln zur Programmierung von Parierwaffen:
+==============================================================================
+
+Standardobjekt: /std/weapon.c
+
+Siehe hierzu: /doc/wiz/balance   (oder 'man balance')
+
+Aktuelle Grenzwerte:
+====================
+
+   Parier-Typ   Genehmigungsgrenze
+  ------------ --------------------
+  PARRY_ONLY   Wie Rustungen vom Typ AT_SHIELD
+  PARRY_TOO    Generelle Genehmigungspflicht
+
+==============================================================================
+Paracelsus@MorgenGrauen, 18/08/1999
diff --git a/doc/wiz/potionmaster b/doc/wiz/potionmaster
new file mode 100644
index 0000000..6b8bfd2
--- /dev/null
+++ b/doc/wiz/potionmaster
@@ -0,0 +1,197 @@
+Der Potionmaster (/secure/potionmaster)
+=======================================
+
+BESCHREIBUNG
+
+    Funktion: Verwaltung der Zaubertraenke, die Spieler finden koennen.
+
+    Zaubertraenke koennen von beliebigen Objekten im Spiel vergeben werden.
+    Jeder Spruch ist in einer eigenen Datei in /secure/ARCH/ZT hinterlegt,
+    wobei der Dateiname das allgemeine Format <nr>.zt haben muss. <nr>
+    entspricht hierbei der ZT-Nummer.
+
+    Die Tips zu den Traenken werden vom Orakel /room/orakel ausgegeben,
+    sofern der Spieler genug Stufenpunkte fuer einen neuen Spruch erspielt
+    hat (siehe hierzu "hilfe zt"). Die Tips werden dabei aus den o.g. Dateien
+    eingelesen. Der ZT wird von dem vergebenden Objekt durch Aufruf von
+    FindPotion(string msg) im Spielerobjekt gutgeschrieben.
+
+    In dieser Datei sind die Funktionen des Potionmasters dokumentiert.
+    Inhalt:
+
+    1. Zaubertraenke eintragen und aktivieren/deaktivieren
+    2. Zaubertraenke in eine Liste einsortieren
+    3. Zaubertraenke verlegen
+    4. Daten zu Zaubertraenken abfragen
+    5. Ein neuer ZT: Was tun?
+    6. Format der Zaubertrank-Tips
+    7. Wo finde ich eigentlich?
+    8. Verschiedenes
+
+
+FUNKTIONEN
+
+1. Zaubertraenke eintragen und aktivieren/deaktivieren
+
+   int AddPotionroom(string room, int list)
+      Der Raum <room> wird als neuer ZT-Fundort eingetragen und in die Liste
+      mit der Nummer <list> eingefuegt. room muss hierbei der load_name() 
+      des Objekts sein, unt <list> darf Werte von 0 bis 7 haben. Der ZT
+      wird dabei aktiviert.
+      
+      Rueckgabewerte:
+      <num> Nummer des naechsten neuen ZTs, <num-1> ist die Nummer des
+            neu eingetragenen ZTs.
+      -1    Zugriff verweigert
+      -2    <room> kein String, <list> ist nicht im Bereich 0-7
+      -3    <room> ist nicht ladbar
+      -4    <room> vergibt schon einen (anderen) ZT
+      -6    Datei mit ZT-Spruch (/secure/ARCH/ZT/<num>.zt) existiert nicht.
+
+   int ActivateRoom(string room)
+      Der ZT im Raum <room> wird aktiviert, d.h. er kann aktiv von dem Raum
+      vergeben werden. Technisch wird er aus der Liste der inaktiven ZTs
+      ausgetragen. <room> muss hierbei der load_name() des Raumes sein.
+
+      Rueckgabewerte:
+      <num>  Nummer des aktivierten ZTs
+      -1     Zugriff verweigert
+      -5     ungueltiger ZT (Raum ist nicht als ZT-Objekt eingetragen)
+      -8     <room> ist bereits aktiviert
+
+   int DeactivateRoom(string room)
+      Der ZT im Objekt <room> wird deaktiviert, d.h. er kann nicht mehr
+      von dem Objekt vergeben werden. Technisch wird er in die Liste der
+      inaktiven ZTs eingetragen. <room> muss hierbei der load_name() des
+      Raumes sein.
+
+      Rueckgabewerte:
+      <num>  Nummer des geaenderten ZTs
+      -1     Zugriff verweigert
+      -5     ungueltiger ZT
+      -9     <room> ist bereits inaktiv
+
+2. Zaubertraenke in eine Liste einsortieren
+
+   int SetListNr(string room, int list)
+      Traegt den Zaubertrank in Raum <room> in die Liste <list> ein. 
+      <room> muss hierbei der load_name() des Objekts sein.
+
+      Rueckgabewerte:
+      <num>  Nummer des geaenderten ZTs
+      -1     Zugriff verweigert
+      -5     ungueltiger ZT
+      -7     <list> ausserhalb der zugelassenen Werte, d.h. <0 oder >7
+
+3. Zaubertraenke verlegen
+
+   int ChangeRoomPath(string old, string new)
+      Der Zaubertrank in Raum <old> wird in den Raum <new> umgetragen.
+
+      Rueckgabewerte:
+      <num> Nummer des erfolgreich geaenderten Zaubertranks
+      -1    Zugriff verweigert
+      -2    <new> oder <old> oder beide sind keine Strings
+      -3    <old> vergibt keinen ZT, es gibt also nichts zu verlegen, oder
+            <new> ist nicht ladbar, dorthin kann also nicht verlegt werden
+      -4    <new> hat schon einen Zaubertrank
+
+4. Daten zu Zaubertraenken abfragen
+
+   mixed QueryPotionData(int num)
+      Abfrage der Daten zu dem ZT mit der Nummer <num>. Ausgegeben wird ein
+      Mapping der Form ([ num : Raumpfad; Listennummer ])
+
+   int QueryInactivePotions()
+      Liefert ein Array mit den Nummern der aktuell deaktivierten ZTs zurueck.
+
+   int QueryActive(mixed potion)
+      Gibt zu einer ZT-Nummer oder einem Raumpfad an, ob der betreffende ZT
+      aktiv ist oder nicht. Wenn ja, wird die entsprechende ZT-Nummer
+      zurueckgegeben.
+      
+      Rueckgabewerte:
+      <num> Nummer des abgefragten ZTs
+      -1    Zugriff verweigert
+      -5    ungueltiger ZT
+      -11   ZT ist nicht aktiv
+   
+   string GetFilenameByNumber(int nr)
+      Abfrage des Dateinamens zu Zaubertrank Nummer <nr>.
+      
+      Rueckgabewerte:
+      <num> Nummer des abgefragten ZTs
+      -1    Zugriff verweigert
+      -5    ungueltiger ZT
+
+   int HasPotion(object obj)
+      Abfrage der Zaubertranknummer, die von dem Objekt <obj> vergeben wird.
+      
+      Rueckgabewerte:
+      <num> Nummer des abgefragten ZTs
+      -1    Zugriff verweigert
+      -3    Raum vergibt keinen ZT
+
+   int GetListByNumber(int nr)
+      Abfrage der Liste aktiver ZTs, in der der ZT mit der Nummer <nr>
+      eingetragen ist.
+      Rueckgabe: Nummer der Liste, in der der ZT enthalten ist, sonst -5.
+
+   int GetInactListByNumber(int nr)
+      Abfrage der Liste inaktiver ZTs, in der der ZT mit der Nummer <nr>
+      eingetragen ist.
+      Rueckgabe: Nummer der Liste, in der der ZT enthalten ist, sonst -10.
+
+5. Ein neuer ZT: Was tun?
+
+   AddPotionRoom(newroom, liste) aufrufen. Wenn ein Fehler auftritt, muss
+   noch der ZT-Tip in dem unter 6. beschriebenen Format hinterlegt werden.
+   Der zu verwendende Dateiname ist in der Fehlermeldung angegeben.
+
+6. Format der Zaubertrank-Tips
+
+   Ein Beispiel mit zwei Tips fuer denselben Zaubertrank:
+
+   Die Zaubermaus wollts wohl verstecken,
+   Im Buecherwald sollst nichts entdecken,
+   Denn Trinkgenuss ist dort verpoent,
+   So ist mans auch RL gewoehnt.
+   XXXXX
+   Der Raum ist prall und star gefuellt,
+   Mit viel Papier, das gern verhuellt
+   In Zauberbuchform manches Od,
+   Das hilft Dir dann aus Deiner Not.
+   %%%%%
+
+   Die Prozentzeichen sind das Endezeichen, danach koennen eventuelle
+   Kommentare stehen. XXXXX ist das Trennzeichen zwischen zwei Tips
+   zum selben ZT. Auswirkung ist, dass der Spieler bei jedem Aufruf
+   seiner Zaubertrank-Liste zufaellig einen Spruch aus der Liste 
+   angezeigt bekommt.
+
+7. Wo finde ich eigentlich?
+
+   - die Zaubertrank-Tips:           /secure/ARCH/ZT/*.zt
+   - die Gesamtliste der ZTs:        /secure/ARCH/POTIONS.dump
+   - das Savefile des Potionmasters: /secure/ARCH/potions.o
+   - das Logfile fuer Aenderungen:   /log/ARCH/POTIONS_MOD.log
+
+8. Verschiedenes
+
+   mixed TipLesen(int nr)
+      Das Orakel auf der Hochebene ruft die Zaubertrank-Tipps ab, diese
+      werden von der Platte gelesen und als String an das Orakel 
+      zurueckgeliefert.
+   int DumpList()
+      Die Komplettliste der ZTs in das Dumpfile /secure/ARCH/POTIONS.dump
+      schreiben.
+
+SIEHE AUCH:
+   Spielerbefehle: zaubertraenke
+   Magierbefehle:  traenke
+   Properties:     P_POTIONROOMS, P_KNOWN_POTIONROOMS
+   Anleitung:      wiz/zaubertraenke
+   ZT finden:      FindPotion(L)
+
+2013-Mai-30 Arathorn
+
diff --git a/doc/wiz/quests b/doc/wiz/quests
new file mode 100644
index 0000000..5c45023
--- /dev/null
+++ b/doc/wiz/quests
@@ -0,0 +1,160 @@
+Leitfaden fuer die Questerstellung/-abnahme:
+============================================
+
+
+Quests im MorgenGrauen:
+-----------------------
+
+Beginnen wir mit einem Zitat:
+
+  Boing sagt: 'Das MorgenGrauen ist ein Questmud.'
+
+Das MorgenGrauen unterscheidet sich von einigen anderen Muds, indem
+eben ein sehr grosser Wert auf Quests gelegt wird. Mittlerweile haben
+wir ja auch schon eine ordentliche Anzahl Quests. Trotzdem ist es
+wichtig und wird immer wieder gerne gesehen, wenn neue Quests geproggt
+werden. Darueberhinaus bleibt man als Magier natuerlich auch laenger
+im Spiel bekannt. Gerade weil Quests auch eine wichtige Anforderung
+zum Sehertum sind, muss ihnen ein besonderes Augenmerk seitens des
+programmierenden Magiers gewidmet werden und besonders sorgfaeltig
+gearbeitet werden. Dazu gibt es nun im folgenden ein paar Hinweise,
+die man als Questprogrammierer einhalten sollte, damit die Quest
+genehmigt werden kann und bei den Spielern gut ankommt.
+
+Questideen:
+-----------
+
+Dies ist der wichtigste Bestandteil einer Quest. Hier sollte man sich
+sehr viel Muehe geben, denn mit dem Konzept steht und faellt eine
+Quest. Damit Spieler Spass an einer Quest haben, ist eine gute Story,
+ein gutes Konzept unabdingbar. Ein wichtiger Erfolgsfaktor ist an
+dieser Stelle auch, sich rechtzeitig mit dem betroffenen Regionsmagier
+und dem Questerzmagier abzusprechen. Spaeter hat man da vielleicht
+keine Gelegenheit mehr und hat sich viel Arbeit gemacht und muss
+wieder viel aendern. Daher: VORHERIGER ABSPRACHE VERMEIDET
+AERGER. Insbesondere bei Quests mit hohem Metzelanteil sollte
+unbedingt Ruecksprache gehalten werden, da solche Quests nicht so
+gerne gesehen sind. 
+
+Questumsetzung:
+---------------
+
+Bei der Umsetzung kann man sich an die Regeln halten, die allgemein
+fuer den Anschluss von Gebieten gelten (NPCs, Balance...). Besondere
+Aufmerksamkeit verdienen die Teile, die zur Loesung der Quest
+notwendig sind (Questitems, Questmaster...)  Es empfiehlt sich auch in
+dieser Phase, immer mal Ruecksprache mit dem Regionsmagier oder
+Questerzmagier zu halten.
+
+Eine Questbelohnung wird von Spielern immer wieder gerne
+genommen. Dabei sollte man allerdings ein gewisses Augenmass
+anlegen. Nicht fuer jede Quest muss es eine super tolle
+Auto-Load-Belohnung geben. 
+
+Fuer das konkrete Umsetzen seien noch ein paar Hinweise gegeben:
+
+ - Fuer die Atmosphaere und die Details sollte man sehr viel Muehe
+   verwenden, so dass sich dem Spieler der logische Aufbau
+   erschliesst. Es ist fuer Spieler ausserordentlich aergerlich, eine
+   Quest zu spielen, deren Bestandteile irgendwie in der Luft
+   haengen. 
+ - Es sollte sich sehr gut ueberlegt werden, wie die Quest reagiert, 
+   wenn mehrere Spieler gleichzeitig die Quest spielen wollen (das
+   wird inbesondere direkt nach dem Anschluss der Fall sein).
+   Dies bezieht sich insbesondere auf Quest-Objekte, die einem Spieler
+   evtl. nicht zur Verfuegung stehen, weil sie gerade ein andere
+   genommen hat, oder Quest-NPCs, die wichtige Auskuenfte haben,
+   aber leider umgenietet wurden. Wichtige Quest-NPCs sollten nach
+   Moeglichkeit besser nicht als Metzelopfer konzipiert werden.
+ - Nach Moeglichkeit sollte es nicht das hundertste Labyrinth geben.
+ - Werden fuer die Quest allgemeine Objekte (wie Schaufeln, Seile
+   etc.) benoetigt, so sollten auch die an anderer Stelle im Mud
+   erhaeltlichen Objekte funktionieren oder es sollte fuer den Spieler
+   erkennbar sein, wieso nur ein spezielles Objekt den Zweck erfuellt.
+ - Questobjekte sollten fuer Spieler nicht erstellbar sein (->
+   Seherbeutel). 
+ - Wird der Questfortschritt in einem Master gespeichert, so empfiehlt
+   es sich, die Daten zu den Spielern nach dem Loesen der Quest wieder
+   zu loeschen (ebenso bei Spielern, die sich geloescht haben).
+ - Es sollten sich auch Gedanken gemacht werden, wie die Quest beim
+   Einschlafen, Beenden oder bei einem Crash reagiert. Es muss also
+   sichergestellt sein, dass der Spieler dann beim naechsten 
+   Questversuch nicht in einen inkonsistenten Zustand landet.
+ - Gut ist, den Questverlauf ein wenig variable zu gestalten, so
+   dass die Quest nicht ohne weiteres durchskriptbar ist.
+ - Bei Pflichtquests bitte beachten, dass NPCs, die zwingend zu toeten
+   sind, nicht zu stark sind.
+ - Das Objekt, welches die Quest nach dem Loesen setzen soll, muss einen 
+   Aufruf von GiveQuest enthalten. Desweiteren ist beim ersten Loesen 
+   in ein Questlogfile im Verzeichnis /log/quest ein Eintrag zu machen, 
+   dass der Spieler die Quest bestanden hat. Diesen Eintrag bitte 
+   mit write_file schreiben.
+  
+Questtest (Magier):
+-------------------
+
+Nun kommt ein entscheidender Schritt fuer die Quest. Denn jetzt
+schauen auch einmal Magierkollegen ueber die Quest und koennen auf
+Bugs, logische Fehler und kleinere Probleme hinweisen. Um moeglichst
+viele derartiger Dinge abzufangen, sollte man auf den Questtest viel
+Zeit verwenden und Magierkollegen bitten, die Quest einmal zu testen. 
+
+Questtest (Spieler):
+--------------------
+
+Wenn es moeglich ist, sollte auch ein Spieler die Quest einmal
+testen. Jedoch sind dazu die Regeln fuer Spielertesties ('man
+testies') einzuhalten. Es ist insbesondere darauf zu achten, dass
+wenn dem Testie eventuelle Forscherpunkte o.ae. zugesprochen werden,
+die negativen Seiten der Quest nicht wegfallen duerfen (soweit sie
+nicht auf Fehlern beruhen). 
+
+Abnahme der Quest:
+------------------
+
+Sofern noch nicht geschehen, muss nun der Regionsmagier die Quest
+abnehmen. (Ist der Programmierer selbst der Regionsmagier, sollte er
+einen Magierkollegen bitten, dies zu machen (fuer die meisten Regionen
+gibt es ja mehr als einen RM).) Wenn dies alles geschen ist, kann der
+Questerzmagier die Quest abnehmen. 
+
+Die Bearbeitung der Quest geht am schnellsten, wenn dem Quest-EM
+folgende Infos vorliegen (z.B. in einer Mail):
+
+ - Eine kurze Beschreibung der Quest, also worum geht es ueberhaupt?
+ - Eine Loesungsskizze (bitte nicht im Home-Verzeichnis rumliegen
+   lassen)
+ - Eine Beschreibung der technischen Loesung, also wie ist das ganze
+   programmiert? 
+ - In welchem Objekt wird die Quest mittels GiveQuest gesetzt?
+ - Eine Aufstellung, welche Files zu der Quest gehoeren und wo sie
+   sich befinden.
+ - Eine Liste der Abhaengigkeiten zu anderen Teilen im Mud? (Gilden-NPCs,
+   MNPCs..)
+ - Eine Einschaetzung der Schwierigkeit der Quest. Wie gut sollte man
+   sein? Welchen Level? Was fuer Stats?...
+ - Einen Vorschlag, wieviele APs fuer die Quest vergeben werden sollen.
+ - Einen Vorschlag, welchen Spruch der Wanderer den Spielern sagen
+   soll.
+ - Eine Liste der Magier und Spieler, die die Quest schon getestet haben.
+
+Danach schaut sich der Quest-EM die Quest an und legt mit dem
+Programmierer zusammen APs, Schwierigkeitsgrad, den Spruch fuer den
+Wanderer etc. fest. Dann wird die Quest vom Quest-EM eingetragen.
+
+Questanschluss:
+---------------
+
+Zum Anschluss der Quest sollte man nach Moeglichkeit ebenfalls online
+sein, um eventuelle Probleme, Bugs zu beseitigen. Auch sollte man nach
+Anschluss der Quest gewissenhaft sein Repfile abarbeiten um Typos,
+Ideen und Bugs abzuarbeiten.
+
+Siehe auch:
+-----------
+
+ QueryQuest, GiveQuest, write_file
+
+------------------------------------------------------------------------------
+Zuletzt geaendert: Mon, 17. Jul 2000, 12:16:41 von Zook.
+
diff --git a/doc/wiz/quests.doc b/doc/wiz/quests.doc
new file mode 100644
index 0000000..24c91c8
--- /dev/null
+++ b/doc/wiz/quests.doc
@@ -0,0 +1,66 @@
+ Das Questsystem wird in MorgenGrauen von einem zentralen Questhandler
+gesteuert. Dieser stellt die folgenden Funktionen zur Verfuegung:
+
+AddQuest(string questname, int questpoints, int experience,
+         string *allowedobj, string hint, int difficulty, int needed)
+ Diese Funktion definiert eine Quest und gibt sie zur Benutzung durch die
+ Spieler frei. Sie darf nur von Erzmagiern aufgerufen werden.
+ Bedeutung der Parameter:
+   questname gibt den Namen der zu definierenden Quest an. Es darf bereits
+             eine Quest dieses Namens geben, ihre Parameter werden dann
+             geaendert.
+   questpoints gibt die Zahl der Questpunkte an, die der Spieler fuer die
+               Loesung dieser Quest angerechnet bekommt. Muss >0 sein.
+   experience gibt die Zahl der Erfahrungspunkte an, die der Spieler fuer
+              eine Quest bekommen kann. DIESE ZAHL KANN <0 SEIN!
+   allowedobj ist ein Array mit den Filenamen der Objekte, die diese Quest als
+              durch einen Spieler geloest kennzeichnen duerfen. Darueberhinaus
+              duerfen Erzmagier dies immer tun.
+   hint ist ein String, der Tips zur Loesung der Quest enthaelt. Dieser String
+        wird dem Spieler vom Orakel als Hinweis gegeben.
+   difficulty ist eine Zahl zwischen 0 und 20, die den "Schwierigkeitsgrad"
+              der Quest angibt. 0 hat eine besondere Bedeutung, naemlich die,
+              das keine Einschaetzung vorliegt.
+   needed legt fest, ob die Quest von einem Spieler geloest werden muss, be-
+          vor er Magier werden kann. Falls needed !=0 ist, MUSS er die Quest
+          loesen, unabhaengig von der 90%-Regel.
+
+RemoveQuest(string questname);
+ Gegenstueck zu AddQuest, loescht eine Quest. Kann natuerlich ebenfalls nur
+ von Erzmagiern aufgerufen werden. DIE SPIELER, DIE DIE QUEST SCHON GELOEST
+ HABEN, BEHALTEN DIE ENTSPRECHENDEN QUESTPUNKTE !!
+
+QueryReadyForWiz(object player)
+ Dieser Funktion muss ein Playerobjekt uebergeben bekommen und prueft, ob
+ der Spieler seitens der Quests bereit ist zur Aufstufung zum Magier, dh
+ ob er 90% der QP sowie alle zwingend vorgeschriebenen Quests (siehe
+ AddQuest, Parameter needed) geloest hat. Falls dies der Fall ist, liefert
+ die Funktion eine 1 zurueck. Wenn er die 90% nicht hat, eine -1. Falls
+ ihm noetige Quests fehlen, eine Liste der nicht geloesten, noetigen Quests.
+
+QueryQuest(questname)
+ Liefert eine -1, falls keine Quest dieses Names eingetragen ist, sonst
+ einen Array mit den Daten der Quest, in der Reihenfolge, in der sie in
+ AddQuest eingegeben werden. Dabei ist questpoints das erste Arrayelement.
+
+QueryAdvanceExp(object player)
+ Stellt fest, ob der Spieler player genuegend Questpunkte hat, um seine
+ Erfahrung zu erhoehen.
+
+-----------------------------------------------------------------------------
+ Weiterhin enthaelt jedes Playerobjekt ein Quest-Modul, das die folgenden
+Funktionen offeriert:
+
+GiveQuest(string questname)
+ Markiert eine Quest bei dem Player als geloest. Es wird getestet, ob die
+ Aktion von einem "allowed_object" vorgenommen wird. Die Questpunkte werden
+ entsprechend geupdated.
+
+QueryQuests()
+ Gibt eine Alist mit den Namen der vom Player geloesten Quests zurueck.
+
+QueryQP()
+ Gibt die Anzahl der vom Player erreichten Questpunkte zurueck.
+
+QueryQuest(string questname)
+ Stellt fest, ob ein Spieler die Quest geloest hat oder nicht.
diff --git a/doc/wiz/regionsleitfaden b/doc/wiz/regionsleitfaden
new file mode 100644
index 0000000..0528d02
--- /dev/null
+++ b/doc/wiz/regionsleitfaden
@@ -0,0 +1,200 @@
+
+Hallo, willkommen in den unendlichen Weiten der Regionsverzeichnisse!
+
+Du moechtest in einer Region mitprogrammieren? Prima, neue kreative 
+Mitarbeiter sind jederzeit willkommen! Du bist herzlich eingeladen, mit 
+Deinen Ideen zur Entwicklung beizutragen.
+
+Um die Programmierung und anschliessende Abnahme fuer alle Beteiligten
+moeglichst reibungslos zu gestalten, seien Dir die in dieser Hilfeseite
+genannten Dinge ans Herz gelegt. Diese lassen sich in folgende Kategorien
+einteilen:
+
+1) Formales zum Codestil
+2) Inhaltliche Anforderungen
+3) Was nicht akzeptiert wird
+4) Was ist vor dem Anschluss zu beachten?
+
+
+1) Formales zum Codestil
+
+o  #pragma strong_types,save_types soll in allen Files verwendet werden,
+   ab Driver-Version LD_3.5.x wird auch rrtt_checks dringend empfohlen.
+
+o  Der Code soll keine Zeilen mit mehr als 78 Zeichen enthalten.
+
+o  Der Code soll sauber eingerueckt und sorgfaeltig formatiert sein, aber
+   bitte ohne Tabulatoren.
+
+o  Verwende keine Lambda-Closures! Was auch immer Du vorhast: Es geht
+   ohne. Es sei ausdruecklich auf die Moeglichkeit von inline-Closures
+   verwiesen, wenn Du unbedingt vermeiden willst, eine separate Funktion
+   zu schreiben.
+
+o  Kommentiere Deinen Code! Insbesondere dort, wo komplexere Objekt-
+   Interaktionen stattfinden, oder wo implizit besondere Eigenschaften
+   (z.B. der Mudlib, oder mathematische "Features") genutzt werden, die im
+   Code nicht auf den ersten Blick ersichtlich oder durchschaubar sind.
+   Daumenregel: "Wenn Du laenger als eine Minute ueber eine Zeile nachdenken
+   musstest, kommentiere sie." ;-) Rechne immer damit, dass jemand, der
+   Deinen Code liest, keine Ahnung hat, was Du da eigentlich tust. :-)
+
+o  Wirf bitte nach Abschluss der Arbeiten Platzhalter-Code raus (z.B. leere
+   AddDetail()-Anweisungen) und entferne nicht fuer das Gebiet benoetigte
+   Dateien aus den Verzeichnissen.
+
+o  Speicherung von Daten in secure-Verzeichnissen soll bitte nur sehr
+   sparsam erfolgen und nur in Abstimmung mit dem RM.
+
+o  save_object() bitte sehr sparsam verwenden (nicht bei jeder Daten-
+   aenderung, bei Bedarf in reset/remove).
+
+o  Wenn Defines zum Einsatz kommen, verwende sie bitte moeglichst sparsam
+   und sorge dafuer, dass Defines klar als solche erkennbar sind. Ausser in
+   Faellen, wo es gar nicht anders geht, solltest Du keine Code-Defines
+   verwenden, die mehr umfassen als einfache Funktionsaufrufe wie z.B.
+      #define TP this_player()
+   Fuer uebliche Standardfaelle existiert bereits eine Headerdatei in der 
+   Mudlib unter /sys/defines.h. 
+
+o  Solltest Du bestimmte Ereignisse in Deinem Gebiet loggen wollen (z.B.
+   (Mini-)Questabschluesse oder besondere Kills), dann benutze bitte 
+   log_file(), so dass die Logfiles nach /log/ geschrieben werden. Zusaetzlich
+   werden so erstellte Logfiles automatisch bei Erreichen einer bestimmten
+   Dateigroesse rotiert, so dass sich der Platzverbrauch in Grenzen haelt.
+   Das Protokollieren mittels write_file() in Regionsverzeichnissen unter 
+   /d/ ist grundsaetzlich NICHT erwuenscht. 
+   Nach Absprache KANN es fuer SELTENE und WICHTIGE Meldungen erlaubt werden,
+   mittels write_file(() nach /log/ zu schreiben.
+
+o  Wenn Du in Deinem Gebiet Daten oder Code ablegst, der nicht fuer 
+   jedermanns Augen bestimmt ist (Questloesungen, Gebietskarten, Savefiles
+   von questrelevanten (Master-)Objekten), solltest Du in Abstimmung mit
+   Deinem Regionsmagier ueberlegen, diese in ein ./secure/-Verzeichnis
+   zu verschieben, damit sichergestellt ist, dass auch tatsaechlich nur
+   berechtigte Magier darauf Zugriff erhalten. Denn bedenke, dass Lese-
+   und Schreibrechte nur fuer Codedateien geprueft werden, jedoch nicht
+   fuer beliebige sonstige Textdateien.
+
+o  Es sei ausdruecklich auf die Manpages "goodstyle", "effizienz", etc.
+   verwiesen.
+
+
+Das soll jetzt nicht heissen, dass der Anschluss von Code kategorisch
+abgelehnt werden wird, der diese Formalien nicht erfuellt. (Ausnahme: Lambda-
+Closures werden in den Regionen nicht mehr akzeptiert.) Ich moechte aber
+wirklich nachdruecklich darum bitten, sie aus einem einfachen Grund
+einzubauen: Du wirst nicht immer der einzige sein, der Deinen Code lesen und
+warten muss, auch in Deiner Abwesenheit koennen Bugs auftreten. Und dann ist
+es wesentlich einfacher, einen Minimalstandard zu haben, der es allen
+ermoeglicht, den Code auch im MG zu lesen und dort zu fixen. Denn nicht immer
+wird es moeglich sein, sich Dateien herunterzuladen und lokal zu bearbeiten.
+
+Zum Bugfixing an dieser Stelle aus aktuellem Anlass eine Anmerkung: Es wird
+von jedem aktiven Regionsmitarbeiter erwartet, dass er einen Fehlerteufel
+(/obj/tools/fehlerteufel) besitzt und dessen Fehlerliste regelmaessig
+durchsieht und aufgetretene Fehler und Warnungen behebt. (Okt. 2007)
+
+
+2) Inhaltliche Anforderungen:
+
+o  Wenn Du ein komplett neues Gebiet schreiben moechtest, das in einer Region 
+   seinen Platz finden soll, sprich bitte die thematische Ausrichtung mit
+   dem RM ab, bevor Du anfaengst, Code zu schreiben. Falls von Deinen Ideen
+   irgendetwas nicht hierher passen sollte, laesst sich das mit wesentlich
+   weniger Frust im Vorfeld klaeren, als wenn hinterher das halbe Gebiet
+   umgebaut werden muesste. Sollte sich die konzeptionelle Ausrichtung 
+   oder der Umfang waehrend der Programmierung grundlegend aendern, besprich
+   dies bitte kurz mit dem RM.
+
+o  Ob neue oder alte Rechtschreibung, ist im wesentlichen Dir selbst ueber-
+   lassen, jedoch waere es schoen, wenn Du die Spieler-Anreden wie "frueher"
+   ueblich gross schreiben wuerdest ("Du", "Dich", "Dein").
+
+o  Es muessen in jedem Raum gewisse Standarddetails vorhanden sein, z.B.
+   Boden, Decke, Waende, Himmel (Sonne, Wolken), etc. Dies kann man sehr
+   bequem mit dem "Otester" pruefen.
+   Es sei aber ausdruecklich darauf hingewiesen, dass der Otester keinesfalls
+   benutzt werden sollte, um saemtliche vorhandenen Substantive bis ins
+   kleinste zu beschreiben. Es ist schoen, wenn Objekte moeglichst voll-
+   staendig beschrieben werden, aber man sollte es auch nicht uebertreiben.
+
+o  Was bitte nur in Ausnahmefaellen gemacht werden sollte, ist, Details, 
+   Infos oder Lang-/Kurzbeschreibungen aus Standardraeumen zu inheriten.
+
+o  Falls Du Beschreibungen/Ausgaben in ASCII-Grafik einbinden moechtest, achte
+   bitte darauf, dass Du auf jeden Fall einen kurzen Alternativtext mit-
+   lieferst und diesen ausgibst, wenn der Spieler P_NO_ASCII_ART gesetzt hat.
+   Es besteht immer die Moeglichkeit, dass Spieler mit Sehschwaeche oder
+   Blinde Deine Objekte anschauen, und diese kommen mit Objekten in reiner
+   ASCII-Grafik nicht zurecht.
+   (Siehe auch die Manpage zu P_NO_ASCII_ART und "hilfe grafik".)
+
+o  Eine Anmerkung zu den Schadensarten DT_HOLY und DT_UNHOLY soll nicht
+   unerwaehnt bleiben: Es wird von vielen Spielern und Magiern als logisch
+   und atmosphaerisch nicht begruendbar empfunden, wenn Gegenstaende oder
+   NPCs diese beiden Schadensarten gleichermassen einsetzen bzw. verursachen
+   koennen. Vergleichbares gilt fuer die gleichzeitige Abwehr beider 
+   Schadensarten. Wenngleich bisher diesbezueglich keine klare Einigung
+   erzielt werden konnte, soll an dieser Stelle dennoch empfohlen werden,
+   von einer gleichzeitigen Nutzung von DT_HOLY und DT_UNHOLY abzusehen.
+   Der zustaendige Regionsmagier muss aber auf jeden Fall in Kenntnis
+   gesetzt werden und entsprechende Objekte zur Pruefung vorgelegt bekommen,
+   falls diese Nutzung dennoch fuer unumgaenglich gehalten wird.
+
+
+3) Was keinesfalls akzeptiert wird
+
+o  Files, die in /players liegen, incl. Headerfiles. Dies erschwert das
+   Reparieren von Bugs ungemein und bringt eine gewisse Unuebersichtlichkeit
+   mit sich. Bitte auch nichts aus /players inheriten (Ausnahmen hiervon sind 
+   aufgrund eines neuen Driver-Features nur noch mit Hilfe eines Erzmagiers 
+   moeglich. Kurz gesagt: es gibt eine Whitelist von Objekten, die das 
+   duerfen. Alle anderen duerfen das per Default nicht.).
+
+
+4) Was ist vor dem Anschluss zu beachten?
+
+o  Code muss vollstaendig fertig sein. Das heisst insbesondere, dass 
+   Debug- und nicht mehr benoetigter Code entfernt wurde und dass alle 
+   erforderlichen Kommentare vorhanden sind.
+
+o  Abnahme durch den RM und ggf. den fuer Gesellenstuecke zustaendigen EM
+   muss erledigt sein. Regionsmagier sind angehalten, eigene Gebiete, die zum
+   Anschluss in der eigenen Region geplant sind, von anderen Magiern abnehmen
+   lassen.
+
+o  Der Magier ist angehalten, das Gebiet durch Testspieler testen zu lassen
+   (siehe hierzu die Testspieler-Regeln). Ob ein Spieltest als Voraussetzung
+   fuer die Abnahme gefordert wird, entscheidet der zustaendige RM. Er kann
+   den Test auch selbst durchfuehren oder ganz darauf verzichten.
+
+o  Quests und Miniquests muessen vom zustaendigen Quest-EM getestet,
+   eingetragen und aktiviert worden sein.
+
+o  Feedback der Testspieler und testenden Magier sollte umgesetzt sein.
+
+o  Forscherpunkte muessen vom zustaendigen EM eingetragen worden sein.
+
+o  Balance-Genehmigungen (Objekte, Heilung, ggf. Gildenbalance) muessen 
+   vorliegen; die genehmigten Eckparameter sollen nachvollziehbar im 
+   Gebietsverzeichnis dokumentiert sein: entweder im jeweiligen File, oder
+   als Textfile z.B. in einem Doku-Verzeichnis.
+
+o  Kraeuter fuer den Kraeuterskill muessen genehmigt und eingetragen worden 
+   sein (dies kann jeder EM mit dem Kraeutertool erledigen).
+
+o  Hinweis: Erstkills muessen NICHT ZWINGEND vom zustaendigen EM eingetragen
+   worden sein. Die Erstkill-NPCs werden automatisch in einer vorlaeufigen
+   Liste gesammelt und vom EM entweder freigegeben oder abgelehnt. Auch
+   Sonder-Stufenpunkte fuer EKs muessen nicht vor dem Anschluss beantragt
+   oder genehmigt worden sein, auch diese Eintragung laesst sich erledigen,
+   wenn der betreffende NPC das erste Mal getoetet wurde.
+
+o  Auch die fuer den Ruestungsskill so beliebten Ruestungen muessen nicht
+   vor dem Anschluss eingetragen werden. Neue Ruestungen werden automatisch
+   beim zustaendigen Masterobjekt angemeldet, sobald sie das erste Mal
+   repariert werden.
+
+Und nun viel Spass bei der Programmierung! 
+
diff --git a/doc/wiz/regionsmagier b/doc/wiz/regionsmagier
new file mode 100644
index 0000000..fae5f9f
--- /dev/null
+++ b/doc/wiz/regionsmagier
@@ -0,0 +1,108 @@
+
+Regionsmagier
+=============
+
+Vorbemerkung: Dieses Dokument ist nicht auf dem aktuellen Stand,
+Anregungen dazu nehme ich, Zook, gerne entgegen. Ich werde das
+Dokument dann nach und nach erweitern, berichtigen.
+
+    Hier sind einige Verhaltensregeln fuer Regionsmagier zusammengetragen. Sie
+    sollten tunlichst beachtet werden, damit es nicht zu Aerger und
+    Enttaeuschungen fuer Spieler und Magier kommt.
+
+    Einstellen von neuen Mitarbeitern:
+
+     * Man sollte dem neuen Magier *vorher* sagen, was fuer Richtlinien fuer
+       die Region gelten.
+     * Der neue Magier sollte zuerst seine Plaene erlaeutern und mit dem RM
+       absprechen, ob das in die Region passt.
+     * Zum Aufnehmen in die Region einfach ein Verzeichnis mit dem Magiernamen
+       anlegen, dann zu Merlin gehen und sagen
+
+       merlin mach <xxx> zum magier / merlin mach <xxx> zur magierin
+
+    Zum Testen von neuen Gebieten:
+
+     * Generell gilt: ERST testen, dann anschliessen.
+     * Logik beachten!
+     * Syntax von Befehlen beachten, kann der Spieler draufkommen?
+     * Objekte pruefen, genaueres siehe unten beim Punkt Balance.
+     * Jedes Monster kurz umhauen (nicht zappen), geht prima mit einem
+       entsprechend hohen Wert fuer P_HANDS. Dann `tail /log/NPC_XP' und die
+       XP-Vergabe ueberpruefen.
+     * Auch den Code anschauen, unnoetige oder schlecht programmierte Dinge
+       bemaengeln, natuerlich mit Verbesserungsvorschlag.
+     * typischer Fehler: darauf achten, ob beim Bewegen von Objekten in den
+       Spieler der Rueckgabewert von move() ueberprueft wird und die
+       entsprechenden Massnahmen ergriffen werden, wenn der Spieler nichts
+       mehr tragen kann.
+     * Bei sich bewegenden Monstern mit dem Magier besprechen, ob das wirklich
+       noetig ist, bzw. ob man den Takt verlaengern kann. Lauf-NPCs sind
+       CPU-Fresser.
+     * Vor dem Anschluss MUESSEN Forscherpunkte eingetragen werden. Das macht
+       der entsprechende Erzmagier, momentan ist das Rikus. Naeheres dazu
+       steht unter `hilfe forscherpunkte'.
+
+    Ein paar grobe Regeln zur Balance:
+
+     * Dies sind Richtlinien, die evtl. nicht mehr aktuell sind. Die aktuellen
+       Regeln, die von den Magiern befolgt werden muessen, stehen im
+       Verzeichnis `/doc/REGELN' sowie insbesondere in `/doc/wiz/balance'.
+     * gute Waffen (WC ueber 190) sollten nur selten ins Spiel kommen, das
+       heisst es sollte keine 5 NPCs auf einem Haufen mit solchen Waffen geben
+       (als Beispiel). Ausserdem sollten diese Waffen schwer zu erlangen sein.
+     * sehr gute Waffen (200 oder mehr) sollten sehr selten sein und sehr
+       schwierig zu bekommen. Extrem gute Waffen koennen ruhig existieren,
+       allerdings sollten sie dann einmalig sein (Beispiel: Hauruck).
+     * Artillerie: Gibt es schon mehr als genug, sollte eigentlich nur noch in
+       extremem Ausnahmefaellen neu reinkommen. Als Artillerie bezeichne ich
+       alles, was im Kampf zusaetzlich hilft (Flammenkugeln, Wurfsterne,
+       Eisstab).
+     * Heilung: tragbare Heilung ist generell nicht erlaubt, allerdings kann
+       man Ausnahmen machen bei entsprechenden Nachteilen, z.b. hohe
+       Saettigung, gleichzeitige Vergiftung, Abhaengigkeit ... der Fantasie
+       sind keine Grenzen gesetzt.
+     * Ausgeglichenheit: Darauf achten, dass nicht nur Mega-Monster rumlaufen,
+       sondern fuer jeden etwas dabei ist. Dabei sollten harte Monster nicht
+       ohne weiteres zu erreichen sein; man sollte spuerbaren Widerstand
+       ueberwinden muessen, bevor man sie erreicht.
+
+Programmhierhinweise: [Ergaenzung vom 2003-03-06, Zook]
+
+Bitte achtet darauf, dass beim Programmieren Eurer Regionsmitarbeiter
+gewisse Standards eingehalten werden und dass typische Fehler vermieden
+werden. Im folgenden ein paar Hinweise:
+
+ * Bei Laeden bitte darauf achten, dass nicht unnoetig "verkaufe" mit
+   einem AddCmd ueberschrieben wird, wenn statt dessen buy_obj() oder
+   sell_obj() verwendet werden kann.
+   Um Laeden besser anzupassen, kann dort auch P_GENDER, P_NAME und
+   P_ARTICLE gesetzt werden.
+ * Bei Waffen kann und sollte die Funktion "is_unsafe" verwendet werden,
+   wenn NPCs die Waffe nicht zuecken sollten. Z.B. liefert einen 
+   Runenschwert bei Elfen-NPCs eine 1 zurueck, sonst eine 0.
+ * Es gibt eine Property P_PLURAL. Die sollte man auch verwenden. 
+   Siehe dazu die Hilfeseite.
+ * Zum Hantieren mit Gegenstaenden stellt put&get einige komfortable
+   Funktionen zur Verfuegung: pick_obj(), drop_obj(), put_obj(), 
+   give_obj().
+   Um Objekte auszuwaehlen kann find_obs() genutzt werden.
+   Prueft ein Objekt, ob es selbst gemeint ist (z.B. in einem AddCmd)
+   bitte pruefen, ob id() verwendet werden sollte.
+   
+
+    Sonstiges:
+
+     * Wenn man ein Verzeichnis unter /d/<region> anlegt, muss man darauf
+       achten, dass der entsprechende Name gebanisht wird, sonst ist ein
+       Spieler der diesen Namen hat automatisch Mitarbeiter der Region (das
+       betrifft Verzeichnisse, die nicht fuer Regionsmitglieder, sondern fuer
+       andere Aufgaben gedacht sind).
+     * Ein Name wird gebanisht indem man in die Gilde geht und dort `banish
+       <name>' eingibt. Bitte keine direkten Funktionsaufrufe im master!
+
+ SIEHE AUCH:
+    forscherpunkte, balance, banish
+
+ LETZTE AeNDERUNG:
+    Don,  6. Feb 2003, 13:30:56 von Zook.
diff --git a/doc/wiz/reputation b/doc/wiz/reputation
new file mode 100644
index 0000000..6e1ac20
--- /dev/null
+++ b/doc/wiz/reputation
@@ -0,0 +1,164 @@
+THEMA:
+  Reputationen
+
+
+ALLGEMEINE BESCHREIBUNG:
+  Man kann bei einer Gruppierung/Volk/Partei/etc. Ruf gewinnen oder verlieren 
+  und somit entweder deren Respekt erlangen oder auf ihrer Abschussliste 
+  landen.
+
+  Am Beispiel der Goblins im Walddorf Skoga: Dort gibt es das Freie Volk, das 
+  aus seinem Heimatdorf vertrieben wurde, und die Goblins, welche das Dorf
+  besetzt haben. Hilft man einer Seite, baut man Ruf auf und erhaelt 
+  beispielsweise Zugang zu Heilstellen und speziellen Items, waehrend die 
+  andere Seite zunehmend misstrauisch reagiert und einen schlussendlich ohne 
+  zu fragen attackiert.
+
+  Es muessen nicht immer mehrere Seiten involviert sein. Auch eine einzelne 
+  Partei ist denkbar, der man helfen kann und in deren Laeden/Kneipen man mit 
+  steigendem Ruf z.B. Verguenstigungen, mehr Informationen, Bonusitems und 
+  Aehnliches erhaelt.
+
+  Denkbar ist es auch, das Ganze zu vernetzen. Beispielsweise koennte ein 
+  Verwandter eines Mitglieds von obengenanntem Freien Volk vor den Angriffen 
+  ins Polargebiet umgezogen sein, aber von des Spielers Heldentaten gehoert 
+  haben und ihm so freundlicher gesonnen sein.
+
+
+METHODEN (s. a. einzelne Manpages):
+
+  int ChangeReputation(string repid, int value, int silent)
+      Die Funktion ist in jedem Spielerobjekt vordefiniert.
+      Vor der Aenderung wird ein Check auf die UID des ausfuehrenden Objektes
+      ausgefuehrt, "fremde" Reputationen darf man somit nicht veraendern.
+      Man kann aber selbstverstaendlich in begruendeten Faellen mit dem
+      zustaendigen Magier/Regionsmagier sprechen, ob man ebenfalls Zugriff
+      erhaelt. Eingetragen wird dies schlussendlich durch einen EM.
+
+
+  int GetReputation(string repid)
+      Ebenfalls im Spielerobjekt vordefiniert. Liefert den aktuellen Wert der
+      angegebenen Reputation zurueck.
+
+
+  mapping GetReputations()
+      Ebenso vordefiniert. Liefert ein Mapping aller im Spieler gespeicherten
+      Reputationen und ihrer Werte zurueck.
+
+
+BEISPIELE:
+
+  // Eine kleine Aufgabe fuer das "Freie Volk" bringt dem Spieler etwas 
+  // Ansehen.
+
+  void QuestGeloest(object pl) {
+    // Silent, wir geben eine eigene Meldung aus.
+    pl->ChangeReputation("freiesvolk", 250, 1);
+
+    tell_object(pl, "Du befreist einen Gefangenen. Das freie Volk wird es "
+      "Dir danken.\n");
+  }
+
+  // Ein NPC des "Schaedlspalta-Klans". Wenn er getoetet wird, verlieren die 
+  // toetenden Spieler Ruf bei dieser Fraktion.
+ 
+  #include <properties.h>
+
+  inherit "/std/npc.c";
+
+  void create() {
+    npc::create();
+    SetProp(P_SHORT, "Ein Goblin des Schaedlspalta-Klans");
+    ...
+  }
+
+  varargs void die(int poison, int ext) {
+    object *enemies;
+    int value;
+    // Begleit-NPCs brauchen keine Reputation
+    enemies = filter(PresentEnemies(), #'interactive);
+    // 50 Reputationsabzug pro Kill, aufgeteilt auf alle Gegner
+    value = -50 / sizeof(enemies);
+    foreach(object pl : enemies) {
+      pl->ChangeReputation("schaedlspalta", value);
+      // Optional koennte ihre "Feindfraktion" das gutheissen:
+      // pl->ChangeReputation("freiesvolk", abs(value));
+    }
+    return npc::die(poison, ext);
+  }
+
+  // Jeder beteiligte Feind kriegt nun eine Meldung, die in etwa lauten 
+  // koennte: "Dein Ansehen beim Schaedlspalta-Klan hat sich etwas 
+  // verschlechtert." Der NPC koennte nun Spieler automatisch angreifen, 
+  // sobald ihr Ruf zu tief gesunken ist:
+  
+  #include <reputation.h>
+
+  void init() {
+    npc::init();
+    if(objectp(this_player()) && !IsEnemy(this_player()) && 
+       this_player()->GetReputation("schaedlspalta") <= REP_DISLIKED)
+      InsertEnemy(this_player());
+  }
+
+  // Ein NPC rueckt bestimmte Informationen erst raus, sobald das Ansehen
+  // des Spielers hoch genug ist:
+
+  #include <properties.h>
+  #include <reputation.h>
+
+  inherit "/std/npc.c";
+
+  string InfoGeheimplan();
+
+  void create() {
+    npc::create();
+    SetProp(P_SHORT, "Der Kommandant des freien Volkes");
+    ...
+    AddInfo("geheimplan", #'InfoGeheimplan, "sagt: ");
+  }
+
+  string InfoGeheimplan() {
+    if(this_player()->GetReputation("freiesvolk") < REP_TRUSTED)
+      return "Das geht Dich ueberhaupt nichts an!";
+    return "Nun, ich vertraue Dir. Also, heute um Mitternacht ... ... ...";
+  }   
+
+  // Pruefung der (wichtigsten) Rueckgabewerte:
+
+  #include <reputations.h>
+  
+  void QuestGeloest(object pl) {
+    string msg;
+
+    // Sonstige Meldungen
+    ...
+
+    switch(pl->ChangeReputation("freiesvolk", 500, 1)) {
+      // Reputation bereits Max
+      case REP_RET_ALREADYMAX:
+        msg = "Dein Ansehen beim freien Volk kann sich nicht mehr weiter "
+              "verbessern.";
+        break;
+      // Reputation waere hoeher als Max geworden, daher auf Max gesetzt
+      case REP_RET_SUCCESSCUT:
+        msg = "Dein Ansehen beim freien Volk hat sich etwas verbessert, "
+              "aber weiter steigern kannst Du es nicht mehr.";
+        break;
+      // Reputation erfolgreich geaendert
+      case REP_RET_SUCCESS:
+        msg = "Dein Ansehen beim freien Volk hat sich etwas verbessert.";
+        break;
+      default:
+        // Technischer Fehler
+        break;
+    }
+
+    if(stringp(msg) && strlen(msg))
+      tell_object(pl, break_string(msg, 78));
+  }
+
+SIEHE AUCH: 
+
+LETZTE AENDERUNG:
+  2009-22-03, 12:30:00 von Nibel
diff --git a/doc/wiz/rm-howto b/doc/wiz/rm-howto
new file mode 100644
index 0000000..75b9ac7
--- /dev/null
+++ b/doc/wiz/rm-howto
@@ -0,0 +1,334 @@
+RM - HOWTO
+**********
+
+Vorlaeufiges Inhaltsverzeichnis:
+
+1) Allgemeines
+   - Fehlerteufel
+   - Logtool
+   - Kommentierung von Aenderungen
+   - eigene Anschluesse
+2) Abnahme von Code/Gebieten
+   - Balance/Genehmigungen
+   - Konzeptionelle Eignung
+   - formale Pruefung
+   - Gemeinschaftsarbeiten
+3) Verlegung von Dateien
+4) Seherhaeuser
+   - Sonderwuensche/Unsichtbarkeit
+   - anderer Befehl zum Betreten
+   - Verweise auf Beispielcode
+5) Debuggen von Code
+6) besondere Funktionen/Funktionaelitaeten
+   - catch_tell() / ReceiveMsg()
+   - move()
+   - Attack() / Defend()
+   - call_out()
+   - remove() / destruct()
+   - for()-Schleifen
+   - write_file()
+   - Verwalten von charakterbezogenen Daten
+
+1) Allgemeines
+==============
+
+o Um stets einen Ueberblick ueber die in Deiner Region (hoffentlich selten)
+  auftretenden Bugs und Warnungen zu behalten, solltest Du einen
+  Fehlerteufel (/obj/tools/fehlerteufel.c) besitzen, bedienen koennen und
+  regelmaessig dessen Listen durchsehen. Deinen Regionsmitarbeitern solltest
+  Du, allein schon, um zusaetzliche Arbeit fuer Dich selbst zu reduzieren,
+  dieses Werkzeug ebenfalls an die Hand geben und sie auffordern, ihren
+  Kram moeglichst umfassend selbst zu reparieren.
+  Neuen Magiern wird dieses Tool uebrigens automatisch von Merlin in die
+  Hand gedrueckt, so dass sie sich vom ersten Tag an daran gewoehnen koennen.
+
+o Es ist empfehlenswert, das Logtool zu besitzen (/obj/tools/logtool.c) und
+  in diesem fuer jedes Repfile eines Regionsmitarbeiters einen Eintrag vor-
+  zusehen. Warum das? Es ist bereits vorgekommen, dass Spieler ernsthaft
+  argumentiert haben, sie duerften einen von ihnen entdeckten Bug ausnutzen,
+  weil sie ihn ja gemeldet haetten (im Repfile!), er aber nicht repariert
+  worden sei (was nicht verwundert, da er im Repfile in der Mehrzahl der
+  Faelle weit unterhalb des Wahrnehmungshorizonts der allermeisten
+  Regionsmagier schwebt).
+
+o Wenn Du in fremdem Code Aenderungen vornehmen musst, die mehr beruehren
+  als nur ein paar Tippfehler in Details oder Infos, dann kommentiere den
+  defekten Code aus und fuege den reparierten mit Kommentar ein. Es reicht
+  an dieser Stelle aus, Deinen Namen und das Datum zu vermerken. In den
+  Header der Datei solltest Du unbedingt ein Changelog einfuegen, in dem
+  das Datum der Aenderung, der Name des Ausfuehrenden (Deiner) sowie die
+  vorgenommene Aenderung mit Begruendung bzw. u.U. Bug-ID aus dem Fehler-
+  teufel einzutragen ist. Wir haben im MG leider keinen wirkungsvollen
+  Debugger und Bugtracker-Mechanismus, so dass wir zur Erhaltung einer
+  gewissen Code-Hygiene Bugfixes mit Hilfe solcher Eintragungen dokumentieren
+  und rueckverfolgen muessen. Insbesondere ist ein solcher Eintrag wichtig,
+  um im Falle von Folge-Bugs die Ursache schneller zu finden.
+
+o Willst Du in Deiner eigenen Region ein Gebiet anschliessen, solltest Du
+  diesen vor Anschluss entweder vom Co-RM oder von einem RM einer anderen
+  Region lesen lassen. Auch wenn Du ein guter Programmierer bist, findet ein
+  zweites Paar Augen oft Dinge, an die man nicht gedacht hat.
+
+
+2) Code wird zur Abnahme vorgelegt
+==================================
+
+o Bei Waffen und Ruestungen unbedingt auf Einhaltung der Balance-Vorgaben
+  achten.
+
+o Sofern ein Objekt eine Balance-Genehmigung besitzt, muss die BTOP-Nummer,
+  die die Balance als eindeutige ID fuer jeden Antrag vergibt, im Header
+  des betreffenden Objektes erkennbar eingetragen sein.
+
+o Vor Anschluss sollte man Ruecksprache mit verschiedenen Instanzen halten,
+  um sicherzustellen, dass der Magier alle wesentlichen Punkte
+  beruecksichtigt hat:
+  - liegen alle Balance-Genehmigungen vor?
+  - sind die FP eingetragen?
+  - sind die ZTs eingetragen und getestet?
+  - sind Sonder-EK-Stupse genehmigt und eingetragen?
+
+o Fuer neue Gebiete ist eine grundsaetzliche Pruefung des Konzepts auf
+  Regionstauglichkeit sinnvoll, damit nicht alteingesessene Institutionen
+  oder Orte ploetzlich zur zweiten Wahl abgewertet werden - beispielsweise
+  einen grossen, neuen Hauptort in der Ebene anzuschliessen, der Port Vain
+  voraussehbar den Rang ablaufen wuerde.
+
+o Alle NPCs sollten vor Anschluss einmal gekillt werden, um sie auf
+  grundsaetzliche Kampf-Funktionsfaehigkeit zu pruefen.
+
+o Haben NPCs Namen, sollte ueberlegt werden, diese Namen ggf. zu banishen.
+  (hilfe banish).
+
+o Es existiert ein Shell-Skript, mit dessen Hilfe man offensichtliche
+  Formfehler in einem kompletten Verzeichnis ermitteln kann (Umlaute im
+  Code, zu lange Zeilen etc.), wobei bezueglich der Formalien auch auf
+  den Regionsmitarbeiter-Leitfaden fuer neue Projekte verwiesen werden
+  soll. Das Skript hierzu ist auf Anfrage bei Zesstra erhaeltlich. Der
+  Regionsmagier hat hierbei die Entscheidungsfreiheit, die Berichte dieses
+  Skripts dem Programmierer des neuen Gebiets als Anhaltspunkte zur
+  Verfuegung zu stellen, oder die Abarbeitung der gemeldeten Punkte als
+  Voraussetzung vor dem Anschluss vorzuschreiben, aber auch jede Abstufung
+  dazwischen ist OK. :-)
+  Zusaetzlicher Tip: Das Skript differenziert zwischen eigentlich nicht
+  akzeptablen Konstrukten und zumindest fragwuerdigen, d.h. man kann diese
+  Unterscheidung an den Verantwortlichen mit entsprechenden Forderungen
+  weitergeben.
+  Das Skript ist unter ftp://mg.mud.de/Software/src_check/ erhaeltlich.
+
+o Sollte ein zur Abnahme anstehendes Projekt eine (grundsaetzlich
+  selbstverstaendlich zulaessige) Gemeinschaftsarbeit sein, sollte man
+  als Regionsmagier darauf bestehen, eine sauber getrennte Codebasis
+  in unterschiedlichen Verzeichnissen vorgelegt zu bekommen, oder aber
+  eine Auflistung, welcher Beitrag von welchem Magier stammt.
+  Wenn diese Auflistung sich bis auf Funktionsebene erstrecken sollte
+  (z.B. "DoWield() ist von X, Details von Y, DefendFunc von Z"), ist
+  das unschoen und an sich abzulehnen.
+
+
+3) Verlegung von Dateien
+========================
+
+o Sollte ein Objekt aus einer anderen Region bzw. allgemein aus einem
+  anderen Verzeichnis (z.B. /players) in Deine Region verlegt werden
+  muessen, sind VOR dem Umhaengen folgende Punkte zu beachten:
+  -- Forscherpunkte muessen umgetragen werden (EM ansprechen),
+  -- Erstkill-Stufenpunkte muessen umgetragen werden (EM ansprechen),
+  -- Zaubertraenke umtragen lassen (EM ansprechen),
+  -- in Padreics Ruestungsskill umtragen lassen (EM ansprechen),
+  -- evtl. im Gebiete vorhandene Seherhaeuser umziehen,
+  -- evtl. im Gebiet vorhandene Kraeuterskill-Kraeuter beruecksichtigen,
+  -- evtl. Briefempfaenger der Postquest beruecksichtigen,
+  -- ueber die Mudlib greppen lassen, um eventuell in anderen Regionen
+     verwendete Referenzen auf die alten Pfade des umziehenden Codes
+     zu finden und dort umzustellen. Hierbei sind in Ausnahmefaellen von
+     fiesem Code auch in Spielersavefiles gespeicherte Pfade zu
+     beruecksichtigen (*ARGL*).
+
+
+4) Seherhaeuser
+===============
+
+o Die Erlaubnis zum Bau eines Seherhauses in einem Gebiet haengt einzig und
+  allein von dem verantwortlichen Magier ab. Sollte dieser laenger nicht
+  erreichbar sein (auch nicht ueber externe Mail!), liegt die Entscheidung
+  beim Regionsmagier, der aber in jedem Fall die Eignung des Bauplatzes
+  in der Umgebung bewerten muss.
+
+o Fuer Sonderwuensche bezueglich Unsichtbarkeit von Seherhaeusern oder
+  besonderer Kommandos zum Betreten des Hauses sei auf die Datei
+  /doc/beispiele/misc/seherhaus.c verwiesen, wo die Vorgehensweise
+  erlaeutert wird. Ein Beispiel einer sehr umfangreichen Implementierung
+  findet sich in /d/ebene/room/hp_str8a.c.
+
+o Bei geaenderten Befehlen zum Betreten muss beachtet werden, dass bei einer
+  Standardimplementierung die Erlaube-Liste umgangen wird, d.h. ohne
+  besondere Vorkehrungen u.U. JEDER das Haus ungehindert betreten kann.
+  Es ist hingegen moeglich, die Erlaube-Liste abzufragen und entsprechend
+  zu behandeln, ein Beispiel hierfuer ist in /d/ebene/room/hp_str8a.c
+  nachzulesen (derzeit jedoch auf Spielerwunsch deaktiviert).
+
+
+5) Debuggen von Code
+====================
+
+o Nach dem Reparieren eines Objektes ist es meist erforderlich, das
+  betreffende Objekt neu zu laden. Falls es sich dabei um Objekte handelt,
+  die z.B. in einem Raum mittels AddItem() hinzugefuegt wurden (wie etwa
+  ein NPC), dann ist es am besten, die Datei mit dem Befehl
+  <upd -ad datei.c> zu aktualisieren und somit saemtliche Clones zu
+  zerstoeren. Wenn man mittels <upd -ar datei.c> die bestehenden Clones
+  ersetzen wuerde, wuerden diese aus der Item-Liste des clonenden Raumes
+  ausgetragen, so dass dieser Raum dann im reset() neue Items erzeugt und
+  diese in der Folge doppelt existieren wuerden.
+
+
+6) besondere Funktionen
+=======================
+
+Es kommt haeufig vor, dass Funktionen ueberschrieben werden muessen, und das
+ist auch normalerweise vollkommen normal und nicht beanstandenswert. Jedoch
+sollte man bei bestimmten Funktionen einiges Augenmerk auf die korrekte
+Ausfuehrung richten. Einige Beispiele sind nachfolgend aufgefuehrt:
+
+o catch_tell() / ReceiveMsg()
+  Die Reaktion von Objekten, insbesondere NPCs, auf eingehende Textmeldungen
+  laesst sich nutzen, um schoene und stimmungsvolle Gebiete mit dynamisch
+  reagierenden Bewohnern zu schaffen. Es laesst sich auf der dunklen Seite
+  der Macht hingegen auch verwenden, um ueble Konstrukte zu realisieren,
+  fuer die es seit Ewigkeiten geeignete Implementierungen gibt, und die
+  demzufolge niemals durch eine Endabnahme durch einen RM durchschluepfen
+  duerfen. Ein paar reale NPC-Beispiele aus der Praxis:
+
+  Schnipsel 1)
+
+  if (sscanf(str, "  %s greift den Priester %s",name1, dummy) == 2)
+  {
+    pl = find_player(lower_case(name1));
+    if (!pl || !living(pl))
+      return 1;
+    else
+      Kill(pl);
+  }
+  Zweck:     Simulation von AddDefender() und InformDefend()/DefendOther()
+  Kommentar: Absolutes No-Go! Mit Echo-Faehigkeiten von Spielern (Gilde oder
+             anderweitig) ist hiermit ein indirekter Playerkill moeglich.
+             Inakzeptable Implementierung.
+
+
+  Schnipsel 2)
+
+  if (sscanf(str, "%s sagt: %s\n", wer,was))
+  {
+    if (lower_case(was)=="ja" )
+      this_player()->move(zielraum, M_TPORT);
+  }
+  Zweck:     Ausloesen eines Kommandos, ohne "sage ..." als Befehl
+             ueberschreiben zu muessen.
+  Kommentar: Ausnutzbar als Remote-Fluchtteleport, indem man die Meldung
+             mittels teile-mit an den NPC sendet:
+             "Robert teilt Dir mit: sagt: ja", was ungeprueft ein move() 
+             zur Folge hat. Offensichtlich ebenso ungeeignet wie das 
+             vorige Beispiel.
+
+
+  Schnipsel 3)
+
+  if (sscanf(lower_case(str),"%s sagt: %sversteck%s",s1,s2,s3))
+    tell_room(environment(),sprintf("Der Fisch sagt: Das ist aber keine "
+      "grosse Hilfe, %s.\n",capitalize(s1)),({TO}));
+
+  sieht erstmal harmlos aus, fuehrt aber mit der Anweisung
+
+  SetChats(8, ({ "Der Fisch sagt: Wo kann ich mich nur verstecken?"}) );
+
+  dazu, dass der NPC dauernd mit sich selber schwatzt. Kein kritischer Bug
+  im eigentlichen Sinn, aber auf jeden Fall der Atmosphaere im Gebiet
+  sehr abtraeglich.
+
+o move()
+  Ueberschreiben von move() ist eine extrem heikle Angelegenheit, bei der
+  beim kleinsten Fehler massive Probleme resultieren koennen, jedoch meist
+  nicht offensichtlich ist, woher das resultiert. Als allgemeine Empfehlung
+  sollte gelten, dass move() NIE ueberschrieben wird, und wenn, dann muss
+  ausfuehrlich und aufmerksam geprueft werden, was da passiert, und ob der
+  gewuenschte Effekt nicht anders sauberer erreicht werden kann.
+  Als zusaetzlicher Hinweis sei auf NotifyMove() und PreventMove() verwiesen,
+  mit deren Hilfe sich die allermeisten Faelle erschlagen lassen, in denen
+  Magier faelschlicherweise glauben, move() ueberschreiben zu muessen.
+
+o Defend()/Attack()
+  hier ist ein beliebter Fehler einfach der, dass man am Ende der Funktion
+  ::Defend() bzw. ::Attack() ruft, aber im Codeblock vorher das Objekt
+  durch eigenen Tod oder anderes schon zerstoert wurde. Dann geht das schief.
+  Einfach mal hinschauen - es ist aber kein wirklich gravierender Fehler,
+  da sowas im Kampf meist ziemlich schnell auffaellt.
+
+o call_out()
+  Hierzu zwei Hinweise: zum einen fuehrt call_out("x",0) seit der Umstellung
+  auf LDmud als Driver nicht mehr implizit zu einem call_out("x",1), wie es
+  zuvor war, sondern tatsaechlich zu einem fast sofortigen Funktionsaufruf der
+  Funktion x() - mit allen Konsequenzen, inklusive eines "too long eval"-
+  Bugs. Wer eine echte Verzoegerung braucht, muss mindestens call_out("x",1)
+  verwenden.
+  Zum anderen wurde mit LDmud die Granularitaet des reset()-Aufrufes auf
+  Heartbeat-Genauigkeit (2 s) verfeinert, so dass man bequem laengere
+  Verzoegerungen auf die Verwendung von reset() umstellen kann.
+
+o Zerstoeren von Objekten mit remove() oder destruct()
+  Man sollte einen sehr kritischen Blick auf Konstrukte werfen, die
+  nach einem remove() noch weiteren Code ausfuehren (Ausnahme: echte efuns 
+  und Compiler-Konstrukte wie return).
+  Wenn man Objekte zerstoeren will oder muss, sollte man immer zuerst 
+  remove() verwenden. Destruct muss dem absoluten Ausnahmefall vorbehalten 
+  bleiben. Man sollte im Hinterkopf behalten, dass Objekte gute Gruende haben
+  koennen, sich einem remove() zu verweigern.
+
+o for()-Schleifen
+  Eigentlich keine Funktion, aber an dieser Stelle doch passend:
+  for()-Schleifen sollten generell durch foreach()-Konstruktionen ersetzt
+  werden, da dies signifikant und messbar schneller ist. Die naechst-
+  schnellere Variante waere etwa folgendes, sofern die Reihenfolge der
+  Abarbeitung unerheblich ist (i ist integer, arr ist ein mixed-Array):
+
+  for ( i=sizeof(arr); i--; ) {
+    tu_etwas_mit(arr[i]);
+  }
+
+o write_file()
+  Benutzung dieser Funktion nur in begruendeten Ausnahmefaellen abnehmen, da
+  keinerlei Begrenzung der Dateigroesse existiert. Insbesondere bei Logfiles
+  entstehen hierdurch im Laufe der Zeit Monsterdateien, die nur Plattenplatz
+  verbrauchen, aber kaum zu ueberschauen sind. Statt write_file() wird in
+  den allermeisten Faellen log_file() mit der Standardgroesse von 50 kB fuer
+  Logfile und eine ggf. vorhandene Altversion (*.OLD) ausreichend sein.
+
+o Verwalten von charakterbezogenen Daten
+  Als Beispiel seien hier Statusdaten fuer den Ablauf von Quests genannt,
+  oder Highscores in irgendwelchen Toplisten. Fuer die Umsetzung dieser
+  Datenerfassung werden typischerweise zwei Techniken eingesetzt. Zum
+  einen kann ein Masterobjekt erstellt werden, das die Daten sammelt und
+  mittels save_object() dauerhaft speichert. Zum anderen kann man auch
+  Daten in einer Property im Spieler ablegen und diese je nach Anwendungs-
+  fall auf SAVE setzen.
+
+  Bei der ersten Variante wird man ueblicherweise die UID oder UUID des 
+  Spielers als Indizierungsmerkmal verwenden. Der erste Fallstrick ist nun,
+  dass die UID bei Spielern (nicht Sehern) ggf. nach einer Selbstloeschung
+  neu vergeben werden kann, so dass die Daten inkonsistent werden bzw. der
+  Spieler scheinbar schon in Eurem Master eingetragen ist, obwohl es sich
+  eigentlich um jemand ganz anderes handelt.
+  Als Abhilfemassnahme bietet sich folgendes an: 
+  a) UUID verwenden, da diese fuer jeden Spieler eindeutig ist.
+  b) Hinweis: find_player() kann auch mit UUIDs umgehen und das zugehoerige
+     Spielerobjekt ermitteln.
+  c) Man sollte ggf. auf das Mudlib-Event EVT_LIB_PLAYER_DELETION lauschen, 
+     um Spieler auszutragen, die sich loeschen, wodurch die zugehoerigen
+     Daten obsolet werden.
+
+  Bei der zweiten Variante muss man verschiedene Dinge beruecksichtigen:
+  a) nicht endlos viele Properties machen, sondern pro Thema (z.B. Quest)
+     einfach eine.
+  b) nur die Properties speichern, bei denen das wirklich noetig ist.
+  c) Speichert man Properties und die Aufgabe wird erledigt, d.h. der 
+     Inhalt der Property obsolet, muss die Property wieder geloescht werden.
diff --git a/doc/wiz/ruestungen b/doc/wiz/ruestungen
new file mode 100644
index 0000000..6c7425b
--- /dev/null
+++ b/doc/wiz/ruestungen
@@ -0,0 +1,212 @@
+ RUeSTUNGEN:
+     a. Allgemeines
+
+	Auch hier gelten die aktuellen Genehmigungsgrenzwerte. Alles, was
+	diese AC-Grenzwerte uebersteigt, ist prinzipiell 
+	genehmigungspflichtig. Die RMs sind gefordert, fuer eine ausgewogene
+	Bestueckung der Ruestungen in ihrem Gebiet zu sorgen. Nicht nur die
+	oberen Schutzwerte gilt es abzudecken, auch die weniger guten 
+	Ruestungen sollte es geben.
+
+	Als Richtwert sollte gelten: Eine gute Lederruestung hat ca. AC 20, 
+	eine stabile Jeans etwa AC 5, eine gehaertete Lederkappe AC 5. Nur 
+	so als Idee...
+
+	Besonders existierende Ruestungen wie der Lichtpanzer etc. sind 
+	definitiv zu gut, bzw. er ist fuer eine so leicht erreichbare 
+	Ruestung zu gut. Hier sollten die RMs verstaerkt darauf achten, dass 
+	nicht unbedingt der Durchschnitt der ACs bei 4/5 der Max-AC liegt, 
+	sondern dass auch hier auf eine Ruestung mit hoher AC viele mit 
+	niedrigerer AC kommen.
+
+	Ruestungen vom Typ AT_MISC duerfen keinerlei Veraenderungen im 
+	Spieler verursachen, keine Attribute veraendern noch sonstwie 
+	kampfrelevante Bedeutung besitzen oder Spieler/Gegner manipulieren. 
+	Die AC solcher Ruestungen ist immer 0 und wird nicht anders ge-
+	nehmigt. Weiter duerfen solche Ruestungen nicht ueber eine Hit-
+	und/oder DefendFunc verfuegen.
+
+     b. Properties
+
+      P_WEIGHT
+	Bitte realistisch halten. Ringe mit weit ueber 100 Gramm sind 
+	Schwachsinn, ebenso Hosen mit Gewichten unter 200 usw.
+  (BTW: Spieler koennen bei Max-Staerke (30) 33200 gr zzgl. etwaige
+   Trageskills der Gilde tragen.)
+
+      P_VALUE
+	Wert der Ruestungen sollte auch nicht zu gross sein und sich ein 
+	wenig an der AC orientieren. Ebenfalls: RMs, schaut genau hin.
+
+      P_ARMOUR_TYPE
+	Bitte sinnvoll benutzen! Kleider als Hosen definieren oder 
+	aehnliches ist unsinnig und sollte nicht genehmigt werden. Sind mal 
+	wieder die RMs fuer zustaendig. Bitte achtet drauf!
+
+	Folgende Ruestungstypen sind moeglich:
+
+	AT_ARMOUR
+		Alles was irgendwie den Torso schuetzt. Also vorn und 
+		hinten, wie ein Pullover, ein Kettenhemd, ein Panzer etc.
+	AT_CLOAK
+		Umhaenge, auch im weiteren Sinn wie Decken und Schleier. Im 
+		Prinzip das, was normalerweise nur den Ruecken schuetzt, bei 
+		Bedarf aber auch vorn herum gewickelt werden koennte.
+	AT_HELMET
+		Kopfbedeckungen jeder Art, vom normalen Hut ueber Kronen bis 
+		hin zu Stirnbaendern (wenn sie schuetzen sollen)
+	AT_TROUSERS
+		Hosen. Alles was zum ueberwiegenden Teil dazu gedacht ist, 
+		die Beine und/oder den Popo zu schuetzen, also auch 
+		Schuerzen oder Leggins. Natuerlich gehoeren auch Badehosen 
+		oder Lendenschuerze hierher. AC dann selbstverstaendlich 
+		gering.
+	AT_BOOT
+		Schuhe, Stiefel und Fussbekleidungen jeder Art.
+	AT_GLOVE
+		Handschuhe oder alles, was man so zum Schutz der oberen 
+		Extremitaeten benutzt, wie Armschoner, Glacehandschuhe, 
+		Faeustlinge, Boxhandschuhe etc.
+	AT_QUIVER
+		Koecher und aehnliches, in denen man Munition fuer 
+		Schusswaffen unterbringen kann. Schuetzen tut sowas 
+		natuerlich nicht.
+	AT_SHIELD
+		Alles, was man so anstelle der eigenen Arme in einen 
+		gegnerischen Schlag halten kann und das nicht offiziell als 
+		Waffe deklariert ist. Es sollte nicht grade aus Papier 
+		bestehen, und das Gewicht ist mit entscheidend fuer die 
+		Guete des Schildes. Sie werden sehr wenig im MG genutzt, was 
+		eigentlich seltsam ist. Schliesslich erreicht ein guter 
+		Schild die Guete von Helm, Hose und Handschuhen zusammen 
+		oder 3/4 der Qualitaet einer Ruestung. Andererseits: es gibt 
+		auch nicht sehr viele Schilde. Da herrscht Bedarf!
+	AT_RING
+		Ringe. Prinzipiell sollte gelten, das Ringe praktisch keine 
+		Schutzwirkung haben (also AC 1 oder max. 2). Nur, und dafuer 
+		sind die Dinger da, wenn sie magisch sind koennen sie 
+		zusaetzliche Funktionen haben.
+	AT_AMULET
+		Im Prinzip dasselbe wie bei AT_RING, nur werden die Dinger 
+		meist an Kordeln um den Hals oder als Broschen an den 
+		Klamotten getragen, koennten also je nach Groesse 
+		tatsaechlich mehr Schutz bieten als ein Ring. Aber auch hier 
+		gilt: AC>2 schreit nach Erklaerung und sollte magischen 
+		Dingern vorbehalten bleiben.
+	AT_BELT
+		Guertel aller Art (z.B. Waffenguertel oder Magisterguertel 
+		der Zauberer). Schutzwirkung hat sowas natuerlich kaum.
+	AT_MISC
+		Alles, was man sonst noch so anziehen kann, was aber eher 
+		als Zierrat gedacht ist. AC immer 0. Bitte *keine* 
+		Kleidungsstuecke, die in eine der anderen Kategorien passen, 
+		als AT_MISC definieren. Dann lieber die AC sehr tief. Wenn 
+		es eh als Gag gedacht ist koennen die Spieler sich auch bei 
+		Bedarf umziehen.
+		Solche Ruestungen duerfen keinerlei (!) Bedeutung im Kampf 
+		fuer den Spieler haben. Keinerlei Veraenderungen im/an 
+		Spieler/Gegner verursachen oder aehnliches.
+
+      P_AC
+	siehe Tabelle weiter unten
+
+      P_EFFECTIVE_AC
+	Falls eine DefendFunc vorhanden ist und die regulaere AC veraendert, 
+	sollte sie gesetzt werden. Es wird der Durchschnittswert der AC 
+	incl. der DefendFunc gesetzt. Dient der Kaempfergilde zur 
+	Einschaetzung.
+
+      P_DAM_TYPE
+	Auch Ruestungen koennen einen Damage-Typ haben. Nutzen tut das 
+	bisher nur die Kaempfergilde, aber schaden tut's keinem. Default ist 
+	DT_BLUDGEON.
+
+      P_NOBUY
+	Alle Ruestungen ab 2/3 der maximal fuer den jeweiligen Ruestungstyp 
+	zulaessigen AC werden beim Verkauf im Laden einbehalten. Dennoch 
+	sollten besondere Ruestungen P_NOBUY gesetzt haben. Insbesondere 
+	waere das fuer alles mit DefendFuncs zu wuenschen, aber auch Sachen, 
+	die als Gag gedacht sind. Dafuer koennen sich die Spieler ruhig 
+	etwas recken.
+
+    c. Spezialruestungen/Ruestungen mit Sonderfunktion
+
+	Alle Ruestungen, die ueber eine DefendFunc oder aehnliches verfuegen 
+	sind genehmigungspflichtig.
+
+	Prinzipiell sollten die geltenden Grenzwerte (s.u.) nicht 
+	ueberschritten werden; Ausnahmen koennen unter Umstaenden genehmigt 
+	werden. Immer ist der Return-Wert per random() zurueckzuliefern, da 
+	der Wert ohne weiteres random() aufaddiert wird.
+
+	WearFuncs, die Restriktionen vorsehen (Geschlechtsabhaengigkeit,
+	Rassen- oder Gildenrestriktionen) sollten die RMs ueberpruefen.
+
+	Saemtliche Sonderfunktionen, wie Heilungen, Sonderattacken auf 
+	Gegner, Waffenbeschaedigungen etc. muessen genehmigt werden.
+
+  Die Properties, mit denen Handschuhe 'handfrei' bzw 'fingerfrei' gemacht
+  werden, duerfen nur vergeben werden, wenn die Handschuhe den Schaden der Hand
+  nicht veraendern und die Beschreibung der Handschuhe dazu passt.
+
+
+    d. AC- und Genehmigungsgrenzen
+
+	Folgende Grenzwerte gelten derzeit:
+
+	+--------------+--------+----------------------------+
+	| Ruestungstyp | MAX_AC | Genehmigungsgrenze (inkl.) |
+	+--------------+--------+----------------------------+
+	| AT_AMULET    |    2   |	      --	     |
+	+--------------+--------+----------------------------+
+	| AT_ARMOUR    |   50   |	      38	     |
+	+--------------+--------+----------------------------+
+	| AT_BELT      |    2   |	      --	     |
+	+--------------+--------+----------------------------+
+	| AT_BOOT      |    6   |		5	     |
+	+--------------+--------+----------------------------+
+	| AT_CLOAK     |   10   |		8	     |
+	+--------------+--------+----------------------------+
+	| AT_GLOVE     |    5   |		5	     |
+	+--------------+--------+----------------------------+
+	| AT_HELMET    |   15   |	      13	     |
+	+--------------+--------+----------------------------+
+	| AT_QUIVER    |    0   |	      --	     |
+	+--------------+--------+----------------------------+
+	| AT_RING      |    2   |	      --	     |
+	+--------------+--------+----------------------------+
+	| AT_SHIELD    |   40   |	      28	     |
+	+--------------+--------+----------------------------+
+	| AT_TROUSERS  |   15   |	      13	     |
+	+--------------+--------+----------------------------+
+	+--------------+--------+----------------------------+
+	| AT_MISC      |    0   |	      --	     |
+	+--------------+--------+----------------------------+
+
+     e. Ruestungen fuer Zauberer
+
+	Zauberer werden normalerweise durch Ruestungen behindert. Gibt man 
+	der Ruestung jedoch die in `/p/zauberer/zauberer.h' definierte ID 
+	GILDEN_ROBEN_ID, behindert die Ruestung Zauberer nicht mehr. Das 
+	Setzen dieser ID ist auf jeden Fall mit dem Chef der Zauberergilde 
+	abzuklaeren sowie mit der Objektbalance!
+
+	Zaubererruestungen koennen ausserdem bestimmte Zaubersprueche 
+	unterstuetzen, naeheres dazu ebenfalls beim Zauberergildenchef sowie 
+	bei der Objektbalance.
+
+     f. Ruestungen mit sonstigen Gildenfaehigkeiten
+
+	Ruestungen, die in irgend einer Weise die Faehigkeiten der Gilden 
+	spezifisch veraendern (zum Beispiel die Schadensart der Karatekas 
+	oder des akshara der Tanjian veraendern) sind auf jeden Fall mit den 
+	Gildenchefs der jeweiligen Gilde sowie mit der Objektbalance 
+	abzusprechen.
+
+ SIEHE AUCH:
+     balance, waffen, fernwaffen, uniques, npcs, grenzwerte,
+     attributsveraenderungen, resistenzen, kampfobjekte
+
+ LETZTE AeNDERUNG:
+  18.10.2010, Zesstra
+
diff --git a/doc/wiz/schadenstypen b/doc/wiz/schadenstypen
new file mode 100644
index 0000000..b8f0909
--- /dev/null
+++ b/doc/wiz/schadenstypen
@@ -0,0 +1,47 @@
+Schadenstypen:
+
+Es werden zwei Arten von Schadenstypen unterschieden:
+
+a) physikalische Schadenstypen
+
+   DT_BLUDGEON      Schlagschaden, z.B. Keulen
+   DT_EXPLOSION     Schaden durch eine Explosion
+   DT_PIERCE        Stechschaden, z.B. Lanzen
+   DT_RIP           Reissender Schade, z.B. Krallen
+   DT_SLASH         Schnittschaden, z.B. Schwerter
+   DT_SQUEEZE       Quetschschaden, z.B. Tentakel
+   DT_WHIP          Peitschenschaden, z.B. Peitschen
+
+   Alle physikalischen Schadenstypen stehen auch in dem Mapping
+   PHYSICAL_DAMAGE_TYPES.
+
+b) magische Schadenstypen
+
+   DT_ACID          Saeureschaden
+   DT_AIR           Luft(mangel)schaden
+   DT_COLD          Kaelteschaden
+   DT_FIRE          Feuerschaden
+   DT_HOLY          Heiliger Schaden
+   DT_LIGHTNING     Blitzschaden
+   DT_MAGIC         Genereller magischer Schaden
+   DT_POISON        Giftschaden
+   DT_SOUND         Laermschaden
+   DT_TERROR        Angstschaden
+   DT_UNHOLY        Unheiliger/daemonischer Schaden
+   DT_WATER         Wasserschaden
+
+   Alle magischen Schadenstypen stehen auch in dem Mapping
+   MAGICAL_DAMAGE_TYPES.
+
+Eine Liste aller definierten Schadenstypen steht ausserdem in dem
+Array ALL_DAMAGE_TYPES.
+
+Alle Schadenstypen und zusammengefasste Gruppen sind definiert in
+<combat.h>
+
+Waffen duerfen maximal 50% mag. Schaden machen. Die Summe der mag.
+Schaeden darf maximal 66% betragen. Es _muss_ immer mind. ein phy.
+Schaden gesetzt sein.
+
+----------------------------------------------------------------------------
+Last modified: Mit, 03.01 12:00:54 2002 von Tilly
diff --git a/doc/wiz/scheidung b/doc/wiz/scheidung
new file mode 100644
index 0000000..d44c5d8
--- /dev/null
+++ b/doc/wiz/scheidung
@@ -0,0 +1,95 @@
+
+                          Scheidung einer MG-Ehe
+                          ======================
+
+  Die Hochzeit im MorgenGrauen ist ein sehr unterschiedlich durchgefuehrtes
+  Ritual, das mit der Hilfe von NPCs oder auch Spielern vorgenommen werden
+  kann. Aufgrund dieser Vielfalt muessen einige Dinge beachtet werden, wenn
+  man eine Hochzeit rueckgaengig machen will.
+
+  Da dabei auch Properties im Spieler geloescht, ggf. Logfiles editiert und
+  Objekte im Spielerinventar zerstoert werden muessen, empfiehlt es sich,
+  diesen Vorgang von einem Magier mit entsprechender Erfahrung und insbeson-
+  dere den noetigen Schreibrechten in der Unterwelt durchfuehren zu lassen.
+
+  1) Grundsaetzliches zur Hochzeit
+ 
+     a) P_MARRIED:
+
+        Property im Spieler, die den Namen des Ehepartners als lowercase 
+        String enthaelt (UID, z.B. "boing"). Diese Property wird von allen 
+        Objekten, die eine Hochzeit durchfuehren koennen, identisch
+        verwendet.
+
+     b) Priester:
+
+        Neben Mitgliedern der Klerus-Gilde koennen Hochzeiten von folgenden
+        NPCs durchgefuehrt werden:
+        /d/unterwelt/chris/monster/priester.c     (Kapelle in der Unterwelt)
+        /d/polar/files.chaos/feuerwehr/mon/cl2_xruur.c       (Chaospriester)
+
+     c) Verlobungs- und Eheringe:
+        
+        Als Eheringe kommen verschiedene Objekte im MG zum Einsatz:
+        /d/unterwelt/chris/objekte/ring.c       (Ring vom Unterweltpriester)
+        /d/polar/files.chaos/feuerwehr/obj/cl2_ehering.c    (schwarzer Dorn)
+        /gilden/files.klerus/ehering.c                (Ring der Klerusgilde)
+
+        Zusaetzlich existiert noch ein Verlobungsring von Rikus:
+        /players/rikus/obj/verlring.c
+        Ein verheirateter Spieler kann diesen Ring zusaetzlich im Inventar
+        haben. Er wird bei der eigentlichen Hochzeit nicht zerstoert.
+
+        Die beiden Ehepartner sowie das Datum des Hochzeitstags werden 
+        zusaetzlich zur Spieler-Property (s. 1a) als Autoload-Daten 
+        in den Ringen abgespeichert.
+
+     d) Logfiles:
+ 
+        Je nachdem, welcher Priester die Hochzeit durchfuehrt, wird der
+        erfolgreiche Abschluss der Zeremonie in unterschiedlichen Logs
+        protokolliert.
+
+        - Die Bluthochzeit der Chaoten in
+          /d/polar/files.chaos/feuerwehr/save/BuchDerHassenden
+        - Die Hochzeit der Kleriker in
+          /log/klerus/HEIRAT
+        - Die Hochzeit in der Unterwelt-Kapelle in
+          /d/unterwelt/chris/HOCHZEITSBUCH
+          und
+          /log/hochzeiten.chris
+
+  2) Vorgehensweise zur Aufloesung der Ehe
+
+     a) Loeschen von P_MARRIED in _beiden_ Spielern (SetProp(P_MARRIED,0))
+        und anschliessendes Speichern des Spielers
+
+     Ist der zweite Spieler netztot, kann die Property direkt gesetzt werden.
+     Sollte der zweite Spieler nicht existieren, weil er inzwischen 
+     geloescht wurde, reicht es, die Property im verbleibenden Spieler 
+     zu aendern (dies wird haeufig auch der Grund der Bitte um Scheidung
+     sein).
+
+     Sollte der zweite Spieler in der laufenden Uptime noch nicht eingeloggt
+     gewesen sein, kann die Property nur von einem Erzmagier mit Hilfe 
+     der Funktion __create_player_dummy() zurueckgesetzt werden.
+
+     b) Zerstoeren _beider_ Eheringe. Falls jedoch von dem Ehepartner 
+        kein Spielerobjekt existiert, ist es nicht moeglich, dessen 
+        Ehering zu zerstoeren.
+
+     c) zerstoeren evtl. vorhandener Verlobungsringe, falls gewuenscht.
+
+     d) Im Fall von Hochzeiten, die in der Unterweltkapelle durchgefuehrt
+        wurden, ist es offenbar Tradition, dass die Scheidung dort in Form
+        eines Zusatzes zum Logfile-Eintrag nachgetragen wird. Beispiel:
+        [...] "Cassandra und Viper  (ges.: Don, 02. Nov 1995, Wargon)"
+        Dies soll auch in Zukunft beibehalten werden. Fuer die Aenderung
+        sind Schreibrechte in der Region Unterwelt erforderlich.
+
+
+  SIEHE AUCH:
+     Properties:  P_MARRIED
+     Klerusgilde: man traue (/doc/g.klerus/traue)
+
+Arathorn, 04.01.2010
diff --git a/doc/wiz/scoremaster b/doc/wiz/scoremaster
new file mode 100644
index 0000000..c32319f
--- /dev/null
+++ b/doc/wiz/scoremaster
@@ -0,0 +1,213 @@
+Der Scoremaster
+===============
+
+BESCHREIBUNG
+
+  Funktion: Verwaltung der Erstkill-Stufenpunkte, die fuer das Toeten von
+  NPCs vergeben werden. Fuer alle NPCs, die mehr als 200000 XP
+  (SCORE_LOW_MARK) geben, wird ein Stufenpunkt vergeben. Ab 600000 XP
+  (SCORE_HIGH_MARK) sind es 2 Stufenpunkte. Ueber diese Werte hinausgehende
+  Punkte muessen beantragt und manuell ueber den Scoremaster eingetragen
+  werden.
+
+  Jeder NPC, der mindestens einen Stufenpunkt gibt, wird automatisch in
+  eine Liste temporaerer EKs eingetragen, die vom EK-Maintainer einzeln
+  bestaetigt werden muessen. Dieses Verfahren ist erforderlich, weil der
+  bis vor einiger Zeit eingesetzte Mechanismus, EKs automatisch einzutragen,
+  dazu gefuehrt hat, dass eigentlich nicht als EK vorgesehene oder erlaubte,
+  aber auch laengst wieder abgehaengte oder gar nie angeschlossene NPCs
+  eingetragen waren. Da aus dem Scoremaster auch die von Brumni in der
+  Fraternitas ausgegebenen EK-Tips abgefragt werden, ist das natuerlich fatal
+  fuer Spieler, wenn sie Tips bekommen, die sie nicht erreichen koennen.
+
+  Die Liste der Erstkills ist ein Mapping, das als Keys eine fortlaufende
+  Nummer enthaelt, zu der jeweils die Daten des NPCs zugeordnet sind. Diese
+  Nummer dient vor allem auch zur Indizierung des Bitstrings im Spieler,
+  in dem die Erstkills gespeichert werden.
+
+  Diese Datei dokumentiert die Funktionalitaet des Scoremasters fuer die
+  Benutzung durch EM und EK-Maintainer, jedoch nicht die vollstaendige
+  interne Arbeitsweise und Verwaltung der Daten.
+
+  Inhaltsverzeichnis dieser Dokumentation
+  1) Neueintragung von EKs
+  2) Verwaltung der unbestaetigten EKs
+  3) Aenderungen an bestehenden EKs
+  4) Spielerbezogene Daten verwalten
+  5) Daten von NPCs abfragen
+  6) Permanentes Loeschen von EKs
+  7) Verwaltung der EK-Tips von Brumni
+  8) Sonstige Funktionen (nur von NPCs gerufen)
+
+
+RUECKGABEWERTE:
+
+  SCORE_INVALID_ARG   -1
+  SCORE_NO_PERMISSION -2
+
+
+FUNKTIONEN
+
+1) Neueintragung von EKs
+
+  NewNPC(string key, int score)
+  AddNPC(string key, int score) [veraltet, leitet an NewNPC weiter]
+        Neuen NPC eintragen, key ist hierbei der Pfad, score die Punktzahl
+        Die ID des EKs wird automatisch ausgewaehlt, indem der naechste
+        freie Platz im Mapping belegt wird.
+
+
+2) Verwaltung der unbestaetigten EKs
+
+  ConfirmScore(mixed key)
+        unbestaetigten EK mit der Nummer oder dem Pfad "key" genehmigen
+    =>  EK in den Spielern setzen und Statistik hochzaehlen,
+    =>  EK aus der Liste der unbestaetigten EKs in die Liste der aktiven
+        uebertragen,
+
+  RejectScore(mixed key)
+        unbestaetigten EK mit der Nummer oder dem Pfad "key" ablehnen
+    =>  Eintrag aus der Liste der unbestaetigten EKs loeschen
+    =>  Bit-Nr. in die Liste der freien Nummern eintragen
+
+  DumpUnconfirmedScores()
+        unbestaetigte NPCs an den abfragenden Magier ausgeben
+
+
+3) Aenderungen an bestehenden EKs
+
+  SetScore(mixed key, int score)
+        Punktzahl fuer bereits eingetragenen NPC aendern, key ist der Pfad
+        oder die NPC-Nummer, score die neue Punktzahl
+
+  RemoveScore(mixed key)
+        Setzt die Punktzahl auf 0. Solche EKs koennen spaeter durch Angabe
+        einer neuen Punktzahl reaktiviert werden.
+        Alternativ kann fuer diese Funktion auch SetScore(mixed key, 0)
+        verwendet werden.
+        key kann hierbei der Pfad oder die NPC-Nummer sein
+
+  MoveScore(mixed oldkey, string newpath)
+        Verlegt einen EK
+        oldkey ist der aktuelle Pfad oder die Nummer
+        newpath ist der neue Pfad
+
+
+4) Spielerbezogene Daten verwalten
+
+  HasKill(mixed pl, mixed npc)
+        fragt ab, ob der Spieler "pl" den Kill "npc" hat
+        pl kann hierbei der Spielername oder das Spielerobjekt sein,
+        npc der Pfad oder dessen Nummer
+
+  SetScoreBit(string pl, int bit)
+        Mit dieser Funktion wird dem Spieler "pl" der EK mit der Nummer
+        "bit" gutgeschrieben.
+
+  ClearScoreBit(string pl, int bit)
+        Mit dieser Funktion wird dem Spieler "pl" der EK mit der Nummer
+        "bit" permanent ausgetragen.
+
+  QueryKillPoints(mixed pl)
+        liefert die Anzahl der Stufenpunkte zurueck, die dem Spieler pl
+        durch die aktiven EKs gutgeschrieben wurden
+
+  getFreeEKsForPlayer(object player)
+        liefert alle EKs, die aktiv sind, und die der Spieler noch nicht
+        hat, in einem Mapping entsprechend der Liste "npcs" zurueck.
+
+  QueryAllKills(string pl)
+        liefert alle Kills des Spielers als Bitstring zurueck, auch solche,
+        die momentan ausgetragen/deaktiviert sind
+        pl ist hierbei der Spielername als String
+
+  QueryKills(string pl)
+        liefert die aktiven Kills des Spielers als Bitstring zurueck
+        pl ist hierbei der Spielername als String
+
+
+5) Daten von NPCs abfragen
+
+  QueryNPCbyNumber(int num)
+        liefert die Daten des NPCs mit der Nummer "num" als Array zurueck
+
+  QueryNPCbyObject(object o)
+        liefert die Daten des NPCs mit dem Objekt "o" als Array zurueck
+
+
+6) Permanentes Loeschen von EKs
+
+  MarkEKForLiquidation(mixed key)
+        entfernt einen EK endgueltig und unwiderruflich und gibt die Nr.
+        wieder frei.
+        Technisch wird der EK erstmal in eine Liste eingetragen. Im Reset
+        iteriert der Master ueber alle Spieler-Savefiles und loescht den EK
+        aus allen Spielern. Nach Abschluss wird der Eintrag in "npcs"
+        geloescht und seine Nr. in die Liste freier Nummern eingetragen.
+
+  UnmarkEKForLiquidation(mixed key)
+        Entfernt die Loeschmarkierung von einem EK
+    =>  Dies geht nur, solange nach einem MarkEKForLiquidation() noch kein
+        reset() gelaufen ist!
+
+  QueryLiquidationMarks()
+        Fragt die fuer Loeschung vorgesehenen EKs ab.
+
+  RestoreEK(string key, int bit, int score)
+        restauriert die Daten eines frueher geloeschten, in den Spielern noch
+        enthaltenen EKs. Moeglich nur dann, wenn der EK frueher mal geloescht
+        wurde, aber in den Bitstrings in den Spielern noch eingetragen ist.
+        Es werden Pfad, Nr. und Punkte benoetigt.
+        Fuer nach dem Umbau des Scoremasters geloeschte EKs nicht mehr
+        moeglich, weil diese permanent aus den Bitstrings ausgetragen wird.
+
+
+7) Verwaltung der EK-Tips von Brumni
+
+  addTip(mixed key,string tip)
+        Traegt fuer den NPC mit der Nummer oder dem Pfad "key" einen EK-Tip-
+        Text fuer Brumni ein.
+
+  changeTip(mixed key,string tip)
+        Aendert den durch Brumni auszugebenden EK-Tip fuer den NPC mit der
+        Nummer oder dem Pfad "key". Der neue Tip wird dabei als 2. Parameter
+        "tip" uebergeben.
+
+  removeTip(mixed key)
+        Loescht den durch Brumni auszugebenden EK-Tip-Spruch. Der Tip als
+        solcher bleibt bestehen - anschliessend wird wieder der Standard-
+        Spruch ausgegeben.
+
+  getTip(mixed key)
+        Gibt den Tip-Spruch fuer den NPC mit der Nummer oder dem Pfad
+        "key" zurueck, oder den Standard-Spruch. Liefert fuer nicht
+        eingetragenen "key" den Leerstring zurueck.
+
+  QueryTipObjects(mixed player)
+        Gibt die Objektnamen der EK-Tips des jeweiligen Spielers zurueck.
+
+  allTipsForPlayer(object player)
+        Gibt den Gesamtstring aller Tips des Spielers "player" zurueck.
+
+  playerMayGetTip(object player)
+        Fragt ab, ob der Spieler "player" einen Tip bekommen kann.
+
+  giveTipForPlayer(object player)
+        Waehlt einen zufaelligen EK aus, den der Spieler noch nicht hat, und
+        traegt diesen im Master in die Liste ein, die mit allTipsForPlayer()
+        abgefragt werden kann.
+
+
+8) Sonstige Funktionen (nur von NPCs gerufen)
+
+  GiveKill(object pl, int bit)
+        schreibt dem Spieler "pl" den EK mit der Nummer "bit" gut.
+        Diese Funktion wird ausschliesslich aus NPCs heraus gerufen.
+
+  QueryNPC(int score)
+        Wird vom getoeteten NPC gerufen, um zu ermitteln, ob dieser einen
+        Erstkill gibt. Wenn der EK noch nicht existiert, wird dieser im
+        Master zunaechst in der Liste der unbestaetigten EKs eingetragen
+        Direkte Abfrage dieser Funktion von aussen z.B. durch Magier nicht
+         moeglich, weil nicht sinnvoll.
+
diff --git a/doc/wiz/seil b/doc/wiz/seil
new file mode 100644
index 0000000..4086842
--- /dev/null
+++ b/doc/wiz/seil
@@ -0,0 +1,68 @@
+
+Dokumentation fuer das Std-Seil: /obj/seil.c
+
+Abhaengigkeiten: /sys/thing/seil.h
+
+Das Standard-Seil ermoeglichst das Festbinden und Loesen eines Seiles an
+Objecten und Raeumen. Es kann im ganzen Morgengrauen verwendet werden.
+
+in den Objecten, die festgebunden werden, wird die Propertie P_TIED gesetzt.
+Sie enthaelt ein Mappng der Form:
+
+([
+
+ objectid: ([ "player" : playerid, "time" : timestamp ])
+
+])
+
+Wenn ein Object festgebunden wird, so wird die Funktion tie() in dem Object
+aufgerufen. Die Funktion muss in dem Object vorhanden sein. Liefert die
+Funktion 1 zurueck, darf man ein Seil daran binden.
+
+Aus der Funktion heraus kann im Seil in der Propertie P_TIE_USER ausgelesen
+werden, welche User die Aktion ausgeloest hat.
+(Diese Daten werden aus Kompatibilitaetsgruenden nicht an die Fkt. direkt
+uebergeben.)
+
+Wird ein Seil wieder losgebunden, so wird die Funktion 
+untie()
+in dem Object aufgerufen. 
+
+Damit ein Seil in einem Raum festgebunden werden kann, muss der Raum eine
+id() bekommen - wie ein normales Object.
+
+In den Funktionen tie() und untie() kann jeweils ueberprueft werden, ob ein
+Spieler ein Seil benutzen darf oder nicht. Liefern die Funktionen 0 zurueck,
+so wird die Benutzung des Seiles verweigert.
+
+Die Funktion seil->query_tied_to_ob() liefert das Object zurueck, an welches
+ein Seil gebunden ist oder 0;
+
+Bei der Benutzung eines Seiles im Raum wird zur Beschreibung die Funktion
+name() aufgerufen. Es kann also P_NAME gesetzt werden oder direkt name() im
+Raum ueberschrieben werden.
+
+Seile koennen ueber NPC's/Raeume und Zauber gesteuert werden:
+
+varargs int binde_seil(string ziel, string msg)
+
+	Ziel beschreibt das Object oder Raum, wo es festgebunden werden soll
+	msg ist die Ausgabe. Wird msg nicht gesetzt, so wird eine 
+	    Standard-Ausgabe ausgegeben.
+
+varargs int loese_seil(string msg)
+	Das Seil wird geloest - es wird dabei die msg in den Raum
+        ausgegeben. Ist msg nicht definiert, wird eine Standardausgabe
+    	erzeugt.
+
+
+Beide Funktionen werden wir von enem Spieler behandelt - es werden tie() und
+untie() in den festgebundenen Objecten ausgewertet.
+
+Eine weitere Propertie ist P_TIE_AUTO.
+Dieser Wert steht per Default auf 1 und erlaubt damit eine automatische
+Benutzung des Seiles ueber die Funktionen binde_seil() und loese_seil().
+Ist diese Propertie auf 0, so koennen nur Spieler das Seil benutzen.
+
+
+Letzte Änderung: 25.6. Gando
diff --git a/doc/wiz/sensitive b/doc/wiz/sensitive
new file mode 100644
index 0000000..9a920a1
--- /dev/null
+++ b/doc/wiz/sensitive
@@ -0,0 +1,67 @@
+Sensitive Objekte
+
+Man kann ein Objekt mit der Property P_SENSITIVE dazu veranlassen, auf
+gewisse Dinge zu reagieren. Wenn diese Property benutzt wird, sollte sie ein
+Array von Arrays enthalten, das so aussieht:
+
+({ ({ ereignis1, key1, grenzwert1 (,Optionen1) }),
+   ({ ereignis2, key2, grenzwert2 (,Optionen2) }),
+   ...
+   ({ ereignisN, keyN, grenzwertN (,OptionenN) }) })
+
+Folgende moegliche Ereignisse sind in <sensitive.h> definiert:
+
+SENSITIVE_ATTACK - reagiert auf Angriff.
+     In diesem Fall ist der Key der Schadenstyp und der Grenzwert der
+     Schaden, ab dem die Funktion trigger_sensitive_attack() in dem Objekt
+     aufgerufen wird. Diese Funktion bekommt uebergeben:
+       1. Den Feind
+       2. Den Key (nicht ALLE Schadenstypen)
+       3. Den Schaden
+       4. Das Argument spell von Defend()
+       5. Die Optionen, und zwar alles nach dem Grenzwert als Array.
+
+     Bemerkungen:
+        o Der Schaden nach Abzug durch Ruestungen und vor Beruecksichtigung
+          von Resistenz und Koerperschutz ist ausschlaggebend.
+        o Ein Ereignis kann mit verschiedenen Keys mehrfach angegeben
+          werden.
+SENSITIVE_INVENTORY - reagiert auf bestimmte Objekte im Inventory.
+     Ein solches Objekt reagiert auf andere Objekte empfindlich, die
+     sensitiv sind und SENSITIVE_INVENTORY_TRIGGER mit dem gleichen Key und
+     einem hoeheren Grenzwert ausloesen.
+
+     Es ist dabei egal, welches der beiden Objekte zuerst da war. In einem
+     solchen Objekt wird dann die Funktion trigger_sensitive_inv()
+     aufgerufen, und zwar mit folgenden Argumenten:
+       1. Das ausloesende Objekt (Das mit Ereignis
+          SENSITIVE_INVENTORY_TRIGGER)
+       2. Der Key
+       3. Der Grenzwert des ausloesenden Objekts
+       4. Die Optionen des ausloesenden Objekts
+       5. Die Optionen des reagierenden Objekts
+SENSITIVE_INVENTORY_TRIGGER - siehe oben
+     Mit diesem Objekt selber geschieht nichts, es loest nur Funktionen in
+     anderen Objekten aus (siehe oben).
+
+In Planung ist noch:
+
+SENSITIVE_ENVIRONMENT_CHANGE (falls im Inventory von Lebewesen)
+
+Die Einsatzmoeglichkeiten sensitiver Objekte sind vielfaeltig:
+
+   * Dynamit koennte jetzt SENSITIVE_ATTACK mit DT_FIRE und z.B. Grenzwert
+     150 haben, die Funktion trigger_sensitive_attack() sollte dann z.B. die
+     Zuendschnur anzuenden...
+   * Bei Nitroglycerin entsprechend mit DT_BLUDGEON, einem sehr kleinen
+     Grenzwert und einer trigger_sensitive_attack()-Funktion, die BUMM
+     macht...
+   * Es soll auch Dinge geben, die man besser NICHT gleichzeitig am gleichen
+     Ort aufbewahren sollte... Fuer solche Dinge sind SENSITIVE_INVENTORY
+     und SENSITIVE_INVENTORY_TRIGGER da.
+   * SENSITIVE_ENVIRONMENT_CHANGE ist dafuer vorgesehen, dass Objekte im
+     Inventory empfindlich auf Tauchen oder Aufenthalt an heissen Orten usw.
+     reagieren, dies ist jedoch noch in Planung.
+
+----------------------------------------------------------------------------
+Last modified: Wed May 8 10:00:28 1996 by Wargon
diff --git a/doc/wiz/sheriff b/doc/wiz/sheriff
new file mode 100644
index 0000000..4fb8366
--- /dev/null
+++ b/doc/wiz/sheriff
@@ -0,0 +1,41 @@
+Was ist zu tun, wenn ich jemanden bei einem Regelverstoss erwische?
+===================================================================
+
+        Grundsaetzlich solltet ihr den Sheriff, einen der Deputies oder
+        einen Erzmagier benachrichtigen.
+
+        Ist kein Magier aus dieser Gruppe anwesend oder sind diese nicht
+        ansprechbar, so empfiehlt sich die folgende Handlungsweise.
+
+        Sprecht den Spieler auf sein Fehlverhalten an und weist ihn darauf
+        hin, dass dies an den Sheriff gemeldet wird, damit er die
+        Gelegenheit hat seine Sicht der Situation festzuhalten und
+        ebenfalls an den Sheriff zu senden.
+        Dieser Hinweis sollte deutlich erfolgen und auch eventuelle Taub-
+        oder Blindheit beruecksichtigen, es empfiehlt sich tell_object()
+        bzw. echoto zu verwenden.
+
+        Sollte der Spieler nicht reagieren und mit seinem Verhalten andere
+        Spieler im Spiel beeintraechtigen, so sollte er nach /room/jail
+        befoerdert werden. Verwendet dazu bitte die Methode move im
+        Player, anstatt ins Jail zu gehen und ihn dann zu transen. Bei
+        letzterem setzt Ihr euch selbst fest.
+
+        Bitte seht von Zaps, Disconnects oder Aehnlichem ab, soweit andere
+        Moeglichkeiten bleiben. Bei den, durchaus nicht unueblichen,
+        obszoenen Level-1-Rufern ist ein Disconnect durchaus angebracht.
+
+        Sendet dem Sheriff eine kurze Beschreibung der Situation und was
+        Ihr unternommen habt.
+
+        Bitte ueberprueft sorgfaeltig bevor Ihr handelt, ob es sich
+        ueberhaupt um einen Regelverstoss handelt und ob die Situation
+        nicht auch ohne obige Eingriffe geklaert werden kann.
+
+
+ SIEHE AUCH:
+    leitfaden
+
+ LETZTE AeNDERUNG:
+    Wed, 30.08.2000, 11:35:00 von Muadib
+
diff --git a/doc/wiz/simul_efuns b/doc/wiz/simul_efuns
new file mode 100644
index 0000000..8670801
--- /dev/null
+++ b/doc/wiz/simul_efuns
@@ -0,0 +1,47 @@
+Allgemein nuetzliche simul_efun's:
+
+file_time(string filename) liefert die Accesstime des Files in Sekunden seit
+	1.1.1970 (das kann man als input fuer ctime oder dtime verwenden).
+
+query_wiz_level(mixed player) bekommt einen Spielernamen oder ein Spieler-
+	Object als argument und liefert den Magierlevel (siehe auch 
+	/secure/wizlevels.h)
+
+query_wiz_grp(mixed player) wie query_wiz_level, liefert aber die Magier-
+	Gruppe (auch wizlevels.h)
+
+mixed *exclude_array(mixed *arr,int from,int to) liefert den array ohne die
+	arr[0..from-1]+arr[to+1..<1]
+
+mixed *remove_alist(mixed key,mixed *alist) nimmt das Elem. mit Schluessel
+	key aus der Alist heraus.
+
+mixed *exclude_alist(int i,mixed *alist) nimmt das Element mit der Nummer i
+	aus der Alist.
+
+string dtime(int wann) wie ctime, aber deutsch (macht aus der Zahl, die time
+	usw liefern, einen lesbaren String)
+
+varags string
+	break_string(string str, int width, mixed indent, int leave_my_lfs)
+	bricht einen String um auf Weite width, man kann einen indent-String
+	angeben, der vor jeden Teilstring gehaengt wird, oder auch eine Zahl
+	dann werden entsprechen viele Leerzeichen dorthin gehaengt. Der letzte
+	Parameter legt fest, ob bereits existierende Linefeeds erhalten bleiben
+	oder nicht.
+
+string uptime() liefert genau diese in lesbarer Form.
+
+public object *all_environment(object ob) liefert einen Array mit dem re-
+	kursiven Environment (den Beutel, in dem ob steckt, den Spieler,
+	der den Beutel traegt, und den Raum, in dem sich der Spieler aufhaelt.
+
+varargs mixed match_living(string str, int players_only)
+	bekommt einen String. Falls der GENAU dem Namen eines nicht netztoten
+	Spielers entspricht, bekommt man den. Falls er genau dem Namen eines
+	Monsters entspricht und man nicht players_only!=0 angegeben hat,
+	liefert er den Namen des Monsters. Ansonsten sucht er nach einem 
+	Spieler, dessen Name mit std anfaengt. Gibt es keinen, returned
+	er eine -2, gibt es mehr als einen, eine -1, bei genau einem den
+	Namen.
+
diff --git a/doc/wiz/skills.doc b/doc/wiz/skills.doc
new file mode 100644
index 0000000..685b383
--- /dev/null
+++ b/doc/wiz/skills.doc
@@ -0,0 +1,77 @@
+ Skills sind Fertigkeiten, die ein Spieler erwerben kann. Zu einem Skill koennen
+mehrere Verben gehoeren. Ausserdem kann ein Verb unter Umstaenden bei mehreren
+Skills definiert sein (zB, falls es eine Magiergilde und eine Psionkier-
+gilde gaebe, koennte es skills "magie" und "psi" geben, die beide das
+Verb "teleportiere" definieren).
+
+ Welche Skills es gibt, welche Verben dazugehoeren, welche Objekte und
+Funktionen diesen zugeordnet sind, regelt ein zentraler "Skillmaster".
+Darueberhinaus gibt es in jedem Spielerobjekt ein "Skill"-Modul.
+
+Der Skillmaster offeriert die folgenden Funktionen:
+
+InsertSkill(string skillname, string skilldescr, string *verben,
+            string *objFunDescr)
+ skillname ist (natuerlich) der Name des Skills (zB Magie).
+ skilldescr ist ein string, der den Skill naeher beschreibt, zB
+            "Magie gibt dem Anwender ein breites Spektrum von Moeglichkeiten,
+             sowohl im Kampf als auch ausserhalb."
+ verben ist ein Array, der die Verben zu dem Skill enthaelt.
+ objFunDescr ist ein Array, der dieselbe Groesse haben muss wie Verben. Jedes
+             Element ist ein 4-elementiger Array. Erstes Element dieses Arrays
+             ist ein Filename, zweites eine Funktion. Bei der Eingabe des Verbs
+             wird in dem Objekt die Funktion aufgerufen. Die dabei uebergebenen
+             Parameter werden spaeter beschrieben.
+             Drittes Element ist ein String, der die zu diesem Verb und Skill
+             gehoerende Aktion naeher beschreibt, zB:
+             "Die Magische Rakete kostet den Gegner zwischen 5 und 10 Hitpoints"
+             Das 4. Element muss eine Zahl aus [1..19] sein und gibt den Level
+             an, ab dem ein Player dieses Skillverb erwerben kann.
+ Die Funktion darf nur von Erzmagiern aufgerufen werden.
+ Es darf noch keinen Skill dieses Names geben. Falls man einen bestehenden
+ Skill lediglich erweitern moechte, muss man die Funktion AddVerbs benutzen
+ (siehe unten).
+
+RemoveSkill(skillname)
+ entfernt einen Skill wieder. ACHTUNG: Wenn Player den Skill bereits erworben
+ haben, verlieren sie ihn, wenn sie zum naechsten mal versuchen, ihn zu be-
+ nutzen.
+
+GetSkills()
+ gibt die AList mit den Skills zurueck.
+
+GetSkill(skillname)
+ liefert den entsprechenden Eintrag aus der AList zurueck.
+
+GetFunctionAndDescription(skillname, verb)
+ liefert den in AddSkill uebergebenen 4elementigen Array mit Objektname,
+ Funktionsname, Aktionsbeschreibung und Level zurueck.
+
+GetSkillDescription(skillname)
+ liefert die in AddSkill uebergebene Beschreibung des Skills zurueck.
+
+AddVerbs(skillname, mixed *verbs, mixed *objFunDescr)
+ erweitert einen bestehenden Skill um einige Verben, naehere Beschreibung
+ siehe AddSkill.
+
+-------------------------------------------------------------------------------
+Das Skillmodul im Playerobjekt bietet die folgenden Funktionen:
+
+GiveAbility(verb, skill, int promill)
+ gibt einem Spieler die Faehigkeit, das Verb verb aus dem Skill skill zu benut-
+ zen. Promill wird bei dem Versuch, das Verb zu benutzen, an das Skillobjekt
+ uebergeben und sollte die Wahrscheinlichkeit, das dem Player die Skillaktion
+ gelingt, in Promill beschreiben. Wenn der Player die Ability schon hatte, wird
+ lediglich promill geupdated.
+ Es wird eine -1 zurueckgegeben, falls eine solche Kombination aus Skill und
+ Verb (noch) nicht definiert ist, eine -2 falls der Level des Spielers nicht
+ ausreicht.
+
+GetAllAbilities()
+ gibt die AList mit den Abilities des Spielers zurueck. Schluessel in der AList
+ sind die Verben, Eintraege sind Arrays mit den Skills. Die Arrays haben so
+ viele Eintraege, wie der Player Skills hat, die das betreffende Wort
+ definieren (im Idealfall also EINEN Eintrag, naemlich wenn es keine Ueber-
+ scheidungen gibt). Die Eintraege sind wiederum 2elementige Arrays, die
+ als 1. Element den Skillnamen, als 2. Element die Promill enthalten.
+
diff --git a/doc/wiz/sqlitedb b/doc/wiz/sqlitedb
new file mode 100644
index 0000000..44a7dce
--- /dev/null
+++ b/doc/wiz/sqlitedb
@@ -0,0 +1,14 @@
+SQLite-DBs im Morgengrauen
+
+Im MG koennen Objekte sqlite-Datenbanken verwenden.
+Die notwendigen efuns dafuer sind sl_open, sl_close, sl_exec, sl_insert_id.
+
+Hat man das Speicherfile (Savefile) der DB, kann man dieses mit dem Kommando
+sqlite3 auf einer Shell auch direkt abfragen:
+
+Auf der Shell fragt man die DB recht simpel so ab:
+sqlite3 -column -header <pfad_zur_db>
+
+Alles aus einer Tabelle anzeigen, wo eine Spalte einen bestimmten Wert hat:
+select * from <tabelle> where <spalte>='abc';
+
diff --git a/doc/wiz/teamkampf b/doc/wiz/teamkampf
new file mode 100644
index 0000000..4cfc934
--- /dev/null
+++ b/doc/wiz/teamkampf
@@ -0,0 +1,113 @@
+
+Teamkampf im MorgenGrauen
+=========================
+
+Zum Teamkampf im MG gehoeren zwei Objekte: Das Lebewesen, das im Team ist,
+sowie das Teamobjekt. Ersteres erbt seine Funktionalitaet aus
+
+/std/living/team.c
+
+das Teamobjekt ist ein clone von
+
+/obj/team.c
+
+Allerdings sollte man immer das #define fuer diesen Pfad nutzen, welches
+in /sys/living/team.h definiert ist: TEAM_OBJECT
+
+Darueberhinaus gibt es in diesem Verzeichnis noch den Teammaster.
+
+
+Alle relevanten Funktionen und Properties sind im Teammitglied abrufbar und
+liefern Informationen ueber den Teamkampf.
+
+
+UEBERSICHT ueber die Properties und Funktionen des Teamkampfs
+=============================================================
+
+Properties des Teammitglieds:
+----------------------------
+P_TEAM                 - Teamobjekt
+P_TEAM_NEWMEMBER       - Spieler moechte ins Team hiervon aufgenommen werden.
+P_TEAM_ATTACK_CMD      - Angriffsbefehl des Spielers, nicht setzbar.
+P_TEAM_AUTOFOLLOW      - Folgewunsch des Spielers, nicht setzbar.
+P_TEAM_WANTED_ROW      - Gewuenschte Reihe des Spielers.
+P_TEAM_WIMPY_ROW       - Fluchtreihe des Spielers.
+P_TEAM_LEADER          - Spieler ist Anfuehrer dieses Teams.
+P_TEAM_ASSOC_MEMBERS   - Alle zugeordneten NPCs bzw. der Spieler dem dieser
+                         NPC zugeordnet ist.
+P_TEAM_COLORS          - Grenzwerte fuer farbige Anzeige.
+
+Funktionen des Teammitglieds:
+----------------------------
+TeamPrefix()           - "[Team Teamname] " falls Teammitglied, "" sonst.
+IsTeamLeader()         - Test ob Spieler Anfuehrer eines Teams ist.
+IsTeamMove()           - Test ob Angriffsbewegung gerade ausgefuehrt wird.
+TeamMembers()          - Teammitglieder.
+PresentPosition()      - Aktuelle Reihennummer des Spielers.
+PresentTeamPositions() - Reihennummern aller anwesenden Teammitglieder.
+PresentTeamRows()      - Reihen aller anwesenden Teammitglieder.
+PresentEnemyRows()     - Reihen aller anwesenden Feindteams zusammen.
+SelectNearEnemy()      - Waehlt direkt angreifbaren Feind aus.
+SelectFarEnemy()       - Waehlt Feind aus hinteren Reihen aus.
+InsertEnemyTeam()      - Macht alle Mitglieder von Team des Feindes zu
+                         Feinden aller Mitglieder des eigenen Teams.
+AssocMember()          - Assoziiert einen HilfsNPC mit einem Spieler.
+DeAssocMember()        - Hebt Assoziation zwischen NPC und Spieler auf.
+TeamFlee()             - Spieler wird veranlasst in Fluchtreihe zu wechseln.
+
+Funktionen des Teamobjekts:
+--------------------------
+SwapRows()             - Spieler tauschen die Reihen
+
+
+BEISPIEL:
+  Man moechte von einem Spieler, welcher sich in einem Team befindet, alle
+  Teammitglieder sowie deren Anzahl ermitteln, die VOR diesem Spieler stehen.
+
+  Im abfragenden Objekt muss man zunaechst die Headerdatei des Teamkampfs
+  includen:
+
+  #include "/sys/living/team.h"
+
+
+  void fun( object pl )
+  {
+   int act_row,all;
+   mixed *rows;
+   object team,*team_members;
+
+   team=pl->QueryProp(P_TEAM);           // liefert das Teamobjekt
+
+   act_row=pl->PresentPosition();        // aktuelle Position ermitteln
+
+   team_members=({});
+
+   if ( objectp(team) && (act_row > 1) )
+    {
+     rows=team->PresentRows(ENV(pl));    // die Reihen werden als mixed-array
+                                         // uebergeben
+
+     foreach ( int i : act_row )
+      team_members+=rows[i];             // die Reihen werden komplett ins
+                                         // neue Array uebertragen
+    }
+
+   all=sizeof(team_members);             // Anzahl der Teammitglieder, die
+                                         // vor dem Spieler stehen
+  }
+
+
+SIEHE AUCH:
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix, teamkampf_intern
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/wiz/teamkampf_intern b/doc/wiz/teamkampf_intern
new file mode 100644
index 0000000..79c2963
--- /dev/null
+++ b/doc/wiz/teamkampf_intern
@@ -0,0 +1,127 @@
+
+Teamkampf-Interna
+=================
+
+Verwaltung der Kampfreihen
+--------------------------
+
+Die Umordnung der Teammitglieder wird durch die Formation gesteuert.
+
+  formin[reihe] - Minimale Anzahl von Teammitgliedern in dieser Reihe
+  formax[reihe] - Maximale Anzahl von Teammitgliedern in dieser Reihe
+
+Die Funktion CheckFormation() passt die Werte so an, dass sie bei Anwesenheit
+aller Teammitglieder erfuellbar sind, wobei ggf. der Maximalwert vorne
+anfangend erhoeht wird und der Minimalwert hinten anfangend verringert wird.
+Dabei ist der Minimalwert der ersten Reihe 1.
+
+Es ist zwischen der Teamaufstellung und der Raumaufstellung zu unterscheiden.
+Die Teamaufstellung ist die Aufstellung, in der die Mitglieder angeordnet
+waeren, wenn alle anwesend waeren. In der Teamaufstellung ist durch die
+Funktion MakeFormation() sichergestellt, dass die Minimal- und
+Maximalanforderungen erfuellt sind.
+Die Raumaufstellung ergibt sich aus den anwesenden Mitgliedern der
+Teamaufstellung. Sollten die Minimalanforderungen einer vorderen Reihe nicht
+erfuellt sein, werden anwesende Mitglieder aus den hinteren Reihen IN DER
+RAUMAUFSTELLUNG nach vorne geschoben soweit noetig.
+
+Vor Verschiebungen und bei Updates der TEAMAUFSTELLUNG werden die Arrays mit
+den Mitgliedern jeder Reihe sortiert, wobei die gewuenschte Reihe der
+Mitglieder das groesste Gewicht (125) im Sortierkriterium hat und die Anzahl
+der Lebenspunkte einfach eingeht. Solange die Teammitglieder unter 250 LP
+haben, kann ein Mitglied mit wenigen LP hinter einem mit vielen LP einsortiert
+sein, der EINE Reihe weiter hinter stehen will, aber nicht zwei oder mehr.
+Wird es noetig, Mitglieder aus einer Reihe in eine andere zu verschieben,
+werden Mitglieder vom Anfang des Arrays nach vorne verschoben (an das Ende
+des davorliegenden Arrays) bzw. Mitglieder vom Ende des Arrays nach hinten
+(an den Anfang des dahinterliegenden Arrays). Dadurch werden immer die
+Mitglieder mit dem staerksten Drang nach vorne an die Front geschickt :-)
+
+Wenn jemand die Reihe wechselt und dabei die Minimalanforderung der Quellreihe
+unterschritten oder die Maximalanforderung der Zielreihe ueberschritten wird,
+wird mit CycleRows() rotiert. Kommt ein neues Mitglied hinzu und die
+Maximalanforderung seiner gewuenschten Reihe wuerde ueberschritten, wird
+in AddToRow() zunaechst versucht ein Mitglied eine Reihe vorzuschieben, falls
+da noch Platz ist, sonst eine Reihe zurueck, falls da noch Platz ist (die
+Anzahl der Mitglieder also < formax ist). Wird ein Mitglied entfernt oder
+gewaltsam entfernt und wuerde dabei die Minimalanforderung seiner Reihe
+unterschritten, wird in RemoveFromRow() versucht, ein Mitglied aus der
+nachfolgenden Reihe nach vorne zu holen, falls dort Ueberschuss vorhanden ist
+(in der nachfolgenden Reihe also mehr Mitglieder als formin sind), sonst aus
+der vorangehenden Reihe, falls dort Ueberschuss ist.
+
+Sollten diese Umordnungen nicht ausreichen die Formation in der
+TEAMAUFSTELLUNG einzuhalten, wird die Formation mit MakeFormation() erzwungen.
+Dies wird in zwei Durchlaeufen erreicht. Der erste Durchlauf wird von vorne
+nach hinten durchgefuehrt. Ist das Maximum einer Reihe ueberschritten, werden
+soviele Mitglieder nach vorne geschoben wie in der davorliegenden Reihe freie
+Plaetze sind und die restlichen ueberschuessigen Mitglieder nach hinten. Sollte
+das Minimum einer Reihe unterschritten sein, werden soviele Mitglieder aus den
+nachfolgenden Reihen hergeholt, wie zum Erreichen des Minimums noetig ist. Der
+zweite Durchlauf wird von hinten nach vorne ausgefuehrt. Falls das Minimum
+einer Reihe unterschritten wird, werden Mitglieder aus den davorliegenden
+Reihen geholt soweit noetig, wenn jedoch Ueberschuss vorhanden ist, wird
+dieser nach vorne geschoben.
+
+BEISPIEL:
+
+Formation 3-6 2-2 1-2 0-6 1-1 (bloedsinnige Formation ;-)
+
+1. Durchlauf (vorne beginnend):
+
+   1 1 6 1 0
+   <----     (Minimum Reihe 1 unterschritten)
+   3 0 5 1 0
+     <--     (Minimum Reihe 2 unterschritten)
+   3 2 3 1 0
+       -->   (Maximum Reihe 3 ueberschritten)
+   3 2 2 2 0
+
+2. Durchlauf (hinten beginnend):
+
+   3 2 2 2 0
+         --> (Minimum Reihe 5 unterschritten)
+   3 2 2 1 1
+
+Ergebnis entspricht der gewuenschten Formation. Ermittlung der RAUMaufstellung:
+
+   2 0 2 1 1 (Anwesende aus der vorangegangenen TEAMaufstellung)
+   <----
+   3 0 1 1 1
+     <----
+   3 2 0 0 1
+       <----
+   3 2 1 0 0
+
+Ergebnis erfuellt Minimalanforderungen zumindest vorne, Maximalanforderungen
+koennen nicht ueberschritten werden, weil die Raumaufstellung hoechstens
+soviele Mitglieder wie die Teamaufstellung hat.
+
+
+Abarbeitung des Angriffsbefehls und Verteilung der Begruessungsschlaege
+-----------------------------------------------------------------------
+Das Grundprinzip ist folgendes:
+Wenn das ganze Team bewegt wird, werden die Begruessungsschlaege unter
+Vorbehalt weggelassen. Sobald alle Teammitglieder bewegt wurden, macht
+jedes Monster, das noch einen Begruessungsschlag ausfuehren muss, einen
+Schlag auf EIN Teammitglied das im Nahkampf erreichbar ist und der Vorbehalt
+wird fuer alle Mitglieder aufgehoben. Wenn ein Teammitglied versucht
+sich zu bewegen und noch ein Begruessungsschlag unter Vorbehalt fehlt,
+wird dieser noch vor der Bewegung nachgeholt.
+
+
+SIEHE AUCH:
+        Uebersicht: teamkampf
+        Properties: P_TEAM, P_ASSOC_MEMBERS, P_TEAM_ATTACK_CMD,
+                    P_TEAM_AUTOFOLLOW, P_TEAM_COLORS, P_TEAM_LEADER,
+                    P_TEAM_NEWMEMBER, P_TEAM_WANTED_ROW, P_TEAM_WIMPY_ROW
+        Bewegung:   IsTeamMove, TeamFlee
+        Mitglieder: IsTeamLeader, TeamMembers
+        Kampf:      AssocMember, DeAssocMember, InsertEnemyTeam,
+                    SelectNearEnemy, SelectFarEnemy
+        Positionen: PresentPosition, PresentRows, PresentEnemyRows,
+                    PresentTeamPosition, SwapRows
+        Sonstiges:  TeamPrefix
+
+----------------------------------------------------------------------------
+Last modified: 16-08-2010, Gabylon
diff --git a/doc/wiz/techniken b/doc/wiz/techniken
new file mode 100644
index 0000000..5defd59
--- /dev/null
+++ b/doc/wiz/techniken
@@ -0,0 +1,111 @@
+****************************************************************************
+* Dieser Text ist veraltet. Die Techniken werden von der Mudlib nicht      *
+* ausgewertet und momentan auch von keiner Gilde (Ausnahme: die Tanjian    *
+* zeigt sie an, tut aber nix damit.                                        *
+****************************************************************************
+----------------------------------------------------------------------------
+             Techniken, mit denen Waffen eingesetzt werden koennen
+----------------------------------------------------------------------------
+
+TQ_THRASH - "Schlagtechnik"
+
+    Die vom Verstaendnis her einfachste Technik: Man nehme sich einen
+    Gegenstand,  der gross genug ist und halbwegs  brauchbare  Dichte 
+    besitzt - also nicht gerade federleicht  fuer seine Groesse ist - 
+    und haue drauf.  Egal ob Henkersaxt,  Stock,  Stuhl,  Bierflasche 
+    (ganz), Knueppel, Keule oder Bratpfanne,  das und aehnliches sind 
+    brauchbare  'Waffen',  um mit dieser Technik Erfolg zu haben.  Es 
+    ist eine schlagende Bewegung,  also das gewollte schwunghafte Zu-
+    sammenfuehren zweier Koerper, fuer gewoehnlich Waffe und Gegner.
+
+
+TQ_THRUST - "Stosstechnik"
+
+    Auch diese Technik erfreut sich zumindest in Kneipenschlaegereien
+    grosser Beliebtheit: Das Stossen.  Mit einem vorzugsweise spitzen
+    Gegenstand wie Speer, Dolch, Bierflasche (zerbrochen) oder Helle-
+    barde  wird dem Gegner ein Loch in den Leib  gestossen,  im Falle 
+    eines   stumpfen Gegenstandes wie z.B.  einem Kampfstock oder dem 
+    eigenen  Zeigefinger oder Knoechel zielt man auf Vitalpunkte oder
+    Weichteile und erzielt auch damit beeindruckende Ergebnisse.  Das
+    Gewicht der Waffe ist  weniger von Bedeutung,  da  der Akteur bei 
+    einem korrekt ausgefuehrtem seine eigene Masse mit einsetzt.
+
+
+TQ_STROKE - "Streichtechnik"
+
+    Ein etwas eigenwillig anmutender Begriff,  aber bei genauerer Be-
+    trachtung hat  diese Technik tatsaechlich etwas mit Streicheln zu
+    tun:  Die wichtigste Komponente der Bewegung fuehrt mehr oder we-
+    niger am  Gegner _entlang_ und nicht auf ihn zu.  Man stelle sich 
+    ein Schwert vor, das geschmeidig durch die Kehle eines Orks glei-
+    tet  und eine Menge Blut  freisetzt oder ein Pergamentblatt,  das
+    man aus der Hand gezogen bekommt  (und ebenfalls eine Menge  Blut
+    freisetzt).  In den allermeisten Faellen ist also eine moeglichst
+    scharfe Schneide im Spiel und, auch wenn schmerzhafte Erfahrungen
+    mit  Pargamentkanten gelegentlich gegenteiliges  vermuten lassen, 
+    je schaerfer die Schneide, desto weniger Druck in Richtung feind-
+    lichen  Zielkoerper  muss fuer  einen  "durchschneidenden Erfolg" 
+    ausgeuebt werden.
+
+
+TQ_WHIP - "Peitschtechnik"
+
+    Unter der Peitschtechnik wird nun alles zusammengefasst,  was den
+    Umgang mit beweglichen Elementen an der Waffe betrifft.  Egal, ob
+    Peitsche a la George Lucas, neunschwaenzige Katze, Manriki-Gusari
+    (eine halbmeter lange Kette mit Gewichten an den Enden), ein- bis
+    dreikoepfigem  beketteten Morgenstern oder gar Dreschflegel,  sie 
+    sind zumindestteilweise sehr unterschiedlich konzipiert (so fehlt
+    der  Peitsche am aeusseren Ende das Gewicht,  so dass jenes durch
+    eine gegenlaeufige Bewegung beschleunigt werden muss), haben aber
+    eines gemeinsam: Der Schaden wird durch ein ueber die normale Be-
+    wegung des Kaempfers  hinaus beschleunigtes Teil der Waffe verur-
+    sacht. Durch jene Beweglichkeit der  Waffe wird ein sehr  grosses 
+    Mass an Koordinationsvermoegen vom Kaempfer abverlangt.
+
+----------------------------------------------------------------------------
+
+Vermischtes
+
+    - Waffen koennen  sich fuer mehrere  Techniken eignen.  Mit einem
+      Katana, dem Schwert der Samurai, beispielsweise kann man in die
+      ungeschuetzten Partien des Gegners stechen,  dem Gegner mit der 
+      Streichtechnik tiefe Schnitte in die Unterseiten der Arme  (ein
+      durch typische Samurairuestungen schlecht geschuetzter Bereich)
+      zufuegen, und mit der beruehmten halben Koerperdrehung dem in-
+      zwischen taumelndem Kontrahenten den Kopf abschlagen. 
+
+    - Waffen koennen sich, obwohl von der gleichen Gattung, fuer ver-
+      schiedene Techniken eignen.  Ein spitzer Dolch mag eine stumpfe
+      Klinge haben  und nur fuer ausschliesslich stossende  Praktiken
+      zu gebrauchen zu sein, waehrend ein abgerundetes Kuechenmesser,
+      ebenfalls vom Typ "Zyn", fuer kantiges Zuschlagen und eventuell
+      auch fuer schnittige Streichtechniken herhalten kann.
+
+    - Je nach Zweck und Koennen wird die beste zu verwendende Technik 
+      variieren:  Wenn es um arme Grashalme geht,  wird die Sense mit 
+      schneidenden Bewegungen gefuehrt  (schoen in der  Milka-Werbung 
+      zu sehen,  fuer die, die es partout nicht glauben wollen),  bei 
+      einer Bauernrevolte mag das gute Stueck jedoch auch mit anderen 
+      Techniken effektiv (und vielleicht sogar effektiver) eingesetzt 
+      werden, wer weiss, wer war schon dabei...?  Selbst bei normalen
+      Waffen wie Schwertern  wuerde ein Ungeuebter  selten versuchen,  
+      mit Streichtechniken Schaden zu verursachen, denn das Zustechen 
+      ist schlicht einfacher.
+
+    - Es wird immer  besondere Waffen geben.  So  sind beispielsweise
+      das Zweililien und  die Hellebarde  beide dem Typ "Kzrok" (fuer
+      nicht-Trves: Stangenwaffen) zuzuordnen, die Techniken  weichen,
+      bedingt  durch die Vielseitigkeit  der Waffen,  jedoch von  der
+      Norm ab: Das Zweililien, an jedem  Ende eine lange und  scharfe
+      Klinge,  kann  ebenso  vielseitig  gehandhabt  werden  wie  ein 
+      Schwert,  waehrend die Hellebarde (eine Mischung aus  Lanze und
+      Axt) durch ihre unausgewogene Gewichtsverteilung  und dem damit
+      verbundenen Potenzial an Schwung schlichtweg DIE Waffe der Wahl 
+      fuer feige Zwerge ist:  Schwingen wie eine grosse  Axt und  den 
+      Gegner auf Distanz halten koennen.  Gut,  dass es keine  feigen 
+      Zwerge gibt ;o)
+
+----------------------------------------------------------------------------
+Last modified: Tue Apr 13 13:00:00 2000 by Anatol
diff --git a/doc/wiz/testspieler b/doc/wiz/testspieler
new file mode 100644
index 0000000..b7fc2f8
--- /dev/null
+++ b/doc/wiz/testspieler
@@ -0,0 +1,40 @@
+
+Testspieler
+===========
+
+ TESTSPIELER:
+    Testspieler sind Zweitcharaktere von Magiern, die auch gleichzeitig mit
+    dem Magier eingeloggt sein duerfen. Sie muessen entsprechend markiert sein
+    (siehe unten) und duerfen auch ruhig vom Magier manipuliert werden.
+
+    TESTSPIELER UNTERLIEGEN VOLL DEN REGELN DES MAGIERVERTRAGS!
+
+    Testspieler werden hauptsaechlich dann gebraucht, wenn Objekte oder
+    Gebiete wirklich aus Spielersicht getestet werden sollen und das
+    Abschalten des Magiermodus dazu nicht ausreicht. Ein anderes Einsatzgebiet
+    ist das Testen von Meldungen oder Aktionen, die nicht nur den
+    Ausfuehrenden selbst betreffen, sondern z.B. auch umstehende Personen in
+    einem Raum.
+
+ GILDENTESTSPIELER:
+    Sofern eine Gilde das Anlegen von Testspielern unterstuetzt, gibt es
+    entsprechende Hilfeseiten unter "hilfe <gildenname>.testspieler".
+
+ MARKIEREN:
+    Ein Testspieler wird durch setzen der Property P_TESTPLAYER markiert. Es
+    reicht zwar aus, diese Property einfach auf einen Wert != 0 zu setzen,
+    aber man sollte hier lieber den Namen des Magiers eintragen, zu dem der
+    Testie gehoert.
+
+    Einige Magier markieren ihre Testspieler nicht, und zwar mit der
+    Begruendung, dass dann Todesmeldungen nicht ausgegeben werden. Das ist
+    allerdings keine Ausrede mehr, das Testspieler-Todesmeldungen auf -TdT
+    ausgegeben werden.
+    Sind nichtmarkierter Testspieler entsprechend manipuliert, koennte es
+    passieren, dass sie wegen Schummelei geloescht werden...
+
+ SIEHE AUCH:
+    zweitspieler, vertrag, mschau, P_TESTPLAYER
+
+ LETZTE AeNDERUNG:
+    19. Maerz 2004 Gloinson
diff --git a/doc/wiz/todesfallen b/doc/wiz/todesfallen
new file mode 100644
index 0000000..5585032
--- /dev/null
+++ b/doc/wiz/todesfallen
@@ -0,0 +1,355 @@
+Manpage zu Todesfallen. Technischer Leitfaden.
+
+
+Diese Manpage richtet sich an (Jung)magier, die Todesfallen nutzen wollen,
+um verschiedenste Dinge in ihren Gebieten damit zu erreichen. Dabei soll hier
+nicht diskutiert werden, wo welche Art von Todesfalle Sinn macht (oder auch
+nicht), sondern es sollen technische Aspekte bei der Programmierung einer
+solchen (Todes)falle aufgezeigt werden.
+
+
+Kapitel 1. Das Umfeld einer Todesfalle.
+
+Eine Todesfalle kann wie in spaeteren Kapiteln beschrieben, leicht umgesetzt
+werden. Damit sie sich auch so verhaelt wie sie soll, werden hier einige
+Sicherheitsaspekte behandelt, die durchgegangen werden sollten.
+
+
+Kapitel 1.1 Wer hat die Todesfalle ausgeloest?
+
+Die meisten Todesfallen werden durch ein Kommando ausgeloest, welches der
+Spieler ausfuehrt. Z.B.
+	druecke grossen roten knopf mit der aufschrift "todesfalle ausloesen"
+In diesem Fall existiert in der aufgerufenen Funktion die Moeglichkeit, ueber
+die Funktion this_player() den aktuell "gueltigen" Spieler auszufischen.
+Hierbei ist zu beachten, dass auch NPCs von dieser Funktion zurueckgegeben
+werden koennen. Auch im init() eines Raumes wird in this_player() der Spieler
+zurueckgegeben. Hierbei ist jedoch zu beachten, dass man immer schauen sollte,
+ob this_player() auch tatsaechlich ein Objekt zurueckliefert. Dies ist
+wichtig, da das init() (oder auch andere Funktionen) durch Gegenstaende, wie
+den Bumerang ausgeloest werden koennen. In diesem Fall steht in this_player()
+ueblicherweise kein Objekt. Die Sicherheitsabfrage sollte also wie folgt
+aussehen:
+
+    object spieler;
+    spieler = this_player();
+    if (spieler) // Ein Lebewesen?
+    {
+      ...
+    }
+    // else: Die Falle nicht ausloesen, da kein Lebewesen.
+
+
+Kapitel 1.2 Wer soll die Todesfalle nicht ausloesen?
+
+Oft kommt es vor, dass eine schoene Todesfalle von Gott und der Welt
+ausgeloest wird. Normalerweise moechte man aber nicht, dass "Gott" oder andere
+besondere Personengruppen diese Falle ausloesen. In den folgenden
+Unterkapiteln werden Abfragen gezeigt, um Personengruppen auszuschliessen.
+
+
+Kapitel 1.2.1 Todesfallen, die nicht auf Geister reagieren.
+
+Ueblicherweise sollen Todesfallen bei den Ausloesern Schaden verursachen. Bei
+Geistern laeuft dies jedoch ins Leere. Man koennte nun auf die Idee kommen,
+alternativ auf Geister zu reagieren.
+
+
+Kapitel 1.2.1.1 Nicht auf Geister reagieren.
+
+Angenommen, man hat einen Spieler (siehe oben), der im Begriff ist, die Falle
+auszuloesen. Man sollte nun pruefen, ob er ein Geist ist. Falls er kein Geist
+ist, kann man wie gewuenscht (Todesfalle) reagieren. Falls nicht, sollte man
+eine passende Meldung ausgeben. Z.B. "Als Geist hast Du nicht die notwendige
+Kraft, diesen Knopf zu druecken." Die technische Abfrage, ob ein Spieler ein
+Geist ist, sieht wie folgt aus.
+
+    if (!spieler->QueryProp(P_GHOST))
+    {
+        // ist _kein_ Geist, also Todesfalle.
+    }
+    else
+    {
+        // Alternativer Text, da Geist.
+    }
+
+
+Kapitel 1.2.1.2 Geister entgeistern.
+
+Da ausschliesslich die Rassenstartraeume entgeistern sollen, wurde dieser
+Punkt herausgenommen. Also: Es ist unerwuenscht, Geister zu entgeistern, um
+eine Todesfalle korrekt auszuloesen.
+
+
+Kapitel 1.2.1.3 Alternative fuer Geister.
+
+Rollenspieltechnisch gesehen macht es in den allerwenigsten Faellen Sinn,
+alternativ auf einen Geist zu reagieren. Der Vollstaendigkeit halber sei diese
+Loesung trotzdem erwaehnt. Ein Programmbeispiel sollte ohne grosse Muehe durch
+die schon vorhandenen Beispiele erstellt werden koennen.
+
+
+Kapitel 1.2.2 Gaeste und kleine Spieler.
+
+Rollenspieltechnisch macht es oft keinen Sinn, auf Gaeste oder kleine Spieler
+anders zu reagieren, als auf "den Rest". Moechte man jedoch einen besonderen
+Schutz fuer kleine Spieler einbauen ("Du hast zu grosse Angst, diesen grossen,
+roten Knopf zu druecken.") oder moechte man Gast-Sterbe-Testern den Hahn 
+zudrehen (die Weicheier!), so sind folgende Abfragen unter Umstaenden
+sinnvoll.
+
+  // Gast?
+  if (spieler->QueryGuest())
+  {
+      // Ist ein Gast...
+  }
+  else
+  {
+      // Todesfalle. Kein Gast.
+  }
+  
+  // Kleiner Spieler?
+  // In diesem Beispiel Abfrage des Spielerlevels.
+  if (spieler->QueryProp(P_LEVEL) < 10)
+  {
+      // Spielerlevel < 10 haben zuviel Angst.
+  }
+  else
+  {
+      // Spielerlevel >= 10 koennen hier ruhig die Todesfalle ausloesen.
+  }
+
+
+Kapitel 1.2.3 Magier
+
+Ueblicherweise sind Magier unsterblich und soll(t)en auch nicht
+(versehentlich) Todesfallen ausloesen. Dies ist vor allem dann der Fall, wenn
+"zufaellig" im gleichen Raum stehende Spieler Meldungen bekommen wuerden und
+dadurch gewarnt werden. Die technische Umsetzung, dass Magier Todesfallen
+nicht ausloesen, sieht wie folgt aus. Die Abfrage beruecksichtigt
+"mschau aus". Das heisst, Magier koennen sterben, wenn sie mschau aus gemacht
+haben.
+
+    #include <wizlevels.h>
+
+    if(IS_LEARNER(spieler) && spieler->QueryProp(P_WANTS_TO_LEARN))
+    {
+      // Magier: Man soll ihm mitteilen, dass er diese Aktion als Magier nicht
+      // tun darf.
+    }
+    else
+    {
+      // Kein Magier. => Todesfalle.
+    }
+
+
+Kapitel 1.3 Wichtige Punkte einer nicht sinnfreien Todesfalle.
+
+Eine Todesfalle ist, wie in Kapitel 2 gezeigt, eigentlich eine einfache Sache.
+Kombiniert mit den schon gezeitgten Sicherheitsabfragen hat man ueblicherweise
+ein gueltiges Opfer. Allgemeine Dinge, wie beispielsweise "Das Opfer sollte
+ein environment haben" werden hier uebergangen und nur die wesentlichen Dinge
+genannt, die beim potentiellen Toeten eines Spielers von Belang sind.
+
+
+Kapitel 1.3.1 Wo ist der Spieler?
+
+Ganz wichtig bei Todesfallen ist die Frage, wo sich der Spieler befindet.
+Wird eine Todesfalle in init() ausgeloest, dann befindet sich der Spieler
+schon in dem entsprechenden Raum, dessen init() nun ausgefuehrt wird. Das
+bedeutet, wenn der Spieler stirbt, sind seine Sachen zunaechst einmal in dem
+betreffenden Raum. In seltenen Faellen spielt es wirklich eine Rolle, wo sich
+der Spieler befindet und er hat eigentlich immer ein environment, in das seine
+Leiche dann kommt. Dennoch sollte man bei Todesfallen testen, wo sich der
+Spieler befindet. Wenn der Spieler die Falle im Vorraus oder von woanders
+ausloesen kann, dann macht es nicht immer Sinn, die Falle tatsaechlich
+auszuloesen oder dem Spieler den Effekt "zuzumuten".
+Eine einfache Abfrage, ob sich der Spieler im gleichen Raum befindet, sieht so
+aus:
+
+    if (environment(spieler) && (environment(spieler) == this_object()))
+    {
+        // Spieler hat ein environment und das environment ist dieser Raum.
+    }
+    
+
+Kapitel 1.3.2 Wer toetet den Spieler?
+
+Ueblicherweise toetet man einen Spieler mit den in Kapitel 2 genannten
+Moeglichkeiten. In diesen Moeglichkeiten ist das toetende Objekt der Raum.
+Da aber nun der Raum keinen Namen hat, muss man diesem Raum einige Properties
+setzen, die ueblicherweise erst einmal nur NPCs haben. Die Properties regeln,
+"wer" in Kampfmeldungen, Angriffen und Todesmeldungen als Angreifer oder
+Killer steht. Setzt man diese Werte direkt vor der Ausfuehrung einer
+Todesfalle, dann kann man mehrere Todesfallen in einem Raum mit verschiedenen
+Meldungen versehen.
+
+    SetProp(P_NAME, "Ein gleissender Feuerball"); // Der Angreifer-Name
+    SetProp(P_KILL_NAME, "Ein gleissender Feuerball");
+        // Name fuer den Todeskanal.
+
+
+Kapitel 1.4 Gimmicks
+
+Der Vollstaendigkeit halber soll noch erwaehnt werden, dass man in der
+Property P_ENEMY_DEATH_SEQUENCE das File einer (eigenen) Todessequenz ablegen
+kann.
+
+
+Kapitel 2 Technische Umsetzung von Todesfallen.
+
+Den Tod durch oder den Angriff auf einen Spieler mittels einer Todesfalle kann
+man auf verschiedene Weise bewerkstelligen. Die wichtigsten Moeglichkeiten
+werden in den folgenden Unterkapiteln kurz erlaeutert. Es wird ausserdem auf
+einige technische Feinheiten eingegangen, die zu beachten sind.
+
+
+Kapitel 2.1 Tod durch die()
+
+Die einfachste Moeglichkeit, einen Spieler sicher sterben zu lassen, ist der
+Aufruf von die(). Die spaeter genannten Moeglichkeiten mit Ausnahme des
+Faketods bewirken letztendlich auch einen Aufruf von die(), sollte der Spieler
+sich nicht ausreichend dagegen geschuetzt haben. Bei dem direkten Aufruf kann
+sich der Spieler nicht dagegen wehren. (Ausnahme: Geist sein, siehe oben.)
+Die technische Umsetzung sieht wie folgt aus. Eventuelle Parameter fuer die()
+sind der manpage fuer die() zu entnehmen.
+
+    spieler->die(); // Jetzt ist der Spieler tot.
+
+
+Kapitel 2.2 Todesfalle mit do_damage()
+
+Die zweite Form der Todesfalle ist nicht ganz so aggressiv, wie die erste.
+Hier wird dem Spieler eine feste oder zufaellige Zahl an Schadenspunkten 
+zugefuegt. Der erlittene Schaden ist dabei nicht von Ruestung oder sonstigem
+Schutz abhaengig, sondern der Schaden betraegt dem uebergebenen Wert. Ist der
+uebergebene Wert hoeher als die Zahl der Lebenspunkte des Spielers, so stirbt
+der Spieler. Nachlesen kann man dies in der manpage zu do_damage().
+Diese Form der Todesfalle ist vermutlich die am haeufigsten verbreitete, da
+der Magier am einfachsten die Konsequenzen ueberblicken kann, ohne den Spieler
+zwingend zu toeten. Wichtig bei dieser Umsetzung ist, dass der Spieler keine
+Angriffsmeldung oder dergleichen sieht. Er bekommt hoechstenfalls mit, dass er
+ueberhaupt Schaden erhalten hat. Daher sollte vor dem Zufuegen des Schadens
+eine Meldung ausgegeben werden, die dem Spieler anzeigt, weshalb er Schaden
+bekam. (Bsp. "Ein Feuerball rast auf Dich zu und trifft Dich.")
+Die technische Umsetzung sieht wie folgt aus:
+
+    tell_object(spieler, "Ein Feuerball trifft Dich von hinten.\n");
+    spieler->do_damage(10, this_object());
+                         // Spieler erhaelt genau 10 Schadenspunkte und
+                         // stirbt, wenn er dadurch unter 0 HP kommt.
+
+Kapitel 2.2.1 Angepasste Todesfalle mit do_damage()
+
+Moechte man, dass die Staerke der Todesfalle abhaengig vom Spieler ist, dann
+kann man den in do_damage() uebergebenen Schaden abhaengig vom Spieler machen.
+Dies ist in Gebieten sinnvoll, in denen Anfaenger und groessere Spieler
+gleichermassen gefordert sein sollen (z.B. Quest). Folgendes Beispiel zeigt,
+wie man eine Todesfalle macht, die dem Spieler etwa 1/4 seiner maximalen HP
+abzieht.
+    
+    spieler->do_damage(spieler->QueryProp(P_MAX_HP) / 4);
+
+
+Kapitel 2.3 Todesfalle mit reduce_hit_point
+
+Mittels reduce_hit_point() ist es moeglich, eine nicht toedliche "Todes"-Falle
+zu entwickeln. Dies kann genutzt werden, wenn man eine eigentlich toedliche
+Falle machen will, die Auswirkungen eines Todes dem Spieler gegenueber aber zu
+aggressiv waeren. Hierbei ist zu beachten, dass ein negativer Wert eine
+Heilung bewirken wuerde. Daher ist zuvor eine Sicherheitsabfrage zu machen.
+Wie bei do_damage() ist eine Meldung auszugeben, da reduce_hit_point eine
+solche nicht generiert. Alles zusammen saehe der Part wie folgt aus:
+
+    int schaden;
+    tell_object(spieler, "Ein Feuerball trifft Dich.\n");
+    // Hier den Schaden berechnen;
+    // Z.B. schaden = 3;
+    if (schaden < 1) schaden = 1; // Es soll mindestens 1 Schadenspunkt geben!
+    spieler->reduce_hit_point(schaden);
+
+
+Kapitel 2.4 Faketode
+
+Faketode sind keine Tode im eigentlichen Sinn, da der Spieler von den
+meisten negativen Auswirkungen verschont bleibt. Ein Faketod ist im Grunde
+keine komplizierte Sache und eignet sich hervorragend fuer Anfaengergebiete.
+Verschiedenen Auspraegungen (Bsp. Gibt es eine Leiche mit der Ausruestung des
+Spielers oder behaelt er die Ausruestung?) gemein ist die Tatsache, dass der
+Spieler augenscheinlich gestorben ist, jedoch kein die() aufgerufen wird. Es
+werden todesbedingt also keine Attribute abgezogen, die Erfahrungspunkte
+bleiben unangetastet usw, usf.
+Die technische Umsetzung sieht wie folgt aus. Dabei ist zu beachten, dass der
+Spieler Geist werden muss. Zuvor sollte wie bei den vorhergehenden Methoden
+der Kill-Name etc. gesetzt werden.
+
+    spieler->SetProp(P_GHOST,1);
+    clone_object("/room/death/death_mark")->move(spieler);
+
+
+Kapitel 2.4.1 Bedingte Faketode.
+
+Man kann die Technik von Kapitel 2.3 mit den Faketoden kombinieren, indem man
+testet, ob der Spieler auf oder unter 0 Lebenspunkte kommen wuerde, wenn man
+anstatt reduce_hitpoint do_damage() machen wuerde und dann zusaetzlich zum
+Abziehen der LP noch einen Faketod ausfuehrt. Dabei sind zwei Dinge zu
+beachten:
+Erstens sollte man keine zwei Meldungen ausgeben, also der Spieler sollte
+keine zwei Feuerbaelle auf sich zufliegen sehen, obwohl nur einer da ist.
+Zweitens sollte man nicht vergessen, dem Spieler dennoch die LP abzuziehen,
+weil der Spieler ansonsten nach dem Entgeistern anstatt 1 LP noch soviele hat,
+wie vor dem Feuerball-Angriff.
+Die technische Umsetzung dieser Kombination wird an dieser Stelle nicht naeher
+erlaeutert, da das Vorgehen aus den vorigen Kapiteln klar ist.
+
+
+Kapitel 2.5 Angriff mittels Defend()
+
+Eine realistische, wenn auch teilweise heikle Moeglichkeit fuer eine
+Todesfalle ist der Aufruf der Defend()-Funktion des Spielers. Der Vorteil
+von Defend ist, dass man unter Angabe der korrekten Parameter den Schutz der
+Ruestungen eines Spielers oder auch die Gildenfaehigkeiten beruecksichtigt
+werden. Daraus folgt, dass der als Beispiel verwendete Feuerball von einem vor
+Feuer schuetzenden Objekt abgeschwaecht wuerde. Anwendungstechnisch gibt es
+erst einmal keine Probleme, sofern einige wichtige Punkte beachtet werden, auf
+die hier nun eingegangen wird. Einziger Nachteil besteht nur in der mangelnden
+Erfahrung der einzutragenden Schadenswerte, da diese nicht 1:1 an die
+Schadenspunkte gekoppelt sind, die an den Spieler weitergereicht werden.
+Die technische Umsetzung fuer den Angriff eines Spielers durch eine Todesfalle
+ueber Defend sieht wie folgt aus:
+
+    #include <new_skills.h>
+
+    int schaden;
+    schaden = 500+random(500); // Diese Werte machen u.U. viel Schaden.
+
+    spieler->Defend(
+        100,
+        DT_FIRE,
+        ([
+            SP_SHOW_DAMAGE:0,
+            SP_PHYSICAL_ATTACK:1
+        ]),
+        this_object()
+    );
+
+Wichtig sind hierbei folgende Punkte:
+    1. Man sollte SP_SHOW_DAMAGE:0 im Mapping angeben, wenn man die Meldung
+       z.B. "Ein Feuerball trifft Dich von hinten.\n" selbst ausgeben will.
+       Tut man dies nicht, muss im Raum zusaetzlich P_GENDER, P_NAME, etc.
+       auf einen sinnvollen Wert gesetzt werden, beispielsweise P_GENDER auf
+       MALE und P_NAME auf "Feuerball".
+    2. SP_PHYSICAL_ATTACK:1 sollte gesetzt werden, wenn des Spielers Ruestung
+       fuer die Verteidigung beruecksichtigt werden soll. Genaueres findet man
+       auf der Manpage von Defend().
+    3. this_object() sollte immer angegeben werden, damit der Raum der
+       Angreifer ist, anstatt ein nicht naeher bestimmtes Objekt. Dies koennte
+       dann beispielsweise der Spieler selbst sein, was dazu fuehrt, dass im
+       Falle eines Todes der Spieler als Killer von sich selbst genannt wird,
+       anstatt "Ein Feuerball".
+
+
+
+
+----------------------------------------------------------------------------
+Last modified: Wed Feb 13 17:00:54 2002 by Bambi
diff --git a/doc/wiz/todessequenz b/doc/wiz/todessequenz
new file mode 100644
index 0000000..0ab03e8
--- /dev/null
+++ b/doc/wiz/todessequenz
@@ -0,0 +1,115 @@
+Eine Todessequenz ist eine ganz normale Textdatei mit folgendem Aufbau:
+In der ersten Zeile steht die Dauer der Todessequenz in heart_beat-Einheiten.
+Es folgen Eintraege der Form <zeit>:<text>. <zeit> ist dabei der Zeitpunkt
+(ebenfalls in heart_beat-Einheiten), in denen der Text <text> ausgegeben
+werden soll. <text> kann sich dabei auch ueber mehrere Zeilen erstrecken;
+Leerzeilen werden 1:1 uebernommen.
+
+Beispiel:
+---- <snip> ----
+70
+1:Vor Dir tut sich ein tiefer, schwarzer Abgrund auf. Ein starker Sog
+versucht, Dich hineinzuziehen.
+
+2:Du balancierst muehsam auf dem Rand des Abgrundes, doch dann wird der
+Sog zu stark!
+
+3:Du faellst! Um Dich herum ist nur noch tiefe Schwaerze.
+... usw.
+---- <snip> ---
+
+Um die Todessequenz ein wenig abwechslungsreicher zu gestalten, kann man
+einige Platzhalter verwenden. Man kann Meldungen einbauen, die abhaenig sind
+
+- vom Geschlecht: dies geht mit <G>mText:wText</G>. mText wird bei maennlichen
+  Toten eingebaut, wText bei weiblichen. Man kann auch einen der Texte weg-
+  lassen; der Doppelpunkt ist jedoch Pflicht!
+  Beispiel:
+    5:Der Tod sagt: KOMM MIT MIR, STERBLICHE<G>R:</G>!
+    6:Der Tod sagt: WAR WOHL NIX, <G>BUERSCHCHEN:FROLLEINCHEN</G>!
+
+- von der Rasse: Dies geht aehnlich wie beim Geschlecht, und zwar in der Form
+  <R>dText|mText|eText|zText|hText|fText</R>.
+  mText wird bei Menschen ausgegeben, eText bei Elfen, zText bei Zwergen,
+  hText bei Hobbits, fText bei Felinen und dText bei allen anderen
+  (zB. Magier mit selbst gesetzten Rassen).
+
+  Wie bei geschlechtsabhaengigen Meldungen koennen auch hier einzelne Texte
+  weggelassen werden.
+
+  Beispiel:
+    1:Der Tod sagt: SCHOEN GESTORBEN, <R>FREMDLING|MENSCHLEIN|SPITZOHR|DREIKAESEHOCH</R>?
+    2:<R>||Der Tod sagt: ELFEN WAREN SCHON LANGE NICHT MEHR HIER!|</R>
+
+- vom Charakter: Der Charakter eines Spielers kann sich im Bereich von -1000
+  (satanisch) bis +1000 (heilig) bewegen. Zwischen <A> und </A> kann man
+  charakterabhaengige Meldungen einbauen. Die Abstufungen werden dabei in der
+  Form ##<Untergrenze>## angegeben, wobei <Untergrenze> die untere Grenze des
+  Charakterwertes ist, ab dem die Meldung ausgegeben wird.
+  Der Text direkt nach <A> entspricht einer Untergrenze von -1000, die
+  weiteren Texte sollten in aufsteigender Reihenfolge angegeben werden.
+  Beispiel:
+    7:<A>
+    Der Tod sagt: AH, EIN SATANIST!
+    ##-999##
+    Der Tod sagt: SO EIN<G>:E</G> SCHLIMME<G>R:</G>!
+    ##0##
+    Der Tod sagt: EIN TYPISCHES UNENTSCHIEDEN...
+    ##1##
+    Der Tod sagt: SO EIN<G>:E</G> LIEBE<G>R:</G>!
+    ##1000##
+    Der Tod sagt: OH, GUTEN TAG, EUER HEILIGKEIT!
+    </A>
+
+- von der Zahl der Tode: Dies geht aehlich wie beim Charakter, allerdings
+  ist der Platzhalter hier <D>...</D>. Die Untergrenze fuer den ersten Text
+  ist 1 (sonst waere der Spieler ja nicht hier ;)
+  Beispiel:
+    8:<D>
+    Der Tod sagt: SCHOEN, DICH AUCH MAL HIER ZU SEHEN!
+    ##2##
+    Der Tod sagt: MACH DIR NIX DRAUS, DAS PASSIERT SCHON MAL!
+    ##20##
+    Der Tod sagt: WAS, DU SCHON WIEDER?
+    ##50##
+    Der Tod sagt: NOCH EINMAL, UND ICH BEHALTE DICH ENDGUELTIG HIER!
+    </D>
+
+- vom Level: Auch hier erfolgt die Auswertung wie beim Charakter, allerdings
+  zwischen den Platzhaltern <L> und </L>. Die Untergrenze fuer den ersten
+  Text ist 0.
+  Beispiel:
+    8:<L>
+    Der Tod sagt: MACH DIR NICHTS DRAUS.
+    ##5##
+    Der Tod sagt: VIELLEICHT SOLLTEST DU DAS NAECHSTE MAL BESSER AUFPASSEN!
+    ##15##
+    Der Tod sagt: SO WIRST DU NIE SEHER ODER MAGIER!
+    ##20##
+    Der Tod sagt: NUR EIN TOTER SEHER IST EIN GUTER SEHER! ;)
+    </L>
+
+- vom Zufall: Und noch mehr Abwechslung... ;) Der Aufbau ist aehnlich dem der
+  vorherigen. Zwischen den Platzhaltern <Z=wert> und </Z> stehen Meldungen der
+  ##x##text, wobei die x die relative Wahrscheinlichkeit (bezogen auf wert)
+  angeben, mit der der Text text ausgegeben wird.
+  Die x sollten zusammengezaehlt wert ergeben! Die Reihenfolge ist zwar
+  prinzipiell egal, aus Performancegruenden sollte man die Texte aber mit
+  absteigender Wahrscheinlichkeit anordnen.
+  Beispiel:
+    9:<Z=6>
+    ##3##
+    Dieser Text wird in 50% aller Faelle ausgegeben (3/6)
+    ##2##
+    Dieser Text in 33% aller Faelle (2/6)
+    ##1##
+    Und dieser Text in 17% aller Faelle (1/6)
+    </Z>
+
+Ausserdem kann man noch den Namen des Toten einbauen, und zwar mit <n> in
+normaler Schreibweise, und mit <N> in GROSSbuchstaben.
+Beispiel:
+  10:Du schaust in den Spiegel und siehst: <n>!
+  11:Der Tod sagt: HALLO, <N>!
+
+
diff --git a/doc/wiz/topliste b/doc/wiz/topliste
new file mode 100644
index 0000000..a39efc6
--- /dev/null
+++ b/doc/wiz/topliste
@@ -0,0 +1,33 @@
+Fuer die Verwaltung der Standardtoplisten gibt es /secure/topliste, welches (zur Zeit) bei Login bei toplisten-willigen Spielern die toplisten-relevanten Daten vom Spieler abfragt und in einer Tabelle eintraegt.
+
+Abfragen laesst die Liste jederzeit wie folgt durch Aufruf folgender Funktionen in /secure/topliste: Liste, SpielerListe, SeherListe und HardcoreListe.
+
+Die 4 sind varargs und bekommen folgende moegliche Argumente:
+* string rasse
+  Nur Spieler der Rasse <rasse> beruecksichtigen
+* string gilde
+  Nur Spieler der Gilde <gilde> beruecksichtigen
+* int limit
+  Max. <limit> Eintraege, Default: 100, Max: 100
+* string sort
+  Liste sortieren nach: lep, qp, xp, age, wizlevel, hardcore, gilde, rasse, 
+  name
+  Default: lep
+
+Die Funktionen liefern ein Array zurueck, was fuer jeden Eintrag in der Topliste wieder ein Array enthaelt: < <string|int>* >*
+
+Beispiele:
+# /secure/topliste->Liste()
+  Die 100 Chars mit den meisten Stufenpunkten
+# /secure/topliste->HardcoreListe(0,0,10)
+  Die 10 HC-Chars mit den meisten Stufenpunkten
+# /secure/topliste->Liste(0,"kaempfer",10,"xp")
+  Die 10 Kaempfer-Chars mit den meisten XP
+# /secure/topliste->Liste("Zwerg","zauberer")
+  Die 100 Zwergenzauberer mit den meisten Stufenpunkten
+Weiteres koennt ihr euch ja sicher denken.
+
+Achso, das Ergebnis sieht dann ungefaehr so aus:
+({ ({name, lep, qp, xp, level, age, rasse, gilde, wizlevel, hardcore}), ... })
+({({"hcplay",100,0,0,1,62,"Mensch","abenteurer",0,1})})
+
diff --git a/doc/wiz/transporter b/doc/wiz/transporter
new file mode 100644
index 0000000..a3f001c
--- /dev/null
+++ b/doc/wiz/transporter
@@ -0,0 +1,19 @@
+DEFINIERT IN:
+	"/std/transport"
+	"/sys/transport.h"
+
+BEMERKUNGEN:
+	Zu Transportern gibt es ein Beispiel unter
+        '/doc/beispiele/misc/bsptransporter1.c' und auch die verwendeten 
+        Properties sind dokumentiert.
+	
+        Um einen Transporter zu aktivieren, muss er in das Preload-File der
+	Region geschrieben werden, oder aber ueber eine Funktion im Start-
+	und Zielraum aufgerufen werden, die das erledigt.
+
+SIEHE AUCH:
+	P_ARRIVEMSG, P_DEPARTMSG, P_ENTERMSG, P_LEAVEMSG, P_LEAVEFAIL,
+	P_ENTERFAIL, P_MAX_PASSENGERS, AddRoute, AddMsg, Start
+        /d/inseln/schiffe/HowTo
+----------------------------------------------------------------------------
+Last modified: Wed Dec 26 14.43:07 2001 by Tilly
diff --git a/doc/wiz/uniques b/doc/wiz/uniques
new file mode 100644
index 0000000..c507ff8
--- /dev/null
+++ b/doc/wiz/uniques
@@ -0,0 +1,42 @@
+
+ UNIQUES
+    
+    Sogenannte "uniques" sind Objekte, die nicht in beliebiger Anzahl im Mud
+    vorhanden sein koennen, sondern von denen es entweder nur eins oder eine
+    begrenzte Anzahl gibt. Beispiele fuer uniques sind der bekannte Voll-
+    strecker des Weghiers oder die gruenen Roben aus dem Schemenreich.
+    Die Begrenzung auf wenige Objekte hat normalerweise den Sinn, besondere
+    Eigenschaften oder aussergewoehnliche Staerke zu rechtfertigen. Bei 
+    einigen Objekten passiert dies auch aus logischen Gruende, weil das
+    Objekt einfach einzigartig ist.
+
+    Fuer uniques gelten folgende Richtlinien:
+
+    - Die Erreichbarkeit des/der uniques darf nicht vom Reboot abhaengen.
+      Das bedeutet, ein Spieler muss waehrend der gesamten Uptime die
+      theoretische Moeglichkeit haben, ein bestimmtes Objekt durch welchen
+      Aufwand auch immer zu erreichen.
+
+    - Das Objekt muss auch gegen den Willen des bisherigen Besitzers zu
+      bekommen sein.
+
+    - Sollte das Objekt in Umlauf sein, muss an der Fundstelle ein Hinweis
+      darauf existieren, dass dieses Objekt dort zu bekommen ist. Auch wenn
+      fanatische Spieler ein Unique 5 Sekunden nach Reboot wegscripten,
+      sollten nachfolgende Spieler wenigstens wissen, wo es mal gewesen ist.
+
+    Uniques, die aufgrund ihrer Werte nicht genehmigungspflichtig sind, sollten
+    sich trotzdem an diese Richtlinie halten. Uniques ohne jegliches Konzept,
+    die der Balance vorgelegt werden, haben jedoch kaum Chance auf Genehmigung.
+    
+
+ SIEHE AUCH
+
+     balance, ruestungen, waffen, fernwaffen, npcs, grenzwerte,
+     attributsveraenderungen, resistenzen, kampfobjekte
+
+
+------------------------------------------------------------------------------
+ LETZTE AeNDERUNG:
+    Don, 31.10.1999, 20:00:00 von Nachtwind
+   
diff --git a/doc/wiz/vertrag b/doc/wiz/vertrag
new file mode 100644
index 0000000..1abc68a
--- /dev/null
+++ b/doc/wiz/vertrag
@@ -0,0 +1,128 @@
+
+Herzlich willkommen im Kreis der Magier!
+
+Ab jetzt kannst Du hinter die Kulisse des MorgenGrauens schauen.
+Diese Faehigkeit birgt Verantwortung.
+
+Deshalb gelten ab jetzt zusaetzlich zu den bisherigen Regeln folgende
+Magierregeln fuer Dich:
+
+Man darf Spielern keine Hilfen geben, es sei denn, es liegt ein
+*offensichtlicher* Fehler vor. Dabei zaehlt auch ein Zweitspieler,
+mit dem ein Magier spielt, zu den Spielern!
+Haelt der Sheriff einen Extra-Charakter eines Magiers nicht fuer einen
+echten Zweitie, kann er ihn jederzeit zum Testspieler erklaeren. 
+
+Beispiele fuer nicht erlaubte Hilfen:
+- Stats von Monstern mitteilen.
+- Objekte clonen, und Spielern geben.
+- Objekte schreiben, die den Spielern zu sehr helfen, oder umgekehrt
+  die Spieler schaedigen.
+- Spieler teleportieren.
+- Explizite Kommandos angeben, die ein Spieler eingeben muss.
+- Selber (oder mit Zweitcharakteren) mitspielen oder -kaempfen, sobald 
+  Insiderwissen in Anwendung kommt. Hier ist der gesunde Menschenverstand
+  bei der Entscheidung gefragt, ab wann dies der Fall ist.
+- Raeume resetten, damit die Spieler Objekte bekommen.
+  (Insbesondere kann das Nebeneffekte haben, die man als normaler
+   Magier nicht ueberschauen kann, ausserdem koennen die Spieler auch mal
+   warten.)
+- Weitergabe von Objektinformationen, die der Spieler nicht einsehen kann.
+
+In den folgenden Faellen darf natuerlich geholfen werden:
+- Spielern aus fehlerhaften Raeumen oder der 'void' heraushelfen.
+- Man sieht, dass der Spieler weiss, was er zu tun hat, aber ihm die
+  abwegige(!) Formulierung nicht einfaellt. (Hier sollte man aber
+  zusaetzlich dem Magier, der das entsprechende Objekt 'verbrochen'
+  hat, eine Mitteilung geben, auf dass er es verbessert.)
+
+Selber spielen soll man nur dann, wenn man den Spielern dabei nicht
+hilft oder ihnen ein Abenteuer vor der Nase wegloest.
+
+
+Generell muss die Privatsphaere von Spielern geachtet werden. 
+
+Snoopen von Spielern ist nur dann erlaubt, wenn es darum geht, Fehler
+im Mud zu finden oder Ideen zu sammeln, um seinen _eigenen_ Gebiete,
+bzw. Regionen fuer die man verantwortlich ist, zu verbessern und 
+anzupassen. Es darf auf keinen Fall dafuer benutzt werden, Spieler
+ohne besonderen Grund zu beobachten, sich ueber sie lustig zu machen, 
+oder sie auszuspionieren. Wenn Spieler Post schreiben oder lesen ist 
+snoopen strengstens untersagt (Briefgeheimnis).
+Generell ist es angebracht Spieler darauf hinzuweisen, dass sie 
+gesnoopt werden.
+
+Es ist ebenso unzulaessig, andere Moeglichkeiten auszunutzen, die 
+dazu dienen Spieler zu beobachten, bzw. auszuspionieren (zB verfolgen).
+
+Insbesondere ist es STRIKT untersagt, Objekte zu schreiben, die in
+irgendeiner Weise (zB add_action(...,"",1)) 'teile mit', 'fluester'
+und aehnliche Kommunikationsbefehle abfangen, um Gespraeche von anderen
+abzuhoeren. Dies stellt einen schweren Eingriff in die Intimsphaere der
+anderen Teilnehmer dar und wird dementsprechend geahndet!
+
+Jegliche Art von Belaestigung von Spielern ist untersagt. 
+Dazu gehoert das Verfluchen, Monster auf sie hetzen, oder ihnen auf
+irgendeine Art boeswillig Schaden zuzufuegen.
+
+
+Zu dem, was Du hier so programmierst:
+Alles was Du hier an Daten ablegst ist natuerlich Dein eigenes, 
+geistiges Eigentum. Trotzdem gehen wir davon aus, das alles, was hier
+im Mudverzeichnis landet, auch fuer das MorgenGrauen entwickelt worden
+ist, also alles was Du schreibst, auch vom Mud genutzt werden darf.
+Dies fuehrt zu folgender Regelung:
+ 
+Fuer das MorgenGrauen gilt uneingeschraenktes Nutzungsrecht fuer alle 
+Monster, Objekte oder Raeume die Du hier programmierst. Dies gilt 
+insbesondere fuer alle Sachen, die bereits an die Regionen des MGs
+angeschlossen sind.
+Das bedeutet fuer Dich, dass unter Umstaenden von Dir geschriebene 
+Objekte auch gegen Deinen Willen angeschlossen bleiben, und vielleicht
+sogar ggf. aus einem Backup wieder eingespielt werden.
+Mit dieser Regel soll verhindert werden, das unglueckselige Magier aus-
+steigen und beim Verlassen des MG riesige Loecher in der Landschaft 
+und im allgemeinen Gleichgewicht hinterlassen.
+
+
+Sollte Deine Magierzeit beendet sein, verpflichtest Du Dich, ueber
+etwaige waehrend Deiner Magierzeit gewonne nicht-oeffentliche Interna
+- insb. nicht-oeffentlichen Code - auch weiterhin Stillschweigen zu 
+bewahren. Dies gilt unabhaengig von dem Grund oder der Art und Weise,
+Deine Magierzeit zu beenden (z.B. Loeschung).
+
+
+Wenn Du diesen Vertrag unterschreibst, erkennst Du die Regeln an.
+Die Regeln in /etc/WIZRULES sind immer verbindlich, unabhaengig davon,
+wie sie zum Zeitpunkt deines Magierwerdens aussahen.
+
+
+Nun genug der strengen Regeln ;).
+Nun zu dem, was Du jeden Moment wirst; und zu dem, was danach kommt:
+
+1.) Wenn Du diesen Vertrag unterschrieben hast, und Dein Sponsor (das ist
+    der, der Dir den Vertrag gegeben hat) Merlin gebeten hat, Dich zum
+    Magier zu machen, bekommst Du die magischen Faehigkeiten der Magier.
+    Du wirst Dich unsichtbar machen koennen, andere Wesen teleportieren
+    koennen (siehe jedoch Regeln), Objekte clonen und so weiter und so
+    weiter. Dein Sponsor hat die Aufgabe, Dir den Umgang mit den neuen
+    Faehigkeiten beizubringen (Du darfst ihn darauf festnageln ;-)).
+
+2.) Du kannst jedoch selbst noch keinerlei Programme schreiben. Wenn Du
+    auch selber programmieren willst, musst Du zuerst ein Gesellenstueck
+    abliefern. Wie das geht, findest du bei der Hilfe zum Gesellenstueck
+    beschrieben("hilfe gesellenstueck").
+
+
+So und nun zu den Dingen, die fuer Dich da sind:
+
+    Mit dem Befehl "mhilfe" kannst Du eine Uebersicht ueber die Befehle
+    bekommen, die ein Magier zusaetzlich zu denen der Spieler hat. In
+    dem Verzeichniss /doc findest Du verschiedene Files, die Dir das
+    Verstaendnis erleichtern sollen. Eine Uebersicht kannst Du mit dem
+    Befehl. "more /doc/README" bekommen.
+	
+    Der gute alte Merlin ist nicht nur der Urvater aller Magier, sondern
+    beherbergt darueber hinaus auch einen (ab und zu) gut besuchten WizClub.
+    Wer sich mit "goto" noch nicht so gut auskennt, kann ihn in der 
+    Abenteurergilde mit dem Kommando "treff" betreten.
diff --git a/doc/wiz/waffen b/doc/wiz/waffen
new file mode 100644
index 0000000..58c4c04
--- /dev/null
+++ b/doc/wiz/waffen
@@ -0,0 +1,202 @@
+ WAFFEN:
+
+    a. Allgemeines
+
+    Alle (zumindest neuen!) Waffen sollten ueber eine vernuenftige
+    Beschreibung und auch Details verfuegen. Einfach "Ein Schwert" ist
+    ein bissel arg duerftig und rechtfertigt auf keinen Fall
+    irgendwelche hohen WCs oder gar HitFuncs! Darauf sollten schon die
+    RMs achten...
+
+    Nach Moeglichkeit auch P_INFO setzen, das ist fuer Spieler nicht so
+    frustrierend und kann ja auch einen netten Spruch enthalten. P_INFO
+    ist *zwingend* bei Waffen mit HitFuncs! Muss ja nicht absolut ein-
+    deutig sein, aber etwas Liebe zum Detail sollte bei Sonderwaffen auf
+    jeden Fall gelten.
+
+    Waffen vom Typ WT_MISC duerfen weder ueber eine Defend- noch eine
+    HitFunc verfuegen. Die AC solcher Waffen ist immer 0. Weiter duerfen
+    solche Waffen keinerlei andere kampfrelevante Bedeutung besitzen
+    oder Manipulationen am/im Spieler/Gegner verursachen.
+
+
+    b. Bemerkungen zu einigen Properties:
+
+     P_WC
+        Die WC sollte einigermassen "realistisch" gewaehlt werden. Die
+        Verantwortung hierfuer obliegt den jeweiligen RMs. Sie sollte
+        zwischen ca. 35 und 200 liegen. Auf jeden Fall sind die aktuellen
+        Genehmigungsgrenzen zu beachten. Sollte die WC diese Grenzen
+        ueberschreiten, unterliegt die Waffe ausser der Genehmigung durch
+        den RM der Beurteilung durch das Waffengremium.
+
+     P_NR_HANDS
+        Waffen ueber einer effektiven WC von 150 muessen zweihaendig sein.
+        Ausnahmen koennen unter Umstaenden genehmigt werden, zum Beispiel
+        wenn die Waffe schwer erreichbar oder zahlenmaessig begrenzt, eine
+        Questbelohnung etc. ist. Alle einhaendigen Waffen ueber WC 140 sind
+        in jedem Fall genehmigen zu lassen.
+
+        Messer muessen generell einhaendig sein!
+
+     P_WEIGHT
+        Bitte realistisch halten. Damit ist *nicht* das RL-Gewicht
+        gemeint, sondern man sollte am besten vergleichbare Waffen des
+        MG als Massstab nutzen. Da hier z.T. gravierende Diskrepanzen
+        bestehen, evtl. mal mehrere vergleichen. Die Verantwortung
+        hierfuer obliegt den RMs.
+
+        Waffen mit einem Gewicht von ueber 4000 Gramm sollten normalerweise
+        auch zweihaendig sein oder muessen der Balance vorgelegt werden.
+
+     ** Besondere Leichtgewichte bitte genehmigen lassen, um spaeterem     **
+     ** Aerger vorzubeugen. Grade fuer Kaempfer ist das Gewicht von Waffen **
+     ** sehr wichtig!                                                      **
+
+    Zur Erinnerung: Spieler mit Kraft 20 koennen nur 25000 Gewichts-
+    einheiten ("Gramm") tragen.
+
+     P_SIZE
+        Die Laenge der Waffe in cm. Setzt man sie nicht, so gilt der
+        Default- wert fuer den jeweiligen Waffentyp, welcher in der Manpage
+        zu P_SIZE notiert ist.
+
+     P_VALUE
+        Wie bei P_WEIGHT sind die RMs gefragt: Augenmass zaehlt. Werte ueber
+        10000 oder so sind zwar nett, aber sinnlos und unrealistisch.
+
+     P_DAM_TYPE
+        Jede Waffe, die aus physikalischem Material besteht (also faktisch
+        alles mit Hardware) *muss* einen physikalischen Schadenstyp haben.
+
+     ** Waffen mit mehr als einem nichtphysikalischen Schadenstyp oder   **
+     ** mehr als 50% nichtphysikalischen Anteilen sind generell zur      **
+     ** Genehmigung vorzulegen und als Besonderheit zu handhaben. Nicht  **
+     ** genehmigt und nur im Rahmen der Gildenbalance ermoeglicht werden **
+     ** a) Waffen mit mehr als 66% nichtphysikalischem Schaden im Array, **
+     ** b) Waffen mit einem nichtphysikalischen Schadenstyp ueber 50%    **
+
+    Weiterhin genehmigungspflichtig sind die Schadenstypen:
+
+    DT_TERROR, DT_SOUND, DT_SQUEEZE
+
+    Diese Schadenstypen werden in Waffen nur genehmigt, wenn sie gut
+    begruendet sind.
+
+    Der Schadenstyp DT_EXPLOSION wird in Waffen generell nicht mehr
+    genehmigt.
+
+     P_WEAPON_TYPE
+        Nur zur Erinnerung: es gibt im MG zu viele Schwerter und Speere.
+        Nutzt auch die anderen Waffentypen! (Messer und Peitschen sind sehr
+        rar. Bitte angepasste WCs!)
+
+     P_EFFECTIVE_WC
+        Hier kann die evtl durch eine HitFunc veraenderte WC angegeben
+        werden. Der Durchschnittswert soll da stehen. Die Kaempfergilde kann
+        das in gewissen Grenzen abschaetzen.
+
+     P_EFFECTIVE_AC
+        Fuer Paradewaffen setzen. Werte unbedingt mit Boing absprechen!
+
+     P_NOBUY
+        Waffen ab WC 150 werden beim Verkauf im Laden zurueckbehalten. Es
+        sollte aber auch fuer Waffen, die HitFuncs enthalten, P_NOBUY
+        gesetzt werden.
+
+
+    c. Spezialwaffen/Waffen mit Sonderfunktion
+
+     ** ALLE Waffen mit HitFunc oder entsprechender Fkt. muessen   **
+     ** genehmigt werden!                                          **
+
+    Solche Waffen muessen ueber ein P_INFO verfuegen und irgendwo in
+    ihrer Beschreibung oder im P_INFO mindestens eine Andeutung ueber
+    die Herkunft oder den Grund ihrer besonderen Faehigkeit haben.
+
+    Auch Spezialwaffen sollten nach Moeglichkeit nicht ueber eine
+    EFFECTIVE_WC von 200 hinausgehen. Der Return-Wert der HitFunc,
+    sofern er von 0 abweicht, MUSS per random() zurueckgegeben werden,
+    da er ohne weiteres random() auf die WC aufaddiert wird.
+
+    Zu beachten ist, dass man bei Waffen, die nur fuer NPCs mehr Schaden
+    machen sollen, nicht (nur) ueber P_RACE prueft, ob der Benutzer ein
+    solcher ist. Es ist denkbar, dass Spieler ihre Rasse temporaer ver-
+    aendern koennen. Waffen die nur bei
+    !interactive(QueryProp(P_WIELDED)) besser zuschlagen, brauchen
+    natuerlich nicht genehmigt zu werden.
+
+    Die Dichte solcher Waffen in einem Gebiet sollte ein vernuenftiges
+    Mass nicht ueberschreiten. Fuer eine Sonderwaffe sollten auch
+    etliche nicht-magische Waffen in der Umgebung sein. Zumindest die
+    starken Waffen (also nicht die, die nur einen Gag oder so
+    beinhalten, sondern wirklich in den Kampf eingreifen) sollten nicht
+    zu leicht zu bekommen sein. Hierauf sollen die RMs achten. Solche
+    Sachen gehoeren zu Monstern, die ein wenig schlechter erreichbar
+    sind oder die besonders stark oder sonstwie unangenehm sind. Also
+    nix verschenken.
+
+    Waffen, die Monster vergiften (also nicht nur P_DAM_TYPE DT_POISON
+    haben) sind zwar nicht grundsaetzlich verboten, aber doch
+    unerwuenscht. Sie sind auf jeden Fall genehmigungspflichtig.
+    Ausserdem sollte die Wahrscheinlichkeit einer Vergiftung pro
+    Kampfrunde max. bei 1% liegen.
+
+    Des weiteren muessen Waffen, die fuer bestimmte Gilden bestimmte
+    Vorteile bringen (sich beim Kami der Tanjian nicht abnutzen zum
+    Beispiel) ebenfalls von der Balance genehmigt werden.
+
+
+    d. Genehmigungsgrenzen
+
+    Einhaendige Waffen  :    ab P_WC >= 140
+    Zweihaendige Waffen :    ab P_WC >= 175
+
+    Fuer Waffen die einen nichtphysikalischen Schadenstyp enthalten:
+
+    Einhaendige Waffen  :    ab P_WC >= 120
+    Zweihaendige Waffen :    ab P_WC >= 150
+
+
+    e. Spezielle Properties fuer die Kaempfergilde
+
+    Diese Properties sind definiert in '/p/kaempfer/kaempfer.h'. Mit ihnen
+    kann man Boni fuer bestimmte Attacken der Kaempfer vergeben (z.B.
+    Bonus auf Waffenschlag oder Todesstoss).
+
+    Genauere Hinweise zu diesen Properties und den zu setzenden Werten
+    findet man in 'man kaempferboni'.
+
+    Prinzipiell gilt:
+
+     ** Alle Waffen, in denen eine solche Property gesetzt wird,  **
+     ** sind mit der Objektbalance abzuklaeren.                   **
+
+
+    f. Parierwaffen
+
+    Parierwaffen sind Waffen, die die Verteidigung unterstuetzen.  Eine
+    Waffe wird als Parierwaffe verwendet, wenn die Property P_PARRY
+    gesetzt ist. Folgende Werte sind moeglich:
+
+    PARRY_NOT     Die ist KEINE Parierwaffe (=default).
+
+    PARRY_ONLY    Dies ist eine reine Parierwaffe.
+
+    PARRY_TOO     Diese Waffe wird sowohl als Parierwaffe als auch
+                  als Angriffswaffe benutzt
+
+    Die Schutzwirkung der Parierwaffe wird wie bei Ruestungen ueber die
+    Property P_AC gesetzt. Ueber die Property P_DEFEND_FUNC kann wie bei
+    Ruestungen eine DefendFunc gesetzt werden.
+
+    Waffen mit PARRY_ONLY unterliegen den gleichen P_AC-Grenzwerten wie
+    Ruestungen vom Typ AT_SHIELD. Waffen mit PARRY_TOO oder einer
+    DefendFunc muessen generell genehmigt werden.
+
+ SIEHE AUCH:
+     balance, ruestungen, fernwaffen, uniques, npcs, grenzwerte,
+     attributsveraenderungen, resistenzen, kampfobjekte, kaempferboni
+
+ LETZTE AeNDERUNG:
+     16. Januar 2014 Gloinson
diff --git a/doc/wiz/waffenskills b/doc/wiz/waffenskills
new file mode 100644
index 0000000..6e2ddf5
--- /dev/null
+++ b/doc/wiz/waffenskills
@@ -0,0 +1,59 @@
+Waffenskills im MorgenGrauen
+----------------------------
+
+Das Skillsystem des MGs ist recht komplex. Hier nur ein paar Bemeerkungen
+zu den Waffenskills.
+
+Es gibt 2 Sorten von Waffenskills:
+
+* allgemeine Waffenskills. Diese sind in die Shell eingebunden.
+* Gildenspezifische Skills. Diese sind in der entsprechenden Gilde definiert.
+
+Die Skills werden in einer Property im Spieler gespeichert (P_NEWSKILLS). Es
+handelt es sich um ein mapping, das diesen Aufbau hat:
+
+(["ANY":([ANYSKILLS]),
+"gilde1":([SKILLS_VON_GILDE_1]),
+"gilde2":([SKILLS_VON_GILDE_2]),
+...])
+
+Mit Query(P_NEWSKILLS) erhaelt man das gesamte Mapping.
+
+Mit QueryProp(P_NEWSKILLS) erhaelt man NUR DIE SKILLS DER AKTUELLEN GILDE!
+Das heisst, im obigen Beispiel, wenn der Spieler in gilde1 ist, ist
+der Returnwert SKILLS_VON_GILDE_1.
+
+Sprich: Allgemeine Skills, wie allgemeine Waffenskills, stehen in diesem 
+Mapping nicht drin! Ebenso wie z.B. der entgifte-Spell aus der 
+Duesterwaldquest (wohl aber der der Kleriker, wenn man einer ist).
+
+Mit QuerySkill("skillname") kann man einen Skill abfragen. Dabei wird, wenn
+kein Skill unter diesem Namen in der aktuellen Gilde eingetragen ist, ein
+eventuell vorhandener ANY-Skill zurueckgegeben. Daher wird z.B. bei einem
+Abenteurer bei QueryProp(P_NEWSKILLS) der Schwertwaffenskill nicht
+angezeigt, wohl aber bei einem QuerySkill(FIGHT(WT_SWORD)).
+
+Prioritaet hat immer der Skill der Gilde, wenn er vorhanden ist.
+
+Man kann auch Skills in der Gilde unterdruecken. Dies geht ueber die Poperty
+P_GUILD_DEACTIVATE_SKILLS. Diese Skills werden nicht per se unterdrueckt,
+sondern nur die entsprechenden ANY-Skills.
+
+Sprich: Es sei A ein Abenteurer.
+
+xcall A->QuerySkill(FIGHT(WT_SWORD))
+
+mag folgendes zurueckgeben:
+
+Result: (["si_difficulty":150,"si_abil":0,"si_guild":"ANY"])
+
+tritt A daraufhin den Kaempfern bei und hat dort noch keinen Schwertskill
+gelernt, wird hingegen 0 zurueckgegebn. Fuer den Fall eines Austritts ist der
+Wert aber nach wie vor gespeichert, wie man per Query(P_NEWSKILLS) leicht
+sehen kann. Dies wird unterdrueckt, da in der Kaempfergilde die Prop 
+P_GUILD_DEACTIVATE_SKILLS gesetzt wird.
+
+Tritt der Spieler den Chaoten bei, aendert sich hingegen bei diesem Aufruf
+nichts.
+
+Letzte Aenderung: Humni, 2003-07-09
diff --git a/doc/wiz/zaubertraenke b/doc/wiz/zaubertraenke
new file mode 100644
index 0000000..aadb54a
--- /dev/null
+++ b/doc/wiz/zaubertraenke
@@ -0,0 +1,95 @@
+
+Zaubertraenke fuer Magier
+=========================
+
+Wie man die Traenke jetzt genau versteckt bleibt dem betreffenden Magier
+ueberlassen, es sollte halt insgesamt ein breites Spektrum von sehr leicht
+zu finden bis fast unmoeglich abgedeckt sein.
+Fuer das Orakel der Hochebene sollte dann ein entsprechender Spruch
+vorbereitet werden, nicht zu kryptisch aber doch orakleig.
+
+Die zufaellige Auswahl an zugeordneten Zaubertraenken wird beim ersten
+Einloggen des Spielers festgelegt.
+
+Die Raeume, in denen Traenke versteckt werden (und es duerfen nur Raeume
+sein), werden in 8 Listen eingeteilt, je nach Schwierigkeitsgrad. Der haengt
+natuerlich von der Lage (so ist ein Trank in einem monsterwimmelnden
+Labyrinth schwieriger zu erreichen, als einer auf der Hochebene), und von
+dem Versteck selbst ab.
+Questraeume, die nur im Rahmen der Quest erreichbar sind, sind ungeeignet.
+
+
+Mein Standardbeispiel fuer ein Versteck ist immer folgendes:
+ 
+> schaue
+blablablabla .... Ein Schreibtisch steht in der Ecke. ... blablabla
+> unt schreibtisch
+Er hat eine Schublade.
+> oeffne schublade                         
+Du oeffnest die Schublade.
+> unt schublade
+In der Schublade enteckst Du ein paar Papiere.
+> unt papiere
+Beim Rumwuehlen in den Papieren entdeckst Du einen kleinen Zaubertrank, den
+Du sofort trinkst.
+ 
+Dann kommt die Auswahlsequenz, welche Eigenschaft man erhoehen will.
+ 
+In diesem Fall reichen Details, Details mit Closure und eine Kommando fuer
+"oeffne" aus. Etwa wie folgt:
+
+  void create() {
+    [...]
+    SetProp(P_INT_LONG, ... Ein Schreibtisch steht in der Ecke ...);
+  
+    AddDetail(({"tisch", "schreibtisch"}),
+      "Er hat eine Schublade.");
+
+    AddCmd("oeffne&schublade", #'action_oeffne,
+           "Was moechtest du oeffnen.");
+  }
+
+  private int action_oeffne() {
+    tell_object(this_player(), "Du oeffnest die Schublade.\n");
+    tell_room(this_object(), this_player()->Name()+
+                             " oeffnet eine Schublade.\n", ({this_player()}));
+
+    AddDetail("schublade",
+              "In der Schublade entdeckst du ein paar Papiere.\n");
+    AddDetail("papiere", #'detail_papiere);
+  }
+
+  // Zaubertrankgebendes Detail  
+  private string detail_papiere() {
+    if (this_player()->FindPotion(
+        break_string("Beim Rumwuehlen in den Papieren entdeckst Du einen "
+                     "kleinen Zaubertrank, den Du sofort trinkst.", 78)))
+      return "";  
+      // Es muss ein String zurueckgegeben werden, da man sonst
+      // die Fehlermeldung "Sowas siehst du hier nicht." bekommt
+    else
+      return "Die Papiere sind alle unbeschriftet.\n";
+  }
+
+  // Aufraeumen des Raumes
+  void reset() {
+    if(!sizeof(filter(all_inventory(this_object()), #'interactive))) {
+      RemoveDetail("papiere");
+      RemoveDetail("schublade");
+    }
+    ::reset();
+  }
+  
+FindPotion() gibt 1 zurueck, wenn der Spieler den Zaubertrank finden darf.
+
+Wer also Traenke verstecken will, macht sowas in der Art und meldet dann den
+Raum persoenlich oder per Post bei den Erzmagiern bzw seinem aktiven
+Regionsmagier an.
+ 
+SIEHE AUCH:
+    Weitere Dateinamen mit Beispielen fuer Trankverstecke kann man der
+    Datei /etc/traenke entnehmen.
+
+    Befehl:    traenke (fuer Magier zum Einschalten des Findens von ZTs)
+
+10. August 2015 Gloinson
diff --git a/doc/wiz/zweitiedb b/doc/wiz/zweitiedb
new file mode 100644
index 0000000..bf72d26
--- /dev/null
+++ b/doc/wiz/zweitiedb
@@ -0,0 +1,21 @@
+In der Zweitie-DB werden alle Chars verwaltet, die als Zweitie von irgendeinem anderen markiert sind. (Zur Zeit: nur die seit Herbst 2014 eingeloggten.)
+
+Direkte Abfrage der Zweitie-DB (fuer Erzmagier):
+
+Die Zweitie-DB liegt unter
+secure/ARCH/second.sqlite
+Das verwaltende Objekt im Mud ist /secure/zweities
+
+Auf der Shell fragt man die DB recht simpel so ab:
+sqlite3 -column -header secure/ARCH/second.sqlite
+
+Alle Zweities von Arathorn ermitteln:
+select * from zweities where erstie='arathorn';
+
+Erstie von Ahab ermitteln:
+select erstie from zweities where name='ahab';
+
+Diese select-Anweisungen lassen sich (als EM) auch im Mud absetzen:
+xcall /secure/zweities->sql_query(
+    "select * from zweities where erstie='arathorn';")
+