Jump to content

Ask me anything about the Jedi source code


Recommended Posts

Hi everybody

 

Hi sir

 

 

Let me tell you something. You have coded two of the best games I ever played. Jedi Academy and Outcast did my childhood, my teenage years and my young adult life on videogames.

 

I don't know how much I can thank you, and what can I do, but you have made gold. Still playing and modding for this JA, 14 years after the release. 

 

 

I think I know every single cheat code, every single g_something of SP game, every single trick of the "playermodel" function and now coding, I understand what I have played. And I think I will play this game until the end of computers.

 

 

I am creating mods for SP, with 45, 55 maps, it requiers me years. But the biggest project of all time we all want here is Jedi Knight III. We want Kyle Katarn to come back. And If I had enough time and energy, I would have contacted the best mappers, modelers, coders and would have launched the project, because I am the kind of modders who finish what they start. 

 

Seeing you here Sir, is like having the announcement of JKIII. It show us that, 14 years later, peoples who made the dream still care about Jedi Knight, and I think that means a lot to all of us.

 

 

Thank you for all.

 

Awesome, thanks for sharing your experience!  I have to say, I have been constantly impressed with the Jedi community since before we released Outcast (how they would react to our early screenshots and point stuff out that needed to be fixed - like additive saber trails instead of normal blending) to how they behaved in Duel mode to the incredible modding scene that made me want to make Academy easier to mod to the constant modding and playing that's gone on since then!  I'm proud to have been a part of a game that's brought so much enjoyment and elicited so much creative passion for so many... :)

 

Here's a little list I wrote up recently of slightly more obscure console commands/cvars.  Maybe there's one in there you didn't know about?  :)

setmindtrick 4 - makes mind trick take over an NPC when you use it on them - you have full control over the NPC, you can even make them kill other NPC or jump to their deaths

iknowkungfu I added so I could test the slow-mo camera spin that plays automatically when you defeat the last enemy in the room. That slow-mo spin is on a console variable, too - you can disable it, make it do it on every kill and even make it do it on dodges/flips/rolls.

G_saberautoblocking is one I made to try out a manual blocking system. If you set that to 0, then bind a key/button to +block, then you will only block when you actually actively do so. We left autoblocking on to be more player-friendly, but I kinda liked the extra level of skill it took.

Helpusobi 1 was our replacement for sv_cheats. I think James Monroe came up with that one. 

There were a bunch of dismemberment console variables that I made to test our dismemberment system. The ESRB found out about them *after* they rated the game and we’d already shipped it. They threatened to change our rating to M unless we removed it from the game (never mind the fact that people get dismembered in every single Star Wars movie). First we obfuscated it, but ultimately we had to disable it altogether.

set g_debugMelee to 1 to be able to do an extended set of melee moves - kicks, punches, grapples and throws.

g_gravity - changes gravity, obvs

g_timescale - slow or fast mo

playermodel <whatever NPC you want> - lets you play as any NPC, even an AT-ST, droid or Boba Fett (with flamethrower, rockets, jetpack, etc.)

g_saberAutoAim - aims your sabers at enemies so when you swing, it just intelligently swings in the right direction

g_saberNewControlScheme use +forcefocus to pull off all the special moves

g_saberLockRandomNess controls frequency of saberlocks

g_debugSaberLock makes saberlocks happen all the time

g_saberPickuppableDroppedSabers lets you pick up sabers that are dropped

g_AIsurrender - enable/disable AI surrendering to the player if outmatched

npc spawn <NPC> spawn any NPC

runscript <.ibi file> lets you run any .ibi file from the console

playerteam free, player, enemy, neutral - change you team (as if you turned to the dark side - Luke, Kyle, etc would attack you, bad guys would be on your side)

