diff --git a/projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj b/projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj
index 9e3316846e4..a62c8902ad2 100644
--- a/projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj
+++ b/projectfiles_vc9/gameengine/ketsji/KX_ketsji.vcproj
@@ -552,7 +552,7 @@
>
+
+
@@ -857,11 +861,11 @@
>
+
+
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 5a06c251b88..6a43251efdd 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -468,6 +468,8 @@ void init_actuator(bActuator *act)
case ACT_ARMATURE:
act->data = MEM_callocN(sizeof( bArmatureActuator ), "armature act");
break;
+ case ACT_STEERING:
+ act->data = MEM_callocN(sizeof( bSteeringActuator), "steering act");
default:
; /* this is very severe... I cannot make any memory for this */
/* logic brick... */
@@ -611,6 +613,7 @@ void sca_remove_ob_poin(Object *obt, Object *ob)
bMessageActuator *ma;
bParentActuator *para;
bArmatureActuator *aa;
+ bSteeringActuator *sta;
sens= obt->sensors.first;
while(sens) {
@@ -658,6 +661,11 @@ void sca_remove_ob_poin(Object *obt, Object *ob)
if (aa->target == ob) aa->target = NULL;
if (aa->subtarget == ob) aa->subtarget = NULL;
break;
+ case ACT_STEERING:
+ sta = act->data;
+ if (sta->target==ob) sta->target = NULL;
+ if (sta->navmesh==ob) sta->navmesh = NULL;
+ break;
}
act= act->next;
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 381fc868a0d..5b732d5b1de 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3612,6 +3612,11 @@ static void lib_link_object(FileData *fd, Main *main)
arma->target= newlibadr(fd, ob->id.lib, arma->target);
arma->subtarget= newlibadr(fd, ob->id.lib, arma->subtarget);
}
+ else if(act->type==ACT_STEERING) {
+ bSteeringActuator *steeringa = act->data;
+ steeringa->target = newlibadr(fd, ob->id.lib, steeringa->target);
+ steeringa->navmesh = newlibadr(fd, ob->id.lib, steeringa->navmesh);
+ }
act= act->next;
}
@@ -11745,6 +11750,11 @@ static void expand_object(FileData *fd, Main *mainvar, Object *ob)
bArmatureActuator *arma= act->data;
expand_doit(fd, mainvar, arma->target);
}
+ else if(act->type==ACT_STEERING) {
+ bSteeringActuator *sta= act->data;
+ expand_doit(fd, mainvar, sta->target);
+ expand_doit(fd, mainvar, sta->navmesh);
+ }
act= act->next;
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 5f2ee73e129..8e15601ff51 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -858,6 +858,9 @@ static void write_actuators(WriteData *wd, ListBase *lb)
case ACT_ARMATURE:
writestruct(wd, DATA, "bArmatureActuator", 1, act->data);
break;
+ case ACT_STEERING:
+ writestruct(wd, DATA, "bSteeringActuator", 1, act->data);
+ break;
default:
; /* error: don't know how to write this file */
}
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index f9310909f2c..70635e76055 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -710,6 +710,8 @@ static char *actuator_name(int type)
return "State";
case ACT_ARMATURE:
return "Armature";
+ case ACT_STEERING:
+ return "Steering";
}
return "unknown";
}
@@ -2895,7 +2897,6 @@ static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, sh
uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1);
yco-= ysize;
break;
-
default:
ysize= 4;
@@ -4232,6 +4233,20 @@ static void draw_actuator_visibility(uiLayout *layout, PointerRNA *ptr)
uiItemR(row, ptr, "children", 0, NULL, 0);
}
+static void draw_actuator_steering(uiLayout *layout, PointerRNA *ptr)
+{
+ uiLayout *row;
+
+ uiItemR(layout, ptr, "mode", 0, NULL, 0);
+ uiItemR(layout, ptr, "target", 0, NULL, 0);
+ uiItemR(layout, ptr, "navmesh", 0, NULL, 0);
+
+ row = uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "distance", 0, NULL, 0);
+ uiItemR(row, ptr, "movement", 0, NULL, 0);
+}
+
+
void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C)
{
uiLayout *box;
@@ -4296,6 +4311,8 @@ void draw_brick_actuator(uiLayout *layout, PointerRNA *ptr, bContext *C)
case ACT_VISIBILITY:
draw_actuator_visibility(box, ptr);
break;
+ case ACT_STEERING:
+ draw_actuator_steering(box, ptr);
}
}
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 03200b784b4..7f2323b941e 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -214,6 +214,15 @@ typedef struct bArmatureActuator {
struct Object *subtarget;
} bArmatureActuator;
+typedef struct bSteeringActuator {
+ char pad[4];
+ int type; /* 0=seek, 1=flee, 2=path following */
+ float dist;
+ float movement;
+ struct Object *target;
+ struct Object *navmesh;
+} bSteeringActuator;
+
typedef struct bActuator {
struct bActuator *next, *prev, *mynew;
short type;
@@ -286,6 +295,7 @@ typedef struct FreeCamera {
#define ACT_SHAPEACTION 21
#define ACT_STATE 22
#define ACT_ARMATURE 23
+#define ACT_STEERING 24
/* actuator flag */
#define ACT_SHOW 1
@@ -502,6 +512,11 @@ typedef struct FreeCamera {
#define ACT_CAMERA_X (float)'x'
#define ACT_CAMERA_Y (float)'y'
+/* steeringactuator->type */
+#define ACT_STEERING_SEEK 0
+#define ACT_STEERING_FLEE 1
+#define ACT_STEERING_PATHFOLLOWING 2
+
#endif
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index 5f802fd47f1..5a55888614f 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -54,6 +54,7 @@ EnumPropertyItem actuator_type_items[] ={
{ACT_SOUND, "SOUND", 0, "Sound", ""},
{ACT_STATE, "STATE", 0, "State", ""},
{ACT_VISIBILITY, "VISIBILITY", 0, "Visibility", ""},
+ {ACT_STEERING, "STEERING", 0, "Steering", ""},
{0, NULL, 0, NULL, NULL}};
EnumPropertyItem edit_object_type_items[] ={
@@ -109,6 +110,8 @@ static StructRNA* rna_Actuator_refine(struct PointerRNA *ptr)
return &RNA_StateActuator;
case ACT_ARMATURE:
return &RNA_ArmatureActuator;
+ case ACT_STEERING:
+ return &RNA_SteeringActuator;
default:
return &RNA_Actuator;
}
@@ -401,6 +404,7 @@ EnumPropertyItem *rna_Actuator_type_itemf(bContext *C, PointerRNA *ptr, int *fre
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_PROPERTY);
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_RANDOM);
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_SCENE);
+ RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_STEERING);
if (ob != NULL) {
if (ob->type==OB_MESH){
@@ -1841,6 +1845,54 @@ static void rna_def_armature_actuator(BlenderRNA *brna)
RNA_def_property_update(prop, NC_LOGIC, NULL);
}
+static void rna_def_steering_actuator(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ static EnumPropertyItem prop_type_items[] ={
+ {ACT_STEERING_SEEK, "SEEK", 0, "Seek", ""},
+ {ACT_STEERING_FLEE, "FLEE", 0, "Flee", ""},
+ {ACT_STEERING_PATHFOLLOWING, "PATHFOLLOWING", 0, "Path following", ""},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "SteeringActuator", "Actuator");
+ RNA_def_struct_ui_text(srna, "Steering Actuator", "");
+ RNA_def_struct_sdna_from(srna, "bSteeringActuator", "data");
+
+ prop= RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, prop_type_items);
+ RNA_def_property_ui_text(prop, "Behavior", "");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
+ prop= RNA_def_property(srna, "movement", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "movement");
+ RNA_def_property_range(prop, 0.0, 1000.0);
+ RNA_def_property_ui_text(prop, "Move", "Movement value");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
+ prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "dist");
+ RNA_def_property_range(prop, 0.0, 1000.0);
+ RNA_def_property_ui_text(prop, "Dist", "Relax distance");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
+ prop= RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_pointer_sdna(prop, NULL, "target");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Target Object", "Set target object");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
+ prop= RNA_def_property(srna, "navmesh", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "Object");
+ RNA_def_property_pointer_sdna(prop, NULL, "navmesh");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "NavMesh Object", "Navigation mesh");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+}
+
void RNA_def_actuator(BlenderRNA *brna)
{
rna_def_actuator(brna);
@@ -1863,6 +1915,7 @@ void RNA_def_actuator(BlenderRNA *brna)
rna_def_shape_action_actuator(brna);
rna_def_state_actuator(brna);
rna_def_armature_actuator(brna);
+ rna_def_steering_actuator(brna);
}
#endif
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 37f5009d319..04bd1178e52 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -172,7 +172,7 @@ extern "C" {
#include "BL_ArmatureObject.h"
#include "BL_DeformableGameObject.h"
-#include "KX_Pathfinder.h"
+#include "KX_NavMeshObject.h"
#ifdef __cplusplus
extern "C" {
@@ -1717,7 +1717,7 @@ static KX_GameObject *gameobject_from_blenderobject(
if (ob->gameflag & OB_NAVMESH)
{
- gameobj = new KX_Pathfinder(kxscene,KX_Scene::m_callbacks);
+ gameobj = new KX_NavMeshObject(kxscene,KX_Scene::m_callbacks);
gameobj->AddMesh(meshobj);
break;
}
@@ -2685,7 +2685,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
struct Object* blenderobject = gameobj->GetBlenderObject();
if (blenderobject->type==OB_MESH && (blenderobject->gameflag & OB_NAVMESH))
{
- KX_Pathfinder* pathfinder = static_cast(gameobj);
+ KX_NavMeshObject* pathfinder = static_cast(gameobj);
pathfinder->BuildNavMesh();
pathfinder->SetVisible(0, true);
}
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 9b41470769f..f7151dfd8c3 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -62,6 +62,7 @@
#include "KX_SCA_ReplaceMeshActuator.h"
#include "KX_ParentActuator.h"
#include "KX_SCA_DynamicActuator.h"
+#include "KX_SteeringActuator.h"
#include "KX_Scene.h"
#include "KX_KetsjiEngine.h"
@@ -89,6 +90,7 @@
#include "BL_ActionActuator.h"
#include "BL_ShapeActionActuator.h"
#include "BL_ArmatureActuator.h"
+#include "RNA_access.h"
/* end of blender include block */
#include "BL_BlenderDataConversion.h"
@@ -1028,6 +1030,39 @@ void BL_ConvertActuators(char* maggiename,
baseact = tmparmact;
break;
}
+ case ACT_STEERING:
+ {
+ bSteeringActuator *stAct = (bSteeringActuator *) bact->data;
+ KX_GameObject *navmeshob = NULL;
+ if (stAct->navmesh)
+ {
+ PointerRNA settings_ptr;
+ RNA_pointer_create((ID *)stAct->navmesh, &RNA_GameObjectSettings, stAct->navmesh, &settings_ptr);
+ if (RNA_enum_get(&settings_ptr, "physics_type") == OB_BODY_TYPE_NAVMESH)
+ navmeshob = converter->FindGameObject(stAct->navmesh);
+ }
+ KX_GameObject *targetob = converter->FindGameObject(stAct->target);
+
+ int mode = KX_SteeringActuator::KX_STEERING_NODEF;
+ switch(stAct->type)
+ {
+ case ACT_STEERING_SEEK:
+ mode = KX_SteeringActuator::KX_STEERING_SEEK;
+ break;
+ case ACT_STEERING_FLEE:
+ mode = KX_SteeringActuator::KX_STEERING_FLEE;
+ break;
+ case ACT_STEERING_PATHFOLLOWING:
+ mode = KX_SteeringActuator::KX_STEERING_PATHFOLLOWING;
+ break;
+ }
+
+ KX_SteeringActuator *tmpstact
+ = new KX_SteeringActuator(gameobj, mode, targetob, navmeshob,
+ stAct->movement, stAct->dist);
+ baseact = tmpstact;
+ break;
+ }
default:
; /* generate some error */
}
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index f456183a16c..3d2f5189c01 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -85,6 +85,7 @@ public:
KX_ACT_SHAPEACTION,
KX_ACT_STATE,
KX_ACT_ARMATURE,
+ KX_ACT_STEERING,
};
SCA_IActuator(SCA_IObject* gameobj, KX_ACTUATOR_TYPE type);
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index dc5a7832432..8697710b02d 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -75,7 +75,7 @@
#include "DNA_world_types.h"
#include "DNA_scene_types.h"
-#include "KX_Pathfinder.h"
+#include "KX_NavMeshObject.h"
// If define: little test for Nzc: guarded drawing. If the canvas is
// not valid, skip rendering this frame.
diff --git a/source/gameengine/Ketsji/KX_Pathfinder.cpp b/source/gameengine/Ketsji/KX_NavMeshObject.cpp
similarity index 87%
rename from source/gameengine/Ketsji/KX_Pathfinder.cpp
rename to source/gameengine/Ketsji/KX_NavMeshObject.cpp
index b6368012b63..efcb3bdee6b 100644
--- a/source/gameengine/Ketsji/KX_Pathfinder.cpp
+++ b/source/gameengine/Ketsji/KX_NavMeshObject.cpp
@@ -26,7 +26,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include "KX_Pathfinder.h"
+#include "KX_NavMeshObject.h"
#include "RAS_MeshObject.h"
#include "DNA_mesh_types.h"
@@ -68,23 +68,36 @@ inline void flipAxes(float* vec)
std::swap(vec[1],vec[2]);
}
-KX_Pathfinder::KX_Pathfinder(void* sgReplicationInfo, SG_Callbacks callbacks)
+KX_NavMeshObject::KX_NavMeshObject(void* sgReplicationInfo, SG_Callbacks callbacks)
: KX_GameObject(sgReplicationInfo, callbacks)
, m_navMesh(NULL)
{
}
-KX_Pathfinder::~KX_Pathfinder()
+KX_NavMeshObject::~KX_NavMeshObject()
{
if (m_navMesh)
delete m_navMesh;
}
-bool KX_Pathfinder::BuildVertIndArrays(RAS_MeshObject* meshobj, float *&vertices, int& nverts,
+CValue* KX_NavMeshObject::GetReplica()
+{
+ KX_NavMeshObject* replica = new KX_NavMeshObject(*this);
+ replica->ProcessReplica();
+ return replica;
+}
+
+void KX_NavMeshObject::ProcessReplica()
+{
+ KX_GameObject::ProcessReplica();
+ BuildNavMesh();
+}
+
+bool KX_NavMeshObject::BuildVertIndArrays(RAS_MeshObject* meshobj, float *&vertices, int& nverts,
unsigned short* &faces, int& npolys)
{
- if (!meshobj || meshobj->HasColliderPolygon()==false)
+ if (!meshobj)
{
return false;
}
@@ -144,7 +157,7 @@ bool KX_Pathfinder::BuildVertIndArrays(RAS_MeshObject* meshobj, float *&vertices
return true;
}
-bool KX_Pathfinder::BuildNavMesh()
+bool KX_NavMeshObject::BuildNavMesh()
{
if (GetMeshCount()==0)
return false;
@@ -162,12 +175,11 @@ bool KX_Pathfinder::BuildNavMesh()
MT_Point3 pos;
for (int i=0; i(navmesh);
+ if (m_navmesh)
+ m_navmesh->RegisterActuator(this);
+ if (m_target)
+ m_target->RegisterActuator(this);
+}
+
+KX_SteeringActuator::~KX_SteeringActuator()
+{
+ if (m_navmesh)
+ m_navmesh->UnregisterActuator(this);
+ if (m_target)
+ m_target->UnregisterActuator(this);
+}
+
+CValue* KX_SteeringActuator::GetReplica()
+{
+ KX_SteeringActuator* replica = new KX_SteeringActuator(*this);
+ // replication just copy the m_base pointer => common random generator
+ replica->ProcessReplica();
+ return replica;
+}
+
+void KX_SteeringActuator::ProcessReplica()
+{
+ if (m_target)
+ m_target->RegisterActuator(this);
+ if (m_navmesh)
+ m_navmesh->RegisterActuator(this);
+ SCA_IActuator::ProcessReplica();
+}
+
+
+bool KX_SteeringActuator::UnlinkObject(SCA_IObject* clientobj)
+{
+ if (clientobj == m_target)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_target = NULL;
+ return true;
+ }
+ else if (clientobj == m_navmesh)
+ {
+ // this object is being deleted, we cannot continue to track it.
+ m_navmesh = NULL;
+ return true;
+ }
+ return false;
+}
+
+void KX_SteeringActuator::Relink(GEN_Map *obj_map)
+{
+ void **h_obj = (*obj_map)[m_target];
+ if (h_obj) {
+ if (m_target)
+ m_target->UnregisterActuator(this);
+ m_target = (KX_GameObject*)(*h_obj);
+ m_target->RegisterActuator(this);
+ }
+
+ h_obj = (*obj_map)[m_navmesh];
+ if (h_obj) {
+ if (m_navmesh)
+ m_navmesh->UnregisterActuator(this);
+ m_navmesh = (KX_NavMeshObject*)(*h_obj);
+ m_navmesh->RegisterActuator(this);
+ }
+}
+
+bool KX_SteeringActuator::Update()
+{
+ bool bNegativeEvent = IsNegativeEvent();
+ RemoveAllEvents();
+
+ if (bNegativeEvent)
+ return false; // do nothing on negative events
+
+ KX_GameObject *obj = (KX_GameObject*) GetParent();
+ const MT_Point3& mypos = obj->NodeGetWorldPosition();
+ const MT_Point3& targpos = m_target->NodeGetWorldPosition();
+ MT_Vector3 vectotarg = targpos - mypos;
+ MT_Vector3 steervec = MT_Vector3(0, 0, 0);
+ bool apply_steerforce = false;
+
+ switch (m_mode) {
+ case KX_STEERING_SEEK:
+ if (vectotarg.length2()>m_distance*m_distance)
+ {
+ apply_steerforce = true;
+ steervec = vectotarg;
+ steervec.normalize();
+ }
+ break;
+ case KX_STEERING_FLEE:
+ if (vectotarg.length2()m_distance*m_distance)
+ {
+ static const int MAX_PATH_LENGTH = 128;
+ static const MT_Vector3 PATH_COLOR(1,0,0);
+
+ float path[MAX_PATH_LENGTH*3];
+ int pathlen = m_navmesh->FindPath(mypos, targpos, path, MAX_PATH_LENGTH);
+ if (pathlen > 1)
+ {
+ //debug draw
+ m_navmesh->DrawPath(path, pathlen, PATH_COLOR);
+
+ apply_steerforce = true;
+ MT_Vector3 waypoint(&path[3]);
+ steervec = waypoint - mypos;
+ steervec.z() = 0;
+ steervec.normalize();
+ }
+ }
+ break;
+ }
+
+ if (apply_steerforce)
+ {
+ MT_Vector3 vel = m_movement*steervec;
+ obj->ApplyMovement(vel, false);
+ }
+
+ return true;
+}
+
+#ifndef DISABLE_PYTHON
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject KX_SteeringActuator::Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "KX_SteeringActuator",
+ sizeof(PyObjectPlus_Proxy),
+ 0,
+ py_base_dealloc,
+ 0,
+ 0,
+ 0,
+ 0,
+ py_base_repr,
+ 0,0,0,0,0,0,0,0,0,
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ 0,0,0,0,0,0,0,
+ Methods,
+ 0,
+ 0,
+ &SCA_IActuator::Type,
+ 0,0,0,0,0,0,
+ py_base_new
+};
+
+PyMethodDef KX_SteeringActuator::Methods[] = {
+ {NULL,NULL} //Sentinel
+};
+
+PyAttributeDef KX_SteeringActuator::Attributes[] = {
+ KX_PYATTRIBUTE_RW_FUNCTION("target", KX_SteeringActuator, pyattr_get_target, pyattr_set_target),
+ { NULL } //Sentinel
+};
+
+PyObject* KX_SteeringActuator::pyattr_get_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_SteeringActuator* actuator = static_cast(self);
+ if (!actuator->m_target)
+ Py_RETURN_NONE;
+ else
+ return actuator->m_target->GetProxy();
+}
+
+int KX_SteeringActuator::pyattr_set_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_SteeringActuator* actuator = static_cast(self);
+ KX_GameObject *gameobj;
+
+ if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_SteeringActuator"))
+ return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
+
+ if (actuator->m_target != NULL)
+ actuator->m_target->UnregisterActuator(actuator);
+
+ actuator->m_target = (KX_GameObject*) gameobj;
+
+ if (actuator->m_target)
+ actuator->m_target->RegisterActuator(actuator);
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+#endif // DISABLE_PYTHON
+
+/* eof */
+
diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.h b/source/gameengine/Ketsji/KX_SteeringActuator.h
new file mode 100644
index 00000000000..fce2205ca6e
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_SteeringActuator.h
@@ -0,0 +1,95 @@
+/**
+* Add steering behaviors
+*
+*
+* $Id$
+*
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* 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
+* of the License, or (at your option) any later version. The Blender
+* Foundation also sells licenses for use in proprietary software under
+* the Blender License. See http://www.blender.org/BL/ for information
+* about this.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+* All rights reserved.
+*
+* The Original Code is: all of this file.
+*
+* Contributor(s): none yet.
+*
+* ***** END GPL LICENSE BLOCK *****
+*/
+
+#ifndef __KX_STEERINGACTUATOR
+#define __KX_STEERINGACTUATOR
+
+#include "SCA_IActuator.h"
+#include "SCA_LogicManager.h"
+
+class KX_GameObject;
+class KX_NavMeshObject;
+
+class KX_SteeringActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ /** Target object */
+ KX_GameObject *m_target;
+ KX_NavMeshObject *m_navmesh;
+
+ int m_mode;
+ MT_Scalar m_distance;
+ MT_Scalar m_movement;
+public:
+ enum KX_STEERINGACT_MODE
+ {
+ KX_STEERING_NODEF = 0,
+ KX_STEERING_SEEK,
+ KX_STEERING_FLEE,
+ KX_STEERING_PATHFOLLOWING,
+ KX_STEERING_MAX
+ };
+
+ KX_SteeringActuator(class SCA_IObject* gameobj,
+ int mode,
+ KX_GameObject *target,
+ KX_GameObject *navmesh,
+ MT_Scalar movement,
+ MT_Scalar distance);
+ virtual ~KX_SteeringActuator();
+ virtual bool Update();
+
+ virtual CValue* GetReplica();
+ virtual void ProcessReplica();
+ virtual void Relink(GEN_Map *obj_map);
+ virtual bool UnlinkObject(SCA_IObject* clientobj);
+
+#ifndef DISABLE_PYTHON
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ /* These are used to get and set m_target */
+ static PyObject* pyattr_get_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
+ static int pyattr_set_target(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
+
+#endif // DISABLE_PYTHON
+
+}; /* end of class KX_SteeringActuator : public SCA_PropertyActuator */
+
+#endif
+