Jump to content

redsaurus

Members
  • Posts

    352
  • Joined

  • Last visited

Everything posted by redsaurus

  1. I think you've just got the tag rotated the wrong way, I'll try to explain the tag_holsterorigin better later. EDIT: I will make some changes to the code so that things are more consistent so probably best for you to wait a bit. The saber appearing in your hand when you use the saber command is the bug, nothing to do with holsters, but I'll fix that.
  2. Sorry this one is so long. Thanks to @@Ramikad for already covering how to do dialogue, I've mentioned it briefly anyway for completeness. Any feedback is useful (especially bad ) PART 3: MOTION I thought it would be more interesting if the player had to force push the door open to get to the second level, so I had a quick read up on rotating doors: http://www.student.oulu.fi/~lvaarisk/tutorials/rotadoor_index.htm (the tutorial is actually mirrored on jkhub too). It's a nice tutorial to go through anyway. Following lassev's tutorial, I created two (quite big) doors. For each door, I created an origin brush where the door would be rotated around, and then made the door and origin brush into a func_static. I set the f_push spawnflag on the two func_static entities so that they would be activated by force push. I set both doors' soundset key to stonedoor, and set the script_targetname keys to bigdoorl and bigdoorr respectively. To rotate the doors a new script would be required, so I created a target_scriptrunner with usescript set to map1/bigdoors. I targeted both of the door func_static entities at the target_scriptrunner, so that when they were force pushed the target_scriptrunner would run the script at scripts/map1/bigdoors.ibi. As the default count value of a target_scriptrunner is 1, the script is only run once, so I didn't have to worry about it accidentally being run again once the doors were open. Now I needed to make the script, so I created bigdoors.icarus and put it in scripts/map1 in my base folder. As the door is only meant to open once and I didn't need all of the stuff from lassev's tutorial it's a pretty short script: affect ( "bigdoorr", FLUSH ) { rotate ( < 0 -75 0 >, 2500 ); } affect ( "bigdoorl", FLUSH ) { rotate ( < 0 75 0 >, 2500 ); } It just rotates both doors to the desired angle (±75 degrees) over a period of 2500ms. I compiled the script, did a fresh compile of the map, and tested it out. It worked, but the crosshair force corona effect still showed even when I'd opened the doors. This is fine, especially if the door is going to be reusable, but I decided to fix this. I checked how some of the force stuff was done in kor1_sample.map and went back to Radiant. I unset the f_push spawnflag on the func_static door entities, and also removed their target using Del Key/Pair. To actually trigger the door opening, I created another func_static entity from a brush textured with textures/system/caulk_nonsolid. I set its f_push spawnflag and targeted it at the target_scriptrunner that would open the doors. I'd noticed that in kor1_sample.map some of the force usable things were set up so that only the player could activate them - that wasn't really necessary here, but I did it just to be safe and so set the npc_targetname key of the new func_static to player. I also set the script_targetname key to dummydoor so that it would be possible to remove the dummy func_static after the player had opened the doors, and stop the force crosshair effect from showing. That meant adding another couple of lines to bigdoors.icarus: affect ( "bigdoorr", FLUSH ) { rotate ( < 0 -75 0 >, 2500 ); } affect ( "bigdoorl", FLUSH ) { rotate ( < 0 75 0 >, 2500 ); } affect ( "dummydoor", FLUSH ) { remove ( "self" ); } After compiling the script and doing a fresh compile of the map, I tested that it still worked. (note: the remove ICARUS command only takes a targetname, *not* a script_targetname, as its argument, so remove( "dummydoor" ); wouldn't work unless the func_static had its targetname set to dummydoor. The affect command instead looks for a script_targetname. If an entity does not have a script_targetname set, then its script_targetname will be the same as its targetname) There was still the slight problem that someone just using the map command to load map1 might not have any levels of force push, and so wouldn't be able to open the door. I changed the intro.icarus script in scripts/map1 to fix that by setting the player's force powers and spawn weapon. That meant adding a few lines to the very top of the script: affect ( "player", /*@AFFECT_TYPE*/ FLUSH ) { set ( /*@SET_TYPES*/ "SET_SABER_THROW", /*@[member='Force']_LEVELS*/ "2" ); set ( /*@SET_TYPES*/ "SET_SABER_DEFENSE", /*@[member='Force']_LEVELS*/ "2" ); set ( /*@SET_TYPES*/ "SET_SABER_OFFENSE", /*@[member='SaberBlade83']_STYLES*/ "2" ); set ( /*@SET_TYPES*/ "SET_FORCE_HEAL_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_JUMP_LEVEL", /*@[member='Force']_LEVELS*/ "3" ); set ( /*@SET_TYPES*/ "SET_FORCE_SPEED_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_PUSH_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_PULL_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_MINDTRICK_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_GRIP_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_LIGHTNING_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_RAGE_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_PROTECT_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_ABSORB_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_DRAIN_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_SIGHT_LEVEL", /*@[member='Force']_LEVELS*/ "3" ); set ( /*@SET_TYPES*/ "SET_WEAPON", /*@[member='weaponx']_NAMES*/ "WP_NONE" ); // This means that the player spawns with no weapons in their hands } camera ( /*@CAMERA_COMMANDS*/ ENABLE ); etc... recompiling the script, and of course testing. Before moving onto the second level, I decided to make it so that the player's Z-95 actually landed in the cutscene at the start of map1. Fortunately I'd already made it a func_static, so I just needed to set its script_targetname to z95. I also turned the z95 shadow plane into a func_static, consisting of an origin brush and the shadow brush, and set its script_targetname to z95_shadow. It's probably most sensible to have your func_static placed where you want it to start from, but I'd placed it where I wanted it to finish, which meant there would be a little extra work. So that it would be easier to write the script to move the Z-95, I placed a load of ref_tag entities. Firstly, one at the origin brush of the shadow with targetname set to shadow_end and another at the origin brush of the Z-95 with targetname set to z95_end. This would be then end destination for the Z-95 and its shadow. Next, I placed one a few hundred units above the Z-95's origin brush with targetname set to z95_hover - the Z-95 would descend and rotate from z95_hover to z95_end. Finally, I placed two more ref_tag entities offset from z95_hover and shadow_end by a few hundred units in the x direction, and gave them targetname z95_start and shadow_start respectively. The Z-95 would move between these ref_tag entities. Since I was placing ref_tag entities, I put in another with targetname set to z95cam that would be the position of the camera view following the Z-95. That was everything needed in terms of entities, so I did a fresh compile of the map and moved onto scripting again. Here's what I wrote in intro.icarus: affect ( "player", /*@AFFECT_TYPE*/ FLUSH ) { set ( /*@SET_TYPES*/ "SET_SABER_THROW", /*@[member='Force']_LEVELS*/ "2" ); set ( /*@SET_TYPES*/ "SET_SABER_DEFENSE", /*@[member='Force']_LEVELS*/ "2" ); set ( /*@SET_TYPES*/ "SET_SABER_OFFENSE", /*@[member='SaberBlade83']_STYLES*/ "2" ); set ( /*@SET_TYPES*/ "SET_FORCE_HEAL_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_JUMP_LEVEL", /*@[member='Force']_LEVELS*/ "3" ); set ( /*@SET_TYPES*/ "SET_FORCE_SPEED_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_PUSH_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_PULL_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_MINDTRICK_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_GRIP_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_LIGHTNING_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_RAGE_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_PROTECT_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_ABSORB_LEVEL", /*@[member='Force']_LEVELS*/ "1" ); set ( /*@SET_TYPES*/ "SET_FORCE_DRAIN_LEVEL", /*@[member='Force']_LEVELS*/ "0" ); set ( /*@SET_TYPES*/ "SET_FORCE_SIGHT_LEVEL", /*@[member='Force']_LEVELS*/ "3" ); set ( /*@SET_TYPES*/ "SET_WEAPON", /*@[member='weaponx']_NAMES*/ "WP_NONE" ); // This means that the player spawns with no weapons in their hands } camera ( /*@CAMERA_COMMANDS*/ ENABLE ); affect ( "z95", FLUSH ) { set ( "SET_CAMERA_GROUP", "ship" ); move ( $tag( "z95_start", ORIGIN)$, < 0 180 0 >, 0 ); wait ( 100 ); move ( $tag( "z95_hover", ORIGIN)$, < 0 180 0 >, 2000 ); wait ( 2000 ); move ( $tag( "z95_end", ORIGIN)$, < 0 0 0 >, 4500 ); } affect ( "z95_shadow", FLUSH ) { move ( $tag( "shadow_start", ORIGIN)$, < 0 180 0 >, 0 ); wait ( 100 ); move ( $tag( "shadow_end", ORIGIN)$, < 0 180 0 >, 2000 ); wait ( 2000 ); move ( $tag( "shadow_end", ORIGIN)$, < 0 0 0 >, 4500 ); } affect ( "fakeplayer", FLUSH ) { set ( /*@SET_TYPES*/ "SET_INVISIBLE", /*@BOOL_TYPES*/ "true" ); } camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "z95cam", ORIGIN)$, 0 ); camera ( /*@CAMERA_COMMANDS*/ FOLLOW, "ship", 0, 0 ); wait ( 6000 ); camera ( /*@CAMERA_COMMANDS*/ FADE, < 0 0 0 >, 0, < 0 0 0 >, 1, 1000 ); camera ( /*@CAMERA_COMMANDS*/ FOLLOW, "NULL", 0, 0 ); wait ( 1000 ); camera ( /*@CAMERA_COMMANDS*/ FADE, < 0 0 0 >, 1, < 0 0 0 >, 0, 1000 ); camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "startcam", ORIGIN)$, 0 ); camera ( /*@CAMERA_COMMANDS*/ PAN, $tag( "startcam", ANGLES)$, < 0.000 0.000 0.000 >, 0 ); affect ( "fakeplayer", FLUSH ) { set ( /*@SET_TYPES*/ "SET_INVISIBLE", /*@BOOL_TYPES*/ "false" ); set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_STAND9" ); set ( /*@SET_TYPES*/ "SET_ANIM_HOLDTIME_BOTH", 2000 ); wait ( 2000 ); set ( /*@SET_TYPES*/ "SET_WALKING", /*@BOOL_TYPES*/ "true" ); set ( /*@SET_TYPES*/ "SET_NAVGOAL", "walkspawn" ); } wait ( 5000 ); remove ( "fakeplayer" ); camera ( /*@CAMERA_COMMANDS*/ DISABLE ); It's a bit more complicated now (or at least longer), so to split it up a little: affect ( "z95", FLUSH ) { set ( "SET_CAMERA_GROUP", "ship" ); move ( $tag( "z95_start", ORIGIN)$, < 0 180 0 >, 0 ); wait ( 100 ); move ( $tag( "z95_hover", ORIGIN)$, < 0 180 0 >, 2000 ); wait ( 2000 ); move ( $tag( "z95_end", ORIGIN)$, < 0 0 0 >, 4500 ); } affect ( "z95_shadow", FLUSH ) { move ( $tag( "shadow_start", ORIGIN)$, < 0 180 0 >, 0 ); wait ( 100 ); move ( $tag( "shadow_end", ORIGIN)$, < 0 180 0 >, 2000 ); wait ( 2000 ); move ( $tag( "shadow_end", ORIGIN)$, < 0 0 0 >, 4500 ); } First, z95 has its SET_CAMERA_GROUP set to ship. Camera groups are collections of entities that the camera can follow as they move around. The move command specifies the final origin, the final angles and the time taken to move the entity. The z95 and z95_shadow are moved to their correct start positions immediately, z95_start and shadow_start respectively, and rotated 180 degrees from their rotation in the map file. After 100ms, they start moving to their next position over a period of 2000ms - the 100ms delay is just so that they actually do get moved to the start position, and wouldn't be necessary if you'd placed the ship sensibly in the first place. Finally, z95 rotates back to its rotation in the map file and lowers to z95_end, and z95_shadow rotates back to its rotation in the map file. I didn't use the rotate command here for z95_shadow as I found that if I did it rotated the other way to z95! affect ( "fakeplayer", FLUSH ) { set ( /*@SET_TYPES*/ "SET_INVISIBLE", /*@BOOL_TYPES*/ "true" ); } I didn't want fakeplayer to show up until after the Z-95 had landed, so I made fakeplayer invisible. Remember that because of how affects work, this command is executed at the same time as z95 and z95_shadow moving to their start positions. camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "z95cam", ORIGIN)$, 0 ); camera ( /*@CAMERA_COMMANDS*/ FOLLOW, "ship", 0, 0 ); wait ( 6000 ); This command moves the camera origin to the ref_tag I'd placed with targetname z95cam, and the FOLLOW camera command makes the camera follow any entities in camera group ship. That means that it follows z95 as it moves. There's no need for a PAN command if you're using the FOLLOW command. The wait command gives the Z-95 and its shadow time to move. camera ( /*@CAMERA_COMMANDS*/ FADE, < 0 0 0 >, 0, < 0 0 0 >, 1, 1000 ); camera ( /*@CAMERA_COMMANDS*/ FOLLOW, "NULL", 0, 0 ); wait ( 1000 ); camera ( /*@CAMERA_COMMANDS*/ FADE, < 0 0 0 >, 1, < 0 0 0 >, 0, 1000 ); camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "startcam", ORIGIN)$, 0 ); camera ( /*@CAMERA_COMMANDS*/ PAN, $tag( "startcam", ANGLES)$, < 0.000 0.000 0.000 >, 0 ); The first FADE camera command fades the screen to black: it changes the overlay colour from an initial RGB colour < 0 0 0 > (black) and alpha 0 (invisible!) to a final colour < 0 0 0 > (black) and alpha 1 (fully visible) over 1000ms. The RGB values are between 0 and 1. The new FOLLOW command stops the camera from following the entities camera group ship. After the first fade is complete, the camera fades back in from black at the camera location given by the ref_tag with targetname startcam. affect ( "fakeplayer", FLUSH ) { set ( /*@SET_TYPES*/ "SET_INVISIBLE", /*@BOOL_TYPES*/ "false" ); set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_STAND9" ); set ( /*@SET_TYPES*/ "SET_ANIM_HOLDTIME_BOTH", 2000 ); wait ( 2000 ); set ( /*@SET_TYPES*/ "SET_WALKING", /*@BOOL_TYPES*/ "true" ); set ( /*@SET_TYPES*/ "SET_NAVGOAL", "walkspawn" ); } wait ( 5000 ); remove ( "fakeplayer" ); camera ( /*@CAMERA_COMMANDS*/ DISABLE ); The only change from last time is that fakeplayer has to be made visible again. I compiled the script, and tested the map out again. I thought that the room for the second level needed to be made a bit more visually interesting, so I added a lava pit round the edge. To stop the cultist from jumping in the lava too much, I placed a brush textured with textures/system/do_not_enter across the surface of the lava, and also put some as barriers around the edge of the pit. I did a fresh compile of the map, and moved onto scripting. I wanted the cultist to actually say something as it was taunting the player, and to zoom the camera in on the cultist a little. Here's what I wrote in intro2.icarus: affect ( "player", /*@AFFECT_TYPE*/ FLUSH ) { set ( /*@SET_TYPES*/ "SET_WEAPON", /*@[member='weaponx']_NAMES*/ "WP_SABER" ); } camera ( /*@CAMERA_COMMANDS*/ ENABLE ); camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "bosscam", ORIGIN)$, 0 ); camera ( /*@CAMERA_COMMANDS*/ PAN, $tag( "bosscam", ANGLES)$, < 0.000 0.000 0.000 >, 0 ); affect ( "bosscultist", FLUSH ) { set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_STAND9" ); wait ( 3000 ); set ( "SET_SABERACTIVE", "true" ); wait ( 500 ); sound ( /*@CHANNELS*/ CHAN_VOICE, "sound/chars/cultist1/misc/victory3.mp3" ); wait ( 1000 ); set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_SHOWOFF_STRONG" ); } affect ( "fakeplayer", FLUSH ) { set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_STAND9" ); set ( /*@SET_TYPES*/ "SET_ANIM_HOLDTIME_BOTH", -1 ); } wait ( 1000 ); camera ( /*@CAMERA_COMMANDS*/ ZOOM, 40, 2000 ); wait ( 5500 ); camera ( /*@CAMERA_COMMANDS*/ ZOOM, 80, 1000 ); camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "playercam", ORIGIN)$, 3000 ); camera ( /*@CAMERA_COMMANDS*/ PAN, $tag( "playercam", ANGLES)$, < 0.000 0.000 0.000 >, 3000 ); wait ( 3000 ); remove ( "fakeplayer" ); camera ( /*@CAMERA_COMMANDS*/ DISABLE ); affect ( "bosscultist", FLUSH ) { wait ( 200 ); set ( /*@SET_TYPES*/ "SET_BEHAVIOR_STATE", /*@BSTATE_STRINGS*/ "BS_DEFAULT" ); // set ( /*@SET_TYPES*/ "SET_LOOK_FOR_ENEMIES", "true" ); // not really necessary due to SET_ENEMY set ( /*@SET_TYPES*/ "SET_ENEMY", "player" ); } affect ( "player", FLUSH ) { set ( "SET_SABERACTIVE", "true" ); } It's largely the same as before - I made sure that the player started with the lightsaber so that when the saber was activated at the end of the script, everything would work properly even if the player had entered the map with a different weapon active. To highlight the mst important changes: affect ( "bosscultist", FLUSH ) { set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_STAND9" ); wait ( 3000 ); set ( "SET_SABERACTIVE", "true" ); wait ( 500 ); sound ( /*@CHANNELS*/ CHAN_VOICE, "sound/chars/cultist1/misc/victory3.mp3" ); wait ( 1000 ); set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_SHOWOFF_STRONG" ); } The sound command with channel set to CHAN_VOICE means that bosscultist says sound/chars/cultist1/misc/victory3.mp3. camera ( /*@CAMERA_COMMANDS*/ ZOOM, 40, 2000 ); wait ( 5500 ); camera ( /*@CAMERA_COMMANDS*/ ZOOM, 80, 1000 ); The ZOOM camera command changes the fov / zoom of the camera. The first command changes the fov to 40 over 2000ms. The second ZOOM command changes the fov back to 80 (which is the default) over 1000ms. I compiled the script, and tested the map again in-game, but even though I had subtitles turned on for cinematics there weren't any! To solve this, I created an empty text file called map2.str in the English folder in the strings folder in base (you may need to create some of these folders). For other languages you'll need to create map2.str in the corresponding language folder in strings. I edited map2.str so that it looked like: VERSION "1" REFERENCE VICTORY3 LANG_ENGLISH "The galaxy will be ours." ENDMARKER When a sound is played in a script, the game looks for the REFERENCE in mapname.str (so map2.str) corresponding to the filename of the sound without a path or extension - so for sound/chars/cultist1/misc/victory3.mp3 that means victory3. It's not case sensitive, so don't worry about the capitalisation. This is why it is sensible to give more unique names to any sound files that are going to be subtitled. I tested the map again, and the subtitles worked. NEXT TIME: requests welcome, will probably take a bit longer to do and also be shorter
  3. I'm planning on doing rof stuff in a bit, will let you know when I do. I might end up just using the Blender plugin by @@mrwonko as it means I don't have to reboot into Windows, though iirc your exporter also supports the effect and sound features of rof files?
  4. Yeah, datapad objectives either need code changes or overwriting base things, so I might not cover them immediately. I'll probably do them at the same time as setting the player model properly, the intro scrolling text and proper load screen briefings as they all really require the use of a mod folder. lassev's tutorial works fine for the player model stuff already: http://www.student.oulu.fi/~lvaarisk/tutorials/forcedplamodelv2.htm
  5. pt3, might be written up by tomorrow https://www.youtube.com/watch?v=qZ1G_OIGu9Y
  6. @ You'll have to add some "worldmodel" lines into the ultimate weapons weapons.dat - look at the weapons.dat included in the SP mod download for reference. It was mainly for the Katarn saberstyle. Playing through the SP campaign with saberthrow as a forcepower makes the game a bit harder too I'll fix the eweb thing for the next release, and think about what to do with saberthrow.
  7. something like this might work: set ( /*@SET_TYPES*/ "SET_ENEMY", "NULL" ); set ( /*@SET_TYPES*/ "SET_BEHAVIOR_STATE", /*@BSTATE_STRINGS*/ "BS_DEFAULT" ); set ( /*@SET_TYPES*/ "SET_LOOK_FOR_ENEMIES", "true" );
  8. I think it's just a question of changing the weapons allowed by the player, so it shouldn't be too much work to get them usable - it might be nice to have a better first person model for the noghri staff and the tusken rifle though.
  9. Although they're meant for JK2, Kengo's cutscene tutorials still apply http://web.archive.org/web/20091022065706/http://geocities.com/kengomaps/tutorials.html. In addition to the stuff in the JKHub tutorials section, lassev's site has some interesting stuff http://www.student.oulu.fi/~lvaarisk/sivut/resources.htm. I also looked at the scripting stuff from http://map-forge.net/wiki/doku.php?id=tutorials:index whilst doing this. You can get BehavED and raven's JA example scripts from http://jkhub.org/files/file/1137-jedi-academy-sdk/ or if you're on a mac you can get IBIze and raven's JA example scripts from http://jkhub.org/files/file/1047-ibize-mac/ If you're using BehavED you *might* want to look at another scripting tutorial for a guide on how to use it. I feel like I might be going a bit too quickly over stuff - any feedback is welcome. PART 2: SILENT FILM I decided to add a couple of short cutscenes rather than just spawning the player straight into the maps. First, though, the player must have got to korriban somehow, so I added a Z-95 and a small landing pad. I could have made the Z-95 a misc_model (to get proper shadows) or a misc_model_static, but instead I decided to make it a func_static so that it would be easier to make it move in the future. The func_static consists of an origin brush (a small cube textured with textures/system/origin) and some clip brushes (textured with textures/system/physics_clip) to make the model solid. I found temporarily making a misc_model of the Z-95 was very helpful for working out where the origin brush should go and how to make the clip brushes. After the brushes were turned into a (single) func_static, I set the model2 key to the Z-95 md3 model, and the modelangles key to 0 180 0 - this is same rotation as setting the angle key to 180 for a misc_model. (sidenote: As func_statics don't cast shadows, I basically followed the http://jkhub.org/tutorials/article/179-high-resolution-shadow-trick/ to give the ship a shadow using a shadow rendered to a plane in blender. This wasn't really necessary though, but I can explain it if anyone wants I suppose.) I decided to have the first cutscene just being the camera looking at the door for a few seconds. This meant writing a new ICARUS script, but a couple of things needed to be set up in the map first. I created a ref_tag at the end of the map with the landing pad, and targeted it towards an info_null in the direction of the door. The location of the ref_tag would be used as the location of the camera, and the angles of the camera in the cutscene would be given by the direction of the line connecting the ref_tag and info_null. I set the targetname of the ref_tag to startcam. In order to run the script that would play the cutscene, I added a target_scriptrunner, and set the usescript to map1/intro. I then targeted the info_player_start at the target_scriptrunner so that the script at scripts/map1/intro.ibi would be run as soon as the map started. With everything in the map done for now, I compiled it and put the bsp into my maps folder. I now needed to make that script! As I use a Mac I don't use BehavED and just write the scripts in a text editor, but you should probably write things in BehavED most of the time. If you do choose to write them in a text editor, you can still open them up in BehavED and compile them though. If you're on a Mac, you'll need to use IBIze in Terminal. I created an empty text file called intro.icarus (intro.txt may be more sensible) and placed it in a folder called map1 inside the scripts folder in my base (you might need to create scripts). I typed this stuff in: camera ( /*@CAMERA_COMMANDS*/ ENABLE ); camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "startcam", ORIGIN)$, 0 ); camera ( /*@CAMERA_COMMANDS*/ PAN, $tag( "startcam", ANGLES)$, < 0.000 0.000 0.000 >, 0 ); wait ( 5000 ); camera ( /*@CAMERA_COMMANDS*/ DISABLE ); saved, and then compiled the script. The ENABLE and DISABLE commands are pretty self-explanatory - they turn camera mode on and off. The MOVE command here moves the camera to the location given by the ref_tag with targetname set to startcam immediately (the 0 at the end means that it takes 0 ms). The PAN command immediately rotates the camera so that it has the same angles as the ref_tag with targetname set to startcam. The wait command means that camera mode stays on for 5000ms, i.e. 5 seconds. I started up the game with map map1 to check that it worked. It did, but there's the slight problem that the player isn't drawn in cutscenes. Fortunately, there is an entity spawned by NPC_Player that has the same model and weapon as the player that you can use in cutscenes, so I opened the map up again. I placed an NPC_Player entity a bit behind the info_player_start and set its droptofloor, cinematic and notsolid spawnflags. I then set its npc_targetname to fakeplayer so that the spawned NPC would have its targetname and script_targetname set to fakeplayer, and set its angle to match the player's. I thought it would be interesting for the "player" to walk forwards a bit during the cutscene, so I created a waypoint_navgoal near the info_player_start for the NPC to walk to, and set its targetname to walkspawn. That was all the mapping needed, so I opened up intro.icarus again after doing a fresh compile of the map, and made a few changes: camera ( /*@CAMERA_COMMANDS*/ ENABLE ); camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "startcam", ORIGIN)$, 0 ); camera ( /*@CAMERA_COMMANDS*/ PAN, $tag( "startcam", ANGLES)$, < 0.000 0.000 0.000 >, 0 ); affect ( "fakeplayer", FLUSH ) { set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_STAND9" ); set ( /*@SET_TYPES*/ "SET_ANIM_HOLDTIME_BOTH", 2000 ); wait ( 2000 ); set ( /*@SET_TYPES*/ "SET_WALKING", /*@BOOL_TYPES*/ "true" ); set ( /*@SET_TYPES*/ "SET_NAVGOAL", "walkspawn" ); } wait ( 5000 ); remove ( "fakeplayer" ); camera ( /*@CAMERA_COMMANDS*/ DISABLE ); The new lines mean that the entity with targetname set to fakeplayer (the "player" NPC) has its animation set to BOTH_STAND9 for 2000ms (2 seconds). After these 2 seconds are up, the "player" NPC then walks towards the waypoint_navgoal with targetname set to walkspawn. Just before the camera is turned off, fakeplayer is removed so that the player doesn't have to worry about a doppelganger. (note: although there are two different wait commands, one waiting 2 seconds and the other 5 seconds, only 5 seconds pass before the camera is turned off - this is because the commands in the fakeplayer affect block are being run on fakeplayer in parallel to the other commands (which are actually being run on the target_scriptrunner) and do not interrupt them.) I compiled the script again, and tested the changes in-game. It was now time to add an intro cutscene to the next map. That meant a couple of changes in Radiant. I added an NPC_Player, placing it next to the info_player_start, and set its spawnflags and npc_targetname just as before. I added the spawnflag cinematic to the NPC_Cultist_Saber, and also gave it the npc_targetname bosscultist so that I could control it from a script. I created two ref_tag entities and targeted them at corresponding info_null entities - one from above where the info_player_spawn was facing towards the boss, and the other above where the boss was facing towards the info_player_spawn. I set their targetname keys to bosscam and playercam respectively. Finally, in order to run the script that would play the cutscene, I added another target_scriptrunner, with usescript set to map2/intro2. I then targeted the info_player_start at the target_scriptrunner so that the script at scripts/map2/intro2.ibi would be run as soon as the map started. I did a fresh compile of the map and went back to scripting. Here's what I wrote: camera ( /*@CAMERA_COMMANDS*/ ENABLE ); // OLD camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "bosscam", ORIGIN)$, 0 ); // OLD camera ( /*@CAMERA_COMMANDS*/ PAN, $tag( "bosscam", ANGLES)$, < 0.000 0.000 0.000 >, 0 ); // OLD affect ( "bosscultist", FLUSH ) { set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_STAND9" ); wait ( 1000 ); set ( "SET_SABERACTIVE", "true" ); wait ( 1500 ); set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_SHOWOFF_STRONG" ); } affect ( "fakeplayer", FLUSH ) { set ( /*@SET_TYPES*/ "SET_ANIM_BOTH", /*@ANIM_NAMES*/ "BOTH_STAND9" ); // OLD set ( /*@SET_TYPES*/ "SET_ANIM_HOLDTIME_BOTH", -1 ); } wait ( 3500 ); camera ( /*@CAMERA_COMMANDS*/ MOVE, $tag( "playercam", ORIGIN)$, 3000 ); camera ( /*@CAMERA_COMMANDS*/ PAN, $tag( "playercam", ANGLES)$, < 0.000 0.000 0.000 >, 3000 ); wait ( 3000 ); remove ( "fakeplayer" ); // OLD camera ( /*@CAMERA_COMMANDS*/ DISABLE ); // OLD affect ( "bosscultist", FLUSH ) { wait ( 200 ); set ( /*@SET_TYPES*/ "SET_BEHAVIOR_STATE", /*@BSTATE_STRINGS*/ "BS_DEFAULT" ); // set ( /*@SET_TYPES*/ "SET_LOOK_FOR_ENEMIES", "true" ); // not really necessary due to SET_ENEMY set ( /*@SET_TYPES*/ "SET_ENEMY", "player" ); } affect ( "player", FLUSH ) { set ( "SET_SABERACTIVE", "true" ); } What happens here is that the camera immediately moves to the position and angles of the ref_tag with targetname bosscam. fakeplayer has its animation set to BOTH_STAND9 for -1ms (that actually means forever, or at least until told otherwise). bosscultist is told to set its animation to BOTH_STAND9 for 1000ms, then turn on its lightsaber and after 1500ms do the taunt animation BOTH_SHOWOFF_STRONG. The script does nothing for 3500ms after issuing these commands. Note that the commands for bosscultist again run in parallel, so the time from start of script until end of wait is 3500ms and not 6000ms. After this wait, the camera is moved to the position and angles of the ref_tag with targetname playercam. As the last number is 3000 rather than 0, this does not happen immediately, but the camera instead moves and rotates to its new position in 3000ms. The next wait command pauses the script until the camera move is finished. Once the camera has been disabled and fakeplayer removed, the remaining commands turn on the players lightsaber, and make the cultist target the player. It is necessary to set the cultist's behaviour to BS_DEFAULT for it to fight because the cinematic spawnflag was set. I finally compiled the script, and went back in game to check it all worked. NEXT TIME: What would be useful?
  10. Here's the result of part 2, just need to finish writing it up now
  11. It's a really nice idea, but might be quite a bit of work If @@Oobah doesn't want to be involved at all I'd rather we just did things from scratch tbh though.
  12. redsaurus

    OpenJK.app

    http://jkhub.org/tutorials/article/178-installing-openjk-on-os-x/ tried this?
  13. You could alternatively target the concealed switch at a target_deactivate which then uses the trigger_once.
  14. I think I'll definitely try to get the noghri stick and tusken rifle usable by the player, there shouldn't be too much work needed.
  15. As people might be more likely to make SP maps if there's a more comprehensive guide, I'm going to try and do some kind of step-by-step making a SP map thing, hopefully covering all the stuff that's already been covered in the very good tutorials people have written, and maybe some other things too. The plot's pretty irrelevant, and probably won't fit neatly into the SP campaign (but Jedi Knight: Enhanced would welcome any maps that do!). You'll start on somewhere korriban-ish (maybe korriban), and there will be two levels: an outside one in which you try to get inside, and then an inside one in which you finish the level by duelling some kind of cultist or reborn. I'll begin by doing a very simple pair of maps, and then gradually introduce more complex things to make them more interesting. This is probably not the best way to make a SP map, but might make things clearer. To follow this you should probably know how to make a box map properly and how to use the entity window. If you think that I am saying something wrong or bad, let me know and I'll improve that bit. Any feedback or requests would be very welcome. PART 1: TWO ROOMS ONE BOSS I opened up Radiant and checked that I was in SP mapping mode by going to File->Project Settings (I was!). I made a quick boxmap and put a sky texture on the walls and ceiling, and sand on the ground. I then added a door frame to lead to the next map, and saved the map as map1.map. As the sky I chose doesn't emit light, I added a couple of entity suns. An entity sun is just a spotlight (a light entity targeted at info_null entity) with the _sun key set to 1 and the _color key set (you can set the colour by hitting K with the entity selected). The second entity sun was meant to be for "shadows", so was a little bluer, not so bright, and in a different direction. The map always needs a spawn point, so I added an info_player_start and set its angle so that it was facing towards the door. To finish the outside map, I needed to make the door frame actually start the next map, so I created a brush to fill the doorframe textured with textures/system/trigger and turned it into a trigger_once. I ticked the playeronly box in the entity window so that only the player reaching the door frame activates the trigger. I then created a target_level_change with the mapname key set to map2, and targeted the trigger_once at the target_level_change. Finally, I compiled the map by doing one of the Bsp->Q3Map2: (test) compile options (doesn't matter which), and put the produced map1.bsp into a maps folder inside my base folder. I then created a new map and made another quick boxmap, this time with some more stone-type textures, saving the map as map2.map. Although there weren't any sources for light, I placed some light entities and made them flicker a bit by setting the style key to 1. The map again needed a spawn point, so I added an info_player_start with the keep_prev spawn flag set so that any damage from the previous level is carried over. For the boss, I added an NPC_Cultist_Saber with the med spawnflag set so that it used medium style, and set its angle to face the player. The credits should run when the boss is killed, so I set its NPC_target to endscriptrunner - the NPC_target is used when the NPC dies. To run the credits, I created a target_scriptrunner with its ​targetname set to endscriptrunner, its delay set to 1 second (so that the cultist's death is still shown), and its usescript set to kor2/theClosingCredits (this means that the script scripts/kor2/theClosingCredits.ibi is run, which is the script used in the base campaign to show the credits). After compiling the map again and putting the map2.bsp in the maps folder, I opened up SP, typed map map1 into the console, and quickly played the maps: https://www.youtube.com/watch?v=0m0DQLXlLag NEXT TIME: haven't decided yet
  16. Don't worry, you're not imagining it, the SFX sabers do cast a bit more light than the normal sabers. In the code the light intensity is set a little higher than the base sabers' intensity.
  17. Do you mean no twirl when turning the saber on and off? Or anything else?
  18. Which build are you using exactly @@Circa? How exactly can I reproduce that? JA+ *should* work alright with OpenJK from #jacoders: Ensiform: cl_consoleKeys defines the console keys available with SDL backend
  19. Anything new with new levels? I was thinking that if I fix the vehicles up a bit more in SP siege_destroyer could be made into a level. @@Pande's dotf could form the basis for a nice naboo level too?
  20. I've hopefully fixed the crash now @@Aidor @@Angel Soul, so it's time for beta 4 release. Sorry I didn't get the fix released for a few days. Here's the new release for Mac/Windows (39.8MB). If you don't already have it (and you're on Windows) you'll need the MSVC++ 2010 redistributable (http://www.microsoft.com/en-gb/download/details.aspx?id=5555) Most features are exactly the same as in the last release (http://jkhub.org/topic/2480-sp-customisation-stuff/page-9?do=findComment&comment=74661) so I won't repeat them. Credits are there too! (as well as in the read me of course) New features: .eent files Maps now load entities from mapentities/mapname.eent in addition to loading them from the .bsp file.As the mod uses the latest OpenJK code, vehicles will be working very slightly better than in base SP.
  21. Since the hosting and domain name was changed I doubt there are still issues with NOD32.
  22. Could you check if it still crashes for you with an otherwise clean base?
  23. Saberthrow is +button9 now. Have you got an edited weapons.dat? If you do you'll need to add the worldmodel lines from the sp_custom.pk3 to your weapons.dat. Not sure about the crashing really, hope that fixes it.. @@therfiles I think that the NPC head swapping should partially work, but it might only turn off sub surfaces of one called "head", so may not work properly with some custom models. If it still leaves the head on base models like luke etc then I'll fix it fairly soon, otherwise a workaround for now is just to have a custom skin file with the head surfaces turned off. There will be improvements to the NPC part swapping eventually anyway.
×
×
  • Create New...