Adding characters and basic code

From XStoryPlayer Wiki
Jump to: navigation, search

Adding characters and basic code

<<Collisions and doors

Part 8 This is a long one

scene.ini Scene.ma tutorial.dat

Are up to this point with some extras like 2 of the walls stopped working for some reason so they were replaced

And a few duped items removed that were not meant to be there

Usually id make sure the scene is lighted a bit better and that all the walls were aligned but i wont for this tutorial feel free to do that yourself if you want

Part 8 what to do

we have our scene

we have lights

we have shadows

we have a background

we have collisions

we have doors

I know lets add in Saiko so she can see our scene i mean her house

Open our scene.ma up either the current one you have copied from this folder or your own

Each object and npc we add needs to know where to be placed we use waypoints to tell them where to spawn

Objects that are placed with a waypoint above the ground will fall down but npc's wont they will stand on that "hight level" and all their actions will be at this level

Things will spawn where the waypoint is facing but since its a cube that’s a little hard to know which face is the main one

Make a new Lambert texture and call is "waypointplayerface"

And texture the face where you spawn from ingame Go check if you need to In my scene its the side facing the apartment

Now that we have that make another Lambert and call it "WaypointNpcFace"

And texture the opposite side

Now we always know where they will face and we don’t have to test until we find it

Now we make Saiko's spawnpoint

Select the waypoint we have in the scene and go to

edit > duplicate special's little box


ESKDup.png


Make sure instance and parent are selected then click duplicate special


ESKDupe settings.png


Do i have to do this every time

Yes otherwise it wont work

Well you can do Ctrl+Shift+D but we need to make sure its on those 2 settings first

next part is the names

The first box is what you want to call your waypoint and the 2nd box must be "waypointShape"

So rename the first box to "SaikoSpawn"

Notice how the 2nd box changes to SaikoSpawnShape instead of waypointShape


ESKAnoying.png


Just change it back to "waypointShape"

If doing multiple waypoints change it back last since its an instance changing any will change all back but their first box is unique to each box

Remember first box is what you want it to be and 2nd must be "waypointShape"


Now take our annoying little cube called SaikoSpawn and place it somewhere in the apartment facing the direction you want then save the scene

Next part is to tell her where to spawn

pack_tutorial\init\stories\tutorial\chars\saiko

And open her init.dat Change the scene_id and waypoint to below or whatever you called them

    scene_id = TUTORIAL1;
    waypoint = "SaikoSpawn";

We will cover the rest in a little while

After that is done save the init.dat and run the filemaker

Then go say hello to Saiko

But she is currently deaf and blind so she wont respond and she does not have any code to do anything anyway aaand you cant touch her either but she is there

Now is a little while so lets cover the basics in Saiko's init file

There is too much to write here so open the initexplained.dat in the folder if you want to have a look


Phew can i have a nap now

No?

Ok lets continue

We will add in the 2 doorbells well 4 but only 2 will do anything other then ring

Make a small rectangle box in the scene and place it on the wall next to the door and use whatever material you want i chose the shiny door handles one

Then rename the object to Doorbell and copy it to the other doors

So we should have 4 doorbells

Next open the scene.ini

and add in

rb "DoorbellShape"
{
 
  render {} // Door is rendered
 
  physics
  {
 
  }
  media
  {
    elem[0]
    {
      filename = "scenes/sounds/doorbell/doorbell1.wav";
 
      type      = AUDIO;
      stream    = false;
      pos3d     = true;
      pos3d_min = 1.0;
      start     = false;
      loop      = false;
      volume    = 1.0;
    }
  }
  interact {} // Can open door by hand
}

I added this above the doors

Add in 3 more and rename them correctly

Now we should have 4 doorbell rb's

Next open the tutorial.dat in the pack_tutorial\init\stories\tutorial\scenes

And add in

  button_objecti DOORBELL1
  {
		obj_name = "Doorbell";
  }

Again i did this above the doors

Make 3 more and rename them correctly

Save everything and run the filemaker then go check out your doorbells

Remember when i said rename them correctly i didn’t and got errors...


Ding ding, Ding ding

Bells work

Ok lets make them do something

pack_tutorial\init\stories\tutorial\chars\saiko\brain\code\ref Then open up base_ref.dat

