Hard Light Productions Forums

General FreeSpace => Multiplayer => Topic started by: Zacam on August 16, 2011, 03:38:10 pm

Title: [Test Build] Multi Sexps Camera Test
Post by: Zacam on August 16, 2011, 03:38:10 pm
Using code supplied by CommanderDJ, Karajorma has made a .patch to address some of the multi-sexp usages.
Thread HERE (http://www.hard-light.net/forums/index.php?topic=76177.0)

I've applied this patch to Trunk 7477 and have an SSE version posted here, and I have a Stand Alone based on the same code running, explicitly for testing this SEXP code change.
Debug Inferno SSE.7z (http://swc.fs2downloads.com/builds/WIN/Antipodes/Debug Inferno SSE.7z) (FRED Included, Debug Only w/PDB's)
MD5: 2E0CD3445DC621222FAFA0E7E238A4AD
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 16, 2011, 03:48:01 pm
List of effected sexps:

set-cutscene-bars: works
set-camera-facing: works
set-camera-facing-object: works
set-camera-FOV: works
set-camera-position: works
camera-shudder: works
reset-camera: works
ignore-key: works
set-jumpnode-name: works
set-jumpnode-color: works
show-jumpnode: works
unset-cutscene-bars: works
hide-jumpnode: works
set-FOV: works
reset-FOV: works
set-camera-target: works
set-camera-rotation: works
subtitle-text: works
subtitle-image: works
clear-subtiles: works
fade-out: works
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 17, 2011, 04:50:46 am
set-jumpnode-color and show-jumpnode worked in my tests. What happened client side when you tried them?

As for the others, I only fixed what CommanderDJ had tried to fix so several of those SEXPs were never touched by either of us.  I can certainly fix them if you get them on Mantis and assign it to me.

Anyway, here's my test mission so you can figure out what you are doing differently from me. If you're using only retail assets I can test your mission too.

[attachment deleted by ninja]
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 17, 2011, 02:29:58 pm
My mission only uses retail assets, so its fine. You used a key-press to activate the event while mine are chained and timed, but I dont think that is the problem, and key-pressed wouldn't work client side anyway.

Everything seems to work just fine server-host side, it always does (Does server-host use single player sexps? It sure seems that way) but client side for the non-working, non-crashing, events... nothing happened. No crash, but the intended result didn't happen either. After hiding the node it wouldn't reappear, the camera wouldn't shudder and so on.


MULTI mantis, or SCP? i've seen sexp requests in both.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: Parias on August 17, 2011, 03:46:58 pm
Just as some more general feedback, I gave this a quick test with a cutscene-based mission I'm working in just involving a lot of chained camera-position and camera-rotation events and it seems to work great so far - my client machine processed all the events same as the host did. I haven't tested the secondaries yet (camera-shudder, jump node functionality, etc) and understand from the above postings that some issues may remain there, but the basic stuff is definitely working good now. This is awesome!
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 17, 2011, 08:33:58 pm
Bug reports for non-working code should always be on SCP mantis because it is the job of the entire SCP to fix those. Features should be on MULTI's mantis since those are the responsibility of whichever coders you manage to attract.

I'm rather confused as to why the show-node SEXP worked for me but didn't seem to work for KyadCK, I'll do some testing in an hour or two.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 17, 2011, 09:44:32 pm
And it is on mantis, ID 0002483.

If it means anything, all the problems are client-side with the exception of set-jumpnode-model crashing server, but I'm betting thats because I tried to turn it into an Arcadia.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 18, 2011, 12:31:06 am
New patch

Code: [Select]
Index: code/parse/sexp.cpp
===================================================================
--- code/parse/sexp.cpp (revision 7478)
+++ code/parse/sexp.cpp (working copy)
@@ -18253,8 +18253,43 @@
  }
 
  cam->set_position(&camera_vec, camera_time, camera_acc_time, camera_dec_time);
+
+ //multiplayer callback
+ multi_start_packet();
+ multi_send_float(camera_vec.xyz.x);
+ multi_send_float(camera_vec.xyz.y);
+ multi_send_float(camera_vec.xyz.z);
+ multi_send_float(camera_time);
+ multi_send_float(camera_acc_time);
+ multi_send_float(camera_dec_time);
+ multi_end_packet();
 }
 
+//CommanderDJ
+void multi_sexp_set_camera_position()
+{
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL) {
+ Int3();
+ return;
+ }
+
+ vec3d camera_vec;
+ float camera_time = 0.0f;
+ float camera_acc_time = 0.0f;
+ float camera_dec_time = 0.0f;
+
+ multi_get_float(camera_vec.xyz.x);
+ multi_get_float(camera_vec.xyz.y);
+ multi_get_float(camera_vec.xyz.z);
+ multi_get_float(camera_time);
+ multi_get_float(camera_acc_time);
+ multi_get_float(camera_dec_time);
+
+ cam->set_position(&camera_vec, camera_time, camera_acc_time, camera_dec_time);
+}
+
 void sexp_set_camera_rotation(int n)
 {
  camera *cam = sexp_get_set_camera();
@@ -18324,32 +18359,43 @@
  }
 
  cam->set_rotation_facing(&location, rot_time, rot_acc_time, rot_dec_time);
+
+ //multiplayer callback
+ multi_start_packet();
+ multi_send_float(location.xyz.x);
+ multi_send_float(location.xyz.y);
+ multi_send_float(location.xyz.z);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_packet();
 }
 
-void sexp_set_camera_facing_object(int n)
+void multi_sexp_set_camera_facing()
 {
- char *object_name = CTEXT(n);
+ camera *cam = sexp_get_set_camera();
+ if(cam == NULL)
+ return;
+
+ vec3d location;
  float rot_time = 0.0f;
  float rot_acc_time = 0.0f;
  float rot_dec_time = 0.0f;
 
- //Now get the rotation time values
- n = CDR(n);
- if(n != -1)
- {
- rot_time = eval_num(n) / 1000.0f;
- n = CDR(n);
- if(n != -1)
- {
- rot_dec_time = rot_acc_time = eval_num(n) / 1000.0f;
- n = CDR(n);
- if(n != -1)
- {
- rot_dec_time = eval_num(n) / 1000.0f;
- }
- }
- }
+ multi_get_float(location.xyz.x);
+ multi_get_float(location.xyz.y);
+ multi_get_float(location.xyz.z);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ cam->set_rotation_facing(&location, rot_time, rot_acc_time, rot_dec_time);
+}
 
+//CommanderDJ
+//helper function for set_camera_facing_object
+void actually_set_camera_facing_object(char *object_name, float rot_time, float rot_acc_time, float rot_dec_time)
+{
  object_ship_wing_point_team oswpt;
  sexp_get_object_ship_wing_point_team(&oswpt, object_name);
 
@@ -18375,6 +18421,56 @@
  }
 }
 
+void sexp_set_camera_facing_object(int n)
+{
+ char *object_name = CTEXT(n);
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ //Now get the rotation time values
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_time = eval_num(n) / 1000.0f;
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_dec_time = rot_acc_time = eval_num(n) / 1000.0f;
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_dec_time = eval_num(n) / 1000.0f;
+ }
+ }
+ }
+ actually_set_camera_facing_object(object_name, rot_time, rot_acc_time, rot_dec_time);
+
+ //multiplayer callback
+ multi_start_packet();
+ multi_send_string(object_name);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_packet();
+}
+
+//CommanderDJ
+void multi_sexp_set_camera_facing_object()
+{
+ char object_name[TOKEN_LENGTH];
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ multi_get_string(object_name);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ actually_set_camera_facing_object(object_name, rot_time, rot_acc_time, rot_dec_time);
+}
+
 extern float VIEWER_ZOOM_DEFAULT;
 void sexp_set_camera_fov(int n)
 {
@@ -18407,8 +18503,37 @@
  }
 
  cam->set_fov(camera_fov, camera_time, camera_acc_time, camera_dec_time);
+
+
+ multi_start_packet();
+ multi_send_float(camera_fov);
+ multi_send_float(camera_time);
+ multi_send_float(camera_acc_time);
+ multi_send_float(camera_dec_time);
+ multi_end_packet();
 }
 
