Leaderboard
Popular Content
Showing content with the highest reputation on 01/26/2021 in Posts
-
1 pointAwesome, I had no idea I could truely help you. My knowledge of the ascii files is limited (tried some things, mostly resulting in crashes, :D). I recently published my K1 Mission Vao mod and N-DReW25 messaged me that it lacked that mask hook, so this rang a bell.
-
1 point
-
1 pointI can ask Shem for permissions on Facebook later for you.
-
1 point@Effix, Thank you! I was thinking about this by the way yesterday when I was trying to figure it out by comparing this file and the "sith_app" file and decided to try again today but saw your recommendation. Now I'll try to do what you said. @Effix, I checked a variation of your solution. You were right! Headwear is no longer reflected on NPCs. Your help has helped me keep working on my mod! Thank you! I will definitely indicate you in the section of special thanks when writing a description of my modification.
-
1 pointI'm far from an expert, but maybe you can remove these nodes in the ascii file: "node dummy MaskHook" & "node dummy GoggleHook".
-
1 pointLife has been crazy, and I've seen things I never thought would happen in my country. But, coding never stops. Time for an overdue update! An earlier update outlined the structure of a subroutine: return_type subA(Argument_1, Argument_2...) { //Part 1 - The code that does stuff //Part 2 - Values returned //Part 3 - Destruction of local variables //Part 4 - Destruction of arguments } Part 2 returns values from a subroutine using the CPDOWNSP opcode. Parts 3 and 4 destroy local variables and arguments using the MOVSP opcode. These opcodes can appear in any part of a subroutine. So, how do we know if we're returning a value, and destroying variables and/or arguments? We analyze part 1 to determine what, if anything, is on the stack. Computers execute operations in sequence unless directed otherwise. In high-level languages like NWScript, control statements alter the sequence. An if statement conditionally executes code. If the test condition fails, this code is jumped over. So, what does an if statement look like in the compiled NCS? 102 CPTOPSP -3 1 110 CONSTI 0 116 EQUALxx 118 JZ 170 124 CPTOPSP -1 1 132 CPTOPSP -3 1 140 CONSTO object 146 JSR 298 152 MOVSP -3 158 JMP 296 164 JMP 170 In the example, the opcode at offset 102 of the NCS file copies the value of a variable to the top of the stack. Offset 110 places the value 0 onto the stack. Offset 116 performs a test of equality of the two values, removes them from the stack, then places the result of the test onto the stack. Offset 118 performs a conditional jump based on the result, removing the result in the process. Offsets 124-164 are the body of the if statement, which consists of a call to a subroutine followed by a return statement: if ( nKillMode == 0 ) { DamagingExplosion(OBJECT_SELF, nDelay, nDamage); return; } So many ops, so few statements. That's why we write in high-level languages instead of assembly, because the compiler allows us to focus on what the program should do rather than creating the proper sequence of opcodes to keep the program from breaking. Notice in the body of the if statement there is a MOVSP. That is the destruction of local variables, part 3. There is no part 2, because the subroutine returns void (nothing). But, how do we know the MOVSP is part 3 and not part 4? And why are there two unconditional jumps??? The challenge of writing a reverse compiler is knowing the rules used to compile. I've spent the past six months observing, analyzing, and documenting those rules. For example, all control statements other than the switch statement are created using the jump-if-zero (JZ) opcode. (Switch statements are created using the jump-if-not-zero [JNZ] opcode.) However, the existence of a JZ opcode does not mean you've encountered a control statement! JZ is used to create the following: Logical AND Logical OR if statements else if statements while statements for statements do-while statements (I finally found one!!!) This means we need to some way of determining what the range of addresses created by the JZ opcode is. In the example above, the range created by the if statement is [124, 170). In this range notation a bracket "[" means the offset is included in the range, and a parenthesis ")" means the offset is outside of the range. The 170 is obvious because it's specified by the JZ opcode; if nKillMode == 0 returns false we jump to 170 and resume execution from there. Where does the 124 come from? Remember what was stated above: "computers execute operations in sequence unless directed otherwise." A JZ opcode is 6 bytes in length and the JZ is at offset 118, so 118 + 6 means the next op in the sequence is at offset 124. If nKillMode == 0 returns true we enter the body of the if statement at offset 124. Offset 124 is the first address in the range, offset 170 is the first address outside of the range. All control statements are ranges, but not all ranges are control statements. The NCS file is itself a range: [0, file size). Subroutines are ranges. However, our focus is on the ranges created by JZ. How do we determine what they are? The unconditional jump, JMP. Notice the example ends with two JMPs. This caused me lots of stress because I didn't know why they were there. I'm now convinced this is one of the rules of compiling NCS files: control statements end with a JMP. The if statement is easily identified as such because the second JMP goes to the same offset as the JZ. The true block of an if-else statement ends in a JMP to an offset greater than that of the JZ. The if and else-if statements all end in JMPs to the same offset. Loops all end in JMPs to an offset less than the offset of the JZ. Logical AND and Logical Or are not control statements, so they do not end in a JMP. Our example has two JMPs. Why? Most likely the original compiler was dumb. The NWScript return statement is translated into a JMP to the end of the subroutine, offset 296. The opcode at this offset is RETN, the last opcode in a subroutine. Anytime you see a return in NWScript that isn't the last statement in the subroutine, you know it will be implemented as a JMP: if ( nKillMode == 0 ) { return; } if ( nKillMode == 1 ) { return; } if ( nKillMode == 2 ) { return; } is 118 JZ 170 158 JMP 296 164 JMP 170 186 JZ 230 218 JMP 296 224 JMP 230 246 JZ 290 278 JMP 296 284 JMP 290 296 RETN The original compiler just stuck the body of the if statement in between the JZ and JMP. A modern compiler would have removed the second JMP since it's unreachable code. OK, this is great and all. But what about the reverse compiler? Well, now that I have the rules down I'm close to the finish line. The reverse compiler accurately finds ranges and determines what types they are. The output looks like this: This is definitely a K2 file Subroutine 13, 21 13, 21 //Subroutine Subroutine 21, 298 21, 298 //Subroutine 124, 170 //if 192, 230 //if 252, 290 //if Subroutine 298, 1345 298, 1345 //Subroutine 320, 396 //if 704, 722 //logical AND or OR 728, 1216 //loop 787, 805 //logical AND or OR 811, 1135 //if 914, 970 //if-else 1017, 1043 //if-else Subroutine 1345, 1601 1345, 1601 //Subroutine 1459, 1553 //if 1511, 1547 //if Subroutine 1601, 1637 1601, 1637 //Subroutine Subroutine 1637, 1813 1637, 1813 //Subroutine 1659, 1727 //if There's more to be done, particularly for loops because they support the break and continue statements (also implemented with JMP). But, hard part seems to be behind me. Should have an update in two weeks.
-
1 pointView File Ep. IX Rey's Lightsaber for K1 *Note: If you still have not seen Star Wars: Episode IX – The Rise of Skywalker and are sensitive to spoilers, please watch the movie before installing this mod. I apologize for some of the low quality images, I use the GOG version of the game without any graphics mods so the in-game screenshots aren't very representative of how the lightsaber actually looks in-game. 1. Description: This mod adds Rey's lightsaber (and saber crystal) from the end of episode IX to KOTOR. 2. How to Access: Rey's saber crystal can be purchased from Yuka Laka's droid shop on Tatooine for 10000 credits. From there, place it into any lightsaber's colour crystal slot. The lightsaber can also be spawned in using the console command: "giveitem sa_reysaber" or "giveitem sa_reycrystal" for the crystal. 3. Installation Instructions (PC): Download and extract the zip file. Run TSLPatcher. 4. Compatibility: This mod uses lightsaber slot and lightsaber crystal slot 34. Any other mods that occupy these slots will be incompatible with this mod. 5. Other notes: This mod was converted from a lightsaber hilt within Plasma's Lightsaber Hilt Collection mod for Star Wars Jedi Knight: Jedi Academy. Plasma has me given me permission to convert his mod to KOTOR and upload it. All credit for the model and texture goes to him, I only converted it to KOTOR and created the KOTOR lightsaber icon. Please check out his original mod at: https://jkhub.org/files/file/3552-lightsaber-hilt-collection/ The icon for Rey's lightsaber crystal was borrowed from Kaidon Jorn's Schematic Lightsaber Mod. He indicated that as long as he was credited for the original work, it could be used in other mods. This is my first mod, so please let me know if you have any problems or suggestions! 6. Very special thanks to: The original mod author: - Plasma Everyone who helped teach and guide me along the way: - Stormie97 - DarthParametric - Rooxon The creator of the lightsaber crystal icon: - Kaidon Jorn The creators of the excellent modding tools I used during the creation of this mod: - Fred Tetra (Kotor Tool) - stoffe (TSL Patcher) - bead-v (KOTORmax, MDLEdit) - mrwonko (GLM Importer and Exporter) - Fair Strides (TSL Patcher) - ndix UR (tga2tpc) Lastly, a special thank you to anyone and everyone who installs this mod, hope you enjoy it! 7. Redistribution: This mod may redistributed as long as proper credit is given to myself for the porting process and lightsaber icon, Plasma for the original lightsaber hilt model and texture, as well as Kaidon Jorn for the lightsaber crystal icon. 8. Legal: This modification is provided as-is and is not supported by BioWare Corp or LucasArts in any capacity. Please use this file at your own risk, neither I nor BioWare or LucasArts are responsible for any damages to your equipment incurred by the usage of this file. Submitter kane001 Submitted 04/20/2020 Category Mods K1R Compatible Yes
-
1 pointAt no point does the game suggest you do not level up, therefore there is no encouragement to refrain from levelling up too far too soon. I think you are mis-remembering it to be honest, I remember it being tough but I remember it also being a satisfying challenge to complete, it is also a challenge that not everybody takes on, which I think is also part of the point, not everyone does all the side quests for various reasons. Be it that they have done it before or they don't have the time, or that they just don't want to. Personally I like to do them and I like them to be challenging, if you can find something in the game that truly encourages you to refrain from levelling up, I would like to hear it because I am confident that there is no such suggestion or encouragement, other than that which comes from online guides or people who have already played the game.
-
1 point...did you grind on respawning Rakghouls or something? You're meant to leave Taris at level 8 or 9. That's the intended progression.
-
1 pointIf it was indeed understood, we wouldn't still have people saying, "But why can't we upload mods that aren't ours? Oh, and the author's read-me said 'No'..."