├── README.md ├── npc.png ├── desc1.png ├── desc2.png ├── desc3.png ├── desc4.png ├── ConvLib.aslx ├── compass.png ├── devtools.png ├── CombatLib.zip ├── notepad_xml.png ├── DanskConvLib.aslx ├── saveloadatts.png ├── enhanced_compass.png ├── notepad_context.png ├── type_attributes.png ├── empire ├── readme.md ├── lib.xml ├── interface.xml └── Empire.aslx ├── compare.rb ├── ShipwiseLib.aslx ├── group_project.aslx ├── notes └── italian.md ├── WeatherLib.aslx ├── braces.html ├── group_project_library.aslx ├── YamlToQuest.rb ├── QuestLib.aslx ├── LiquidLib.aslx ├── LiquidDemo.aslx ├── StackLibrary.aslx ├── ShopLib.aslx ├── InvPane2.aslx ├── StackLib.aslx ├── LockDemo.aslx ├── weather.aslx ├── LiftLib.aslx ├── EnhancedIt.aslx ├── third_past.aslx ├── StackDemo.aslx ├── ClockLib.aslx ├── CompliantNpcLib.aslx └── SaveLoad.aslx /README.md: -------------------------------------------------------------------------------- 1 | # quest 2 | Tutorials and Libraries for quest 5 3 | -------------------------------------------------------------------------------- /npc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/npc.png -------------------------------------------------------------------------------- /desc1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/desc1.png -------------------------------------------------------------------------------- /desc2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/desc2.png -------------------------------------------------------------------------------- /desc3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/desc3.png -------------------------------------------------------------------------------- /desc4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/desc4.png -------------------------------------------------------------------------------- /ConvLib.aslx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/ConvLib.aslx -------------------------------------------------------------------------------- /compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/compass.png -------------------------------------------------------------------------------- /devtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/devtools.png -------------------------------------------------------------------------------- /CombatLib.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/CombatLib.zip -------------------------------------------------------------------------------- /notepad_xml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/notepad_xml.png -------------------------------------------------------------------------------- /DanskConvLib.aslx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/DanskConvLib.aslx -------------------------------------------------------------------------------- /saveloadatts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/saveloadatts.png -------------------------------------------------------------------------------- /enhanced_compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/enhanced_compass.png -------------------------------------------------------------------------------- /notepad_context.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/notepad_context.png -------------------------------------------------------------------------------- /type_attributes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThePix/quest/HEAD/type_attributes.png -------------------------------------------------------------------------------- /empire/readme.md: -------------------------------------------------------------------------------- 1 | These three files are the start of a 4X game for Quest. I am not sure Quest is the best medium for this, and I have no plans to take these any further, but the files are there for anyone interested. Feel free to use this however you want. 2 | 3 | The Pixie, May/2018 4 | -------------------------------------------------------------------------------- /compare.rb: -------------------------------------------------------------------------------- 1 | require "rexml/document" 2 | include REXML 3 | 4 | 5 | 6 | 7 | 8 | 9 | def get_lists filename 10 | doc = REXML::Document.new File.new(filename) 11 | templates = [] 12 | doc.elements.each("library/template") do |temp| 13 | templates << temp.attributes["name"] 14 | end 15 | dynamic_templates = [] 16 | doc.elements.each("library/dynamictemplate") do |temp| 17 | dynamic_templates << temp.attributes["name"] 18 | end 19 | verb_templates = [] 20 | doc.elements.each("library/verbtemplate") do |temp| 21 | verb_templates << temp.attributes["name"] 22 | end 23 | return templates, dynamic_templates, verb_templates 24 | end 25 | 26 | 27 | 28 | a1, b1, c1 = get_lists "English.aslx" 29 | a2, b2, c2 = get_lists "Greek.aslx" 30 | p (a1 - a2) 31 | p (b1 - b2) 32 | p (c1 - c2) 33 | -------------------------------------------------------------------------------- /ShipwiseLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /group_project.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | c76a1ed4-9935-44c1-97e7-b7857e268d49 8 | 1.0 9 | 2017 10 | false 11 |
All rooms, objects, exits (if you name them), commands (if you name them) and functions you add to the game must have a name that starts with your initials (or other two letter identifier), and that includes the new name for gateway. This is to ensure there are no conflicts. If two people have a room called gateway in their zone, we will have problems when we put it together.

Commands and verb elements will generally be better submitted to the library. Functions might too if others will use them.

Use the Combined function to test in game if this is the final version or just your bit.

if (IsCombined()) msg("This is the full version!")

NOTE: Any changes you make to game, hub, or player will be lost (as well as any objects or commands or exits inside them) when you game is combined with everything else.

NOTE: The library may be updated periodically, and that may well affect the hub and player, but should not affect your zone.]]>
12 | 13 | StartScript 14 | 15 | false 16 |
17 | 18 | 19 | false 20 | 21 | DescribeHub 22 | 23 | 24 | HubEnterScript 25 | 26 | 27 | 28 | 29 | false 30 | human 31 | 32 | DescribePlayer 33 | 34 | 35 | 36 | travel 37 | 44 | 45 | 46 | 47 | false 48 | 49 | 50 | 51 | 52 | 53 | false 54 | 55 | 56 | AddToHubGateway (this) 57 | 58 | 59 |
60 | -------------------------------------------------------------------------------- /notes/italian.md: -------------------------------------------------------------------------------- 1 | A list of translations needed for the Italian version of Quest 2 | ------------------------------------------------------------- 3 | 4 | To support the AGAIN command, the command and abbreviation, plus an error message: 5 | 6 | again 7 | g 8 | There is nothing to repeat. 9 | 10 | This is used in the status panel; not sure why it is missing, it has been in Quest for years: 11 | 12 | Status 13 | Score 14 | Health 15 | Money 16 | 17 | Text for the interface: 18 | 19 | Type here... 20 | Continue... 21 | 22 | Various error messages for when the player uses ALL. 23 | 24 | 25 | Nothing here to take. 26 | You've nothing to drop. 27 | You've nothing to wear. 28 | You've nothing to take off. 29 | 30 | Possessives (the last three are netrual, male, female; all the same in English): 31 | 32 | its 33 | his 34 | her 35 | your 36 | their 37 | their 38 | their 39 | 40 | For a list when there is nothing there: 41 | 42 | nothing 43 | 44 | When the player locks a container: 45 | 46 | Locked. 47 | 48 | When saying who the author is: 49 | 50 | by 51 | 52 | Also: 53 | 54 | Eat 55 | Yes 56 | No 57 | 58 | 59 | Various messages for clothing (object.article will be "it" or "them" in English): 60 | 61 | "You put " + object.article + " on." 62 | "You can't wear " + object.article + "." 63 | "You would need to get " + object.article + " before you can put " + object.article + " on." 64 | "You would need to get " + object.article + " before you can take " + object.article + " off." 65 | "You are already wearing " + object.article + "." 66 | "You are not wearing " + object.article + "." 67 | "You cannot remove " + object.article + "!" 68 | "You cannot wear that over " + GetDisplayGarment(object) + "." 69 | "You cannot wear that while wearing " + GetDisplayGarment(object) + "." 70 | "You take " + object.article + " off." 71 | "You can't remove that while wearing " + GetDisplayGarment(object) + "." 72 | 73 | And for containers: 74 | 75 | "You can't put " + object.article + " there." 76 | 77 | This is added to an item when it is listed (eg "hat (worn)") 78 | 79 | worn 80 | 81 | Also these used for display verbs (when you click on an object, these are shown and can be clicked): 82 | 83 | Wear 84 | Remove 85 | 86 | Commands are tricky because we need to cover all possibilities, so please list any alternatives you can think of in the format "take #object# off". 87 | 88 | wear #object# 89 | remove #object# 90 | give #object# 91 | tell #object1# to #object2# 92 | 93 | 94 | These error responses are also a bit more tricky as they vary depending on the object. The WriteVerb function modifies the verb, so in the first, it might return "They are". This will work in Italian too. 95 | 96 | WriteVerb(object, "be") + " too heavy to be taken." 97 | "You can't carry any more items." 98 | "You can't put more items in " + object.article + "." 99 | 100 | "You can't put " + object.article + " there." 101 | "You can't give " + object.article + "." 102 | "You eat " + object.article + "." 103 | "It is too dark to make anything out." 104 | WriteVerb(object, "do") + " nothing." 105 | 106 | 107 | -------------------------------------------------------------------------------- /WeatherLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 18 | 19 | if (not HasInt(game, "weathercount")) { 20 | game.weathercount = 0 21 | } 22 | if (game.currentweather = null) { 23 | game.currentweather = PickOneObject(FilterByType(AllObjects(), "weather_type")) 24 | } 25 | game.weathercount = game.weathercount + 1 26 | do (game.currentweather, "weatherchangescript") 27 | if (game.weathertochange) { 28 | game.weathercount = 0 29 | exit = PickOneUnlockedExit(game.currentweather) 30 | game.currentweather = exit.to 31 | if (HasString(exit, "message") and not GetBoolean(game.pov.parent, "inside")) { 32 | msg (exit.message) 33 | } 34 | } 35 | if (not HasInt(game.pov, "soaking")) game.pov.soaking = 0 36 | if (not GetBoolean(game.pov.parent, "inside")) { 37 | game.pov.soaking = game.pov.soaking + game.currentweather.rain 38 | } 39 | else { 40 | game.pov.soaking = game.pov.soaking - 5 41 | } 42 | if (game.pov.soaking > 100) game.pov.soaking = 100 43 | if (0 > game.pov.soaking) game.pov.soaking = 0 44 | 45 | 46 | 47 | 48 | if (not GetBoolean(game.pov.parent, "inside")) { 49 | msg ("" + game.currentweather.alias) 50 | } 51 | 52 | 53 | 54 | return (game.currentweather.look) 55 | 56 | 57 | 58 | 0 59 | 60 | game.weathertochange = RandomChance(game.weathercount) 61 | 62 | 63 | 64 | 65 | 66 | 67 | _ObjectEditor 68 | Weather 69 | editor_object; editor_player 70 | 71 | 72 | dropdowntypes 73 | *=Not weather; weather_type=Weather 74 | Weather 75 | 76 | 77 | 78 | number 79 | Rain amount 80 | rain 81 | weather_type 82 | 83 | 84 | 85 | 86 | textbox 87 | Look at sky 88 | look 89 | weather_type 90 | 91 | 92 | 93 | 94 | script 95 | Weather change script (must set game.weathertochange) 96 | weatherchangescript 97 | weather_type 98 | 99 | 100 | 101 | checkbox 102 | Inside? 103 | inside 104 | weather_type 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /braces.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Quest Bracket Check 5 | 10 | 11 | 71 | 72 | 73 | 74 |

Quest Bracket Check

75 | 76 | 77 |
78 | 79 |
80 |
81 |
Possible errors
82 | 83 |
84 |
Notes
85 |

86 | The text processor in Quest allows you to create some complex strings, but if you miss a curly brace, it can lead to some weird errors that are difficult to spot. Paste your code into this box to have it check that you have as many start braces as end braces. If there is an error, the output will have properly formatted sections replaced by ---, which might help you find the error. 87 |

88 |

89 | As well as curly braces, it will also try to match parentheses and angle brackets. 90 |

91 |

92 | I have designed this with text output in mind, but it will probably work on Quest code too, and you should be able paste a whole script in. The text will be broken up into chunks at each msg (if you have "msg" in your text, you may have problems!). It will only find one error per bracket type per chunk. 93 |

94 |

95 | It is not that clever and some things will confuse it. For example, if you use greater than or less than in a text processor "if" directive, it will think that is an angle bracket and complain it is not matched. You could delete the offending greater than or less than symbols after pasting into this page to get around that. 96 |

