Mercurial > boomslang
comparison gamelib/scenes/mess.py @ 852:f95830b58336
Merge pyntnclick
author | Stefano Rivera <stefano@rivera.za.net> |
---|---|
date | Sat, 21 Jun 2014 22:04:35 +0200 |
parents | eed75a1d50c4 |
children |
comparison
equal
deleted
inserted
replaced
546:ad4d6ffd25d7 | 852:f95830b58336 |
---|---|
1 """Mess where crew eat. Fun stuff.""" | 1 """Mess where crew eat. Fun stuff.""" |
2 | 2 |
3 from random import randint | 3 from random import randint |
4 | 4 |
5 from gamelib.state import Scene, Item, CloneableItem, Thing, Result | 5 from pyntnclick.i18n import _ |
6 from gamelib.cursor import CursorSprite | 6 from pyntnclick.state import Scene, Item, CloneableItem, Thing, Result |
7 from gamelib.sound import get_sound | 7 from pyntnclick.cursor import CursorSprite |
8 from gamelib import constants | 8 from pyntnclick.scenewidgets import (InteractNoImage, InteractImage, |
9 from gamelib.scenewidgets import (InteractNoImage, InteractImage, | |
10 InteractImageRect, InteractAnimated, | 9 InteractImageRect, InteractAnimated, |
11 GenericDescThing) | 10 GenericDescThing) |
12 | 11 |
13 from gamelib.scenes.game_constants import PLAYER_ID | 12 from gamelib.scenes.game_constants import PLAYER_ID |
14 from gamelib.scenes.game_widgets import Door | 13 from gamelib.scenes.game_widgets import Door |
21 | 20 |
22 INITIAL_DATA = { | 21 INITIAL_DATA = { |
23 'life support status': 'broken', # broken, replaced, fixed | 22 'life support status': 'broken', # broken, replaced, fixed |
24 } | 23 } |
25 | 24 |
26 def __init__(self, state): | 25 def setup(self): |
27 super(Mess, self).__init__(state) | |
28 self.add_thing(CansOnShelf()) | 26 self.add_thing(CansOnShelf()) |
29 self.add_thing(Tubes()) | 27 self.add_thing(Tubes()) |
30 self.add_thing(ToMap()) | 28 self.add_thing(ToMap()) |
31 self.add_thing(DetergentThing()) | 29 self.add_thing(DetergentThing()) |
32 self.add_thing(Boomslang()) | 30 self.add_thing(Boomslang()) |
33 self.add_item(DetergentBottle('detergent_bottle')) | 31 self.add_item_factory(DetergentBottle) |
32 self.add_item_factory(EmptyCan) | |
33 self.add_item_factory(FullCan) | |
34 self.add_item_factory(DentedCan) | |
34 # Flavour items | 35 # Flavour items |
35 # extra cans on shelf | 36 # extra cans on shelf |
36 self.add_thing(GenericDescThing('mess.cans', 1, | 37 self.add_thing(GenericDescThing('mess.cans', 1, |
37 "A large collection of rusted, useless cans.", | 38 _("A large collection of rusted, useless cans."), |
38 ( | 39 ( |
39 (154, 335, 89, 106), | 40 (154, 335, 89, 106), |
40 (152, 435, 63, 66), | 41 (152, 435, 63, 66), |
41 ))) | 42 ))) |
42 self.add_thing(GenericDescThing('mess.broccoli', 2, | 43 self.add_thing(GenericDescThing('mess.broccoli', 2, |
43 "An impressively overgrown broccoli.", | 44 _("An impressively overgrown broccoli."), |
44 ( | 45 ( |
45 (503, 89, 245, 282), | 46 (503, 89, 245, 282), |
46 (320, 324, 229, 142), | 47 (320, 324, 229, 142), |
47 ))) | 48 ))) |
48 | 49 |
49 | 50 |
50 class BaseCan(CloneableItem): | 51 class BaseCan(CloneableItem): |
51 """Base class for the cans""" | 52 """Base class for the cans""" |
52 | 53 |
54 MAX_COUNT = 3 | |
55 | |
53 def interact_with_full_can(self, item): | 56 def interact_with_full_can(self, item): |
54 return Result("You bang the cans together. It sounds like two" | 57 return Result(_("You bang the cans together. It sounds like two" |
55 " cans being banged together.", | 58 " cans being banged together."), |
56 soundfile="can_hit.ogg") | 59 soundfile="can_hit.ogg") |
57 | 60 |
58 def interact_with_dented_can(self, item): | 61 def interact_with_dented_can(self, item): |
59 return self.interact_with_full_can(item) | 62 return self.interact_with_full_can(item) |
60 | 63 |
61 def interact_with_empty_can(self, item): | 64 def interact_with_empty_can(self, item): |
62 return self.interact_with_full_can(item) | 65 return self.interact_with_full_can(item) |
63 | 66 |
64 def interact_with_machete(self, item): | 67 def interact_with_machete(self, item): |
65 return Result("You'd mangle it beyond usefulness.") | 68 return Result(_("You'd mangle it beyond usefulness.")) |
66 | 69 |
67 def interact_with_canopener(self, item): | 70 def interact_with_canopener(self, item): |
68 empty = EmptyCan('empty_can') | 71 self.game.replace_inventory_item(self.name, 'empty_can') |
69 self.state.add_item(empty) | 72 return Result(_("You open both ends of the can, discarding the" |
70 self.state.replace_inventory_item(self.name, empty.name) | 73 " hideous contents.")) |
71 return Result("You open both ends of the can, discarding the" | |
72 " hideous contents.") | |
73 | 74 |
74 | 75 |
75 class EmptyCan(BaseCan): | 76 class EmptyCan(BaseCan): |
76 "After emptying the full can." | 77 "After emptying the full can." |
77 | 78 |
79 NAME = 'empty_can' | |
78 INVENTORY_IMAGE = "empty_can.png" | 80 INVENTORY_IMAGE = "empty_can.png" |
79 CURSOR = CursorSprite('empty_can_cursor.png') | 81 CURSOR = CursorSprite('empty_can_cursor.png') |
80 | 82 |
81 def interact_with_titanium_leg(self, item): | 83 def interact_with_titanium_leg(self, item): |
82 return Result("Flattening the can doesn't look like a useful" | 84 return Result(_("Flattening the can doesn't look like a useful" |
83 " thing to do.") | 85 " thing to do.")) |
84 | 86 |
85 def interact_with_canopener(self, item): | 87 def interact_with_canopener(self, item): |
86 return Result("There's nothing left to open on this can") | 88 return Result(_("There's nothing left to open on this can")) |
87 | 89 |
88 | 90 |
89 class FullCan(BaseCan): | 91 class FullCan(BaseCan): |
90 "Found on the shelf." | 92 "Found on the shelf." |
91 | 93 |
94 NAME = 'full_can' | |
92 INVENTORY_IMAGE = "full_can.png" | 95 INVENTORY_IMAGE = "full_can.png" |
93 CURSOR = CursorSprite('full_can_cursor.png') | 96 CURSOR = CursorSprite('full_can_cursor.png') |
94 | 97 |
95 def interact_with_titanium_leg(self, item): | 98 def interact_with_titanium_leg(self, item): |
96 dented = DentedCan("dented_can") | 99 self.game.replace_inventory_item(self.name, 'dented_can') |
97 self.state.add_item(dented) | 100 return Result(_("You club the can with the femur. The can gets dented," |
98 self.state.replace_inventory_item(self.name, dented.name) | 101 " but doesn't open."), soundfile="can_hit.ogg") |
99 return Result("You club the can with the femur. The can gets dented," | |
100 " but doesn't open.", soundfile="can_hit.ogg") | |
101 | 102 |
102 | 103 |
103 class DentedCan(BaseCan): | 104 class DentedCan(BaseCan): |
104 "A can banged on with the femur" | 105 "A can banged on with the femur" |
105 | 106 |
107 NAME = 'dented_can' | |
106 INVENTORY_IMAGE = "dented_can.png" | 108 INVENTORY_IMAGE = "dented_can.png" |
107 CURSOR = CursorSprite('dented_can_cursor.png') | 109 CURSOR = CursorSprite('dented_can_cursor.png') |
108 | 110 |
109 def interact_with_titanium_leg(self, item): | 111 def interact_with_titanium_leg(self, item): |
110 return Result("You club the can with the femur. The dents shift" | 112 return Result(_("You club the can with the femur. The dents shift" |
111 " around, but it still doesn't open.", | 113 " around, but it still doesn't open."), |
112 soundfile="can_hit.ogg") | 114 soundfile="can_hit.ogg") |
113 | 115 |
114 | 116 |
115 class CansOnShelf(Thing): | 117 class CansOnShelf(Thing): |
116 | 118 |
127 | 129 |
128 INITIAL_DATA = { | 130 INITIAL_DATA = { |
129 'cans_available': 3, | 131 'cans_available': 3, |
130 } | 132 } |
131 | 133 |
134 def should_add(self): | |
135 return self.get_data('cans_available') > 0 | |
136 | |
137 def select_interact(self): | |
138 return '%icans' % (self.get_data('cans_available'),) | |
139 | |
132 def interact_without(self): | 140 def interact_without(self): |
133 starting_cans = self.get_data('cans_available') | 141 starting_cans = self.get_data('cans_available') |
134 if starting_cans > 0: | 142 if starting_cans > 0: |
135 can = FullCan("full_can") | 143 self.game.add_inventory_item('full_can') |
136 self.state.add_item(can) | |
137 self.state.add_inventory_item(can.name) | |
138 self.set_data('cans_available', starting_cans - 1) | 144 self.set_data('cans_available', starting_cans - 1) |
139 self.set_interact('%icans' % (starting_cans - 1)) | 145 self.set_interact() |
140 if starting_cans == 1: | 146 if starting_cans == 1: |
141 self.scene.remove_thing(self) | 147 self.scene.remove_thing(self) |
142 return Result({ | 148 return Result({ |
143 3: "Best before a long time in the past." | 149 3: _("Best before a long time in the past." |
144 " Better not eat these.", | 150 " Better not eat these."), |
145 2: "Mmmm. Nutritious bacteria stew.", | 151 2: _("Mmmm. Nutritious bacteria stew."), |
146 1: "Candied silkworms. Who stocked this place?!", | 152 1: _("Candied silkworms. Who stocked this place?!"), |
147 }[starting_cans]) | 153 }[starting_cans]) |
148 else: | 154 else: |
149 return Result("The rest of the cans are rusted beyond usefulness.") | 155 return Result(_("The rest of the cans are rusted beyond " |
156 "usefulness.")) | |
150 | 157 |
151 def get_description(self): | 158 def get_description(self): |
152 return "The contents of these cans look synthetic." | 159 return _("The contents of these cans look synthetic.") |
153 | 160 |
154 | 161 |
155 class Tubes(Thing): | 162 class Tubes(Thing): |
156 | 163 |
157 NAME = "mess.tubes" | 164 NAME = "mess.tubes" |
169 "status": "blocked", | 176 "status": "blocked", |
170 } | 177 } |
171 | 178 |
172 def get_description(self): | 179 def get_description(self): |
173 if self.get_data('status') == "blocked": | 180 if self.get_data('status') == "blocked": |
174 return ("The broccoli seems to have become" | 181 return _("The broccoli seems to have become" |
175 " entangled with something.") | 182 " entangled with something.") |
176 elif self.get_data("status") == "broken": | 183 elif self.get_data("status") == "broken": |
177 return "These broken pipes look important." | 184 return _("These broken pipes look important.") |
178 elif self.get_data("status") == "replaced": | 185 elif self.get_data("status") == "replaced": |
179 return ("The pipes have been repaired but are the repairs" | 186 return _("The pipes have been repaired but are the repairs" |
180 " aren't airtight, yet") | 187 " aren't airtight, yet") |
181 else: | 188 else: |
182 return "Your fix looks like it's holding up well." | 189 return _("Your fix looks like it's holding up well.") |
190 | |
191 def select_interact(self): | |
192 return self.get_data('status') | |
183 | 193 |
184 def interact_with_machete(self, item): | 194 def interact_with_machete(self, item): |
185 if self.get_data("status") == "blocked": | 195 if self.get_data("status") == "blocked": |
186 self.set_data("status", "broken") | 196 self.set_data("status", "broken") |
187 self.set_interact("broken") | 197 self.set_interact() |
188 return Result("With a flurry of disgusting mutant vegetable " | 198 return Result(_("With a flurry of disgusting mutant vegetable " |
189 "chunks, you clear the overgrown broccoli away from " | 199 "chunks, you clear the overgrown broccoli away " |
190 "the access panel and reveal some broken tubes. " | 200 "from the access panel and reveal some broken " |
191 "They look important.", | 201 "tubes. They look important."), |
192 soundfile='chopping.ogg') | 202 soundfile='chopping.ogg') |
193 elif self.get_data("status") == "broken": | 203 elif self.get_data("status") == "broken": |
194 return Result("It looks broken enough already.") | 204 return Result(_("It looks broken enough already.")) |
195 elif self.get_data("status") == "replaced": | 205 elif self.get_data("status") == "replaced": |
196 return Result("Cutting holes won't repair the leaks.") | 206 return Result(_("Cutting holes won't repair the leaks.")) |
197 else: | 207 else: |
198 return Result("After all that effort fixing it, chopping it to " | 208 return Result(_("After all that effort fixing it, chopping it to " |
199 "bits doesn't seem very smart.") | 209 "bits doesn't seem very smart.")) |
200 | 210 |
201 def interact_with_cryo_pipes_three(self, item): | 211 def interact_with_cryo_pipes_three(self, item): |
202 if self.get_data("status") == "blocked": | 212 if self.get_data("status") == "blocked": |
203 return Result("It would get lost in the fronds.") | 213 return Result(_("It would get lost in the fronds.")) |
204 else: | 214 else: |
205 self.state.remove_inventory_item(item.name) | 215 self.game.remove_inventory_item(item.name) |
206 self.set_data('status', 'replaced') | 216 self.set_data('status', 'replaced') |
207 self.set_interact("replaced") | 217 self.set_interact() |
208 self.scene.set_data('life support status', 'replaced') | 218 self.scene.set_data('life support status', 'replaced') |
209 return Result("The pipes slot neatly into place, but don't make" | 219 return Result(_("The pipes slot neatly into place, but don't make" |
210 " an airtight seal. One of the pipes has cracked" | 220 " an airtight seal. One of the pipes has cracked" |
211 " slightly as well.") | 221 " slightly as well.")) |
212 | 222 |
213 def interact_with_duct_tape(self, item): | 223 def interact_with_duct_tape(self, item): |
214 if self.get_data("status") == "broken": | 224 if self.get_data("status") == "broken": |
215 return Result("It would get lost in the fronds.") | 225 return Result(_("It would get lost in the fronds.")) |
216 elif self.get_data("status") == 'fixed': | 226 elif self.get_data("status") == 'fixed': |
217 return Result("There's quite enough tape on the ducting already.") | 227 return Result( |
228 _("There's quite enough tape on the ducting already.")) | |
218 else: | 229 else: |
219 self.set_data("fixed", True) | 230 self.set_data("fixed", True) |
220 self.set_data("status", "fixed") | 231 self.set_data("status", "fixed") |
221 self.set_interact("fixed") | 232 self.set_interact() |
222 self.scene.set_data('life support status', 'fixed') | 233 self.scene.set_data('life support status', 'fixed') |
223 # TODO: A less anticlimactic climax? | 234 return Result(_("It takes quite a lot of tape, but eventually " |
224 return Result("It takes quite a lot of tape, but eventually" | 235 "everything is airtight and ready to hold " |
225 "everything is airtight and ready to hold pressure." | 236 "pressure. Who'd've thought duct tape could " |
226 " Who'd've thought duct tape could actually be used" | 237 "actually be used to tape ducts?")) |
227 " to tape ducts?") | |
228 | 238 |
229 def interact_without(self): | 239 def interact_without(self): |
230 if self.get_data("status") == "blocked": | 240 if self.get_data("status") == "blocked": |
231 return Result("The mutant broccoli resists your best efforts.") | 241 return Result(_("The mutant broccoli resists your best efforts.")) |
232 elif self.get_data("status") == "broken": | 242 elif self.get_data("status") == "broken": |
233 return Result("Shoving the broken pipes around doesn't help much.") | 243 return Result(_("Shoving the broken pipes around doesn't help " |
244 "much.")) | |
234 elif self.get_data("status") == "replaced": | 245 elif self.get_data("status") == "replaced": |
235 return Result("Do you really want to hold it together for the " | 246 return Result(_("Do you really want to hold it together for the " |
236 "rest of the voyage?") | 247 "rest of the voyage?")) |
237 else: | 248 else: |
238 return Result("You don't find any leaks. Good job, Prisoner %s." | 249 return Result(_("You don't find any leaks. Good job, Prisoner %s.") |
239 % PLAYER_ID) | 250 % PLAYER_ID) |
240 | 251 |
241 | 252 |
242 class Boomslang(Thing): | 253 class Boomslang(Thing): |
243 NAME = 'mess.boomslang' | 254 NAME = 'mess.boomslang' |
255 | 266 |
256 INITIAL_DATA = { | 267 INITIAL_DATA = { |
257 'anim_pos': -1, | 268 'anim_pos': -1, |
258 } | 269 } |
259 | 270 |
260 HISS = get_sound('boomslang.ogg') | 271 HISS = 'boomslang.ogg' |
261 | 272 |
262 def is_interactive(self, tool=None): | 273 def is_interactive(self, tool=None): |
263 return False | 274 return False |
264 | 275 |
265 def animate(self): | 276 def animate(self): |
277 hiss = self.game.gd.sound.get_sound(self.HISS) | |
266 if self.get_data('anim_pos') > -1: | 278 if self.get_data('anim_pos') > -1: |
267 self.current_interact.animate() | 279 self.current_interact.animate() |
268 if self.get_data('anim_pos') > self.current_interact._anim_pos: | 280 if self.get_data('anim_pos') > self.current_interact._anim_pos: |
269 self.set_interact('no_snake') | 281 self._set_interact('no_snake') |
270 self.set_data('anim_pos', -1) | 282 self.set_data('anim_pos', -1) |
271 else: | 283 else: |
272 self.set_data('anim_pos', self.current_interact._anim_pos) | 284 self.set_data('anim_pos', self.current_interact._anim_pos) |
273 return True | 285 return True |
274 if randint(0, 30 * constants.FRAME_RATE) == 0: | 286 if randint(0, 30 * self.game.gd.constants.frame_rate) == 0: |
275 self.set_interact('snake') | 287 self._set_interact('snake') |
276 self.set_data('anim_pos', 0) | 288 self.set_data('anim_pos', 0) |
277 self.HISS.play() | 289 hiss.play() |
278 return False | 290 return False |
279 | 291 |
280 | 292 |
281 class DetergentThing(Thing): | 293 class DetergentThing(Thing): |
282 | 294 |
292 | 304 |
293 INITIAL_DATA = { | 305 INITIAL_DATA = { |
294 'taken': False, | 306 'taken': False, |
295 } | 307 } |
296 | 308 |
309 def select_interact(self): | |
310 if self.get_data('taken'): | |
311 return 'taken' | |
312 return self.INITIAL | |
313 | |
297 def interact_without(self): | 314 def interact_without(self): |
298 if self.get_data('taken'): | 315 if self.get_data('taken'): |
299 return Result("The remaining bottles leak.") | 316 return Result(_("The remaining bottles leak.")) |
300 self.set_data('taken', True) | 317 self.set_data('taken', True) |
301 self.set_interact('taken') | 318 self.set_interact() |
302 self.state.add_inventory_item('detergent_bottle') | 319 self.game.add_inventory_item('detergent_bottle') |
303 return Result("You pick up an empty dishwashing liquid bottle. You" | 320 return Result(_("You pick up an empty dishwashing liquid bottle. You" |
304 " can't find any sponges.") | 321 " can't find any sponges.")) |
305 | 322 |
306 def get_description(self): | 323 def get_description(self): |
307 return "Empty plastic containers. They used to hold dishwasher soap." | 324 return _("Empty plastic containers. " |
325 "They used to hold dishwasher soap.") | |
308 | 326 |
309 | 327 |
310 class DetergentBottle(Item): | 328 class DetergentBottle(Item): |
329 NAME = 'detergent_bottle' | |
311 INVENTORY_IMAGE = 'bottle_empty.png' | 330 INVENTORY_IMAGE = 'bottle_empty.png' |
312 CURSOR = CursorSprite('bottle_empty_cursor.png', 27, 7) | 331 CURSOR = CursorSprite('bottle_empty_cursor.png', 27, 7) |
313 | 332 |
314 | 333 |
315 class ToMap(Door): | 334 class ToMap(Door): |