Mercurial > parpg-core
comparison src/parpg/entities/action.py @ 178:487fba82abff
Moved the action module into the entities package.
Removed the objects package.
author | KarstenBock@gmx.net |
---|---|
date | Sun, 09 Oct 2011 21:02:48 +0200 |
parents | src/parpg/objects/action.py@c50a7adeae85 |
children | 61d158ce6bc3 |
comparison
equal
deleted
inserted
replaced
177:32dc19350db3 | 178:487fba82abff |
---|---|
1 # This file is part of PARPG. | |
2 | |
3 # PARPG is free software: you can redistribute it and/or modify | |
4 # it under the terms of the GNU General Public License as published by | |
5 # the Free Software Foundation, either version 3 of the License, or | |
6 # (at your option) any later version. | |
7 | |
8 # PARPG is distributed in the hope that it will be useful, | |
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 # GNU General Public License for more details. | |
12 | |
13 # You should have received a copy of the GNU General Public License | |
14 # along with PARPG. If not, see <http://www.gnu.org/licenses/>. | |
15 | |
16 #exceptions | |
17 | |
18 import logging | |
19 | |
20 logger = logging.getLogger('action') | |
21 | |
22 from parpg.gui import drag_drop_data as data_drag | |
23 from parpg.dialoguecontroller import DialogueController | |
24 from parpg.components import container, lockable | |
25 | |
26 | |
27 class NoSuchQuestException(Exception): | |
28 """NoQuestException is used when there is no active quest with the id""" | |
29 pass | |
30 | |
31 #classes | |
32 | |
33 class Action(object): | |
34 """Base Action class, to define the structure""" | |
35 | |
36 | |
37 def __init__(self, controller, commands = None): | |
38 """Basic action constructor | |
39 @param controller: A reference to the GameSceneController. | |
40 @type controller: parpg.GameSceneController | |
41 @param commands: Special commands that are executed | |
42 @type commands: Dictionary | |
43 """ | |
44 self.commands = commands or () | |
45 self.controller = controller | |
46 self.model = controller.model | |
47 | |
48 def execute(self): | |
49 """To be overwritten""" | |
50 #Check if there are special commands and execute them | |
51 for command_data in self.commands: | |
52 command = command_data["Command"] | |
53 if command == "SetQuestVariable": | |
54 quest_id = command_data["ID"] | |
55 variable = command_data["Variable"] | |
56 value = command_data["Value"] | |
57 quest_engine = self.model.game_state.quest_engine | |
58 if quest_engine.hasQuest(quest_id): | |
59 quest_engine[quest_id].setValue(variable, value) | |
60 else: | |
61 raise NoSuchQuestException | |
62 elif command == "ResetMouseCursor": | |
63 self.controller.resetMouseCursor() | |
64 elif command == "StopDragging": | |
65 data_drag.dragging = False | |
66 | |
67 class ChangeMapAction(Action): | |
68 """A change map scheduled""" | |
69 def __init__(self, controller, target_map_name, target_pos, commands=None): | |
70 """Initiates a change of the position of the character | |
71 possibly flagging a new map to be loaded. | |
72 @param controller: A reference to the GameSceneController. | |
73 @type controller: parpg.GameSceneController | |
74 @param commands: Special commands that are executed | |
75 @type commands: Dictionary | |
76 @type view: class derived from parpg.ViewBase | |
77 @param view: The view | |
78 @type target_map_name: String | |
79 @param target_map_name: Target map id | |
80 @type target_pos: Tuple | |
81 @param target_pos: (X, Y) coordinates on the target map. | |
82 @return: None""" | |
83 super(ChangeMapAction, self).__init__(controller, commands) | |
84 self.view = controller.view | |
85 self.target_pos = target_pos | |
86 self.target_map_name = target_map_name | |
87 | |
88 def execute(self): | |
89 """Executes the map change.""" | |
90 self.model.changeMap(self.target_map_name, | |
91 self.target_pos) | |
92 super(ChangeMapAction, self).execute() | |
93 | |
94 class OpenAction(Action): | |
95 """Open an lockable""" | |
96 def __init__(self, controller, lockable, commands=None): | |
97 """ | |
98 @param controller: A reference to the GameSceneController. | |
99 @type controller: parpg.GameSceneController | |
100 @param commands: Special commands that are executed | |
101 @type commands: Dictionary | |
102 @type view: class derived from parpg.ViewBase | |
103 @param view: The view | |
104 @param lockable: A reference to the lockable | |
105 """ | |
106 Action.__init__(self, controller, commands) | |
107 self.view = controller.view | |
108 self.lockable = lockable | |
109 | |
110 def execute(self): | |
111 """Open the lockable.""" | |
112 try: | |
113 lockable.open(self.lockable.lockable) | |
114 self.lockable.fifeagent.behaviour.animate("open") | |
115 self.lockable.fifeagent.behaviour.queue_animation("opened", | |
116 repeating=True) | |
117 except lockable.LockedError: | |
118 self.view.hud.createExamineBox(self.lockable.description.view_name, | |
119 "Locked") | |
120 Action.execute(self) | |
121 | |
122 class CloseAction(Action): | |
123 """Close an lockable""" | |
124 def __init__(self, controller, lockable, commands=None): | |
125 """ | |
126 @param controller: A reference to the GameSceneController. | |
127 @type controller: parpg.GameSceneController | |
128 @param commands: Special commands that are executed | |
129 @type commands: Dictionary | |
130 @type view: class derived from parpg.ViewBase | |
131 @param view: The view | |
132 @param lockable: A reference to the lockable | |
133 """ | |
134 Action.__init__(self, controller, commands) | |
135 self.lockable = lockable | |
136 | |
137 def execute(self): | |
138 """Close the lockable.""" | |
139 lockable.close(self.lockable.lockable) | |
140 self.lockable.fifeagent.behaviour.animate("close") | |
141 self.lockable.fifeagent.behaviour.queue_animation("closed", | |
142 repeating=True) | |
143 Action.execute(self) | |
144 | |
145 class UnlockAction(Action): | |
146 """Unlocks a lockable.""" | |
147 def __init__(self, controller, lockable, commands = None): | |
148 """ | |
149 @param controller: A reference to the GameSceneController. | |
150 @type controller: parpg.GameSceneController | |
151 @param commands: Special commands that are executed | |
152 @type commands: Dictionary | |
153 @param lockable: A reference to the lockable | |
154 """ | |
155 Action.__init__(self, controller, commands) | |
156 self.lockable = lockable | |
157 | |
158 def execute(self): | |
159 """Open the box.""" | |
160 lockable.unlock(self.lockable.lockable) | |
161 Action.execute(self) | |
162 | |
163 class LockAction(Action): | |
164 """Locks a lockable.""" | |
165 def __init__(self, controller, lockable, commands = None): | |
166 """ | |
167 @param controller: A reference to the GameSceneController. | |
168 @type controller: parpg.GameSceneController | |
169 @param commands: Special commands that are executed | |
170 @type commands: Dictionary | |
171 @param lockable: A reference to the lockable | |
172 """ | |
173 Action.__init__(self, controller, commands) | |
174 self.lockable = lockable | |
175 self.view = controller.view | |
176 | |
177 def execute(self): | |
178 """Lock the box.""" | |
179 try: | |
180 lockable.lock(self.lockable.lockable) | |
181 except lockable.OpenError: | |
182 self.view.hud.createExamineBox(self.lockable.description.view_name, | |
183 "Is open") | |
184 | |
185 Action.execute(self) | |
186 | |
187 | |
188 class ExamineAction(Action): | |
189 """Examine an object.""" | |
190 def __init__(self, controller, examine_id, examine_name, examine_desc=None, commands=None): | |
191 """ | |
192 @param controller: A reference to the GameSceneController. | |
193 @type controller: parpg.GameSceneController | |
194 @param examine_id: An object id | |
195 @type examine_id: integer | |
196 @param examine_name: An object name | |
197 @type examine_name: string | |
198 @param examine_desc: A description of the object that will be displayed. | |
199 @type examine_desc: string | |
200 @param commands: Special commands that are executed | |
201 @type commands: Dictionary | |
202 """ | |
203 super(ExamineAction, self).__init__(controller, commands) | |
204 self.view = controller.view | |
205 self.examine_id = examine_id | |
206 self.examine_name = examine_name | |
207 if examine_desc is not None: | |
208 self.examine_desc = examine_desc | |
209 else: | |
210 self.examine_desc = "No Description" | |
211 | |
212 def execute(self): | |
213 """Display the text.""" | |
214 action_text = self.examine_desc | |
215 self.view.hud.addAction(unicode(action_text)) | |
216 logger.debug(action_text) | |
217 #this code will cut the line up into smaller lines that will be displayed | |
218 place = 25 | |
219 while place < len(action_text): | |
220 if action_text[place] == ' ': | |
221 action_text = action_text[:place] +'\n'+action_text[place:] | |
222 place += 26 #plus 1 character to offset the new line | |
223 else: place += 1 | |
224 self.view.displayObjectText(self.examine_id, unicode(action_text), time=3000) | |
225 Action.execute(self) | |
226 | |
227 class ExamineItemAction(Action): | |
228 """Examine an item.""" | |
229 def __init__(self, controller, examine_name, examine_desc, commands = None): | |
230 """ | |
231 @param controller: A reference to the GameSceneController. | |
232 @type controller: parpg.GameSceneController | |
233 @param commands: Special commands that are executed | |
234 @type commands: Dictionary | |
235 @type view: class derived from parpg.ViewBase | |
236 @param view: The view | |
237 @type examine_name: String | |
238 @param examine_name: Name of the object to be examined. | |
239 @type examine_name: String | |
240 @param examine_name: Description of the object to be examined. | |
241 """ | |
242 super(ExamineItemAction, self).__init__(controller, commands) | |
243 self.view = controller.view | |
244 self.examine_name = examine_name | |
245 self.examine_desc = examine_desc | |
246 | |
247 def execute(self): | |
248 """Display the text.""" | |
249 action_text = unicode(self.examine_desc) | |
250 self.view.hud.addAction(action_text) | |
251 logger.debug(action_text) | |
252 Action.execute(self) | |
253 | |
254 class ExamineContentsAction(Action): | |
255 """Examine the contens of an container""" | |
256 def __init__(self, controller, container, commands=None): | |
257 """ | |
258 @param controller: A reference to the GameSceneController. | |
259 @type controller: parpg.GameSceneController | |
260 @param container: The container | |
261 @type container: parpg.entities.General | |
262 @param commands: Special commands that are executed | |
263 @type commands: Dictionary | |
264 """ | |
265 Action.__init__(self, controller, commands) | |
266 self.view = controller.view | |
267 self.container = container | |
268 | |
269 def execute(self): | |
270 """Examine the contents""" | |
271 self.view.hud.createBoxGUI(self.container.description.view_name, | |
272 self.container.container) | |
273 Action.execute(self) | |
274 | |
275 class ReadAction(Action): | |
276 """Read a text.""" | |
277 def __init__(self, controller, text_name, text, commands = None): | |
278 """ | |
279 @param controller: A reference to the GameSceneController. | |
280 @type controller: parpg.GameSceneController | |
281 @param commands: Special commands that are executed | |
282 @type commands: Dictionary | |
283 @param view: The view | |
284 @type view: class derived from parpg.ViewBase | |
285 @param text_name: Name of the object containing the text | |
286 @type text_name: String | |
287 @param text: Text to be displayied | |
288 @type text: String | |
289 """ | |
290 super(ReadAction, self).__init__(controller, commands) | |
291 self.view = controller.view | |
292 self.text_name = text_name | |
293 self.text = text | |
294 | |
295 def execute(self): | |
296 """Examine the box.""" | |
297 action_text = unicode('\n'.join(["You read " + self.text_name + ".", | |
298 self.text])) | |
299 self.view.hud.addAction(action_text) | |
300 logger.debug(action_text) | |
301 super(ReadAction, self).execute() | |
302 | |
303 class TalkAction(Action): | |
304 """An action to represent starting a dialogue""" | |
305 def __init__(self, controller, npc, commands = None): | |
306 """ | |
307 @param controller: A reference to the GameSceneController. | |
308 @type controller: parpg.GameSceneController | |
309 @param commands: Special commands that are executed | |
310 @type commands: Dictionary | |
311 @type view: class derived from parpg.ViewBase | |
312 @param view: The view | |
313 @type npc: NonPlayerCharacter | |
314 @param npc: NPC to interact with. | |
315 """ | |
316 super(TalkAction, self).__init__(controller, commands) | |
317 self.view = controller.view | |
318 self.npc = npc | |
319 | |
320 def execute(self): | |
321 """Talk with the NPC when close enough, otherwise move closer. | |
322 @return: None""" | |
323 player_char = self.model.game_state.\ | |
324 getObjectById("PlayerCharacter").fifeagent | |
325 npc_coordinates = self.npc.fifeagent.behaviour.getLocation().\ | |
326 getLayerCoordinates() | |
327 pc_coordinates = player_char.behaviour.agent.\ | |
328 getLocation().getLayerCoordinates() | |
329 | |
330 distance_squared = (npc_coordinates.x - pc_coordinates.x) *\ | |
331 (npc_coordinates.x - pc_coordinates.x) +\ | |
332 (npc_coordinates.y - pc_coordinates.y) *\ | |
333 (npc_coordinates.y - pc_coordinates.y) | |
334 | |
335 # If we are too far away, we approach the NPC again | |
336 if distance_squared > 2: | |
337 player_char.behaviour.approach( | |
338 [npc_coordinates.x, npc_coordinates.y], | |
339 TalkAction(self.controller, | |
340 self.npc, | |
341 self.commands | |
342 ) | |
343 ) | |
344 else: | |
345 player_char.behaviour.agent.act( | |
346 'stand', | |
347 self.npc.fifeagent.behaviour.getLocation() | |
348 ) | |
349 | |
350 if self.npc.dialogue.dialogue is not None: | |
351 dialogue_controller = DialogueController( | |
352 self.controller.engine, | |
353 self.view, | |
354 self.model, | |
355 self.controller.application | |
356 ) | |
357 self.controller.application.manager.push_mode( | |
358 dialogue_controller | |
359 ) | |
360 dialogue_controller.startTalk(self.npc) | |
361 else: | |
362 self.npc.fifeagent.behaviour.agent.say("Leave me alone!", 1000) | |
363 | |
364 self.model.game_state.getObjectById("PlayerCharacter").\ | |
365 fifeagent.behaviour.idle() | |
366 self.model.game_state.getObjectById("PlayerCharacter").\ | |
367 fifeagent.behaviour.nextAction = None | |
368 super(TalkAction, self).execute() | |
369 | |
370 class UseAction(Action): | |
371 """Action for carryable items. It executes special commands that can be only | |
372 used on carryable utens""" | |
373 | |
374 | |
375 def __init__(self, controller, item, commands = None): | |
376 """ | |
377 @param controller: A reference to the GameSceneController. | |
378 @type controller: parpg.GameSceneController | |
379 @param item: Item on which the action is called | |
380 @type item: CarryableItem | |
381 @param commands: Special commands that are executed | |
382 @type commands: Dictionary | |
383 """ | |
384 super(UseAction, self).__init__(controller, commands) | |
385 self.view = controller.view | |
386 self.item = item | |
387 | |
388 def execute(self): | |
389 #Check if there are special commands and execute them | |
390 for command_data in self.commands: | |
391 command = command_data["Command"] | |
392 if command == "ReplaceItem": | |
393 object_id = command_data["ID"] | |
394 object_type = command_data["ObjectType"] | |
395 containable = self.item.containable | |
396 new_item = self.model.createItemByType(object_type, | |
397 object_id, | |
398 self.item.world) | |
399 container.put_item(containable.container, | |
400 new_item.containable, | |
401 containable.slot) | |
402 self.model.deleteObject(self.item.general.identifier) | |
403 self.item.delete() | |
404 self.view.hud.inventory.updateImages() | |
405 super(UseAction, self).execute() | |
406 | |
407 class PickUpAction(Action): | |
408 """Action for picking up items from a map""" | |
409 | |
410 def __init__(self, controller, item, commands = None): | |
411 super(PickUpAction, self).__init__(controller, commands) | |
412 self.item = item | |
413 self.view = controller.view | |
414 | |
415 def execute(self): | |
416 real_item = self.item.containable | |
417 self.item.fifeagent = None | |
418 player = self.model.game_state.getObjectById("PlayerCharacter") | |
419 self.model.moveObject(self.item.general.identifier, None) | |
420 self.model.updateObjectDB(self.item.world) | |
421 container.put_item(player.container, real_item) | |
422 super(PickUpAction, self).execute() | |
423 | |
424 class DropItemAction(Action): | |
425 """Action for dropping an items on a map""" | |
426 def __init__(self, controller, item, commands = None): | |
427 super(DropItemAction, self).__init__(controller, commands) | |
428 self.item = item | |
429 | |
430 def execute(self): | |
431 map_name = self.model.game_state.current_map_name | |
432 identifier = self.item.entity.general.identifier | |
433 agent_values = self.model.items[identifier] | |
434 coords = (self.model.game_state.getObjectById("PlayerCharacter"). | |
435 fifeagent.behaviour.getLocation().getExactLayerCoordinates() | |
436 ) | |
437 agent_values["Position"] = (coords.x, coords.y) | |
438 agent_values["Rotation"] = 0 | |
439 agent_values["Map"] = map_name | |
440 self.model.deleteObject(identifier) | |
441 self.model.addAgent(self.model.ALL_AGENTS_KEY, | |
442 {identifier: agent_values}) | |
443 self.model.placeAgents(self.item.entity.world) | |
444 self.model.updateObjectDB(self.item.entity.world) | |
445 super(DropItemAction, self).execute() | |
446 | |
447 class DropItemFromContainerAction(DropItemAction): | |
448 """Action for dropping an items from the Inventory to a map""" | |
449 | |
450 def __init__(self, controller, item, container_gui, commands = None): | |
451 super(DropItemFromContainerAction, self).__init__(controller, item, commands) | |
452 self.container_gui = container_gui | |
453 | |
454 def execute(self): | |
455 super(DropItemFromContainerAction, self).execute() | |
456 container.remove_item(self.item.container, self.item.slot) | |
457 self.container_gui.updateImages() | |
458 | |
459 class BrewBeerAction(Action): | |
460 """Action for brewing beer in a pot""" | |
461 def __init__(self, controller, pot, commands = None): | |
462 super(BrewBeerAction, self).__init__(controller, commands) | |
463 self.pot = pot.container | |
464 self.view = controller.view | |
465 | |
466 def execute(self): | |
467 """Brew the beer""" | |
468 has_water = False | |
469 has_yeast = False | |
470 has_fruit = False | |
471 has_wood = False | |
472 has_bottle = False | |
473 player_character = (self.model.game_state. | |
474 getObjectById("PlayerCharacter").container) | |
475 for item in self.pot.children: | |
476 if not item: | |
477 continue | |
478 if item.item_type == "Questionable water": | |
479 if has_water: | |
480 self.view.hud.addAction(unicode(\ | |
481 "Please put only 1 water in the pot")) | |
482 return | |
483 has_water = True | |
484 water_type = 1 | |
485 water = item | |
486 elif item.item_type == "Pure water": | |
487 if has_water: | |
488 self.view.hud.addAction(unicode(\ | |
489 "Please put only 1 water in the pot")) | |
490 return | |
491 has_water = True | |
492 water_type = 2 | |
493 water = item | |
494 elif item.item_type == "Grain": | |
495 if has_fruit: | |
496 self.view.hud.addAction(unicode(\ | |
497 "Please put only 1 fruit in the pot")) | |
498 return | |
499 has_fruit = True | |
500 fruit_type = 3 | |
501 fruit = item | |
502 elif item.item_type == "Wild potato": | |
503 if has_fruit: | |
504 self.view.hud.addAction(unicode(\ | |
505 "Please put only 1 fruit in the pot")) | |
506 return | |
507 has_fruit = True | |
508 fruit_type = 2 | |
509 fruit = item | |
510 elif item.item_type == "Rotten yam": | |
511 if has_fruit: | |
512 self.view.hud.addAction(unicode(\ | |
513 "Please put only 1 fruit in the pot")) | |
514 return | |
515 has_fruit = True | |
516 fruit_type = 1 | |
517 fruit = item | |
518 elif item.item_type == "Yeast": | |
519 if has_yeast: | |
520 self.view.hud.addAction(unicode(\ | |
521 "Please put only 1 yeast in the pot")) | |
522 return | |
523 has_yeast = True | |
524 yeast = item | |
525 else: | |
526 self.view.hud.addAction(unicode( | |
527 "Item " + (item.entity.description.view_name) + | |
528 " is not needed for brewing beer")) | |
529 self.view.hud.addAction(unicode(\ | |
530 "Please put only ingredients for the beer in the pot.\ | |
531 Things like bottles and wood have to be in your inventory")) | |
532 return | |
533 wood = container.get_item(player_character, "Wood") | |
534 if wood: | |
535 has_wood = True | |
536 bottle = container.get_item(player_character, "Empty beer bottle") | |
537 if bottle: | |
538 has_bottle = True | |
539 if has_water and has_fruit and has_wood and has_bottle: | |
540 container.remove_item(self.pot, water.slot) | |
541 container.remove_item(self.pot, fruit.slot) | |
542 if has_yeast: | |
543 container.remove_item(self.pot, yeast.slot) | |
544 container.remove_item(player_character, wood.slot) | |
545 new_item = (self.model.createItemByType("Beer", "Beer", | |
546 self.pot.entity.world) | |
547 ) | |
548 container.put_item(player_character, new_item.containable) | |
549 self.view.hud.inventory.updateImages() | |
550 beer_quality = 0 | |
551 if water_type == 1: | |
552 if fruit_type == 1: | |
553 beer_quality = -1 | |
554 elif fruit_type == 2: | |
555 beer_quality = 2 | |
556 elif fruit_type == 3: | |
557 beer_quality = 3 | |
558 if water_type == 2: | |
559 if fruit_type == 1: | |
560 beer_quality = 1 | |
561 elif fruit_type == 2: | |
562 beer_quality = 3 | |
563 elif fruit_type == 3: | |
564 beer_quality = 4 | |
565 if beer_quality > 0 and has_yeast: | |
566 beer_quality += 1 | |
567 self.model.game_state.quest_engine.quests["beer"].\ | |
568 setValue("beer_quality", beer_quality) | |
569 else: | |
570 self.view.hud.addAction(unicode( | |
571 """For brewing beer you need at least: | |
572 In the pot: | |
573 Fruit (like grain, potato, yam) | |
574 Water | |
575 Optionally: | |
576 Good quality yeast. | |
577 Wild yeast will be used if none present. | |
578 In the inventory: | |
579 Wood | |
580 Empty bottle""")) | |
581 super(BrewBeerAction, self).execute() | |
582 | |
583 ACTIONS = {"ChangeMap":ChangeMapAction, | |
584 "Open":OpenAction, | |
585 "Close":CloseAction, | |
586 "Unlock":UnlockAction, | |
587 "Lock":LockAction, | |
588 "ExamineItem":ExamineItemAction, | |
589 "Examine":ExamineAction, | |
590 "Look":ExamineItemAction, | |
591 "Read":ReadAction, | |
592 "Talk":TalkAction, | |
593 "Use":UseAction, | |
594 "PickUp":PickUpAction, | |
595 "DropFromInventory":DropItemFromContainerAction, | |
596 "BrewBeer":BrewBeerAction, | |
597 "ExamineContents": ExamineContentsAction, | |
598 } |