+//CommanderDJ
+void multi_sexp_set_camera_fov()
+{
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL)
+ return;
+
+ float camera_fov = VIEWER_ZOOM_DEFAULT;
+ float camera_time = 0.0f;
+ float camera_acc_time = 0.0f;
+ float camera_dec_time = 0.0f;
+
+ multi_get_float(camera_fov);
+ multi_get_float(camera_time);
+ multi_get_float(camera_acc_time);
+ multi_get_float(camera_dec_time);
+
+ cam->set_fov(camera_fov, camera_time, camera_acc_time, camera_dec_time);
+}
+
 //Internal helper function for set-target and set-host
 object *sexp_camera_get_objsub(int node, int *o_submodel)
 {
@@ -18532,17 +18657,34 @@
 
 void sexp_reset_camera(int node)
 {
+ bool cam_reset = false;
  camera *cam = cam_get_current().getCamera();
  if(cam != NULL)
  {
  if(is_sexp_true(node))
  {
  cam->reset();
+ cam_reset = true;
  }
  }
  cam_reset_camera();
+ multi_start_packet();
+ multi_send_bool(cam_reset);
+ multi_end_packet();
 }
 
+void multi_sexp_reset_camera()
+{
+ camera *cam = cam_get_current().getCamera();
+ bool cam_reset = false;
+
+ multi_get_bool(cam_reset);
+ if((cam != NULL) && cam_reset) {
+ cam->reset();
+ }
+ cam_reset_camera();
+}
+
 void sexp_show_subtitle(int node)
 {
  //These should be set to the default if not required to be explicitly defined
@@ -18992,18 +19134,18 @@
 void sexp_set_jumpnode_name(int n) //CommanderDJ
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
-
+
+ char *new_name = CTEXT(n); //for multi
  char *old_name = CTEXT(n); //for multi
 
- if(jnp==NULL)
+ if(jnp==NULL) {
  return;
+ }
 
  n=CDR(n);
 
  jnp->set_name(CTEXT(n));
 
- char *new_name = CTEXT(n); //for multi
-
  //multiplayer callback
  multi_start_packet();
  multi_send_string(old_name);
@@ -19011,14 +19153,12 @@
  multi_end_packet();
 }
 
-void multi_sexp_set_jumpnode_name(int n) //CommanderDJ
+void multi_sexp_set_jumpnode_name() //CommanderDJ
 {
- char *old_name = "\0";
+ char old_name[TOKEN_LENGTH];
+ char new_name[TOKEN_LENGTH];
 
  multi_get_string(old_name);
-
- char *new_name = "\0";
-
  multi_get_string(new_name);
 
  jump_node *jnp = jumpnode_get_by_name(old_name);
@@ -19036,11 +19176,51 @@
  if(jnp==NULL)
  return;
 
+ char* jumpnode_name = CTEXT(n); //for multi
+
  n=CDR(n);
 
- jnp->set_alphacolor(eval_num(n),eval_num(CDR(n)),eval_num(CDR(CDR(n))),eval_num(CDR(CDR(CDR(n)))));
+ int red = eval_num(n);
+
+ int green = eval_num(CDR(n));
+
+ int blue = eval_num(CDR(CDR(n)));
+
+ int alpha = eval_num(CDR(CDR(CDR(n))));
+
+ jnp->set_alphacolor(red, green, blue, alpha);
+
+ multi_start_packet();
+ multi_send_string(jumpnode_name);
+ multi_send_int(red);
+ multi_send_int(green);
+ multi_send_int(blue);
+ multi_send_int(alpha);
+ multi_end_packet();
 }
 
+//CommanderDJ
+void multi_sexp_set_jumpnode_color()
+{
+ char jumpnode_name[TOKEN_LENGTH] ;
+ int red, blue, green, alpha;
+
+ multi_get_string(jumpnode_name);
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp==NULL) {
+ multi_discard_remaining_packet();
+ return;
+ }
+
+ multi_get_int(red);
+ multi_get_int(green);
+ multi_get_int(blue);
+ multi_get_int(alpha);
+
+ jnp->set_alphacolor(red, green, blue, alpha);
+}
+
 void sexp_set_jumpnode_model(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
@@ -19048,27 +19228,90 @@
  if(jnp==NULL)
  return;
 
- n=CDR(n);
+ char* jumpnode_name = CTEXT(n);
 
- jnp->set_model(CTEXT(n), is_sexp_true(CDR(n)) != 0);
+ char* model_name = CTEXT(CDR(n));
+
+ bool show_polys = CDR(CDR(n));
+
+ jnp->set_model(model_name, (is_sexp_true(show_polys) != 0));
+
+ multi_start_packet();
+ multi_send_string(jumpnode_name);
+ multi_send_string(model_name);
+ multi_send_bool(show_polys);
+ multi_end_packet();
 }
 
+void multi_sexp_set_jumpnode_model()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+ char model_name[TOKEN_LENGTH];
+
+ multi_get_string(jumpnode_name);
+ multi_get_string(model_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp==NULL)
+ return;
+
+ bool show_polys;
+
+ show_polys = multi_get_bool(show_polys);
+
+ jnp->set_model(model_name, (is_sexp_true(show_polys) != 0));
+
+}
+
 void sexp_show_jumpnode(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
 
  if(jnp!=NULL)
  jnp->show(true);
+
+ multi_start_packet();
+ multi_send_string(CTEXT(n));
+ multi_end_packet();
 }
 
+void multi_sexp_show_jumpnode()
+{
+ char jumpnode_name[TOKEN_LENGTH] ;
+
+ multi_get_string(jumpnode_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp!=NULL)
+ jnp->show(true);
+}
+
 void sexp_hide_jumpnode(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
 
  if(jnp!=NULL)
  jnp->show(false);
+
+ multi_start_packet();
+ multi_send_string(CTEXT(n));
+ multi_end_packet();
 }
 
+void multi_sexp_hide_jumpnode()
+{
+ char jumpnode_name[TOKEN_LENGTH] ;
+
+ multi_get_string(jumpnode_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp!=NULL)
+ jnp->show(false);
+}
+
 //WMC - This is a bit of a hack, however, it's easier than
 //coding in a whole new SCript_system function.
 int sexp_script_eval(int node, int return_type)
@@ -21619,21 +21862,58 @@
  break;
 
  case OP_CUTSCENES_SET_CUTSCENE_BARS:
+ case OP_CUTSCENES_UNSET_CUTSCENE_BARS:
  multi_sexp_toggle_cutscene_bars(op_num == OP_CUTSCENES_SET_CUTSCENE_BARS );
  break;
 
+ case OP_CUTSCENES_SET_CAMERA_FACING:
+ multi_sexp_set_camera_facing();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_FACING_OBJECT:
+ multi_sexp_set_camera_facing_object();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_FOV:
+ multi_sexp_set_camera_fov();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_POSITION:
+ multi_sexp_set_camera_position();
+ break;
+
  case OP_SET_CAMERA_SHUDDER:
  multi_sexp_set_camera_shudder();
  break;
 
+ case OP_CUTSCENES_RESET_CAMERA:
+ multi_sexp_reset_camera();
+ break;
+
  case OP_JUMP_NODE_SET_JUMPNODE_NAME:
- multi_sexp_set_jumpnode_name(op_num == OP_JUMP_NODE_SET_JUMPNODE_NAME);
+ multi_sexp_set_jumpnode_name();
  break;
 
  case OP_IGNORE_KEY:
  multi_sexp_ignore_key();
  break;
 
+ case OP_JUMP_NODE_SET_JUMPNODE_COLOR:
+ multi_sexp_set_jumpnode_color();
+ break;
+
+ case OP_JUMP_NODE_SET_JUMPNODE_MODEL:
+ multi_sexp_set_jumpnode_model();
+ break;
+
+ case OP_JUMP_NODE_SHOW_JUMPNODE:
+ multi_sexp_show_jumpnode();
+ break;
+
+ case OP_JUMP_NODE_HIDE_JUMPNODE:
+ multi_sexp_hide_jumpnode();
+ break;
+
  // bad sexp in the packet
  default:
  // probably just a version error where the host supports a SEXP but a client does not
@@ -21642,7 +21922,7 @@
  }
  // a more major problem
  else {
- Warning(LOCATION, "Received invalid SEXP packet from host. Function involving operator %d lacks termination. Entire packet may be corrupt. Discarding remaining packet");
+ Warning(LOCATION, "Received invalid SEXP packet from host. Function involving operator %d lacks termination. Entire packet may be corrupt. Discarding remaining packet", op_num);
  Int3();
  return;
  }


The SEXPs that KyadCK report not working (with the exception of reset-camera and unset-cutscene-bars which were actually broken) appear to actually be a mission design issue as I ran server and client next to each other and noticed exactly the same thing happening on both. When I ran my mission instead the hide, show and change colour SEXPs all worked perfectly.


[attachment deleted by ninja]
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 18, 2011, 02:30:51 am
Re-tested using original patch and events triggered via keypress. modified status post to fit.

I dont know yet if jumpnode-name was changed again in the newer patch, but client-side on the original the name didn't change (it did host-side)

Other sexps changed to untested pending new build.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 18, 2011, 03:03:30 am
New patch to resolve the issues caused by my changes to the multi SEXP system in r7481-7480

Code: [Select]
Index: code/parse/sexp.cpp
===================================================================
--- code/parse/sexp.cpp (revision 7480)
+++ code/parse/sexp.cpp (working copy)
@@ -18253,8 +18253,43 @@
  }
 
  cam->set_position(&camera_vec, camera_time, camera_acc_time, camera_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_float(camera_vec.xyz.x);
+ multi_send_float(camera_vec.xyz.y);
+ multi_send_float(camera_vec.xyz.z);
+ multi_send_float(camera_time);
+ multi_send_float(camera_acc_time);
+ multi_send_float(camera_dec_time);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_camera_position()
+{
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL) {
+ Int3();
+ return;
+ }
+
+ vec3d camera_vec;
+ float camera_time = 0.0f;
+ float camera_acc_time = 0.0f;
+ float camera_dec_time = 0.0f;
+
+ multi_get_float(camera_vec.xyz.x);
+ multi_get_float(camera_vec.xyz.y);
+ multi_get_float(camera_vec.xyz.z);
+ multi_get_float(camera_time);
+ multi_get_float(camera_acc_time);
+ multi_get_float(camera_dec_time);
+
+ cam->set_position(&camera_vec, camera_time, camera_acc_time, camera_dec_time);
+}
+
 void sexp_set_camera_rotation(int n)
 {
  camera *cam = sexp_get_set_camera();
@@ -18324,32 +18359,43 @@
  }
 
  cam->set_rotation_facing(&location, rot_time, rot_acc_time, rot_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_float(location.xyz.x);
+ multi_send_float(location.xyz.y);
+ multi_send_float(location.xyz.z);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_callback();
 }
 
-void sexp_set_camera_facing_object(int n)
+void multi_sexp_set_camera_facing()
 {
- char *object_name = CTEXT(n);
+ camera *cam = sexp_get_set_camera();
+ if(cam == NULL)
+ return;
+
+ vec3d location;
  float rot_time = 0.0f;
  float rot_acc_time = 0.0f;
  float rot_dec_time = 0.0f;
 
- //Now get the rotation time values
- n = CDR(n);
- if(n != -1)
- {
- rot_time = eval_num(n) / 1000.0f;
- n = CDR(n);
- if(n != -1)
- {
- rot_dec_time = rot_acc_time = eval_num(n) / 1000.0f;
- n = CDR(n);
- if(n != -1)
- {
- rot_dec_time = eval_num(n) / 1000.0f;
- }
- }
- }
+ multi_get_float(location.xyz.x);
+ multi_get_float(location.xyz.y);
+ multi_get_float(location.xyz.z);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ cam->set_rotation_facing(&location, rot_time, rot_acc_time, rot_dec_time);
+}
 
