# HG changeset patch # User KarstenBock@gmx.net # Date 1321201154 -3600 # Node ID 75c0b728ccf31a3c42841907dea706c229dab053 # Parent 1b66e1ce226b65e7d0514dd8a051b76eb628d357 Further work on the scripting system. diff -r 1b66e1ce226b -r 75c0b728ccf3 components/fifeagent.py --- a/components/fifeagent.py Sun Nov 13 13:37:24 2011 +0100 +++ b/components/fifeagent.py Sun Nov 13 17:19:14 2011 +0100 @@ -34,4 +34,10 @@ def setup_behaviour(agent): """Attach the behaviour to the layer""" if agent.behaviour: - agent.behaviour.attachToLayer(agent.entity.getID(), agent.layer) \ No newline at end of file + agent.behaviour.attachToLayer(agent.entity.getID(), agent.layer) + +def approach(agent, target_or_location, action): + if agent.behaviour: + agent.behaviour.approach(target_or_location, action) + +commands = {"approach":approach} \ No newline at end of file diff -r 1b66e1ce226b -r 75c0b728ccf3 dialogueactions.py --- a/dialogueactions.py Sun Nov 13 13:37:24 2011 +0100 +++ b/dialogueactions.py Sun Nov 13 17:19:14 2011 +0100 @@ -94,7 +94,6 @@ @type kwargs: dict of objects """ DialogueAction.__init__(self, *args, **kwargs) - self.npc_id = args[0] def __call__(self, game_state): """ @@ -104,7 +103,7 @@ game state. @type game_state: dict of objects """ - npc_id = self.npc_id + npc_id = game_state["npc"].general.identifier # NOTE Technomage 2010-11-13: This print statement seems overly # verbose, so I'm logging it as an INFO message instead. # print("You've met {0}!".format(npc_id)) diff -r 1b66e1ce226b -r 75c0b728ccf3 gamescenecontroller.py --- a/gamescenecontroller.py Sun Nov 13 13:37:24 2011 +0100 +++ b/gamescenecontroller.py Sun Nov 13 17:19:14 2011 +0100 @@ -73,6 +73,8 @@ model, application) World.__init__(self) + self.systems.scripting.game_state = self.model.game_state + #this can be helpful for IDEs code analysis if False: assert(isinstance(self.engine, fife.Engine)) @@ -563,6 +565,7 @@ if self.paused: return ControllerBase.pump(self, dt) + World.pump(self, dt) self.updateMouse() if self.model.active_map: self.view.highlightFrontObject(self.last_mousecoords) diff -r 1b66e1ce226b -r 75c0b728ccf3 gamestate.py --- a/gamestate.py Sun Nov 13 13:37:24 2011 +0100 +++ b/gamestate.py Sun Nov 13 17:19:14 2011 +0100 @@ -26,6 +26,10 @@ self.current_map_name = None self.maps = {} self.npcs_met = set() + self.funcs = { + "meet":self.meet, + "met":self.met + } def addObject(self, object_id, map_id, game_object): @@ -68,10 +72,13 @@ @type map: String @param map: The map name. @returns: The list of objects on this map. Or an empty list""" + return [i for i in self.getObjectDictOfMap(map_id).values() + if map_id in self.objects] + + + def getObjectDictOfMap(self, map_id): if map_id in self.objects: - return [i for i in self.objects[map_id].values() \ - if map_id in self.objects] - + return self.objects[map_id] return {} def deleteObjectsFromMap(self, map_id): @@ -157,4 +164,4 @@ @type npc: str @param npc: The NPC's name or id @return: None""" - return npc in self.npcs_met + return npc in self.npcs_met \ No newline at end of file diff -r 1b66e1ce226b -r 75c0b728ccf3 systems/scriptingsystem.py --- a/systems/scriptingsystem.py Sun Nov 13 13:37:24 2011 +0100 +++ b/systems/scriptingsystem.py Sun Nov 13 17:19:14 2011 +0100 @@ -11,24 +11,31 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from collections import deque +from copy import deepcopy + from parpg.bGrease import System -from collections import deque class Script(object): """Script object""" - def __init__(self, condition, actions, system): + def __init__(self, actions, system): """Constructor""" assert(isinstance(actions, deque)) - self.condition = condition self.actions = actions + assert(isinstance(system, ScriptingSystem)) self.system = system + self.reset() + + def reset(self): + """Resets the state of the script""" + self.running_actions = deepcopy(self.actions) self.running = False self.finished = False self.time = 0 self.wait = 0 self.cur_action = None - + def update(self, time): """Advance the script""" if not self.running: @@ -39,12 +46,21 @@ if self.wait <= self.time: self.time = 0 try: - action = self.actions.popleft() - self.cur_action = action[0] - self.wait = action[1] - if len(action) >= 3: - vals = action[3:] if len(action) > 3 else () - command = action[2] + action_data = self.running_actions.popleft() + action = self.system.actions[action_data[0]] + action_params = eval(action_data[1], + self.system.funcs, + self.system.vals + ) + self.cur_action = action(self.system.world, action_params) + self.wait = action_data[2] + if len(action_data) >= 4: + vals = ( + eval(action_data[4], self.system.funcs, self.system.vals) + if len(action_data) > 4 + else () + ) + command = action_data[3] self.system.commands[command]( *vals, action=self.cur_action @@ -62,12 +78,15 @@ their behavior. """ - def __init__(self, funcs, commands): + def __init__(self, commands, actions): """Constructor""" - self.funcs = funcs + self.funcs = {} self.vals = {} - self.scripts = [] + self.scripts = {} self.commands = commands + self.conditions = [] + self.actions = actions + self.game_state = None def step(self, dt): """Execute a time step for the system. Must be defined @@ -76,11 +95,50 @@ :param dt: Time since last step invocation :type dt: float """ - for script in self.scripts: + self.vals.clear() + self.vals.update( + self.game_state.getObjectDictOfMap( + self.game_state.current_map_name) + ) + self.funcs.clear() + self.funcs.update(self.game_state.funcs) + for condition_data in self.conditions: + condition = condition_data[0] + script_name = condition_data[1] + if not self.scripts.has_key(script_name): + return + script = self.scripts[script_name] + if eval(condition, self.funcs, self.vals) and not script.running: + script.running = True + for script in self.scripts.itervalues(): assert(isinstance(script, Script)) if script.finished: - self.scripts.remove(script) + script.reset() elif script.running: script.update(dt) - elif eval(script.condition, self.funcs, self.vals): - script.running = True \ No newline at end of file + + def setScript(self, name, actions): + """Sets a script. + @param name: The name of the script + @param actions: What the script does + """ + self.scripts[name] = Script(actions, + self + ) + + def addCondition(self, condition, script_name): + """Adds a condition. + @param condition: Condition which will be evaluated + @param script_name: Name of the script that will be executed if the + condition evaluates to True. + """ + self.conditions.append((condition, script_name)) + + + def runScript(self, name): + """Runs a script with the given name + @param name: The name of the script""" + if self.scripts.has_key(name): + self.scripts[name].running = True + + \ No newline at end of file diff -r 1b66e1ce226b -r 75c0b728ccf3 world.py --- a/world.py Sun Nov 13 13:37:24 2011 +0100 +++ b/world.py Sun Nov 13 17:19:14 2011 +0100 @@ -3,7 +3,9 @@ from parpg.mode import FifeMode from parpg import components +from parpg.components.fifeagent import commands from parpg.systems import ScriptingSystem +from parpg.entities.action import ACTIONS class World(FifeMode, BaseWorld): @@ -15,7 +17,7 @@ """Configure the game world's components, systems and renderers""" for name, component in components.components.iteritems(): setattr(self.components, name, component) - self.systems.scripting = ScriptingSystem({}) + self.systems.scripting = ScriptingSystem(commands, ACTIONS) def pump(self, dt): for component in self.components: