Noodle Posted April 1, 2015 Posted April 1, 2015 Hi guys, time for another question. I've recently been playing around with NPCs to see if I can add some new enemies to the game for my Singleplayer maps and I thought it would be nice to make some experiments with the Droideka vehicle. First thing I did was create a new NPC with the CLASS_MARK1 because the vehicle weapons seems to now work in Singleplayer (Does anybody know why and if there's anyway to fix it?) and a simple script so that the deka wouldn't roll, just walk without the shield. It did work, but for some reason it shoots from its head instead of its hands. Pic related: . Since I'm a man of science, I tried to see how did the Vehicle NPC shoot in Singleplayer, and I noticed that it did shoot from its arms with the "droideka_laser" weapon found in the vehicles/weapons folder of the pk3 but it shoots backwards. Pic related again: So question time: - Does anybody know if I can make an NPC have a modded vehicle's weapon like the droideka's? How? - Is there any way to make it shoot not-backwards?- Why does the CLASS_MARK1 NPC (also tried with stormtrooper, ATST and many other classes) shoot from its head instead of the hands? Is there any way I can fix it? How? Lancelot likes this
mrwonko Posted April 1, 2015 Posted April 1, 2015 Tags. Looks like they need to be adjusted/added. Take a look at the mark1 model - what's the name of its muzzle tag? You need to change the Droideka model, adding the missing tag. Noodle likes this
Noodle Posted April 1, 2015 Author Posted April 1, 2015 Tags. Looks like they need to be adjusted/added. Take a look at the mark1 model - what's the name of its muzzle tag? You need to change the Droideka model, adding the missing tag. Sounds like a good idea, though I'm new at the whole moding thing. What software do I need to do that? The droideka has 4 muzzle tags named Muzzle1, muzzle2,muzzle3, and muzzle4. The mark1 has no muzzle tag, but a bunch of tags named 'flash' that are at both arms. Still, when I changed the NPC class to stormtrooper, or to ATST, it had the same problem. Even with a blaster rifle it kept shooting from the face. If the problem is still indeed a tag, how can I add them?
Circa Posted April 1, 2015 Posted April 1, 2015 I think I fixed it in my prequel conversion mod, but I can't remember if I did or how I did it. https://jkhub.org/files/file/1548-prequel-conversion-mod/ Noodle likes this
Noodle Posted April 1, 2015 Author Posted April 1, 2015 (edited) I think I fixed it in my prequel conversion mod, but I can't remember if I did or how I did it. I am impressed! How did I never hear of this mod before? The Droideka worked quite well, only thing that seemed buggy was that sometimes this happened: Edit: I think the solution you had was to give the Deka an emplaced gun and change the effects so it looked like the vehicle's custom weapon. The only downside is that now the emplaced gun fires the droideka lasers. Edited April 1, 2015 by Noodle Circa likes this
Serenity937 Posted April 1, 2015 Posted April 1, 2015 EoC also supports Droideka an example of the droideka in SP and MP can be seen here https://www.youtube.com/watch?v=nqQx1rtjKxU you can get it here. http://www.moddb.com/mods/serenitysabersystems Circa likes this
Circa Posted April 1, 2015 Posted April 1, 2015 I am impressed! How did I never hear of this mod before? The Droideka worked quite well, only thing that seemed buggy was that sometimes this happened: Edit: I think the solution you had was to give the Deka an emplaced gun and change the effects so it looked like the vehicle's custom weapon. The only downside is that now the emplaced gun fires the droideka lasers. Yeah, the only real way of fixing it completely is to add a new weapon for it to use, via code. Serenity937 and Noodle like this
Noodle Posted April 1, 2015 Author Posted April 1, 2015 Yeah, the only real way of fixing it completely is to add a new weapon for it to use, via code. Thanks for the help! I'll stick to your solution since I have no coding knowledge.
Solution Serenity937 Posted April 1, 2015 Solution Posted April 1, 2015 Add a New NPC class with individual behaviour ,code in the animations, .dat file additions in code and file x2 different ways (MP Differes from SP),effects code. Its was quite a fair bit of work. switch( team ) {// not sure if TEAM_ENEMY is appropriate here, I think I should be using NPC_class to check for behavior - dmv case TEAM_ENEMY: // special cases for enemy droids switch( NPC->client->NPC_class) { case CLASS_ATST: NPC_BehaviorSet_ATST( bState ); return; case CLASS_PROBE: NPC_BehaviorSet_ImperialProbe(bState); return; case CLASS_DROIDEKA: NPC_BehaviorSet_DROIDEKA(bState); return; case CLASS_REMOTE: NPC_BehaviorSet_Remote( bState ); return; The behaviour state set up /* ------------------------- NPC_BehaviorSet_DROIDEKA ------------------------- */ void NPC_BehaviorSet_DROIDEKA( int bState ) { switch( bState ) { case BS_STAND_GUARD: case BS_DEFAULT: case BS_PATROL: case BS_STAND_AND_SHOOT: case BS_HUNT_AND_KILL: NPC_BSDROIDEKA_Default(); break; default: NPC_BehaviorSet_Default( bState ); break; } } and the i made a whole new NPC AI set up for this bad boy void G_DROIDEKACheckPain( gentity_t *self, gentity_t *other, const vec3_t point, int damage, int mod,int hitLoc ) { if ( rand() & 1 ) { G_SoundOnEnt( self, CHAN_LESS_ATTEN, "sound/chars/droideka/pain25" ); } else { G_SoundOnEnt( self, CHAN_LESS_ATTEN, "sound/chars/droideka/pain100" ); } } /* ------------------------- NPC_DROIDEKA_Pain ------------------------- */ void NPC_DROIDEKA_Pain( gentity_t *self, gentity_t *inflictor, gentity_t *other, const vec3_t point, int damage, int mod,int hitLoc ) { G_DROIDEKACheckPain( self, other, point, damage, mod, hitLoc ); NPC_Pain( self, inflictor, other, point, damage, mod ); } /* ------------------------- DROIDEKA_Hunt -------------------------` */ void DROIDEKA_Hunt( qboolean visible, qboolean advance ) { //If we're not supposed to stand still, pursue the player if ( NPCInfo->standTime < level.time ) { //Move towards our goal NPCInfo->goalEntity = NPC->enemy; NPCInfo->goalRadius = 12; NPC_MoveToGoal( qtrue ); } if ( NPCInfo->goalEntity == NULL ) {//hunt NPCInfo->goalEntity = NPC->enemy; } NPCInfo->combatMove = qtrue; NPC_MoveToGoal( qtrue ); NPC_FaceEnemy(); //Update our angles regardless NPC_UpdateAngles( qtrue, qtrue ); } /* ------------------------- DROIDEKA_Ranged ------------------------- */ void DROIDEKA_Ranged( qboolean visible, qboolean advance, qboolean altAttack ) { if ( TIMER_Done( NPC, "atkDelay" ) && visible ) // Attack? { TIMER_Set( NPC, "atkDelay", Q_irand( 500, 1000 ) ); ucmd.buttons |= BUTTON_ATTACK; } if ( NPCInfo->scriptFlags & SCF_CHASE_ENEMIES ) { DROIDEKA_Hunt( visible, advance ); } } /* ------------------------- DROIDEKA_Attack ------------------------- */ void DROIDEKA_Attack( void ) { qboolean altAttack=qfalse; // Rate our distance to the target, and our visibilty float distance = (int) DistanceHorizontalSquared( NPC->currentOrigin, NPC->enemy->currentOrigin ); distance_e distRate = ( distance > MIN_MELEE_RANGE_SQR ) ? DIST_LONG : DIST_MELEE; qboolean visible = NPC_ClearLOS( NPC->enemy ); qboolean advance = (qboolean)(distance > MIN_DISTANCE_SQR); if ( NPC_CheckEnemyExt() == qfalse ) { NPC->enemy = NULL; DROIDEKA_Hunt( visible, advance ); return; } NPC_FaceEnemy( qtrue ); // If we cannot see our target, move to see it if ( visible == qfalse ) { if ( NPCInfo->scriptFlags & SCF_CHASE_ENEMIES ) { DROIDEKA_Hunt( visible, advance ); return; } } // Decide what type of attack to do //If we're too far away, then keep walking forward if ( distRate != DIST_MELEE ) { DROIDEKA_Hunt( visible, advance ); return; } NPC_FaceEnemy( qtrue ); DROIDEKA_Ranged( visible, advance,altAttack ); } /* ------------------------- DROIDEKA_Patrol ------------------------- */ void DROIDEKA_Patrol( void ) { if ( NPC_CheckPlayerTeamStealth() ) { NPC_UpdateAngles( qtrue, qtrue ); return; } //If we have somewhere to go, then do that if (!NPC->enemy) { if ( UpdateGoal() ) { ucmd.buttons |= BUTTON_WALKING; NPC_MoveToGoal( qtrue ); NPC_UpdateAngles( qtrue, qtrue ); } } } /* ------------------------- DROIDEKA_Idle ------------------------- */ void DROIDEKA_Idle( void ) { BubbleShield_Update(); } /* ------------------------- NPC_BSDROIDEKA_Default ------------------------- */ void NPC_BSDROIDEKA_Default( void ) { if ( NPC->enemy ) { if( (NPCInfo->scriptFlags & SCF_CHASE_ENEMIES) ) { NPCInfo->goalEntity = NPC->enemy; } DROIDEKA_Attack(); } else if ( NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES ) { DROIDEKA_Patrol(); } else { DROIDEKA_Idle(); } } as a result ,you can script the decca easily. Did the same with SBD also. you can download examples of the code and build your own version http://www.moddb.com/mods/serenitysabersystems/addons/serenityjedienginesdk NumberWan and Noodle like this
Noodle Posted April 1, 2015 Author Posted April 1, 2015 Add a New NPC class with individual behaviour ,code in the animations, .dat file additions in code and file x2 different ways (MP Differes from SP),effects code. Its was quite a fair bit of work. switch( team ) {// not sure if TEAM_ENEMY is appropriate here, I think I should be using NPC_class to check for behavior - dmv case TEAM_ENEMY: // special cases for enemy droids switch( NPC->client->NPC_class) { case CLASS_ATST: NPC_BehaviorSet_ATST( bState ); return; case CLASS_PROBE: NPC_BehaviorSet_ImperialProbe(bState); return; case CLASS_DROIDEKA: NPC_BehaviorSet_DROIDEKA(bState); return; case CLASS_REMOTE: NPC_BehaviorSet_Remote( bState ); return; The behaviour state set up /* ------------------------- NPC_BehaviorSet_DROIDEKA ------------------------- */ void NPC_BehaviorSet_DROIDEKA( int bState ) { switch( bState ) { case BS_STAND_GUARD: case BS_DEFAULT: case BS_PATROL: case BS_STAND_AND_SHOOT: case BS_HUNT_AND_KILL: NPC_BSDROIDEKA_Default(); break; default: NPC_BehaviorSet_Default( bState ); break; } } and the i made a whole new NPC AI set up for this bad boy void G_DROIDEKACheckPain( gentity_t *self, gentity_t *other, const vec3_t point, int damage, int mod,int hitLoc ) { if ( rand() & 1 ) { G_SoundOnEnt( self, CHAN_LESS_ATTEN, "sound/chars/droideka/pain25" ); } else { G_SoundOnEnt( self, CHAN_LESS_ATTEN, "sound/chars/droideka/pain100" ); } } /* ------------------------- NPC_DROIDEKA_Pain ------------------------- */ void NPC_DROIDEKA_Pain( gentity_t *self, gentity_t *inflictor, gentity_t *other, const vec3_t point, int damage, int mod,int hitLoc ) { G_DROIDEKACheckPain( self, other, point, damage, mod, hitLoc ); NPC_Pain( self, inflictor, other, point, damage, mod ); } /* ------------------------- DROIDEKA_Hunt -------------------------` */ void DROIDEKA_Hunt( qboolean visible, qboolean advance ) { //If we're not supposed to stand still, pursue the player if ( NPCInfo->standTime < level.time ) { //Move towards our goal NPCInfo->goalEntity = NPC->enemy; NPCInfo->goalRadius = 12; NPC_MoveToGoal( qtrue ); } if ( NPCInfo->goalEntity == NULL ) {//hunt NPCInfo->goalEntity = NPC->enemy; } NPCInfo->combatMove = qtrue; NPC_MoveToGoal( qtrue ); NPC_FaceEnemy(); //Update our angles regardless NPC_UpdateAngles( qtrue, qtrue ); } /* ------------------------- DROIDEKA_Ranged ------------------------- */ void DROIDEKA_Ranged( qboolean visible, qboolean advance, qboolean altAttack ) { if ( TIMER_Done( NPC, "atkDelay" ) && visible ) // Attack? { TIMER_Set( NPC, "atkDelay", Q_irand( 500, 1000 ) ); ucmd.buttons |= BUTTON_ATTACK; } if ( NPCInfo->scriptFlags & SCF_CHASE_ENEMIES ) { DROIDEKA_Hunt( visible, advance ); } } /* ------------------------- DROIDEKA_Attack ------------------------- */ void DROIDEKA_Attack( void ) { qboolean altAttack=qfalse; // Rate our distance to the target, and our visibilty float distance = (int) DistanceHorizontalSquared( NPC->currentOrigin, NPC->enemy->currentOrigin ); distance_e distRate = ( distance > MIN_MELEE_RANGE_SQR ) ? DIST_LONG : DIST_MELEE; qboolean visible = NPC_ClearLOS( NPC->enemy ); qboolean advance = (qboolean)(distance > MIN_DISTANCE_SQR); if ( NPC_CheckEnemyExt() == qfalse ) { NPC->enemy = NULL; DROIDEKA_Hunt( visible, advance ); return; } NPC_FaceEnemy( qtrue ); // If we cannot see our target, move to see it if ( visible == qfalse ) { if ( NPCInfo->scriptFlags & SCF_CHASE_ENEMIES ) { DROIDEKA_Hunt( visible, advance ); return; } } // Decide what type of attack to do //If we're too far away, then keep walking forward if ( distRate != DIST_MELEE ) { DROIDEKA_Hunt( visible, advance ); return; } NPC_FaceEnemy( qtrue ); DROIDEKA_Ranged( visible, advance,altAttack ); } /* ------------------------- DROIDEKA_Patrol ------------------------- */ void DROIDEKA_Patrol( void ) { if ( NPC_CheckPlayerTeamStealth() ) { NPC_UpdateAngles( qtrue, qtrue ); return; } //If we have somewhere to go, then do that if (!NPC->enemy) { if ( UpdateGoal() ) { ucmd.buttons |= BUTTON_WALKING; NPC_MoveToGoal( qtrue ); NPC_UpdateAngles( qtrue, qtrue ); } } } /* ------------------------- DROIDEKA_Idle ------------------------- */ void DROIDEKA_Idle( void ) { BubbleShield_Update(); } /* ------------------------- NPC_BSDROIDEKA_Default ------------------------- */ void NPC_BSDROIDEKA_Default( void ) { if ( NPC->enemy ) { if( (NPCInfo->scriptFlags & SCF_CHASE_ENEMIES) ) { NPCInfo->goalEntity = NPC->enemy; } DROIDEKA_Attack(); } else if ( NPCInfo->scriptFlags & SCF_LOOK_FOR_ENEMIES ) { DROIDEKA_Patrol(); } else { DROIDEKA_Idle(); } } as a result ,you can script the decca easily. Did the same with SBD also. you can download examples of the code and build your own version http://www.moddb.com/mods/serenitysabersystems/addons/serenityjedienginesdk I'm impressed! I guess now its a good time to learn a bit of coding.
Serenity937 Posted April 1, 2015 Posted April 1, 2015 Honestly mate! Its worth trying your hand at coding. Think small and start small,Set yourself a realistic goal,something small and you wont get overwhelmed at the start.Stay on one topic ,Animations is where i started. swapping them about. For your purpose i would select Class system. Get the openjk code (Its the best,stable and nice and clean). Then learn everything by searching through the code for 1 class type i suggest CLASS_R2D2. its a simple set up not too different to how you might want a decca to act. Unless your a genius i suggest doing a simple search for tutorials and also other released SDK ,s to learn from.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now