control <targetname> - take over an NPC by targetname (or it will pick whoever you’re looking at

grab <targetname> grapple the NPC you’re looking at or by targetname

knockdown - knock yourself down
Smoo, Sir Crusher and Cerez like this
Link to comment

Let me explain this more in depth (concerns only JK2)

Current JK2 QVM rand() implementation uses a linear congruential generator algorithm and returns LOWEST bits of calculated value:

int rand( void ) {
    randSeed = (69069 * randSeed + 1);
    return randSeed & 0x7fff;
}

Unfortunately lowest bits have very short periods - at most 2^n for nth bit. For example subsequent (rand() & 1) calls yield (1, 0, 1, 0, 1, 0…) sequence. Now consider this simplified code example:

if (rand() & 1) {
    SaberBlock();
    if (rand() & 1) {
        SaberParry();
    }
}

Of course SaberParry() never actually happens, despite the developer's intent. This is simplified and over-dramatized, but this type of unintended correlations surely exist in JK2 code due to this rand() implementation. Also consider that players who've never seen the code are aware that parry never happens right after block. One could say that they "recognize pattern" (although here it's just a dead code, you can imagine more complex and not 0/1 correlations).

 

Now examine same code segment in a mod:

if (rand() & 1) {
    SaberBlock();
    saberColor = rand();
    if (rand() & 1) {
        SaberParry();
    }
}

The situation changes diametrically even though a mod developer thought he wasn't altering block/parry behaviour.

 

Nice catch - though, of course, inside SaberBlock() there are multiple calls to rand(), so that doesn't quite work out the way you said.

Link to comment

BTW, sorry if I disappear for several days at a time.  This weekend we had company and a party to host, so I didn't have time to sit down for a couple hours and do this.  And this week we have some important big-wigs visiting Raven and I need to get a mode I'm working on in perfect shape and a stable build together before they get here.  Thanks for understanding!

Cerez, Asgarath83, Smoo and 1 other like this
Link to comment
Guest Redemption

Hi, @@MGummelt that Raven meeting sounds interesting :) 

I'm afraid what you said about adding the function before the function doesn't work, I've been trying all kinds of ways including what you said a couple of days ago.

This is what I'm trying at the moment but, if I can't get this working properely, I'll revert to:

anim = qirand ( loads of anims here)

Here's what I've got so far.

if (victim->client->NPC_class == CLASS_GALAKMECH || victim->client->NPC_class == CLASS_SHADOWTROOPER)
				{
					vec3_t	att_Right, att_Up, att_Left, att_DeflectionDir;
						float	swingRDot, swingUDot;

						swingRDot = DotProduct(att_Right, att_DeflectionDir);
						swingUDot = DotProduct(att_Up, att_DeflectionDir);

						if (swingRDot > 0.25f)
						{//deflect to right
							if (swingUDot > 0.25f)
							{//deflect to top
								PM_SetSaberMove(LS_D1_TR);
							}
							else if (swingUDot > 0.25f)
							{//deflect to bottom
								PM_SetSaberMove(LS_D1_BR);
							}
							else
							{//deflect horizontally
								PM_SetSaberMove(LS_D1__R);
							}
						}
						else if (swingRDot < 0.25f)
						{//deflect to left
							if (swingUDot < 0.25f)
							{//deflect to top
								PM_SetSaberMove(LS_D1_TL);
							}
							else if (swingUDot < 0.25f)
							{//deflect to bottom
								PM_SetSaberMove(LS_D1_BL);
							}
							else
							{//deflect horizontally
								PM_SetSaberMove(LS_D1__L);
							}
						}
						else
						{//deflect in middle
							if (swingUDot > 0.25f)
							{//deflect to top
								PM_SetSaberMove(LS_D1_T_);
							}
							else if (swingUDot < -0.25f)
							{//deflect to bottom
								PM_SetSaberMove(LS_D1_B_);
							}
							else
							{//deflect horizontally?  Well, no such thing as straight back in my face, so use top
								if (swingRDot > 0)
								{
									PM_SetSaberMove(LS_D1_TR);
								}
								else if (swingRDot < 0)
								{
									PM_SetSaberMove(LS_D1_TL);
								}
								else
								{
									PM_SetSaberMove(LS_D1_T_);
								}
							}
						}
					return didDamage;
				}

Thank you

Link to comment

Hi, @@MGummelt that Raven meeting sounds interesting :)

I'm afraid what you said about adding the function before the function doesn't work,

Wait, hold on. What do you mean "it doesn't work". How does it not work? What's the error? Show me what you did. Did you try to move the whole function definition higher up (you can't do that) or did you just declare it at the top like I showed (that should absolutely work).

 

To clarify the terms I'm using, just in case you're not familiar:

http://www.cprogramming.com/declare_vs_define.html

Link to comment

