This information is preliminary and may change at any time without notice.
language.rb contains the locale-specific formatting code.
language.rb must create a class called NHLanguage, which must inherit NHLangBase, and define entry points called as below. NHLanguage may define other methods or variables, but they must not begin with NH or nh to avoid conflicts with future releases.
:::ruby
class NHLanguage < NHLangBase
# nh_begin_format is called at the beginning of any formatting operation,
# so that language scripts that wish to maintain state may clear such state
# when a formatting operation begins.
#
# nh_begin_format may be omitted; the default action is to do nothing.
def nh_begin_format
# return value is ignored
end
# nh_format_parameter is called for any format specifier whose type
# specification is "s" or a string enclosed in curly braces.
#
# spec is nil if the type specification is "s", or a String if the type
# specification is a string enclosed in curly braces; it does not include
# the curly braces.
#
# arg is the parameter from the parameter list that the format specifier
# primarily refers to. Its type may be Integer, String, Array,
# NHGameState, NHMonster or NHObject.
#
# arglist is the list of all parameters including parameter 0. This is
# provided so that spec can reference more than one parameter: "%3${ng2}"
# might mean "parameter 3 is an adjective and needs to agree with the
# gender and number of parameter 2".
def nh_format_parameter(spec, arg, arglist)
# return value is a string to be substituted for a format specifier
end
# nh_join is called when a new string is to be joined to the existing
# output. Its purpose is to implement such rules as mandatory contractions
# and words (such as English "a"/"an") that change form according to what
# occurs before or after them.
#
# nh_join may be omitted; the default action is to return the concatenation
# of str1 and str2 without modification.
def nh_join(str1, str2)
# return value is a string resulting from the concatenation of str1 and
# str2, with any modifications according to the rules of the language
end
# nh_end_format is called at the end of a formatting operation. Its
# purpose is to give the language script a last pass at the final output
# of the formatting.
#
# nh_end_format may be omitted; the default action is to return str
# unchanged.
def nh_end_format(str)
# return value is str with any desired transformations; this will be
# the final formatting output
end
# nh_read_object is called when the user has made a wish. str is the
# user's input. This function should not attempt to enforce the rules
# limiting non-wizard-mode wishes; such limits remain in the C code.
def nh_read_object(str)
# return value is nil or an object of type NHWish
end
# nh_read_monster is called to read a monster type. str is the user's
# input. It is used for non-blessed genocide and in wizard mode to create
# monsters.
def nh_read_monster(str)
# return value is an object of type NHReadMonster
end
# nh_artifact_match matches the user-supplied name (name1) with the
# translated name of an artifact (name2). The match is case-insensitive if
# ignore_case is true.
#
# The match should take normalization forms into account.
#
# nh_artifact_match may be omitted; the default action is to compare name1
# and name2 in their entirety. This is provided so that language scripts
# can omit such things as articles from the match.
def nh_artifact_match(name1, name2, ignore_case)
# return value is true if the names match, else false
end
# nh_capitalize_words returns the string (str) with each word capitalized.
#
# nh_capitalize_words may be omitted; the default action is to capitalize
# each word according to default Unicode rules. Language scripts may
# override this if the language has special capitalization rules.
def nh_capitalize_words(str)
# return value is the capitalized string
end
# nh_data_match converts a string (str) to an Array of strings that may be
# matched to a pattern in the data file.
#
# nh_data_match may be omitted; the default value is to return str only,
# with whitespace reduced to single spaces, leading and trailing whitespace
# removed and the rest converted to normalization form C. Language scripts
# may use this to convert possible plurals to singulars or other such
# variant forms.
def nh_data_match(str)
# return value is an Array of strings to be matched against the data
# file
end
end
language.rb benefits from declarations in langbase.rb and nhconst.rb, and from declarations in pline2.c and uniruby.c, which provide services as described below.
The Unicode class provides a means of looking up various character properties, as defined by the Unicode standard:
:::ruby
class Unicode
def Unicode.cbyte?(num)
# true if num is a UTF-8 continuation byte
end
def Unicode.surrogate?(num)
# true if num is a UTF-16 surrogate
end
def Unicode.leading_surrogate?(num)
# true if num is a UTF-16 leading surrogate
end
def Unicode.trailing_surrogate?(num)
# true if num is a UTF-16 trailing surrogate
end
def Unicode.valid?(num)
# true if num is a valid Unicode code point and not a surrogate
end
def Unicode.combining_class(num)
# return value is an Integer, the canonical combining class of the code
# point num
end
def Unicode.ea_width(num)
# return value is a String, the East Asian width of the code point num
end
def Unicode.general_category(num)
# return value is a String, the general category of the code point num
end
def Unicode.composition(num1, num2)
# return value is an Integer, the code point that composes num1 and num2,
# or nil if there is no composition
end
def Unicode.decomposition(num, compat)
# return value is a String in the UTF-8 encoding, the decomposition of
# the code point num; this is a compatibility decomposition if compat is
# true, or a canonical decomposition if false
end
def Unicode.decimal_value(num)
# return value is an Integer, the decimal value of the code point num, or
# nil if it has no decimal value
end
def Unicode.downcase(num)
# return value is a String in the UTF-8 encoding, the lowercase mapping of
# the code point num.
end
def Unicode.capitalize(num)
# return value is a String in the UTF-8 encoding, the titlecase mapping of
# the code point num.
end
def Unicode.upcase(num)
# return value is a String in the UTF-8 encoding, the uppercase mapping of
# the code point num.
end
def Unicode.casefold(num)
# return value is a String in the UTF-8 encoding, the casefold mapping of
# the code point num; this is different from downcase
end
def Unicode.width(num)
# return value is an Integer, an approximation of the width of the code
# point num as displayed on a terminal window; this may be 0, 1 or 2
end
end
The built-in String class is augmented for better Unicode support.
The case mappings implemented here are the defaults, with one-to-many mappings such as ß to SS fully supported. Final lowercase sigma is taken into account. Some languages have special capitalization rules; two examples are Turkish i -> İ and ı -> I, and the Dutch IJ digraph. For such languages, language.rb will need to take these rules into account.
downcase!, upcase! and capitalize! are not redefined, and no casefold! or normalize! methods are provided. These may be provided in a future release.
:::ruby
class String
def downcase
# return value is a String, the original string in lowercase
end
def capitalize
# return value is a String: the first character is titlecased and the
# rest is converted to lowercase
end
def upcase
# return value is a String, the original string in uppercase
end
def casefold
# return value is a String, the original string casefolded
# note that this is not the same as downcase
end
def normalize(form)
# form is a String: "NFC", "NFD", "NFKC" or "NFKD"
# return value is a String, the original string normalized
end
def width
# return value is an Integer, the approximate width of the string on a
# terminal
end
end
The built-in Array class is augmented so that to_i returns the number of elements; this will facilitate its use for forming plurals.
The NHLangBase class provides constants corresponding to those defined in pm.h and oname.h (generated by makedefs); these have the form NH_ plus the name in C, so that NHLangBase::NH_PM_BLACK_DRAGON has the same value as PM_BLACK_DRAGON in C.
The NHLangBase class also provides these methods:
:::ruby
class NHLangBase
def NHLangBase.nh_split_words(str1, str2)
# return value is an array of five strings:
# prefix, word1, infix, word2, suffix
# prefix is the part of str1 before the last word.
# word1 is the last word in str1.
# infix is the part of str1 after the last word, plus the part of str2
# before the first word.
# word2 is the first word in str2.
# suffix is the part of str2 after the first word.
end
def nh_obj_called(num)
# return value is a String, the user-provided name by which object num is
# called, or nil if no such name is defined
end
def nh_obj_name(num)
# return value is a String, the translated real name of object num, or
# nil if num is out of range
end
def nh_obj_descr(num)
# return value is a String, the translated unidentified description of
# object num, or nil if no such description
end
def nh_obj_class(oclass)
# oclass is a String with one character, the map symbol for an object
# class, or nil
# return value is a Range, giving the first and last indexes of the
# requested class, or 1...NUM_OBJECTS (all objects) if oclass is nil
end
def nh_mon_name(num)
# return value is a String, the translated name of monster num, or nil if
# num is out of range
end
def nh_title_to_mon(title)
# return value is a two-element Array, containing the translated monster
# name corresponding to the title and the name's length, or [nil, nil] if
# no such monster
end
def nh_Japanese_items
# return value is an Enumerable of two-element Arrays, each bearing a
# Japanese item name (a String) and its object index (an Integer)
end
def nh_fruits
# return value is an Enumerable of two-element Arrays, each bearing a
# fruit name (a String) and its fruit ID number (an Integer)
end
def nh_artifact_name(name)
# return value is an Array of two elements, the full name of an artifact
# and its object index, or [nil, nil]
end
end
The second parameter of nh_format_parameter may be any of Integer, String, Array, NHGameState, NHMonster or NHObject; any Array will contain only these six types (presently an Array contains only String or NHMonster). The third parameter of nh_format_parameter is an Array containing any of these six types. NHGameState occurs in element 0 and no other, and the rest contain the explicit parameters to the format function in the order that they were specified.
NHGameState presents this interface; the read-only attributes are set in the function game_state in src/pline2.c. The language script may add more methods or variables, but they must not begin with nh or NH to avoid conflict with future releases.
:::ruby
class NHGameState
attr_reader :nh_gameover # True if game has ended
attr_reader :nh_hallu # True if hallucinating
attr_reader :nh_uswallow # True if swallowed
attr_reader :nh_blind # True if blind
attr_reader :nh_in_endgame # True if in endgame
attr_reader :nh_poly_gender # 0 if the hero is male, 1 if female, 2 if neuter
attr_reader :nh_female # True if the hero is female
attr_reader :nh_humanoid # True if the hero is humanoid in form
attr_reader :nh_neuter # True if the hero is neuter
attr_reader :nh_role_en # Untranslated male name of role
attr_reader :nh_hand # Translated string for the hand of the hero's
# current form
attr_reader :nh_mrg_to_wielded # True if weapon picked is merged with wielded
# one
attr_reader :nh_twoweap # True if wielding two weapons
# For the benefit of pluralization routines
def to_i
1
end
end
NHMonster presents this interface; the read-only attributes are set in the function P_m in src/pline2.c. The language script may add more methods or variables, but they must not begin with nh or NH to avoid conflict with future releases.
:::ruby
class NHMonster
attr_reader :nh_name # Personal name of monster (empty if none)
attr_reader :nh_mtame # True if monster is tame
attr_reader :nh_minvis # True if monster is invisible
attr_reader :nh_canspotmon # True if monster can be seen
attr_reader :nh_usteed # True if monster is being ridden
attr_reader :nh_ustuck # True if monster is holding you
attr_reader :nh_ispriest # True if monster is a priest
attr_reader :nh_isminion # True if monster is a minion
attr_reader :nh_mname_en # Untranslated description of monster from monst.c
attr_reader :nh_hname # Random monster name if hallucinating, else same
# as mname
attr_reader :nh_mname # Translated description of monster from monst.c
attr_reader :nh_renegade # True if monster is renegade
attr_reader :nh_female # True if monster is female
attr_reader :nh_humanoid # True if monster is humanoid in form
attr_reader :nh_neuter # True if monster is neuter
attr_reader :nh_hgname # Random god name if hallucinating, else same as
# gname
attr_reader :nh_gname # Name of monster's actual god
attr_reader :nh_isshk # True if monster is a shopkeeper
attr_reader :nh_saddle # True if monster is wearing a saddle
attr_reader :nh_pname # True if monster's name is a proper name
attr_reader :nh_mplayer # True if monster is a player-monster
attr_reader :nh_rank # Rank of monster if a player-monster, else empty
attr_reader :nh_unique # True if monster is unique
attr_reader :nh_pgender # 0 for male, 1 for female, 2 for neuter
attr_reader :nh_no_priest_name # True if allegiance of high priest should be
# concealed
# For the benefit of pluralization routines
def to_i
1
end
end
NHObject presents this interface; the read-only attributes are set in the functions P_oq and P_ot in src/pline2.c. The language script may add more methods or variables, but they must not begin with nh or NH to avoid conflict with future releases.
:::ruby
class NHObject
attr_reader :nh_quan # Number of items in this stack
attr_reader :nh_otyp # untranslated object name
attr_reader :nh_oc_name_known # true if user knows the real name
attr_reader :nh_actualn # translated object name
attr_reader :nh_dn # translated object description
attr_reader :nh_oc_uname # name assigned by user
attr_reader :nh_jap_name # Japanese item name
attr_reader :nh_pname # true if object name is a proper name
attr_reader :nh_oname # name of individual object
attr_reader :nh_oclass # on-screen symbol for object class
attr_reader :nh_dknown # true if description known
attr_reader :nh_known # true if identified
attr_reader :nh_opoisoned # true if poisoned
attr_reader :nh_mname # translated name of associated monster
attr_reader :nh_vegetarian # true if the object is vegetarian
attr_reader :nh_m_pname # true if the associated monster has a proper
# name
attr_reader :nh_m_unique # true if the associated monster is unique
attr_reader :nh_knows_egg # true if the hero knows this type of egg
attr_reader :nh_boots # true if the object is a pair of boots
attr_reader :nh_gloves # true if the object is a pair of gloves
attr_reader :nh_cloak # true if the object is a cloak
attr_reader :nh_helmet # true if the object is a helmet
attr_reader :nh_shield # true if the object is a shield
attr_reader :nh_suit # true if the object is a suit of armor
attr_reader :nh_fname # name of object if it is a fruit, or nil
attr_reader :nh_spe # "special" number for object
attr_reader :nh_historic # true if the object is a historic statue
attr_reader :nh_owt # actual weight of object
attr_reader :nh_oc_weight # weight according to object class
attr_reader :nh_odiluted # true if the object is a diluted potion
attr_reader :nh_bknown # true if the b/u/c status is known
attr_reader :nh_rknown # true if the object is known to be rustproof
# etc.
attr_reader :nh_oerodeproof # true if the object is rustproof etc.
attr_reader :nh_blessed # true if the object is blessed
attr_reader :nh_cursed # true if the object is cursed
attr_reader :nh_oc_magic # true if the object is a magical item
attr_reader :nh_costly # true if the object belongs to a shopkeeper
attr_reader :nh_shopkeeper # shopkeeper claiming this object, or nil
attr_reader :nh_ocarry # monster (NHMonster) carrying this object, or
# nil
attr_reader :nh_carried # true if hero is carrying the object
attr_reader :nh_oinvis # true if the object is invisible
attr_reader :nh_oc_charged # true if the object is chargeable
attr_reader :nh_greased # true if the object is greased
attr_reader :nh_w_armor # true if the object is worn as armor
attr_reader :nh_w_wep # true if the object is the wielded weapon
attr_reader :nh_w_quiver # true if the object is in the quiver
attr_reader :nh_w_swapwep # true if the object is the secondary weapon
attr_reader :nh_w_amul # true if the object is worn as an amulet
attr_reader :nh_w_ringl # true if the object is the left ring
attr_reader :nh_w_ringr # true if the object is the right ring
attr_reader :nh_w_tool # true if the object is worn as eyewear
attr_reader :nh_w_saddle # true if the object is a worn saddle
attr_reader :nh_w_ball # true if the object is a punishment ball
attr_reader :nh_w_chain # true if the object is a punishment chain
attr_reader :nh_fixed # true if the object is a fixed crysknife
attr_reader :nh_oeroded # degree of rust or fire damage
attr_reader :nh_oeroded2 # degree of corrosion or rotting damage
attr_reader :nh_rustprone # true if the object can be rusted
attr_reader :nh_flammable # true if the object can be burnt
attr_reader :nh_corrodeable # true if the object can be corroded
attr_reader :nh_rottable # true if the object can be rottd
attr_reader :nh_unpaid # true if the object is unpaid
attr_reader :nh_quotedprice # quoted price of the object
attr_reader :nh_age # obj->age; for candles, this is how long it
# will burn
attr_reader :nh_bimanual # true if the object is a two-handed weapon
attr_reader :nh_lamplit # true if the object is lit
attr_reader :nh_leashmon # monster ID of attached pet, or nil
attr_reader :nh_oc_cost # base cost of object
attr_reader :nh_oeaten # nutrition left in food, if partly eaten, or
# nil
attr_reader :nh_recharged # number of times the object has been recharged
attr_reader :nh_stale_egg # true if the object is a stale egg
attr_reader :nh_uskin # true if the object is armor embedded in your
# skin
attr_reader :nh_weptool # true if the object is a weapon-tool
attr_reader :nh_oc_unique # true if the object is unique
# For the benefit of pluralization routines
def to_i
@nh_quan
end
def nh_w_ring
@nh_w_ringl || @nh_w_ringr
end
end
The method nh_read_monster returns an object of class NHReadMonster, which presents the following interface. The language script may add more methods or variables, but they must not begin with nh or NH to avoid conflict with future releases.
:::ruby
# Class returning the monster that the user typed in
class NHReadMonster
attr_accessor :nh_name # string
attr_accessor :nh_tame # Boolean
attr_accessor :nh_peaceful # Boolean
attr_accessor :nh_hostile # Boolean
end
The method nh_read_object returns an object of class NHWish (or nil), which presents the following interface. The language script may add more methods or variables, but they must not begin with nh or NH to avoid conflict with future releases.
~~~~~~
:::ruby
class NHWish
attr_accessor :nh_cnt # integer
attr_accessor :nh_spe # integer
attr_accessor :nh_spesgn # -1, 0, +1
attr_accessor :nh_typ # integer giving object type or range of
# object types
attr_accessor :nh_very # integer: 0, 1 (very), 2 (thoroughly)
attr_accessor :nh_rechrg # integer
attr_accessor :nh_blessed # Boolean
attr_accessor :nh_uncursed # Boolean
attr_accessor :nh_iscursed # Boolean
attr_accessor :nh_ispoisoned # Boolean
attr_accessor :nh_isgreased # Boolean
attr_accessor :nh_eroded # integer
attr_accessor :nh_eroded2 # integer
attr_accessor :nh_erodeproof # Boolean
attr_accessor :nh_isinvisible # Boolean
attr_accessor :nh_halfeaten # Boolean
attr_accessor :nh_mntmp # integer giving monster, or nil
attr_accessor :nh_contents # nil, :empty, :spinach
attr_accessor :nh_islit # Boolean
attr_accessor :nh_ishistoric # Boolean
attr_accessor :nh_isdiluted # Boolean
attr_accessor :nh_ftype # integer giving fruit type, or 0
attr_accessor :nh_oclass # string giving object class, or nil
attr_accessor :nh_name # string giving name, or nil
end
Wiki: Information for Developers
Wiki: messages.po
Wiki: quest.txt