Linedef types Python code

Below is a Python module for dealing with Doom linedef types. Provides functions to create a human-readable description code from a trigger number, and the inverse operation.

""" Guide to Trigger Description Codes (TM):

Example:   "FLOOR SR UP SLOW CRUSH LNC-8"

Categories: DOOR   - Doors (regular and locked) FLOOR  - Floor movers CEIL   - Ceiling movers PLAT   - Platforms and lifts CRUSHER - Crushers STAIR  - Stair builders ELEVATOR - Boom elevators LIGHT  - Light changers EXIT   - Exits TELEPORT - Teleports DONUT  - Donuts (lower pillar, raise surrounding sector) TRANSFER - Transfer properties (Boom) SCROLL  - Scroll lines and sectors (Boom)

Trigger types: P1 - Push(door) trigger, works once PR - Push(door) trigger, works repeatedly S1 - Switch, works once SR - Switch, works repeatedly W1 - Walk across, works once WR - Walk across, works repeatedly G1 - Shoot, works once GR - Shoot, works repeatedly

Door locks: YEL - Yellow key lock RED - Red key lock BLU - Blue key lock

Door types: OWC - Open, Wait, Close CWO - Close, Wait, Open OSO - Open, Stay Open CSC - Close, Stay Closed

Motion speed SLOW - Slow NORM - Normal FAST - Fast TURB - Turbo INST - Instant

Delay times 3SEC - 3 seconds 4SEC - 4 seconds 30SEC - 30 seconds

Sector property changers: CPYTEX     - Copy Texture CPYTEX+DELTYPE - Copy Texture, Reset type CPYTEX+TYPE  - Copy Texture and Type

Directions: DOWN - Down UP  - Up  NOMOVE - Stay (only change properties)

Miscellaneous: SECRET - A secret exit MONSTER - Monsters can activate the trigger LINE  - Line teleporters REVERSE - Line teleporter, reversed SILENT - Make crushers or teleporters silent CRUSH - Enable crushing (for CEILs and FLOORs,        not to be confused with CRUSHERs)

Destinations/platforms: LNF - Lowest Neighbor Floor LNC - Lowest Neighbor Ceiling HNF - Highest Neighbor Floor HNC - Highest Neighbor Ceiling NNF - Next Neighbor Floor NNC - Next Neighbor Ceiling HNF+8 - 8 above Highest neighbor Floor LNC+8 - 8 under Lowest neighbor Ceiling F+8 - 8 above floor 8  - 8 units Absolute (STAIRs only) 16 - 16 units Absolute (STAIRs only) 24 - 24 units Absolute 32 - 32 units Absolute 512 - 512 units absolute SLT - Shortest Lower Texture SUT - Shortest Upper Texture NLF - Next Lowest neighbor Floor NLC - Next Lowest neighbor Ceiling NHF - Next Highest neighbor Floor CURRF - Current Floor (ELEVATORs) FLR - Floor CL - Ceiling NAF - Next adjacent floor PERP - Perpetual STOP - Stop ongoing motion

Models: TRIG - Use trigger sector as model NUM - Lookup adjacent model numerically

Lighting: 35 - 35 units 255 - 255 units MAXN - Maximum Neighbor MINN - Minimum Neighbor BLINK - Blinking

Transfers (check boomref.txt for more info): FLIGHT   - Transfer floor light level CLIGHT   - Transfer ceiling light level TRANSLUCENCY - Transfer line translucency HEIGHTS  - The famous 242! FRICTION  - Transfer friction WIND    - Transfer current POINTFORCE - Transfer force point (?)

Scrollers (check boomref.txt for more info): CARRY   - Carry objects (conveyor) WRTSECTOR - With respect to 1st side's sector ACCEL   - Accelerate scrolling RIGHT   - Right direction LEFT   - Left direction WALL   - Scroll wall SYNCED  - Sync scrolling to sector OFFSETS  - Scroll by offsets """

from fnmatch import fnmatchcase