BTW, sorry if I disappear for several days at a time.  This weekend we had company and a party to host, so I didn't have time to sit down for a couple hours and do this.  And this week we have some important big-wigs visiting Raven and I need to get a mode I'm working on in perfect shape and a stable build together before they get here.  Thanks for understanding!

 

Not worry, real life come ever before of virtual life. thanks to you for all help you get to us for our projects ^_^

 

About my code troubles: i'm sorry for late but i try to answer about all your consideration.

First off, thanks for answers. really, i appreciated and you give me also some new code incipit.

SAbout my bug of invisible saber: the NPC file i used for testing my AI get 5 different version of NPC for test all possible weapons behavours:

Arcane
{
    playerModel    stormtrooper
    weapon        WP_BLASTER_PISTOL
    weapon        WP_BLASTER
    weapon        WP_REPEATER
    weapon        WP_FLECHETTE
    weapon        WP_DEMP2
    weapon        WP_CONCUSSION
    weapon        WP_BOWCASTER
    weapon        WP_ROCKET_LAUNCHER
    weapon        WP_JAWA
    weapon        WP_POISON
//    saber        dual_3
    FP_HEAL        1
    FP_LEVITATION    1
    FP_DRAIN    1
    FP_SEE        1
    FP_RAGE        1
    FP_PROTECT    1
    FP_SPEED    1    
    FP_PUSH        1
    FP_PULL        1
    FP_SABER_DEFENSE 1
    FP_SABER_OFFENSE 1    
    FP_SABERTHROW    1
    FP_LIGHTNING    1
    FP_GRIP        1    
    FP_TELEPATHY    1
    FP_ABSORB    1
    FP_FORCEGLYPH    1
    forceRegenRate        150
    forcePowerMax        100
    rank        lt
    reactions    3
    aim        1
    move        4
    aggression    5
    evasion        3
    intelligence    4
    playerTeam    TEAM_ENEMY
    enemyTeam    TEAM_PLAYER
    class        CLASS_WIZARD
    yawSpeed    100
    walkSpeed    55
    runSpeed    160
    snd            weequay
    sndcombat    weequay
    sndjedi        weequay
    health        300
    dismemberProbHead    30
    dismemberProbArms    30
    dismemberProbLegs    20
    dismemberProbHands    50
    dismemberProbWaist    0
}

Arcane2
{
    playerModel    stormtrooper
//    Test per vedere se il modello Dumahim

può lanciar granate.
    altfire        1
    weapon        WP_BLASTER_PISTOL
    weapon        WP_BLASTER
    weapon        WP_REPEATER
    weapon        WP_FLECHETTE
    weapon        WP_DEMP2
    weapon        WP_CONCUSSION
    weapon        WP_BOWCASTER
    weapon        WP_ROCKET_LAUNCHER
    weapon        WP_JAWA
    weapon        WP_POISON
    FP_HEAL        0
    FP_LEVITATION    0
    FP_DRAIN    0
    FP_SEE        0
    FP_RAGE        0
    FP_PROTECT    0
    FP_SPEED    0    
    FP_PUSH        0
    FP_PULL        0
    FP_SABER_DEFENSE 0
    FP_SABER_OFFENSE 0    
    FP_SABERTHROW    0
    FP_LIGHTNING    0
    FP_GRIP        0    
    FP_TELEPATHY    0
    FP_ABSORB    0
    FP_FORCEGLYPH    0
    forceRegenRate        150
    forcePowerMax        100
    rank        captain
    reactions    3
    aim        1
    move        4
    aggression    5
    evasion        3
    intelligence    4
    playerTeam    TEAM_ENEMY
    enemyTeam    TEAM_PLAYER
    class        CLASS_WIZARD
    yawSpeed    100
    walkSpeed    55
    runSpeed    160
    snd            weequay
    sndcombat    weequay
    sndjedi        weequay
    health        300
    dismemberProbHead    30
    dismemberProbArms    30
    dismemberProbLegs    20
    dismemberProbHands    50
    dismemberProbWaist    0
}