+//CommanderDJ
+//helper function for set_camera_facing_object
+void actually_set_camera_facing_object(char *object_name, float rot_time, float rot_acc_time, float rot_dec_time)
+{
  object_ship_wing_point_team oswpt;
  sexp_get_object_ship_wing_point_team(&oswpt, object_name);
 
@@ -18375,6 +18421,56 @@
  }
 }
 
+void sexp_set_camera_facing_object(int n)
+{
+ char *object_name = CTEXT(n);
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ //Now get the rotation time values
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_time = eval_num(n) / 1000.0f;
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_dec_time = rot_acc_time = eval_num(n) / 1000.0f;
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_dec_time = eval_num(n) / 1000.0f;
+ }
+ }
+ }
+ actually_set_camera_facing_object(object_name, rot_time, rot_acc_time, rot_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_string(object_name);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_callback();
+}
+
+//CommanderDJ
+void multi_sexp_set_camera_facing_object()
+{
+ char object_name[TOKEN_LENGTH];
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ multi_get_string(object_name);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ actually_set_camera_facing_object(object_name, rot_time, rot_acc_time, rot_dec_time);
+}
+
 extern float VIEWER_ZOOM_DEFAULT;
 void sexp_set_camera_fov(int n)
 {
@@ -18407,8 +18503,37 @@
  }
 
  cam->set_fov(camera_fov, camera_time, camera_acc_time, camera_dec_time);
+
+
+ multi_start_callback();
+ multi_send_float(camera_fov);
+ multi_send_float(camera_time);
+ multi_send_float(camera_acc_time);
+ multi_send_float(camera_dec_time);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_camera_fov()
+{
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL)
+ return;
+
+ float camera_fov = VIEWER_ZOOM_DEFAULT;
+ float camera_time = 0.0f;
+ float camera_acc_time = 0.0f;
+ float camera_dec_time = 0.0f;
+
+ multi_get_float(camera_fov);
+ multi_get_float(camera_time);
+ multi_get_float(camera_acc_time);
+ multi_get_float(camera_dec_time);
+
+ cam->set_fov(camera_fov, camera_time, camera_acc_time, camera_dec_time);
+}
+
 //Internal helper function for set-target and set-host
 object *sexp_camera_get_objsub(int node, int *o_submodel)
 {
@@ -18528,21 +18653,50 @@
 
  Sexp_fov = 0.0;
  //cam->set_fov(VIEWER_ZOOM_DEFAULT);
+
+ multi_start_callback();
+ multi_end_callback();
 }
 
+void multi_sexp_reset_fov()
+{
+ camera *cam = Main_camera.getCamera();
+ if(cam == NULL)
+ return;
+
+ Sexp_fov = 0.0;
+}
+
 void sexp_reset_camera(int node)
 {
+ bool cam_reset = false;
  camera *cam = cam_get_current().getCamera();
  if(cam != NULL)
  {
  if(is_sexp_true(node))
  {
  cam->reset();
+ cam_reset = true;
  }
  }
  cam_reset_camera();
+ multi_start_callback();
+ multi_send_bool(cam_reset);
+ multi_end_callback();
 }
 
+void multi_sexp_reset_camera()
+{
+ camera *cam = cam_get_current().getCamera();
+ bool cam_reset = false;
+
+ multi_get_bool(cam_reset);
+ if((cam != NULL) && cam_reset) {
+ cam->reset();
+ }
+ cam_reset_camera();
+}
+
 void sexp_show_subtitle(int node)
 {
  //These should be set to the default if not required to be explicitly defined
@@ -18638,10 +18792,18 @@
  Subtitles.push_back(new_subtitle);
 }
 
-void sexp_clear_subtitles() {
+void sexp_clear_subtitles()
+{
  Subtitles.clear();
+
+ multi_do_callback();
 }
 
+void multi_sexp_clear_subtitles()
+{
+ Subtitles.clear();
+}
+
 void sexp_show_subtitle_text(int node)
 {
  int n = node;
@@ -18992,18 +19154,18 @@
 void sexp_set_jumpnode_name(int n) //CommanderDJ
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
-
+
+ char *new_name = CTEXT(n); //for multi
  char *old_name = CTEXT(n); //for multi
 
- if(jnp==NULL)
+ if(jnp==NULL) {
  return;
+ }
 
  n=CDR(n);
 
  jnp->set_name(CTEXT(n));
 
- char *new_name = CTEXT(n); //for multi
-
  //multiplayer callback
  multi_start_callback();
  multi_send_string(old_name);
@@ -19011,14 +19173,12 @@
  multi_end_callback();
 }
 
-void multi_sexp_set_jumpnode_name(int n) //CommanderDJ
+void multi_sexp_set_jumpnode_name() //CommanderDJ
 {
- char *old_name = "\0";
+ char old_name[TOKEN_LENGTH];
+ char new_name[TOKEN_LENGTH];
 
  multi_get_string(old_name);
-
- char *new_name = "\0";
-
  multi_get_string(new_name);
 
  jump_node *jnp = jumpnode_get_by_name(old_name);
@@ -19036,11 +19196,51 @@
  if(jnp==NULL)
  return;
 
+ char* jumpnode_name = CTEXT(n); //for multi
+
  n=CDR(n);
 
- jnp->set_alphacolor(eval_num(n),eval_num(CDR(n)),eval_num(CDR(CDR(n))),eval_num(CDR(CDR(CDR(n)))));
+ int red = eval_num(n);
+
+ int green = eval_num(CDR(n));
+
+ int blue = eval_num(CDR(CDR(n)));
+
+ int alpha = eval_num(CDR(CDR(CDR(n))));
+
+ jnp->set_alphacolor(red, green, blue, alpha);
+
+ multi_start_callback();
+ multi_send_string(jumpnode_name);
+ multi_send_int(red);
+ multi_send_int(green);
+ multi_send_int(blue);
+ multi_send_int(alpha);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_jumpnode_color()
+{
+ char jumpnode_name[TOKEN_LENGTH] ;
+ int red, blue, green, alpha;
+
+ multi_get_string(jumpnode_name);
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp==NULL) {
+ multi_discard_remaining_callback_data();
+ return;
+ }
+
+ multi_get_int(red);
+ multi_get_int(green);
+ multi_get_int(blue);
+ multi_get_int(alpha);
+
+ jnp->set_alphacolor(red, green, blue, alpha);
+}
+
 void sexp_set_jumpnode_model(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
@@ -19048,27 +19248,90 @@
  if(jnp==NULL)
  return;
 
- n=CDR(n);
+ char* jumpnode_name = CTEXT(n);
 
- jnp->set_model(CTEXT(n), is_sexp_true(CDR(n)) != 0);
+ char* model_name = CTEXT(CDR(n));
+
+ bool show_polys = CDR(CDR(n));
+
+ jnp->set_model(model_name, (is_sexp_true(show_polys) != 0));
+
+ multi_start_callback();
+ multi_send_string(jumpnode_name);
+ multi_send_string(model_name);
+ multi_send_bool(show_polys);
+ multi_end_callback();
 }
 
+void multi_sexp_set_jumpnode_model()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+ char model_name[TOKEN_LENGTH];
+
+ multi_get_string(jumpnode_name);
+ multi_get_string(model_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp==NULL)
+ return;
+
+ bool show_polys;
+
+ show_polys = multi_get_bool(show_polys);
+
+ jnp->set_model(model_name, (is_sexp_true(show_polys) != 0));
+
+}
+
 void sexp_show_jumpnode(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
 
  if(jnp!=NULL)
  jnp->show(true);
+
+ multi_start_callback();
+ multi_send_string(CTEXT(n));
+ multi_end_callback();
 }
 
+void multi_sexp_show_jumpnode()
+{
+ char jumpnode_name[TOKEN_LENGTH] ;
+
+ multi_get_string(jumpnode_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp!=NULL)
+ jnp->show(true);
+}
+
 void sexp_hide_jumpnode(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
 
  if(jnp!=NULL)
  jnp->show(false);
+
+ multi_start_callback();
+ multi_send_string(CTEXT(n));
+ multi_end_callback();
 }
 
+void multi_sexp_hide_jumpnode()
+{
+ char jumpnode_name[TOKEN_LENGTH] ;
+
+ multi_get_string(jumpnode_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp!=NULL)
+ jnp->show(false);
+}
+
 //WMC - This is a bit of a hack, however, it's easier than
 //coding in a whole new SCript_system function.
 int sexp_script_eval(int node, int return_type)
@@ -21619,21 +21882,66 @@
  break;
 
  case OP_CUTSCENES_SET_CUTSCENE_BARS:
+ case OP_CUTSCENES_UNSET_CUTSCENE_BARS:
  multi_sexp_toggle_cutscene_bars(op_num == OP_CUTSCENES_SET_CUTSCENE_BARS );
  break;
 
+ case OP_CUTSCENES_SET_CAMERA_FACING:
+ multi_sexp_set_camera_facing();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_FACING_OBJECT:
+ multi_sexp_set_camera_facing_object();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_FOV:
+ multi_sexp_set_camera_fov();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_POSITION:
+ multi_sexp_set_camera_position();
+ break;
+
  case OP_SET_CAMERA_SHUDDER:
  multi_sexp_set_camera_shudder();
  break;
 
+ case OP_CUTSCENES_RESET_CAMERA:
+ multi_sexp_reset_camera();
+ break;
+
+ case OP_CUTSCENES_RESET_FOV:
+ multi_sexp_reset_fov();
+ break;
+
  case OP_JUMP_NODE_SET_JUMPNODE_NAME:
- multi_sexp_set_jumpnode_name(op_num == OP_JUMP_NODE_SET_JUMPNODE_NAME);
+ multi_sexp_set_jumpnode_name();
  break;
 
  case OP_IGNORE_KEY:
  multi_sexp_ignore_key();
  break;
 