The difference between the 3 refs is

base ref is global commands like the door bell and the player passing events?

While run0_ref is stuff like player talking things that directly effect the npc?

The basic_ref i have no idea never used it

So in the base_ref add in under the //---

TUTORIAL1:DOORBELL1.hit =
{
  talk.s = "hello";
}
TUTORIAL1:DOORBELL1.hit //<--- The name of the scene and its unique name then the action of hitting it
 
  talk.s = "hello"; //<--- Saiko will say anything you put between the ""

Save and go see what she says

Ding ding hello, Ding ding hello

Now that works lets do something a bit more useful with it

Let's add in Monica and get her out of the way

So in the Maya scene special dupe the waypoint Ctrl+Shift+D

Rename it to “MonicaSpawn” and then rename the 2nd box to “waypointShape” and position it behind Monica's door and rotate it correctly so it looks like she is opening the door

Next we need to add Monica into the scene

pack_tutorial\init\stories\tutorial\chars\monica init.dat Change these to match

	cloth_type = CASUAL;
 
    scene_id = TUTORIAL1;
    waypoint = "MonicaSpawn";

And remove

      pose_type = JOG
    pose_id   = 0;

So she will go back to standing

Now save everything and run the filemaker then go see Monica ingame

Now lets incorporate the door bell into the scene

Open the tutorial.dat where the doors are located

And change Monica's door to be

  	door_objecti DOOR2
  {
    q        = 32;
    q_min    = 0;
    q_max    = 32;
    q_spring = 1;
 
	  open = false;
 
obj_name = "MonicaDoor";
}

The q min and max depends on the rotation of the door but if the handle is on the right then its max 32

So we have a locked door we need to make the doorbell tell Monica that someone is here

We need to open Monica's base_ref pack_tutorial\init\stories\tutorial\chars\monica\brain\code\ref And add in

TUTORIAL1:DOORBELL2.hit =
{
[state.dyn.me.do.state2 == NONE]
{
 state.dyn.me.do.state2 = START;
 }
}

This will tell Monica to do [START] inside her run when the doorbell is pressed but only once

Then open pack_tutorial\init\stories\tutorial\chars\monica\brain\code\run run0_state.dat

This is where we will make Monica do stuff

If you have some understanding of coding this will be easy if not this will be harder so i will add images to help also you can check out a later file to see it compleated

We now need to add our [START]

case (state.dyn.me.do.state2)
{ 
  [NONE]
  {
  }
 
    [START]
  {
  talk.s = "coming"; 
  do_set_timer(6);
  state.dyn.me.do.state2 = WALK_TO_DOOR;
  state.dyn.me.do.offended = WAITFOROFF;
  }
}


ESKCode1.png


case (state.dyn.me.do.state2) //<---- You can have multipul cases all working together
 
  [NONE] //<---- Innercase i guess i don’t really know what they would be called but NONE is the default
  {
  }
 
    [START] //<----- When we say state.dyn.me.do.state2 = START
we are saying do this
  {
  talk.s = "coming";//<----- Whatever you want Monica to say when we press the doorbell
  do_set_timer(6); //<---- Wait for 6 seconds
  state.dyn.me.do.state2 = WALK_TO_DOOR; //<--- Go to the next innercase
  state.dyn.me.do.offended = WAITFOROFF; //<---- This one will be added a bit later but its incase we offend monica
  }

Next part is to get the door to open on its own as if monica opened it

[WALK_TO_DOOR]
  {
 
    loc.ts = GetTs();  
		[loc.ts < state.dyn.me.do.ts] return;
 
    // Open door
		loc.so.obj = TUTORIAL1:DOOR2;
		loc.so.par = DOOR_SET_STATUS;
		loc.so.val = DOOR_SETVAL_STATUS_OPEN;	    
		SetObject(loc.so);
 
		// Let door be open from now on
		loc.so.status = loc.so.val;
	  SetObjState(loc.so);
 
		// Can see,hear from now on
		loc.state.can_see  = true;
    loc.state.can_hear = true;
    SetCharState(loc.state); 
		SetCanSee(true);
		SetCanHear(true);
 
		// I am in alerted state
		set_main_focus(STARE);
 
	  do_set_timer(3);
	  state.dyn.me.do.state2 = OPENING_DOOR;
 
  }


