Porting Jaymod shotgun to RTCW


(wolfETplayer) #1

Hello! I’m trying to port shotgun from Jaymod (Enemy Territory) to Return to Castle Wolfenstein Single Player.

I successfully ported the model. But there is major issues with the reloading animations.

I know that shotgun from Jaymod is using unique reloading mechanic, which is implemented via source code. Thankfully author of Jaymod uploaded the source code on GitHub.

So, reload begin procedure overrides for shotgun like this:

       // Jaymod
	if (weapon == WP_M97) {
		PM_BeginM97Reload();
		return;
	}

Same goes for the reload finish:

static void PM_FinishWeaponReload( void ) {

		// Jaymod Overrides for Shotgun
		if( pm->ps->weapon == WP_M97 ) {
			PM_M97Reload();
			return;
		}


Here is the reload function from Jaymod source code:

=================
PM_BeginM97Reload
=================
*/
void PM_BeginM97Reload( void )
{
	int anim;

	// Choose which first person animation to play
	if ( pm->ps->ammoclip[BG_FindClipForWeapon(WP_M97)] == 0 ) {
		anim = WEAP_ALTSWITCHFROM;
		PM_AddEvent( EV_M97_PUMP );
		pm->ps->weaponTime += M97_RLT_ALTSWITCHFROM;
		pm->ps->holdable[HOLDABLE_M97] = M97_RELOADING_BEGIN_PUMP;

        // 3rd person
	    if( pm->ps->eFlags & EF_PRONE ) {
		    BG_AnimScriptEvent( pm->ps, pm->character->animModelInfo, ANIM_ET_RELOADPRONE_SG1, qfalse, qtrue );
	    } else {
		    BG_AnimScriptEvent( pm->ps, pm->character->animModelInfo, ANIM_ET_RELOAD_SG1, qfalse, qtrue );
	    }
	} else {
		anim = WEAP_RELOAD1;
		pm->ps->weaponTime += M97_RLT_RELOAD1;
		pm->ps->holdable[HOLDABLE_M97] = M97_RELOADING_BEGIN;
	}

	// Play it
	PM_StartWeaponAnim(anim);

	// Initialize override
	pm->pmext->m97reloadInterrupt = qfalse;

	// Set state to reloading
	pm->ps->weaponstate = WEAPON_RELOADING;

}

void PM_M97Reload() {

	// Transition from shell + pump
	if( pm->ps->holdable[HOLDABLE_M97] == M97_RELOADING_BEGIN_PUMP ) {

		// Load a shell
		PM_ReloadClip( WP_M97 );

		// Branch depending on if we need another shell or not
		if (!pm->ps->ammo[BG_FindAmmoForWeapon(WP_M97)] || pm->pmext->m97reloadInterrupt) {
			// Break back to ready position
			PM_StartWeaponAnim(WEAP_DROP2);
			pm->ps->weaponTime += M97_RLT_DROP2;
			pm->ps->weaponstate = WEAPON_READY;
		} else {
			// Transition to load another shell
			PM_StartWeaponAnim(WEAP_ALTSWITCHTO);
			pm->ps->weaponTime += M97_RLT_ALTSWITCHTO;
			pm->ps->holdable[HOLDABLE_M97] = M97_RELOADING_AFTER_PUMP;
		}
		return;
	}

	// Load a shell on most states
	if (pm->ps->holdable[HOLDABLE_M97] != M97_RELOADING_AFTER_PUMP && pm->ps->holdable[HOLDABLE_M97] != M97_RELOADING_BEGIN) {
		PM_ReloadClip( WP_M97 );
	}

	// Override - but must load at least one shell!
	if( pm->pmext->m97reloadInterrupt && pm->ps->holdable[HOLDABLE_M97] != M97_RELOADING_BEGIN ) {
		PM_StartWeaponAnim(WEAP_RELOAD3);
		pm->ps->weaponTime += M97_RLT_RELOAD3;
		pm->ps->weaponstate = WEAPON_READY;
		return;
	}

	// If clip isn't full, load another shell
	if( pm->ps->ammoclip[WP_M97] < GetAmmoTableData(WP_M97)->maxclip && pm->ps->ammo[BG_FindAmmoForWeapon(WP_M97)] ) {
		PM_AddEvent( EV_FILL_CLIP );
		PM_StartWeaponAnim(WEAP_RELOAD2);

		// Delay time - support quick reload
		if (pm->skill[SK_LIGHT_WEAPONS] >= 2)
			pm->ps->weaponTime += M97_RLT_RELOAD2_QUICK;
		else
			pm->ps->weaponTime += M97_RLT_RELOAD2;

		pm->ps->holdable[HOLDABLE_M97] = M97_RELOADING_LOOP;

		// 3rd person
		if( pm->ps->eFlags & EF_PRONE ) {
			BG_AnimScriptEvent( pm->ps, pm->character->animModelInfo, ANIM_ET_RELOADPRONE_SG2, qfalse, qtrue );
		} else {
			BG_AnimScriptEvent( pm->ps, pm->character->animModelInfo, ANIM_ET_RELOAD_SG2, qfalse, qtrue );
		}
	} else {
		PM_StartWeaponAnim(WEAP_RELOAD3);			// From loop to read
		pm->ps->weaponTime += M97_RLT_RELOAD3;
		pm->ps->weaponstate = WEAPON_READY;
	}
}

Here is my adapted version for RTCW(I removed prone,skill features):

/*
=================
PM_BeginM97Reload
=================
*/
void PM_BeginM97Reload( void )
{
	int anim;

	// Choose which first person animation to play 
	if ( pm->ps->ammoclip[BG_FindClipForWeapon(WP_M97)] == 0 ) {
		anim = WEAP_ALTSWITCHFROM;
		PM_AddEvent( EV_M97_PUMP );
		pm->ps->weaponTime += M97_RLT_ALTSWITCHFROM;
		pm->ps->holdable[HI_M97] = M97_RELOADING_BEGIN_PUMP;

	} else {
		anim = WEAP_RELOAD1;
		pm->ps->weaponTime += M97_RLT_RELOAD1;
		pm->ps->holdable[HI_M97] = M97_RELOADING_BEGIN;
	}

	// Play it
	PM_StartWeaponAnim(anim);

	// Initialize override
	pm->ps->m97reloadInterrupt = qfalse;

	// Set state to reloading
	pm->ps->weaponstate = WEAPON_RELOADING;

}
// Jaymod
void PM_M97Reload() {

	// Transition from shell + pump
	if( pm->ps->holdable[HI_M97] == M97_RELOADING_BEGIN_PUMP ) {

		// Load a shell
		PM_ReloadClip( WP_M97 );

		// Branch depending on if we need another shell or not
		if (!pm->ps->ammo[BG_FindAmmoForWeapon(WP_M97)] || pm->ps->m97reloadInterrupt) {
			// Break back to ready position
			PM_StartWeaponAnim(WEAP_DROP2);
			pm->ps->weaponTime += M97_RLT_DROP2;
			pm->ps->weaponstate = WEAPON_READY;
		} else {
			// Transition to load another shell
			PM_StartWeaponAnim(WEAP_ALTSWITCHTO);
			pm->ps->weaponTime += M97_RLT_ALTSWITCHTO;
			pm->ps->holdable[HI_M97] = M97_RELOADING_AFTER_PUMP;
		}
		return;
	}

	// Load a shell on most states
	if (pm->ps->holdable[HI_M97] != M97_RELOADING_AFTER_PUMP && pm->ps->holdable[HI_M97] != M97_RELOADING_BEGIN) {
		PM_ReloadClip( WP_M97 );
	}

	// Override - but must load at least one shell!
	if( pm->ps->m97reloadInterrupt && pm->ps->holdable[HI_M97] != M97_RELOADING_BEGIN ) {
		PM_StartWeaponAnim(WEAP_RELOAD3);
		pm->ps->weaponTime += M97_RLT_RELOAD3;
		pm->ps->weaponstate = WEAPON_READY;
		return;
	}

	// If clip isn't full, load another shell
	if( pm->ps->ammoclip[WP_M97] < ammoTable[WP_M97].maxclip && pm->ps->ammo[BG_FindAmmoForWeapon(WP_M97)] ) {
		PM_AddEvent( EV_FILL_CLIP );
		PM_StartWeaponAnim(WEAP_RELOAD2);
	pm->ps->weaponTime += M97_RLT_RELOAD2;
	pm->ps->holdable[HI_M97] = M97_RELOADING_LOOP;
} else {
	PM_StartWeaponAnim(WEAP_RELOAD3);			// From loop to read
	pm->ps->weaponTime += M97_RLT_RELOAD3;
	pm->ps->weaponstate = WEAPON_READY;
}
}


Here is what happening in the game:

//youtu.be/RNk6Oz6T50c

So it seems reloading animation just fails to loop. Don’t really know what to do. Trying to make it work for 2 weeks already.

Here is link for jaymod source code:


And link for my mod:

I wonder if anyone can help me here. Someone familiar with the coding. If anyone will make this work, I’ll find a way to repay you.


(ryven) #2

I think i got it fixed. Do you prefer me pushing a patch to your repo or just post all details here? In short there are couple of things that are missing from the original code, and one issue with storing persistent value in the playerstate instead of dedicated structure, which causes undesired effects.

This weapon is pretty cool though, enjoyed playing with it, seems a bit op but it depends on which level you could receive it, is there particular reason why you set 5 bullets in the clip instead of 6 like in the jaymod?

//youtu.be/b6ukQI8bQaQ


(ronboy) #3

[QUOTE=ryven;568681]I think i got it fixed. Do you prefer me pushing a patch to your repo or just post all details here? In short there are couple of things that are missing from the original code, and one issue with storing persistent value in the playerstate instead of dedicated structure, which causes undesired effects.

This weapon is pretty cool though, enjoyed playing with it, seems a bit op but it depends on which level you could receive it, is there particular reason why you set 5 bullets in the clip instead of 6 like in the jaymod?
[/QUOTE]

Nice work on getting the Jaymod shotgun to work in RealRTCW, ryven. I’m surprised that your mission didn’t fail though, because village2 is a mandatory stealth level.


(wolfETplayer) #4

[QUOTE=ryven;568681]I think i got it fixed. Do you prefer me pushing a patch to your repo or just post all details here? In short there are couple of things that are missing from the original code, and one issue with storing persistent value in the playerstate instead of dedicated structure, which causes undesired effects.

This weapon is pretty cool though, enjoyed playing with it, seems a bit op but it depends on which level you could receive it, is there particular reason why you set 5 bullets in the clip instead of 6 like in the jaymod?

//youtu.be/b6ukQI8bQaQ
[/QUOTE]

Wow! Push it to the repo please.
Hm, so replacement of “pmext” to playerstate has broken the whole reloading function?
Max capacity,damage etc. is a subjects to change.

Thank you. Really appreciate your help. You will be credited.

Did you received my PM btw?


(ryven) #5

Not really, it broke the animations, but main reason reloading didn’t work was that you didn’t include the if block:

   
if ( pm->ps->weaponstate == WEAPON_RELOADING ) {
        PM_FinishWeaponReload();
[B]
        // This will happen for chained shotgun 
        if (pm->ps->weaponTime > 0) {
                return;
        }[/B]
}

which should keep reloading 1 bullet at a time, till you interrupt it or ammo ends. Otherwise the weaponstate changes to ready, and it will stop the reloading and all consequent animations.

It’s just that in reality it also has 6 bullets, so the main reason for the change was puzzling me, but i have no problems changing clip size in favor of balance. Though there are other ways to achieve that:d

Don’t worry about it :wink: i miss mod editing questions in this section, so i am happy to help if i can!

If you go enough fast you can avoid failing before soldiers will hit the alarm button :d And it’s much easier to achieve that with shotgun btw.


(wolfETplayer) #6

[QUOTE=ryven;568703]Not really, it broke the animations, but main reason reloading didn’t work was that you didn’t include the if block:

   
if ( pm->ps->weaponstate == WEAPON_RELOADING ) {
        PM_FinishWeaponReload();
[B]
        // This will happen for chained shotgun 
        if (pm->ps->weaponTime > 0) {
                return;
        }[/B]
}

which should keep reloading 1 bullet at a time, till you interrupt it or ammo ends. Otherwise the weaponstate changes to ready, and it will stop the reloading and all consequent animations.

It’s just that in reality it also has 6 bullets, so the main reason for the change was puzzling me, but i have no problems changing clip size in favor of balance. Though there are other ways to achieve that:d

Don’t worry about it :wink: i miss mod editing questions in this section, so i am happy to help if i can!
[/QUOTE]

Got it! Thanks again!