+ case OP_JUMP_NODE_SET_JUMPNODE_COLOR:
+ multi_sexp_set_jumpnode_color();
+ break;
+
+ case OP_JUMP_NODE_SET_JUMPNODE_MODEL:
+ multi_sexp_set_jumpnode_model();
+ break;
+
+ case OP_JUMP_NODE_SHOW_JUMPNODE:
+ multi_sexp_show_jumpnode();
+ break;
+
+ case OP_JUMP_NODE_HIDE_JUMPNODE:
+ multi_sexp_hide_jumpnode();
+ break;
+
+ case OP_CLEAR_SUBTITLES:
+ multi_sexp_clear_subtitles();
+ break;
+
  // bad sexp in the packet
  default:
  // probably just a version error where the host supports a SEXP but a client does not
@@ -21642,7 +21950,7 @@
  }
  // a more major problem
  else {
- Warning(LOCATION, "Received invalid SEXP packet from host. Function involving operator %d lacks termination. Entire packet may be corrupt. Discarding remaining packet");
+ Warning(LOCATION, "Received invalid SEXP packet from host. Function involving operator %d lacks termination. Entire packet may be corrupt. Discarding remaining packet", op_num);
  Int3();
  return;
  }

I threw in a reset-fov SEXP and clear-subtitles SEXP while I was at it. You won't be able to test the latter until I fix the actual subtitle SEXPs of course. :p

EDIT : http://fs2downloads.com/Misc-Downloads/Builds/MoreMultiFixes.7z you can try that build instead of the one at the top of the thread.

[attachment deleted by ninja]
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: Parias on August 18, 2011, 08:06:26 am
Ran through my own little test mission with the latest build and I can confirm that set-camera-fov works.

Noticed a little weird problem with the fade-out SEXP though (I know this isn't on KyadCK's list, but..) - the "red" fade-out (passing it 2 for the second number value) shows up red as expected for the host, but shows as black for the client.

Edit: Same deal with white fade-outs as well; my client always seems to receive them as black.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 18, 2011, 01:04:51 pm
Status post updated.

EDIT: and updated again after a more formal test, reset-camera still isnt working client-side
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 18, 2011, 09:40:16 pm
Ummm. Reset camera works for me. So I don't know what's going on there. Which mission did you test with?
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 18, 2011, 10:52:33 pm
modified from your origonal, used:

-when
    key pressed
        (key)
    set camera position
         (position)
(chain 3 seconds)
-when
       true
    set camera facing
          (cords)
(chain 5 seconds)
-when
       true
    reset-camera

both zalem and lester reported their views not being reset, i'll check again with key-press for reset incase I messed something up


EDIT: apperently i just dont know how to use cutscene sexps right, but key-press trigger works, will just use that from now on
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 19, 2011, 12:54:23 am
OKay, I'll look at the rest now.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: CommanderDJ on August 19, 2011, 01:00:36 am
Woohoo, go karajorma. Looking forward to how this turns out!
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: bigchunk1 on August 19, 2011, 01:57:15 am
Yes, this is making me all warm & fuzzy inside as well.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 19, 2011, 03:04:46 am
Updated the build. AFAIK everything should work now.

Code: [Select]
Index: code/parse/sexp.cpp
===================================================================
--- code/parse/sexp.cpp (revision 7487)
+++ code/parse/sexp.cpp (working copy)
@@ -18099,8 +18099,31 @@
  }
 }
 
-void sexp_fade_out(float delta_time, ubyte R, ubyte G, ubyte B)
+void sexp_fade_out(float delta_time, int fade_type)
 {
+ ubyte R = 0;
+ ubyte G = 0;
+ ubyte B = 0;
+
+ switch(fade_type)
+ {
+ //White out
+ case 1:
+ gr_create_shader(&Viewer_shader, 255, 255, 255, Viewer_shader.c);
+ break;
+ //Red out
+ case 2:
+ gr_create_shader(&Viewer_shader, 255, 0, 0, Viewer_shader.c);
+ break;
+ //Black out
+ default:
+ gr_create_shader(&Viewer_shader, 0, 0, 0, Viewer_shader.c);
+ }
+
+ R = Viewer_shader.r;
+ G = Viewer_shader.g;
+ B = Viewer_shader.b;
+
  if(delta_time > 0.0f) {
  Fade_type = FI_FADEOUT;
  Fade_delta_time = delta_time;
@@ -18115,9 +18138,7 @@
 void sexp_fade_out(int n)
 {
  float delta_time = 0.0f;
- ubyte R = 0;
- ubyte G = 0;
- ubyte B = 0;
+ int fade_type = 0;
 
  if(n != -1)
  {
@@ -18126,57 +18147,30 @@
  n = CDR(n);
  if(n != -1)
  {
- switch(eval_num(n))
- {
- //White out
- case 1:
- gr_create_shader(&Viewer_shader, 255, 255, 255, Viewer_shader.c);
- break;
- //Red out
- case 2:
- gr_create_shader(&Viewer_shader, 255, 0, 0, Viewer_shader.c);
- break;
- //Black out
- default:
- gr_create_shader(&Viewer_shader, 0, 0, 0, Viewer_shader.c);
- }
-
- R = Viewer_shader.r;
- G = Viewer_shader.g;
- B = Viewer_shader.b;
+ fade_type = eval_num(n);
  }
- else
- {
- gr_create_shader(&Viewer_shader, 0, 0, 0, Viewer_shader.c);
- }
  }
 
- sexp_fade_out(delta_time, R, G, B);
+ sexp_fade_out(delta_time, fade_type);
 
  multi_start_callback();
  multi_send_float(delta_time);
- multi_send_int(R);
- multi_send_int(G);
- multi_send_int(B);
+ multi_send_int(fade_type);
  multi_end_callback();
 }
 
 void multi_sexp_fade_out()
 {
  float delta_time = 0.0f;
- int R = 0;
- int G = 0;
- int B = 0;
+ int fade_type;
 
  multi_get_float(delta_time);
- multi_get_int(R);
- multi_get_int(G);
- if (!multi_get_int(B)){
+ if (!multi_get_int(fade_type)){
  Int3(); // misformed packet
  return;
  }
 
- sexp_fade_out(delta_time, (ubyte)R, (ubyte)G, (ubyte)B);
+ sexp_fade_out(delta_time, fade_type);
 }
 
 camera* sexp_get_set_camera(bool reset = false)
@@ -18253,8 +18247,43 @@
  }
 
  cam->set_position(&camera_vec, camera_time, camera_acc_time, camera_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_float(camera_vec.xyz.x);
+ multi_send_float(camera_vec.xyz.y);
+ multi_send_float(camera_vec.xyz.z);
+ multi_send_float(camera_time);
+ multi_send_float(camera_acc_time);
+ multi_send_float(camera_dec_time);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_camera_position()
+{
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL) {
+ Int3();
+ return;
+ }
+
+ vec3d camera_vec;
+ float camera_time = 0.0f;
+ float camera_acc_time = 0.0f;
+ float camera_dec_time = 0.0f;
+
+ multi_get_float(camera_vec.xyz.x);
+ multi_get_float(camera_vec.xyz.y);
+ multi_get_float(camera_vec.xyz.z);
+ multi_get_float(camera_time);
+ multi_get_float(camera_acc_time);
+ multi_get_float(camera_dec_time);
+
+ cam->set_position(&camera_vec, camera_time, camera_acc_time, camera_dec_time);
+}
+
 void sexp_set_camera_rotation(int n)
 {
  camera *cam = sexp_get_set_camera();
@@ -18289,8 +18318,38 @@
  }
 
  cam->set_rotation(&rot_angles, rot_time, rot_acc_time, rot_dec_time);
+
+ multi_start_callback();
+ multi_send_float(rot_angles.b);
+ multi_send_float(rot_angles.h);
+ multi_send_float(rot_angles.p);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_callback();
 }
 
+void multi_sexp_set_camera_rotation()
+{
+ camera *cam = sexp_get_set_camera();
+ if(cam == NULL)
+ return;
+
+ angles rot_angles;
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ multi_get_float(rot_angles.b);
+ multi_get_float(rot_angles.h);
+ multi_get_float(rot_angles.p);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ cam->set_rotation(&rot_angles, rot_time, rot_acc_time, rot_dec_time);
+}
+
 void sexp_set_camera_facing(int n)
 {
  camera *cam = sexp_get_set_camera();
@@ -18324,32 +18383,43 @@
  }
 
  cam->set_rotation_facing(&location, rot_time, rot_acc_time, rot_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_float(location.xyz.x);
+ multi_send_float(location.xyz.y);
+ multi_send_float(location.xyz.z);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_callback();
 }
 
-void sexp_set_camera_facing_object(int n)
+void multi_sexp_set_camera_facing()
 {
- char *object_name = CTEXT(n);
+ camera *cam = sexp_get_set_camera();
+ if(cam == NULL)
+ return;
+
+ vec3d location;
  float rot_time = 0.0f;
  float rot_acc_time = 0.0f;
  float rot_dec_time = 0.0f;
 
- //Now get the rotation time values
- n = CDR(n);
- if(n != -1)
- {
- rot_time = eval_num(n) / 1000.0f;
- n = CDR(n);
- if(n != -1)
- {
- rot_dec_time = rot_acc_time = eval_num(n) / 1000.0f;
- n = CDR(n);
- if(n != -1)
- {
- rot_dec_time = eval_num(n) / 1000.0f;
- }
- }
- }
+ multi_get_float(location.xyz.x);
+ multi_get_float(location.xyz.y);
+ multi_get_float(location.xyz.z);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ cam->set_rotation_facing(&location, rot_time, rot_acc_time, rot_dec_time);
+}
 
+//CommanderDJ
+//helper function for set_camera_facing_object
+void actually_set_camera_facing_object(char *object_name, float rot_time, float rot_acc_time, float rot_dec_time)
+{
  object_ship_wing_point_team oswpt;
  sexp_get_object_ship_wing_point_team(&oswpt, object_name);
 
@@ -18375,6 +18445,56 @@
  }
 }
 