97 | 98 | 99 | -------------------------------------------------------------------------------- /group_project_library.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | travel 4 | 13 | You travel in some unspecified manner... 14 | 15 | 16 | 17 | 18 | name = room.name + "_destination" 19 | if (not GetObject(name) = null) error ("Something has gone wrong, and a destination is being added to the hub a second time.") 20 | create (name) 21 | obj = GetObject (name) 22 | obj.parent = destinations 23 | obj.look = room.dimensionderscription 24 | obj.alias = room.dimensionname 25 | obj.to = room 26 | obj.linkcolour = room.dimensioncolour 27 | 28 | 29 | 30 | msg ("Looking good...") 31 | msg ("As a {either player.isfemale:female|male} {player.race}.") 32 | 33 | 34 | 35 | msg ("This is the hub, the starting point of your adventure!") 36 | 37 | 38 | 39 | msg ("Welcome to...") 40 | msg ("Group project!") 41 | 42 | 43 | 44 | msg ("So this is the hub...") 45 | player.cantravelfromanywhere = false 46 | 47 | 48 | 49 | room = GetObject(roomname) 50 | if (room = null) { 51 | obj.parent = hub 52 | } 53 | else { 54 | obj.parent = room 55 | } 56 | 57 | 58 | 59 | return (gateway.completed) 60 | 61 | 62 | 63 | flag = true 64 | foreach (obj, GetDirectChildren(destinations)) { 65 | if (not obj.to.completed) { 66 | flag = false 67 | } 68 | } 69 | return (flag) 70 | 71 | 72 | 73 | gateway.completed = true 74 | 75 | 76 | 77 | false 78 | 79 | 80 | 81 | 82 | _ObjectEditor 83 | Gateway 84 | gateway_type 85 | 86 | 87 | Dimension name 88 | textbox 89 | dimensionname 90 | 91 | 92 | 93 | Dimension description 94 | richtext 95 | dimensionderscription 96 | 97 | 98 | 99 | Start script 100 | script 101 | _initialise_ 102 | 103 | 104 | 105 | label 106 | This will run when the game starts. The first line must be "AddToHubGateway (this)" 107 | 108 | 109 | 110 | dropdown 111 | Link colour (when travelling from hub) 112 | dimensioncolour 113 | [HTMLColorNames] 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /YamlToQuest.rb: -------------------------------------------------------------------------------- 1 | # A way to convert YAML to Quest XML 2 | # 3 | # Version 2: added scenery objects and zones 4 | # Version 3: added object prefixes 5 | # 6 | # By The Pixie 7 | 8 | 9 | # This will be added to every object and room 10 | # Useful for a group project to avoid name collisions 11 | OBJECT_PREFIX = "" 12 | 13 | 14 | 15 | require 'yaml' 16 | 17 | LIST1 = "North;Northeast;East;Southeast;South;Southwest;West;NorthWest;Up;Down;In;Out".split ";" 18 | LIST2 = "South;Southwest;West;NorthWest;North;Northeast;East;Southeast;Down;Up;Out;In".split ";" 19 | 20 | 21 | class Room 22 | attr_reader :alias, :desc, :name, :exits, :inside 23 | 24 | def initialize name, desc 25 | @alias = name 26 | @desc = desc 27 | @name = name.gsub(' ', '_').gsub(/[^\w]/, '').downcase 28 | # p @alias 29 | @exits = [] 30 | @objects = [] 31 | end 32 | 33 | def inside 34 | @inside = true 35 | end 36 | 37 | def to_s 38 | s = " \n" 39 | s += " \n" 40 | s += " #{@alias}\n" 41 | s += " \n" 44 | s += " \n" if @inside 45 | @objects.each do |k, v| 46 | s += " \n" 47 | s += " \n" 48 | s += " #{k}\n" 49 | s += " \n" 50 | s += " \n" 53 | s += " \n" 54 | end 55 | @exits.each { |exit| s += exit.to_s } 56 | s += " \n" 57 | s 58 | end 59 | 60 | def objects h 61 | @objects = h 62 | end 63 | 64 | end 65 | 66 | class Exit 67 | attr_reader :to, :dir 68 | 69 | def initialize dir, to, message = nil 70 | @to = to 71 | @message = message if message != '' 72 | @dir = dir 73 | end 74 | 75 | def to_s 76 | s = " \n" 77 | s += " \n" 78 | s += " #{@message}\n" if @message 79 | s += " \n" 80 | s 81 | end 82 | 83 | end 84 | 85 | 86 | 87 | def find list, name 88 | l = list.select { |e| e.is_a?(Room) && e.alias == name } 89 | raise "Not found #{name}" if l.length == 0 90 | raise "Found multiple #{name}" if l.length > 1 91 | l[0] 92 | end 93 | 94 | 95 | def reverse dir 96 | n = LIST1.index dir 97 | raise "Direction not found #{dir}" unless n 98 | LIST2[n] 99 | end 100 | 101 | 102 | 103 | data = YAML.load_file("quest.yml") 104 | list = [] 105 | data.each do |h| 106 | if h.is_a? Hash 107 | # p h 108 | room = Room.new h['Name'], h['Desc'] 109 | h.delete 'Name' 110 | h.delete 'Desc' 111 | if h['Inside'] 112 | room.inside 113 | h.delete 'Inside' 114 | end 115 | if h['Objs'] 116 | room.objects h['Objs'] 117 | h.delete 'Objs' 118 | end 119 | # p h 120 | h.each do |dir, v| 121 | l = v.split '|' 122 | s1 = l.length > 1 ? l[1] : nil 123 | s2 = l.length > 2 ? l[2] : nil 124 | dest = find(list, l[0]) 125 | room.exits << Exit.new(dir, dest, s1) 126 | dest.exits << Exit.new(reverse(dir), room, s2) 127 | end 128 | list << room 129 | else 130 | list << h 131 | end 132 | end 133 | 134 | 135 | 136 | File.open("quest.xml", "w") do |file| 137 | flag = false 138 | list.each do |el| 139 | if el.is_a? Room 140 | file << el.to_s 141 | else 142 | file << " \n" if flag 143 | file << " \n" 144 | file << " \n" 145 | flag = true 146 | end 147 | end 148 | file << " \n" 149 | end 150 | 151 | print "Done" -------------------------------------------------------------------------------- /QuestLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 22 | 23 | 24 | 25 | quest #object# 26 | quests 27 | 42 | 43 | 44 | 45 | quests;q;current quests;cq 46 | 50 | 51 | 52 | 53 | successes;successful quests;sq 54 | 58 | 59 | 60 | 61 | fails;failures;failed quests;fq 62 | 66 | 67 | 68 | 69 | 70 | if (GetObject("quests") = null) { 71 | create ("quests") 72 | } 73 | flag = true 74 | foreach (o, FilterByAttribute(GetDirectChildren(quests), "state", state)) { 75 | msg (QuestSummary(o)) 76 | flag = false 77 | } 78 | if (flag) { 79 | msg (Spaces(4) + "None") 80 | } 81 | firsttime { 82 | msg (" ") 83 | msg ("[Type SUCCESSFUL QUESTS or SQ to see a list of successfully completed quests]") 84 | msg ("[Type FAILED QUESTS or FQ for a list of failed quests]") 85 | } 86 | msg (" ") 87 | 88 | 89 | 90 | 91 | if (GetObject("quests") = null) { 92 | create ("quests") 93 | } 94 | obj.parent = quests 95 | if (not HasAttribute(obj, "history")) { 96 | obj.history = NewStringList() 97 | } 98 | if (not obj.status = s) { 99 | if (state = "Success") { 100 | msg ("Quest completed: {i:" + obj.alias + "}") 101 | obj.state = "Successful" 102 | } 103 | else if (state = "Failed") { 104 | msg ("Quest failed: {i:" + obj.alias + "}") 105 | obj.state = "Failed" 106 | } 107 | else if (state = "Start") { 108 | msg ("Quest started: {i:" + obj.alias + "}") 109 | obj.state = "Active" 110 | } 111 | else { 112 | msg ("Quest updated: {i:" + obj.alias + "}") 113 | obj.state = "Active" 114 | } 115 | } 116 | if (HasString(obj, "status")) { 117 | list add (obj.history, "{s:" + obj.status + "}") 118 | } 119 | obj.status = s 120 | 121 | 122 | 123 | return (Spaces(4) + "{i:" + obj.alias + ":} " + obj.status) 124 | 125 | 126 | 127 | Quest (obj, s, "Next") 128 | 129 | 130 | 131 | Quest (obj, s, "Success") 132 | 133 | 134 | 135 | Quest (obj, s, "Failed") 136 | 137 | 138 | 139 | Quest (obj, s, "Start") 140 | 141 | 142 | 143 | if (GetObject("quests") = null) { 144 | create ("quests") 145 | } 146 | if (not quest.parent = quests) { 147 | return ("Inactive") 148 | } 149 | else { 150 | return (quest.state) 151 | } 152 | 153 | 154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /LiquidLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 17 | 18 | 19 | 20 | 0 21 | 10 22 | 23 | 24 | Look at 25 | Drop 26 | Fill 27 | Drink from 28 | Empty 29 | 30 | 31 | 32 | if (this.full = this.capacity) { 33 | msg ("It is already full.") 34 | } 35 | else if (not GetBoolean(game.pov.parent, "watersource")) { 36 | msg ("Nothing to fill it with here.") 37 | } 38 | else { 39 | if (this.full > 0 and not this.liquidtype = game.pov.parent.liquidtype) { 40 | MixLiquid(this, game.pov.parent.liquidtype) 41 | } 42 | else { 43 | msg ("You fill it with " + game.pov.parent.liquidtype + ".") 44 | this.liquidtype = game.pov.parent.liquidtype 45 | } 46 | this.full = this.capacity 47 | } 48 | 49 | 50 | 51 | if (this.full = 0) { 52 | msg ("It is already empty.") 53 | } 54 | else if (HasScript(game.pov.parent, "handle_emptying")) { 55 | game.pov.parent.emptiedliquidtype = this.liquidtype 56 | this.full = 0 57 | do(game.pov.parent, "handle_emptying") 58 | } 59 | else { 60 | msg ("You empty it.") 61 | this.full = 0 62 | } 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | do (this, "drinkfrom") 71 | 72 | 73 | 74 | if (this.full = 0) { 75 | msg ("It is empty.") 76 | } 77 | else { 78 | DrinkLiquid(this.liquidtype) 79 | this.full = this.full - 1 80 | } 81 | 82 | 83 | 84 | 85 | 86 | msg ("You fill it with " + game.pov.parent.liquidtype + ".") 87 | container.liquidtype = liquidtype 88 | 89 | 90 | 91 | 92 | msg ("You take a drink from it.") 93 | 94 | 95 | 96 | 97 | fill 98 | fill 99 | "You can't fill " + object.article + "." 100 | 101 | 102 | empty 103 | empty 104 | "You can't empty " + object.article + "." 105 | 106 | 107 | drinkfrom 108 | drink from 109 | "You can't drink from " + object.article + "." 110 | 111 | 112 | 113 | 114 | 115 | _ObjectEditor 116 | Liquids 117 | 118 | 119 | 120 | 121 | dropdowntypes 122 | Type 123 | *=None; liquidcontainer=Container 124 | 150 125 | editor_object 126 | 127 | 128 | 129 | 130 | number 131 | Maximum capacity 132 | capacity 133 | 100 134 | liquidcontainer 135 | 0 136 | 137 | 138 | 139 | number 140 | Starting volume 141 | full 142 | 100 143 | liquidcontainer 144 | 0 145 | 146 | 147 | 148 | textbox 149 | Name of starting liquid 150 | liquidtype 151 | liquidcontainer 152 | 153 | 154 | 155 | 156 | 157 | checkbox 158 | Source of liquid here 159 | watersource 160 | editor_room 161 | 162 | 163 | 164 | textbox 165 | Name of liquid 166 | liquidtype 167 | editor_room 168 | 169 | 170 | 171 | script 172 | Run this script when a container is emptied (the "emptiedliquidtype" attribute of the room will be set) 173 | handle_emptying 174 | editor_room 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /LiquidDemo.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 19 | 20 | 21 | 22 | "It is already full." 23 | "It is already empty." 24 | "Nothing to fill it with here." 25 | "You fill it with " + game.pov.parent.liquidtype + "." 26 | 27 | 28 | 29 | 0 30 | 10 31 | 32 | 33 | Look at 34 | Drop 35 | Fill 36 | Drink from 37 | Empty 38 | 39 | 40 | 41 | if (this.full = this.capacity) { 42 | msg (DynamicTemplate("LiquidAlreadyFull")) 43 | } 44 | else if (not GetBoolean(game.pov.parent, "watersource")) { 45 | msg (DynamicTemplate("LiquidNothingHere")) 46 | } 47 | else { 48 | if (this.full > 0 and not this.liquidtype = game.pov.parent.liquidtype) { 49 | MixLiquid(this, game.pov.parent.liquidtype) 50 | } 51 | else { 52 | msg (DynamicTemplate("LiquidFillFromRoom")) 53 | this.liquidtype = game.pov.parent.liquidtype 54 | } 55 | this.full = this.capacity 56 | } 57 | 58 | 59 | 60 | if (this.full = 0) { 61 | msg (DynamicTemplate("LiquidAlreadyEmpty")) 62 | } 63 | else if (HasScript(game.pov.parent, "handle_emptying")) { 64 | game.pov.parent.emptiedliquidtype = this.liquidtype 65 | this.full = 0 66 | do(game.pov.parent, "handle_emptying") 67 | } 68 | else { 69 | msg ("You empty it.") 70 | this.full = 0 71 | } 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | do (this, "drinkfrom") 80 | 81 | 82 | 83 | if (this.full = 0) { 84 | msg ("It is empty.") 85 | } 86 | else { 87 | DrinkLiquid(this.liquidtype) 88 | this.full = this.full - 1 89 | } 90 | 91 | 92 | 93 | 94 | 95 | msg (DynamicTemplate("LiquidFillFromRoom")) 96 | container.liquidtype = liquidtype 97 | 98 | 99 | 100 | 101 | msg ("You take a drink from it.") 102 | 103 | 104 | 105 | 106 | fill 107 | fill 108 | "You can't fill " + object.article + "." 109 | 110 | 111 | empty 112 | empty 113 | "You can't empty " + object.article + "." 114 | 115 | 116 | drinkfrom 117 | drink from 118 | "You can't drink from " + object.article + "." 119 | 120 | 121 | 122 | 123 | 124 | _ObjectEditor 125 | Liquids 126 | 127 | 128 | 129 | 130 | dropdowntypes 131 | Type 132 | *=None; liquidcontainer=Container 133 | 150 134 | editor_object 135 | 136 | 137 | 138 | 139 | number 140 | Maximum capacity 141 | capacity 142 | 100 143 | liquidcontainer 144 | 0 145 | 146 | 147 | 148 | number 149 | Starting volume 150 | full 151 | 100 152 | liquidcontainer 153 | 0 154 | 155 | 156 | 157 | textbox 158 | Name of starting liquid 159 | liquidtype 160 | liquidcontainer 161 | 162 | 163 | 164 | 165 | 166 | checkbox 167 | Source of liquid here 168 | watersource 169 | editor_room 170 | 171 | 172 | 173 | textbox 174 | Name of liquid 175 | liquidtype 176 | editor_room 177 | 178 | 179 | 180 | script 181 | Run this script when a container is emptied (the "emptiedliquidtype" attribute of the room will be set) 182 | handle_emptying 183 | editor_room 184 | 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /StackLibrary.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 14 | 44 | 45 | 46 | 50 | 53 | 54 | 58 | 61 | 62 | 66 | 69 | 70 | 74 | 77 | 78 | 79 | 83 | 86 | 87 | 88 | 95 | 132 | 133 | 134 | 135 | 136 | 144 | 145 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 160 | 161 | if (HasScript(obj, att)) { 162 | do (obj, att) 163 | } 164 | if (HasString(obj, att)) { 165 | msg (GetString(obj, att)) 166 | } 167 | 168 | 169 | 170 | 171 | 172 | game 173 | 174 | Unstack (this) 175 | 176 | 177 | UseInStack (this) 178 | 179 | 180 | ConsumeInStack (this) 181 | 182 | 183 | LookInStack (this) 184 | 185 | 186 | 187 | 188 | 189 | 190 | false 191 | You take it. 192 | 193 | if (this.alias = null) { 194 | this.alias = object.name 195 | } 196 | container = this.stackparent 197 | 198 | this.parent = container 199 | SetStack(container) 200 | if (this.takemsg = null) { 201 | msg(DynamicTemplate("TakeSuccessful", object)) 202 | } 203 | else { 204 | msg (this.takemsg) 205 | } 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | _ObjectEditor 216 | Stackable 217 | editor_room; editor_player 218 | 219 | 220 | dropdowntypes 221 | *=Not stackable; stack_container=The stack itself; childstack_object=Member of a stack 222 | Stack 223 | 224 | 225 | 226 | objects 227 | stackparent 228 | childstack_object 229 | Stack container 230 | 231 | 232 | 233 | 234 | 235 | -------------------------------------------------------------------------------- /ShopLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 17 | 18 | 19 | 20 | "Sorry " + GetDisplayName(object) + " is not for sale." 21 | "You look longingly at " + GetDisplayName(object) + ", but you cannot afford it." 22 | "You buy " + GetDisplayName(object) + " for " + DisplayMoney(BuyingPrice(object)) + "." 23 | "You sell " + GetDisplayName(object) + " for " + DisplayMoney(SellingPrice(object)) + "." 24 | "Where do you think you are, a shop or something?" 25 | "You cannot sell things here - only buy." 26 | "You do not have " + GetDisplayName (object) + "." 27 | "Item to purchase (have " + DisplayMoney(game.pov.money) + ")" 28 | "You think about making a purchase, but decide not to." 29 | 30 | 31 | 32 | buy #object#;purchase #object# 33 | shopstock 34 | 44 | 45 | 46 | 47 | ^buy$|^purchase$ 48 | 68 | 69 | 70 | 71 | sell #object#;flog #object# 72 | 97 | You want to sell what? 98 | 99 | 100 | 101 | sell junk;flog junk;sell crap;flog crap 102 | 122 | You want to sell what? 123 | 124 | 125 | 126 | 127 | sl = NewStringList () 128 | foreach (obj, GetDirectChildren(game.pov.parent.shopstock)) { 129 | list add (sl, GetDisplayName (obj) + " (" + DisplayMoney(BuyingPrice(obj)) + ")") 130 | } 131 | return (Join (sl, ", ")) 132 | 133 | 134 | 135 | 136 | if (not HasObject(game.pov.parent, "shopstock")) { 137 | msg (DynamicTemplate("NotAShop", game.pov)) 138 | return (false) 139 | } 140 | if (HasInt(game.pov, "maxobjects")) { 141 | if (game.pov.maxobjects > 0) { 142 | children = GetDirectChildren(game.pov) 143 | if (ListCount(children) >= game.pov.maxobjects) { 144 | if (HasString(game.pov, "containermaxobjects")) { 145 | message = prefix + game.pov.containermaxobjects 146 | } 147 | else { 148 | message = prefix + DynamicTemplate("MaxObjectsInInventory", object) 149 | } 150 | return (false) 151 | } 152 | } 153 | } 154 | return (true) 155 | 156 | 157 | 158 | 159 | if (not HasInt (obj, "price")) { 160 | msg (DynamicTemplate("NotForSale", obj)) 161 | } 162 | else { 163 | buyingprice = BuyingPrice(obj) 164 | if (buyingprice > game.pov.money) { 165 | msg (DynamicTemplate("CannotAfford", obj)) 166 | } 167 | else { 168 | if (GetBoolean(obj, "cloneonpurchase")) { 169 | CloneObjectAndMove(obj, game.pov) 170 | } 171 | else { 172 | obj.parent = game.pov 173 | } 174 | game.pov.money = game.pov.money - buyingprice 175 | P (DynamicTemplate("BuySuccessful", obj)) 176 | } 177 | } 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 191 | 195 | 196 | 199 | 203 | 204 | 205 | 206 | -------------------------------------------------------------------------------- /InvPane2.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 19 | 20 | 21 | 23 | var Inventory2Verbs; 24 | $(function() { 25 | var s = "
\ 26 |