ESKCode2.png


[WALK_TO_DOOR]
  {
 
    loc.ts = GetTs();                          //<---
		[loc.ts < state.dyn.me.do.ts] return; //<--- This section says wait for timer to finish and must be added for the timer to work
 
    // Open door
		loc.so.obj = TUTORIAL1:DOOR2; //<--- Our scene name then the door name
		loc.so.par = DOOR_SET_STATUS; //<-- What we are setting
		loc.so.val = DOOR_SETVAL_STATUS_OPEN;	    //<--- Saying we want the door to be open insted of closed
		SetObject(loc.so); //<--- Setting the above
 
		// Let door be open from now on
		loc.so.status = loc.so.val;
	  SetObjState(loc.so);
 
		// Can see,hear from now on
		loc.state.can_see  = true;
    loc.state.can_hear = true;
    SetCharState(loc.state); 
		SetCanSee(true);
		SetCanHear(true);
 
		// I am in alerted state
		set_main_focus(STARE); //<--- Stare at the player
 
	  do_set_timer(3);
	  state.dyn.me.do.state2 = OPENING_DOOR;
 
  }

And then add



  [OPENING_DOOR]
  {
    // Wait for door to open
 
    loc.ts = GetTs();  
		[loc.ts < state.dyn.me.do.ts] return;
 
		// If main not in view
		[!state.dyn.me.avatar.in_view] return;
 
		// Say hello
		talk.s     = "Hello, can I help you?";
		talk.delay = 500;
 
		do_set_timer(3);
 
		state.dyn.me.do.state2 = STANDING_IN_DOOR;
  }




  [OPENING_DOOR]
  {
    // Wait for door to open
 
    loc.ts = GetTs();  
		[loc.ts < state.dyn.me.do.ts] return;
 
		// If main not in view
		[!state.dyn.me.avatar.in_view] return; //<--- If the player is not in sight then keep trying until they are
 
		// Say hello
		talk.s     = "Hello, can I help you?";
		talk.delay = 500; //<--- Wait half a second before talking
 
		do_set_timer(3);
 
		state.dyn.me.do.state2 = STANDING_IN_DOOR;
  }

Now we will add in the code for when Monica is offended getting Monica offended is easy just say something rude or whip something out

[OFFENDED]
	{
	  loc.ts = GetTs();  
		[loc.ts < state.dyn.me.do.ts] return;
 
		// Slam Door
		loc.so.obj = TUTORIAL1:DOOR2;
		loc.so.par = DOOR_SET_Q;
		loc.so.val = 0;
		SetObject(loc.so);
 
		loc.so.par = DOOR_SET_QMIN;
    loc.so.val = 0;  
		SetObject(loc.so);
 
		loc.so.par = DOOR_SET_QMAX;
		loc.so.val = 0;  
		SetObject(loc.so);
 
		loc.so.par = DOOR_SET_QSPRING;
		loc.so.val = 1;
		SetObject(loc.so);
 
		// Let door be closed from now on
		loc.so.door_state_q       =  0;
	  loc.so.door_state_qmin    = 0;
	  loc.so.door_state_qmax    =  0;
	  loc.so.door_state_qspring =  1.33;
	  SetObjState(loc.so);
 
    // Cannot see,hear from now on
    loc.state.scene_id = NONE;				
		loc.state.can_see  = false;
    loc.state.can_hear = false;
    SetCharState(loc.state); 
		SetCanSee(false);
		SetCanHear(false);
 
		state.dyn.me.do.state2 = END;
	}


ESKCode3.png