+void sexp_set_camera_facing_object(int n)
+{
+ char *object_name = CTEXT(n);
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ //Now get the rotation time values
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_time = eval_num(n) / 1000.0f;
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_dec_time = rot_acc_time = eval_num(n) / 1000.0f;
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_dec_time = eval_num(n) / 1000.0f;
+ }
+ }
+ }
+ actually_set_camera_facing_object(object_name, rot_time, rot_acc_time, rot_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_string(object_name);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_callback();
+}
+
+//CommanderDJ
+void multi_sexp_set_camera_facing_object()
+{
+ char object_name[TOKEN_LENGTH];
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ multi_get_string(object_name);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ actually_set_camera_facing_object(object_name, rot_time, rot_acc_time, rot_dec_time);
+}
+
 extern float VIEWER_ZOOM_DEFAULT;
 void sexp_set_camera_fov(int n)
 {
@@ -18407,8 +18527,37 @@
  }
 
  cam->set_fov(camera_fov, camera_time, camera_acc_time, camera_dec_time);
+
+
+ multi_start_callback();
+ multi_send_float(camera_fov);
+ multi_send_float(camera_time);
+ multi_send_float(camera_acc_time);
+ multi_send_float(camera_dec_time);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_camera_fov()
+{
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL)
+ return;
+
+ float camera_fov = VIEWER_ZOOM_DEFAULT;
+ float camera_time = 0.0f;
+ float camera_acc_time = 0.0f;
+ float camera_dec_time = 0.0f;
+
+ multi_get_float(camera_fov);
+ multi_get_float(camera_time);
+ multi_get_float(camera_acc_time);
+ multi_get_float(camera_dec_time);
+
+ cam->set_fov(camera_fov, camera_time, camera_acc_time, camera_dec_time);
+}
+
 //Internal helper function for set-target and set-host
 object *sexp_camera_get_objsub(int node, int *o_submodel)
 {
@@ -18492,8 +18641,30 @@
 
  //*****Set
  cam->set_object_target(objp, submodel);
+
+ multi_start_callback();
+ multi_send_object(objp);
+ multi_send_int(submodel);
+ multi_end_callback();
 }
 
+void multi_sexp_set_camera_target()
+{
+ int submodel;
+ object *objp;
+
+ //Try to get current camera
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL)
+ return;
+
+ multi_get_object(objp);
+ multi_get_int(submodel);
+
+ cam->set_object_target(objp, submodel);
+}
+
 void sexp_set_fov(int n)
 {
  camera *cam = Main_camera.getCamera();
@@ -18506,8 +18677,24 @@
 
  Sexp_fov = (new_fov * (PI/180.0f));
  //cam->set_fov(eval_num(n) * (PI/180.0f));
+
+ multi_start_callback();
+ multi_send_float(new_fov);
+ multi_end_callback();
 }
 
+void multi_sexp_set_fov()
+{
+ float new_fov;
+
+ camera *cam = Main_camera.getCamera();
+ if(cam == NULL)
+ return;
+
+ multi_get_float(new_fov);
+ Sexp_fov = (new_fov * (PI/180.0f));
+}
+
 int sexp_get_fov()
 {
  camera *cam = Main_camera.getCamera();
@@ -18528,21 +18715,50 @@
 
  Sexp_fov = 0.0;
  //cam->set_fov(VIEWER_ZOOM_DEFAULT);
+
+ multi_start_callback();
+ multi_end_callback();
 }
 
+void multi_sexp_reset_fov()
+{
+ camera *cam = Main_camera.getCamera();
+ if(cam == NULL)
+ return;
+
+ Sexp_fov = 0.0;
+}
+
 void sexp_reset_camera(int node)
 {
+ bool cam_reset = false;
  camera *cam = cam_get_current().getCamera();
  if(cam != NULL)
  {
  if(is_sexp_true(node))
  {
  cam->reset();
+ cam_reset = true;
  }
  }
  cam_reset_camera();
+ multi_start_callback();
+ multi_send_bool(cam_reset);
+ multi_end_callback();
 }
 
+void multi_sexp_reset_camera()
+{
+ camera *cam = cam_get_current().getCamera();
+ bool cam_reset = false;
+
+ multi_get_bool(cam_reset);
+ if((cam != NULL) && cam_reset) {
+ cam->reset();
+ }
+ cam_reset_camera();
+}
+
 void sexp_show_subtitle(int node)
 {
  //These should be set to the default if not required to be explicitly defined
@@ -18638,10 +18854,18 @@
  Subtitles.push_back(new_subtitle);
 }
 
-void sexp_clear_subtitles() {
+void sexp_clear_subtitles()
+{
  Subtitles.clear();
+
+ multi_do_callback();
 }
 
+void multi_sexp_clear_subtitles()
+{
+ Subtitles.clear();
+}
+
 void sexp_show_subtitle_text(int node)
 {
  int n = node;
@@ -18992,18 +19216,18 @@
 void sexp_set_jumpnode_name(int n) //CommanderDJ
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
-
+
+ char *new_name = CTEXT(n); //for multi
  char *old_name = CTEXT(n); //for multi
 
- if(jnp==NULL)
+ if(jnp==NULL) {
  return;
+ }
 
  n=CDR(n);
 
  jnp->set_name(CTEXT(n));
 
- char *new_name = CTEXT(n); //for multi
-
  //multiplayer callback
  multi_start_callback();
  multi_send_string(old_name);
@@ -19011,14 +19235,12 @@
  multi_end_callback();
 }
 
-void multi_sexp_set_jumpnode_name(int n) //CommanderDJ
+void multi_sexp_set_jumpnode_name() //CommanderDJ
 {
- char *old_name = "\0";
+ char old_name[TOKEN_LENGTH];
+ char new_name[TOKEN_LENGTH];
 
  multi_get_string(old_name);
-
- char *new_name = "\0";
-
  multi_get_string(new_name);
 
  jump_node *jnp = jumpnode_get_by_name(old_name);
@@ -19036,11 +19258,48 @@
  if(jnp==NULL)
  return;
 
+ char* jumpnode_name = CTEXT(n); //for multi
+
  n=CDR(n);
 
- jnp->set_alphacolor(eval_num(n),eval_num(CDR(n)),eval_num(CDR(CDR(n))),eval_num(CDR(CDR(CDR(n)))));
+ int red = eval_num(n);
+ int green = eval_num(CDR(n));
+ int blue = eval_num(CDR(CDR(n)));
+ int alpha = eval_num(CDR(CDR(CDR(n))));
+
+ jnp->set_alphacolor(red, green, blue, alpha);
+
+ multi_start_callback();
+ multi_send_string(jumpnode_name);
+ multi_send_int(red);
+ multi_send_int(green);
+ multi_send_int(blue);
+ multi_send_int(alpha);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_jumpnode_color()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+ int red, blue, green, alpha;
+
+ multi_get_string(jumpnode_name);
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp==NULL) {
+ multi_discard_remaining_callback_data();
+ return;
+ }
+
+ multi_get_int(red);
+ multi_get_int(green);
+ multi_get_int(blue);
+ multi_get_int(alpha);
+
+ jnp->set_alphacolor(red, green, blue, alpha);
+}
+
 void sexp_set_jumpnode_model(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
@@ -19048,27 +19307,86 @@
  if(jnp==NULL)
  return;
 
- n=CDR(n);
+ char* jumpnode_name = CTEXT(n);
+ char* model_name = CTEXT(CDR(n));
+ int show_polys = is_sexp_true(CDR(CDR(n)));
 
- jnp->set_model(CTEXT(n), is_sexp_true(CDR(n)) != 0);
+ jnp->set_model(model_name, show_polys != 0);
+
+ multi_start_callback();
+ multi_send_string(jumpnode_name);
+ multi_send_string(model_name);
+ multi_send_int(show_polys);
+ multi_end_callback();
 }
 
+void multi_sexp_set_jumpnode_model()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+ char model_name[TOKEN_LENGTH];
+ int show_polys;
+
+ multi_get_string(jumpnode_name);
+ multi_get_string(model_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp==NULL)
+ return;
+
+ show_polys = multi_get_int(show_polys);
+
+ jnp->set_model(model_name, show_polys != 0);
+}
+
 void sexp_show_jumpnode(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
 
  if(jnp!=NULL)
  jnp->show(true);
+
+ multi_start_callback();
+ multi_send_string(CTEXT(n));
+ multi_end_callback();
 }
 
+void multi_sexp_show_jumpnode()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+
+ multi_get_string(jumpnode_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp!=NULL)
+ jnp->show(true);
+}
+
 void sexp_hide_jumpnode(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
 
  if(jnp!=NULL)
  jnp->show(false);
+
+ multi_start_callback();
+ multi_send_string(CTEXT(n));
+ multi_end_callback();
 }
 
+void multi_sexp_hide_jumpnode()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+
+ multi_get_string(jumpnode_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp!=NULL)
+ jnp->show(false);
+}
+
 //WMC - This is a bit of a hack, however, it's easier than
 //coding in a whole new SCript_system function.
 int sexp_script_eval(int node, int return_type)
@@ -21619,21 +21937,78 @@
  break;
 
  case OP_CUTSCENES_SET_CUTSCENE_BARS:
+ case OP_CUTSCENES_UNSET_CUTSCENE_BARS:
  multi_sexp_toggle_cutscene_bars(op_num == OP_CUTSCENES_SET_CUTSCENE_BARS );
  break;
 