####

\ 27 |
\ 28 |
\ 29 |
    \ 30 |
\ 31 |
\ 32 |
\ 33 | \ 34 | \ 35 | \ 36 | \ 37 | \ 38 | \ 39 | \ 40 | \ 41 | \ 42 |
\ 43 |
\ 44 |
"; 45 | $("#Inventory2Holder").remove(); 46 | $(s).insertBefore("#statusVarsLabel"); 47 | $("#Inventory2Holder").multiOpenAccordion({ active: [0] }); 48 | $("#lstInventory2").selectable({ 49 | selected: function (event, ui) { 50 | $(ui.selected).siblings().removeClass("ui-selected"); 51 | updateVerbButtons($(ui.selected), Inventory2Verbs, "cmdInventory2"); 52 | } 53 | }); 54 | 55 | }); 56 | 57 | function updateInventory2(listName,listData) { 58 | listData = JSON.parse(listData); 59 | var listElement = "#lst" + listName; 60 | var buttonPrefix = "cmd" + listName; 61 | var idPrefix = buttonPrefix; 62 | eval(listName + "Verbs = new Array();"); 63 | 64 | var verbsArray = eval(listName + "Verbs"); 65 | 66 | var previousSelectionText = ""; 67 | var previousSelectionKey = ""; 68 | var foundPreviousSelection = false; 69 | 70 | var $selected = $(listElement + " .ui-selected"); 71 | if ($selected.length > 0) { 72 | previousSelectionText = $selected.first().text(); 73 | previousSelectionKey = $selected.first().data("key"); 74 | } 75 | 76 | $(listElement).empty(); 77 | var count = 0; 78 | $.each(listData, function (key, value) { 79 | var data = value; 80 | var objectDisplayName = data["Text"]; 81 | 82 | verbsArray.push(data); 83 | 84 | if (true) { 85 | var $newItem = $("
  • ").data("key", key).data("elementid", data["ElementId"]).data("elementname", data["ElementName"]).data("index", count).html(objectDisplayName); 86 | if (objectDisplayName == previousSelectionText && key == previousSelectionKey) { 87 | $newItem.addClass("ui-selected"); 88 | foundPreviousSelection = true; 89 | updateVerbButtons($newItem, verbsArray, idPrefix); 90 | } 91 | $(listElement).append($newItem); 92 | count++; 93 | } 94 | }); 95 | 96 | var selectSize = count; 97 | if (selectSize < 3) selectSize = 3; 98 | if (selectSize > 12) selectSize = 12; 99 | $(listElement).attr("size", selectSize); 100 | 101 | if (!foundPreviousSelection) { 102 | for (var i = 1; i <= verbButtonCount; i++) { 103 | var target = $("#" + buttonPrefix + i); 104 | target.hide(); 105 | } 106 | } 107 | } 108 | 109 | 110 | ]]> 111 |
  • 112 | 113 | 114 | 115 | //Log ("in InitInv2") 116 | //OutputTextNoBr(Replace(inv2_object.javascriptstuff, "####", label)) 117 | JS.addScript(Replace(inv2_object.javascriptstuff, "####", label)) 118 | 119 | 120 | 121 | 122 | SetInv2(GetDirectChildren(game.secondinventoryholder)) 123 | 124 | 125 | 126 | "") { 140 | verbs = verbs + "," 141 | } 142 | verbs = verbs + "\"" + verb + "\"" 143 | } 144 | if (s <> "") { 145 | s = s + ", " 146 | } 147 | if (HasString(o, "listalias")) { 148 | s2 = Replace(o.listalias, "\"", "\\\"") 149 | } 150 | else { 151 | s2 = GetDisplayAlias(o) 152 | } 153 | s = s + "\"k" + count + "\": {\"Text\":\"" + s2 + "\",\"Verbs\":[" + verbs + "],\"ElementId\":\"" + o.name + "\",\"ElementName\":\"" + GetDisplayAlias(o) + "\"}" 154 | //s = s + "\"k" + count + "\": {\"Text\":\"" + GetDisplayAlias(o) + "\",\"Verbs\":[" + verbs + "],\"ElementId\":\"" + o.name + "\",\"ElementName\":\"" + GetDisplayAlias(o) + "\"}" 155 | count = count + 1 156 | } 157 | s = "{" + s + "}" 158 | JS.updateInventory2("Inventory2", s) 159 | ]]> 160 |
    161 | -------------------------------------------------------------------------------- /StackLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 19 | 20 | 21 | 22 | 26 | 56 | 57 | 58 | 62 | 65 | 66 | 70 | 73 | 74 | 78 | 81 | 82 | 86 | 89 | 90 | 91 | 95 | 98 | 99 | 100 | 107 | 131 | 132 | 143 | 144 | 145 | 146 | 154 | 155 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 170 | 171 | if (HasScript(obj, att)) { 172 | do (obj, att) 173 | } 174 | if (HasString(obj, att)) { 175 | msg (GetString(obj, att)) 176 | } 177 | 178 | 179 | 180 | 181 | 182 | game 183 | false 184 | 185 | Unstack (this) 186 | 187 | 188 | UseInStack (this) 189 | 190 | 191 | ConsumeInStack (this) 192 | 193 | 194 | LookInStack (this) 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | false 206 | You take it. 207 | 208 | if (this.alias = null) { 209 | this.alias = this.name 210 | } 211 | container = this.stackparent 212 | 213 | this.parent = container 214 | SetStack(container) 215 | if (this.takemsg = null) { 216 | msg(DynamicTemplate("TakeSuccessful", object)) 217 | } 218 | else { 219 | msg (this.takemsg) 220 | } 221 | 222 | 223 | 224 | 225 | false 226 | 1 227 | You take it. 228 | 229 | this.parent = null 230 | game.pov.money = game.pov.money + this.money 231 | if (this.takemsg = null) { 232 | msg(DynamicTemplate("TakeSuccessful", object)) 233 | } 234 | else { 235 | msg (this.takemsg) 236 | } 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | _ObjectEditor 247 | Stackable 248 | editor_room; editor_player 249 | 250 | 251 | dropdowntypes 252 | *=Not stackable; stack_container=Heterogeneous stack; homo_stack_container=Homogeneous stack;childstack_object=Member of a stack;cash_object=Pile of cash 253 | Stack 254 | 255 | 256 | 257 | objects 258 | stackparent 259 | childstack_object 260 | Stack container 261 | 262 | 263 | 264 | number 265 | money 266 | cash_object 267 | Amount 268 | 269 | 270 | 271 | 272 | 273 | -------------------------------------------------------------------------------- /LockDemo.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ac0b3225-36cd-43ab-b1fc-eb4cdc4af74e 7 | 1.0 8 | 2016 9 | 10 | false 11 | 12 | 13 | 14 | The Pixie 15 | 16 | 17 | msg ("Your race is {if player.race=dragon-descended:dragon}.") 18 | msg ("You have {if player.scales=True:scales}.") 19 | msg ("You have {if player.scales=True:{if player.race=dragon-descended:dragon }scales}.") 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | An ornate room devoid of lights. 28 | Lounge 29 | 30 | 31 | 32 | weak 33 | The door is closed. 34 | 35 | 36 | 37 | 38 | 39 | 40 | 1 41 | Door 42 | brass key 43 | door 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | By a gravestone. That is what it looks like! 52 | Kitchen 53 | 54 | 55 | 56 | 0 57 | 0 58 | 59 | 60 | strength 61 | 62 | 63 | 64 | charisma 65 | 66 | 67 | 68 | dragon-descended 69 | 70 | 71 | 72 | 73 | 74 | The door is closed. 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 1 86 | silver key 87 | 88 | 89 | 90 | 91 | 1 92 | 93 | false 94 | false 95 | Door 96 | brass key 97 | door2 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | do (this, "findexits") 128 | if (this.locked) { 129 | if (this.autounlock and AllKeysAvailable(this)) { 130 | do (this, "unlock") 131 | if (not this.isopen) { 132 | OpenCloseDoors (this, true) 133 | } 134 | } 135 | else { 136 | msg (DynamicTemplate("LockedObject", this)) 137 | } 138 | } 139 | else { 140 | OpenCloseDoors (this, true) 141 | } 142 | 143 | 144 | do (this, "findexits") 145 | if (this.locked) { 146 | msg (DynamicTemplate("LockedObject", this)) 147 | } 148 | else { 149 | CloseObject (this) 150 | this.blocks.locked = true 151 | if (not this.matches = null) { 152 | this.matches.isopen = false 153 | this.matches.blocks.locked = true 154 | } 155 | } 156 | 157 | 158 | do (this, "findexits") 159 | if (this.locked) { 160 | msg (DynamicTemplate("AlreadyLocked", this)) 161 | } 162 | else if (this.isopen and not this.canlockopen) { 163 | msg (DynamicTemplate("CannotLockOpen", this)) 164 | } 165 | else { 166 | if (AllKeysAvailable(this)) { 167 | msg (this.lockmessage) 168 | this.locked = true 169 | if (not this.matches = null) { 170 | this.matches.locked = true 171 | } 172 | } 173 | else { 174 | msg (this.nokeymessage) 175 | } 176 | } 177 | 178 | 179 | do (this, "findexits") 180 | if (not this.locked) { 181 | msg (DynamicTemplate("AlreadyUnlocked", this)) 182 | } 183 | else { 184 | if (AllKeysAvailable(this)) { 185 | msg (this.unlockmessage) 186 | this.locked = false 187 | if (not this.matches = null) { 188 | this.matches.locked = false 189 | } 190 | if (this.autoopen and not this.isopen) { 191 | TryOpenClose (true, this) 192 | if (not this.matches = null) { 193 | this.matches.isopen = true 194 | } 195 | } 196 | } 197 | else { 198 | msg (this.nokeymessage) 199 | } 200 | } 201 | 202 | 203 | // Used internally by this door only 204 | if (HasString(object, "openmsg")) { 205 | msg (object.openmsg) 206 | } 207 | else { 208 | msg (DynamicTemplate("OpenSuccessful", object)) 209 | } 210 | OpenCloseDoors (this, true) 211 | 212 | 213 | // Used internally by this door only 214 | if (HasString(object, "closemsg")) { 215 | msg (object.closemsg) 216 | } 217 | else { 218 | msg (DynamicTemplate("CloseSuccessful", object)) 219 | } 220 | OpenCloseDoors (this, false) 221 | 222 | 223 | if (this.blocks = null) { 224 | if (this.matches = null) { 225 | error ("No \"matches\" attribute set for " + this.name) 226 | } 227 | exit = GetExitByLink (this.parent, this.matches.parent) 228 | if (exit = null) { 229 | error ("No exit found from " + this.name + " to " + this.matches.name) 230 | } 231 | this.blocks = GetObject(exit) 232 | exit = GetExitByLink (this.matches.parent, this.parent) 233 | if (exit = null) { 234 | error ("No exit found to " + this.name + " from " + this.matches.name) 235 | } 236 | this.matches.blocks = GetObject(exit) 237 | this.matches.matches = this 238 | } 239 | 240 | 241 | 242 | door.isopen = open 243 | door.blocks.locked = not open 244 | if (not door.matches = null) { 245 | door.matches.isopen = open 246 | door.matches.blocks.locked = not open 247 | } 248 | 249 | -------------------------------------------------------------------------------- /weather.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 676a1c90-ef6b-4fbe-85f8-8330b299c907 8 | 1.1 9 | 2017 10 | false 11 | 2 12 | 0 13 | 14 | false 15 | 0 16 | false 17 | false 18 | false 19 | White 20 | White 21 | false 22 | false 23 | 24 | Black 25 | Cyan 26 | false 27 | 28 | game.currentweather = pre_thunder 29 | 30 | 31 | WeatherReport 32 | 33 | false 34 | 35 | 36 | 37 | 38 | The hut 39 | This hut is nice and dry. 40 | false 41 | 42 | 43 | 44 | 45 | 46 | soaking 47 | 48 | 49 | 50 | 0 51 | 100 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | It is vert hot, there is not a cloud in the sky. 65 | -10 66 | 5) 68 | ]]> 69 | 5) 71 | ]]> 72 | 73 | 74 | It is not quite so hot 75 | 76 | 77 | 78 | Thunder clouds are rolling in. 79 | 80 | 81 | 82 | 83 | 84 | It is hot, no clouds above. 85 | -5 86 | 87 | game.weathertochange = RandomChance(game.weathercount) 88 | 89 | 90 | game.weathertochange = RandomChance(game.weathercount) 91 | 92 | 93 | 94 | It is getting very hot. 95 | 96 | 97 | 98 | It is getting milder. 99 | 100 | 101 | 102 | 103 | 104 | It is warm, the sky is cloudless 105 | -2 106 | 107 | 108 | 109 | game.weathertochange = RandomChance(game.weathercount * 5) 110 | 111 | 112 | 113 | It is starting to get warm. 114 | 115 | 116 | 117 | 118 | 119 | Dark clouds cover the sky. 120 | 121 | game.weathertochange = RandomChance(10*game.weathercount) 122 | 123 | 124 | 125 | The threatened thunder seems to have passed. 126 | 127 | 128 | 129 | You feel a few spots of rain. 130 | 131 | 132 | 133 | 134 | 135 | 1 136 | Dark clouds covetr the sky, and big drops of rain are falling. 137 | 2) 139 | ]]> 140 | 141 | 142 | The heavens open, and rain comes down in sheets! 143 | 144 | 145 | 146 | 147 | 148 | 15 149 | It is raining hard, the sky is black. 150 | 151 | 152 | You think the rain is easing off a bit. 153 | 154 | 155 | 156 | A sudden crack of lightning. 157 | 158 | 159 | 160 | 161 | 162 | 6 163 | It is raining. 164 | 165 | 166 | The rain has stopped. 167 | 168 | 169 | 170 | 171 | 172 | 15 173 | It is raining hard, the sky is black. 174 | 175 | game.weathercount = true 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | It is hot and humid; you feel a storm is coming. 185 | 0 186 | 5) 188 | ]]> 189 | 190 | 191 | A few spots of rain are starting to fall. 192 | 193 | 194 | 195 | 196 | 197 | Deep in the forest, the track from the north just stops. 198 | The forest 199 | 200 | 201 | You wander back through the trees. 202 | 203 | 204 | 205 | 206 | A clearing in the forest. To the north is a hut. 207 | A clearing 208 | 209 | 210 | 211 | 212 | 213 | 214 | You walk into he deep forest. 215 | 216 | 217 | 218 | 219 | 222 | 223 | 224 | 225 | quests 226 | speak to Mary 227 | south 228 | south 229 | take apple 230 | quests 231 | north 232 | north 233 | give apple to mary 234 | quests 235 | 236 | 237 | -------------------------------------------------------------------------------- /empire/lib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 52 | 53 | 54 | 55 | 56 | administrate 57 | administrate 58 | "You can't administrate " + object.article + "." 59 | 60 | 61 | increase 62 | increase 63 | "You can't increase " + object.article + "." 64 | 65 | 66 | decrease 67 | decrease 68 | "You can't decrease " + object.article + "." 69 | 70 | 71 | construct 72 | construct 73 | "You can't construct " + object.article + "." 74 | 75 | 76 | condemn 77 | condemn 78 | "You can't condemn " + object.article + "." 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | wait;next;next turn;turn 88 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 0 126 | 0 127 | 0 128 | 129 | Name: " + this.alias) 131 | msg ("Progress: " + this.progress) 132 | msg ("Annual commitment: " + this.commit) 133 | msg ("Discoveries: " + this.count) 134 | msg ("Description: " + this.text) 135 | ]]> 136 | 137 | " + this.alias + " is increased 10 points (now " + this.commit + ").") 140 | if (this.commit = 10) this.displayverbs = Split("Look at|Increase|Decrease", "|") 141 | ]]> 142 | 143 | " + this.alias + " is decreased 10 points (now " + this.commit + ").") 146 | if (this.commit = 0) this.displayverbs = Split("Look at|Increase", "|") 147 | ]]> 148 | 149 | 150 | Look at 151 | Increase 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | false 160 | 999999 161 | 0 162 | Name: " + this.alias) 164 | if (this.economy > 0) { 165 | msg ("Income: " + this.economy) 166 | } 167 | else { 168 | msg ("Maintenance: " + (-this.economy)) 169 | } 170 | msg ("Description: " + this.text) 171 | ]]> 172 | 173 | 174 | 175 | 176 | 177 | 178 | 1 179 | 180 | Name: " + this.prototype.alias) 182 | msg ("Count: " + this.count) 183 | msg ("Economy: " + (this.count * this.prototype.economy)) 184 | msg ("Description: " + this.text) 185 | ]]> 186 | 187 | " + this.alias + " has been constructed on " + this.parent.alias + " for " + this.prototype.cost + " credits!") 190 | player.credits = player.credits - this.prototype.cost 191 | if (this.count = 1) this.displayverbs = Split("Look at|Construct|Condemn", "|") 192 | ]]> 193 | 194 | " + this.alias + " has been demolished on " + this.parent.alias + " for " + (this.prototype.cost/10) + " credits.") 197 | player.credits = player.credits - this.prototype.cost / 10 198 | if (this.count = 0) this.displayverbs = Split("Look at|Construct", "|") 199 | ]]> 200 | 201 | 202 | 203 | 204 | 205 | 206 | Look at 207 | Administrate 208 | 209 | 210 | Name: " + this.alias) 212 | msg ("Star type: " + this.colour) 213 | msg ("Description: " + this.text) 214 | economy = 0 215 | building_count = 0 216 | foreach (o, GetDirectChildren(this)) { 217 | msg ("" + o.prototype.alias + ": " + o.count) 218 | building_count = building_count + o.count 219 | economy = economy + o.count * o.prototype.economy 220 | } 221 | msg ("Economy: " + economy) 222 | ]]> 223 | 224 | 225 | player.parent = this 226 | 227 | 228 | 229 | 230 | 231 | 232 | colours = Split("Red,White,Cyan,Blue,DarkBlue,LightBlue,Orange,Purple,Yellow,Lime,Green,Magenta", ",") 233 | for (i, 1, n) { 234 | create("star_" + i, "starsystem") 235 | o = GetObject("star_" + i) 236 | o.x = GetRandomInt(-300, 300) 237 | o.y = GetRandomInt(-300, 300) 238 | o.id = i 239 | o.alias = "Star " + i 240 | o.colour = StringListItem(colours, GetRandomInt(0, 11)) 241 | o.parent = maproom 242 | o.owned = false 243 | o.text = "none" 244 | } 245 | 246 | 247 | 248 | 249 | 250 | 251 | _ObjectEditor 252 | Empire 253 | editor_room; defaultplayer 254 | 255 | 256 | 257 | 258 | 259 | dropdowntypes 260 | Type 261 | *=None; discovery=Discovery; researcharea=Research area 262 | 150 263 | 264 | 265 | 266 | 267 | 268 | richtext 269 | Description 270 | text 271 | researcharea;discovery 272 | 273 | 274 | 275 | 276 | number 277 | Discovered at 278 | progress 279 | discovery 280 | 281 | 282 | 283 | number 284 | Size 285 | size 286 | discovery 287 | 288 | 289 | 290 | number 291 | Cost 292 | cost 293 | discovery 294 | 295 | 296 | 297 | number 298 | Economy (annual addition - or loss - to the empire's credits) 299 | economy 300 | discovery 301 | 302 | 303 | 304 | 305 | Type 306 | dropdown 307 | discoverytype 308 | Building;Vessel;Primary weapon;Secondary weapon;Turret;FTL engine;Sub-light engine;Sensor;Cloak;Other 309 | discovery 310 | 311 | 312 | 313 | script 314 | Script to run when added to a ship design 315 | effect 316 | discovery 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | -------------------------------------------------------------------------------- /LiftLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 19 | 20 | 21 | 22 | 23 | 24 | press 25 | press;push 26 | "You can't press " + object.article + "." 27 | 28 | 29 | 30 | 31 | 32 | 33 | 1 34 | 0 35 | false 36 | The lift ascends to ###. 37 | The lift descends to ###. 38 | 39 | Nothing happens. Perhaps because you are already on ###. 40 | 41 | oldvalue = this.last_floor 42 | currentvalue = this.current_floor 43 | change = oldvalue - currentvalue 44 | if (game.gridmap) { 45 | thisdict = DictionaryItem(player.grid_coordinates, this.name) 46 | if (Grid_GetRoomBooleanForPlayer(game.pov, this, "grid_isdrawn")) { 47 | dictionary remove (thisdict, "z") 48 | dictionary add (thisdict, "z", currentvalue*1.0+change) 49 | Grid_CalculateMapCoordinates (this, game.pov) 50 | Grid_Redraw //THIS CLEARS ANY GRID FILLS! 51 | Grid_DrawPlayerInRoom (game.pov.parent) 52 | } 53 | } 54 | 55 | 56 | LeavingTheLift(this) 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | Press 65 | 1 66 | You press the button. 67 | 68 | if (HasString(this, "lockedmessage")) { 69 | msg (this.lockedmessage) 70 | } 71 | else { 72 | _PressButton(this, false) 73 | } 74 | 75 | 76 | // Invoke this to have the lift move to this button's destination 77 | // without any text appearing. The Arrival function is not called 78 | _PressButton(this, true) 79 | 80 | 81 | 82 | 83 | true 84 | 99 | 100 | 101 | 102 | 103 | exit = ObjectListItem (ScopeExitsForRoom (button.parent), 0) 104 | current = exit.to 105 | current_button = null 106 | foreach (o, GetDirectChildren(button.parent)) { 107 | if (o.destination = current) current_button = o 108 | } 109 | if (exit.to = button.destination) { 110 | moved = false 111 | s = button.parent.samefloor 112 | } 113 | else { 114 | moved = true 115 | button.parent.last_floor = button.parent.current_floor 116 | exit.to = button.destination 117 | if (button.parent.current_floor > button.floor) { 118 | s = button.parent.goingdown 119 | } 120 | else { 121 | s = button.parent.goingup 122 | } 123 | button.parent.current_floor = button.floor 124 | if (not current_button = null) { 125 | if (HasString(current_button, "departure")) { 126 | s = current_button.departure + " " + s 127 | } 128 | } 129 | if (HasString(button, "arrival")) { 130 | s = s + " " + button.arrival 131 | } 132 | button.parent.usage_count = button.parent.usage_count + 1 133 | } 134 | // prepend the button pressing message 135 | s = button.pressmsg + " " + s 136 | // Swap ### for the floor name 137 | if (HasString(button, "floorname")) { 138 | s = Replace (s, "###", ToString (button.floorname)) 139 | } 140 | else { 141 | s = Replace (s, "###", "floor " + button.floor) 142 | } 143 | if (not silently) { 144 | Arrival(button, s, moved) 145 | } 146 | 147 | 148 | 149 | 150 | 151 | 152 | 158 | 159 | msg(s) 160 | 161 | 162 | 163 | 164 | if (not lift.leavingmsg = "") { 165 | msg (lift.leavingmsg) 166 | } 167 | 168 | 169 | 170 | 171 | if (DoesInherit(button, "liftroom")) { 172 | return (button) 173 | } 174 | return (button.parent) 175 | 176 | 177 | 178 | return (ObjectListItem (ScopeExitsForRoom (LiftRoom(button)), 0)) 179 | 180 | 181 | 182 | exit = LiftExit(button) 183 | return (exit.to) 184 | 185 | 186 | 187 | current = LiftCurrentFloor(button) 188 | current_button = null 189 | foreach (o, GetDirectChildren(LiftRoom(button))) { 190 | if (o.destination = current) current_button = o 191 | } 192 | return (current_button) 193 | 194 | 195 | 196 | ol = NewObjectList() 197 | foreach (o, GetDirectChildren(LiftRoom(button))) { 198 | if (DoesInherit(o, "liftbutton")) list add(ol, o) 199 | } 200 | return (ol) 201 | 202 | 203 | 204 | ol = NewObjectList() 205 | foreach (o, LiftAllButtons(button)) { 206 | list add(ol, GetObject(GetExitByLink (o.destination, LiftRoom(button)))) 207 | } 208 | return (ol) 209 | 210 | 211 | 212 | return (GetObject(GetExitByLink (LiftCurrentFloor(button), LiftRoom(button)))) 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | _ObjectEditor 226 | Lift 227 | defaultplayer 228 | 229 | 230 | dropdowntypes 231 | Type 232 | *=None; liftroom=Lift; liftbutton=Lift Button; liftentrance=Lift Entrance 233 | 150 234 | 235 | 236 | 237 | textbox 238 | Same floor message 239 | samefloor 240 | liftroom 241 | 242 | 243 | 244 | textbox 245 | The going up message 246 | goingup 247 | liftroom 248 | 249 | 250 | 251 | textbox 252 | The going down message 253 | goingdown 254 | liftroom 255 | 256 | 257 | 258 | textbox 259 | The leaving message 260 | leavingmsg 261 | liftroom 262 | 263 | 264 | 265 | checkbox 266 | Lock exit after entering lift 267 | lockexits 268 | liftroom 269 | 270 | 271 | 272 | textbox 273 | Departure message 274 | departure 275 | editor_room 276 | liftbutton 277 | 278 | 279 | 280 | textbox 281 | Arrival message 282 | arrival 283 | liftbutton 284 | 285 | 286 | 287 | textbox 288 | Press message 289 | pressmsg 290 | liftbutton 291 | 292 | 293 | 294 | textbox 295 | Floor name 296 | floorname 297 | liftbutton 298 | 299 | 300 | 301 | textbox 302 | Locked message 303 | lockedmessage 304 | liftbutton 305 | 306 | 307 | 308 | 309 | objects 310 | Destination 311 | destination 312 | liftbutton 313 | 314 | 315 | 316 | number 317 | Floor 318 | floor 319 | 100 320 | liftbutton 321 | 322 | 323 | 324 | -------------------------------------------------------------------------------- /EnhancedIt.aslx: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 27 | 28 | 29 | 30 | 31 | 32 | 45 | 46 | 47 | = maxstrength and strength>0) { 62 | match = ScriptDictionaryItem(dictionary, keywords) 63 | maxstrength = strength 64 | } 65 | } 66 | if (match <> null) { 67 | parameters = NewObjectDictionary() 68 | dictionary add (parameters, "this", object) 69 | invoke (match, parameters) 70 | handled = true 71 | } 72 | } 73 | if (not handled) { 74 | if (HasScript(object, defaultscript)) { 75 | d = NewDictionary() 76 | dictionary add (d, "text", text) 77 | do (object, defaultscript, d) 78 | } 79 | else { 80 | msg (DynamicTemplate(defaulttemplate, object)) 81 | } 82 | } 83 | } 84 | ]]> 85 | 86 | 0) { 92 | // Pop next variable off the queue 93 | var = StringListItem(game.pov.currentcommandvarlistqueue, 0) 94 | if (queuelength = 1) { 95 | game.pov.currentcommandvarlistqueue = null 96 | } 97 | else { 98 | newqueue = NewStringList() 99 | for (i, 1, queuelength - 1) { 100 | list add (newqueue, StringListItem(game.pov.currentcommandvarlistqueue, i)) 101 | } 102 | game.pov.currentcommandvarlistqueue = newqueue 103 | } 104 | // Resolve variable 105 | value = StringDictionaryItem(game.pov.currentcommandvarlist, var) 106 | if (value <> "") { 107 | result = null 108 | resolvinglist = false 109 | // This is to resolve issue 626 110 | if (StartsWith(var, "objectexit")) { 111 | result = ResolveName(var, value, "exit") 112 | } 113 | if (result = null) { 114 | if (StartsWith(var, "object")) { 115 | if (GetBoolean(game.pov.currentcommandpattern, "allow_all")) { 116 | scope = FilterByAttribute(GetScope("object", "", "object"), "scenery", false) 117 | game.pov.currentcommandpendingobjectscope = ListExclude(scope, FilterByAttribute(scope, "not_all", true)) 118 | game.pov.currentcommandpendingvariable = var 119 | ResolveNameList (value, "object") 120 | resolvinglist = true 121 | } 122 | else if (HasScript(game.pov.currentcommandpattern, "multipleobjects")) { 123 | game.pov.currentcommandpendingobjectlist = NewObjectList() 124 | game.pov.currentcommandpendingvariable = var 125 | do (game.pov.currentcommandpattern, "multipleobjects") 126 | ResolveNameList (value, "object") 127 | resolvinglist = true 128 | } 129 | else { 130 | result = ResolveName(var, value, "object") 131 | } 132 | } 133 | else if (StartsWith(var, "exit")) { 134 | result = ResolveName(var, value, "exit") 135 | } 136 | else if (StartsWith(var, "text")) { 137 | result = StringDictionaryItem(game.pov.currentcommandvarlist, var) 138 | } 139 | else { 140 | error ("Unhandled command variable '" + var + "' - command variable names must begin with 'object', 'exit' or 'text'") 141 | } 142 | } 143 | // at this point, ResolveName has returned - either an object name, unresolved, or pending 144 | if (result = null) { 145 | if ((not resolvinglist) and LengthOf(GetString(game.pov, "currentcommandpendingvariable")) = 0) { 146 | UnresolvedCommand (value, var) 147 | } 148 | } 149 | else { 150 | AddToResolvedNames (var, result) 151 | } 152 | } 153 | else { 154 | ResolveNextName 155 | } 156 | } 157 | else { 158 | resolvedall = true 159 | } 160 | } 161 | else if (queuetype = "null") { 162 | resolvedall = true 163 | } 164 | else { 165 | error ("Invalid queue type") 166 | } 167 | if (resolvedall) { 168 | // This is the only bit changed, next ten lines 169 | foreach (obj, game.pov.currentcommandresolvedobjects) { 170 | if (obj.gender in game.lastobjects) { 171 | dictionary remove (game.lastobjects, obj.gender) 172 | } 173 | dictionary add (game.lastobjects, obj.gender, obj) 174 | if (obj.article in game.lastobjects) { 175 | dictionary remove (game.lastobjects, obj.article) 176 | } 177 | dictionary add (game.lastobjects, obj.article, obj) 178 | if (obj.possessive in game.lastobjects) { 179 | dictionary remove (game.lastobjects, obj.possessive) 180 | } 181 | dictionary add (game.lastobjects, obj.possessive, obj) 182 | } 183 | if (not DictionaryContains(game.pov.currentcommandresolvedelements, "multiple")) { 184 | dictionary add (game.pov.currentcommandresolvedelements, "multiple", false) 185 | } 186 | if (not GetBoolean(game.pov.currentcommandpattern, "isundo")) { 187 | if (LengthOf(game.pov.currentcommand) > 0) { 188 | start transaction (game.pov.currentcommand) 189 | } 190 | } 191 | if (not GetBoolean(game.pov.currentcommandpattern, "isoops")) { 192 | // TO DO: game.unresolved* should be game.pov.unresolved* 193 | game.unresolvedcommand = null 194 | game.unresolvedcommandvarlist = null 195 | game.unresolvedcommandkey = null 196 | } 197 | if (HasScript(game.pov.currentcommandpattern, "script")) { 198 | // This is the bit that actually runs the commands 199 | do (game.pov.currentcommandpattern, "script", game.pov.currentcommandresolvedelements) 200 | } 201 | HandleNextCommandQueueItem 202 | } 203 | ]]> 204 | 205 | 206 | null) { 214 | foreach (altname, obj.alt) { 215 | CompareNames (LCase(altname), value, obj, fullmatches, partialmatches) 216 | } 217 | } 218 | } 219 | // allow referring to objects from the previous command by gender or article 220 | // This is the only bit changed. 221 | if (objtype = "object") { 222 | foreach (key, game.lastobjects) { 223 | CompareNames (key, value, ObjectDictionaryItem(game.lastobjects, key), fullmatches, partialmatches) 224 | } 225 | } 226 | // Also check the secondary scope, but only if we have not found anything yet 227 | if (ListCount(fullmatches) = 0 and ListCount(partialmatches) = 0 and not secondaryscope = null) { 228 | foreach (obj, secondaryscope) { 229 | name = LCase(GetDisplayAlias(obj)) 230 | CompareNames (name, value, obj, fullmatches, partialmatches) 231 | if (obj.alt <> null) { 232 | foreach (altname, obj.alt) { 233 | CompareNames (LCase(altname), value, obj, fullmatches, partialmatches) 234 | } 235 | } 236 | } 237 | } 238 | if (ListCount(fullmatches) = 1) { 239 | return (ListItem(fullmatches, 0)) 240 | } 241 | else if (ListCount(fullmatches) = 0 and ListCount(partialmatches) = 1) { 242 | return (ListItem(partialmatches, 0)) 243 | } 244 | else if (ListCount(fullmatches) + ListCount(partialmatches) = 0) { 245 | return (null) 246 | } 247 | else { 248 | candidates = ListCompact(fullmatches + partialmatches) 249 | if (LengthOf(variable) > 0) { 250 | // single object command, so after showing the menu, add the object to game.pov.currentcommandresolvedelements 251 | game.pov.currentcommandpendingvariable = variable 252 | ShowMenu (DynamicTemplate("DisambiguateMenu", value), candidates, true) { 253 | varname = game.pov.currentcommandpendingvariable 254 | game.pov.currentcommandpendingvariable = null 255 | if (result <> null) { 256 | AddToResolvedNames (varname, GetObject(result)) 257 | } 258 | } 259 | } 260 | else { 261 | // multi-object command, so after showing the menu, add the object to the list 262 | game.pov.currentcommandmultiobjectpending = true 263 | ShowMenu (DynamicTemplate("DisambiguateMenu", value), candidates, true) { 264 | if (result <> null) { 265 | list add (game.pov.currentcommandpendingobjectlist, GetObject(result)) 266 | ResolveNextNameListItem 267 | } 268 | } 269 | } 270 | return (null) 271 | } 272 | ]]> 273 | -------------------------------------------------------------------------------- /third_past.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 19 | 20 | 21 | 22 | 23 | 24 | "{=CapFirst(player.alias)} dropped " + object.article + "." 25 | 26 | 27 | 28 | "{=CapFirst(player.alias)} picked " + object.article + " up." 29 | "{=CapFirst(player.gender)} can't take " + object.article + "." 30 | WriteVerb(object, "be") + " too heavy to be taken." 31 | "{=CapFirst(player.alias)} could not carry any more items." 32 | "{=CapFirst(player.alias)} could not put more items in " + object.article + "." 33 | "{=CapFirst(player.gender)} could not drop " + object.article + "." 34 | "{=CapFirst(player.gender)} could not put " + object.article + " there." 35 | "{=CapFirst(player.gender)} was already carrying " + object.article + "." 36 | "{=CapFirst(player.gender)} was not carrying " + object.article + "." 37 | "{=CapFirst(player.gender)} could not use " + object.article + "." 38 | "{=CapFirst(player.gender)} could not give " + object.article + "." 39 | WriteVerb(object, "say") + " nothing." 40 | 41 | 42 | 43 | "{=CapFirst(player.gender)} could not open " + object.article + "." 44 | "{=CapFirst(player.gender)} could not close " + object.article + "." 45 | "{=CapFirst(player.alias)} opened " + object.article + "." 46 | "{=CapFirst(player.alias)} closed " + object.article + "." 47 | 48 | 49 | 50 | 51 | "{=CapFirst(player.gender)} could not lock " + object.article + " when " + object.gender + " " + Conjugate(object, "be") + " open." 52 | "{=CapFirst(player.alias)} switched " + object.article + " on." 53 | "{=CapFirst(player.alias)} switched " + object.article + " off." 54 | "{=CapFirst(player.alias)} ate " + object.article + "." 55 | "{=CapFirst(player.alias)} was looking " + text +"." 56 | "It was too dark to make anything out." 57 | 58 | 59 | 60 | 61 | 62 | 63 | "{=CapFirst(player.alias)} put " + object.article + " on." 64 | "{=CapFirst(player.gender)} can't wear " + object.article + "." 65 | "{=CapFirst(player.gender)} would need to get " + object.article + " before {player.gender} can put " + object.article + " on." 66 | "{=CapFirst(player.gender)} would need to get " + object.article + " before {player.gender} can take " + object.article + " off." 67 | "{=CapFirst(player.gender)} are already wearing " + object.article + "." 68 | "{=CapFirst(player.gender)} are not wearing " + object.article + "." 69 | "{=CapFirst(player.gender)} cannot remove " + object.article + "!" 70 | "{=CapFirst(player.gender)} cannot wear that over " + GetDisplayGarment(object) + "." 71 | "{=CapFirst(player.gender)} cannot wear that while wearing " + GetDisplayGarment(object) + "." 72 | "{=CapFirst(player.alias)} take " + object.article + " off." 73 | "{=CapFirst(player.gender)} can't remove that while wearing " + GetDisplayGarment(object) + "." 74 | 75 | 76 | "{=CapFirst(player.gender)} could not buy " + object.article + "." 77 | "{=CapFirst(player.gender)} could not climb " + object.article + "." 78 | "{=CapFirst(player.gender)} could not drink " + object.article + "." 79 | "{=CapFirst(player.gender)} could not eat " + object.article + "." 80 | WriteVerb(object1, "do") + " not want " + object2.article + "." 81 | "{=CapFirst(player.gender)} could not hit " + object.article + "." 82 | "{=CapFirst(player.gender)} could not kill " + object.article + "." 83 | "{=CapFirst(player.gender)} could not kiss " + object.article + "." 84 | "{=CapFirst(player.gender)} could not knock " + object.article + "." 85 | "{=CapFirst(player.gender)} could not lick " + object.article + "." 86 | "{=CapFirst(player.gender)} could not lie on " + object.article + "." 87 | "{=CapFirst(player.gender)} listened, but " + object.gender + " made no sound." 88 | "{=CapFirst(player.gender)} could not lock " + object.article + "." 89 | "{=CapFirst(player.gender)} could not move " + object.article + "." 90 | "{=CapFirst(player.gender)} could not pull " + object.article + "." 91 | "{=CapFirst(player.gender)} could not push " + object.article + "." 92 | "{=CapFirst(player.gender)} could not read " + object.article + "." 93 | "{=CapFirst(player.gender)} could not search " + object.article + "." 94 | "{=CapFirst(player.gender)} could not show " + object.article + "." 95 | "{=CapFirst(player.gender)} could not sit on " + object.article + "." 96 | "{=CapFirst(player.gender)} sniffed, but " + object.gender + " did not smell of much." 97 | "{=CapFirst(player.gender)} could not taste " + object.article + "." 98 | "{=CapFirst(player.gender)} could not throw " + object.article + "." 99 | "{=CapFirst(player.gender)} could not tie " + object.article + "." 100 | "{=CapFirst(player.gender)} could not touch " + object.article + "." 101 | "{=CapFirst(player.gender)} could not turn " + object.article + " on." 102 | "{=CapFirst(player.gender)} could not turn " + object.article + " off." 103 | "{=CapFirst(player.gender)} could not turn " + object.article + "." 104 | "{=CapFirst(player.gender)} could not unlock " + object.article + "." 105 | "{=CapFirst(player.gender)} could not untie " + object.article + "." 106 | "{=CapFirst(player.gender)} could not use " + object2.article + " that way." 107 | "{=CapFirst(player.gender)} could not wear " + object.article + "." 108 | 109 | 110 | 111 | 112 | 113 | 114 | gender = obj.gender 115 | if (gender = "he" or gender = "she") { 116 | gender = "it" 117 | } 118 | switch (verb) { 119 | case ("be") { 120 | switch (gender) { 121 | case ("you") { 122 | return ("were") 123 | } 124 | case ("we") { 125 | return ("were") 126 | } 127 | case ("they") { 128 | return ("were") 129 | } 130 | default { 131 | return ("was") 132 | } 133 | } 134 | } 135 | case ("do") { 136 | return ("did") 137 | } 138 | default { 139 | if (EndsWith(verb, "e")) { 140 | return (verb + "d") 141 | } 142 | else { 143 | return (verb + "ed") 144 | } 145 | } 146 | } 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /StackDemo.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | a9bfdc45-5714-4f08-a962-4de554d5123c 8 | 1.0 9 | 2013 10 | 11 | false 12 | false 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Funny yellow potion 24 | It's a yellow potion. (It's also a child of the 'blue potion' of the 'potions' stack.) 25 | 26 | 27 | 28 | Look at 29 | Drink 30 | Take 31 | 32 | 33 | potion_stack 34 | 35 | msg ("You drink the potion and recover 10% health.") 36 | player.health = player.health + 10 37 | destroy (this.name) 38 | 39 | 40 | 41 | 42 | 43 | Yellow potion 44 | It's a yellow potion. (It's also a child of the 'blue potion' of the 'potions' stack.) 45 | 46 | 47 | 48 | Look at 49 | Drink 50 | Take 51 | 52 | potion_stack 53 | 54 | msg ("You drink the potion and recover 10% health.") 55 | player.health = player.health + 10 56 | destroy (this.name) 57 | 58 | 59 | 60 | 61 | 62 | Yellow potion 63 | It's a yellow potion. (It's also a child of the 'blue potion' of the 'potions' stack.) 64 | 65 | 66 | 67 | 68 | Look at 69 | Drink 70 | Take 71 | 72 | potion_stack 73 | 74 | msg ("You drink the potion and recover 10% health.") 75 | player.health = player.health + 10 76 | destroy (this.name) 77 | 78 | 79 | 80 | 81 | 82 | Green potion 83 | It's a green potion. (It's also a child of the 'blue potion' of the 'potions' stack.) 84 | 85 | 86 | 87 | Look at 88 | Drink 89 | Take 90 | 91 | You think about drinking it but decide not to. 92 | very green potion]]> 93 | You take the green potion. 94 | potion_stack 95 | 96 | msg ("You drink the potion and recover 20% health.") 97 | player.health = player.health + 20 98 | destroy (this.name) 99 | 100 | 101 | 102 | 103 | 104 | potions]]> 105 | false 106 | 4 107 | Blue potion 108 | It's a blue potion. (It's also the main object of the 'potions' stack, although there's no way to see this in a game.) 109 | 110 | Look at 111 | Drink 112 | Take 113 | 114 | 115 | You pick it up and instantly feel 5% better. Weird. 116 | 117 | 118 | Look at 119 | Drink 120 | Drop 121 | 122 | Drink which potion? 123 | 124 | blue potion 125 | potion_stack 126 | 127 | msg ("You drink it and recover 25% health.") 128 | player.health = player.health + 25 129 | MoveObject (this, game) 130 | 131 | 132 | IncreaseHealth (5) 133 | 134 | 135 | 136 | 137 | 138 | Green potion 139 | It's a green potion. (It's also a child of the 'blue potion' of the 'potions' stack.) 140 | 141 | 142 | 143 | Look at 144 | Drink 145 | Take 146 | 147 | false 148 | You take the green potion. 149 | potion_stack 150 | 151 | msg ("You drink the potion and recover 20% health.") 152 | player.health = player.health + 20 153 | destroy (this.name) 154 | 155 | 156 | 157 | 158 | That looks painful... 159 | 160 | 161 | Look at 162 | Use 163 | 164 | 165 | 166 | player.health = player.health - 25 167 | msg ("Ouch! Why did you do that?") 168 | 169 | 170 | 171 | 172 | drink2 #object# 173 | 181 | 182 | 183 | 184 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | Potions]]> 196 | 197 | 198 | 199 | x 200 | 203 | 204 | game.pov.maxvolume) { 228 | continue = false 229 | if (HasString(game.pov, "containerfullmessage")) { 230 | message = prefix + game.pov.containerfullmessage 231 | } 232 | else { 233 | message = prefix + DynamicTemplate("FullInventory", object) 234 | } 235 | } 236 | } 237 | children = GetDirectChildren(game.pov) 238 | if (HasInt(game.pov, "maxobjects")) { 239 | if (game.pov.maxobjects > 0) { 240 | if (ListCount(children) >= game.pov.maxobjects) { 241 | continue = false 242 | if (HasString(game.pov, "containermaxobjects")) { 243 | message = prefix + game.pov.containermaxobjects 244 | } 245 | else { 246 | message = prefix + DynamicTemplate("MaxObjectsInInventory", object) 247 | } 248 | } 249 | } 250 | } 251 | if (continue = false) { 252 | msg (message) 253 | } 254 | else { 255 | found = true 256 | takemsg = object.takemsg 257 | switch (TypeOf(object, "take")) { 258 | case ("script") { 259 | if (ismultiple) { 260 | OutputTextNoBr (prefix) 261 | } 262 | do (object, "take") 263 | takemsg = "" 264 | } 265 | case ("boolean") { 266 | if (object.take = true) { 267 | object.parent = game.pov 268 | if (takemsg = null) { 269 | takemsg = DynamicTemplate("TakeSuccessful", object) 270 | } 271 | } 272 | else { 273 | found = false 274 | } 275 | } 276 | case ("string") { 277 | object.parent = game.pov 278 | takemsg = object.take 279 | } 280 | default { 281 | found = false 282 | } 283 | } 284 | if (not found and takemsg = null) { 285 | takemsg = DynamicTemplate("TakeUnsuccessful", object) 286 | } 287 | if (LengthOf(takemsg) > 0) { 288 | msg (prefix + takemsg) 289 | } 290 | if (HasScript(object, "ontake")) { 291 | do (object, "ontake") 292 | } 293 | if (found and GetBoolean (object, "scenery") and object.parent = game.pov) { 294 | object.scenery = false 295 | } 296 | } 297 | } 298 | ]]> 299 | -------------------------------------------------------------------------------- /empire/interface.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 |
    8 |
    9 |
    10 | 11 |
    12 |
    13 |
    14 | Next 15 |          16 | Help 17 |
    18 | Back 19 |          20 | Home 21 |
    22 | Research Labs 23 |
    24 | Design Office 25 |
    26 | War Room 27 |
    28 | Stars & Planets 29 |
    30 |
    31 | Turn: --- 32 |
    33 | Credits: --- 34 |
    35 |
    36 |

    Welcome to Star Empire. Click on the words to the right to navigate to different areas. Clicking "Home" will take you to the throne room, while clicking "Back" will take you back one level. Clicking "Next" to end this turn. Time will pass, and your empire will flourish or fail according to your instructions.

    37 | 38 | 39 | 40 |
    41 | 70 | ]]>
    71 |
    72 | 73 | 74 | 94 | 95 | 96 | 97 | 98 | 99 | help 100 | 103 | 104 | 105 | 106 | 107 | home 108 | 111 | 112 | 113 | 114 | planets 115 | 118 | 119 | 120 | 121 | research 122 | 125 | 126 | 127 | 128 | design 129 | 132 | 133 | 134 | 135 | military 136 | 139 | 140 | 141 | 142 | 143 | back 144 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | .noselect { 160 | -webkit-touch-callout: none; 161 | -webkit-user-select: none; 162 | -khtml-user-select: none; 163 | -moz-user-select: none; 164 | -ms-user-select: none; 165 | user-select: none; 166 | } 167 | 168 | 169 | function ArrowClick(s) { 170 | ASLEvent("ArrowCallback", s); 171 | } 172 | function StarClick(s) { 173 | ASLEvent("StarCallback", s); 174 | } 175 | 176 | 177 | 178 | 179 | 180 | " 182 | s = s + "" 183 | s = s + "" 184 | foreach (o, GetDirectChildren(maproom)) { 185 | if (not o = player) { 186 | px = game.x + o.x * game.scale 187 | py = game.y + o.y * game.scale 188 | if (o.owned) { 189 | s = s + "" 190 | } 191 | else { 192 | s = s + "" 193 | } 194 | s = s + "" 195 | if (game.scale > 2) { 196 | s = s + "" + o.alias + "" 197 | } 198 | } 199 | } 200 | s = s + "Imperial Cartographic Services" 201 | s = s + "Scale: " + game.scale + ", X offset: " + game.x + ", Y offset: " + game.y + "" 202 | s = s + "" 203 | s = s + "" 204 | s = s + "" 205 | s = s + "" 206 | 207 | s = s + "" 208 | s = s + "" 209 | 210 | s = s + "" 211 | s = s + "" 212 | 213 | s = s + "" 214 | s = s + "" 215 | 216 | s = s + "" 217 | JS.eval ("$('#gamePanel').css('display', 'block');") 218 | JS.eval ("$('#gamePanel').html('" + s +"');") 219 | // Need to do this here as the css method only changes the existing elements 220 | JS.eval ("$('.noselect').css('-webkit-touch-callout', 'none')") 221 | JS.eval ("$('.noselect').css('-webkit-user-select', 'none')") 222 | JS.eval ("$('.noselect').css('-khtml-user-select', 'none')") 223 | JS.eval ("$('.noselect').css('-moz-user-select', 'none')") 224 | JS.eval ("$('.noselect').css('ms-user-select', 'none')") 225 | JS.eval ("$('.noselect').css('user-select', 'none')") 226 | ]]> 227 | 228 | 229 | if (s = "0") { 230 | game.y = game.y + 20 231 | } 232 | if (s = "1") { 233 | game.x = game.x - 20 234 | } 235 | if (s = "2") { 236 | game.y = game.y - 20 237 | } 238 | if (s = "3") { 239 | game.x = game.x + 20 240 | } 241 | if (s = "4") { 242 | game.x = 300 243 | game.y = 200 244 | } 245 | if (s = "5") { 246 | game.scale = game.scale * 2 247 | } 248 | if (s = "6") { 249 | if (game.scale > 1) { 250 | game.scale = game.scale / 2 251 | } 252 | } 253 | Map 254 | 255 | 256 | 257 | foreach (o, GetDirectChildren(maproom)) { 258 | if (not o = player) { 259 | if (o.id = ToInt(s)) { 260 | do(o, "look") 261 | } 262 | } 263 | } 264 | 265 | 266 | 267 | 268 |
    269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /empire/Empire.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 6b536464-42df-422b-8a83-bc2ca1397e85 9 | 0.0 10 | 2016 11 | Can you rule the galaxy? 12 | The Pixie 13 | Sci-Fi 14 | 15 | 900 16 | 17 | false 18 | false 19 | false 20 | false 21 | false 22 | Dosis 23 | 1 24 | 300 25 | 200 26 | 27 | false 28 | 29 | player.time = 1 30 | player.credits = 500 31 | 32 | 33 | 34 | 35 | 36 | 37 | Throne Room 38 | false 39 | 40 | request (SetInterfaceString, "PlacesObjectsLabel=News") 41 | JS.eval ("$('#page1').html('The throne room is the hub of your command centre, giving an overview of your empire.');") 42 | 43 | Welcome to your empire. It is not much, but you control one planet, with a basic mine, and a fleet of five ship Cobra ships.") 45 | msg ("This is just a \"proof of concept\" and there is not much you can do yet. If you research \"Fields\" you will soon discover photon torpedoes, but there is nothing else to discover yet. Do take a look at the star map though!") 46 | GenerateGalaxy (20) 47 | msg ("It is 237 years since the collapse. After two centuries of just struggling to live, the survivors on your planet are starting to look to the future. Old technology has been recovered from the ruins of the ancient cities, and five \"Cobra\" class warships have been built, and currently orbit the planet.") 48 | msg ("Are you ready to seize the memoment? To lead your people to the stars, to forge a new empire?") 49 | ]]> 50 | 51 | ClearScreen 52 | 53 | 54 | 55 | 56 | 0 57 | 58 | 59 | JS.eval ("$('#clock').html('" + this.time + "');") 60 | 61 | 62 | JS.eval ("$('#cash').html('" + this.credits + "');") 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | War Room 81 | false 82 | 83 | request (SetInterfaceString, "PlacesObjectsLabel=Fleets") 84 | JS.eval ("$('#page1').html('Organise and deploy your fleets.');") 85 | 86 | 87 | ClearScreen 88 | 89 | 90 | 91 | 92 | Look at 93 | 94 | Fleet 1 95 | " + this.alias + "" 97 | foreach (o, GetDirectChildren(this)) { 98 | s = s + "
    " + o.design.alias + ": " + o.number 99 | } 100 | msg (s) 101 | ]]>
    102 | 103 | 104 | 5 105 | design1 106 | 107 |
    108 | 109 | 110 | 111 |
    112 | 113 | 114 | Research Labs 115 | false 116 | 117 | request (SetInterfaceString, "PlacesObjectsLabel=Research areas") 118 | JS.eval ("$('#page1').html('Decide how much of your resources you will spend on each field of science. Each turn will bring you nearer to new discoveries.');") 119 | 120 | 121 | ClearScreen 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | Fields 130 | This area of science is to do with fields, principally electromagnetic fields and gravity fields. Research in this direction may lead to artificial gravity, gravity bombs, anti-gravity and photon torpedeos. 131 | 132 | 133 | 134 | The photon torpedo is an unguided missile contructed of "hard" light. 135 | false 136 | 50 137 | Photon Torpedo 138 | Secondary weapon 139 | 140 | 141 | 142 | 143 | Basic laser 144 | 0 145 | Primary weapon 146 | 147 | 148 | 149 | 150 | 151 | 152 | Particle physics 153 | Research in construction will allow bigger ships and buildings to be constructed. 154 | 155 | 156 | 157 | 158 | Construction 159 | 160 | 161 | 162 | 0 163 | Vessel 164 | 1 165 | 100 166 | Caravel 167 | 168 | 169 | 170 | 171 | 172 | Basic mine 173 | 70 174 | 0 175 | 1 176 | Building 177 | 25 178 | Used to extract metals and other materials from the planet. 179 | 180 | 181 | 182 | 183 | 184 | Spacedock 185 | 0 186 | 1 187 | Building 188 | -10 189 | Used to extract metals and other materials from the planet. 190 | 200 191 | 192 | 193 | 194 | 195 | 196 | 197 | Design Office 198 | false 199 | 200 | request (SetInterfaceString, "PlacesObjectsLabel=Designs") 201 | JS.eval ("$('#page1').html('Here you can design ships for your fleet, using the technologies you have uncovered.');") 202 | 203 | 204 | ClearScreen 205 | 206 | 207 | 208 | Cobra 209 | 210 | Look at 211 | 212 | basiclaser 213 | caravel 214 | Name: " + this.alias) 216 | msg ("Body: " + this.vessel.alias) 217 | foreach (s, Split("Primary weapon;Secondary weapon;Turret;FTL engine;Sub-light engine;Sensor;Cloak;Other", ";")) { 218 | s2 = Replace(LCase(s), " ", "_") 219 | if (HasObject(this, s2)) { 220 | o = GetAttribute(this, s2) 221 | msg ("" + s + ": " + o.alias) 222 | } 223 | } 224 | ]]> 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | false 234 | 235 | request (SetInterfaceString, "PlacesObjectsLabel=Star systems") 236 | Map 237 | JS.eval ("$('#page1').html('Use the map to explore the galaxy. Click the side arrows to scroll, the + and - to zoom in and out and the square to centre the view.');") 238 | 239 | 240 | JS.eval ("$('#gamePanel').css('display', 'none');") 241 | 242 | 243 | ClearScreen 244 | 245 | 246 | 247 | 248 | Home world 249 | 0 250 | 0 251 | red 252 | 0 253 | 254 | This is your home world; it has a pleasant atmosphere and a varied geography. An ideal base for your empire. 255 | 256 | 257 | 258 | 1 259 | Command Centre 260 | commandcentre 261 | 262 | 263 | 264 | 265 | 1 266 | Basic Mine (1) 267 | 268 | Look at 269 | Construct 270 | Condemn 271 | 272 | basicmine 273 | 274 | 275 | 276 | 277 | 1 278 | Basic dock (1) 279 | basicdockyard 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | Command Centre 292 | 0 293 | 1 294 | Building 295 | 0 296 | It is from here that you control your empire. You can only have one, and if you ever lose it, you have lost the game. 297 | 298 | 299 |
    -------------------------------------------------------------------------------- /ClockLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 35 | 36 | 37 | 38 | 39 | 40 | 0 41 | 0 42 | 0 43 | 0 44 | 1 45 | 15 46 | 12 midnight 47 | 12 noon 48 | am 49 | pm 50 | false 51 | You take your fob watch from your pocket, and look at it. It's ###. 52 | You wait ### minutes, but nothing happens. 53 | 54 | JS.eval("$('#clock').html('" + TimeAsString() + "');") 55 | 56 | 2000 57 | 58 | 59 | 60 | clock;time;watch 61 | 64 | 65 | 66 | 67 | ^wait$|^z$ 68 | 81 | 82 | 83 | 84 | true 85 | 99 | 100 | 101 | 120 | 121 | 122 | 126 | 159 | 160 | 161 | 165 | 166 | 167 | 168 | 169 | 170 | 173 | 174 | game_clock.increment = minutes 175 | 176 | 177 | 178 | 181 | 182 | time = game_clock.time + time 183 | o = null 184 | while (o = null) { 185 | o = AttemptCreateEvent(time) 186 | time = time + 1 187 | } 188 | o.look = script 189 | o.alias = alias 190 | 191 | 192 | 195 | 196 | game_clock.nextstep = step 197 | game_clock.countdown = delay 198 | //msg("delay=" + delay) 199 | 200 | 201 | 202 | 203 | 207 | 208 | minutes = time % 60 209 | hours24 = (time / 60) % 24 210 | days = time / (60 * 24) 211 | name = "event_" + DD(days) + "_" + DD(hours24) + "_" + DD(minutes) 212 | //msg("Setting for: " + name) 213 | o = GetObject(name) 214 | if (o = null) { 215 | create(name) 216 | return (GetObject(name)) 217 | } 218 | else { 219 | return (null) 220 | } 221 | 222 | 223 | 227 | 228 | if (TypeOf(minutes) = "string") { 229 | l = Split(minutes, ":") 230 | if (not ListCount(l) = 3) error("SetTime failed to understand " + minutes) 231 | game_clock.days = ToInt(StringListItem(l, 0)) 232 | game_clock.hours24 = ToInt(StringListItem(l, 1)) 233 | game_clock.minutes = ToInt(StringListItem(l, 2)) 234 | game_clock.time = (game_clock.days * 24 + game_clock.hours24) * 60 + game_clock.minutes 235 | } 236 | else { 237 | game_clock.time = minutes 238 | game_clock.minutes = game_clock.time % 60 239 | game_clock.hours24 = (game_clock.time / 60) % 24 240 | game_clock.days = game_clock.time / (60 * 24) + 1 241 | } 242 | if (not GetObject("NpcTurnScript") = null) { 243 | DisableTurnScript (NpcTurnScript) 244 | } 245 | game.clock = TimeAsString() 246 | 247 | 248 | 251 | time) 261 | ]]> 262 | 263 | 267 | time) 277 | ]]> 278 | 279 | 282 | 283 | return (game_clock.time) 284 | 285 | 286 | 289 | 292 | 293 | 294 | 297 | 305 | 306 | 307 | 311 | 314 | 315 | 316 | 321 | 327 | 328 | 329 | 338 | 339 | year = game_clock.startyear 340 | day = game_clock.days 341 | if (1 > day) error("Date function cannot cope with a day of zero or less") 342 | // what year is it? 343 | flag = true 344 | while (flag) { 345 | if (year % 4 = 0) { 346 | days_this_year = 366 347 | } 348 | else { 349 | days_this_year = 365 350 | } 351 | if (day > days_this_year) { 352 | year = year + 1 353 | day = day - days_this_year 354 | } 355 | else { 356 | flag = false 357 | } 358 | } 359 | // days in month 360 | if (year % 4 = 0) { 361 | days_in_months = Split("31;29;31;30;31;30;31;31;30;31;30;31", ";") 362 | } 363 | else { 364 | days_in_months = Split("31;28;31;30;31;30;31;31;30;31;30;31", ";") 365 | } 366 | // what month is it? 367 | month = 1 368 | for (i, 0, 11) { 369 | days_in_month = ToInt(StringListItem(days_in_months, i)) 370 | if (day > days_in_month) { 371 | month = month + 1 372 | day = day - days_in_month 373 | } 374 | else { 375 | return (DisplayDate(year, month, day)) 376 | } 377 | } 378 | 379 | 380 | 383 | 384 | months = Split(";January;February;March;April;May;June;July;August;September;October;November;December", ";") 385 | return ("" + day + "th of " + StringListItem(months, month) + ", " + year) 386 | 387 | 388 | -------------------------------------------------------------------------------- /CompliantNpcLib.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 22 | 23 | 24 | 25 | "Tell " + object.article + " all you want, " + object.gender + "'s not going to do anything." 26 | 27 | 28 | 29 | 30 | 31 | 32 | .*)$|^go (?.*)$|^(?north|east|south|west|northeast|northwest|southeast|southwest|in|out|up|down|n|e|s|w|ne|nw|se|sw|o|u|d)$]]> 33 | [UnresolvedLocation] 34 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 80 | 81 | 82 | 83 | 84 | .*) to|(?.*),) go to (?.*)$|^(?.*), go (?.*)$]]> 85 | You can't go there. 86 | 89 | 90 | 91 | .*) to|(?.*),) (go |)(?north|east|south|west|northeast|northwest|southeast|southwest|in|out|up|down|n|e|s|w|ne|nw|se|sw|o|u|d)$]]> 92 | You can't go there. 93 | 96 | 97 | 98 | // WARNING: This does not allow for doors that are stopped by scripts 99 | if (not DoesInherit(npc, "compliant_npc")) { 100 | msg(DynamicTemplate("PosturesNotNpc", npc)) 101 | } 102 | else if (not exit.visible) { 103 | msg ([UnresolvedLocation]) 104 | } 105 | else { 106 | do (npc, "requestgo", QuickParams("object", exit)) 107 | } 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | .*) to|(?.*),) (follow me|follow)$]]> 116 | 124 | 125 | 126 | 127 | .*) to|(?.*),) (stop following|don't follow|do not follow|wait here|wait)( me|)$]]> 128 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | .*) to|(?.*),) (get|take|pick up) (?.*)$]]> 143 | 160 | 161 | 162 | 163 | .*) to|(?.*),) (drop) (?.*)$]]> 164 | none 165 | 166 | foreach (npc, FilterByType(ScopeVisibleNotHeldForRoom (game.pov.parent), "compliant_npc")) { 167 | foreach (obj, GetDirectChildren(npc)) { 168 | list add (items, obj) 169 | } 170 | } 171 | 172 | 183 | 184 | 185 | 186 | .*) to|(?.*),) (give me|give) (?.*)$]]> 187 | none 188 | 189 | foreach (npc, FilterByType(ScopeVisibleNotHeldForRoom (game.pov.parent), "compliant_npc")) { 190 | foreach (obj, GetDirectChildren(npc)) { 191 | list add (items, obj) 192 | } 193 | } 194 | 195 | 198 | 199 | 200 | .*) to|(?.*),) (give) (?.*) to (?.*)$]]> 201 | none 202 | 203 | foreach (npc, FilterByType(ScopeVisibleNotHeldForRoom (game.pov.parent), "compliant_npc")) { 204 | foreach (obj, GetDirectChildren(npc)) { 205 | list add (items, obj) 206 | } 207 | } 208 | 209 | 212 | 213 | 214 | if (not DoesInherit(npc, "compliant_npc")) { 215 | msg(DynamicTemplate("PosturesNotNpc", npc)) 216 | } 217 | else if (not object.parent = npc) { 218 | msg(WriteVerb(npc, "do") + " not have " + object.article + ".") 219 | } 220 | else { 221 | msg ("Giving " + object.name + " to " + subject.name) 222 | do(npc, "requestgive", QuickParams("object", object, "subject", subject)) 223 | } 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 10 242 | true 243 | Okay! 244 | 'I'd rather not.' 245 | 'I don't think so.' 246 | 'Not happening.' 247 | 'No way!' 248 | 'In your dreams, creep!' 249 | 250 | 251 | 252 | 253 | // level is an int 254 | // you could have compliance drop if degree is big enough - 255 | // the NPC is so horrified he is less likely to agree in future 256 | if (not IsDefined("level")) level = 10 257 | degree = (level - this.compliance) / 3 258 | if (degree > 4) degree = 4 259 | if (degree >= 0) { 260 | this.complies = false 261 | msg(GetString(this, "nomsg" + degree)) 262 | } 263 | else { 264 | this.complies = true 265 | } 266 | 267 | 268 | 269 | 270 | do (this, "checkagreement", QuickParams("level", 12)) 271 | if (this.complies) { 272 | if (HasScript(object, "npc_take")) { 273 | do (object, "npc_take", QuickParams("npc", npc)) 274 | } 275 | else if ((HasBoolean(object, "npc_take") and not GetBoolean(object, "npc_take")) or (not HasAttribute(object, "npc_take") and not GetBoolean(object, "take"))) { 276 | msg ("'I can't get that,' says " + GetDefiniteName(this) + ".") 277 | } 278 | else { 279 | msg ("'" + this.yesmsg + "' says " + CapFirst(GetDefiniteName(this)) + ", picking " + GetDefiniteName(object) + " up.") 280 | object.parent = this 281 | } 282 | } 283 | 284 | 285 | 286 | do (this, "checkagreement", QuickParams("level", 12)) 287 | if (this.complies) { 288 | if (HasScript(object, "npc_drop")) { 289 | do (object, "npc_drop", QuickParams("npc", this)) 290 | } 291 | else if ((HasBoolean(object, "npc_drop") and not GetBoolean(object, "npc_drop")) or (not HasAttribute(object, "npc_drop") and not GetBoolean(object, "drop"))) { 292 | msg ("'I can't drop that,' says " + GetDefiniteName(this) + ".") 293 | } 294 | else { 295 | msg ("'" + this.yesmsg + "' says " + CapFirst(GetDefiniteName(this)) + ", dropping " + GetDefiniteName(object) + ".") 296 | object.parent = this.parent 297 | } 298 | } 299 | 300 | 301 | 302 | do (this, "checkagreement", QuickParams("level", 12)) 303 | if (this.complies) { 304 | if (HasScript(this, "give_" + object.name + "_to_" + subject.name)) { 305 | do (this, "give_" + object.name + "_to_" + subject.name) 306 | } 307 | else if (HasScript(this, "give_" + object.name)) { 308 | do (this, "give_" + object.name + "_to_" + subject.name, QuickParams("subject", subject)) 309 | } 310 | else if ((HasBoolean(object, "npc_drop") and not GetBoolean(object, "npc_drop")) or (not HasAttribute(object, "npc_drop") and not GetBoolean(object, "drop"))) { 311 | msg ("'I can't drop that,' says " + GetDefiniteName(this) + ".") 312 | } 313 | else { 314 | if (subject.gender = "you") { 315 | target = "you" 316 | } 317 | else { 318 | target = GetDefiniteName(subject) 319 | } 320 | msg ("'" + this.yesmsg + "' says " + CapFirst(GetDefiniteName(this)) + ", giving " + GetDefiniteName(object) + " to " + target + ".") 321 | object.parent = subject 322 | } 323 | } 324 | 325 | 326 | 327 | do (this, "checkagreement", QuickParams("level", 8)) 328 | if (this.complies) { 329 | if (object.locked) { 330 | msg ("'It's locked,' says " + GetDefiniteName(this) + ".") 331 | } 332 | else { 333 | if (this.posture = null) { 334 | msg ("'" + this.yesmsg + "' says " + CapFirst(GetDefiniteName(this)) + ", heading " + object.alias + ".") 335 | } 336 | else if (this.posture_object = null) { 337 | msg ("'" + this.yesmsg + "' says " + GetDefiniteName(this) + ", standing up and going " + object.alias + ".") 338 | } 339 | else { 340 | msg ("'" + this.yesmsg + "' says " + GetDefiniteName(this) + ", getting off " + GetDefiniteName(this.posture_object) + ", and walking " + object.alias + "wards.") 341 | } 342 | this.posture_object = null 343 | this.posture = null 344 | this.listalias = this.alias 345 | this.parent = object.to 346 | } 347 | } 348 | 349 | 350 | 351 | do (this, "checkagreement", QuickParams("level", 8)) 352 | if (this.complies) { 353 | if (this.following = game.pov) { 354 | msg ("'I am!' says " + GetDefiniteName(this) + ".") 355 | } 356 | else { 357 | msg ("'" + this.yesmsg + "' says " + GetDefiniteName(this) + ", looking expectantly at you.") 358 | this.following = game.pov 359 | } 360 | } 361 | 362 | 363 | 364 | do (this, "checkagreement", QuickParams("level", 20)) 365 | if (this.complies) { 366 | if (this.following = null) { 367 | msg ("'I am!' says " + GetDefiniteName(this) + ".") 368 | } 369 | else { 370 | msg ("'" + this.yesmsg + "' says " + GetDefiniteName(this) + ", tapping " + this.possessive + " foot.") 371 | this.following = game.pov 372 | } 373 | } 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | -------------------------------------------------------------------------------- /SaveLoad.aslx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 20 | 21 | 22 | 23 | 25 | 26 | 27 | saveLoad = { 28 | debug:false, 29 | 30 | saveGame:function(title, filename, data) { 31 | if (!this.lsTest()) return; 32 | var currentdate = new Date(); 33 | var s = title + "|"; 34 | s += currentdate.toLocaleString() + "|"; 35 | if (!this.debug) { 36 | localStorage.setItem(title + ": " + filename, s + data); 37 | } 38 | else { 39 | this.lastSave = s + data 40 | } 41 | addText("Saved: " + filename + "
    "); 42 | }, 43 | 44 | loadGame:function(title, filename) { 45 | if (!this.lsTest()) return; 46 | if (!this.debug) { 47 | var data = localStorage.getItem(title + ": " + filename); 48 | } 49 | else { 50 | var currentdate = new Date(); 51 | data = this.lastSave; 52 | } 53 | if (data === null) { 54 | addText("Failed to find file: " + filename); 55 | return; 56 | } 57 | var arr = data.split("|"); 58 | arr.shift(); 59 | arr.shift(); 60 | ASLEvent("LoadGame", arr.join("|")); 61 | }, 62 | 63 | deleteGame:function(title, filename) { 64 | if (!this.lsTest()) return; 65 | if (!this.debug) { 66 | localStorage.removeItem(title + ": " + filename); 67 | } 68 | addText("Deleted:" + filename); 69 | }, 70 | 71 | dirGame:function(title) { 72 | if (!this.lsTest()) return; 73 | var s = ""; 74 | if (!this.debug) { 75 | $.each(localStorage, function(key, value){ 76 | var regex = new RegExp("^" + title + ": "); 77 | var name = key.replace(regex, ""); 78 | if (regex.test(key)) { 79 | var arr = value.split("|"); 80 | s += ""; 81 | s += ""; 82 | } 83 | }); 84 | } 85 | s += "
    FilenameTimestamp
    " + name + "" + arr[1] + "
    "; 86 | addText(s); 87 | }, 88 | 89 | lsTest:function() { 90 | if (this.debug) return true; 91 | if (platform === "desktop") { 92 | alert("Cannot save (localStorage not available). Save and load via the File menu instead."); 93 | return false; 94 | } 95 | var test = 'test'; 96 | try { 97 | localStorage.setItem(test, test); 98 | localStorage.removeItem(test); 99 | return true; 100 | } catch(e) { 101 | alert("Cannot save (localStorage not available)."); 102 | return false; 103 | } 104 | }, 105 | }; 106 | 107 | ]]>
    108 |
    109 | 110 | 111 | 112 | 113 | 114 | 115 | ^(save|load|restore)$ 116 | 120 | 121 | 122 | 123 | save #text# 124 | 130 | 131 | 132 | 133 | load #text#;restore #text# 134 | 137 | 138 | 139 | 140 | del #text#;delete #text# 141 | 145 | 146 | 147 | 148 | dir;ls 149 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 171 | 172 | allowedTypes = Split("object;list;int;integer;boolean;flag;dictionaryoflists") 173 | if (not HasAttribute(game, "saveloadatts")) { 174 | msg("Error: Save/load not properly implemented - no game.saveloadatts attribute set.") 175 | msg("") 176 | return (false) 177 | } 178 | if (not TypeOf(game, "saveloadatts") = "stringlist") { 179 | msg("Error: Save/load not properly implemented - the game.saveloadatts attribute must be a string list.") 180 | msg("") 181 | return (false) 182 | } 183 | foreach (s, game.saveloadatts) { 184 | if (StartsWith(s, "player:parent:")) { 185 | msg("Error: Save/load not properly implemented - the game.saveloadatts list includes player.parent.") 186 | msg("") 187 | return (false) 188 | } 189 | arr = Split(s, ".") 190 | if (not ListCount(arr) = 3) { 191 | msg("Error: Save/load not properly implemented - the game.saveloadatts list includes a badly formatted attribute; " + s + " (should have three parts separated by dots).") 192 | msg("") 193 | return (false) 194 | } 195 | if (not ListContains(allowedTypes, arr[2])) { 196 | msg("Error: Save/load not properly implemented - the game.saveloadatts list includes a badly formatted attribute; " + s + " (third part should be one of " + Join(allowedTypes, ", ") + "; not " + arr[2] + ").") 197 | msg("") 198 | return (false) 199 | } 200 | } 201 | 202 | foreach (obj, AllObjects()) { 203 | if (not obj = player) { 204 | list add (game.saveloadatts, obj.name + ".parent.object") 205 | } 206 | } 207 | AddAtts(game, game.saveloadints, "int") 208 | AddAtts(game, game.saveloadflags, "flag") 209 | AddAtts(player, player.saveloadints, "int") 210 | AddAtts(player, player.saveloadflags, "flag") 211 | list add (game.saveloadatts, "game.textprocessor_seen.dictionaryoflists") 212 | list add (game.saveloadatts, "game.roomsvisited.string") 213 | list add (game.saveloadatts, "game.exitslocked.string") 214 | list add (game.saveloadatts, "game.exitsnotvisible.string") 215 | list add (game.saveloadatts, "game.itemslocked.string") 216 | list add (game.saveloadatts, "game.itemsopen.string") 217 | list add (game.saveloadatts, "game.itemsworn.string") 218 | list add (game.saveloadatts, "game.itemshidden.string") 219 | list add (game.saveloadatts, "game.itemsdisplay.string") 220 | list add (game.saveloadatts, "game.clonedata.string") 221 | list add (game.saveloadatts, "player.current_location.object") 222 | 223 | JS.addScript (saveloaddata.saveloadscript) 224 | return (true) 225 | 226 | 227 | if (not values = null) { 228 | values = Split(values, ";") 229 | for (i, 0, ListCount(values) - 1) { 230 | list add (game.saveloadatts, obj.name + "." + values[i] + "." + typename) 231 | } 232 | } 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | msg("LoadGame") 261 | PreLoad 262 | pos = 0 263 | foreach (val, Split(s, ";")) { 264 | ary = Split(StringListItem(game.saveloadatts, pos), ".") 265 | obj = GetObject(StringListItem (ary, 0)) 266 | att = StringListItem (ary, 1) 267 | type = LCase(StringListItem (ary, 2)) 268 | if (val = "" or TypeOf(val) = "null") { 269 | set (obj, att, null) 270 | } 271 | else if (type = "object") { 272 | set (obj, att, GetObject(val)) 273 | } 274 | else if (type = "list") { 275 | set (obj, att, Split(val, "|")) 276 | } 277 | else if (type = "int" or type = "integer") { 278 | if (IsInt(val)) { 279 | set (obj, att, ToInt(val)) 280 | } 281 | else { 282 | error("Load error: Cannot convert \"" + val + "\" to an integer for " + StringListItem(game.saveloadatts, pos)) 283 | } 284 | } 285 | else if (type = "boolean" or type = "flag") { 286 | set (obj, att, LCase(val) = "true") 287 | } 288 | else if (type = "dictionaryoflists") { 289 | set (obj, att, SuperSplit(val)) 290 | } 291 | else { 292 | set (obj, att, Replace(val, "@@@semicolon@@@", ";")) 293 | } 294 | pos = pos + 1 295 | } 296 | 297 | SetAll(game.roomsvisited, "visited", true) 298 | SetAll(game.exitslocked, "locked", true) 299 | SetAll(game.exitsnotvisible, "visible", false) 300 | SetAll(game.itemslocked, "locked", true) 301 | SetAll(game.itemsopen, "isopen", true) 302 | SetAll(game.itemsworn, "worn", true) 303 | SetAll(game.itemshidden, "hidden", true) 304 | SetAll(game.itemsdisplay, "display", true) 305 | ol = FilterByNotAttribute(AllObjects(), "prototype", null) 306 | while (not ListCount(ol) = 0) { 307 | o = ObjectListItem(ol, 0) 308 | destroy(o.name) 309 | ol = FilterByNotAttribute(AllObjects(), "prototype", null) 310 | } 311 | SetCloneData(game.clonedata) 312 | 313 | PostLoad 314 | player.parent = player.current_location 315 | msg("Game loaded") 316 | 317 | 318 | 319 | 320 | 321 | // First collect the standard data, and add to the game object 322 | player.current_location = player.parent 323 | // For rooms 324 | game.roomsvisited = ListWith(AllObjects(), "visited", true) 325 | // For exits 326 | game.exitslocked = ListWith(AllExits(), "locked", true) 327 | game.exitsnotvisible = ListWith(AllExits(), "visible", false) 328 | // For containers 329 | game.itemslocked = ListWith(AllObjects(), "locked", true) 330 | game.itemsopen = ListWith(AllObjects(), "isopen", true) 331 | // For wearables 332 | game.itemsworn = ListWith(AllObjects(), "worn", true) 333 | // For conversations 334 | game.itemshidden = ListWith(AllObjects(), "hidden", true) 335 | game.itemsdisplay = ListWith(AllObjects(), "display", true) 336 | 337 | game.clonedata = GetCloneData() 338 | 339 | data = NewStringList() 340 | foreach (attri, game.saveloadatts) { 341 | ary = Split(attri, ".") 342 | obj = GetObject(StringListItem (ary, 0)) 343 | if (not ListCount(ary) = 3) { 344 | error("Save error: Badly formatted entry: " + attri) 345 | } 346 | else if (obj = null) { 347 | error("Save error: Failed to find an object called: " + StringListItem (ary, 0)) 348 | } 349 | else { 350 | att = StringListItem (ary, 1) 351 | type = LCase(StringListItem (ary, 2)) 352 | val = GetAttribute(obj, att) 353 | if (TypeOf(val) = "null") { 354 | list add (data, "") 355 | } 356 | else if (type = "object") { 357 | if (not TypeOf(val) = "object") error("Save: Expected " + attri + ", found " + TypeOf(val)) 358 | list add (data, val.name) 359 | } 360 | else if (type = "list") { 361 | if (not TypeOf(val) = "stringlist") error("Save: Expected " + attri + ", found " + TypeOf(val)) 362 | list add (data, Join(val, "|")) 363 | } 364 | else if (type = "int" or type = "integer") { 365 | if (not TypeOf(val) = "int") error("Save: Expected " + attri + ", found " + TypeOf(val)) 366 | list add (data, "" + val) 367 | } 368 | else if (type = "boolean" or type = "flag") { 369 | if (not TypeOf(val) = "boolean") error("Save: Expected " + attri + ", found " + TypeOf(val)) 370 | list add (data, "" + val) 371 | } 372 | else if (type = "dictionaryoflists") { 373 | list add (data, SuperJoin(val)) 374 | } 375 | else if (type = "string") { 376 | if (not TypeOf(val) = "string") error("Save: Expected " + attri + ", found " + TypeOf(val)) 377 | list add (data, Replace(val, ";", "@@@semicolon@@@")) 378 | } 379 | else { 380 | error("Save error: Invalid type for " + StringListItem (ary, 0) + ": " + type) 381 | } 382 | } 383 | } 384 | 385 | PreSave 386 | //msg("here3") 387 | return (Join(data, ";")) 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 408 | 409 | l = FilterByAttribute(list, att, val) 410 | return (Join(ObjectListToStringList(l, "name"), "|")) 411 | 412 | 413 | if (not s = null and not s = "") { 414 | l = Split(s, "|") 415 | foreach (s, l) { 416 | o = GetObject(s) 417 | if (o = null) error ("Failed to find object: " + s) 418 | set (o, att, val) 419 | } 420 | } 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | ol = FilterByNotAttribute(AllObjects(), "prototype", null) 430 | sl = NewStringList() 431 | msg("About to do clones") 432 | foreach (o, ol) { 433 | s = o.name + "/" + o.prototype.name 434 | if (HasAttribute(o, "saveloadatts")) { 435 | foreach (att, o.saveloadatts) { 436 | s = s + "/" + GetAttribute(o, att) 437 | } 438 | list add (sl, s) 439 | } 440 | else { 441 | error("Clone prototype, " + o.prototype.name + ", has no 'saveloadatts' attribute.") 442 | } 443 | } 444 | return (Join(sl, "|")) 445 | 446 | 447 | 448 | if (not str = null) { 449 | foreach (s, Split(str, "|")) { 450 | l = Split(s, "/") 451 | prototype = GetObject(StringListItem(l, 1)) 452 | o = CloneObject(prototype) 453 | if (not o.name = StringListItem(l, 0)) error ("Name mismatch in clones: " + o.name + " is not " + StringListItem(l, 0)) 454 | list remove (l, prototype.name) 455 | list remove (l, o.name) 456 | for (i, 0, ListCount(l) - 1) { 457 | val = StringListItem(l, i) 458 | att = StringListItem(o.saveloadatts, i) 459 | if (val = "") { 460 | set (o, att, null) 461 | } 462 | else if (IsInt(val)) { 463 | set (o, att, ToInt(val)) 464 | } 465 | else if (val = "True") { 466 | set (o, att, true) 467 | } 468 | else if (val = "False") { 469 | set (o, att, false) 470 | } 471 | else { 472 | set (o, att, val) 473 | } 474 | } 475 | } 476 | } 477 | 478 | 479 | 480 | 481 | 482 | 483 | 489 | 490 | sublist = NewStringList() 491 | foreach (key, col) { 492 | val = DictionaryItem(col, key) 493 | s2 = Join(ToStringList(val), "#") 494 | s = key + "~" + s2 495 | list add (sublist, s) 496 | } 497 | return(Join(sublist, "|")) 498 | 499 | 500 | dict = NewDictionary() 501 | list = Split(str, "|") 502 | foreach (s, list) { 503 | sublist = Split(s, "~") 504 | key = StringListItem(sublist, 0) 505 | value = StringListItem(sublist, 1) // here 506 | dictionary add(dict, key, Split(value, "#")) 507 | } 508 | return(dict) 509 | 510 | 511 | sl = NewStringList() 512 | foreach (el, col) { 513 | list add (sl, ToString(el)) 514 | } 515 | return(sl) 516 | 517 | 518 | 519 | 522 | 523 | if (not HasAttribute(object, "saveloadatts")) { 524 | error ("Cannot clone an object, " + object.name + ", with no 'saveloadatts' set, as it will not save properly.") 525 | return (null) 526 | } 527 | if (not TypeOf(object, "saveloadatts") = "stringlist") { 528 | error ("Cannot clone an object, " + object.name + ", as 'saveloadatts' is not a string list.") 529 | return (null) 530 | } 531 | 532 | newobject = ShallowClone(object) 533 | if (not HasString(object, "alias")) { 534 | newobject.alias = object.name 535 | } 536 | if (not HasAttribute(object, "prototype")) { 537 | newobject.prototype = object 538 | } 539 | foreach (o, GetDirectChildren(object)) { 540 | o2 = CloneObject (o) 541 | MoveObject (o2, newobject) 542 | } 543 | return (newobject) 544 | 545 | 546 |
    547 | --------------------------------------------------------------------------------