JCarter426

M478_Staff
  • Content Count

    1,496
  • Joined

  • Last visited

  • Days Won

    123

Everything posted by JCarter426

  1. Actually, there are belt models in the game - i_belt_001 through 014. As has been discussed before, though, you need a hook on the body models for anything to appear (and I don't believe they have belt hooks) and you also need a way of telling the game to render the belt model on the belt hook when it's equipped... which nobody has figured out how to do in KOTOR, to my knowledge. Some of it seems to be in the 2DAs but I could never get anything new to show up when I messed around with it. The key data could very well be hard coded.
  2. Here's my folder and its contents so far. Now it's time to convert this file with MDLOps. Load your edited ASCII file, then read and write. MDLOps will generate a new MDL and MDX. Run the Head Fixer on the MDL. The Head Fixer creates a new, fixed MDL file to put the animations back. Rename the fixed MDL and the MDX file from the previous step to whatever you want. However, the file name must have the same number of characters as the original (in this case 8). You could get around this by renaming before you export, but it requires more setup work, so I resign to keeping it the same. Once you've chosen your name, open the MDL in a hex editor. Find and replace the original name (mine was P_AttonH) with your new name (mine is JC_DuH01). Be careful to only replace characters, not delete them; that would break the model and cause your game to crash, most likely. There are 5 Duros textures in the game, so at this stage I use the same process to create duplicate models for each texture variation. After some 2DA editing to get the head in the game, or in my case simply keeping it as P_AttonH for a quick test, we can see our final result: Behold, a new head that can go on any body. You can use roughly the same process to create new full body models if you like, mixing heads and bodies from different models. That's what I did for the Handmaiden Sisters and I've made a tutorial here. So, go make new heads, and good luck!
  3. Open your original head project (Atton Template for me). Select and rename everything with Tools -> Rename Objects. Add a prefix, something that makes it obvious which head these objects belong to. Now merge it with everything from your head project (I called mine Duros Head 1). With that imported, you should see one head at the origin and one above it. Select everything on the top half and move it down. Make it overlap the other head as much as it can. Now that everything is in position, you can link the MaskHook and GoggleHook helpers to head_g with the Select and Link tool. For this next part, hide everything except the two head geometries to make it easier to see them. Then you need to turn on the Snap Toggle so you can snap to vertices. Select your new head geometry and go edit the editable mesh. Move each vertex along the bottom circumference of the neck into the corresponding positions on the template head. These two heads have the same number of vertices so it's pretty easy. If you're not so lucky, you might need a bit more modeling skill to get them in place. You may also have to adjust the vertex weighting, which is not very fun. I didn't have to for the Duros, or the majority of the heads I've done so far, so I'm not going to cover that here. I also decide to scale down the second layer of vertices to match Atton's neck more closely, so there isn't a bulge. Once you're satisfied with your vertices, unhide everything and then delete all the objects in the template head. You won't need them anymore. The Duros model was lacking a texture, so I applied one here using the material editor. I notice his head includes a turtleneck, so later I might remap the model to remove it. Or maybe Duros just get cold easily. Now, this part is important. I only learned this through experimentation, because frankly it's not a very intuitive part of the design. Animations are applied to the head and body separately, meaning you can end up with each part playing entirely different animations if you don't give them the same setting. We don't want the Duros to use Atton's animations, so I change the supermodel to S_Female02, the default male supermodel. We do this by selecting the Aurora base and changing the text in the box next to Super in the MDL Base Parameters. We could change it to something else if we like; I might decide I want the Duros to retain his hunched over posture... if so, I would make some new body models that use those animations and then set the head's supermodel correspondingly. Now's a good time to save again. I save in different slots; that way if I screw something up, I won't have to start over from the beginning. I also notice the goggle and mask hooks are most certainly in the wrong places, so I reposition them. There's only so much I can do, however, as the shape of the head is just too different from a human's; only the breath mask looks any good. When you're finished editing, select the Aurora base and export as geometry only. Export it anywhere except in your folder, so you don't accidentally overwrite something. Now rename your file to something new - again, so you don't overwrite. The naming scheme I use is the original model name, plus "-ascii", plus "_new". Move this file to your folder now.
  4. Now save this as a new project. In a new project, import your full body model (mine is N_Duros). Now delete everything except the highlighted items below. Again, it will differ from model to model. What you're trying to keep is the object necklwr_g and all its children, as well as the head geometry - called here simply "head", but it may be "Head_Geo" or even part of "torso". This head is already its own object so that's it. Other models have the head as part of the torso - but that's fine, as you can simply delete all the vertices below the neck for those. In any case, save this project once you're finished. With this project still open, go to File -> Merge and import everything from your head template project (mine was Head Template Male). Select necklwr_g and link it to torsoUpr_g with the Select and Link tool. Now it should look like this. Next, select the head geometry and the Aurora base (here, P_AttonH). Link them using the Fast Linker tool in NWMax. Now save this as a new project. There's a point to all these separate files, I assure you.
  5. When I was working on something unrelated earlier, I noticed that the model PMBBL actually does have hooks for the collar and left forearm. So I wonder if there is some usable material left after all.
  6. Yeah, I'll get on the K1 soon. Just a few adjustments because K1 lacks a few functions and I have to remove that info from it, and also account for a bug in K1. I didn't feel like doing that with an untested script but since it is working then I'll go ahead with that. All that's needed for compatibility is for the other modder to add the ExecuteScript line to fire your script, in addition to their changes. So it's not difficult, but it requires awareness of other mods that edit it and cooperation and such. And regarding the head stuff... I did some testing and basically got nowhere. There's no way to consistently force an NPC outside the module, it's just too random. I had another idea that seemed like it was going to work, creating an NPC with no body, just the head hook, and placing the head hook below the module... but that didn't cooperate with the DuplicateHeadAppearance function, so it was a dead end. But it was close... so close. Although, I did confirm the convoluted process does work. It's still just a matter of hiding the NPC from view.
  7. This is a repost of an old tutorial I did on LucasForums. The original discussion thread is HERE. This tutorial will go over the process of ripping heads from a full body model, as I did in my modding resource JC's Heads for K2. Through this method, we'll be able to take a Duros character and let him use any body model in the game, just as most human characters as well as Twi'leks and Devaronians can. No longer will he be cursed to wear a white jumpsuit. I'll note that at the time I'm writing this, I have only made heads for Knights of the Old Republic II: The Sith Lords. But I believe the process is the same for the first game. Tools you will need: KOTOR Tool MDLOps 0.7a2 (or later) a 3D modeling program that supports NWMax (such as 3ds Max or Gmax) NWMax a hex editor To start, extract the model you want to turn into a head. In this case, n_duros. Extract both the MDL and MDX files. Next, extract a head to use as a template. It should be similar to your final result, so that means roughly the same size, and at least the same gender. Make sure to get one with the mask and goggle hooks already on it. I like to use Atton's head, as that makes it easy to test as well. Again, extract both the MDL and MDX. Now extract the texture for your head. In this case, N_Duros01. Save as TGA. Place all these files in a folder somewhere, then convert each model to ASCII using using MDLOps. In your modeling program, import your head template model (mine is P_AttonH). Import geometry only. Immediately save this project. After it saves, delete all the highlighted items below. The names will differ slightly depending on which head you're using, but the stuff you keep should all be the same (except the Aurora base, which has the name of the model).
  8. This is a repost of an old tutorial I did on LucasForums. The original discussion thread is HERE. So, one benefit of plot usable items is that if they have an activate property you can use them even if you don't have them equipped, so long as the item is in your inventory. But one thing I've noticed is there are over 200 existing icons, and the engine only supports up to 255 (well, 256 if it accepts 000, but I've never actually checked). So there isn't much room for your items to have custom icons like there is with other item types. However, there are a whole bunch of icons left over from K1 which are not used at all. So I made a list of all the ones I could find that are currently used (it's not inconceivable that I missed some): 22 7 10 12 16 17 23 25 29 35 42 55 56 59 60 61 62 63 64 65 66 67 68 71 72 77 78 84 85 86 88 89 90 91 92 94 95 96 98 99 100 101 102 103 106 107 108 109 110 111 122-251Again, those are the ones that are used. If you use one of those, it will affect other items in the game. So don't use them. 69, 70, 74, 75, 113-122 and 252-255 don't exist at all; the others exist but shouldn't appear in the game. And in case you don't know... Plot Usable Item is a base item type that appears in your inventory but cannot be equipped. It is similar to the Aesthetic Item type, which uses the same icon set (and thus meaning there are even fewer numbers for us to use). The difference between the two types (I think) is that if a Plot Usable Item has an Activate Item property, the item will appear in your action menu. This allows you to have access to usable item equipping it - meaning a) you don't use up and equipment slot, so you can equip other things, and the whole party will have access to the item. I don't think this feature was actually used in the game, however. To create a plot usable item, create a new item and set the base item type to Plot Usable Items. Model Variation determines the icon number. The icons themselves are located in ERFs -> Texture Packs -> ***_GUI -> I, and the files all begin with "ip_pltuseitm_" (e.g. the unused holocron is ip_pltuseitm_072.tpc). Some additional information: 1 is a book of some kind. 11 is a Mandalorian helmet. 12 (used), 28, and 35 (used) all have Czerka logos. 15 has the Star Forge symbol on it - I think it's the Sith medallion from K1. 24 and 39 are crystals. 32 is the krayt dragon pearl. 33 is a Sand Person. 40 is Sith armor. 44-53 are all keycards. 72 is a holocron (107 is also a holocron, but is used for an HK part). 79 is the dancer's outfit, but the icon that is actually used is ia_slave_001 (I believe this is true of the Sith and Sand People disguises as well - so they wouldn't even be used in K1). 83 is another dancer's outfit, resembling Leia's more than the one in the game. Anyway, long story short, feel free to use any number that is not on this list. The only issue would be compatibility with other mods that do the same thing.
  9. This is a repost of an old tutorial I did on LucasForums. Original posts can be found HERE. The combat animations are in fact in the regular old animations.2da; combatanimations.2da is more like a seating arrangement. It lists all the attacks and then states which animation goes with it - hit, parry, dodge, and so on. It's entirely numbers so it can be a mess. animations.2da gives you more of a clue, but the naming scheme can seem a bit weird at first glance. The animation name is an alphanumeric code with four parts, alternating letters and numbers. The first part corresponds to the attack type - a generic attack, a feat, or a monster attack. There also seems to be some attempt to divide it into ranged and melee, but I can't discern it entirely. b - ranged c- melee f - feat g - generic m - monsterNext, it's divided into weapon type as well as whether the character wielding one or two. These are given abbreviations for K2 only. 0 - N/A - droid 1 - SB - stun baton 2 - SS - single saber 3 - 2HS - two-handed saber (double-bladed) 4 - DS - dual sabers 5 - SB - single blaster 6 - DB - dual blasters 7 - RF - rifle 8 - NT - natural attack (unarmed, I believe) 9 - HC - heavy carbine 10 - UC - unarmed, complex (K2 only) 11 - N/A - wrist launcher (K2 only)Next, what the character is doing. a - attack d - damage f - appears unused g - dodge n - deflection p - parry r - ready w - wieldAnd finally, another number. In most cases this is simply a variation number; some in K2 have an additional letter, for even more variation. So, for example, if you want a character wielding a blaster rifle to dodge, the animation would be g7g1. g: generic 7: rifle g: dodge 1: variation (in this case there's only one) In the original thread, Fallen Guardian asked about power blast. This is where it gets complicated. Some of these variables are limited by other variables. Parry, for instance, is only a melee occurrence. I believe this is the reason for the distinction between ranged and melee that I mentioned above. Let's look at the first part again. 1:b - ranged 1:c - melee, complex 1:f - melee, feats 1:m - melee, monster 1:g - both, genericAnd now let's look at the third part. 3:a - both, attack 3:d - both, damage 3:g - ranged, dodge 3:n - melee, deflection 3:p - melee, parry(Putting this in code because of the emoticon.) 1:b is used for [i]all[/i] blaster attack animations. 1:c covers complex melee animations such as parries and clashes. 1:f is reserved for melee feats - critical strike, flurry, and power attack, as well as Force Jump. 1:m is for engaging a monster in melee. 1:g is anything else. 3:a is used for any attack. 3:d is used for any damage. 3:g is used for dodging ranged attacks. 3:n is used for deflecting ranged attacks with a lightsaber. 3:p is used for parrying melee attacks.Because of these specifications, certain ones do not belong with certain other ones. If that's not confusing enough, the final number is not always a simple variation; what it is depends on both of the above letter slots. I'll go over the feats for you. MELEE (f***) 1 - critical strike 2 - flurry 3 - power 4 - jump RANGED (b***) 1 - attack 2 - attack 2 3 - sniper shot 4 - power blast So, finally, a power blast animation is b*a4. The asterisk is either 5, 6, 7, or 9, depending on whether you are dealing with a single blaster, dual blasters, a rifle, or a heavy carbine. To make things even more confusing, there are a couple other animations that use the same scheme, in a way. The knocked down animations, for instance, are g1x1, g1y1, and g1z1. And in K2, there are multiple ready animations for lightsabers, the final number corresponding to the saber form, but I don't know if they ever finished the animations for them. If you're still confused, the 2DA for K2 has a description column that might help. The format is virtually the same as K1's, but of course K2 has more animations so you shouldn't go by it entirely.
  10. No, it... those are two different things. There are some areas with just corrupted walkmesh data. There's a tiny bit that counts as a walkable point, even though it's not connected to anything else. As far as I'm aware it's not actually part of any room's walkmesh - probably just garbage data. But it happens with a lot of modules, not just Telos. And it's usually far below the rest of the module. One example is 950COR. It's possible to teleport into the skybox and for some reason HK-47 is hanging out there. As for the second thing, what I mean is that when you spawn a creature it spawns in at the nearest possible location. So if you spawn one, for example, a meter below the floor, it will usually spawn it on the floor. It ignores the Z value you input because there's no walkmesh there, instead getting the nearest workable location. Generally this location has the correct X and Y value, but if you try to spawn something inside a wall or another object or whatever, it will similarly be displaced along those axes. So if you spawn a creature with an extreme negative Z value, there's a chance it will end up at one of those weird points instead of any legitimate coordinates. But it's highly dependent on the module. I don't want to change the direction the camera's facing, though... that would probably be more distracting. I'd only want to get the direction, and as far as I'm aware there is no such function.
  11. It works with some modules. The walkmesh is a bit wonky at points, and it's possible to teleport to locations outside the main area, usually far below it. Even if it doesn't work, the game should ignore the Z value in such a case but not the X or Y so it wouldn't hurt to try. There is one other problem though. It's possible to have the camera facing in a different direction than the player is.
  12. Yeah, I might try that... Maybe cycle through each creature until there's no line of sight, and if that doesn't work spawn behind the player outside their field of vision, with an extreme negative Z value to try to force them below the module if possible.
  13. Under the module might work... I'm not sure if it would work with every module, though. I thought about doing it in relation to the player's location, but the problem is there's still no way to tell where in the module the player is. To spawn them outside of the player's field of vision, right? The problem is if the player is at the very edge of the module and facing towards the other end, there is nowhere behind the player and the creature could end up spawning right next to them. Then again, the creature only has to exist for a fraction of a second, so it's not a huge issue. And it's possible to put in a few different options, depending on what works best. For example, getting the location of whatever object is farthest away from the player, and if that's not far enough away then to try some other option.
  14. Yay! That's probably the first time a script ever worked on the first try in the history of everything ever. There's still the matter of retaining the head, but I haven't had any new ideas on that front. It's really a critical flaw that DuplicateHeadAppearance requires objects and can't do with just numbers.
  15. There are notes in the script, but I can summarize. First you go down to the open variables section: string sItemBase = "jc_d_test"; string sScript = ""; int nCheckHead = TRUE; int nCheckGender = TRUE; int nCheckPheno = FALSE; int nSlot = 1; int nB = 64; (those are all the open variables, don't change any others unless you know what you're doing) and change the item name from "jc_d_test" to whatever you want your item to be called (12 characters or fewer). You make an item with this name and tag, and the description you want and so on, but with no disguise property on the item. Let's say I change this to "jc_example". Then set the gender and phenotype booleans based on how you want the appearance to vary. By default, only gender is enabled, since K2 doesn't use phenotype. Then you duplicate this item to apply the disguise property you want, changing the item's tag, template, and file name. The naming convention is the original item base name, plus a suffix for gender and phenotype. If you just want a male version and a female version, then going by my example, the new items would be "jc_example_m" and "jc_example_f". If you are using phenotype as well, then you would have "jc_example_m_s" and "jc_example_f_m" for male, small and female, medium, and so on. A full list would be: jc_example jc_example_m_s jc_example_m_m jc_example_m_l jc_example_f_s jc_example_f_m jc_example_f_l If you set both gender and phenotype to false, then the disguise item should have the suffix "_d" instead; in my example this would be "jc_example_d". You can also change the inventory slot the item will use. By default I've gone with armor, but you could change this to a mask or whatever. I've included an index in the script comments. The last one is the local boolean that's used to check if the creature has put the item on or not. I've left this as an open variable for compatibility reasons but you shouldn't need to change it. So change those and only those, then save it. Then execute it through the heartbeat script like this: //:: k_hen_heartbt01 /* Heartbeat for the non-active party members. */ //:: Created By: //:: Copyright (c) 2002 Bioware Corp. #include "k_inc_debug" #include "k_inc_switch" void main() { ExecuteScript("k_ai_master", OBJECT_SELF, KOTOR_HENCH_EVENT_ON_HEARTBEAT); /* object oEnemy = GetNearestCreature(CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, OBJECT_SELF, 1, CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY); //GN_SetSpawnInCondition(SW_FLAG_SHOUTED_AT, FALSE); if(!GN_GetSpawnInCondition(SW_FLAG_AI_OFF) && !GetSoloMode()) { if(GetPartyMemberByIndex(0) != OBJECT_SELF) { if(IsObjectPartyMember(OBJECT_SELF) && //Note that this check replaces GetIsObjectValid(oMaster) //GetCurrentAction(OBJECT_SELF) != ACTION_FOLLOW && GetCurrentAction(OBJECT_SELF) != ACTION_MOVETOPOINT && //GetCurrentAction(OBJECT_SELF) != ACTION_WAIT && GetCurrentAction(OBJECT_SELF) != ACTION_FOLLOWLEADER && !GetIsConversationActive() && //GetDistanceBetween(OBJECT_SELF, GetPartyMemberByIndex(0)) > 4.5 && !GN_GetSpawnInCondition(SW_FLAG_SPECTATOR_STATE) && GetCommandable()) { //Db_PostString(GetTag(OBJECT_SELF) + " HEARTBEAT CHECK 1 PASS", 4, 10, 2.0); if(!GN_GetIsFighting(OBJECT_SELF) && !GetIsObjectValid(oEnemy)) { //Db_PostString(GetTag(OBJECT_SELF) + " HEARTBEAT CHECK 2 PASS", 4, 12, 2.0); //The distance checking is now down in the script fired from AI Action Update - Leave 5m Radius of party leader. ClearAllActions(); ActionFollowLeader(); } } } } ... else if(GetSoloMode() && GetCurrentAction(OBJECT_SELF) == ACTION_FOLLOWLEADER) { ClearAllActions(); } if(GN_GetSpawnInCondition(SW_FLAG_EVENT_ON_HEARTBEAT)) { SignalEvent(OBJECT_SELF, EventUserDefined(1001)); } */ ExecuteScript("jc_d_test", OBJECT_SELF, -1); } ...replacing "jc_d_test" with your script name, of course. Recompile k_hen_heartbt01 and you should be all set.
  16. I did some testing that answered a few questions I had. And I've confirmed that my convoluted head process should work. The spawning procedure is still needed for the initial appearance change, though. And I've yet to determine the best way of spawning the creature somewhere the player won't be able to see them. Every module's coordinates different, so I'm not sure how to go about this. Also it would probably be unavoidable in small modules anyway. As such, I decided not to write the head duplicating function yet. The following code should work work for masks and such, however: /* jc_d_test K2 VERSION This allows for the extension of body model slots through the use of disguise items. When the item is equipped, the heartbeat script will replace that item with a copy that has the desired disguise property. The disguise effect can vary based on the user's gender and phenotype. The character may also retain their original head or be given a new one through the disguise; however, this has not yet been implemented. In the K2 version of the script, feedback is hidden, phenotype is disabled by default, and everything is contained in in one script. */ // This sets the string for gender string JC_SET_GENDER(object oUser) { /* 0 = Male 1 = Female 2 = Both 3 = Other 4 = None */ string sGender; int nGender = GetGender(oUser); if(nGender == 0 ) sGender = "_m"; else if(nGender == 1 ) sGender = "_f"; else if(nGender == 2 ) sGender = "_m"; else if(nGender == 3 ) sGender = "_m"; else if(nGender == 4 ) sGender = "_m"; else sGender = "_m"; return sGender; } // This sets the string for phenotype string JC_SET_PHENO(object oUser) { /* Small - Scoundrel, Jedi Consular, Jedi Master, Sith Lord Medium - Scout, Jedi Sentinel, Jedi Watchman, Sith Assassin, and default Large - Soldier, Jedi Guardian, Jedi Weapon Master, Sith Marauder */ string sPheno; int nClass = GetClassByPosition(1, oUser); if( nClass == 0 || nClass == 3 || nClass == 11 || nClass == 14 ){ sPheno = "_l"; } else if( nClass == 2 || nClass == 4 || nClass == 12 || nClass == 15 ){ sPheno = "_s"; } else sPheno = "_m"; return sPheno; } // This cycles through the inventory to replace disguise items with the dummy item. void JC_SWAP_INVENTORY_CYCLE(string sItemBase, string sDisguise, object oUser) { object oItem = GetFirstItemInInventory(oUser); while( oItem != OBJECT_INVALID ) { string sTag = GetTag(oItem); if( sTag == sDisguise ) { DestroyObject(oItem, 0.0, TRUE, 0.0, TRUE); CreateItemOnObject(sItemBase, oUser, 1, TRUE); } oItem = GetNextItemInInventory(oUser); } } //This just runs the above subroutine for every possible disguise item name. void JC_SWAP_INVENTORY(string sItemBase, object oUser ){ JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_m", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_m" + "_s", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_m" + "_m", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_m" + "_l", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_f", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_f" + "_s", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_f" + "_m", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_f" + "_l", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_s", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_l", oUser); JC_SWAP_INVENTORY_CYCLE(sItemBase, sItemBase + "_d", oUser); } void JC_SWAP_EQUIP(string sDisguise, int nSlot, object oUser, string sScript) { int nGame = 2; object oEquip = GetItemInSlot(nSlot, oUser); ActionUnequipItem(oEquip, TRUE); DestroyObject(oEquip, 0.0, TRUE, 0.0, TRUE); object oItem = CreateItemOnObject(sDisguise, oUser, 1, TRUE); if( nGame == 1 ) { CreateItemOnObject(sDisguise, oUser, 1, TRUE); ExecuteScript(sScript, oUser, -1); } else { DelayCommand(0.1, AssignCommand(oUser, ActionEquipItem(CreateItemOnObject(sDisguise, oUser, 1, TRUE), nSlot, TRUE))); } } void JC_SWAP_HEARTBEAT() { /* Open variables - sItemBase: File name of the item that the user can equip. This item should have no disguise properties on it. The name must be 12 characters or fewer. - sScript: New script to fire equip the disguise. This has to be in a new script file for K1 due to a bug in the script compiler. - nCheckHead: Whether we want to keep the user's original head. - nCheckGender: Whether we want to change appearance based on gender. - nCheckPheno: Whether we want to change appearance based on character class. - nSlot: Which inventory slot the item goes in. 0 = Head 1 = Body 4 = Right Weapon 6 = Left Weapon 7 = Left Arm 8 = Right Arm 9 = Implant 10 = Belt See NWScript for more details. - nB: Boolean used to check if the creature has put the item on. This is currently Boolean 64, but I've left it open for compatibility reasons. */ string sItemBase = "jc_d_test"; string sScript = ""; int nCheckHead = TRUE; int nCheckGender = TRUE; int nCheckPheno = FALSE; int nSlot = 1; int nB = 64; /* Other variables (don't touch) - oUser: The creature that uses the item. But since this is going in the heartbeat script, it should be OBJECT_SELF. - sGender: Suffix to add to the disguise item name, for gender. - sPheno Suffix to add to the disguise item name, for phenotype. - sDisguise: Disguise item name. It's either item base plus the suffixes, or plus "_d" if there are none. For example... Item base = jc_example Disguise (male, small) = jc_example_m_s Disguise (just female) = jc_example_f Disguise (just large) = jc_example_l Disguise (no qualifiers) = jc_example_d Item names and tags should be assigned accordingly in the UTI files. - oEquip: The item currently equipped in nSlot. - sEquip: Tag of oEquip. */ object oUser = OBJECT_SELF; string sGender = ""; if( nCheckGender == TRUE ) sGender = JC_SET_GENDER(oUser); string sPheno = ""; if( nCheckPheno == TRUE ) sPheno = JC_SET_PHENO(oUser); string sDisguise = sItemBase + sGender + sPheno; if( sDisguise == sItemBase ) sDisguise = sItemBase + "_d"; object oEquip = GetItemInSlot(nSlot, oUser); string sEquip = GetStringLeft(GetTag(oEquip), GetStringLength(sItemBase)); //This will clear the player's inventory of any disguise items, replacing them with dummy copies. JC_SWAP_INVENTORY(sItemBase, GetFirstPC()); //This will replace the dummy item with the proper disguise item if equipped. if( !GetLocalBoolean(oUser, nB) && sEquip == sItemBase ) { SetLocalBoolean(oUser, nB, TRUE); JC_SWAP_EQUIP(sDisguise, nSlot, oUser, sScript); } } void main() { int i; for( i = 0; i < 30; i++ ) { DelayCommand(IntToFloat(i) * 0.2, JC_SWAP_HEARTBEAT()); } } It's untested but it compiles properly so I assume there aren't huge problems with it. This the K2 version. A script for K1 would have to be adjusted slightly, but I didn't feel like doing it all yet. So if anyone wants to test it, I'd be very interested in seeing the results.
  17. That wouldn't be compatible with any head mods, though. And would be a fair bit more work with setting up all the 2DAs, and you'd also have to directly map each appearance to each new appearance in the script, which would mean using the TSL Patcher for the script too. But sure, that is an option in theory.
  18. I haven't taken a look at that mod, but that's basically it, yeah. In an ideal situation, the item you actually equip would have no disguise property, then the heartbeat script would fire and replace it with the disguise one. And then similarly swap out any in the inventory with the dummy version. Disguise effect wouldn't preserve the head, though. All that nonsense is just to preserve the head. You shouldn't need booleans if we're talking about mask items. The heartbeat script would only need to check if the item doesn't have the correct disguise property, which could be handled through the item tag. Mm, like I said I've thought about doing it before too... I've just never had a reason to try it. If I have time I might write up some generic code at least as a starting point.
  19. I've given this some thought before. It's totally possible with the heartbeat script, just not... practical. But if you do want to go with that option, there is an alternative to the disguise effect. You could script the heartbeat to remove and replace the item, depending on whoever is wearing it, and then make multiple copies of the item, each with the right disguise property. However, you wouldn't be able to include those items in the upgrade system, since you'd be destroying the upgrade parts every time the item was equipped. That couldn't be removed through ClearAllEffects and as a bonus the disguise would be removed immediately when the item is removed. If you want to retain each character's head though, that's much trickier. There is a function for that, DuplicateHeadAppearance, but it requires two spawned objects in order to compare their heads. You can't just input head numbers. It might be possible to implement, but because it would be so convoluted I never attempted it. It would go something along the lines of... Equip item -> Heartbeat script fires -> get the item user's current appearance, before the disguise item -> apply the disguise item -> spawn a creature, any creature (ideally somewhere the player can't see) -> apply the desired disguise effect to that creature -> DuplicateHeadAppearance with the spawned creature and the item user (assuming it gets the right head) -> delete the spawned creature -> item user now has the desired head and body combination. There are a number of potential issues I can imagine. You'd probably have to set a boolean for whether the item has been equipped or not, to make sure the script is fired when the item is equipped but also when it is removed to fix everything, and also to account for area transitions, party members being sent away and then summoned again, etc. You might also have to store the player's appearance as a numeric so you can call it again later. I'm not sure if simply removing the item would set everything back to normal, so you might have to repeat the spawning and duplicating procedure, or apply a disguise effect using the player's original appearance, or maybe apply any other disguise effect and then clear it... I could go on and on. Like I said, convoluted. But it may be possible. And it's tempting.
  20. I've converted each shot with the stacks into an image sequence for anyone who wants to look into this: Jedi Library Stacks
  21. Looks like it's from one of the visual effect models, v_revmask1_dur or v_revmask2_dur (I believe that's just male/female).
  22. Sounds like one of the metamagic feats. A lot of that was left in KOTOR and may be functional - for example, all the existing spell casting functions include a parameter for metamagic feats - although I never took a look at it. There's other stuff that's in a similar state. It seems the Sith uniform was going to be done through a polymorph spell, and so that might be still functional. Also the time stop effect does work, although it makes the game a little crazy. It freezes literally everything in the game.
  23. I doubt adding model accessories would be possible. It looks like the 2DAs were set up to allow for it, but the models weren't. There are no hooks for the additional items, nor do I see any way of assigning them. A lot of stuff that was fully functional in NWN was simply stripped away from KOTOR. Since they actually made distinct models for all the items, I assume they intended to put it in at some point... but maybe they ran out of time, or they couldn't get it to look nice. So even if the belts and such have models, there's no way to tell the game to render it, at least not that I can see.
  24. User content does not count as "personal information". The terms of service had a whole section covering user content and it affirms that user content was always the intellectual property of the user: It stipulates that the site is free to maintain and distribute copies according to the needs of the site's function (since that's how hosting works) but they claim no ownership of the files and include provisions for removal of files. They have since shut down the site, so all this agreement is effectively terminated. It does not apply to Nexus or any other site. GameFront has nothing to do with where the files are going now. They shut down their site and are no longer hosting the files. But they gave a warning before the shutdown so users could get what they wanted before time ran out. So some people in the modding community used the Internet Archive and other means to create a backup - just copies of the Filefront webpages as they originally appeared, as if the site were still hosted. The Nexus staff then took the files from these backups and began hosting them on their own site, without seeking permission - or even any form of communication at all. So, it's all right because it was their plan to unilaterally ignore everyone's intellectual rights from the beginning. The problem I have is that they're not just preserving the files. The mods were actually already saved and are in no danger of being lost. They may be more difficult to find for the average user, but they are there, in their original state, the state everybody agreed to. This was the most that had to be done to save the content from being lost, and it was the most that could be done while still respecting the rights of everyone involved. Nexus, on the other hand, has chosen to take these files and integrate them into their website structure. These stolen mods appear alongside other mods as if they were uploaded legitimately. They're being allowed to get away with this because they claim to be doing this for the greater good of saving these mods. And the users of their site praise them for this because to them, to the users of Nexus that don't frequent Deadly Stream or JKHub or the other respective communities, Nexus is their savior, because their disregard for intellectual property allows their hosting to be more public and convenient. But I don't know these users on Nexus. And they don't know me. There has never been any interaction between us. I don't upload mods there because I upload them here and on LucasForums, where the KOTOR modding community is active (to a degree). If you take content I created and distribute it on a site I don't use to people don't know, without involving me at all, it feels like you're going behind my back. That's what bothers me. The interaction is cut. I'm never going to hear what they think of my mods and the only mods of mine they ever get to see are the ones that happen to have been stolen - which in this case, are from years ago, some bugs and lacking the updates I've already done. And that's not fair to either side. It's that interaction that keeps the modding community alive.
  25. They don't have to make the mods public on their website in order to preserve the files. They don't have to release them all at once under a dummy account rather than putting the absolute least effort possible in attempting to contact and properly credit any of the authors at all.