Arcane3
{
    playerModel    stormtrooper
//    Test per vedere se il modello Dumahim

può lanciar granate.
    weapon        WP_SABER
    saber        dual_3
    FP_HEAL        1
    FP_LEVITATION    1
    FP_DRAIN    1
    FP_SEE        1
    FP_RAGE        1
    FP_PROTECT    1
    FP_SPEED    1    
    FP_PUSH        1
    FP_PULL        1
    FP_SABER_DEFENSE 1
    FP_SABER_OFFENSE 1    
    FP_SABERTHROW    1
    FP_LIGHTNING    1
    FP_GRIP        1    
    FP_TELEPATHY    1
    FP_ABSORB    1
    FP_FORCEGLYPH    1
    forceRegenRate        150
    forcePowerMax        100
    rank        lt
    reactions    3
    aim        1
    move        4
    aggression    5
    evasion        3
    intelligence    4
    playerTeam    TEAM_ENEMY
    enemyTeam    TEAM_PLAYER
    class        CLASS_WIZARD
    yawSpeed    100
    walkSpeed    55
    runSpeed    160
    snd            weequay
    sndcombat    weequay
    sndjedi        weequay
    health        300
    dismemberProbHead    30
    dismemberProbArms    30
    dismemberProbLegs    20
    dismemberProbHands    50
    dismemberProbWaist    0
}

Arcane4
{
    playerModel    stormtrooper
//    Test per vedere se il modello Dumahim

può lanciar granate.
    weapon        WP_SABER
    saber        dual_3
//    weapon        WP_CANNON
    weapon        WP_REPEATER
    weapon        WP_FLECHETTE
    weapon        WP_DEMP2
    weapon        WP_CONCUSSION
    weapon        WP_BOWCASTER
    weapon        WP_ROCKET_LAUNCHER
    weapon        WP_JAWA
    weapon        WP_POISON
    FP_HEAL        1
    FP_LEVITATION    1
    FP_DRAIN    1
    FP_SEE        1
    FP_RAGE        1
    FP_PROTECT    1
    FP_SPEED    1    
    FP_PUSH        1
    FP_PULL        1
    FP_SABER_DEFENSE 1
    FP_SABER_OFFENSE 1    
    FP_SABERTHROW    1
    FP_LIGHTNING    1
    FP_GRIP        1    
    FP_TELEPATHY    1
    FP_ABSORB    1
    FP_FORCEGLYPH    1
    forceRegenRate        150
    forcePowerMax        100
    rank        lt
    reactions    3
    aim        1
    move        4
    aggression    5
    evasion        3
    intelligence    4
    playerTeam    TEAM_ENEMY
    enemyTeam    TEAM_PLAYER
    class        CLASS_WIZARD
    yawSpeed    100
    walkSpeed    55
    runSpeed    160
    snd            weequay
    sndcombat    weequay
    sndjedi        weequay
    health        300
    dismemberProbHead    30
    dismemberProbArms    30
    dismemberProbLegs    20
    dismemberProbHands    50
    dismemberProbWaist    0
}

Arcane5
{
    playerModel    stormtrooper
//    Test per vedere se il modello Dumahim

può lanciar granate.
    weapon        WP_TUSKEN_STAFF
    weapon        WP_TUSKEN_RIFLE
    weapon        WP_BLOODGUN
    weapon        WP_CANNON
    weapon        WP_DISRUPTOR
    weapon        WP_BRYAR_PISTOL
    weapon        WP_THERMAL
    FP_HEAL        1
    FP_LEVITATION    1
    FP_DRAIN    1
    FP_SEE        1
    FP_RAGE        1
    FP_PROTECT    1
    FP_SPEED    1    
    FP_PUSH        1
    FP_PULL        1
    FP_SABER_DEFENSE 1
    FP_SABER_OFFENSE 1    
    FP_SABERTHROW    1
    FP_LIGHTNING    1
    FP_GRIP        1    
    FP_TELEPATHY    1
    FP_ABSORB    1
    FP_FORCEGLYPH    1
    forceRegenRate        150
    forcePowerMax        100
    rank        lt
    reactions    3
    aim        1
    move        4
    aggression    5
    evasion        3
    intelligence    4
    playerTeam    TEAM_ENEMY
    enemyTeam    TEAM_PLAYER
    class        CLASS_WIZARD
    yawSpeed    100
    walkSpeed    55
    runSpeed    160
    snd            weequay
    sndcombat    weequay
    sndjedi        weequay
    health        300
    dismemberProbHead    30
    dismemberProbArms    30
    dismemberProbLegs    20
    dismemberProbHands    50
    dismemberProbWaist    0
}