[OFFENDED] //<------ This is what we will use when monica gets offended
	{
	  loc.ts = GetTs();  
		[loc.ts < state.dyn.me.do.ts] return;
 
		// Slam Door
		loc.so.obj = TUTORIAL1:DOOR2;
		loc.so.par = DOOR_SET_Q; //<--- Set the q to 0 so closed
		loc.so.val = 0;
		SetObject(loc.so);
 
		loc.so.par = DOOR_SET_QMIN;
    loc.so.val = 0;  //<------ Set the min and max to 0 so it wont open
		SetObject(loc.so);
 
		loc.so.par = DOOR_SET_QMAX;
		loc.so.val = 0;  
		SetObject(loc.so);
 
		loc.so.par = DOOR_SET_QSPRING;
		loc.so.val = 1; //<------- Set the spring to 1 so the door slams closed
		SetObject(loc.so);
 
		// Let door be closed from now on
		loc.so.door_state_q       =  0;
	  loc.so.door_state_qmin    = 0;
	  loc.so.door_state_qmax    =  0;
	  loc.so.door_state_qspring =  1.33;
	  SetObjState(loc.so);
 
		    // Cannot see,hear from now on
    loc.state.scene_id = NONE;				//<---- Make monica stop seeing and listening
		loc.state.can_see  = false;
    loc.state.can_hear = false;
    SetCharState(loc.state); 
		SetCanSee(false);
		SetCanHear(false);
		state.dyn.me.do.state2 = END; //<---- We need to pass this to an empty innercase otherwise it can just infinity repeat the above 
	}

Now after the closing bracket for the case but before the end of the state </run0_state>

add in



case (state.dyn.me.do.offended)
{
 [WAITFOROFF]
 
  {
[grel.offended != NONE]
    {
	do_set_timer(1);
      state.dyn.me.do.state2 = OFFENDED;
	  state.dyn.me.do.offended = OFFENDED;
    }
	return;
  }
 
}
case (state.dyn.me.do.offended)//<--- A new case that will work while the other one is going
{
 [WAITFOROFF]
 
  {
 // talk.s     = "waiting for offended"; //<--- This i added for debuging purposes to see if it was actually working
[grel.offended != NONE] //<--- Is Monica offended if so do what is below
    {
	do_set_timer(1);
      state.dyn.me.do.state2 = OFFENDED; //<--- Go to the offended state above and slam the door
	  state.dyn.me.do.offended = OFFENDED;
      //return;
    }
	return;
  }
}

Save everything and go press Monica's doorbell then offend her

You don’t need to run the filemaker unless you have made changes to either the scene.ma or the scene.ini

Now that she can slam the door in your face lets get her to help you

Next thing we need to do is play with the NLP and its words

Now i don’t fully understand how to use the NLP so it is slow and painful for me and this is why my stories have limited player responses if there is a better way to do this i would like someone to let me know

Anyway go ingame and press Monica's doorbell then say something like

"im looking for saiko"

"hi im looking for saiko"

"i have a pizza for saiko"


then exit the game (F3)

Open the trace.txt in the XStoryPlayer3 folder

Look for CTALK this is what the player has just said

then the brain translates it

So if we say

CTALK: "im looking for saiko"

we get the following reactions

21:24:58 BRAIN: "state.code.ref.state.RUN0.look.word"

21:24:58 BRAIN: "state.code.ref.state.RUN0.look.if"

21:24:58 BRAIN: "state.code.ref.state.RUN0.look.get"

21:24:58 BRAIN: "state.code.ref.state.RUN0.activity.word"

21:24:58 BRAIN: "state.code.ref.state.RUN0.activity.if"

21:24:58 BRAIN: "state.code.ref.state.RUN0.activity.get"

21:24:58 BRAIN: "state.code.ref.state.RUN0.word.get"

21:24:58 BRAIN: "state.code.ref.basic.look.word"

21:24:58 BRAIN: "state.code.ref.basic.look.if"

21:24:58 BRAIN: "state.code.ref.basic.look.get"

21:24:58 BRAIN: "state.code.ref.basic.activity.word"

21:24:58 BRAIN: "state.code.ref.basic.activity.if"

21:24:58 BRAIN: "state.code.ref.basic.activity.get"

21:24:58 BRAIN: "state.code.ref.basic.word.get"


We have looking as an activity

And if we say

CTALK: "hi im looking for saiko"

We get

21:25:03 BRAIN: "state.code.ref.state.RUN0.hello.greet"

21:25:03 BRAIN: "state.code.ref.state.RUN0.hello.if"

21:25:03 BRAIN: "state.code.ref.state.RUN0.hello.get"

21:25:03 BRAIN: "state.code.ref.state.RUN0.value.greet"

21:25:03 BRAIN: "state.code.ref.state.RUN0.value.if"

21:25:03 BRAIN: "state.code.ref.state.RUN0.value.get"

