Creating a Controller
From LagoonWiki
Creating a Controller
Python
Create a python class, generaly in the scripts/controller/unitControllers directory. import all the usual stuff
from common.defs import * from npython import * import math from controller import PyController from lagoonmath import vector3 from common.displayer import Displayer
So this allows us all the usual access to the engine, including the debuging displayer system Next we create a class which extends from PyController, and overwrite the 3 key functions
class MoveController(PyController):
def __init__(self, entityPath)
PyController.__init__(self, entityPath)
def on_enter(self):
PyController.on_enter(self)
self.displayer = Displayer()
def on_exit(self):
PyController.on_exit(self)
self.displayer.clear()
def on_tick(self, time, dtime):
command_point = vector3(call('%s.gv' % self.entityPath, 'command_point')) # Where in the world in the right click happens gets set in a command_point variable
pos = vector3(call('%s.gv' % self.entityPath, 'pos')) #Where our boat is right now
dp = command_point - pos
self.displayer.clear()
self.displayer.drawLine(pos, command_point)
d = dp.len()
if d > 100.0: # we are more then 100 units from the goal
newDesiredSpeed = call('%s.gf' % self.entityPath, 'maxSpeed') #full speed ahead
newDesiredHeading = math.atan2(dp.x, dp.z) #aim at the goal
call('%s.sf' % self.entityPath, 'desiredSpeed', newDesiredSpeed)
call('%s.sf' % self.entityPath, 'desiredHeading', newDesiredHeading)
else:
call('%s.sf' % self.entityPath, 'desiredSpeed', 0.0)
this finishes our class, which simply tells the boat to go to some destination point, next we have to register this class with the controllerServer so it knows which controllre to create when the rmenu event happens
from controller import controllerServer
controllerServer.register_PyController('MoveController', MoveController)
Next we have to add this class to the __init__.py in unitControllers:
#file unitControllers/__init__.py from moveController import MoveController
Finally we have to go and actually add this element to the rmenu
#file: common/rmenu.py
if unitToWorld.add():
RMenuItem('Move', RMENU_SET_CONTROLLER', data='MoveController') #name for rmenu, event to create a controller, same string that we register the class to
C++
Create a controller in c++ allows you to do things more effeciently computationally.
use the classbuilder to create your class
cd code/templates && wish classbuilder.tcl Classname: nMoveController Superclass Name: nController Directory: Controller
Next add your controller to the pak file
#file code/pak/controller.pak
standardmodule nmovecontroller controller
setmods {
...
nmovecontroller
...
}
Next - edit code/inc/controller/nmovecontroller.h
-- void Tick virtual void on_enter() virtual on_exit() virtual on_tick(time, dtime) //define vars protected: var var_pos; var var_command_point; var var_desiredSpeed; var var_maxSpeed; var var_desiredHeading;
Next edit code/src/controller/nmovecontroller_main.cc
--void Tick
void nMoveController::initvars()
//.connect and default all of our vars
}
void nMoveController::on_enter(){}
void nMoveController::on_exit(){}
void nMoveController::on_tick(time, dtime){
//just as with python, only in c
vector3 pos = var_pos.GetV();
vector3 command_point = var_command_point.GetV();
vector3 dp = command_point - pos;
var_desiredHeading.SetF(atan2(dp.x, dp.z));
var_desiredSpeed.SetF(var_maxSpeed.GetF());
}
C++ Controllers do not need to be registered with the controller server, it instiantiates them based on name
Finally we have to go and actually add this element to the rmenu
#file: common/rmenu.py
if unitToWorld.add():
RMenuItem('Move', RMENU_SET_CONTROLLER', data='nmovecontroller') #name for rmenu, event to create a controller, all lowercase version of our class name