+ case OP_CUTSCENES_SET_CAMERA_FACING:
+ multi_sexp_set_camera_facing();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_FACING_OBJECT:
+ multi_sexp_set_camera_facing_object();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_TARGET :
+ multi_sexp_set_camera_target();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_ROTATION:
+ multi_sexp_set_camera_rotation();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_FOV:
+ multi_sexp_set_camera_fov();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_POSITION:
+ multi_sexp_set_camera_position();
+ break;
+
  case OP_SET_CAMERA_SHUDDER:
  multi_sexp_set_camera_shudder();
  break;
 
+ case OP_CUTSCENES_RESET_CAMERA:
+ multi_sexp_reset_camera();
+ break;
+
+ case OP_CUTSCENES_SET_FOV:
+ multi_sexp_set_fov();
+ break;
+
+ case OP_CUTSCENES_RESET_FOV:
+ multi_sexp_reset_fov();
+ break;
+
  case OP_JUMP_NODE_SET_JUMPNODE_NAME:
- multi_sexp_set_jumpnode_name(op_num == OP_JUMP_NODE_SET_JUMPNODE_NAME);
+ multi_sexp_set_jumpnode_name();
  break;
 
  case OP_IGNORE_KEY:
  multi_sexp_ignore_key();
  break;
 
+ case OP_JUMP_NODE_SET_JUMPNODE_COLOR:
+ multi_sexp_set_jumpnode_color();
+ break;
+
+ case OP_JUMP_NODE_SET_JUMPNODE_MODEL:
+ multi_sexp_set_jumpnode_model();
+ break;
+
+ case OP_JUMP_NODE_SHOW_JUMPNODE:
+ multi_sexp_show_jumpnode();
+ break;
+
+ case OP_JUMP_NODE_HIDE_JUMPNODE:
+ multi_sexp_hide_jumpnode();
+ break;
+
+ case OP_CLEAR_SUBTITLES:
+ multi_sexp_clear_subtitles();
+ break;
+
  // bad sexp in the packet
  default:
  // probably just a version error where the host supports a SEXP but a client does not
@@ -21642,7 +22017,7 @@
  }
  // a more major problem
  else {
- Warning(LOCATION, "Received invalid SEXP packet from host. Function involving operator %d lacks termination. Entire packet may be corrupt. Discarding remaining packet");
+ Warning(LOCATION, "Received invalid SEXP packet from host. Function involving operator %d lacks termination. Entire packet may be corrupt. Discarding remaining packet", op_num);
  Int3();
  return;
  }

[attachment deleted by ninja]
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 19, 2011, 03:14:19 am
I still don't know how to apply patches yet, can someone who does turn this into a usable build so I can test it please?
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 19, 2011, 03:19:13 am
I already did. Same link as before. :D

http://fs2downloads.com/Misc-Downloads/Builds/MoreMultiFixes.7z
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 19, 2011, 03:26:50 am
Sneaky. Considering I already compile I suppose I should probably learn how to apply patches at some point too.

I do have a question though. For Set-jumpnode-model, when I used Tinsl.pof or whatever the arcadia's model name is, it crashed the server. Is it limited to specific models and I just did it wrong, or was this something that got fixed?
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 19, 2011, 03:31:25 am
To be honest I have no idea, I've never used that SEXP.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 19, 2011, 04:16:46 am
Tested some more, status list updated. 3 crashes and 1 not quite working this time, pastebins included

EDIT: Tested and updated again. 2 more not quite working, but I'm honestly not that worried about jumpnode-name or jumpnode-model.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: Parias on August 19, 2011, 04:48:11 am
Looks like Fade-out is fully functional now - both red and white. Thanks!
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 19, 2011, 05:40:19 am
Tested some more, status list updated. 3 crashes and 1 not quite working this time, pastebins included

EDIT: Tested and updated again. 2 more not quite working, but I'm honestly not that worried about jumpnode-name or jumpnode-model.

Can you post the mission you used for testing. Those errors are consistent with the ones I'd expect if people weren't using the same builds but the SEXPs triggering them were altered quite a while back.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 19, 2011, 01:26:20 pm
For most of the tests, we used the untitled.fs2 attached below. Subtitle-image crash was discovered using the WiH intro modified for BPmulti as its the only mission I have where I know the cutscene sexps were done right and it happened to have subtitle-image at the end.

[attachment deleted by ninja]
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: Zacam on August 19, 2011, 06:16:55 pm
Patch 4 to Trunk 7490 + Stand Alone

Debug Inferno SSE2.7z (http://swc.fs2downloads.com/builds/WIN/Antipodes/Debug Inferno SSE2.7z) (FRED Included, Debug Only w/PDB's)
MD5: 87E400CE7FEA008BAEAD28C88F1AABFE
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 19, 2011, 11:31:06 pm
Hopefully the last round of changes. Both the reset-fov and clear subtitles SEXPs were ones which didn't send any data. That uncovered a flaw in the system which I've now patched.

Here's the code

Code: [Select]
Index: network/multi_sexp.cpp
===================================================================
--- network/multi_sexp.cpp (revision 7491)
+++ network/multi_sexp.cpp (working copy)
@@ -444,27 +444,30 @@
 
 void multi_reduce_counts(int amount)
 {
- ubyte terminator;
-
  Multi_sexp_bytes_left -= amount;
  current_argument_count -= amount;
 
  if (Multi_sexp_bytes_left < 0 || current_argument_count < 0) {
  Warning(LOCATION, "multi_get_x function call has read an invalid amount of data. Trace out and fix this!");
  }
+}
 
- if (current_argument_count == 0) {
- // read in the terminator
- GET_DATA(terminator);
- if (terminator != CALLBACK_TERMINATOR) {
- Warning(LOCATION, "multi_get_x function call has been called on an improperly terminated callback. Trace out and fix this!");
- // discard remainder of packet
- Multi_sexp_bytes_left = 0;
- return;
- }
- Multi_sexp_bytes_left--;
- op_num = -1;
+void multi_finished_callback()
+{
+ ubyte terminator;
+
+ Assert(current_argument_count == 0);
+
+ // read in the terminator
+ GET_DATA(terminator);
+ if (terminator != CALLBACK_TERMINATOR) {
+ Warning(LOCATION, "multi_get_x function call has been called on an improperly terminated callback. Trace out and fix this!");
+ // discard remainder of packet
+ Multi_sexp_bytes_left = 0;
+ return;
  }
+ Multi_sexp_bytes_left--;
+ op_num = -1;
 }
 
 bool multi_sexp_discard_operator()
Index: network/multi_sexp.h
===================================================================
--- network/multi_sexp.h (revision 7491)
+++ network/multi_sexp.h (working copy)
@@ -30,6 +30,7 @@
 void sexp_packet_received(ubyte *received_packet, int num_ubytes);
 int multi_sexp_get_next_operator();
 int multi_sexp_get_operator();
+void multi_finished_callback();
 bool multi_sexp_discard_operator();
 
 void multi_discard_remaining_callback_data();
Index: parse/sexp.cpp
===================================================================
--- parse/sexp.cpp (revision 7491)
+++ parse/sexp.cpp (working copy)
@@ -18099,8 +18099,31 @@
  }
 }
 
