Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj6
-rw-r--r--source/blender/blenkernel/intern/sca.c3
-rw-r--r--source/blender/blenloader/intern/readfile.c12
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/include/BIF_butspace.h2
-rw-r--r--source/blender/include/BIF_interface.h1
-rw-r--r--source/blender/include/butspace.h4
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h8
-rw-r--r--source/blender/makesdna/DNA_controller_types.h3
-rw-r--r--source/blender/makesdna/DNA_object_types.h6
-rw-r--r--source/blender/makesdna/DNA_sensor_types.h1
-rw-r--r--source/blender/src/buttons_logic.c626
-rw-r--r--source/blender/src/interface.c4
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp8
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp15
-rw-r--r--source/gameengine/Converter/KX_ConvertControllers.cpp1
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.cpp7
-rw-r--r--source/gameengine/GameLogic/SCA_AlwaysSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.cpp10
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h7
-rw-r--r--source/gameengine/GameLogic/SCA_IController.cpp97
-rw-r--r--source/gameengine/GameLogic/SCA_IController.h4
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.cpp13
-rw-r--r--source/gameengine/GameLogic/SCA_IObject.h19
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.cpp23
-rw-r--r--source/gameengine/GameLogic/SCA_ISensor.h10
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_JoystickSensor.h1
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.cpp11
-rw-r--r--source/gameengine/GameLogic/SCA_KeyboardSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_LogicManager.cpp20
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_MouseSensor.h2
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.cpp6
-rw-r--r--source/gameengine/GameLogic/SCA_PropertySensor.h1
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.cpp16
-rw-r--r--source/gameengine/GameLogic/SCA_RandomSensor.h1
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp7
-rw-r--r--source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h1
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.cpp5
-rw-r--r--source/gameengine/Ketsji/KX_MouseFocusSensor.h1
-rw-r--r--source/gameengine/Ketsji/KX_RadarSensor.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_RaySensor.h1
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.cpp207
-rw-r--r--source/gameengine/Ketsji/KX_StateActuator.h83
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.cpp14
-rw-r--r--source/gameengine/Ketsji/KX_TouchSensor.h1
49 files changed, 1112 insertions, 192 deletions
diff --git a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
index c8173750bdc..af0ba74497a 100644
--- a/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
+++ b/projectfiles_vc7/gameengine/ketsji/KX_ketsji.vcproj
@@ -475,6 +475,9 @@
RelativePath="..\..\..\source\gameengine\Ketsji\KX_SoundActuator.cpp">
</File>
<File
+ RelativePath="..\..\..\source\gameengine\Ketsji\KX_StateActuator.cpp">
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_TrackToActuator.cpp">
</File>
<File
@@ -696,6 +699,9 @@
RelativePath="..\..\..\source\gameengine\Ketsji\KX_SoundActuator.h">
</File>
<File
+ RelativePath="..\..\..\source\gameengine\Ketsji\KX_StateActuator.h">
+ </File>
+ <File
RelativePath="..\..\..\source\gameengine\Ketsji\KX_TrackToActuator.h">
</File>
<File
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 92544f19721..16ca5d7542d 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -465,6 +465,9 @@ void init_actuator(bActuator *act)
case ACT_PARENT:
act->data = MEM_callocN(sizeof( bParentActuator ), "parent act");
break;
+ case ACT_STATE:
+ act->data = MEM_callocN(sizeof( bStateActuator ), "state act");
+ break;
default:
; /* this is very severe... I cannot make any memory for this */
/* logic brick... */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index fa7cbb06139..9cfce5e34fa 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3011,6 +3011,9 @@ static void lib_link_object(FileData *fd, Main *main)
bParentActuator *parenta = act->data;
parenta->ob = newlibadr(fd, ob->id.lib, parenta->ob);
}
+ else if(act->type==ACT_STATE) {
+ /* bStateActuator *statea = act->data; */
+ }
act= act->next;
}
@@ -3307,11 +3310,19 @@ static void direct_link_object(FileData *fd, Object *ob)
direct_link_constraints(fd, &ob->constraints);
link_glob_list(fd, &ob->controllers);
+ if (ob->init_state) {
+ /* if a known first state is specified, set it so that the game will start ok */
+ ob->state = ob->init_state;
+ } else if (!ob->state) {
+ ob->state = 1;
+ }
cont= ob->controllers.first;
while(cont) {
cont->data= newdataadr(fd, cont->data);
cont->links= newdataadr(fd, cont->links);
test_pointer_array(fd, (void **)&cont->links);
+ if (cont->state_mask == 0)
+ cont->state_mask = 1;
cont= cont->next;
}
@@ -7635,6 +7646,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
+
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 2595b95bbf0..9f28e13ff7b 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -715,6 +715,9 @@ static void write_actuators(WriteData *wd, ListBase *lb)
case ACT_PARENT:
writestruct(wd, DATA, "bParentActuator", 1, act->data);
break;
+ case ACT_STATE:
+ writestruct(wd, DATA, "bStateActuator", 1, act->data);
+ break;
default:
; /* error: don't know how to write this file */
}
diff --git a/source/blender/include/BIF_butspace.h b/source/blender/include/BIF_butspace.h
index cbbd8013c82..f0b37814947 100644
--- a/source/blender/include/BIF_butspace.h
+++ b/source/blender/include/BIF_butspace.h
@@ -99,6 +99,8 @@ extern void validate_editbonebutton_cb(void *bonev, void *namev);
#define BUTS_ACT_SEL 64
#define BUTS_ACT_ACT 128
#define BUTS_ACT_LINK 256
+#define BUTS_SENS_STATE 512
+#define BUTS_ACT_STATE 1024
/* buttons grid */
diff --git a/source/blender/include/BIF_interface.h b/source/blender/include/BIF_interface.h
index fbd4e4ecd91..3da4466d4d3 100644
--- a/source/blender/include/BIF_interface.h
+++ b/source/blender/include/BIF_interface.h
@@ -185,6 +185,7 @@ void uiDrawBlock(struct uiBlock *block);
void uiGetMouse(int win, short *adr);
void uiComposeLinks(uiBlock *block);
void uiSetButLock(int val, char *lockstr);
+uiBut *uiFindInlink(uiBlock *block, void *poin);
void uiClearButLock(void);
int uiDoBlocks(struct ListBase *lb, int event, int movemouse_quit);
void uiSetCurFont(uiBlock *block, int index);
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 7571d64be91..c0542e3f34c 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -52,6 +52,8 @@ struct Image;
#define BUTS_ACT_SEL 64
#define BUTS_ACT_ACT 128
#define BUTS_ACT_LINK 256
+#define BUTS_SENS_STATE 512
+#define BUTS_ACT_STATE 1024
/* internal */
@@ -583,6 +585,8 @@ void curvemap_buttons(struct uiBlock *block, struct CurveMapping *cumap, char la
#define B_SETACTOR 2715
#define B_SETMAINACTOR 2716
#define B_SETDYNA 2717
+#define B_SET_STATE_BIT 2718
+#define B_INIT_STATE_BIT 2719
/* *********************** */
#define B_FPAINTBUTS 2900
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index a326f5b01d6..417ba540e2c 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -208,6 +208,11 @@ typedef struct bParentActuator {
struct Object *ob;
} bParentActuator;
+typedef struct bStateActuator {
+ int type; /* 0=Set, 1=Add, 2=Rem, 3=Chg */
+ unsigned int mask; /* the bits to change */
+} bStateActuator;
+
typedef struct bActuator {
struct bActuator *next, *prev, *mynew;
short type;
@@ -279,11 +284,14 @@ typedef struct FreeCamera {
#define ACT_2DFILTER 19
#define ACT_PARENT 20
#define ACT_SHAPEACTION 21
+#define ACT_STATE 22
/* actuator flag */
#define ACT_SHOW 1
#define ACT_DEL 2
#define ACT_NEW 4
+#define ACT_LINKED 8
+#define ACT_VISIBLE 16
/* link codes */
#define LINK_SENSOR 0
diff --git a/source/blender/makesdna/DNA_controller_types.h b/source/blender/makesdna/DNA_controller_types.h
index 95c9b0d0cf7..cc9215e7d14 100644
--- a/source/blender/makesdna/DNA_controller_types.h
+++ b/source/blender/makesdna/DNA_controller_types.h
@@ -57,7 +57,7 @@ typedef struct bController {
struct bSensor **slinks;
short val, valo;
- int pad5;
+ unsigned int state_mask;
} bController;
@@ -71,6 +71,7 @@ typedef struct bController {
#define CONT_SHOW 1
#define CONT_DEL 2
#define CONT_NEW 4
+#define CONT_MASK 8
#endif
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 83168248b9a..c4e8cb4925b 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -216,7 +216,9 @@ typedef struct Object {
struct DerivedMesh *derivedDeform, *derivedFinal;
int lastDataMask; /* the custom data layer mask that was last used to calculate derivedDeform and derivedFinal */
- int pad;
+ unsigned int state; /* bit masks of game controllers that are active */
+ unsigned int init_state; /* bit masks of initial state as recorded by the users */
+ int pad2;
/*#ifdef WITH_VERSE*/
void *vnode; /* pointer at object VerseNode */
@@ -440,6 +442,8 @@ extern Object workob;
#define OB_ADDCONT 512
#define OB_ADDACT 1024
#define OB_SHOWCONT 2048
+#define OB_SETSTBIT 4096
+#define OB_INITSTBIT 8192
/* ob->restrictflag */
#define OB_RESTRICT_VIEW 1
diff --git a/source/blender/makesdna/DNA_sensor_types.h b/source/blender/makesdna/DNA_sensor_types.h
index 90e2b8f9f41..3fd57a85349 100644
--- a/source/blender/makesdna/DNA_sensor_types.h
+++ b/source/blender/makesdna/DNA_sensor_types.h
@@ -202,6 +202,7 @@ typedef struct bJoystickSensor {
#define SENS_DEL 2
#define SENS_NEW 4
#define SENS_NOT 8
+#define SENS_VISIBLE 16
/* sensor->pulse */
#define SENS_PULSE_CONT 0
diff --git a/source/blender/src/buttons_logic.c b/source/blender/src/buttons_logic.c
index b6877b2e2b7..c4fc17bc4d0 100644
--- a/source/blender/src/buttons_logic.c
+++ b/source/blender/src/buttons_logic.c
@@ -88,6 +88,7 @@
#include "mydevice.h"
#include "nla.h" /* For __NLA : Important, do not remove */
#include "butspace.h" // own module
+#include "interface.h"
/* internals */
void buttons_enji(uiBlock *, Object *);
@@ -228,7 +229,7 @@ static void sca_move_sensor(void *datav, void *data2_unused)
bSensor *sens_to_delete= datav;
int val;
Base *base;
- bSensor *sens;
+ bSensor *sens, *tmp;
val= pupmenu("Move up%x1|Move down %x2");
@@ -245,12 +246,24 @@ static void sca_move_sensor(void *datav, void *data2_unused)
if(sens) {
if( val==1 && sens->prev) {
- BLI_remlink(&base->object->sensors, sens);
- BLI_insertlinkbefore(&base->object->sensors, sens->prev, sens);
+ for (tmp=sens->prev; tmp; tmp=tmp->prev) {
+ if (tmp->flag & SENS_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->sensors, sens);
+ BLI_insertlinkbefore(&base->object->sensors, tmp, sens);
+ }
}
else if( val==2 && sens->next) {
- BLI_remlink(&base->object->sensors, sens);
- BLI_insertlink(&base->object->sensors, sens->next, sens);
+ for (tmp=sens->next; tmp; tmp=tmp->next) {
+ if (tmp->flag & SENS_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->sensors, sens);
+ BLI_insertlink(&base->object->sensors, tmp, sens);
+ }
}
BIF_undo_push("Move sensor");
allqueue(REDRAWBUTSLOGIC, 0);
@@ -267,7 +280,7 @@ static void sca_move_controller(void *datav, void *data2_unused)
bController *controller_to_del= datav;
int val;
Base *base;
- bController *cont;
+ bController *cont, *tmp;
val= pupmenu("Move up%x1|Move down %x2");
@@ -284,12 +297,27 @@ static void sca_move_controller(void *datav, void *data2_unused)
if(cont) {
if( val==1 && cont->prev) {
- BLI_remlink(&base->object->controllers, cont);
- BLI_insertlinkbefore(&base->object->controllers, cont->prev, cont);
+ /* locate the controller that has the same state mask but is earlier in the list */
+ tmp = cont->prev;
+ while(tmp) {
+ if(tmp->state_mask & cont->state_mask)
+ break;
+ tmp = tmp->prev;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->controllers, cont);
+ BLI_insertlinkbefore(&base->object->controllers, tmp, cont);
+ }
}
else if( val==2 && cont->next) {
+ tmp = cont->next;
+ while(tmp) {
+ if(tmp->state_mask & cont->state_mask)
+ break;
+ tmp = tmp->next;
+ }
BLI_remlink(&base->object->controllers, cont);
- BLI_insertlink(&base->object->controllers, cont->next, cont);
+ BLI_insertlink(&base->object->controllers, tmp, cont);
}
BIF_undo_push("Move controller");
allqueue(REDRAWBUTSLOGIC, 0);
@@ -306,7 +334,7 @@ static void sca_move_actuator(void *datav, void *data2_unused)
bActuator *actuator_to_move= datav;
int val;
Base *base;
- bActuator *act;
+ bActuator *act, *tmp;
val= pupmenu("Move up%x1|Move down %x2");
@@ -323,12 +351,25 @@ static void sca_move_actuator(void *datav, void *data2_unused)
if(act) {
if( val==1 && act->prev) {
- BLI_remlink(&base->object->actuators, act);
- BLI_insertlinkbefore(&base->object->actuators, act->prev, act);
+ /* locate the first visible actuators before this one */
+ for (tmp = act->prev; tmp; tmp=tmp->prev) {
+ if (tmp->flag & ACT_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->actuators, act);
+ BLI_insertlinkbefore(&base->object->actuators, tmp, act);
+ }
}
else if( val==2 && act->next) {
- BLI_remlink(&base->object->actuators, act);
- BLI_insertlink(&base->object->actuators, act->next, act);
+ for (tmp=act->next; tmp; tmp=tmp->next) {
+ if (tmp->flag & ACT_VISIBLE)
+ break;
+ }
+ if (tmp) {
+ BLI_remlink(&base->object->actuators, act);
+ BLI_insertlink(&base->object->actuators, tmp, act);
+ }
}
BIF_undo_push("Move actuator");
allqueue(REDRAWBUTSLOGIC, 0);
@@ -348,7 +389,7 @@ void do_logic_buts(unsigned short event)
bActuator *act;
Base *base;
Object *ob;
- int didit;
+ int didit, bit;
ob= OBACT;
if(ob==0) return;
@@ -462,6 +503,18 @@ void do_logic_buts(unsigned short event)
make_unique_prop_names(cont->name);
base->object->scaflag |= OB_SHOWCONT;
BLI_addtail(&(base->object->controllers), cont);
+ /* set the controller state mask from the current object state.
+ A controller is always in a single state, so select the lowest bit set
+ from the object state */
+ for (bit=0; bit<32; bit++) {
+ if (base->object->state & (1<<bit))
+ break;
+ }
+ cont->state_mask = (1<<bit);
+ if (cont->state_mask == 0) {
+ /* shouldn't happen, object state is never 0 */
+ cont->state_mask = 1;
+ }
}
base= base->next;
}
@@ -469,6 +522,32 @@ void do_logic_buts(unsigned short event)
allqueue(REDRAWBUTSLOGIC, 0);
break;
+ case B_SET_STATE_BIT:
+ base= FIRSTBASE;
+ while(base) {
+ if(base->object->scaflag & OB_SETSTBIT) {
+ base->object->scaflag &= ~OB_SETSTBIT;
+ base->object->state = 0x3FFFFFFF;
+ }
+ base= base->next;
+ }
+ allqueue(REDRAWBUTSLOGIC, 0);
+ break;
+
+ case B_INIT_STATE_BIT:
+ base= FIRSTBASE;
+ while(base) {
+ if(base->object->scaflag & OB_INITSTBIT) {
+ base->object->scaflag &= ~OB_INITSTBIT;
+ base->object->state = base->object->init_state;
+ if (!base->object->state)
+ base->object->state = 1;
+ }
+ base= base->next;
+ }
+ allqueue(REDRAWBUTSLOGIC, 0);
+ break;
+
case B_CHANGE_CONT:
base= FIRSTBASE;
while(base) {
@@ -505,7 +584,7 @@ void do_logic_buts(unsigned short event)
BIF_undo_push("Delete controller");
allqueue(REDRAWBUTSLOGIC, 0);
break;
-
+
case B_ADD_ACT:
base= FIRSTBASE;
while(base) {
@@ -717,6 +796,8 @@ static char *actuator_name(int type)
return "2D Filter";
case ACT_PARENT:
return "Parent";
+ case ACT_STATE:
+ return "State";
}
return "unknown";
}
@@ -732,21 +813,21 @@ static char *actuator_pup(Object *owner)
return "Actuators %t|Action %x15|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
- "|Visibility %x18|2D Filter %x19|Parent %x20";
+ "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
break;
case OB_MESH:
return "Actuators %t|Shape Action %x21|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
- "|Visibility %x18|2D Filter %x19|Parent %x20";
+ "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
break;
default:
return "Actuators %t|Motion %x0|Constraint %x9|Ipo %x1"
"|Camera %x3|Sound %x5|Property %x6|Edit Object %x10"
"|Scene %x11|Random %x13|Message %x14|CD %x16|Game %x17"
- "|Visibility %x18|2D Filter %x19|Parent %x20";
+ "|Visibility %x18|2D Filter %x19|Parent %x20|State %x22";
}
}
@@ -815,7 +896,8 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
if(scavisflag & BUTS_ACT_ACT) OBACT->scavisflag |= OB_VIS_ACT;
}
- if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK)) {
+ /* BUTS_XXX_STATE are similar to BUTS_XXX_LINK for selecting the object */
+ if(scavisflag & (BUTS_SENS_LINK|BUTS_CONT_LINK|BUTS_ACT_LINK|BUTS_SENS_STATE|BUTS_ACT_STATE)) {
doit= 1;
while(doit) {
doit= 0;
@@ -824,7 +906,7 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
while(ob) {
/* 1st case: select sensor when controller selected */
- if((scavisflag & BUTS_SENS_LINK) && (ob->scavisflag & OB_VIS_SENS)==0) {
+ if((scavisflag & (BUTS_SENS_LINK|BUTS_SENS_STATE)) && (ob->scavisflag & OB_VIS_SENS)==0) {
sens= ob->sensors.first;
while(sens) {
for(a=0; a<sens->totlinks; a++) {
@@ -879,7 +961,7 @@ static ID **get_selected_and_linked_obs(short *count, short scavisflag)
}
/* 4th case: select actuator when controller selected */
- if( (scavisflag & BUTS_ACT_LINK) && (ob->scavisflag & OB_VIS_CONT)) {
+ if( (scavisflag & (BUTS_ACT_LINK|BUTS_ACT_STATE)) && (ob->scavisflag & OB_VIS_CONT)) {
cont= ob->controllers.first;
while(cont) {
for(a=0; a<cont->totlinks; a++) {
@@ -1458,6 +1540,7 @@ static int get_col_actuator(int type)
case ACT_GAME: return TH_BUT_SETTING2;
case ACT_VISIBILITY: return TH_BUT_NUM;
case ACT_CONSTRAINT: return TH_BUT_ACTION;
+ case ACT_STATE: return TH_BUT_SETTING2;
default: return TH_BUT_NEUTRAL;
}
}
@@ -1468,7 +1551,23 @@ static void set_col_actuator(int item, int medium)
}
-static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, short yco, short width)
+char *get_state_name(Object *ob, short bit)
+{
+ bController *cont;
+ unsigned int mask;
+
+ mask = (1<<bit);
+ cont = ob->controllers.first;
+ while (cont) {
+ if (cont->state_mask & mask) {
+ return cont->name;
+ }
+ cont = cont->next;
+ }
+ return (char*)"";
+}
+
+static short draw_actuatorbuttons(Object *ob, bActuator *act, uiBlock *block, short xco, short yco, short width)
{
bSoundActuator *sa = NULL;
bCDActuator *cda = NULL;
@@ -1487,11 +1586,12 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
bVisibilityActuator *visAct = NULL;
bTwoDFilterActuator *tdfa = NULL;
bParentActuator *parAct = NULL;
+ bStateActuator *staAct = NULL;
float *fp;
short ysize = 0, wval;
- char *str;
- int myline;
+ char *str, name[32];
+ int myline, stbit;
/* yco is at the top of the rect, draw downwards */
uiBlockSetEmboss(block, UI_EMBOSSM);
@@ -2022,6 +2122,37 @@ static short draw_actuatorbuttons(bActuator *act, uiBlock *block, short xco, sho
break;
+ case ACT_STATE:
+ ysize = 34;
+
+ glRects(xco, yco-ysize, xco+width, yco);
+ uiEmboss((float)xco,
+ (float)yco-ysize, (float)xco+width, (float)yco, 1);
+
+ staAct = act->data;
+
+ str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3";
+
+ uiDefButI(block, MENU, B_REDR, str,
+ xco + 10, yco - 24, 65, 19, &staAct->type,
+ 0.0, 0.0, 0, 0,
+ "Select the bit operation on object state mask");
+
+ for (wval=0; wval<15; wval+=5) {
+ uiBlockBeginAlign(block);
+ for (stbit=0; stbit<5; stbit++) {
+ uiDefButBitI(block, TOG, (1<<(stbit+wval)), 0, "", (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(wval+stbit)));
+ }
+ for (stbit=0; stbit<5; stbit++) {
+ uiDefButBitI(block, TOG, (1<<(stbit+wval+15)), 0, "", (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(wval+stbit+15)));
+ }
+ }
+ uiBlockEndAlign(block);
+
+ yco-= ysize;
+
+ break;
+
case ACT_RANDOM:
ysize = 69;
@@ -2596,6 +2727,120 @@ void buttons_bullet(uiBlock *block, Object *ob)
uiBlockEndAlign(block);
}
+static void check_object_state(void *arg1_but, void *arg2_mask)
+{
+ unsigned int *cont_mask = arg2_mask;
+ uiBut *but = arg1_but;
+
+ if (*cont_mask == 0 || !(G.qual & LR_SHIFTKEY))
+ *cont_mask = (1<<but->retval);
+ but->retval = B_REDR;
+}
+
+static void check_controller_state_mask(void *arg1_but, void *arg2_mask)
+{
+ unsigned int *cont_mask = arg2_mask;
+ uiBut *but = arg1_but;
+
+ /* a controller is always in a single state */
+ *cont_mask = (1<<but->retval);
+ but->retval = B_REDR;
+}
+
+static int first_bit(unsigned int mask)
+{
+ int bit;
+
+ for (bit=0; bit<32; bit++) {
+ if (mask & (1<<bit))
+ return bit;
+ }
+ return -1;
+}
+
+static uiBlock *controller_state_mask_menu(void *arg_cont)
+{
+ uiBlock *block;
+ uiBut *but;
+ bController *cont = arg_cont;
+ int mask;
+
+ short yco = 12, xco = 0, stbit, offset;
+
+ block= uiNewBlock(&curarea->uiblocks, "Controller state mask", UI_EMBOSS, UI_HELV, curarea->win);
+
+ /* use this for a fake extra empy space around the buttons */
+ uiDefBut(block, LABEL, 0, "", -5, -5, 200, 34, NULL, 0, 0, 0, 0, "");
+
+ for (offset=0; offset<15; offset+=5) {
+ uiBlockBeginAlign(block);
+ for (stbit=0; stbit<5; stbit++) {
+ but = uiDefButBitI(block, TOG, (1<<(stbit+offset)), (stbit+offset), "", (short)(xco+12*stbit+13*offset), yco, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
+ uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
+ }
+ for (stbit=0; stbit<5; stbit++) {
+ but = uiDefButBitI(block, TOG, (1<<(stbit+offset+15)), (stbit+offset+15), "", (short)(xco+12*stbit+13*offset), yco-12, 12, 12, (int *)&(cont->state_mask), 0, 0, 0, 0, "");
+ uiButSetFunc(but, check_controller_state_mask, but, &(cont->state_mask));
+ }
+ }
+ uiBlockEndAlign(block);
+
+ uiBlockSetDirection(block, UI_TOP);
+
+ return block;
+}
+
+static void do_object_state_menu(void *arg, int event)
+{
+ Object *ob = arg;
+
+ switch (event) {
+ case 0:
+ ob->state = 0x3FFFFFFF;
+ break;
+ case 1:
+ ob->state = ob->init_state;
+ if (!ob->state)
+ ob->state = 1;
+ break;
+ case 2:
+ ob->init_state = ob->state;
+ break;
+ }
+ allqueue(REDRAWBUTSLOGIC, 0);
+}
+
+static uiBlock *object_state_mask_menu(void *arg_obj)
+{
+ uiBlock *block;
+ uiBut *but;
+ short xco = 0;
+
+ block= uiNewBlock(&curarea->uiblocks, "obstatemenu", UI_EMBOSSP, UI_HELV, curarea->win);
+ uiBlockSetButmFunc(block, do_object_state_menu, arg_obj);
+
+ uiDefBut(block, BUTM, 1, "Set all bits", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefBut(block, BUTM, 1, "Recall init state", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 1, "");
+ uiDefBut(block, SEPR, 0, "", 0, (short)(xco-=6), 160, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefBut(block, BUTM, 1, "Store init state", 0, (short)(xco-=20), 160, 19, NULL, 0.0, 0.0, 1, 2, "");
+
+ uiBlockSetDirection(block, UI_TOP);
+ return block;
+}
+
+static int is_sensor_linked(uiBlock *block, bSensor *sens)
+{
+ bController *cont;
+ int i, count;
+
+ for (count=0, i=0; i<sens->totlinks; i++) {
+ cont = sens->links[i];
+ if (uiFindInlink(block, cont) != NULL)
+ return 1;
+ }
+ return 0;
+}
+
/* never used, see CVS 1.134 for the code */
/* static FreeCamera *new_freecamera(void) */
@@ -2614,7 +2859,7 @@ void logic_buts(void)
uiBlock *block;
uiBut *but;
World *wrld;
- int a;
+ int a, iact, stbit, offset;
short xco, yco, count, width, ycoo;
char *pupstr, name[32];
@@ -2686,158 +2931,241 @@ void logic_buts(void)
uiClearButLock();
idar= get_selected_and_linked_obs(&count, G.buts->scaflag);
-
+
+ /* clean ACT_LINKED and ACT_VISIBLE of all potentially visible actuators so that
+ we can determine which is actually linked/visible */
+ for(a=0; a<count; a++) {
+ ob= (Object *)idar[a];
+ act= ob->actuators.first;
+ while(act) {
+ act->flag &= ~(ACT_LINKED|ACT_VISIBLE);
+ act = act->next;
+ }
+ /* same for sensors */
+ sens= ob->sensors.first;
+ while(sens) {
+ sens->flag &= ~(SENS_VISIBLE);
+ sens = sens->next;
+ }
+ }
+
+ /* start with the controller because we need to know which one is visible */
/* ******************************* */
- xco= 375; yco= 170; width= 230;
+ xco= 695; yco= 170; width= 275;
uiBlockSetEmboss(block, UI_EMBOSSP);
- uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 80, 19, "");
+ uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
- uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
- uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+ uiDefButBitS(block, TOG, BUTS_CONT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+ uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
+ uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
uiBlockEndAlign(block);
+ ob= OBACT;
+
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
uiClearButLock();
uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
-
- if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
-
+ if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
+
/* presume it is only objects for now */
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
- uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
- if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
- uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
+ if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
+ uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
+ if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
+ uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
uiBlockEndAlign(block);
- yco-=20;
+ yco-=17;
- if(ob->scaflag & OB_SHOWSENS) {
-
- sens= ob->sensors.first;
- while(sens) {
- uiBlockSetEmboss(block, UI_EMBOSSM);
- uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X, xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
- uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
+ /* mark all actuators linked to these controllers */
+ /* note that some of these actuators could be from objects that are not in the display list.
+ It's ok because those actuators will not be displayed here */
+ cont= ob->controllers.first;
+ while(cont) {
+ for (iact=0; iact<cont->totlinks; iact++) {
+ act = cont->links[iact];
+ act->flag |= ACT_LINKED;
+ }
+ cont = cont->next;
+ }
- ycoo= yco;
- if(sens->flag & SENS_SHOW)
- {
- uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
- but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name");
- uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
+ if(ob->scaflag & OB_SHOWCONT) {
- sens->otype= sens->type;
- yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name);
- if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+ /* first show the state */
+ uiBlockSetEmboss(block, UI_EMBOSSP);
+ uiDefBlockBut(block, object_state_mask_menu, ob, "State", (short)(xco-10), (short)(yco-10), 40, 19, "Object state menu: store and retrieve initial state");
+ uiBlockSetEmboss(block, UI_EMBOSS);
+ if (!ob->state)
+ ob->state = 1;
+ for (offset=0; offset<15; offset+=5) {
+ uiBlockBeginAlign(block);
+ for (stbit=0; stbit<5; stbit++) {
+ but = uiDefButBitI(block, TOG, 1<<(stbit+offset), stbit+offset, "", (short)(xco+35+12*stbit+13*offset), yco, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset)));
+ uiButSetFunc(but, check_object_state, but, &(ob->state));
}
- else {
- set_col_sensor(sens->type, 1);
- glRecti(xco+22, yco, xco+width-22,yco+19);
- but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, "");
- uiButSetFunc(but, sca_move_sensor, sens, NULL);
- but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, "");
- uiButSetFunc(but, sca_move_sensor, sens, NULL);
+ for (stbit=0; stbit<5; stbit++) {
+ but = uiDefButBitI(block, TOG, 1<<(stbit+offset+15), stbit+offset+15, "", (short)(xco+35+12*stbit+13*offset), yco-12, 12, 12, (int *)&(ob->state), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+offset+15)));
+ uiButSetFunc(but, check_object_state, but, &(ob->state));
}
+ }
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, OB_SETSTBIT, B_SET_STATE_BIT, "All",(short)(xco+235), yco-10, 25, 19, &ob->scaflag, 0, 0, 0, 0, "Set all state bits");
+ uiDefButBitS(block, TOG, OB_INITSTBIT, B_INIT_STATE_BIT, "Ini",(short)(xco+260), yco-10, 25, 19, &ob->scaflag, 0, 0, 0, 0, "Set the initial state");
+ uiBlockEndAlign(block);
- but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
- uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
-
- yco-=20;
+ yco-=35;
+
+ /* display only the controllers that match the current state */
+ offset = 0;
+ for (stbit=0; stbit<32; stbit++) {
+ if (!(ob->state & (1<<stbit)))
+ continue;
+ /* add a separation between controllers of different states */
+ if (offset) {
+ offset = 0;
+ yco -= 6;
+ }
+ cont= ob->controllers.first;
+ while(cont) {
+ if (cont->state_mask & (1<<stbit)) {
+ /* this controller is visible, mark all its actuator */
+ for (iact=0; iact<cont->totlinks; iact++) {
+ act = cont->links[iact];
+ act->flag |= ACT_VISIBLE;
+ }
+ uiBlockSetEmboss(block, UI_EMBOSSM);
+ uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
+ uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
+ uiBlockSetEmboss(block, UI_EMBOSSP);
+ sprintf(name, "%d", first_bit(cont->state_mask)+1);
+ uiDefBlockBut(block, controller_state_mask_menu, cont, name, (short)(xco+width-44), yco, 22, 19, "Set controller state mask");
+ uiBlockSetEmboss(block, UI_EMBOSSM);
+
+ if(cont->flag & CONT_SHOW) {
+ cont->otype= cont->type;
+ uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type");
+ but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-166), 19, cont->name, 0, 31, 0, 0, "Controller name");
+ uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
+
+ ycoo= yco;
+ yco= draw_controllerbuttons(cont, block, xco, yco, width);
+ if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+ }
+ else {
+ cpack(0x999999);
+ glRecti(xco+22, yco, xco+width-22,yco+19);
+ but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type");
+ uiButSetFunc(but, sca_move_controller, cont, NULL);
+ but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-166), 19, cont, 0, 0, 0, 0, "Controller name");
+ uiButSetFunc(but, sca_move_controller, cont, NULL);
+ ycoo= yco;
+ }
+
+ but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+ uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
+
+ uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, "");
+ /* offset is >0 if at least one controller was displayed */
+ offset++;
+ yco-=20;
+ }
+ cont= cont->next;
+ }
- sens= sens->next;
}
yco-= 6;
}
}
-
+
/* ******************************* */
- xco= 675; yco= 170; width= 230;
+ xco= 375; yco= 170; width= 250;
uiBlockSetEmboss(block, UI_EMBOSSP);
- uiDefBlockBut(block, controller_menu, NULL, "Controllers", xco-10, yco+35, 100, 19, "");
+ uiDefBlockBut(block, sensor_menu, NULL, "Sensors", xco-10, yco+35, 70, 19, "");
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BUTS_CONT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
- uiDefButBitS(block, TOG, BUTS_CONT_ACT, B_REDR, "Act", xco+110+(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
- uiDefButBitS(block, TOG, BUTS_CONT_LINK, B_REDR, "Link", xco+110+2*(width-100)/3, yco+35, (width-100)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Sensor/Actuator");
+ uiDefButBitS(block, TOG, BUTS_SENS_SEL, B_REDR, "Sel", xco+80, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+ uiDefButBitS(block, TOG, BUTS_SENS_ACT, B_REDR, "Act", xco+80+(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
+ uiDefButBitS(block, TOG, BUTS_SENS_LINK, B_REDR, "Link", xco+80+2*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+ uiDefButBitS(block, TOG, BUTS_SENS_STATE, B_REDR, "Sta", xco+80+3*(width-70)/4, yco+35, (width-70)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only sensors connected to active states");
uiBlockEndAlign(block);
- ob= OBACT;
-
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
uiClearButLock();
uiSetButLock(object_is_libdata(ob), ERROR_LIBDATA_MESSAGE);
- if( (ob->scavisflag & OB_VIS_CONT) == 0) continue;
-
+
+ if( (ob->scavisflag & OB_VIS_SENS) == 0) continue;
+
/* presume it is only objects for now */
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- if(ob->controllers.first) uiSetCurFont(block, UI_HELVB);
- uiDefButBitS(block, TOG, OB_SHOWCONT, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 0, 0, 0, "Active Object name");
- if(ob->controllers.first) uiSetCurFont(block, UI_HELV);
- uiDefButBitS(block, TOG, OB_ADDCONT, B_ADD_CONT, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Controller");
+ if(ob->sensors.first) uiSetCurFont(block, UI_HELVB);
+ uiDefButBitS(block, TOG, OB_SHOWSENS, B_REDR, ob->id.name+2,(short)(xco-10), yco, (short)(width-30), 19, &ob->scaflag, 0, 31, 0, 0, "Object name, click to show/hide sensors");
+ if(ob->sensors.first) uiSetCurFont(block, UI_HELV);
+ uiDefButBitS(block, TOG, OB_ADDSENS, B_ADD_SENS, "Add",(short)(xco+width-40), yco, 50, 19, &ob->scaflag, 0, 0, 0, 0, "Add a new Sensor");
uiBlockEndAlign(block);
yco-=20;
- if(ob->scaflag & OB_SHOWCONT) {
-
- cont= ob->controllers.first;
- while(cont) {
- uiBlockSetEmboss(block, UI_EMBOSSM);
- uiDefIconButBitS(block, TOG, CONT_DEL, B_DEL_CONT, ICON_X, xco, yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Delete Controller");
- uiDefIconButBitS(block, ICONTOG, CONT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &cont->flag, 0, 0, 0, 0, "Controller settings");
-
- if(cont->flag & CONT_SHOW) {
- cont->otype= cont->type;
- uiDefButS(block, MENU, B_CHANGE_CONT, controller_pup(),(short)(xco+22), yco, 100, 19, &cont->type, 0, 0, 0, 0, "Controller type");
- but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, cont->name, 0, 31, 0, 0, "Controller name");
- uiButSetFunc(but, make_unique_prop_names_cb, cont->name, (void*) 0);
-
- ycoo= yco;
- yco= draw_controllerbuttons(cont, block, xco, yco, width);
- if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
- }
- else {
- cpack(0x999999);
- glRecti(xco+22, yco, xco+width-22,yco+19);
- but= uiDefBut(block, LABEL, 0, controller_name(cont->type), (short)(xco+22), yco, 100, 19, cont, 0, 0, 0, 0, "Controller type");
- uiButSetFunc(but, sca_move_controller, cont, NULL);
- but= uiDefBut(block, LABEL, 0, cont->name,(short)(xco+122), yco,(short)(width-144), 19, cont, 0, 0, 0, 0, "Controller name");
- uiButSetFunc(but, sca_move_controller, cont, NULL);
+ if(ob->scaflag & OB_SHOWSENS) {
+
+ sens= ob->sensors.first;
+ while(sens) {
+ if (!(G.buts->scaflag & BUTS_SENS_STATE) ||
+ sens->totlinks == 0 || /* always display sensor without links so that is can be edited */
+ is_sensor_linked(block, sens)) {
+ sens->flag |= SENS_VISIBLE;
+ uiBlockSetEmboss(block, UI_EMBOSSM);
+ uiDefIconButBitS(block, TOG, SENS_DEL, B_DEL_SENS, ICON_X, xco, yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Delete Sensor");
+ uiDefIconButBitS(block, ICONTOG, SENS_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &sens->flag, 0, 0, 0, 0, "Sensor settings");
+
ycoo= yco;
+ if(sens->flag & SENS_SHOW)
+ {
+ uiDefButS(block, MENU, B_CHANGE_SENS, sensor_pup(), (short)(xco+22), yco, 100, 19, &sens->type, 0, 0, 0, 0, "Sensor type");
+ but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, sens->name, 0, 31, 0, 0, "Sensor name");
+ uiButSetFunc(but, make_unique_prop_names_cb, sens->name, (void*) 0);
+
+ sens->otype= sens->type;
+ yco= draw_sensorbuttons(sens, block, xco, yco, width,ob->id.name);
+ if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+ }
+ else {
+ set_col_sensor(sens->type, 1);
+ glRecti(xco+22, yco, xco+width-22,yco+19);
+ but= uiDefBut(block, LABEL, 0, sensor_name(sens->type), (short)(xco+22), yco, 100, 19, sens, 0, 0, 0, 0, "");
+ uiButSetFunc(but, sca_move_sensor, sens, NULL);
+ but= uiDefBut(block, LABEL, 0, sens->name, (short)(xco+122), yco, (short)(width-144), 19, sens, 0, 31, 0, 0, "");
+ uiButSetFunc(but, sca_move_sensor, sens, NULL);
+ }
+
+ but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
+ uiSetButLink(but, NULL, (void ***)&(sens->links), &sens->totlinks, LINK_SENSOR, LINK_CONTROLLER);
+
+ yco-=20;
}
-
- but= uiDefIconBut(block, LINK, 0, ICON_LINK, (short)(xco+width), ycoo, 19, 19, NULL, 0, 0, 0, 0, "");
- uiSetButLink(but, NULL, (void ***)&(cont->links), &cont->totlinks, LINK_CONTROLLER, LINK_ACTUATOR);
-
- uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, cont, LINK_CONTROLLER, 0, 0, 0, "");
-
- yco-=20;
-
- cont= cont->next;
+ sens= sens->next;
}
yco-= 6;
}
}
-
+
/* ******************************* */
- xco= 985; yco= 170; width= 280;
+ xco= 1040; yco= 170; width= 280;
uiBlockSetEmboss(block, UI_EMBOSSP);
- uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 100, 19, "");
+ uiDefBlockBut(block, actuator_menu, NULL, "Actuators", xco-10, yco+35, 90, 19, "");
uiBlockSetEmboss(block, UI_EMBOSS);
uiBlockBeginAlign(block);
- uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
- uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
- uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-110)/3, yco+35, (width-110)/3, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+ uiDefButBitS(block, TOG, BUTS_ACT_SEL, B_REDR, "Sel", xco+110, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show all selected Objects");
+ uiDefButBitS(block, TOG, BUTS_ACT_ACT, B_REDR, "Act", xco+110+(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show active Object");
+ uiDefButBitS(block, TOG, BUTS_ACT_LINK, B_REDR, "Link", xco+110+2*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show linked Objects to Controller");
+ uiDefButBitS(block, TOG, BUTS_ACT_STATE, B_REDR, "Sta", xco+110+3*(width-100)/4, yco+35, (width-100)/4, 19, &G.buts->scaflag, 0, 0, 0, 0, "Show only actuators connected to active states");
uiBlockEndAlign(block);
for(a=0; a<count; a++) {
ob= (Object *)idar[a];
@@ -2859,34 +3187,38 @@ void logic_buts(void)
act= ob->actuators.first;
while(act) {
- uiBlockSetEmboss(block, UI_EMBOSSM);
- uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X, xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator");
- uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings");
+ if (!(G.buts->scaflag & BUTS_ACT_STATE) ||
+ !(act->flag & ACT_LINKED) || /* always display actuators without links so that is can be edited */
+ (act->flag & ACT_VISIBLE)) { /* this actuator has visible connection, display it */
+ act->flag |= ACT_VISIBLE; /* mark the actuator as visible to help implementing the up/down action */
+ uiBlockSetEmboss(block, UI_EMBOSSM);
+ uiDefIconButBitS(block, TOG, ACT_DEL, B_DEL_ACT, ICON_X, xco, yco, 22, 19, &act->flag, 0, 0, 0, 0, "Delete Actuator");
+ uiDefIconButBitS(block, ICONTOG, ACT_SHOW, B_REDR, ICON_RIGHTARROW, (short)(xco+width-22), yco, 22, 19, &act->flag, 0, 0, 0, 0, "Actuator settings");
+
+ if(act->flag & ACT_SHOW) {
+ act->otype= act->type;
+ uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob), (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type");
+ but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name");
+ uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
+
+ ycoo= yco;
+ yco= draw_actuatorbuttons(ob, act, block, xco, yco, width);
+ if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
+ }
+ else {
+ set_col_actuator(act->type, 1);
+ glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
+ but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type");
+ uiButSetFunc(but, sca_move_actuator, act, NULL);
+ but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name");
+ uiButSetFunc(but, sca_move_actuator, act, NULL);
+ ycoo= yco;
+ }
- if(act->flag & ACT_SHOW) {
- act->otype= act->type;
- uiDefButS(block, MENU, B_CHANGE_ACT, actuator_pup(ob), (short)(xco+22), yco, 100, 19, &act->type, 0, 0, 0, 0, "Actuator type");
- but= uiDefBut(block, TEX, 1, "", (short)(xco+122), yco, (short)(width-144), 19, act->name, 0, 31, 0, 0, "Actuator name");
- uiButSetFunc(but, make_unique_prop_names_cb, act->name, (void*) 0);
+ uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, "");
- ycoo= yco;
- yco= draw_actuatorbuttons(act, block, xco, yco, width);
- if(yco-6 < ycoo) ycoo= (yco+ycoo-20)/2;
- }
- else {
- set_col_actuator(act->type, 1);
- glRecti((short)(xco+22), yco, (short)(xco+width-22),(short)(yco+19));
- but= uiDefBut(block, LABEL, 0, actuator_name(act->type), (short)(xco+22), yco, 100, 19, act, 0, 0, 0, 0, "Actuator type");
- uiButSetFunc(but, sca_move_actuator, act, NULL);
- but= uiDefBut(block, LABEL, 0, act->name, (short)(xco+122), yco, (short)(width-144), 19, act, 0, 0, 0, 0, "Actuator name");
- uiButSetFunc(but, sca_move_actuator, act, NULL);
- ycoo= yco;
+ yco-=20;
}
-
- uiDefIconBut(block, INLINK, 0, ICON_INLINK,(short)(xco-19), ycoo, 19, 19, act, LINK_ACTUATOR, 0, 0, 0, "");
-
- yco-=20;
-
act= act->next;
}
yco-= 6;
diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c
index 6582866d9a1..4fbf92d646e 100644
--- a/source/blender/src/interface.c
+++ b/source/blender/src/interface.c
@@ -2797,6 +2797,10 @@ static void ui_add_link_line(ListBase *listb, uiBut *but, uiBut *bt)
line->to= bt;
}
+uiBut *uiFindInlink(uiBlock *block, void *poin)
+{
+ return ui_find_inlink(block, poin);
+}
void uiComposeLinks(uiBlock *block)
{
diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index 32946267202..21c18634e21 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -2324,6 +2324,14 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
bool isInActiveLayer = (blenderobj->lay & activeLayerBitInfo)!=0;
BL_ConvertSensors(blenderobj,gameobj,logicmgr,kxscene,keydev,executePriority,activeLayerBitInfo,isInActiveLayer,canvas,converter);
}
+ // apply the initial state to controllers
+ for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
+ {
+ KX_GameObject* gameobj = static_cast<KX_GameObject*>(logicbrick_conversionlist->GetValue(i));
+ struct Object* blenderobj = converter->FindBlenderObject(gameobj);
+ gameobj->SetState(blenderobj->state);
+ }
+
#endif //CONVERT_LOGIC
logicbrick_conversionlist->Release();
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index f219c3a1472..c02c2a29595 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -56,6 +56,7 @@
#include "KX_ConstraintActuator.h"
#include "KX_CameraActuator.h"
#include "KX_GameActuator.h"
+#include "KX_StateActuator.h"
#include "KX_VisibilityActuator.h"
#include "KX_SCA_AddObjectActuator.h"
#include "KX_SCA_EndObjectActuator.h"
@@ -857,7 +858,19 @@ void BL_ConvertActuators(char* maggiename,
baseact = tmp_vis_act;
}
break;
-
+
+ case ACT_STATE:
+ {
+ bStateActuator *sta_act = (bStateActuator *) bact->data;
+ KX_StateActuator * tmp_sta_act = NULL;
+
+ tmp_sta_act =
+ new KX_StateActuator(gameobj, sta_act->type, sta_act->mask);
+
+ baseact = tmp_sta_act;
+ }
+ break;
+
case ACT_2DFILTER:
{
bTwoDFilterActuator *_2dfilter = (bTwoDFilterActuator*) bact->data;
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp b/source/gameengine/Converter/KX_ConvertControllers.cpp
index a26cfa95b6d..179dd9f8478 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -161,6 +161,7 @@ void BL_ConvertControllers(
if (gamecontroller)
{
gamecontroller->SetExecutePriority(executePriority++);
+ gamecontroller->SetState(bcontr->state_mask);
STR_String uniquename = bcontr->name;
uniquename += "#CONTR#";
uniqueint++;
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
index 67df5d091ab..f9fbf2387c4 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.cpp
@@ -53,10 +53,13 @@ SCA_AlwaysSensor::SCA_AlwaysSensor(class SCA_EventManager* eventmgr,
: SCA_ISensor(gameobj,eventmgr, T)
{
//SetDrawColor(255,0,0);
- m_alwaysresult = true;
+ Init();
}
-
+void SCA_AlwaysSensor::Init()
+{
+ m_alwaysresult = true;
+}
SCA_AlwaysSensor::~SCA_AlwaysSensor()
{
diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
index 474ed025432..8bf2a8aa98e 100644
--- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h
+++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h
@@ -45,6 +45,8 @@ public:
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
+
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_IActuator.cpp b/source/gameengine/GameLogic/SCA_IActuator.cpp
index 568d0eb4a89..eeca2d7b44c 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.cpp
+++ b/source/gameengine/GameLogic/SCA_IActuator.cpp
@@ -36,6 +36,7 @@ using namespace std;
SCA_IActuator::SCA_IActuator(SCA_IObject* gameobj,
PyTypeObject* T) :
+ m_links(0),
SCA_ILogicBrick(gameobj,T)
{
// nothing to do
@@ -109,3 +110,12 @@ SCA_IActuator::~SCA_IActuator()
RemoveAllEvents();
}
+void SCA_IActuator::DecLink()
+{
+ m_links--;
+ if (m_links < 0)
+ {
+ printf("Warning: actuator %s has negative m_links: %d\n", m_name.Ptr(), m_links);
+ m_links = 0;
+ }
+}
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index b802aa4b298..774b27c5ad4 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -34,8 +34,11 @@
class SCA_IActuator : public SCA_ILogicBrick
{
+ friend class SCA_LogicManager;
protected:
std::vector<CValue*> m_events;
+ int m_links; // number of active links to controllers
+ // when 0, the actuator is automatically stopped
void RemoveAllEvents();
public:
@@ -83,6 +86,10 @@ public:
*/
bool IsNegativeEvent() const;
virtual ~SCA_IActuator();
+
+ void IncLink() { m_links++; }
+ void DecLink();
+ bool IsNoLink() const { return !m_links; }
};
#endif //__KX_IACTUATOR
diff --git a/source/gameengine/GameLogic/SCA_IController.cpp b/source/gameengine/GameLogic/SCA_IController.cpp
index 5cb62678c6b..bbe5a51db3c 100644
--- a/source/gameengine/GameLogic/SCA_IController.cpp
+++ b/source/gameengine/GameLogic/SCA_IController.cpp
@@ -29,6 +29,7 @@
#include "SCA_IController.h"
#include "SCA_LogicManager.h"
#include "SCA_IActuator.h"
+#include "SCA_ISensor.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -37,6 +38,7 @@
SCA_IController::SCA_IController(SCA_IObject* gameobj,
PyTypeObject* T)
:
+ m_statemask(0),
SCA_ILogicBrick(gameobj,T)
{
}
@@ -45,6 +47,7 @@ SCA_IController::SCA_IController(SCA_IObject* gameobj,
SCA_IController::~SCA_IController()
{
+ UnlinkAllActuators();
}
@@ -65,6 +68,14 @@ const std::vector<class SCA_IActuator*>& SCA_IController::GetLinkedActuators()
void SCA_IController::UnlinkAllSensors()
{
+ if (IsActive())
+ {
+ std::vector<class SCA_ISensor*>::iterator sensit;
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ (*sensit)->DecLink();
+ }
+ }
m_linkedsensors.clear();
}
@@ -72,6 +83,14 @@ void SCA_IController::UnlinkAllSensors()
void SCA_IController::UnlinkAllActuators()
{
+ if (IsActive())
+ {
+ std::vector<class SCA_IActuator*>::iterator actit;
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ (*actit)->DecLink();
+ }
+ }
m_linkedactuators.clear();
}
@@ -95,26 +114,94 @@ void SCA_IController::Trigger(SCA_LogicManager* logicmgr)
void SCA_IController::LinkToActuator(SCA_IActuator* actua)
{
m_linkedactuators.push_back(actua);
+ if (IsActive())
+ {
+ actua->IncLink();
+ }
}
void SCA_IController::UnlinkActuator(class SCA_IActuator* actua)
{
std::vector<class SCA_IActuator*>::iterator actit;
- std::vector<class SCA_IActuator*>::iterator actfound = m_linkedactuators.end();
for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
{
if ((*actit) == actua)
- actfound = actit;
+ {
+ break;
+ }
}
- if (!(actfound==m_linkedactuators.end()))
+ if (!(actit==m_linkedactuators.end()))
{
- m_linkedactuators.erase(actfound);
+ m_linkedactuators.erase(actit);
+ if (IsActive())
+ {
+ (*actit)->DecLink();
+ }
}
-
}
void SCA_IController::LinkToSensor(SCA_ISensor* sensor)
{
m_linkedsensors.push_back(sensor);
+ if (IsActive())
+ {
+ sensor->IncLink();
+ }
+}
+
+void SCA_IController::UnlinkSensor(class SCA_ISensor* sensor)
+{
+ std::vector<class SCA_ISensor*>::iterator sensit;
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ if ((*sensit) == sensor)
+ {
+ break;
+ }
+
+ }
+ if (!(sensit==m_linkedsensors.end()))
+ {
+ m_linkedsensors.erase(sensit);
+ if (IsActive())
+ {
+ (*sensit)->DecLink();
+ }
+ }
}
+
+void SCA_IController::ApplyState(unsigned int state)
+{
+ std::vector<class SCA_IActuator*>::iterator actit;
+ std::vector<class SCA_ISensor*>::iterator sensit;
+
+ if (m_statemask & state)
+ {
+ if (!IsActive())
+ {
+ // reactive the controller, all the links to actuator are valid again
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ (*actit)->IncLink();
+ }
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ (*sensit)->IncLink();
+ }
+ SetActive(true);
+ }
+ } else if (IsActive())
+ {
+ for (actit = m_linkedactuators.begin();!(actit==m_linkedactuators.end());++actit)
+ {
+ (*actit)->DecLink();
+ }
+ for (sensit = m_linkedsensors.begin();!(sensit==m_linkedsensors.end());++sensit)
+ {
+ (*sensit)->DecLink();
+ }
+ SetActive(false);
+ }
+}
+
diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h
index 79e956dec4e..f67c0942eb4 100644
--- a/source/gameengine/GameLogic/SCA_IController.h
+++ b/source/gameengine/GameLogic/SCA_IController.h
@@ -36,6 +36,7 @@ class SCA_IController : public SCA_ILogicBrick
protected:
std::vector<class SCA_ISensor*> m_linkedsensors;
std::vector<class SCA_IActuator*> m_linkedactuators;
+ unsigned int m_statemask;
public:
SCA_IController(SCA_IObject* gameobj,PyTypeObject* T);
virtual ~SCA_IController();
@@ -47,6 +48,9 @@ public:
void UnlinkAllSensors();
void UnlinkAllActuators();
void UnlinkActuator(class SCA_IActuator* actua);
+ void UnlinkSensor(class SCA_ISensor* sensor);
+ void SetState(unsigned int state) { m_statemask = state; }
+ void ApplyState(unsigned int state);
};
diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp
index 6df9e23f3fa..826e7bbdf0e 100644
--- a/source/gameengine/GameLogic/SCA_IObject.cpp
+++ b/source/gameengine/GameLogic/SCA_IObject.cpp
@@ -40,7 +40,7 @@
MT_Point3 SCA_IObject::m_sDummy=MT_Point3(0,0,0);
-SCA_IObject::SCA_IObject(PyTypeObject* T): CValue(T)
+SCA_IObject::SCA_IObject(PyTypeObject* T): m_state(0), CValue(T)
{
m_suspended = false;
}
@@ -329,6 +329,17 @@ void SCA_IObject::Resume(void)
}
}
+void SCA_IObject::SetState(unsigned int state)
+{
+ m_state = state;
+ // update the status of the controllers
+ SCA_ControllerList::iterator contit;
+ for (contit = m_controllers.begin(); contit != m_controllers.end(); contit++)
+ {
+ (*contit)->ApplyState(m_state);
+ }
+}
+
/* ------------------------------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h
index e8251e0ceaa..07b4310a91e 100644
--- a/source/gameengine/GameLogic/SCA_IObject.h
+++ b/source/gameengine/GameLogic/SCA_IObject.h
@@ -67,7 +67,12 @@ protected:
* Ignore updates?
*/
bool m_suspended;
-
+
+ /**
+ * current state = bit mask of state that are active
+ */
+ unsigned int m_state;
+
public:
SCA_IObject(PyTypeObject* T=&Type);
@@ -111,7 +116,17 @@ public:
* Resume progress
*/
void Resume(void);
-
+
+ /**
+ * Set the object state
+ */
+ void SetState(unsigned int state);
+
+ /**
+ * Get the object state
+ */
+ unsigned int GetState(void) { return m_state; }
+
// const class MT_Point3& ConvertPythonPylist(PyObject* pylist);
// here come the python forwarded methods
diff --git a/source/gameengine/GameLogic/SCA_ISensor.cpp b/source/gameengine/GameLogic/SCA_ISensor.cpp
index 9fdee0c19da..1c29eb27be5 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.cpp
+++ b/source/gameengine/GameLogic/SCA_ISensor.cpp
@@ -52,6 +52,7 @@ SCA_ISensor::SCA_ISensor(SCA_IObject* gameobj,
SCA_ILogicBrick(gameobj,T),
m_triggered(false)
{
+ m_links = 0;
m_suspended = false;
m_invert = false;
m_pos_ticks = 0;
@@ -111,6 +112,25 @@ void SCA_ISensor::Resume() {
m_suspended = false;
}
+void SCA_ISensor::Init() {
+ printf("Sensor %s has no init function, please report this bug to Blender.org\n", m_name);
+}
+
+void SCA_ISensor::DecLink() {
+ m_links--;
+ if (m_links < 0)
+ {
+ printf("Warning: sensor %s has negative m_links: %d\n", m_name.Ptr(), m_links);
+ m_links = 0;
+ }
+ if (!m_links)
+ {
+ // sensor is detached from all controllers, initialize it so that it
+ // is fresh as at startup when it is reattached again.
+ Init();
+ }
+}
+
/* python integration */
PyTypeObject SCA_ISensor::Type = {
@@ -177,7 +197,8 @@ void SCA_ISensor::Activate(class SCA_LogicManager* logicmgr, CValue* event)
{
// calculate if a __triggering__ is wanted
- if (!m_suspended) {
+ // don't evaluate a sensor that is not connected to any controller
+ if (m_links && !m_suspended) {
bool result = this->Evaluate(event);
if (result) {
logicmgr->AddActivatedSensor(this);
diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h
index e14fb34241a..292b2d160ae 100644
--- a/source/gameengine/GameLogic/SCA_ISensor.h
+++ b/source/gameengine/GameLogic/SCA_ISensor.h
@@ -64,6 +64,9 @@ class SCA_ISensor : public SCA_ILogicBrick
/** Sensor must ignore updates? */
bool m_suspended;
+ /** number of connections to controller */
+ int m_links;
+
/** Pass the activation on to the logic manager.*/
void SignalActivation(class SCA_LogicManager* logicmgr);
@@ -81,6 +84,7 @@ public:
void Activate(class SCA_LogicManager* logicmgr,CValue* event);
virtual bool Evaluate(CValue* event) = 0;
virtual bool IsPositiveTrigger();
+ virtual void Init();
virtual PyObject* _getattr(const STR_String& attr);
virtual CValue* GetReplica()=0;
@@ -114,6 +118,12 @@ public:
/** Resume sensing. */
void Resume();
+ void IncLink()
+ { m_links++; }
+ void DecLink();
+ bool IsNoLink() const
+ { return !m_links; }
+
/* Python functions: */
KX_PYMETHOD_DOC(SCA_ISensor,IsPositive);
KX_PYMETHOD_DOC(SCA_ISensor,GetUsePosPulseMode);
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
index b0e7fee130d..81938f05af1 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.cpp
@@ -64,9 +64,13 @@ std::cout << " button flag "<< m_buttonf << std::endl;
std::cout << " hat " << m_hat << std::endl;
std::cout << " hat flag " << m_hatf << std::endl;
*/
- m_istrig=0;
+ Init();
}
+void SCA_JoystickSensor::Init()
+{
+ m_istrig=0;
+}
SCA_JoystickSensor::~SCA_JoystickSensor()
{
diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h
index 2fbe1edf1e7..69068da6494 100644
--- a/source/gameengine/GameLogic/SCA_JoystickSensor.h
+++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h
@@ -95,6 +95,7 @@ public:
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
index f13b1bcf4c9..c6c06846e3b 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.cpp
@@ -62,7 +62,7 @@ SCA_KeyboardSensor::SCA_KeyboardSensor(SCA_KeyboardManager* keybdmgr,
if (hotkey == SCA_IInputDevice::KX_ESCKEY)
keybdmgr->GetInputDevice()->HookEscape();
// SetDrawColor(0xff0000ff);
- m_val=0;
+ Init();
}
@@ -71,7 +71,14 @@ SCA_KeyboardSensor::~SCA_KeyboardSensor()
{
}
-
+void SCA_KeyboardSensor::Init()
+{
+ // this function is used when the sensor is disconnected from all controllers
+ // by the state engine. It reinitializes the sensor as if it was just created.
+ // However, if the target key is pressed when the sensor is reactivated, it
+ // will not generated an event (see remark in Evaluate()).
+ m_val = 0;
+}
CValue* SCA_KeyboardSensor::GetReplica()
{
diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
index e87eddecd32..b86f6931d27 100644
--- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h
+++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h
@@ -114,6 +114,8 @@ public:
PyTypeObject* T=&Type );
virtual ~SCA_KeyboardSensor();
virtual CValue* GetReplica();
+ virtual void Init();
+
short int GetHotkey();
virtual bool Evaluate(CValue* event);
diff --git a/source/gameengine/GameLogic/SCA_LogicManager.cpp b/source/gameengine/GameLogic/SCA_LogicManager.cpp
index 49f01d643e5..fb1a2c29eb6 100644
--- a/source/gameengine/GameLogic/SCA_LogicManager.cpp
+++ b/source/gameengine/GameLogic/SCA_LogicManager.cpp
@@ -165,6 +165,11 @@ void* SCA_LogicManager::FindBlendObjByGameMeshName(const STR_String& gamemeshnam
void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
{
+ controllerlist contlist = m_sensorcontrollermapje[sensor];
+ for (controllerlist::const_iterator c= contlist.begin();!(c==contlist.end());c++)
+ {
+ (*c)->UnlinkSensor(sensor);
+ }
m_sensorcontrollermapje.erase(sensor);
for (vector<SCA_EventManager*>::const_iterator ie=m_eventmanagers.begin();
@@ -176,6 +181,8 @@ void SCA_LogicManager::RemoveSensor(SCA_ISensor* sensor)
void SCA_LogicManager::RemoveController(SCA_IController* controller)
{
+ controller->UnlinkAllSensors();
+ controller->UnlinkAllActuators();
std::map<SCA_ISensor*,controllerlist>::iterator sit;
for (sit = m_sensorcontrollermapje.begin();!(sit==m_sensorcontrollermapje.end());++sit)
{
@@ -236,7 +243,8 @@ void SCA_LogicManager::BeginFrame(double curtime, double fixedtime)
!(c==contlist.end());c++)
{
SCA_IController* contr = *c;//controllerarray->at(c);
- triggeredControllerSet.insert(SmartControllerPtr(contr,0));
+ if (contr->IsActive())
+ triggeredControllerSet.insert(SmartControllerPtr(contr,0));
}
//sensor->SetActive(false);
}
@@ -273,6 +281,16 @@ void SCA_LogicManager::UpdateFrame(double curtime, bool frame)
(*ia)->SetActive(false);
//m_activeactuators.pop_back();
+ } else if ((*ia)->IsNoLink())
+ {
+ // This actuator has no more links but it still active
+ // make sure it will get a negative event on next frame to stop it
+ // Do this check after Update() rather than before to make sure
+ // that all the actuators that are activated at same time than a state
+ // actuator have a chance to execute.
+ CValue* event = new CBoolValue(false);
+ (*ia)->RemoveAllEvents();
+ (*ia)->AddEvent(event);
}
}
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.cpp b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
index 8810b7470ed..11e67eda014 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.cpp
@@ -58,7 +58,6 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
{
m_mousemode = mousemode;
m_triggermode = true;
- m_val = 0; /* stores the latest attribute */
switch (m_mousemode) {
case KX_MOUSESENSORMODE_LEFTBUTTON:
@@ -79,7 +78,12 @@ SCA_MouseSensor::SCA_MouseSensor(SCA_MouseManager* eventmgr,
default:
; /* ignore, no hotkey */
}
+ Init();
+}
+void SCA_MouseSensor::Init()
+{
+ m_val = 0; /* stores the latest attribute */
}
SCA_MouseSensor::~SCA_MouseSensor()
diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h
index 86c9d96a800..26a1c5e3fd2 100644
--- a/source/gameengine/GameLogic/SCA_MouseSensor.h
+++ b/source/gameengine/GameLogic/SCA_MouseSensor.h
@@ -96,7 +96,7 @@ class SCA_MouseSensor : public SCA_ISensor
virtual ~SCA_MouseSensor();
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
-
+ virtual void Init();
virtual bool IsPositiveTrigger();
short int GetModeKey();
SCA_IInputDevice::KX_EnumInputs GetHotKey();
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.cpp b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
index f1fcb18d32e..d6eb246ffd2 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.cpp
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.cpp
@@ -57,7 +57,6 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
m_lastresult(false),
m_range_expr(NULL)
{
- m_recentresult=false;
//CParser pars;
//pars.SetContext(this->AddRef());
//CValue* resultval = m_rightexpr->Calculate();
@@ -73,7 +72,12 @@ SCA_PropertySensor::SCA_PropertySensor(SCA_EventManager* eventmgr,
{
PrecalculateRangeExpression();
}
+ Init();
+}
+void SCA_PropertySensor::Init()
+{
+ m_recentresult = false;
}
void SCA_PropertySensor::PrecalculateRangeExpression()
diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h
index 81c9b958f25..6871cb3afdc 100644
--- a/source/gameengine/GameLogic/SCA_PropertySensor.h
+++ b/source/gameengine/GameLogic/SCA_PropertySensor.h
@@ -77,6 +77,7 @@ public:
virtual void Delete();
virtual ~SCA_PropertySensor();
virtual CValue* GetReplica();
+ virtual void Init();
void PrecalculateRangeExpression();
bool CheckPropertyCondition();
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.cpp b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
index 0e856e0d6bb..3626522e49a 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.cpp
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.cpp
@@ -50,16 +50,9 @@ SCA_RandomSensor::SCA_RandomSensor(SCA_EventManager* eventmgr,
PyTypeObject* T)
: SCA_ISensor(gameobj,eventmgr, T)
{
- m_iteration = 0;
- m_interval = 0;
- m_lastdraw = false;
-
// m_basegenerator is never deleted => memory leak
m_basegenerator = new SCA_RandomNumberGenerator(startseed);
- m_currentDraw = m_basegenerator->Draw();
- //registration is done globally, don't do it here
- //Note: it was probably done to work around a bug in Evaluate(). It is now fixed
- //RegisterToManager();
+ Init();
}
@@ -69,6 +62,13 @@ SCA_RandomSensor::~SCA_RandomSensor()
/* Nothing to be done here. */
}
+void SCA_RandomSensor::Init()
+{
+ m_iteration = 0;
+ m_interval = 0;
+ m_lastdraw = false;
+ m_currentDraw = m_basegenerator->Draw();
+}
CValue* SCA_RandomSensor::GetReplica()
diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h
index cc54179aa4e..d29bfb6837a 100644
--- a/source/gameengine/GameLogic/SCA_RandomSensor.h
+++ b/source/gameengine/GameLogic/SCA_RandomSensor.h
@@ -54,6 +54,7 @@ public:
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
/* --------------------------------------------------------------------- */
/* Python interface ---------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
index e320453b7aa..027cb2a0ffa 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.cpp
@@ -58,10 +58,15 @@ KX_NetworkMessageSensor::KX_NetworkMessageSensor(
m_NetworkScene(NetworkScene),
m_subject(subject),
m_frame_message_count (0),
- m_IsUp(false),
m_BodyList(NULL),
m_SubjectList(NULL)
{
+ Init();
+}
+
+void KX_NetworkMessageSensor::Init()
+{
+ m_IsUp = false;
}
KX_NetworkMessageSensor::~KX_NetworkMessageSensor()
diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
index d051b715aab..6fd92d17be3 100644
--- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
+++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
@@ -65,6 +65,7 @@ public:
virtual CValue* GetReplica();
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
void EndFrame();
/* ------------------------------------------------------------- */
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
index 60b90138abe..f306f0dbfbb 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
@@ -69,11 +69,14 @@ KX_MouseFocusSensor::KX_MouseFocusSensor(SCA_MouseManager* eventmgr,
m_gp_canvas(canvas),
m_kxscene(kxscene)
{
+ Init();
+}
+void KX_MouseFocusSensor::Init()
+{
m_mouse_over_in_previous_frame = false;
m_positive_event = false;
m_hitObject = 0;
-
}
bool KX_MouseFocusSensor::Evaluate(CValue* event)
diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
index 86f32fbf4be..b011ebe1288 100644
--- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h
+++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h
@@ -68,6 +68,7 @@ class KX_MouseFocusSensor : public SCA_MouseSensor
* @attention Overrides default evaluate.
*/
virtual bool Evaluate(CValue* event);
+ virtual void Init();
virtual bool IsPositiveTrigger() {
bool result = m_positive_event;
diff --git a/source/gameengine/Ketsji/KX_RadarSensor.cpp b/source/gameengine/Ketsji/KX_RadarSensor.cpp
index 31fffffa3c1..987e0b946b2 100644
--- a/source/gameengine/Ketsji/KX_RadarSensor.cpp
+++ b/source/gameengine/Ketsji/KX_RadarSensor.cpp
@@ -71,7 +71,6 @@ KX_RadarSensor::KX_RadarSensor(SCA_EventManager* eventmgr,
//sumoObj->setClientObject(&m_client_info);
}
-
KX_RadarSensor::~KX_RadarSensor()
{
diff --git a/source/gameengine/Ketsji/KX_RaySensor.cpp b/source/gameengine/Ketsji/KX_RaySensor.cpp
index a85dc61cac8..02b814105b4 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.cpp
+++ b/source/gameengine/Ketsji/KX_RaySensor.cpp
@@ -60,17 +60,19 @@ KX_RaySensor::KX_RaySensor(class SCA_EventManager* eventmgr,
m_bFindMaterial(bFindMaterial),
m_distance(distance),
m_scene(ketsjiScene),
- m_bTriggered(false),
- m_axis(axis),
- m_rayHit(false),
- m_hitObject(NULL)
+ m_axis(axis)
{
-
+ Init();
}
-
+void KX_RaySensor::Init()
+{
+ m_bTriggered = false;
+ m_rayHit = false;
+ m_hitObject = NULL;
+}
KX_RaySensor::~KX_RaySensor()
{
diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h
index 8a317ffaa07..f4305b053d1 100644
--- a/source/gameengine/Ketsji/KX_RaySensor.h
+++ b/source/gameengine/Ketsji/KX_RaySensor.h
@@ -66,6 +66,7 @@ public:
virtual bool Evaluate(CValue* event);
virtual bool IsPositiveTrigger();
+ virtual void Init();
bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index fff33ca82fd..1526709f425 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -754,8 +754,6 @@ int KX_Scene::NewRemoveObject(class CValue* gameobj)
for (SCA_ControllerList::iterator itc = controllers.begin();
!(itc==controllers.end());itc++)
{
- (*itc)->UnlinkAllSensors();
- (*itc)->UnlinkAllActuators();
m_logicmgr->RemoveController(*itc);
}
diff --git a/source/gameengine/Ketsji/KX_StateActuator.cpp b/source/gameengine/Ketsji/KX_StateActuator.cpp
new file mode 100644
index 00000000000..95a79f0c480
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_StateActuator.cpp
@@ -0,0 +1,207 @@
+/*
+ * $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.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 *****
+ * Actuator to toggle visibility/invisibility of objects
+ */
+
+#include "KX_StateActuator.h"
+#include "KX_GameObject.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+KX_StateActuator::KX_StateActuator(
+ SCA_IObject* gameobj,
+ int operation,
+ unsigned int mask,
+ PyTypeObject* T
+ )
+ : SCA_IActuator(gameobj,T),
+ m_operation(operation),
+ m_mask(mask)
+{
+ // intentionally empty
+}
+
+KX_StateActuator::~KX_StateActuator(
+ void
+ )
+{
+ // intentionally empty
+}
+
+CValue*
+KX_StateActuator::GetReplica(
+ void
+ )
+{
+ KX_StateActuator* replica = new KX_StateActuator(*this);
+ replica->ProcessReplica();
+ // this will copy properties and so on...
+ CValue::AddDataToReplica(replica);
+ return replica;
+}
+
+bool
+KX_StateActuator::Update()
+{
+ bool bNegativeEvent = IsNegativeEvent();
+ unsigned int objMask;
+
+ RemoveAllEvents();
+ if (bNegativeEvent) return false;
+
+ KX_GameObject *obj = (KX_GameObject*) GetParent();
+
+ objMask = obj->GetState();
+ switch (m_operation)
+ {
+ case OP_CPY:
+ objMask = m_mask;
+ break;
+ case OP_SET:
+ objMask |= m_mask;
+ break;
+ case OP_CLR:
+ objMask &= ~m_mask;
+ break;
+ case OP_NEG:
+ objMask ^= m_mask;
+ break;
+ default:
+ // unsupported operation, no nothing
+ return false;
+ }
+ obj->SetState(objMask);
+ return false;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Python functions */
+/* ------------------------------------------------------------------------- */
+
+
+
+/* Integration hooks ------------------------------------------------------- */
+PyTypeObject
+KX_StateActuator::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0,
+ "KX_StateActuator",
+ sizeof(KX_StateActuator),
+ 0,
+ PyDestructor,
+ 0,
+ __getattr,
+ __setattr,
+ 0, //&MyPyCompare,
+ __repr,
+ 0, //&cvalue_as_number,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+PyParentObject
+KX_StateActuator::Parents[] = {
+ &KX_StateActuator::Type,
+ &SCA_IActuator::Type,
+ &SCA_ILogicBrick::Type,
+ &CValue::Type,
+ NULL
+};
+
+PyMethodDef
+KX_StateActuator::Methods[] = {
+ {"setOperation", (PyCFunction) KX_StateActuator::sPySetOperation,
+ METH_VARARGS, SetOperation_doc},
+ {"setMask", (PyCFunction) KX_StateActuator::sPySetMask,
+ METH_VARARGS, SetMask_doc},
+ {NULL,NULL} //Sentinel
+};
+
+PyObject*
+KX_StateActuator::_getattr(
+ const STR_String& attr
+ )
+{
+ _getattr_up(SCA_IActuator);
+};
+
+
+
+/* set operation ---------------------------------------------------------- */
+char
+KX_StateActuator::SetOperation_doc[] =
+"setOperation(op)\n"
+"\t - op : bit operation (0=Copy, 1=Set, 2=Clear, 3=Negate)"
+"\tSet the type of bit operation to be applied on object state mask.\n"
+"\tUse setMask() to specify the bits that will be modified.\n";
+PyObject*
+
+KX_StateActuator::PySetOperation(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int oper;
+
+ if(!PyArg_ParseTuple(args, "i", &oper)) {
+ return NULL;
+ }
+
+ m_operation = oper;
+
+ Py_Return;
+}
+
+/* set mask ---------------------------------------------------------- */
+char
+KX_StateActuator::SetMask_doc[] =
+"setMask(mask)\n"
+"\t - mask : bits that will be modified"
+"\tSet the value that defines the bits that will be modified by the operation.\n"
+"\tThe bits that are 1 in the value will be updated in the object state,\n"
+"\tthe bits that are 0 are will be left unmodified expect for the Copy operation\n"
+"\twhich copies the value to the object state.\n";
+PyObject*
+
+KX_StateActuator::PySetMask(PyObject* self,
+ PyObject* args,
+ PyObject* kwds) {
+ int mask;
+
+ if(!PyArg_ParseTuple(args, "i", &mask)) {
+ return NULL;
+ }
+
+ m_mask = mask;
+
+ Py_Return;
+}
+
+
diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h
new file mode 100644
index 00000000000..8698e51b2c1
--- /dev/null
+++ b/source/gameengine/Ketsji/KX_StateActuator.h
@@ -0,0 +1,83 @@
+/*
+ * $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.
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 *****
+ * Actuator to toggle visibility/invisibility of objects
+ */
+
+#ifndef __KX_STATEACTUATOR
+#define __KX_STATEACTUATOR
+
+#include "SCA_IActuator.h"
+
+class KX_StateActuator : public SCA_IActuator
+{
+ Py_Header;
+
+ /** Make visible? */
+ enum {
+ OP_CPY = 0,
+ OP_SET,
+ OP_CLR,
+ OP_NEG
+ };
+ int m_operation;
+ unsigned int m_mask;
+
+ public:
+
+ KX_StateActuator(
+ SCA_IObject* gameobj,
+ int operation,
+ unsigned int mask,
+ PyTypeObject* T=&Type
+ );
+
+ virtual
+ ~KX_StateActuator(
+ void
+ );
+
+ virtual CValue*
+ GetReplica(
+ void
+ );
+
+ virtual bool
+ Update();
+
+ /* --------------------------------------------------------------------- */
+ /* Python interface ---------------------------------------------------- */
+ /* --------------------------------------------------------------------- */
+
+ virtual PyObject* _getattr(const STR_String& attr);
+ //KX_PYMETHOD_DOC
+ KX_PYMETHOD_DOC(KX_StateActuator,SetOperation);
+ KX_PYMETHOD_DOC(KX_StateActuator,SetMask);
+};
+
+#endif
+
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.cpp b/source/gameengine/Ketsji/KX_TouchSensor.cpp
index 3f185359de0..56c2780871b 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.cpp
+++ b/source/gameengine/Ketsji/KX_TouchSensor.cpp
@@ -77,18 +77,14 @@ KX_TouchSensor::KX_TouchSensor(SCA_EventManager* eventmgr,KX_GameObject* gameobj
:SCA_ISensor(gameobj,eventmgr,T),
m_touchedpropname(touchedpropname),
m_bFindMaterial(bFindMaterial),
-m_eventmgr(eventmgr),
+m_eventmgr(eventmgr)
/*m_sumoObj(sumoObj),*/
-m_bCollision(false),
-m_bTriggered(false),
-m_bLastTriggered(false)
{
// KX_TouchEventManager* touchmgr = (KX_TouchEventManager*) eventmgr;
// m_resptable = touchmgr->GetResponseTable();
// m_solidHandle = m_sumoObj->getObjectHandle();
- m_hitObject = NULL;
m_colliders = new CListValue();
KX_ClientObjectInfo *client_info = gameobj->getClientInfo();
@@ -98,8 +94,16 @@ m_bLastTriggered(false)
m_physCtrl = dynamic_cast<PHY_IPhysicsController*>(gameobj->GetPhysicsController());
MT_assert( !gameobj->GetPhysicsController() || m_physCtrl );
+ Init();
}
+void KX_TouchSensor::Init()
+{
+ m_bCollision = false;
+ m_bTriggered = false;
+ m_bLastTriggered = false;
+ m_hitObject = NULL;
+}
KX_TouchSensor::~KX_TouchSensor()
{
diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h
index f594196628a..056440ccd6c 100644
--- a/source/gameengine/Ketsji/KX_TouchSensor.h
+++ b/source/gameengine/Ketsji/KX_TouchSensor.h
@@ -72,6 +72,7 @@ public:
virtual CValue* GetReplica();
virtual void SynchronizeTransform();
virtual bool Evaluate(CValue* event);
+ virtual void Init();
virtual void ReParent(SCA_IObject* parent);
virtual void RegisterSumo(KX_TouchEventManager* touchman);