21:25:03 BRAIN: "state.code.ref.state.RUN0.greet.get"

21:25:03 BRAIN: "state.code.ref.basic.hello.greet"

21:25:03 BRAIN: "state.code.ref.basic.hello.if"

21:25:03 BRAIN: "state.code.ref.basic.hello.get"

21:25:03 BRAIN: "state.code.ref.basic.value.greet"

21:25:03 BRAIN: "state.code.ref.basic.value.if"

21:25:03 BRAIN: "state.code.ref.basic.value.get"

21:25:03 BRAIN: "state.code.ref.basic.greet.get"


Where hi is the main word referenced as a greeting

CTALK: "i have a pizza for saiko"

21:25:09 BRAIN: "state.code.ref.state.RUN0.saiko.name.me.info"

21:25:09 BRAIN: "state.code.ref.state.RUN0.saiko.name.me.if"

21:25:09 BRAIN: "state.code.ref.state.RUN0.saiko.name.me.get"

21:25:09 BRAIN: "state.code.ref.state.RUN0.saiko.name.me.info"

21:25:09 BRAIN: "state.code.ref.state.RUN0.saiko.name.me.if"

21:25:09 BRAIN: "state.code.ref.state.RUN0.saiko.name.me.get"

21:25:09 BRAIN: "state.code.ref.state.RUN0.value.name.me.info"

21:25:09 BRAIN: "state.code.ref.state.RUN0.value.name.me.if"

21:25:09 BRAIN: "state.code.ref.state.RUN0.value.name.me.get"

21:25:09 BRAIN: "state.code.ref.state.RUN0.value.attr.me.info"

21:25:09 BRAIN: "state.code.ref.state.RUN0.value.attr.me.if"

21:25:09 BRAIN: "state.code.ref.state.RUN0.value.attr.me.get"

In this one we get Saiko's name referenced as a name

This is the annoying part each sentence we gave Monica has Saiko's name in it but only one sentence uses it

"im looking for saiko"

"hi im looking for saiko"

"i have a pizza for saiko"

We can add more then one at a time tho

saiko.name.me.get =
				{
 
				}
 
 
 
basic.hello.get    = saiko.name.me.get;
basic.activity.get = saiko.name.me.get;

So each one will be directed to Saiko's name

The problem with this is if i was to just say

"hi im looking for saiko"

It would be the same as if i said

21:48:32 CTALK: "hello i like licking windows"

21:48:34 BRAIN: "state.code.ref.basic.hello.get"

So the response would be the same

Open Monica's run0_ref

pack_tutorial\init\stories\tutorial\chars\monica\brain\code\ref


And add in

saiko.name.me.get =
				{
				talk.s = "she lives across the hall";
				talk.dur       = 3000;
				talk.rem.s = "Bye";
		  talk.rem.dur   = 1000;
					do_set_timer(6);
				      state.dyn.me.do.state2 = OFFENDED;
	  state.dyn.me.do.offended = OFFENDED;
				}
 
basic.hello.get = saiko.name.me.get;
basic.activity.get = saiko.name.me.get; 
saiko.word = saiko.name.me.get;


This will make Monica say she lives across the hall then bye and she will go to her offended state which is just slamming the door if we had added other dialogue then we would have to make another like [CLOSEDDOOR] and closed the door that way

But what happens if the player does not talk to Monica and then presses Saiko's doorbell or presses Saiko's doorbell first

Well add this into Monica's base_ref.dat

TUTORIAL1:DOORBELL1.hit =
{
[state.dyn.me.do.state2 != NONE]
{
talk.s = "fine then";
					do_set_timer(6);
				      state.dyn.me.do.state2 = OFFENDED;
	  state.dyn.me.do.offended = OFFENDED;
 }
 [state.dyn.me.do.state2 == NONE]
 {
 				      state.dyn.me.do.state2 = OFFENDED;
	  state.dyn.me.do.offended = OFFENDED;
 }
 
}

This will make it if you press Saiko's doorbell while Monica is standing there she will say fine then and close the door

Also if you press Saiko's doorbell first Monica will never answer her door

This will end part 8

In the next part there will be all the files needed

Next we will code Saiko since Monica is all done for now

Part 9 did not think you would make it


>>Coding the story