-void sexp_fade_out(float delta_time, ubyte R, ubyte G, ubyte B)
+void sexp_fade_out(float delta_time, int fade_type)
 {
+ ubyte R = 0;
+ ubyte G = 0;
+ ubyte B = 0;
+
+ switch(fade_type)
+ {
+ //White out
+ case 1:
+ gr_create_shader(&Viewer_shader, 255, 255, 255, Viewer_shader.c);
+ break;
+ //Red out
+ case 2:
+ gr_create_shader(&Viewer_shader, 255, 0, 0, Viewer_shader.c);
+ break;
+ //Black out
+ default:
+ gr_create_shader(&Viewer_shader, 0, 0, 0, Viewer_shader.c);
+ }
+
+ R = Viewer_shader.r;
+ G = Viewer_shader.g;
+ B = Viewer_shader.b;
+
  if(delta_time > 0.0f) {
  Fade_type = FI_FADEOUT;
  Fade_delta_time = delta_time;
@@ -18115,9 +18138,7 @@
 void sexp_fade_out(int n)
 {
  float delta_time = 0.0f;
- ubyte R = 0;
- ubyte G = 0;
- ubyte B = 0;
+ int fade_type = 0;
 
  if(n != -1)
  {
@@ -18126,57 +18147,30 @@
  n = CDR(n);
  if(n != -1)
  {
- switch(eval_num(n))
- {
- //White out
- case 1:
- gr_create_shader(&Viewer_shader, 255, 255, 255, Viewer_shader.c);
- break;
- //Red out
- case 2:
- gr_create_shader(&Viewer_shader, 255, 0, 0, Viewer_shader.c);
- break;
- //Black out
- default:
- gr_create_shader(&Viewer_shader, 0, 0, 0, Viewer_shader.c);
- }
-
- R = Viewer_shader.r;
- G = Viewer_shader.g;
- B = Viewer_shader.b;
+ fade_type = eval_num(n);
  }
- else
- {
- gr_create_shader(&Viewer_shader, 0, 0, 0, Viewer_shader.c);
- }
  }
 
- sexp_fade_out(delta_time, R, G, B);
+ sexp_fade_out(delta_time, fade_type);
 
  multi_start_callback();
  multi_send_float(delta_time);
- multi_send_int(R);
- multi_send_int(G);
- multi_send_int(B);
+ multi_send_int(fade_type);
  multi_end_callback();
 }
 
 void multi_sexp_fade_out()
 {
  float delta_time = 0.0f;
- int R = 0;
- int G = 0;
- int B = 0;
+ int fade_type;
 
  multi_get_float(delta_time);
- multi_get_int(R);
- multi_get_int(G);
- if (!multi_get_int(B)){
+ if (!multi_get_int(fade_type)){
  Int3(); // misformed packet
  return;
  }
 
- sexp_fade_out(delta_time, (ubyte)R, (ubyte)G, (ubyte)B);
+ sexp_fade_out(delta_time, fade_type);
 }
 
 camera* sexp_get_set_camera(bool reset = false)
@@ -18253,8 +18247,43 @@
  }
 
  cam->set_position(&camera_vec, camera_time, camera_acc_time, camera_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_float(camera_vec.xyz.x);
+ multi_send_float(camera_vec.xyz.y);
+ multi_send_float(camera_vec.xyz.z);
+ multi_send_float(camera_time);
+ multi_send_float(camera_acc_time);
+ multi_send_float(camera_dec_time);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_camera_position()
+{
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL) {
+ Int3();
+ return;
+ }
+
+ vec3d camera_vec;
+ float camera_time = 0.0f;
+ float camera_acc_time = 0.0f;
+ float camera_dec_time = 0.0f;
+
+ multi_get_float(camera_vec.xyz.x);
+ multi_get_float(camera_vec.xyz.y);
+ multi_get_float(camera_vec.xyz.z);
+ multi_get_float(camera_time);
+ multi_get_float(camera_acc_time);
+ multi_get_float(camera_dec_time);
+
+ cam->set_position(&camera_vec, camera_time, camera_acc_time, camera_dec_time);
+}
+
 void sexp_set_camera_rotation(int n)
 {
  camera *cam = sexp_get_set_camera();
@@ -18289,8 +18318,38 @@
  }
 
  cam->set_rotation(&rot_angles, rot_time, rot_acc_time, rot_dec_time);
+
+ multi_start_callback();
+ multi_send_float(rot_angles.b);
+ multi_send_float(rot_angles.h);
+ multi_send_float(rot_angles.p);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_callback();
 }
 
+void multi_sexp_set_camera_rotation()
+{
+ camera *cam = sexp_get_set_camera();
+ if(cam == NULL)
+ return;
+
+ angles rot_angles;
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ multi_get_float(rot_angles.b);
+ multi_get_float(rot_angles.h);
+ multi_get_float(rot_angles.p);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ cam->set_rotation(&rot_angles, rot_time, rot_acc_time, rot_dec_time);
+}
+
 void sexp_set_camera_facing(int n)
 {
  camera *cam = sexp_get_set_camera();
@@ -18324,32 +18383,43 @@
  }
 
  cam->set_rotation_facing(&location, rot_time, rot_acc_time, rot_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_float(location.xyz.x);
+ multi_send_float(location.xyz.y);
+ multi_send_float(location.xyz.z);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_callback();
 }
 
-void sexp_set_camera_facing_object(int n)
+void multi_sexp_set_camera_facing()
 {
- char *object_name = CTEXT(n);
+ camera *cam = sexp_get_set_camera();
+ if(cam == NULL)
+ return;
+
+ vec3d location;
  float rot_time = 0.0f;
  float rot_acc_time = 0.0f;
  float rot_dec_time = 0.0f;
 
- //Now get the rotation time values
- n = CDR(n);
- if(n != -1)
- {
- rot_time = eval_num(n) / 1000.0f;
- n = CDR(n);
- if(n != -1)
- {
- rot_dec_time = rot_acc_time = eval_num(n) / 1000.0f;
- n = CDR(n);
- if(n != -1)
- {
- rot_dec_time = eval_num(n) / 1000.0f;
- }
- }
- }
+ multi_get_float(location.xyz.x);
+ multi_get_float(location.xyz.y);
+ multi_get_float(location.xyz.z);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ cam->set_rotation_facing(&location, rot_time, rot_acc_time, rot_dec_time);
+}
 
+//CommanderDJ
+//helper function for set_camera_facing_object
+void actually_set_camera_facing_object(char *object_name, float rot_time, float rot_acc_time, float rot_dec_time)
+{
  object_ship_wing_point_team oswpt;
  sexp_get_object_ship_wing_point_team(&oswpt, object_name);
 
@@ -18375,6 +18445,56 @@
  }
 }
 
+void sexp_set_camera_facing_object(int n)
+{
+ char *object_name = CTEXT(n);
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ //Now get the rotation time values
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_time = eval_num(n) / 1000.0f;
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_dec_time = rot_acc_time = eval_num(n) / 1000.0f;
+ n = CDR(n);
+ if(n != -1)
+ {
+ rot_dec_time = eval_num(n) / 1000.0f;
+ }
+ }
+ }
+ actually_set_camera_facing_object(object_name, rot_time, rot_acc_time, rot_dec_time);
+
+ //multiplayer callback
+ multi_start_callback();
+ multi_send_string(object_name);
+ multi_send_float(rot_time);
+ multi_send_float(rot_acc_time);
+ multi_send_float(rot_dec_time);
+ multi_end_callback();
+}
+
+//CommanderDJ
+void multi_sexp_set_camera_facing_object()
+{
+ char object_name[TOKEN_LENGTH];
+ float rot_time = 0.0f;
+ float rot_acc_time = 0.0f;
+ float rot_dec_time = 0.0f;
+
+ multi_get_string(object_name);
+ multi_get_float(rot_time);
+ multi_get_float(rot_acc_time);
+ multi_get_float(rot_dec_time);
+
+ actually_set_camera_facing_object(object_name, rot_time, rot_acc_time, rot_dec_time);
+}
+
 extern float VIEWER_ZOOM_DEFAULT;
 void sexp_set_camera_fov(int n)
 {
@@ -18407,8 +18527,37 @@
  }
 
  cam->set_fov(camera_fov, camera_time, camera_acc_time, camera_dec_time);
+
+
+ multi_start_callback();
+ multi_send_float(camera_fov);
+ multi_send_float(camera_time);
+ multi_send_float(camera_acc_time);
+ multi_send_float(camera_dec_time);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_camera_fov()
+{
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL)
+ return;
+
+ float camera_fov = VIEWER_ZOOM_DEFAULT;
+ float camera_time = 0.0f;
+ float camera_acc_time = 0.0f;
+ float camera_dec_time = 0.0f;
+
+ multi_get_float(camera_fov);
+ multi_get_float(camera_time);
+ multi_get_float(camera_acc_time);
+ multi_get_float(camera_dec_time);
+
+ cam->set_fov(camera_fov, camera_time, camera_acc_time, camera_dec_time);
+}
+
 //Internal helper function for set-target and set-host
 object *sexp_camera_get_objsub(int node, int *o_submodel)
 {
@@ -18492,8 +18641,30 @@
 
  //*****Set
  cam->set_object_target(objp, submodel);
+
+ multi_start_callback();
+ multi_send_object(objp);
+ multi_send_int(submodel);
+ multi_end_callback();
 }
 
+void multi_sexp_set_camera_target()
+{
+ int submodel;
+ object *objp;
+
+ //Try to get current camera
+ camera *cam = sexp_get_set_camera();
+
+ if(cam == NULL)
+ return;
+
+ multi_get_object(objp);
+ multi_get_int(submodel);
+
+ cam->set_object_target(objp, submodel);
+}
+
 void sexp_set_fov(int n)
 {
  camera *cam = Main_camera.getCamera();
@@ -18506,8 +18677,24 @@
 
  Sexp_fov = (new_fov * (PI/180.0f));
  //cam->set_fov(eval_num(n) * (PI/180.0f));
+
+ multi_start_callback();
+ multi_send_float(new_fov);
+ multi_end_callback();
 }
 
+void multi_sexp_set_fov()
+{
+ float new_fov;
+
+ camera *cam = Main_camera.getCamera();
+ if(cam == NULL)
+ return;
+
+ multi_get_float(new_fov);
+ Sexp_fov = (new_fov * (PI/180.0f));
+}
+
 int sexp_get_fov()
 {
  camera *cam = Main_camera.getCamera();
@@ -18528,21 +18715,49 @@
 
  Sexp_fov = 0.0;
  //cam->set_fov(VIEWER_ZOOM_DEFAULT);
+
+ multi_do_callback();
 }
 
+void multi_sexp_reset_fov()
+{
+ camera *cam = Main_camera.getCamera();
+ if(cam == NULL)
+ return;
+
+ Sexp_fov = 0.0;
+}
+
 void sexp_reset_camera(int node)
 {
+ bool cam_reset = false;
  camera *cam = cam_get_current().getCamera();
  if(cam != NULL)
  {
  if(is_sexp_true(node))
  {
  cam->reset();
+ cam_reset = true;
  }
  }
  cam_reset_camera();
+ multi_start_callback();
+ multi_send_bool(cam_reset);
+ multi_end_callback();
 }
 
+void multi_sexp_reset_camera()
+{
+ camera *cam = cam_get_current().getCamera();
+ bool cam_reset = false;
+
+ multi_get_bool(cam_reset);
+ if((cam != NULL) && cam_reset) {
+ cam->reset();
+ }
+ cam_reset_camera();
+}
+
 void sexp_show_subtitle(int node)
 {
  //These should be set to the default if not required to be explicitly defined
@@ -18638,10 +18853,18 @@
  Subtitles.push_back(new_subtitle);
 }
 
