DarthParametric

Modders
  • Content Count

    4,568
  • Joined

  • Last visited

  • Days Won

    514

Everything posted by DarthParametric

  1. Haha, yeah, scripts can be super overwhelming, and this scene has a bunch of stuff going on. The basic breakdown of them though is: k_ptar_calobar Set Calo and thugs to opposing factions Play Calo underarming grenade animation Play tossing grenade sound k_ptar_gren Equip ranged weapons on the thugs Play sound of grenade bouncing k_ptar_gren2 Get the location of the waypoint for where the grenade lands Spawn a grenade model at that waypoint k_ptar_flash Play the grenade beeping sound Play the ion grenade explosion VFX Have Calo equip a heavy blaster Play the sound of a thug being hit (I assume this is a generic grunt/yell, meant to be because of the flash) k_ptar_kill Get the locations where the thugs are standing Despawn the thugs Have Calo equip a heavy blaster (again) Play blaster fire sounds Play thugs getting hit sounds Spawn corpses where the thugs used to be k_ptar_caloex ??? Calo walks towards the bar exit Edit: And here are the pertinent elements of the DLG nodes related to each script (tar03_calo031.dlg ) k_ptar_calobar Comment: Clothing rustles as he throws the flash grenade CameraID 3 CameraAngle 6 k_ptar_gren CameraID 4 CameraAngle 6 k_ptar_gren2 Comment: Clink sound of the grenade landing CameraID 5 CameraAngle 6 k_ptar_flash Comment: BEEP, the a flash sounding explosion CameraID 6 CameraAngle 6 k_ptar_kill Comment: 3 blaster shots ring out. CameraID 7 CameraAngle 6 Edit 2: Btw @ebmar, I was thinking that since you are primarily focussing on textures for the moment, do you want a non-mirrored head and/or body for this?
  2. Ah, yeah, forgot about that one. Looking at the dialogue for that scene, there are a few scripts it uses in succession. The first is after he finishes counting to 3, k_ptar_calobar: void main() { object object1 = OBJECT_SELF; object oTaproomvic031 = GetObjectByTag("taproomvic031", 0); object oTaproomvic032 = GetObjectByTag("taproomvic032", 0); object oTaproomvic033 = GetObjectByTag("taproomvic033", 0); object oCalo031 = GetObjectByTag("calo031", 0); sub1(oCalo031, 1); AssignCommand(oCalo031, sub2(intGLOB_130, 1)); ActionPauseConversation(); ChangeToStandardFaction(oCalo031, 2); ChangeToStandardFaction(oTaproomvic031, 4); ChangeToStandardFaction(oTaproomvic032, 4); ChangeToStandardFaction(oTaproomvic033, 4); AssignCommand(oCalo031, PlayAnimation(118, 1.0, 0.0)); // DP note: This is ANIMATION_FIREFORGET_THROW_LOW DelayCommand(0.6, PlaySound("cs_grentoss")); DelayCommand(1.2, ActionResumeConversation()); } Then k_ptar_gren: void main() { string string1 = "flash_gren"; location location1 = GetLocation(GetObjectByTag("GRENADE_WP", 0)); object oTaproomvic031 = GetObjectByTag("taproomvic031", 0); object oTaproomvic032 = GetObjectByTag("taproomvic032", 0); object oTaproomvic033 = GetObjectByTag("taproomvic033", 0); AssignCommand(oTaproomvic031, ActionEquipMostDamagingRanged(OBJECT_INVALID)); DelayCommand(0.2, AssignCommand(oTaproomvic032, ActionEquipMostDamagingRanged(OBJECT_INVALID))); DelayCommand(0.5, AssignCommand(oTaproomvic033, ActionEquipMostDamagingRanged(OBJECT_INVALID))); ActionPauseConversation(); DelayCommand(0.8, ActionResumeConversation()); DelayCommand(0.90000004, PlaySound("cb_gr_boncehard1")); } Then k_ptar_gren2: void main() { string string1 = "flash_gren"; location location1 = GetLocation(GetObjectByTag("GRENADE_WP", 0)); ActionPauseConversation(); CreateItemOnFloor(string1, location1, 0); DelayCommand(0.8, ActionResumeConversation()); } Then k_ptar_flash: void main() { object oTaproomvic031 = GetObjectByTag("taproomvic031", 0); object oTaproomvic032 = GetObjectByTag("taproomvic032", 0); object oTaproomvic033 = GetObjectByTag("taproomvic033", 0); object oFlash_gren = GetObjectByTag("flash_gren", 0); location location1 = GetLocation(GetObjectByTag("GRENADE_WP", 0)); object oCalo031 = GetObjectByTag("calo031", 0); object object12 = GetItemPossessedBy(oCalo031, "G_W_HVYBLSTR01"); ActionPauseConversation(); DelayCommand(0.5, PlaySound("cs_grenbeep")); DelayCommand(1.0, ApplyEffectAtLocation(0, EffectVisualEffect(3011, 0), location1, 0.0)); // DP note: this is VFX_FNF_GRENADE_ION DelayCommand(0.1, AssignCommand(oCalo031, ActionEquipItem(object12, 5, 0))); DelayCommand(1.2, DestroyObject(oFlash_gren, 0.0, 0, 0.0)); DelayCommand(1.2, ActionResumeConversation()); DelayCommand(1.2, AssignCommand(oTaproomvic032, PlaySound("n_swoopgang_hit1"))); } Then k_ptar_kill: void main() { object oInvis_sound1 = GetObjectByTag("invis_sound1", 0); object oInvis_sound2 = GetObjectByTag("invis_sound2", 0); object oInvis_sound3 = GetObjectByTag("invis_sound3", 0); object oCalo031 = GetObjectByTag("calo031", 0); object oTaproomvic031 = GetObjectByTag("taproomvic031", 0); object oTaproomvic032 = GetObjectByTag("taproomvic032", 0); object oTaproomvic033 = GetObjectByTag("taproomvic033", 0); location location1 = GetLocation(GetObjectByTag("tar03_wpvic0", 0)); location location3 = GetLocation(GetObjectByTag("tar03_wpvic1", 0)); location location5 = GetLocation(GetObjectByTag("tar03_wpvic2", 0)); object object18 = GetItemPossessedBy(oCalo031, "G_W_HVYBLSTR01"); sub1(10.0); DestroyObject(oTaproomvic031, 0.0, 1, 0.0); DestroyObject(oTaproomvic032, 0.0, 1, 0.0); DestroyObject(oTaproomvic033, 0.0, 1, 0.0); DelayCommand(1.0, AssignCommand(oCalo031, ActionEquipItem(object18, 5, 0))); DelayCommand(0.5, AssignCommand(oCalo031, PlaySound("cb_ht_blastleth1"))); DelayCommand(1.0, AssignCommand(oCalo031, PlaySound("cb_ht_blastleth2"))); DelayCommand(1.8, AssignCommand(oCalo031, PlaySound("cb_ht_blastleth1"))); DelayCommand(2.5, AssignCommand(oCalo031, PlaySound("cb_ht_blastleth2"))); DelayCommand(1.7, AssignCommand(oInvis_sound1, PlaySound("n_swoopgang_hit1"))); DelayCommand(2.9, AssignCommand(oInvis_sound2, PlaySound("n_rodian_hit1"))); DelayCommand(3.3, AssignCommand(oInvis_sound3, PlaySound("n_swoopgang_hit1"))); DelayCommand(2.0, sub2(1, "bp_dead3", location1)); DelayCommand(2.5, sub2(1, "bp_dead1", location3)); DelayCommand(3.0, sub2(1, "bp_dead2", location5)); } Then k_ptar_caloex which I can't decompile, but I gather is him walking out of the bar.
  3. Does it translate to "Space Monkey Piss"?
  4. I remembered that there's that banter between Mission and Bastila where Mission gets forced prone. Checking the dialogue file, the script used is k_swg_bantforce: ///Bastila trips Mission with a Force power void main() { AssignCommand(GetObjectByTag("Mission"),PlayAnimation(ANIMATION_LOOPING_PRONE)); ActionPauseConversation(); ActionWait(2.0); ActionResumeConversation(); } So using some variant of that might work for your escape scene. Of course another issue is probably the VO. I imagine you'd need additional lines for Selven, which presumably means having to completely replace her existing dialogue, as I can't image you could match it with someone else.
  5. Ah, well I guess that is another bug for bead-v to fix in his spare time then. Although I thought there was also something added to KOTORMax to deal with it as well.
  6. Make sure you are using the 1.0.4 beta version from a few posts up. I'm not sure if it is in older versions.
  7. I'd say you have some model issues there. 40K polys seems a tad excessive. I'm not sure exactly what is going on, but decompiling the binary gives an ASCII of 6.6MB vs 2.5MB for the original. The poly/vert/edge counts seem to be the same, so maybe it is blowing out tex vert number or something. The new ASCII is 215K lines vs 75K for the original. Your keys are bezier, which may be the source of the animation problem. Try converting them to linear before exporting. I thought @bead-v had added some toggle or global switch for that after I complained about it. Edit: Ah, there's a toggle in MDLEdit. In the settings, convert bezier controllers to linear.
  8. Yeah you could do something like a stun/concussion grenade, although I don't think K1 has that head shaking stun animation that TSL does. I guess you could just knock everyone prone, although I'm unsure on the scriptability of that. K1 has a lot more limitations than TSL. Someone more knowledgeable than me would have to chime in.
  9. All the points covered what is required to produce what I supplied in the linked archive, a TSLPatcher setup that will install the appearance change in a compatible manner. You can continue to tweak things like the texture after the fact, since no setup changes are required for an updated texture beyond overwriting the original one in the tslpatchdata folder. If you want more advanced elements, like scripts and so forth, that's a whole other thing, as I mentioned in my first post. It would require additional setup steps, and may warrant switching to module injection (i.e. a MOD file) rather than just dumping everything in the Override.
  10. All the "ModelX" columns get replaced with PFBL - modela, modelb, modelc, modeld, modele, modelf, modelg, modelh, modeli, modelj All the "TexX" columns get replaced with PFBSelven - texa, texb, texc, texd, texe, texf, texg, texh, texi, texj The "TexAEvil" column is a special case for Dark Side underwear, you can star that out - **** - for non-player appearance rows.
  11. The key with DeNCS is using the correct game nwscript.nss. K1_tar_m03ad_holo_scripts.7z
  12. If you want to do a simple head swap/custom appearance, that's pretty straightforward. You're already most of the way there. You've got your custom model and custom texture. The rest is just extracting a few source files and a bit of TSLPatcher config. Here: https://www.darthparametric.com/files/kotor/k1/[K1]_Selven_Custom_Appearance_ebmar.7z Note that I have included the placeholder head texture I gave you previously, so make sure you overwrite that with your new version before installing. The steps involved to create such a setup: Extract source files using KOTORTool - heads.2da, appearance.2da, tar03_selven031.utc from tar_m03ab, PFBF04.tga (checking that it does not require a TXI, which this doesn't) Use Convert2DA to convert both the 2DAs to tab delimited text files so they can be easily edited in Excel, etc. Create a custom heads.2da with an added row for the Selven head model. This is extremely simple in this case. Just copy one of the existing NPC rows and paste it at the end, then change the row ID and head cells to "107" and "pfhebmar". Save as a tab-delimited text file. Create a custom appearance.2da with an added row for the Selven body. For this you can just copy an existing female player row and paste it at the end. I choose one of the "large" ones. Using that as your starting point, edit the values as appropriate. Give it a new row ID (509), new custom label (Ebmar_Taris_Selven), then change all the model and texture values to PFBFL and PFBSelven. Everything else can remain unchanged. Save as a tab-delimited text file. Note that we are specifying a custom body texture here in order to override whatever armour variation she may actually have equipped in the UTC, to side-step any custom textures the end-user may be using, and to allow for your own custom texture edit, if required. Use Convert2DA to convert your two text files to 2DAs. Create a mod folder with the appropriate structure. I like a "working" folder where I keep all the source files, and a "release" folder where I put the TSLPatcher setup. Create a release folder with a "tslpatchdata" sub-folder. Copy across the vanilla heads.2da and appearance.2da, head model MDL/MDX, head texture, body texture (rename PFBF04.tga to PFBSelven01.tga), and UTC. Create an "info.rtf" file. This has the text that the installer will show, so add info and instructions as appropriate. Get the TSLPatcher files. Copy across TSLPatcher.exe one level above the tslpatchdata folder. Run ChangeEdit.exe and go to File -> New. Choose the tslpatchdata folder you created and save changes.ini Now you can create your config. Under Settings, set the Window Caption to the mod's name (I used [K1] Selven Custom Appearance) and hit the Save Changes button down the bottom. You'll always need to come back here to save any additional changes you make. In the top Modifiers menu, choose Add 2DA File. In the popup, write heads.2da in the filename field and hit ok. Repeat and add appearance.2da. N.B. It is important that you add heads.2da first, due to the required order of operations. Now under 2DA Files you should see both heads.2da and appearance.2da listed. Select heads.2da Select the middle of the three buttons on the top right to compare two 2DA files. Choose the vanilla heads.2da when it asks for the original, and your custom heads.2da when it asks for the modified one. It will compare the two files and determine what you added. In this case, you should see AddRow0. Double click on that to open the editor. You will see there is a description explaining what you need to do next. Namely, in the Set Column Value section, for Column write 2DAMEMORY1 and for Value write RowIndex. Then hit the red arrow pointing right to add it. You can then close that editor. What you have done is added a "memory token". In this case, you are telling TSLPatcher to remember the index (i.e. ID number) of the new row it is adding to heads.2da which we'll need in the next step. Open the editor for appearance.2da. As before, add a new 2DAMEMORY token for RowIndex, except this time you'll want to increment the number (i.e. 2DAMEMORY2). Now TSLPatcher is storing two values, the row indexes for both 2DAs. On the right, double click on "normalhead" to make it editable. Change the Value to 2DAMEMORY1, then click the right facing red arrow to make the change. Close that editor. This is using the stored heads.2da row index memory token to set the proper head value in appearance.2da. This sort of thing is the primary strength of TSLPatcher, as it can dynamically account for people's custom pre-existing 2DAs that may have any number of additional rows. In the top Modifiers menu, choose Add GFF File and put tar03_selven031.utc in the filename field. Under the GFF Files section you will see your UTC, select it. Down the bottom tick the Replace File If It Already Exists, leave the destination as Override, and click the Set button. In the Modify Field Value section, click the little folder icon to the right to load the UTC. You'll see the GFF Field box turns green. From the drop down menu select Appearance_Type. Change the Value field to 2DAMEMORY2 and then click the upwards pointing red arrow to set the change. This will edit the UTC to add the row index of your custom appearance.2da row. Now go to the Install Files section. Click on the Add Multiple Files button next to the red arrows. For the folder name use Override and tick the Replace Existing checkbox. Select your model and TGAs. N.B. Very important! DO NOT add the 2DAs or UTC. This is a common rookie mistake. It will be automatically handled by TSLPatcher. Now go back to Settings and click Save Changes. You should be done and can close ChangeEdit. Run your TSLPatcher to test your install setup and make sure everything works in-game. Edit: Before and after pics (obviously without the custom head texture) If you want to go to full on quest editing/creation, that's going to add a reasonable degree of extra difficulty. You'll need to edit/create scripts and dialogue, possibly you'll want additional NPCs, etc. You are almost certainly talking about edits across two or more modules.
  13. Yeah, shows new mods being posted. Shows pretty much everything as far as I can tell. Also auto-updates, so you can just leave it open in a tab if you are that keen.
  14. Cheers. And yeah, swapping them like you say is probably the best course of action. I'll see what the sound like in the game.
  15. It occurs to me that since I suck so much at textures, I'd be far better off worrying about fixing the models and just giving you the base textures to play with. Although in the case of your biker Revan, the tattoos probably obfuscate the skin tone change anyway for the most part.
  16. The activity page has an option for a condensed version. Perhaps that could also be applied to the sidebar?
  17. I was thinking maybe something like dogtags could be an option if necessary, although that's probably still insufficient.
  18. Not a possibility, a fact: The only issue I'm having is trying to colour match to the heads. It's a freaking nightmare as they are all different. It's no wonder that Bioware and Obsidian went with jumpsuits. I might have to do a unique texture per head.
  19. No need, I am working on a non-mirrored UVs underwear model using the Canderous body. Will release it shortly.
  20. You need to enable the bumpmappable/tangentspace flag when compiling the model, then specify the normal/bump map in TXI of the diffuse map. Creating the map itself is done in the standard manner for any game engine, but as @ndix UR pointed out above, normal maps need to be converted to a RGBA TPC in order to work. TGAs will cause the game to hang/crash. There will be more detailed, step-by-step information available once @Tyvokka implements the wiki.
  21. The fake WAVs aren't mono though. It would be interesting to see - for experimental purposes if nothing else - whether simply adding the fake WAV header to a stereo MP3 is sufficient, or whether there is indeed some other processing they did via Miles K1 is mostly all the same, although they do have some that go the other way - WAVs with fake MP3 headers (e.g. al_xxxx). TSL though has a few different variations (based on Obsidian using at least two different encoders, from what I can glean).
  22. The originals are just MP3 with a fake 199 58 byte WAV header. I wonder what would happen if you added that to your files? Do you have a sample MP3 that we can try it with? Or presumably you can just hex edit one/some yourself. Edit: Doing some tests, it's pretty easy to set up batch processing, assuming it works. You can just export the first 199 58 bytes from the header of an existing WAV from a hex editor and then create a batch file: @echo off for %%F in (*.mp3) do copy /b "header.bin" + "%%~nF.mp3" "%%~nF.wav" pause Edit 2: Actually, comparing to other MP3s, it looks like the fake header is only 58 bytes. I was going too far into actual relevant MP3 header data. Trimming 199 would allow it to play in Wnamp, etc. but I don't know how the game would react.
  23. Looks like the primary ground texture is LTA_wall00 with darker edge/corner areas using LTA_wall00a . As the name suggests, these textures are likely used elsewhere for wall textures, so replacing them outright is probably not the best idea. The easiest way to check what textures are being used and how retextures will look is to extract the room models and load the entire module into Max/GMax (I'm not sure if Blender's script has a module loading capability as yet).
  24. Can you get it here? https://deadlystream.com/store/category/5-modders-account/
  25. Yeah I think it is far more logical dealing with the ASCII: newanim default w_LaserFire_R length 0.0 transtime 0.0 animroot w_LaserFire_R node dummy w_LaserFire_R parent NULL endnode node dummy AuroraLight01 parent w_LaserFire_R colorkey 0.0 0.0 0.0 0.0 endlist endnode node dummy zap parent w_LaserFire_R birthratekey 0.0 0.0 endlist endnode doneanim default w_LaserFire_R newanim travel01 w_LaserFire_R length 3.93333 transtime 0.0 animroot w_LaserFire_R event 0 detonate node dummy w_LaserFire_R parent NULL endnode node dummy AuroraLight01 parent w_LaserFire_R colorkey 0.0 1.0 0.0 0.0 0.0333333 1.0 0.0 0.0 0.166667 1.0 0.0 0.0 0.333333 0.0 0.0 0.0 0.466667 0.0 0.0 0.0 0.5 0.0 0.0 0.0 endlist endnode node dummy zap parent w_LaserFire_R birthratekey 0.0 2.0 endlist endnode doneanim travel01 w_LaserFire_R Although this particular one is pretty simple given that the light is a straight red and either on or off. If you wanted different colours though, like say orange or purple, you'd have to convert the RGB to [0,1]. For example an orange of 255,120,0 would be 1.0 0.47 0.0 or thereabouts.