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¶meter");
+ (3) AddCmd(({"test"}),1);
+ (4) AddCmd("test",0,0,"XYZ");
+ (5) AddCmd("test&mit¶meter",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¶meter"
+ RemoveCmd("test|teste&mit¶meter"
+ - 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';")
+