-void sexp_clear_subtitles() {
+void sexp_clear_subtitles()
+{
  Subtitles.clear();
+
+ multi_do_callback();
 }
 
+void multi_sexp_clear_subtitles()
+{
+ Subtitles.clear();
+}
+
 void sexp_show_subtitle_text(int node)
 {
  int n = node;
@@ -18992,18 +19215,18 @@
 void sexp_set_jumpnode_name(int n) //CommanderDJ
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
-
+
+ char *new_name = CTEXT(n); //for multi
  char *old_name = CTEXT(n); //for multi
 
- if(jnp==NULL)
+ if(jnp==NULL) {
  return;
+ }
 
  n=CDR(n);
 
  jnp->set_name(CTEXT(n));
 
- char *new_name = CTEXT(n); //for multi
-
  //multiplayer callback
  multi_start_callback();
  multi_send_string(old_name);
@@ -19011,14 +19234,12 @@
  multi_end_callback();
 }
 
-void multi_sexp_set_jumpnode_name(int n) //CommanderDJ
+void multi_sexp_set_jumpnode_name() //CommanderDJ
 {
- char *old_name = "\0";
+ char old_name[TOKEN_LENGTH];
+ char new_name[TOKEN_LENGTH];
 
  multi_get_string(old_name);
-
- char *new_name = "\0";
-
  multi_get_string(new_name);
 
  jump_node *jnp = jumpnode_get_by_name(old_name);
@@ -19036,11 +19257,48 @@
  if(jnp==NULL)
  return;
 
+ char* jumpnode_name = CTEXT(n); //for multi
+
  n=CDR(n);
 
- jnp->set_alphacolor(eval_num(n),eval_num(CDR(n)),eval_num(CDR(CDR(n))),eval_num(CDR(CDR(CDR(n)))));
+ int red = eval_num(n);
+ int green = eval_num(CDR(n));
+ int blue = eval_num(CDR(CDR(n)));
+ int alpha = eval_num(CDR(CDR(CDR(n))));
+
+ jnp->set_alphacolor(red, green, blue, alpha);
+
+ multi_start_callback();
+ multi_send_string(jumpnode_name);
+ multi_send_int(red);
+ multi_send_int(green);
+ multi_send_int(blue);
+ multi_send_int(alpha);
+ multi_end_callback();
 }
 
+//CommanderDJ
+void multi_sexp_set_jumpnode_color()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+ int red, blue, green, alpha;
+
+ multi_get_string(jumpnode_name);
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp==NULL) {
+ multi_discard_remaining_callback_data();
+ return;
+ }
+
+ multi_get_int(red);
+ multi_get_int(green);
+ multi_get_int(blue);
+ multi_get_int(alpha);
+
+ jnp->set_alphacolor(red, green, blue, alpha);
+}
+
 void sexp_set_jumpnode_model(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
@@ -19048,27 +19306,86 @@
  if(jnp==NULL)
  return;
 
- n=CDR(n);
+ char* jumpnode_name = CTEXT(n);
+ char* model_name = CTEXT(CDR(n));
+ int show_polys = is_sexp_true(CDR(CDR(n)));
 
- jnp->set_model(CTEXT(n), is_sexp_true(CDR(n)) != 0);
+ jnp->set_model(model_name, show_polys != 0);
+
+ multi_start_callback();
+ multi_send_string(jumpnode_name);
+ multi_send_string(model_name);
+ multi_send_int(show_polys);
+ multi_end_callback();
 }
 
+void multi_sexp_set_jumpnode_model()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+ char model_name[TOKEN_LENGTH];
+ int show_polys;
+
+ multi_get_string(jumpnode_name);
+ multi_get_string(model_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp==NULL)
+ return;
+
+ show_polys = multi_get_int(show_polys);
+
+ jnp->set_model(model_name, show_polys != 0);
+}
+
 void sexp_show_jumpnode(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
 
  if(jnp!=NULL)
  jnp->show(true);
+
+ multi_start_callback();
+ multi_send_string(CTEXT(n));
+ multi_end_callback();
 }
 
+void multi_sexp_show_jumpnode()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+
+ multi_get_string(jumpnode_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp!=NULL)
+ jnp->show(true);
+}
+
 void sexp_hide_jumpnode(int n)
 {
  jump_node *jnp = jumpnode_get_by_name(CTEXT(n));
 
  if(jnp!=NULL)
  jnp->show(false);
+
+ multi_start_callback();
+ multi_send_string(CTEXT(n));
+ multi_end_callback();
 }
 
+void multi_sexp_hide_jumpnode()
+{
+ char jumpnode_name[TOKEN_LENGTH];
+
+ multi_get_string(jumpnode_name);
+
+ jump_node *jnp = jumpnode_get_by_name(jumpnode_name);
+
+ if(jnp!=NULL)
+ jnp->show(false);
+}
+
 //WMC - This is a bit of a hack, however, it's easier than
 //coding in a whole new SCript_system function.
 int sexp_script_eval(int node, int return_type)
@@ -21619,21 +21936,78 @@
  break;
 
  case OP_CUTSCENES_SET_CUTSCENE_BARS:
+ case OP_CUTSCENES_UNSET_CUTSCENE_BARS:
  multi_sexp_toggle_cutscene_bars(op_num == OP_CUTSCENES_SET_CUTSCENE_BARS );
  break;
 
+ case OP_CUTSCENES_SET_CAMERA_FACING:
+ multi_sexp_set_camera_facing();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_FACING_OBJECT:
+ multi_sexp_set_camera_facing_object();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_TARGET :
+ multi_sexp_set_camera_target();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_ROTATION:
+ multi_sexp_set_camera_rotation();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_FOV:
+ multi_sexp_set_camera_fov();
+ break;
+
+ case OP_CUTSCENES_SET_CAMERA_POSITION:
+ multi_sexp_set_camera_position();
+ break;
+
  case OP_SET_CAMERA_SHUDDER:
  multi_sexp_set_camera_shudder();
  break;
 
+ case OP_CUTSCENES_RESET_CAMERA:
+ multi_sexp_reset_camera();
+ break;
+
+ case OP_CUTSCENES_SET_FOV:
+ multi_sexp_set_fov();
+ break;
+
+ case OP_CUTSCENES_RESET_FOV:
+ multi_sexp_reset_fov();
+ break;
+
  case OP_JUMP_NODE_SET_JUMPNODE_NAME:
- multi_sexp_set_jumpnode_name(op_num == OP_JUMP_NODE_SET_JUMPNODE_NAME);
+ multi_sexp_set_jumpnode_name();
  break;
 
  case OP_IGNORE_KEY:
  multi_sexp_ignore_key();
  break;
 
+ case OP_JUMP_NODE_SET_JUMPNODE_COLOR:
+ multi_sexp_set_jumpnode_color();
+ break;
+
+ case OP_JUMP_NODE_SET_JUMPNODE_MODEL:
+ multi_sexp_set_jumpnode_model();
+ break;
+
+ case OP_JUMP_NODE_SHOW_JUMPNODE:
+ multi_sexp_show_jumpnode();
+ break;
+
+ case OP_JUMP_NODE_HIDE_JUMPNODE:
+ multi_sexp_hide_jumpnode();
+ break;
+
+ case OP_CLEAR_SUBTITLES:
+ multi_sexp_clear_subtitles();
+ break;
+
  // bad sexp in the packet
  default:
  // probably just a version error where the host supports a SEXP but a client does not
@@ -21642,11 +22016,13 @@
  }
  // a more major problem
  else {
- Warning(LOCATION, "Received invalid SEXP packet from host. Function involving operator %d lacks termination. Entire packet may be corrupt. Discarding remaining packet");
+ Warning(LOCATION, "Received invalid SEXP packet from host. Function involving operator %d lacks termination. Entire packet may be corrupt. Discarding remaining packet", op_num);
  Int3();
  return;
  }
  }
+
+ multi_finished_callback();
  }
 }
 

and here's a build to test with

http://fs2downloads.com/Misc-Downloads/Builds/MoreMultiFixes.7z

I can't test the issue with subtitles until someone gives me a retail mission that tests it but everything else should be fixed so I probably can commit this.

[attachment deleted by ninja]
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 20, 2011, 04:07:24 pm
crash when clearing subtitle-image (server side): http://pastebin.com/Zzy2tXF1
crash when setting subtitle-image (client side): http://pastebin.com/kQ0vdwZ4

a tga image to test subtitle-image with: http://www.mediafire.com/?m0etlo25rfukojs

status post updated with recent test results, aside from node-name and node-model (which we dont care about that much) this is all thats left.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 22, 2011, 05:59:44 am
crash when clearing subtitle-image (server side): http://pastebin.com/Zzy2tXF1

Ummm. What?

The code for that SEXP is one line! If it's crashing it's nothing that I did that's causing it. Can you get the same crash in single player too?

Seriously though I really can't test this stuff without a test mission made for retail. And that's also where you should be doing your testing too. If Blue Planet is crashing when retail isn't then the issue may be with Blue Planet not the code. That's why I like to test with retail only.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 22, 2011, 11:43:29 am
Well we hit a slight wall then, because I cant think of any retail mission that uses subtitle-image, nor do I have any idea where to put the .tga for a retail mission to read it from. We've tried under fs2/data/interface/ (only example i had was ***.vp/interface/) and fs2/data/hud/ under lester's sugestion, and renaming the image, and removing .tga from it in the event. After 4 tests, every one nothing happened server-side (couldnt find the file?) and crashed client: http://pastebin.com/SH4599Sw
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 22, 2011, 07:35:46 pm
If you post the mission, I'll look into it. :)
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 22, 2011, 08:09:54 pm
Here is the mission: http://www.mediafire.com/?asth5bp69f3twwr (name in-game is 'cutscenes')
Here again is the image: http://www.mediafire.com/?m0etlo25rfukojs

Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 24, 2011, 03:39:16 am
Fixed. The reason why your jump nodes weren't working appears to be due to them having a space in the name. Try them without and they should work. If you need spaces in jump nodes file a separate Mantis request and I'm sure someone else can fix that pretty quickly.

The image subtitles SEXP works without crashing but since I can't get the image to actually appear either I have no idea whether the SEXP is actually working or not.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: KyadCK on August 24, 2011, 05:12:46 pm
Well, subtitle-image works now, just tested wit the WiH intro in multi. Need to learn where that file belongs at some point.

A massive thank you for getting all these working Karajorma!  :yes:
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 24, 2011, 08:40:04 pm
No problem.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: karajorma on August 25, 2011, 12:52:59 am
Hmmmmm. Actually I need some people to test something in multiplayer so now there's a small price to pay for my help. :p

http://fs2downloads.com/Misc-Downloads/Builds/MoreMultiFixes.7z

Updated from the last time. This should be the same as the next nightly to come out but the weapons and object limits have been bumped. I need people to check that this doesn't screw anything up in multiplayer before I commit it.
Title: Re: [Test Build] Multi Sexps Camera Test
Post by: MatthTheGeek on August 25, 2011, 05:00:04 am
Just made a quick test with SSX-Kahn and no issue to report.