the dual_3 model saber is replaced by a magic scepter imbue with fire power, but it works perfectly fine as model if get to player with saber cheat command consolle.

arcane1 is for testing AI switching weapon basic behavour. the 2 is for testing altfire behavour and advanced and more smart fight.

3 is for testing saber only - saberist behavour. 4 testing the switching before saber and other weapons (and was four to not working fine) 5 is for testing last set of weapons. WP_JAWA is modded for is a sonic shoot stun weapon. it works well. i fixed also his fire rate.

WP_BRYAR_PISTOL is turned into a magic bow. disruptor into a sniper bow. tusken rifle into a bowcaster with magic arrows.

as i told in the other thread (where i post the AI code related to switching weapons) the problem was when NPC get player \ enemy close, it equip saber for fight. it works fight. it activate NPC_fencer state and this state switch weapon to saber. (yes,. in past i tried also the set_saber function of icarus script, but in this contest it not work much fine)

the adding of NPC_FENCER state fixed the saber invisible model trouble.

the problem was the NPC not leave NPC_FENCER state, because into NPC.cpp there is a condituion related to

else if (NPC->client->ps.weapon == WP_SABER )... it activate Jedi behavour for all NPC with saber, for all classes. my AI is done cloning and editing boba fett AI and renaming functions for avoid overwriting or function conflict or function duplicated. basically, NPC_FENCER activate also, with saber, the statement of jedi behavour, so NPC fight like a jedi and forget to fight like bobafett. because into AI_jedi.cpp there is nothing concerned switch weapons, NPC not change more his state.

i fix that editing the NPC.cpp condition in that way:

else if ( NPC->client->ps.weapon == WP_SABER && NPC->client->NPC_class != CLASS_WIZARD )
    {//jedi
        
        NPC_BehaviorSet_Jedi( bState );
        dontSetAim = qtrue;
    }

because my AI use this behavour:

else if ( NPC->client->NPC_class == CLASS_WIZARD )
    {
        
            NPC_Update();        
            if (NPCInfo->surrenderTime)
            {
                NPC_Flee();
            }
            else
            {
                if (!NPC_Tactics())
                {
                    if ( NPC_Flying( NPC ) )
                    {
                        NPC_BehaviorSet_Seeker(bState);
                        //NPC_BSRT_Default();
                    }
                    else
                    {
                        NPC_BehaviorSet_Jedi( bState );
                    }
                }
                dontSetAim = qtrue;
            }
    }

this avoid interferences and now All works fine! :D

About your suggest:

-so is possible to create with code the saber bladetrace that cut and damages the enemy in artificial way. pretty interessing! I will conserve this suggest. sure can be useful in future. maybe some day i can use for create a monster with multiple sabertrace generated by code D: for moment for some monster creature i workaround the fact that a monster cannot carry more of two saber moving into model project on max the r_hand , l_hand tag on the position i want the moster doing saber damage (example... inside the mouth) or where i want it shoots force lightning or other things. 

- yes, working on an looong if \ else statement about specific saber name that do specific saber damage is not exaclty the more friendly code work. you suggest me a good alternative: working on MOD and add the name exception into the MOD statements. nice suggest. thanks! :)

 

I discover casually the interference of behavour state that cause the problem of saber switch because after some hundred of test into t3_bounty map with npc fight simulation i noticed that a normal reborn \ other class npc turn off saber when i set into notarget cheats. the boba fett ai instead, not turn off the saber if player "disappering" so for that i understand that my Ai follow some strange behavour related to saber combat. and i checked AI_jedi.cpp and i see there is a counter about aggression level of saberist that turn down weapons after a lot of time, when aggression level is sufficient low after lost the enemy.

after that and a lot of test around AI_jedi.cpp also about some saber function, i discovered the origin of the problem lead on NPC.cpp and so i found the cause.

MGummelt likes this
Link to comment
Guest Redemption

Hi, @@MGummelt, I commented out my attempt, and only added what you provided; that being the qboolean at the top of the file:

void WP_SaberDrop( gentity_t *self, gentity_t *saber );
qboolean WP_SaberLose( gentity_t *self, vec3_t throwDir );
void WP_SaberReturn( gentity_t *self, gentity_t *saber );
void WP_SaberBlock( gentity_t *saber, vec3_t hitloc, qboolean missleBlock );
void WP_SaberBlockNonRandom( gentity_t *self, vec3_t hitloc, qboolean missileBlock );
void ForceThrow( gentity_t *self, qboolean pull );
qboolean WP_ForcePowerAvailable( gentity_t *self, forcePowers_t forcePower, int overrideAmt );
void WP_ForcePowerDrain( gentity_t *self, forcePowers_t forcePower, int overrideAmt );
qboolean WP_SaberParry(gentity_t *victim, gentity_t *attacker);

Piece of code at applydamage bit:

if (victim->client && (victim->client->NPC_class == CLASS_GALAKMECH || victim->client->NPC_class == CLASS_SHADOWTROOPER))
				{
					WP_SaberParry(victim, attacker);
					return didDamage;
				}

The error I get is Error: identifier "attacker" is undefined.

 

So what I've done to get this to compile is add *attacker to gentity_t here:

qboolean WP_SaberApplyDamage(gentity_t *ent, float baseDamage, int baseDFlags, qboolean brokenParry)
{
	qboolean	didDamage = qfalse;
	gentity_t	*victim;
        gentity_t       *attacker;
	int			dFlags = baseDFlags;
	float		maxDmg;

It doesn't rebound of the shadowtrooper ingame anymore :( But... it definitely works with setting PM_setsabermove(), but I need to somehow implement an angle case so that it knows what anim to play. Sorry to bother you.

Link to comment
Guest Redemption
qboolean WP_SaberApplyDamage(gentity_t *ent, float baseDamage, int baseDFlags, qboolean brokenParry)
{
	qboolean	didDamage = qfalse;
	gentity_t	*victim;
	gentity_t	*attacker;
	int			dFlags = baseDFlags;
	int			WP_SaberParry(gentity_t	*victim, gentity_t *attacker);
	float		maxDmg;

I just tried this, and while it didn't work from hitting the shadowtrooper on the back, when I knocked away his saber and attempted to hit him from the front, the game crashed to desktop.

Smoo likes this
Link to comment

Nice catch - though, of course, inside SaberBlock() there are multiple calls to rand(), so that doesn't quite work out the way you said.

 

Sure, as I wrote, this was an over-dramatized example :-)

The saber combat works great and as a player I join all other people in this thread – thank you for my favorite saber combat system and game!

 

I believe that the probabilities of various randomized things happening are not what they look like when reading the code due to correlations of rand() values. I don't have hard data to support it but I'm gonna collect it. Mods can unintentionally change these correlations by adding, removing or rearranging rand() calls and this is something to look out for and something that may hopefully explain different feeling of different mods in JK2.

 

Footnote: Doesn't apply to JKA because it uses correctly implemented rand() procedures. Gonna add it to all my posts so people don't get wrong ideas.

Smoo and MGummelt like this
Link to comment

Hey, just made an account for JKHub to respond to a thread about manual saber blocking and figured I'd offer up my insights if anyone had any questions about the Jedi Outcast or Jedi Academy source code (SP or MP). It's been almost 15 years since I've written or even seen most of it, but hopefully if you ask me a specific question about a specific chunk of code (copy/paste a chunk or gimme a file name and line number) I can at least try to jog my memory and speak intelligently about it. ;)

 

I'll try to check back if people have questions.

Hello, i have a question regarding NPC stats (aggression, move, aim, evasion, reactions and intelligence), as for now you can set them in the .npc file between 1-5, i'd like to edit the code to increase them to maybe 1-20 to make an Npc more dangerous.

Can you help me with this?

Link to comment

Hello, i have a question regarding NPC stats (aggression, move, aim, evasion, reactions and intelligence), as for now you can set them in the .npc file between 1-5, i'd like to edit the code to increase them to maybe 1-20 to make an Npc more dangerous.

Can you help me with this?

im pretty sure that stuff is hard coded, and if you should have more dangerous npc's out of this i think it would need more then just edit some numbers, but also increase the damage output and more coding to it

Asgarath83 likes this
Link to comment

im pretty sure that stuff is hard coded, and if you should have more dangerous npc's out of this i think it would need more then just edit some numbers, but also increase the damage output and more coding to it

Totally agree. change a value not change that. you need to manually code all effects of every parameters.

(by 5 to 20 is a looong work >.< )

 

@@MGummelt sorry if i disturb again, but i have just a last question: there is some way to overcap the graphical engine limit related to MD3 and GLM? i mean that game crash if a mesh of MD3 model contain more of 1000 vertexes. and also for GLM models same things. also, if a model of character is too many complex or highpoly people get message "ran out of transform ghouls 2 space adjust mini heap size." what mean exactly this error and how is possible to overcap this limit into the code?

Link to comment

Hi, @@MGummelt, I commented out my attempt, and only added what you provided; that being the qboolean at the top of the file:

void WP_SaberDrop( gentity_t *self, gentity_t *saber );
qboolean WP_SaberLose( gentity_t *self, vec3_t throwDir );
void WP_SaberReturn( gentity_t *self, gentity_t *saber );
void WP_SaberBlock( gentity_t *saber, vec3_t hitloc, qboolean missleBlock );
void WP_SaberBlockNonRandom( gentity_t *self, vec3_t hitloc, qboolean missileBlock );
void ForceThrow( gentity_t *self, qboolean pull );
qboolean WP_ForcePowerAvailable( gentity_t *self, forcePowers_t forcePower, int overrideAmt );
void WP_ForcePowerDrain( gentity_t *self, forcePowers_t forcePower, int overrideAmt );
qboolean WP_SaberParry(gentity_t *victim, gentity_t *attacker);

Piece of code at applydamage bit:

if (victim->client && (victim->client->NPC_class == CLASS_GALAKMECH || victim->client->NPC_class == CLASS_SHADOWTROOPER))
				{
					WP_SaberParry(victim, attacker);
					return didDamage;
				}

The error I get is Error: identifier "attacker" is undefined.

 

So what I've done to get this to compile is add *attacker to gentity_t here:

qboolean WP_SaberApplyDamage(gentity_t *ent, float baseDamage, int baseDFlags, qboolean brokenParry)
{
	qboolean	didDamage = qfalse;
	gentity_t	*victim;
        gentity_t       *attacker;
	int			dFlags = baseDFlags;
	float		maxDmg;

It doesn't rebound of the shadowtrooper ingame anymore :( But... it definitely works with setting PM_setsabermove(), but I need to somehow implement an angle case so that it knows what anim to play. Sorry to bother you.

 

You don't need to create an attacker variable (it won't be initialized to anything - just random memory or NULL).  "ent" is the attacker in this case (the character who's swinging the lightsaber).  You can just pass "ent" in for the attacker.  Or initialize your attacker variable to be ent, like so:

gentity_t *attacker = ent;

 

That's all.

Link to comment

Hello, i have a question regarding NPC stats (aggression, move, aim, evasion, reactions and intelligence), as for now you can set them in the .npc file between 1-5, i'd like to edit the code to increase them to maybe 1-20 to make an Npc more dangerous.

Can you help me with this?

What is it you're trying to accomplish?  Do you want to make them more aggressive, move faster, aim better, evade more, react quicker and have more options available?  Or do you want more granularity?

 

Keep in mind that many of these values are checked in many different places in the AI code and if you're changing the scale of them, you'll have to change all the sites that check them.  Like stats.aggression - some actions check for a relatively low number, like just checking to see if they should attack at the given moment.  Others may check for a very high aggression (75-125 to go berzerk, for example).

 

So it depends on what you're trying to accomplish by "increasing them to 1-20".  If you just want to make NPCs more dangerous, increasing them in the .npc file is enough.  But if you are trying to change the scale of the range to add more granularity, you'll need to modify all the code that increments, decrements and checks those stats.

 

-Mike

Link to comment

@@MGummelt sorry if i disturb again, but i have just a last question: there is some way to overcap the graphical engine limit related to MD3 and GLM? i mean that game crash if a mesh of MD3 model contain more of 1000 vertexes. and also for GLM models same things. also, if a model of character is too many complex or highpoly people get message "ran out of transform ghouls 2 space adjust mini heap size." what mean exactly this error and how is possible to overcap this limit into the code?

 

Sorry, graphics were not my area in Jedi.  You'd have to ask James Monroe.

Link to comment

Stoiss, on 02 Mar 2017 - 2:08 PM, said:snapback.png

im pretty sure that stuff is hard coded, and if you should have more dangerous npc's out of this i think it would need more then just edit some numbers, but also increase the damage output and more coding to it

Totally agree. change a value not change that. you need to manually code all effects of every parameters.

(by 5 to 20 is a looong work >.< )

 

Actually, increasing those values will make them tougher enemies.  In fact, that's how I make the enemies more difficult in higher difficulty levels of the game (I hate when games just make the enemies have more health).  If you play on higher difficulty levels, we spawn tougher enemies with more abilities, more aggression and who are better at using them.

 

Look in NPC_Spawn.cpp for all references to the g_spskill cvar.  It's used to increase some of their stats like aim, speed, health, turning speed.  It's also checked all over the AI code to make the enemies smarter and faster.  So if you just want enemies more dangerous, play on the highest difficulty levels.  If you want them even more dangerous, use higher values in the .npc files (or add to their stats on load in NPC_Spawn - maybe based on difficulty level)

 

-Mike

Archangel35757 and Asgarath83 like this
Link to comment

This is an Example of what i edited in the SP code, but it doesn't make the NPC tougher or anything. 

 

//===AI STATS=====================================================================
if ( !parsingPlayer )
{
// aggression
if ( !Q_stricmp( token, "aggression" ) ) {
if ( COM_ParseInt( &p, &n ) ) {
SkipRestOfLine( &p );
continue;
}
if ( n < 1 || n > 5 ) { ---------------------------- I changed the normal value which is 1-5, to 1-9.
gi.Printf(  "bad %s in NPC '%s'\n", token, NPCName );
continue;
}
if ( NPC->NPC )
{
stats->aggression = n;
}
continue;
}

 

Link to comment

No, if I recall we didn't want to give designers the ability to access any cvar they wanted - that would just be chaos.  It would open up a bunch of features to them that we didn't intend, they didn't need and which they wouldn't entirely know the effects of.  And some would work in development (like cheats) but not release.  Instead if they needed a specific command to do something a cvar or console command could do, we wrote an ICARUS command for it.

 

However, I imagine something like this could fairly easily be written.  At least, someone could probably write a function to stuff a command to the console (like "\set g_sex f") or call Cvar_Set and Cvar_Get...

 

We actually did add support for it in OpenJK project for JA single player.  Not sure about JK2 SP. And pretty sure not for JAMP. (We still don't support jk2mp and probably never will because jk2mv exists)

Link to comment

Actually, the standard doesn't require that -- only for variables.

True. I think we did it anyway if for no other reason than knowing by looking at the declaration whether it was actually defined in that file or not.

Link to comment

This is an Example of what i edited in the SP code, but it doesn't make the NPC tougher or anything.

 

 

//===AI STATS=====================================================================

if ( !parsingPlayer )

{

// aggression

if ( !Q_stricmp( token, "aggression" ) ) {

if ( COM_ParseInt( &p, &n ) ) {

SkipRestOfLine( &p );

continue;

}

if ( n < 1 || n > 5 ) { ---------------------------- I changed the normal value which is 1-5, to 1-9.

gi.Printf( "bad %s in NPC '%s'\n", token, NPCName );

continue;

}

if ( NPC->NPC )

{

stats->aggression = n;

}

continue;

}

 

Yeah that won't do anything but allow you to set a higher aggression stat in the .npc file.

 

Also, if I recall, I think the aggression stat is just used to set the initial aggression of an AI? The actual, current aggression goes up and down dynamically as they detect enemies, fight and take damage, I think.

GamingPrince83 likes this
Link to comment

@@Asgarath83, make LOD's for your models and you'll never see the mini heap size error ever again. The 1000 vertex count per object is not a big deal, at all, far from it. You can have 32 parts to a model with 1000 vertex's each, that's a 32k vertex count for 1 model which is VERY high. Even games made for 8th generation game consoles don't have that much detail for a character model so the limit is actually quite high.

 

To put that into perspective a game like The Force Unleashed the Darth Maul model which I'm sure you would agree is much higher quality than anything in the base JA game has less than 6k vertex's and you want to be able to put models in game that have more than 32k.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...