desc2num = \ { "": 0, "NO ACTION":0, "DOOR PR SLOW OWC 4SEC MONSTER":1, "DOOR PR FAST OWC 4SEC":117, "DOOR SR SLOW OWC 4SEC":63, "DOOR SR FAST OWC 4SEC":114, "DOOR S1 SLOW OWC 4SEC":29, "DOOR S1 FAST OWC 4SEC":111, "DOOR WR SLOW OWC 4SEC":90, "DOOR WR FAST OWC 4SEC":105, "DOOR W1 SLOW OWC 4SEC":4, "DOOR W1 FAST OWC 4SEC":108, "DOOR P1 SLOW OSO":31, "DOOR P1 FAST OSO":118, "DOOR SR SLOW OSO":61, "DOOR SR FAST OSO":114, "DOOR S1 SLOW OSO":103, "DOOR S1 FAST OSO":112, "DOOR WR SLOW OSO":86, "DOOR WR FAST OSO":106, "DOOR W1 SLOW OSO":2, "DOOR W1 FAST OSO":109, "DOOR GR FAST OSO":46, "DOOR SR SLOW CSC":42, "DOOR SR FAST CSC":116, "DOOR S1 SLOW CSC":50, "DOOR S1 FAST CSC":113, "DOOR WR SLOW CSC":75, "DOOR WR FAST CSC":107, "DOOR W1 SLOW CSC":3, "DOOR W1 FAST CSC":110, "DOOR SR SLOW CWO 30SEC":196, "DOOR S1 SLOW CWO 30SEC":175, "DOOR WR SLOW CWO 30SEC":76, "DOOR W1 SLOW CWO 30SEC":16, "DOOR PR SLOW OWC 4SEC BLU":26, "DOOR PR SLOW OWC 4SEC RED":28, "DOOR PR SLOW OWC 4SEC YEL":27, "DOOR P1 SLOW OSO BLU":32, "DOOR P1 SLOW OSO RED":33, "DOOR P1 SLOW OSO YEL":34, "DOOR SR FAST OSO BLU":99, "DOOR SR FAST OSO RED":134, "DOOR SR FAST OSO YEL":136, "DOOR S1 FAST OSO BLU":133, "DOOR S1 FAST OSO RED":135, "DOOR S1 FAST OSO YEL":137, "FLOOR SR DOWN SLOW LNF":60, "FLOOR S1 DOWN SLOW LNF":23, "FLOOR WR DOWN SLOW LNF":82, "FLOOR W1 DOWN SLOW LNF":38, "FLOOR SR DOWN SLOW LNF CPYTEX+TYPE NUM":177, "FLOOR S1 DOWN SLOW LNF CPYTEX+TYPE NUM":159, "FLOOR WR DOWN SLOW LNF CPYTEX+TYPE NUM":84, "FLOOR W1 DOWN SLOW LNF CPYTEX+TYPE NUM":37, "FLOOR SR UP SLOW NNF":69, "FLOOR S1 UP SLOW NNF":18, "FLOOR WR UP SLOW NNF":128, "FLOOR W1 UP SLOW NNF":119, "FLOOR SR UP FAST NNF":132, "FLOOR S1 UP FAST NNF":131, "FLOOR WR UP FAST NNF":129, "FLOOR W1 UP FAST NNF":130, "FLOOR SR DOWN SLOW NNF":222, "FLOOR S1 DOWN SLOW NNF":221, "FLOOR WR DOWN SLOW NNF":220, "FLOOR W1 DOWN SLOW NNF":219, "FLOOR SR UP SLOW LNC":64, "FLOOR S1 UP SLOW LNC":101, "FLOOR WR UP SLOW LNC":91, "FLOOR W1 UP SLOW LNC":5, "FLOOR G1 UP SLOW LNC":24, "FLOOR SR UP SLOW LNC-8 CRUSH":65, "FLOOR S1 UP SLOW LNC-8 CRUSH":55, "FLOOR WR UP SLOW LNC-8 CRUSH":94, "FLOOR W1 UP SLOW LNC-8 CRUSH":56, "FLOOR SR DOWN SLOW HNF":45, "FLOOR S1 DOWN SLOW HNF":102, "FLOOR WR DOWN SLOW HNF":83, "FLOOR W1 DOWN SLOW HNF":19, "FLOOR SR DOWN FAST HNF+8":70, "FLOOR S1 DOWN FAST HNF+8":71, "FLOOR WR DOWN FAST HNF+8":98, "FLOOR W1 DOWN FAST HNF+8":36, "FLOOR SR UP SLOW 24":180, "FLOOR S1 UP SLOW 24":161, "FLOOR WR UP SLOW 24":92, "FLOOR W1 UP SLOW 24":58, "FLOOR SR UP SLOW 24 CPYTEX+TYPE TRIG":179, "FLOOR S1 UP SLOW 24 CPYTEX+TYPE TRIG":160, "FLOOR WR UP SLOW 24 CPYTEX+TYPE TRIG":93, "FLOOR W1 UP SLOW 24 CPYTEX+TYPE TRIG":59, "FLOOR SR UP SLOW SLT":176, "FLOOR S1 UP SLOW SLT":158, "FLOOR WR UP SLOW SLT":96, "FLOOR W1 UP SLOW SLT":30, "FLOOR SR UP SLOW 512":178, "FLOOR S1 UP SLOW 512":140, "FLOOR WR UP SLOW 512":147, "FLOOR W1 UP SLOW 512":142, "FLOOR SR NOMOVE CPYTEX+TYPE SLT TRIG":190, "FLOOR S1 NOMOVE CPYTEX+TYPE SLT TRIG":189, "FLOOR WR NOMOVE CPYTEX+TYPE SLT TRIG":154, "FLOOR W1 NOMOVE CPYTEX+TYPE SLT TRIG":153, "FLOOR SR NOMOVE CPYTEX+TYPE SLT NUM":78, "FLOOR S1 NOMOVE CPYTEX+TYPE SLT NUM":241, "FLOOR WR NOMOVE CPYTEX+TYPE SLT NUM":240, "FLOOR W1 NOMOVE CPYTEX+TYPE SLT NUM":239, "CEIL SR DOWN FAST FLR":43, "CEIL S1 DOWN FAST FLR":41, "CEIL WR DOWN FAST FLR":152, "CEIL W1 DOWN FAST FLR":145, "CEIL SR UP SLOW HNC":186, "CEIL S1 UP SLOW HNC":166, "CEIL WR UP SLOW HNC":151, "CEIL W1 UP SLOW HNC":40, "CEIL SR DOWN SLOW F+8":187, "CEIL S1 DOWN SLOW F+8":167, "CEIL WR DOWN SLOW F+8":72, "CEIL W1 DOWN SLOW F+8":44, "CEIL SR DOWN SLOW LNC":205, "CEIL S1 DOWN SLOW LNC":203, "CEIL WR DOWN SLOW LNC":201, "CEIL W1 DOWN SLOW LNC":199, "CEIL SR DOWN SLOW HNF":205, "CEIL S1 DOWN SLOW HNF":204, "CEIL WR DOWN SLOW HNF":202, "CEIL W1 DOWN SLOW HNF":200, "PLAT SR SLOW CPYTEX TRIG 24":66, "PLAT S1 SLOW CPYTEX TRIG 24":15, "PLAT WR SLOW CPYTEX TRIG 24":148, "PLAT W1 SLOW CPYTEX TRIG 24":143, "PLAT SR SLOW CPYTEX TRIG 32":67, "PLAT S1 SLOW CPYTEX TRIG 32":14, "PLAT WR SLOW CPYTEX TRIG 32":149, "PLAT W1 SLOW CPYTEX TRIG 32":144, "PLAT SR SLOW CPYTEX+DELTYPE TRIG NAF":68, "PLAT S1 SLOW CPYTEX+DELTYPE TRIG NAF":20, "PLAT WR SLOW CPYTEX+DELTYPE TRIG NAF":95, "PLAT W1 SLOW CPYTEX+DELTYPE TRIG NAF":22, "PLAT G1 SLOW CPYTEX+DELTYPE TRIG NAF":47, "PLAT SR SLOW 3SEC PERP":181, "PLAT S1 SLOW 3SEC PERP":162, "PLAT WR SLOW 3SEC PERP":87, "PLAT W1 SLOW 3SEC PERP":53, "PLAT SR STOP":182, "PLAT S1 STOP":163, "PLAT WR STOP":89, "PLAT W1 STOP":54, "PLAT SR SLOW 3SEC LNF":62, "PLAT S1 SLOW 3SEC LNF":21, "PLAT WR SLOW 3SEC LNF":88, "PLAT W1 SLOW 3SEC LNF":10, "PLAT SR FAST 3SEC LNF":123, "PLAT S1 FAST 3SEC LNF":122, "PLAT WR FAST 3SEC LNF":120, "PLAT W1 FAST 3SEC LNF":121, "PLAT SR INST CL":211, "PLAT WR INST CL":212, "CRUSHER SR SLOW":184, "CRUSHER S1 SLOW":49, "CRUSHER WR SLOW":73, "CRUSHER W1 SLOW":25, "CRUSHER SR FAST":183, "CRUSHER S1 FAST":164, "CRUSHER WR FAST":77, "CRUSHER W1 FAST":6, "CRUSHER SR SLOW SILENT":185, "CRUSHER S1 SLOW SILENT":165, "CRUSHER WR SLOW SILENT":150, "CRUSHER W1 SLOW SILENT":141, "CRUSHER SR STOP":188, "CRUSHER S1 STOP":168, "CRUSHER WR STOP":74, "CRUSHER W1 STOP":57, "STAIR SR UP SLOW 8":258, "STAIR S1 UP SLOW 8":7, "STAIR WR UP SLOW 8":256, "STAIR W1 UP SLOW 8":8, "STAIR SR UP FAST 16":259, "STAIR S1 UP FAST 16":127, "STAIR WR UP FAST 16":257, "STAIR W1 UP FAST 16":100, "ELEVATOR SR FAST NHF":230, "ELEVATOR S1 FAST NHF":229, "ELEVATOR WR FAST NHF":228, "ELEVATOR W1 FAST NHF":227, "ELEVATOR SR FAST NHF":234, "ELEVATOR S1 FAST NLF":233, "ELEVATOR WR FAST NLF":232, "ELEVATOR W1 FAST NLF":231, "ELEVATOR SR FAST CURRF":238, "ELEVATOR S1 FAST CURRF":237, "ELEVATOR WR FAST CURRF":236, "ELEVATOR W1 FAST CURRF":235, "LIGHT SR 35":139, "LIGHT S1 35":170, "LIGHT WR 35":79, "LIGHT W1 35":35, "LIGHT SR 255":138, "LIGHT S1 255":171, "LIGHT WR 255":81, "LIGHT W1 255":13, "LIGHT SR MAXN":192, "LIGHT S1 MAXN":169, "LIGHT WR MAXN":80, "LIGHT W1 MAXN":12, "LIGHT SR MINN":194, "LIGHT S1 MINN":173, "LIGHT WR MINN":157, "LIGHT W1 MINN":104, "LIGHT SR BLINK":193, "LIGHT S1 BLINK":172, "LIGHT WR BLINK":156, "LIGHT W1 BLINK":17, "EXIT S1":11, "EXIT W1":52, "EXIT G1":197, "EXIT S1 SECRET":51, "EXIT W1 SECRET":124, "EXIT G1 SECRET":198, "TELEPORT SR":195, "TELEPORT S1":174, "TELEPORT WR":97, "TELEPORT W1":39, "TELEPORT WR MONSTER":126, "TELEPORT W1 MONSTER":125, "TELEPORT SR MONSTER":269, "TELEPORT S1 MONSTER":268, "TELEPORT SR SILENT":210, "TELEPORT S1 SILENT":209, "TELEPORT WR SILENT":208, "TELEPORT W1 SILENT":207, "TELEPORT WR SILENT LINE":244, "TELEPORT W1 SILENT LINE":243, "TELEPORT WR SILENT LINE REVERSE":263, "TELEPORT W1 SILENT LINE REVERSE":262, "TELEPORT WR SILENT LINE MONSTER":267, "TELEPORT W1 SILENT LINE MONSTER":266, "TELEPORT WR SILENT LINE REVERSE MONSTER":265, "TELEPORT W1 SILENT LINE REVERSE MONSTER":264, "DONUT SR":191, "DONUT S1":9, "DONUT WR":155, "DONUT W1":146, "TRANSFER FLIGHT":213, "TRANSFER CLIGHT":261, "TRANSFER TRANSLUCENCY":260, "TRANSFER HEIGHTS":242, "TRANSFER FRICTION":223, "TRANSFER WIND":224, "TRANSFER CURRENT":225, "TRANSFER POINTFORCE":226, "SCROLL CL":250, "SCROLL FLR":251, "SCROLL CARRY":252, "SCROLL FLR+CARRY":253, "SCROLL WALL SYNCED":254, "SCROLL WALL OFFSETS":255, "SCROLL WALL RIGHT":85, "SCROLL WALL LEFT":48, "SCROLL CL WRTSECTOR":245, "SCROLL FLR WRTSECTOR":246, "SCROLL CARRY WRTSECTOR":247, "SCROLL F+CARRY WRTSECTOR":248, "SCROLL WALL WRTSECTOR":249, "SCROLL CL ACCEL":214, "SCROLL FLR ACCEL":215, "SCROLL CARRY ACCEL":216, "SCROLL FLR+CARRY ACCEL":217, "SCROLL WALL ACCEL":218 }
 * 1) Define description codes for the standard triggers
 * 1) Doors
 * 1) Floors
 * 1) Ceilings
 * 1) Platforms and lifts
 * 1) Crushers
 * 1) Stairs
 * 1) Boom elevators
 * 1) Lighting
 * 1) Exits
 * 1) Teleports
 * 1) Donuts
 * 1) Boom property transfer
 * 1) Scrollers

num2desc = {} for desc, num in desc2num.items: num2desc[num] = desc

trigcompat = \ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]

def check_compat(num): """Check the compatibility for a trigger number""" if 8192 <= num < 32768: return "BOOM GENERALIZED" try: return ["UNKNOWN", "DOOM19", "BOOM EXTENDED"][trigcompat[num]] except: return "UNKNOWN"

def decode(n): """Generate a description code for a number.""" d = [] if n < 8192: if n in num2desc: return num2desc[n] return "UNKNOWN" # Boom generalized elif 0x2F80 <= n < 0x3000: n -= 0x2F80 d += ["CRUSHER"] d += [("W1","WR","S1","SR","G1","GR","P1","PR") [n&0x0007]] d += [("SLOW","NORMAL","FAST","TURBO")    [(n&0x0018)>>3]] d += [("MONSTER","")             [(n&0x0020)>>5]] d += [("SILENT","")              [(n&0x00c0)>>6]] elif 0x3000 <= n < 0x3400: n -= 0x3000 d += ["STAIR"] d += [("W1","WR","S1","SR","G1","GR","P1","PR") [n&0x0007]] d += [("SLOW","NORMAL","FAST","TURBO")    [(n&0x0018)>>3]] d += [("","MONSTER")             [(n&0x0020)>>5]] d += [("4","8","16","24")           [(n&0x00c0)>>6]] d += [("DOWN","UP")              [(n&0x0100)>>8]] d += [("", "IGNTXT")             [(n&0x0200)>>9]] elif 0x3400 <= n < 0x3800: n -= 0x3400 d += ["PLATFORM"] d += [("W1","WR","S1","SR","G1","GR","P1","PR") [n&0x0007]] d += [("SLOW","NORMAL","FAST","TURBO")    [(n&0x0018)>>3]] d += [("MONSTER","")             [(n&0x0020)>>5]] d += [("1","3","5","10")           [(n&0x00c0)>>6]] d += [("LNF","NNF","LNC","PERP")       [(n&0x0300)>>8]] elif 0x3800 <= n < 0x3c00: n -= 0x3800 d += ["DOOR"] d += [("W1","WR","S1","SR","G1","GR","P1","PR") [n&0x0007]] d += [("SLOW","NORMAL","FAST","TURBO")    [(n&0x0018)>>3]] d += [("OWC","OSO")              [(n&0x0020)>>5]] d += [("ANY","RED","YELLOW","BLUE","RED",       "BLUE","YELLOW","ALL")          [(n&0x01c0)>>6]] d += [("3KEYS","6KEYS")            [(n&0x0200)>>9]] elif 0x3c00 <= n < 0x4000: n -= 0x3c00 d += ["DOOR"] d += [("W1","WR","S1","SR","G1","GR","P1","PR") [n&0x0007]] d += [("SLOW","NORMAL","FAST","TURBO")    [(n&0x0018)>>3]] d += [("OWC","OSO","CWO","CSC")        [(n&0x0060)>>5]] d += [("MONSTER","")             [(n&0x0080)>>7]] d += [("1SECS","4SECS","9SECS","30SECS")   [(n&0x0300)>>8]] elif 0x4000 <= n < 0x6000: n -= 0x4000 d += ["CEIL"] d += [("W1","WR","S1","SR","G1","GR","P1","PR") [n&0x0007]] d += [("SLOW","NORMAL","FAST","TURBO")    [(n&0x0018)>>3]] d += [("TRIG","NUM")             [(n&0x0020)>>5]] d += [("DOWN","UP")              [(n&0x0040)>>6]] d += [("HNC","LNC","NNC","HNF","FLR",       "SUT","24","32")             [(n&0x0380)>>7]] d += [("","CPYTEX+DELTYPE","CPYTEX","CHGTYPE") [(n&0x0c00)>>10]] d += [("CRUSH","")              [(n&0x1000)>>12]] elif 0x6000 <= n < 0x8000: n -= 0x6000 d += ["FLOOR"] d += [("W1","WR","S1","SR","G1","GR","P1","PR") [n&0x0007]] d += [("SLOW","NORMAL","FAST","TURBO")    [(n&0x0018)>>3]] d += [("TRIG","NUM")             [(n&0x0020)>>5]] d += [("DOWN","UP")              [(n&0x0040)>>6]] d += [("HNF","LNF","NNF","LNC","CL",       "SLT","24","32")             [(n&0x0380)>>7]] d += [("","CPYTEX+DELTYPE","CPYTEX","CHGTYPE") [(n&0x0c00)>>10]] d += [("CRUSH","")              [(n&0x1000)>>12]] # Bit of a hack, but works return (" ".join(d)).replace(" "," ").rstrip(" ")

