/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Silvan Nellen co-programmer: ... */ #include "script_trigger.h" #include "class_list.h" #include "script.h" #include "state.h" CREATE_SCRIPTABLE_CLASS(ScriptTrigger, CL_SCRIPT_TRIGGER, addMethod("setAbsCoor", ExecutorLua3(&PNode::setAbsCoor)) ->addMethod("getAbsCoorX", ExecutorLua0ret(&PNode::getAbsCoorX)) ->addMethod("getAbsCoorY", ExecutorLua0ret(&PNode::getAbsCoorY)) ->addMethod("getAbsCoorZ", ExecutorLua0ret(&PNode::getAbsCoorZ)) ); /** * Constructs a new ScriptTrigger. * @param root the xml element to load the parameters from. * */ ScriptTrigger::ScriptTrigger(const TiXmlElement* root) { this->setClassID(CL_SCRIPT_TRIGGER, "ScriptTrigger"); this->toList(OM_COMMON); returnCount = 1; actionFinished = false; doDebugDraw = false; invert = false; scriptCalled = false; scriptIsOk = false; triggerLasts = false; addToScript = false; if(root != NULL) { loadParams(root); if(addToScript) { script->addObject( "ScriptTrigger", this->getName()); } } } /** * Deletes the ScriptTrigger. * */ ScriptTrigger::~ScriptTrigger() { } /** * Reads the values from the tml element and sets them. * @param root the xml element to load the parameters from. * */ void ScriptTrigger::loadParams(const TiXmlElement* root) { WorldEntity ::loadParams(root); LoadParam(root, "file", this, ScriptTrigger, setScript) .describe("the fileName of the script, that should be triggered by this script trigger") .defaultValues(""); LoadParam(root, "function", this, ScriptTrigger, setFunction) .describe("the function of the script, that should be triggered by this script trigger") .defaultValues(""); LoadParam(root, "abs-coor", this, ScriptTrigger, setAbsCoor) .describe("where this script trigger should be located") .defaultValues(""); LoadParam(root, "radius", this, ScriptTrigger, setRadius) .describe("the fileName of the script, that should be triggered by this script trigger") .defaultValues(0); LoadParam(root, "delay", this, ScriptTrigger, setDelay) .describe("the delay after which the funtion sould be triggered") .defaultValues(0); LoadParam(root, "worldentity", this, ScriptTrigger, setTarget) .describe("The name of the target as it is in the *.oxw file") .defaultValues(""); LoadParam(root, "triggerparent", this, ScriptTrigger, setTriggerParent) .describe("The name of the parent as it is in the *.oxw file") .defaultValues(""); LoadParam(root, "callonce", this, ScriptTrigger, setCallOnce) .describe("True if the script shoul only be called once") .defaultValues(""); LoadParam(root, "invert", this, ScriptTrigger, setInvert) .describe("") .defaultValues(""); LoadParam(root, "triggerlasts", this, ScriptTrigger, setTriggerLasts) .describe("") .defaultValues(""); LoadParam(root, "debugdraw", this, ScriptTrigger, setDebugDraw) .describe("True if the script should only be called once") .defaultValues(""); LoadParam(root, "addtoscript", this, ScriptTrigger, setAddToScript) .describe("True if this scripttrigger should be aviable in the script") .defaultValues(""); } /** * Sets the target(a world entity) of the ScriptTrigger. If the distance between the target and this trigger is smaller than the radius, the script gets triggered. * @param target The worldentity that the script supervises. */ void ScriptTrigger::setTarget(const std::string& target) { BaseObject* targetEntity = ClassList::getObject(target, CL_WORLD_ENTITY); if (targetEntity != NULL) { this->setTarget(dynamic_cast(targetEntity)); } else { PRINTF(2)("Target %s for %s::%s does not Exist\n", target.c_str(), this->getClassName(), this->getName()); } } /** * Sets the parent of the trigger. * @param parent The parrent. */ void ScriptTrigger::setTriggerParent(const std::string& parent) { BaseObject* parentEntity = ClassList::getObject(parent, CL_WORLD_ENTITY); if (parentEntity != NULL) { this->setParent(dynamic_cast(parentEntity)); this->setParentMode(PNODE_MOVEMENT); } else { PRINTF(2)("Parent %s for %s::%s does not Exist\n", parent.c_str(), this->getClassName(), this->getName()); } } void ScriptTrigger::tick(float timestep) { if(actionFinished) return; if(triggerLasts && scriptCalled) { executeAction(timestep); return; } if( !invert && this->distance(target) < radius) { if(!callOnce) { executeAction(timestep); scriptCalled = true; } else if(callOnce && !scriptCalled) { executeAction(timestep); scriptCalled = true; } } else if( invert && this->distance(target) > radius) { if(!callOnce) { executeAction(timestep); } else if(callOnce && !scriptCalled) { executeAction(timestep); scriptCalled = true; } } //else //printf("SCRIPTTRIGGER: target out of range\n"); } void ScriptTrigger::executeAction(float timestep) { if(scriptIsOk) { //testScriptingFramework(); if(!(script->selectFunction(this->functionName,returnCount)) ) printf("Error ScriptTrigger: Selection of %s in %s failed.\n",functionName.c_str(), script->getFileName().c_str()); script->pushParam( timestep, this->functionName); if( !(script->executeFunction()) ) printf("Error ScriptTrigger: Execution of %s in %s failed.\n",functionName.c_str(), script->getFileName().c_str()); actionFinished = script->getReturnedBool(); } } void ScriptTrigger::setScript(const std::string& file) { ScriptManager* scriptManager = State::getScriptManager(); if (scriptManager != NULL) { script = scriptManager->getScriptByFile(file); if(script != NULL) { scriptIsOk = true; } } } /* void ScriptTrigger::testScriptingFramework() { std::string file("lunartest2.lua"); //get script Script* script = State::getScriptManager()->getScriptByFile(file); printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState())); //execute a function printf("----------- main -----------\n"); std::string main("main"); if( script->selectFunction(main,3)) printf("function %s selected\n",main.c_str()); script->pushParam(3.14159,main); printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState())); script->executeFunction(); int ret = script->getReturnedInt(); printf("main returned %i\n",ret); if(script->getReturnedBool()) printf("main returned true\n"); else printf("main returned false\n"); float retf = script->getReturnedFloat(); printf("main returned %f\n",retf); printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState())); //execute a 2nd function printf("----------- test -----------\n"); std::string test("test"); if( script->selectFunction(test,0)) printf("function %s selected\n",test.c_str()); script->executeFunction(); //if(argc>1) lua_dofile(script.getLuaState(), argv[1]); printf("-------------------------- top of the stack:%i\n",lua_gettop(script->getLuaState())); }*/