Browse Source

Map Door Text parser, beta mission timers

pull/2/head
Brandon Cornejo 6 years ago
parent
commit
6084cd474a
  1. 2
      .gitignore
  2. 7
      commands.txt
  3. 4
      config.tin
  4. 9
      mdt
  5. 55
      mdtconfig.json
  6. 15
      src/actions.tin
  7. 1
      src/aliases.tin
  8. 4
      src/combat.tin
  9. 16
      src/deadletter.tin
  10. 16
      src/gmcp.tin
  11. 332
      src/mdtparse.py
  12. 24
      src/missiontimers.tin
  13. 116
      src/missiontimers/letters.tin
  14. 56
      src/missiontimers/sausage_lite.tin
  15. 79
      src/missiontimers/sausages.tin
  16. 0
      src/spottimers.tin
  17. 7
      src/tpamonitor.tin

2
.gitignore

@ -0,0 +1,2 @@
logs/*.log
logs/active/*.log

7
commands.txt

@ -0,0 +1,7 @@
minimap:
clear && watch -c -n 0.25 -t 'clear && cat logs/minimap.log'
timers:
clear && watch -t -n 5 cat xptimers.log

4
config.tin

@ -18,13 +18,15 @@
#READ {src/prompt.tin}; #READ {src/prompt.tin};
#READ {src/xpmonitor.tin}; #READ {src/xpmonitor.tin};
#READ {src/tpamonitor.tin}; #READ {src/tpamonitor.tin};
#READ {src/timers.tin};
#READ {src/spottimers.tin};
#READ {src/combat.tin}; #READ {src/combat.tin};
#READ {src/deadletter.tin}; #READ {src/deadletter.tin};
#READ {src/quow.tin}; #READ {src/quow.tin};
#READ {src/magic.tin}; #READ {src/magic.tin};
#READ {src/missiontimers.tin};
#SESSION {discworld} {discworld.starturtle.net} {4242}; #SESSION {discworld} {discworld.starturtle.net} {4242};
#FORMAT {log_file} {logs/active/%t.log} {%Y-%m-%d}; #FORMAT {log_file} {logs/active/%t.log} {%Y-%m-%d};

9
mdt

@ -0,0 +1,9 @@
#!/bin/sh
# clear && watch --color -t -n 0.4 'python src/mdtparse.py logs/mapdoortext.log | tail -n `tput lines`'
clear && while true; do
output=$(python src/mdtparse.py logs/mapdoortext.log | tail -n `tput lines`);
clear;
echo "$output";
sleep 0.3;
done

55
mdtconfig.json

@ -0,0 +1,55 @@
{
"default_npc_value": 1,
"bonus_player_value": -1,
"minimum_room_value": 1,
"show_hidden_room_count": false,
"custom_matches": [
["string/regex, colour, point, is_regex"],
["zero out these entries so they do not weigh room values"],
[".*rats{0,1}$", "", 0, true],
[".*cats{0,1}$", "", 0, true],
[".*dogs{0,1}$", "", 0, true],
[".*pigeons{0,1}$", "", 0, true],
["skeleton warrior", "", 0, false],
[" truffle pig", "", 0, false],
["giant fruitbat", "", 0, false],
["fireflies", "", 0, false],
["small blue light", "", 0, false],
[" cloud", "", 0, false],
["tortoise", "", 0, false],
["cockroach", "", 0, false],
["Bes Pelargic Highlights"],
["student", "", 3, false],
["imperial guard", "orange", 5, false],
["^(.+?) (tang|sung|mcsweeney|fang|hong) bodyguards{0,1}$", "orange", 4, true],
["^(.+?) (tang|sung|mcsweeney|fang|hong) noblem(en|an)$", "orange", 3, true],
["^(.+?) (tang|sung|mcsweeney|fang|hong) captain$", "orange", 3, true],
["Djelibeybi Highlights"],
["^(.+?) pries(t|ts|tess|tesses)$", "", 0, true],
["ceremonial guard", "orange", 5, false],
["palace guard", "orange", 2, false],
["soldier", "", 2, false],
["recruit", "", 2, false],
["d'reg", "", 2, false],
["Ephebe Highlights"],
["hoplite", "orange", 4, false],
["citadel guard", "orange", 4, false],
["philosopher", "", 2, false],
["lad(y|ies)", "", 2, true],
["Sto Plains Highlights"],
["knight", "orange", 4, false],
["little old ladies", "orange", 2, false],
["hunter grflx", "", 3, false],
["grflx mentor", "", 3, false],
["grflx adolescent", "", 2, false],
["grflx worker", "", 3, false],
["grflx workleader", "", 3, false],
["Valid colours: orange, "]
]
}

15
src/actions.tin

@ -28,6 +28,21 @@
#NOP ==[Command Color Highlighting]== #NOP ==[Command Color Highlighting]==
#SUB {%w %w with a total of %* item} {<148>%1 %2<099> with a total of <148>%3<099> item} #SUB {%w %w with a total of %* item} {<148>%1 %2<099> with a total of <148>%3<099> item}
#NOP ==[Truffle Found]==
#HIGHLIGHT {The young truffle pig unearths a truffle from the ground.} {bold green};
#NOP ==[Attention Soul(s)]==
#ACTION {^{(?!Ryattenoki).+} tugs on your sleeve in a desperate attempt to get some attention.$} {
#showme {\a};
};
#NOP ==[Copperhead Mines]==
#HIGHLIGHT {Something doesn't smell right. You take a sniff but the faint odour of rotten eggs makes you cough.} {bold green underscore};
#ACTION {Something doesn't smell right. You take a sniff but the faint odour of rotten eggs makes you cough.} {
#showme {\a};
};
#NOP ==[End Session On Quit]==
#ACTION {Thanks for playing. See you next time.} { #ACTION {Thanks for playing. See you next time.} {
#end; #end;
} }

1
src/aliases.tin

@ -1,4 +1,5 @@
#ALIAS {setsize} {rows 300;cols 110}; #ALIAS {setsize} {rows 300;cols 110};
#ALIAS {setmsize} {rows 300;cols 60};
#ALIAS {^clear$} { #ALIAS {^clear$} {
#system {tput clear}; #system {tput clear};

4
src/combat.tin

@ -8,7 +8,8 @@
#HIGHLIGHT {^You {viciously |messily |barely |neatly |}{thrust|snick|fillet|poke|chop up|chop|jab|scratch|boot|kick|hit|tickle|hack|prick|shred|nick|cut|stab|perforate|pierce|impale|slice|skewer|take} {a sliver off |into |}%1{'?s?} %2 {on|with} %3} {$my_attacks_color}; #HIGHLIGHT {^You {viciously |messily |barely |neatly |}{thrust|snick|fillet|poke|chop up|chop|jab|scratch|boot|kick|hit|tickle|hack|prick|shred|nick|cut|stab|perforate|pierce|impale|slice|skewer|take} {a sliver off |into |}%1{'?s?} %2 {on|with} %3} {$my_attacks_color};
#HIGHLIGHT {^You {viciously |messily |barely |neatly |}stab %1 {deeply |}in %2 with %3} {$my_attacks_color}; #HIGHLIGHT {^You {viciously |messily |barely |neatly |}stab %1 {deeply |}in %2 with %3} {$my_attacks_color};
#HIGHLIGHT {^You stab %1 right through %2's %3} {$my_attacks_color}; #HIGHLIGHT {^You stab %1 right through %2's %3} {$my_attacks_color};
#HIGHLIGHT {^You {viciously |messily |barely |neatly |}{poke|kick|punch|jab|boot|tickle} %1 in %2} {$my_attacks_color};
#HIGHLIGHT {^You {viciously |messily |barely |neatly |}{poke|kick|punch|jab|boot|tickle|kick out} %1 in %2} {$my_attacks_color};
#HIGHLIGHT {^You {punch|kick out} at %1 but {his|her} %2 absorbs {some|most} of the blow\.$} {$my_attacks_color};
#NOP ==[My Specials]== #NOP ==[My Specials]==
@ -16,6 +17,7 @@
#HIGHLIGHT {^You prepare to {stab|slice|trip|shove|impale|kick|punch} %2} {bold green}; #HIGHLIGHT {^You prepare to {stab|slice|trip|shove|impale|kick|punch} %2} {bold green};
#HIGHLIGHT {^You attempt to launch a powerful attack. %1} {bold red}; #HIGHLIGHT {^You attempt to launch a powerful attack. %1} {bold red};
#HIGHLIGHT {^You launch a powerful attack. %1} {bold green}; #HIGHLIGHT {^You launch a powerful attack. %1} {bold green};
#HIGHLIGHT {^You launch a powerful attack, landing a %1} {bold green};
#HIGHLIGHT {^You try to {trip|shove} %1} {bold red}; #HIGHLIGHT {^You try to {trip|shove} %1} {bold red};
#HIGHLIGHT {^You shove %1} {bold green}; #HIGHLIGHT {^You shove %1} {bold green};
#HIGHLIGHT {^You trip %1} {bold green}; #HIGHLIGHT {^You trip %1} {bold green};

16
src/deadletter.tin

@ -1,6 +1,15 @@
#CLASS {deadletter} {kill}; #CLASS {deadletter} {kill};
#CLASS {deadletter} {open}; #CLASS {deadletter} {open};
#VAR {difficult_customer_targets} {
{Triad Boss}{Triad [Boss]}
{Queen Shelox}{Queen Shelox}
{Ice Giants}{Ice Giants}
{Security guards}{Security Guards}
{Smuggler Captain}{Smuggler Captain}
{The Clown}{Ha'pennywise the Clown}
};
#VAR {distant_land_targets} { #VAR {distant_land_targets} {
{Boy Willie}{Boy [Willie]} {Boy Willie}{Boy [Willie]}
{Disembowel-Meself-Honourably Dibhala}{Disembowel-Meself-Honourably [Dibhala]} {Disembowel-Meself-Honourably Dibhala}{Disembowel-Meself-Honourably [Dibhala]}
@ -41,6 +50,13 @@
}; };
} }
#foreach {$difficult_customer_targets[]} {target} {
#regex {$target} {$current_match_line} {
#format {letter_solution_line} {%c[DC] %c*%c Deliver to %c%s%c.} {bold blue} {bold yellow} {bold blue} {bold green} {$difficult_customer_targets[$target]} {bold blue};
#echo {$letter_solution_line};
};
}
}; };
}; };

16
src/gmcp.tin

@ -27,7 +27,7 @@
#VAR GMCP[vitals] {%0}; #VAR GMCP[vitals] {%0};
#math {hploss} {$GMCP[vitals][hp] - $GMCP[oldvitals][hp]}; #math {hploss} {$GMCP[vitals][hp] - $GMCP[oldvitals][hp]};
#if {$hploss < -100} {
#if {$hploss < -150} {
#echo {<139>HP IS FALLING! CAREFUL!<099>}; #echo {<139>HP IS FALLING! CAREFUL!<099>};
#showme {\a\a}; #showme {\a\a};
} }
@ -35,6 +35,12 @@
update_prompt; update_prompt;
} }
#EVENT {IAC SB GMCP char.info IAC SE}
{
#IF {$debug} { #SHOWME %1 };
#VAR GMCP[charinfo] {%0};
}
#EVENT {IAC SB GMCP room.info IAC SE} #EVENT {IAC SB GMCP room.info IAC SE}
{ {
#IF {$debug} { #SHOWME %1 }; #IF {$debug} { #SHOWME %1 };
@ -49,7 +55,7 @@
#REPLACE {minimap} {u001b} {}; #REPLACE {minimap} {u001b} {};
#SYSTEM {rm logs/minimap.log && touch logs/minimap.log}; #SYSTEM {rm logs/minimap.log && touch logs/minimap.log};
#LINE {log} {logs/minimap.log} {\n\n $minimap \n\n};
#LINE {log} {logs/minimap.log} {\n\n$minimap};
#SYSTEM {sed -i -e 's/^/ /' logs/minimap.log}; #SYSTEM {sed -i -e 's/^/ /' logs/minimap.log};
} }
@ -57,7 +63,9 @@
{ {
#IF {$debug} { #SHOWME %1 }; #IF {$debug} { #SHOWME %1 };
#VAR GMCP[room][mdt] {%0}; #VAR GMCP[room][mdt] {%0};
#LINE {log} {logs/mapdoortext.log} {\n\n\n %0};
#REPLACE {GMCP[room][mdt]} {\\n} {};
#SYSTEM {rm logs/mapdoortext.log && touch logs/mapdoortext.log};
#LINE {log} {logs/mapdoortext.log} {$GMCP[room][mdt]};
} }
#EVENT {IAC WILL GMCP} #EVENT {IAC WILL GMCP}
@ -66,7 +74,7 @@
#SEND {$IAC$DO$GMCP\}; #SEND {$IAC$DO$GMCP\};
#nop #SEND {$IAC$SB$GMCP Core.Hello { "client": "$CLIENT_NAME", "version": "$CLIENT_VERSION" } $IAC$SE\}; #nop #SEND {$IAC$SB$GMCP Core.Hello { "client": "$CLIENT_NAME", "version": "$CLIENT_VERSION" } $IAC$SE\};
#SEND {$IAC$SB$GMCP Core.Hello { "client": "TinTin++", "version": "2.01.2" } $IAC$SE\}; #SEND {$IAC$SB$GMCP Core.Hello { "client": "TinTin++", "version": "2.01.2" } $IAC$SE\};
#SEND {$IAC$SB$GMCP Core.Supports.Set ["Char.Vitals", "room.info", "room.map", "room.writtenmap"] $IAC$SE\}
#SEND {$IAC$SB$GMCP Core.Supports.Set ["Char.Vitals", "room.info", "room.map", "room.writtenmap", "char.info"] $IAC$SE\}
} }
#EVENT {PROGRAM START} #EVENT {PROGRAM START}

332
src/mdtparse.py

@ -0,0 +1,332 @@
#!/usr/bin/env python
import os
import re
import sys
import math
import json
class MapDoorText:
number_map = {
"a ": 1,
"an ": 1,
"the ": 1,
"one ": 1,
"two ": 2,
"three ": 3,
"four ": 4,
"five ": 5,
"six ": 6,
"seven ": 7,
"eight ": 8,
"nine ": 9,
"ten ": 10,
"eleven ": 11,
"twelve ": 12,
"thirteen ": 13,
"fourteen ": 14,
"fifteen ": 15,
"sixteen ": 16,
"seventeen ": 17,
"eighteen ": 18,
"nineteen ": 19,
"twenty ": 20,
"twenty-one ": 21,
"twenty-two ": 22,
"twenty-three ": 23,
"twenty-four ": 24,
"twenty-five ": 25,
"twenty-six ": 26,
"twenty-seven ": 27,
"twenty-eight ": 28,
"twenty-nine ": 29,
"thirty ": 30,
}
direction_map = {
"north": "n",
"northeast": "ne",
"east": "e",
"southeast": "se",
"south": "s",
"southwest": "sw",
"west": "w",
"northwest": "nw",
"n": "n",
"ne": "ne",
"e": "e",
"se": "se",
"s": "s",
"sw": "sw",
"w": "w",
"nw": "nw",
}
colour_map = {
# http://terminal-color-builder.mudasobwa.ru/
"orange": "\033[01;38;05;214m",
"reset": "\033[00;39;49m"
}
def __init__(self):
self.return_value = []
self.custom_matches = []
# Load the JSON configuration file
with open('mdtconfig.json', 'r') as config_file:
config = json.load(config_file)
# Strip comments from custom matches
for match in config['custom_matches']:
if len(match) > 1:
self.custom_matches.append(match)
self.default_npc_value = config['default_npc_value']
self.bonus_player_value = config['bonus_player_value']
self.minimum_room_value = config['minimum_room_value']
self.show_hidden_room_count = config['show_hidden_room_count']
@staticmethod
def explode(div, mdt):
if div == '':
return False
pos, fragments = 0, []
for m in re.finditer(div, mdt):
fragments.append(mdt[pos:m.start()])
pos = m.end()
fragments.append(mdt[pos:])
return fragments
def parse_mdt(self, mdt_line):
# Make lower case, do initial replacements
mdt_line = mdt_line.lower()
mdt_line = mdt_line.replace(" are ", " is ")
mdt_line = mdt_line.replace(" black and white ", " black white ")
mdt_line = mdt_line.replace(" brown and white ", " brown white ")
mdt_line = mdt_line.replace("the limit of your vision is ", "the limit of your vision:")
mdt_line = mdt_line.replace(" and ", ", ")
mdt_line = mdt_line.replace(" is ", ", ")
mdt_table = self.explode(', ', mdt_line)
data = {
'last_direction': '',
'last_enemy_line': '',
'last_count': 0,
'last_was_dir': 0,
'enemies_by_square': [],
'ignoring_exits': False,
'entity_table': [],
'room_id': 1,
'room_value': 0,
'longest_direction': 0,
'nothing': True,
'next_color': ''
}
exit_strings = ['doors ', 'a door ', 'exits ', 'an exit ', 'a hard to see through exit ']
for entry in mdt_table:
if entry != "" and ' of a ' not in entry:
if entry.startswith(tuple(exit_strings)):
# print('Special exit, ignore this line? next line is processed...')
data['ignoring_exits'] = True
elif entry.startswith('the limit of your vision:'):
if data['last_count'] > 0:
this_square = [data['last_count'], data['last_direction'], data['room_id'], int(math.floor(data['room_value']))]
data['enemies_by_square'].append(this_square)
data['nothing'] = False
data['next_color'] = ''
data['room_id'] = data['room_id'] + 1
data['room_value'] = 0
data['last_direction'] = ''
data['last_enemy_line'] = ''
data['last_count'] = 0
data['last_was_dir'] = 0
else:
# find the quantity first
quantity = 1
for nm_key in self.number_map:
if entry.startswith(nm_key):
quantity = self.number_map[nm_key]
entry = entry[len(nm_key):]
break
is_direction = 0
this_direction = ''
if entry.startswith("northeast"):
is_direction = 1
this_direction = "northeast"
elif entry.startswith("northwest"):
is_direction = 1
this_direction = "northwest"
elif entry.startswith("southeast"):
is_direction = 1
this_direction = "southeast"
elif entry.startswith("southwest"):
is_direction = 1
this_direction = "southwest"
elif entry.startswith("north"):
is_direction = 1
this_direction = "north"
elif entry.startswith("east"):
is_direction = 1
this_direction = "east"
elif entry.startswith("south"):
is_direction = 1
this_direction = "south"
elif entry.startswith("west"):
is_direction = 1
this_direction = "west"
if is_direction == 1:
if not data['ignoring_exits']:
# print('[handling direction, not exits]')
data['last_was_dir'] = 1
if data['last_direction'] != '':
data['last_direction'] = '{}, '.format(data['last_direction'])
data['last_direction'] = '{}{} {}'.format(
data['last_direction'], quantity, self.direction_map[this_direction]
)
else:
# print('[ignoring exits direction line]')
pass
else:
data['ignoring_exits'] = False
if data['last_was_dir'] == 1:
# reset count
if data['last_count'] > 0:
this_square = [data['last_count'], data['last_direction'], data['room_id'], int(math.floor(data['room_value']))]
data['enemies_by_square'].append(this_square)
data['nothing'] = False
data['next_color'] = ''
data['room_id'] = data['room_id'] + 1
data['room_value'] = 0
data['last_direction'] = ''
data['last_enemy_line'] = ''
data['last_count'] = 0
data['last_was_dir'] = 0
data['next_color'] = ''
add_player_value = False
# Special GMCP MDT colour codes
if entry[0:6] == 'u001b[':
# u001b[38;5;37mRuhsbaaru001b[39;49mu001b[0m
here = entry.index('m')
data['next_color'] = entry[7:here]
# entry = entry[here + 1:-20]
# entry = entry.replace('u001b', '')
entry = entry.replace('u001b', '\033')
# Might be a second colour code for PK
if entry[0:6] == 'u001b[':
here = entry.index('m')
data['next_color'] = entry[7:here]
entry = entry[here + 1:-20]
add_player_value = True
this_value = self.default_npc_value
for custom_match in self.custom_matches:
if custom_match[3]:
# This is a regex match
rexp = re.compile(custom_match[0])
if rexp.match(entry):
if custom_match[1] and custom_match[1] in self.colour_map:
entry = '{}{}{}'.format(
self.colour_map[custom_match[1]],
entry,
self.colour_map['reset']
)
this_value = custom_match[2]
else:
# This is a regular string match
if custom_match[0] in entry:
if custom_match[1] and custom_match[1] in self.colour_map:
entry = '{}{}{}'.format(
self.colour_map[custom_match[1]],
entry,
self.colour_map['reset']
)
this_value = custom_match[2]
if add_player_value == True:
this_value = this_value + self.bonus_player_value
data['room_value'] = data['room_value'] + (this_value * quantity)
if quantity > 1:
entry = '{} {}'.format(quantity, entry)
data['entity_table'].append([data['room_id'], entry, data['next_color']])
data['last_count'] = data['last_count'] + quantity
if data['last_enemy_line'] != '':
data['last_enemy_line'] = '{}, '.format(data['last_enemy_line'])
data['last_enemy_line'] = '{}{}'.format(data['last_enemy_line'], entry)
if data['nothing']:
self.return_value.append('Nothing seen, try elsewhere!')
else:
done_here = False
rooms_ignored = 0
data['enemies_by_square'].sort(key=lambda square: square[3])
# Grab shortest
for square in data['enemies_by_square']:
# Only show if this room meets the minimum value
if square[3] >= self.minimum_room_value and len(square[1]) > data['longest_direction']:
data['longest_direction'] = len(square[1])
for square in data['enemies_by_square']:
# Only show if this room meets the minimum value
if square[3] >= self.minimum_room_value:
done_here = False
fstring = '{{:<{}}} [{{}}] '.format(data['longest_direction'])
output = fstring.format(square[1], square[3])
for entity in data['entity_table']:
if entity[0] == square[2]:
if done_here:
output = '{}, '.format(output)
output = '{}{}'.format(output, entity[1])
done_here = True
if square[0] < 2:
output = '{} [{} thing]'.format(output, square[0])
else:
output = '{} [{} things]'.format(output, square[0])
self.return_value.append(output)
else:
rooms_ignored = rooms_ignored + 1
square = None
for entity in data['entity_table']:
entity = None
if rooms_ignored > 0 and self.show_hidden_room_count:
output = '({} rooms below your value limit of {})'.format(rooms_ignored, self.minimum_room_value)
self.return_value.append(output)
if __name__ == '__main__':
if len(sys.argv) < 2:
print('[error] No input provided.')
sys.exit()
argument, mdt_line = sys.argv.pop(1), None
# Is this a file passed to us?
if os.path.exists(argument):
with open(argument, 'r') as f:
mdt_line = f.readline()
else:
mdt_line = argument
mdt = MapDoorText()
mdt.parse_mdt(mdt_line)
for line in mdt.return_value:
print(line)

24
src/missiontimers.tin

@ -0,0 +1,24 @@
#CLASS {missiontimers} {kill};
#CLASS {missiontimers} {open};
#NOP ==[ Load Sausage Mission stuff ]==
#READ {src/missiontimers/sausage_lite.tin};
#ALIAS {missions} {
#if {&missions} { #echo {Mission Timers:}; } { #return; };
#if {&missions[sausage]} {
#foreach {$missions[sausage][active_list][%*]} {player} {
#showme {\t$player is cooling down on sausage missions.};
};
#foreach {$missions[sausage][retry_list][%*]} {player} {
#showme {\t$player is not able to request a new sausage mission.};
};
};
};
#nop "#event {RECEIVED OUTPUT} {%0}" catches all the things.... one event trigger
#nop and process a bunch of stuff?
#CLASS {missiontimers} {close};

116
src/missiontimers/letters.tin

@ -0,0 +1,116 @@
#CLASS {missiontimers_letters} {kill};
#CLASS {missiontimers_letters} {open};
#NOP [1 = Local, 2= Far Away, 3 = Distant Lands, 4 = Difficult Customer]
#VAR {dead_letter_rewards} {
{4 Ankh-Morpork dollars}{1}
{8 Ankh-Morpork dollars}{2}
{3 Djelian talents and 5 Djelian tooni}{3}
{4 Lancre crowns and 2 Lancre shillings}{3}
{7 Ephebian decadrachmae and 2 Ephebian stater}{3}
{2 Ankh-Morpork ten-dollars}{3}
{2 Genuan forins and 5 Genuan livres}{3}
{1 Klatchian ten dinar and 2 Klatchian two dinar coins}{3}
{1 Agatean Empire ten-rhinu and 5 Agatean Empire rhinu}{3}
{7 Lancre crowns and 5 Lancre shillings}{4}
{2 Agatean Empire ten-rhinu and 5 Agatean Empire rhinu}{4}
{6 Djelian talents and 5 Djelian tooni}{4}
{4 Genuan forins and 3 Genuan livres}{4}
{3 Ankh-Morpork ten-dollars and 2 Ankh-Morpork dollars}{4}
{1 Ephebian mina and 5 Ephebian decadrachmae}{4}
{1 Agatean Empire fifty-rhinu and 2 Agatean Empire ten-rhinu}{5}
{9 Ankh-Morpork ten-dollars}{5}
{1 Lancre sovereign and 1 Lancre tencrown}{5}
{3 Ephebian minae and 5 Ephebian decadrachmae}{5}
{1 Genuan ducat and 2 Genuan forins}{5}
}
#var {missions[letter][active_list]} {};
#var {missions[letter][retry_list]} {};
#ALIAS {/letter_returned} {
#list {missions[letter][retry_list]} {find} {$GMCP[charinfo][name]} {letter_current};
#if {$letter_current == 0} {
#list {missions[letter][retry_list]} {add} {$GMCP[charinfo][name]};
#line sub variable {
#delay {600} {
#nop Print message
#format {letter_retry_line} {%c[MH] %c*%c %s%c can now request a new letter from Frank.} {bold blue} {bold yellow} {bold green}{$GMCP[charinfo][name]} {bold blue};
#echo {$letter_retry_line};
#unvar {letter_retry_line};
#nop Remove player from state list
#list {missions[letter][retry_list]} {find} {$GMCP[charinfo][name]} {letter_current_inner};
#list {missions[letter][retry_list]} {delete} {$letter_current_inner};
};
};
};
#unvar {letter_current};
};
#ALIAS {return letter} {
#send {return letter};
/letter_returned;
};
#ACTION {^You offer to give a letter to Frank} {
/letter_returned;
};
#ACTION {^You have been awarded %d experience points and given %+} {
#nop You have been awarded 60407 experience points and given 2 Agatean Empire ten-rhinu and 5 Agatean Empire rhinu.
-- Last difficulty completion seen for future salute trigger
local iLastDifficultyCompleted = 0
-- Detected a reward string, record a difficulty level in preperation for the salute line
function QuowMissionReward (sName, sLine, wildcards)
sCashValue = wildcards[1]
if (sQuowRewards[sCashValue] ~= nil) then
iLastDifficultyCompleted = sQuowRewards[sCashValue]
else
-- See if we were waiting for an Ozzie pottery timer?
if (IsTimer("StoPotteryWaiting_" .. sCurrentCharacter) == 0) then
AddTimer ("StoLatPottery_" .. sCurrentCharacter, 1, 0, 0, "", 1061, "QuowMissionNotify")
elseif (IsTimer("OCPennieMission_" .. sCurrentCharacter) == 0) then
AddTimer ("OCPennieLaced_" .. sCurrentCharacter, 1, 0, 0, "", 1061, "QuowMissionNotify")
end
end
end
}
<trigger
enabled="y"
keep_evaluating="n"
match="^(?:> )?You have been awarded [0-9]{1,7} experience points and given (.+?)\.$"
regexp="y"
script="QuowMissionReward"
name="QuowMissionReward"
sequence="40"
>
</trigger>
#ACTION {^You salute smartly as you deliver a letter} {
-- Saw a successful delivery mission, start a timer if we have a known difficulty completion value
function QuowLetterSuccess (sName, sLine, wildcards)
if (bNotificationTimers ~= true) then
return
end
if (iLastDifficultyCompleted == 1) then
AddTimer ("DeadLetterLocal_" .. sCurrentCharacter, 1, 0, 0, "", 1061, "QuowMissionNotify")
elseif (iLastDifficultyCompleted == 2) then
AddTimer ("DeadLetterCloseby_" .. sCurrentCharacter, 1, 0, 0, "", 1061, "QuowMissionNotify")
elseif (iLastDifficultyCompleted == 3) then
AddTimer ("DeadLetterFaraway_" .. sCurrentCharacter, 1, 0, 0, "", 1061, "QuowMissionNotify")
elseif (iLastDifficultyCompleted == 4) then
AddTimer ("DeadLetterDistant_" .. sCurrentCharacter, 1, 0, 0, "", 1061, "QuowMissionNotify")
elseif (iLastDifficultyCompleted == 5) then
AddTimer ("DeadLetterDifficult_" .. sCurrentCharacter, 1, 0, 0, "", 1061, "QuowMissionNotify")
end
iLastDifficultyCompleted = 0
end
};
#CLASS {missiontimers_letters} {close};

56
src/missiontimers/sausage_lite.tin

@ -0,0 +1,56 @@
#CLASS {missiontimers_sausages} {kill};
#CLASS {missiontimers_sausages} {open};
#var {missions[sausage][active_list]} {};
#var {missions[sausage][retry_list]} {};
#nop You have four hours to deliver 150 fresh - line to start it all?
#ACTION {^You have four hours to deliver %d fresh} {
#action {^Sam Slager says to%+you: I'll have to take care of this one later} {
#nop [A mission started, start checking for resignations];
#nop Are we already waiting on a timer for this character?
#list {missions[sausage][retry_list]} {find} {$GMCP[charinfo][name]} {sausage_current};
#if {$sausage_current == 0} {
#list {missions[sausage][retry_list]} {add} {$GMCP[charinfo][name]};
#line sub variable {
#delay {600} {
#nop Print message
#format {sausage_retry_line} {%c[MH] %c*%c %s%c can now try a new sausage mission from Sam Slager.} {bold blue} {bold yellow} {bold green}{$GMCP[charinfo][name]} {bold blue};
#echo {$sausage_retry_line};
#unvar {sausage_retry_line};
#nop Remove player from state list
#list {missions[sausage][retry_list]} {find} {$GMCP[charinfo][name]} {sausage_current_inner};
#list {missions[sausage][retry_list]} {delete} {$sausage_current_inner};
};
};
};
#unvar {sausage_current};
};
#action {^Sam Slager says to%+you: Thank you, that's all} {
#nop [A mission started, start checking for completions];
#nop Are we already waiting on a timer for this character?
#list {missions[sausage][active_list]} {find} {$GMCP[charinfo][name]} {sausage_current};
#if {$sausage_current == 0} {
#list {missions[sausage][active_list]} {add} {$GMCP[charinfo][name]};
#line sub variable {
#delay {3600} {
#nop Print message
#format {sausage_timer_line} {%c[MH] %c*%c %s can get full XP for a sausage mission.} {bold blue} {bold yellow} {bold blue} {$GMCP[charinfo][name]};
#echo {$sausage_timer_line};
#unvar {sausage_timer_line};
#nop Remove player from state list
#list {missions[sausage][active_list]} {find} {$GMCP[charinfo][name]} {sausage_current_inner};
#list {missions[sausage][active_list]} {delete} {$sausage_current_inner};
};
};
};
#unvar {sausage_current};
};
};
#CLASS {missiontimers_sausages} {close};

79
src/missiontimers/sausages.tin

@ -0,0 +1,79 @@
#CLASS {missiontimers_sausages} {kill};
#CLASS {missiontimers_sausages} {open};
#NOP =======================
#NOP ===== VARIABLES =====
#NOP =======================
#VARIABLE {missions[sausage]} {
{current_difficulty}{1}
{current_primer}{1}
}
#NOP =======================
#NOP ===== Aliases =====
#NOP =======================
#ALIAS {/sausage_mission_start} {
#unaction {^You have four hours to deliver %1 fresh %2 sausages to Sam Slager.$};
#var {missions[sausage][current_difficulty]} {$missions[sausage][current_primer]};
#nop [A mission started, start checking for resignations]
#action {^Sam Slager says to %1 I'll have to take care of this one later.$} {
#unaction {^You have four hours to deliver %1 fresh %2 sausages to Sam Slager.$};
#unaction {^Sam Slager says to %1 I'll have to take care of this one later.$};
#unaction {^Sam Slager gives you %1{dollar|pence}%3$};
#line sub variable {
#delay {600} {
#format {sausage_retry_line} {%c[MH] %c*%c %s%c can now try a new sausage mission from Sam Slager.} {bold blue} {bold yellow} {bold green}{$GMCP[charinfo][name]} {bold blue};
#echo {$sausage_retry_line};
#unvar {sausage_retry_line};
};
};
};
#nop [A mission started, start checking for completions]
#action {^Sam Slager gives you %1{dollar|pence}%3$} {
#unaction {^You have four hours to deliver %1 fresh %2 sausages to Sam Slager.$};
#unaction {^Sam Slager says to %1 I'll have to take care of this one later.$};
#unaction {^Sam Slager gives you %1{dollar|pence}%3$};
#if {$missions[sausage][current_difficulty]} {
#format {delayname} {sausage_easy_%s} {$GMCP[charinfo][name]};
#line sub variable {
#delay {$delayname} {
#format {sausage_timer_line} {%c[MH] %c*%c %s last finished an unspiced sausage mission.} {bold blue} {bold yellow} {bold blue} {$GMCP[charinfo][name]};
#echo {$sausage_timer_line};
#unvar {sausage_timer_line};
} {3600};
};
#unvar {delayname};
};
#else {
#line sub variable {
#format {delayname} {sausage_hard_%s} {$GMCP[charinfo][name]};
#delay {$delayname} {
#format {sausage_timer_line} {%c[MH] %c*%c %s last finished a spiced sausage mission.} {bold blue} {bold yellow} {bold blue} {$GMCP[charinfo][name]};
#echo {$sausage_timer_line};
#unvar {sausage_timer_line};
} {3600};
};
#unvar {delayname};
};
};
};
#NOP =======================
#NOP ===== Actions =====
#NOP =======================
#NOP ==[Sausage Missions]==
#ACTION {^Sam Slager asks you: So, you want to try filling a sausage order? You'll have four hours to hunt %1, gather spices to mix into the ground meat, make %2 sausages from it, and deliver them to me. Are you up to it?$} {
#var {missions[sausage][current_primer]} {2};
#action {^You have four hours to deliver %1 fresh %2 sausages to Sam Slager.$} { /sausage_mission_start; };
};
#ACTION {^Sam Slager asks you: So, you want to try filling a sausage order? You'll have four hours to hunt %1, make %2 sausages from it, and deliver them to me. Are you up to it?$} {
#var {missions[sausage][current_primer]} {1};
#action {^You have four hours to deliver %1 fresh %2 sausages to Sam Slager.$} { /sausage_mission_start; };
};
#CLASS {missiontimers_sausages} {close};

0
src/timers.tin → src/spottimers.tin

7
src/tpamonitor.tin

@ -66,6 +66,13 @@
update_prompt; update_prompt;
} }
#nop ### alias to reset TPA status, if it breaks and we didn't catch it ###
#alias {tpareset} {
#unvar {tpa_start};
#unvar {tpa_end};
#var {tpa_status} {0};
}
#var {tpa_status} {0}; #var {tpa_status} {0};
#CLASS {tpamonitor} {close}; #CLASS {tpamonitor} {close};
Loading…
Cancel
Save