def encode_std(desc): """Encode an exact description of a trigger into its corresponding number. For inexact descriptions, use find_std.""" try: return desc2num[desc] except: raise Exception, "Description not recognized"

def encode_gen(desc): """Encode a generalized (Boom) trigger description to a trigger number. Invalid or incompatible terms get converted to the default  value.""" num = 0 def pk(seq, shift): for i in range(len(seq)): if seq[i] in desc: return i << shift return 0 num |= pk(("W1","WR","S1","SR","G1","GR","P1","PR"), 0) num |= pk(("SLOW","NORMAL","FAST","TURBO"), 3) if ("FLOOR" in desc) or ("CEIL" in desc): num |= pk(("TRIG","NUM"), 5) num |= pk(("DOWN","UP"), 6) num |= pk(("xx","CPYTEX+DELTYPE","CPYTEX","CHGTYPE"), 10) num |= pk(("CRUSH",), 12) if "FLOOR" in desc: num |= pk(("HNF","LNF","NNF","LNC","CL","SLT","24","32"), 7) num += 0x6000 else: num |= pk(("HNC","LNC","NNC","HNF","FLR","SUT","24","32"), 7) num += 0x4000 elif "CRUSHER" in desc: num |= pk(("MONSTER",), 5) num |= pk(("SILENT",), 6) num += 0x2F80 elif "STAIR" in desc: num |= pk(("xx","MONSTER"), 5) num |= pk(("4","8","16","24"), 6) num |= pk(("DOWN","UP"), 8) num |= pk(("xx","IGNTXT"), 9) num += 0x3000 elif "PLATFORM" in desc: num |= pk(("MONSTER",), 5) num |= pk(("1","3","5","10"), 6) num |= pk(("LNF","NNF","LNC","PERP"), 8) num += 0x3400 elif "DOOR" in desc: num |= pk(("SLOW","NORMAL","FAST","TURBO"), 3) if ("BLU" in desc) or ("YEL" in desc) or ("RED" in desc) or\ ("ALL" in desc) or ("ANY" in desc): num |= pk(("OWC","OSO"), 5) num |= pk(("ANY","RED","YELLOW","BLUE","RED","BLUE","YELLOW","ALL"), 6) num |= pk(("3KEYS","6KEYS"), 9) num += 0x3800 else: num |= pk(("OWC","OSO","CWO","CSC"), 5) num |= pk(("MONSTER",), 7) num |= pk(("1SECS","4SECS","9SECS","30SECS"), 8) num += 0x3c00 else: raise LookupError, "Insufficient information provided" return num

def find_std(desc): """Search the standard (non-generalized) triggers. A list of matches is returned. All terms must match. Wildcards are allowed.  Example:

find_std("CEIL UP S?")   should return:

['CEIL S1 UP SLOW HNC', 'CEIL SR UP SLOW HNC']""" terms = desc.split  matches = []  for dsc in num2desc.values:    d = dsc.split    matchedterms = 0    for term in terms:      for key in d:        if fnmatchcase(key, term):          matchedterms += 1    if matchedterms == len(terms):      matches.append(dsc)  return matches

__all__ = [find_std, encode_std, encode_gen, decode, check_compat]