-
Posts
123 -
Joined
-
Last visited
Content Type
Profiles
News Articles
Tutorials
Forums
Downloads
Posts posted by Serenity937
-
-
Some Early developments
Darth Sion likes this -
When this releases, can I install this as a fresh download/install or do I need the files from "Evolution of Combat III" for it to work properly?
No you don't need EoCIII
Only JKA installed and patched is required
Darth Sion likes this -
Looking good. More screens before release tho would be diddly-daddly delightful.
Have you checked out my video logs?
Darth Sion and Bek like this -
will this be supported for MAC?
Sorry ,unless someone else want to do it.no
Hi guys
Hopefully you had a chance to see what we are trying to achieve .
1. Uniformity .
It always annoyed me that single player and multi player combat systems were different from each other. I understand why there different but i never liked it anyway.
The first task with the mod is to get mp/sp exactly the same (or a near as dammit) taking into account that 1 is played with 0 latency and the other could be 80-120 ping for some people.
2. Inspirations
My first and most important inspiration is the films.If you truly want to understand EoC sabersystem then you have to really,really watch the sabercombat.
https://www.youtube.com/watch?v=lN7dkSIgYgE
Look how quigon Blocks,Dodges and moves his legs.The pace of attack and defence.He slaps and kicks his enemys "NO SILLY JUMPING ABOUT"
This is where the message is often lost.People compare the sabersystem to base,ojp Moviebattles etc etc.
It should (but sadly never has been) be compared to the movies style.
It contain elements and ideas from all mods,as all mods contain elements from the movies.
My second inspiration is The mods themselves.
Like everybody else i played all the popular mods,but in many cases i found them unbalanced or unfair.
Im not going to name any mods here because i dont want to start any pointless debate about opinions.
However ,In the early days some mods came out and were fantastic but as time went on they got updated and changed and on the way they lost something and it became more about Points and bars on the screen.People look to see the block point bar on the screen and can measure from there BP when to go for a kill.This is predictable and repetitive. It leaves little to the imagination and make sabercombat a simple routing that is followed to the letter or you fail.
I understand its "All about balance" so i decided to go back to basics (stawars basics ,whatever that means!).
Lets stick to sabercombat for now ill talk about guns later.I was in the British army for 18 years so i count myself as a bit of an authority on combat in general .
The sabersystem is built to allow much more freedom of movement.Im not going to talk code here but i did it by chaining and splicing lots of animations code in the sabersystem code.
I have not "AND NEVER WILL" write a tutorial for the sabersystem. I have made a video to get people started
But after that it is up to people to develop there own style- "Feel the force flowing through you".........Who said that?????
The sabersystem in mp and sp is almost identical so practice in the training room with tavion.
Some basic tips.
walking in close saber contact will reduce the amount of force used to block some types of attack .
Accurate blocking will tire your opponent quickly
Use of slaps and kicks in close combat is advised to stun your enemy and create a opening for attack.
Crouch or meditate to regain your forcepowers at x2 speed
Dont let your force powers drop below 25 fp in saber combat, blocking lightning can be very difficult at close range as close lightning now inflicts more damage and costs more to block .Warning Bots and Npc,s can see if your tired or low on fp by your animations and will strike harder if they get a chance.
Im personally a singleplayer fan more than Multiplayer and i can tell you this.If you like Mp sabersystem/anims and A.I then you going to love using the same sabersystem combat system anims etc etc in singleplayer.
Im especially proud of the A.I in sp and spent months on end building there combat.They have about 15 more animations than the player gets.I did this on purpose so they are unpredictable with the animations and can be very hard to kill in some cases.
I made stormtroopers and Imp soldiers relatively hard.They are a well trained army in weapon combat and unarmed combat.They will kick your ass if you get close,they may punch/ kick or butt stroke you with there weapon.
Saber users come in varying difficulty .But there are no un-experianced sith/Jedi in the field of combat. So dont expect them to be easy after they have years of training and experience,And of course if you face Desann or yoda or any "Master" then you can expect megga aggression, Very High speed combat and there force power ability's are Way better than yours...Trust me.If you play sp and spawn yoda in game to help you.Just watch him Kicking ass."HE IS AWESOME TO WATCH".He has his own full animations and seperate saberstyles too.
This is a quote from another post but i wanted to add it here so people can get the info.
OK guys ...Flame on :winkthumb:Asgarath83, Darth Sion, JAWSFreelao and 2 others like this -
Hi mate
The crashing problem you speak of is something that plagued EoCIII.
I spent an absolute age trying to find what caused the crash and i also came to the conclusion that a gunner bot is the cause.
From my side i can say this.I went through the code gunner class system with a fine tooth comb, almost to the point of totally rebuilding the gunner class system.
And can say that there is not 1 gunner bot that "does something" code related that causes the crash.Not 1 bot does something different from another gunner bot that could cause the crash.If this was not the case it would mean every gunner bot crashes the mod when they do whatever it is that is causing the crash.
This leads me to believe that there is something in the Botfiles themselves.
I am willing to bet if you check every single .JKB bot file you will find one with an error like this.
GeneralBotInfo { reflex 500 accuracy 1 turnspeed 0.01 turnspeed_combat 0.05 maxturn 360 perfectaim 1 chatability 1 chatfrequency 3 hatelevel 3 camper 0 saberspecialist 0 forceinfo 7-2-000000000000000000 }}
Now i don't expect you to check and read and correct every single bot .jkb file. Thats my fault.But if you do want to stop this crash to screen when a certain gunner bot either spawns in or dies or fires a specific weapon.
Thats where i would start
I do believe this happens when the code reads a certain part of the .jkb file....but i could be wrong.
Hopefully this might help.
and sorry for the error that i never found
Darth Sion likes this -
I will admit this is impressive. No doubt. BUT, I will be more impressed when some of my skins show up in trailers closer to release. ;D
Want to add a skin to the class system in EoCIV ? No problem PM me and ill add it,build how you wish saber sith/jedi/weapons i can add any personal class.In EoC i also added a class building system but only for gunners.In EoC jedi are jedi,sith are sith.You can select force powers but restricted to saber only.Gunners get a start weapon then after that you have to kill some one and take there weapon if you want one. "ITS STAR WARS not STAR FREE FOR ALL" so no weapons lying on maps in mp or sp.
Jeff, JAWSFreelao and Rayce like this -
Here is a nice review people might want to see.
Credit for the good review should also go to stoiss for his massive,excellent effort in making the sabersystem in EoCIII for EoC 1 and 2 also.Even though he no longer works on EoC.His contributions to EoC will live on.
Respect to my friend stoiss.
Asgarath83, Darth Sion, DarthStiv and 3 others like this -
The 7th film is about the new characters coming together then re-uniting the old team(chewie,han etc) and the search for luke who only turns up in the final quarter.The bad guys chasing leads by capturing rebels and using torture and mind control to find more rebels ,with the ultimate goal of finding skywalker and bringing him to justice for the murder of vader and palpatine. Skywalker now living like Oldben or a hermit keeps an eye on the kid from afar(His sister knows where he is).Laying low to protect his family from persecution.He himself has become a legend of folk law.The stories of his rise help as a inspiration for the rebels (Led by the princess).Just as in "A new hope" the film ends with a small but very significant victory,Ultimately bringing on the full wrath of the bad guys who are going to give the rebels a kicking in the 8th film.Things you will see like "A new chosen one".And a spiritual teacher from the past.Made the film much more Familiar for old gits like me.
-
Ok yes ill do 2 versions ,an installer and a asset.zip
-
Sabersystem tutorial
http://www.moddb.com/mods/serenitysabersystems/videos/serenitysabersystem-tutorial-part-1#imagebox
http://www.moddb.com/mods/serenitysabersystems/videos/sabering-tutorial-part-2#imagebox
pretty much all you need to get started
-
I am interested in the sabersystem. I remember that Evolution of Combat III was inspired from OJP but modified several things. Finaly, the fight seemed to be a little random in EoC III.
I would know if EoC IV sabersystem will keep the same or will be closer to the original OJP sabersystem.
The evolution of combat 1,2 and 3 sabersystem was built "on top" of the ojp system. so we started with ojp 1.2 enhanced code base and built on top of that.
Evolution of combat IV is built from the very first released code that hit the web. Obviously much work was needed to get it running .ask any of the coders from openjk about the amazing work they have done if you dont believe me.
The sabersystem coding started with the singleplayer side of the code.Firstly i had to re learn many things as up until that point i had only worked with mp code.
The singleplayer sabersystem was finished after 8 months of steady hobby coding.I basically looked at the movies for my inspiration. No lie.......honestly.. I watched some battles frame for frame, watching speed.leg movements, meterial impacts saber v saber, saber v walls, saber v blaster bolt. etc etc
Obviously this can only result in the sabersystem being "MY" interpretation of what i saw.No more jumping around like a baffooooon .As most old school Jka players do.general bad habits picked up from playing Jko and brought in to Jka.... Remember "My" Interpretation "My" views. ....so dont bother arguing with me on this ,because i dont give a shit and wont respond.
I always thought JKO/JKA sabersystems were only half finished and as a result they added a lot of stupid shit to spice it up... I watched fencing videos, swordsmanship videos,
ninja vids, fan vids, startwars fan vids.
Then this got my attention.
No stupid jumping around ,timed calculated ,and MOST important...Realistic attacks. A real blocking system that is as difficult to master as the attack systems.
And thats why many people do not like this mod .they find it sometimes too slow, too fast, too complicated. but i stress.nothing in life is easy.not everybody can master everything.
.This mod does and always will have elements of OJP in singleplayer and multiplayer. both singleplayer and multiplayer sabersystems are built as identically as possible, sharing much of the same code. the BOTS and NPC,s have there own separate sabersystems now. they can do things that you cannot, you can do things that they cannot.
I can confirm that both MP+SP sabersystems are fully finished now and i have been playing with the idea of some sort of demo release.
So if you do not know EoC at all i can only suggest maybe you try this
http://www.moddb.com/mods/evolution-of-combat-iii-remastered
but if you want more info before committing to a large download. Most of your answers can be found by reading the mods name.That means no extra maps,models,weapons. it means an evolution of what you already have. the question is...Is it something for you??? or are you just happy to hop around like a hamster,hoping for a lucky hit.
If you think its better to walk in to a room full of stormtroopers. press saberthrow then your saber flies around the room killing every stormtrooper in the room as you stand and watch, then DO NOT DOWNLOAD THIS MOD. because its not for you....
If you think its better to walk in to a room full of stormtroopers. They all shoot at you and they just stand there like idiots but not 1 blaster hits you because they are all so shit , then DO NOT DOWNLOAD THIS MOD. because its not for you....
If you want to learn something along the way,if you want a real challenge where its perfectly possibly that your going to get your ass kicked and you might actually learn from that then take a look............
I hope this has been helpful to you.
Here is a recent comment on the download page
the full message can be read here http://www.moddb.com/mods/evolution-of-combat-iv/news/eociv-preview-1
-
That was a very scarce article. I'd be interested to hear what exactly the new engine is supposedly capable of (a bit more detail than just "improved animations"), in what ways the combat was changed, what the "tons of new features" are about, why this mod is or was popular, what happened to the previous iterations... you know, a bit more than just a copy&paste of the moddb page. Especially so given that the "teaser" is itself almost without any substance.
Its a fair point,Its meant to be just sort of a small introduction to say "its being made".
Evolution of Combat is kind of a small mod that only interests a small group of people"Its not everybody,s cup of tea".
The aim of the new moddb page and video is to bring people from the old EoCIII moddb page to the new,to avoid any confusion about what build ,what update ,etc,etc.
So its really a message for the people who have followed the mod for the last 5 years.Having said that....... New people are always welcome to come and try it.
So your post comes at me as if its from someone who maybe has not come across the mod before ,and thats because the mod has only a small fan base mainly from a Russian community.
So in answer to your fair question i can only say its everything Evolution of Combat III has but in a new code "The old one is OJP and no EXE stuff".However im much better at coding now than i was 5/6 years ago and this enables me to correct any bugs i might have missed 5 years ago.
And of course build on new ideas.The big bonus is that i am able to say for singleplayer is the mod now runs Jedi outcast flawlessly after almost 2 years working on just that.
singleplayer and multiplayer now share an Identical sabersystem, guns systems and melee combat ,all the manual saberblocking, meleeblocking dodging stuff is identical.
3 years working on Bot A.I and about 1 on NPC A.I .
A now extensive BOT CLASS system and Player Class system for multiplayer.
I am currently working on Weapons Buying with a point based ,savable,experiance/ reward system.in MP
So i would maybe start here http://www.moddb.com/mods/serenitysabersystems/videos/serenitysabersystem-tutorial-part-1#imagebox
Its a mod that basically makes everything harder to beat,hopefully without going in to the Impossible to beat arena.
Well i hope this helps get you started no need for people to "stress out".
Big thanks to SiLink for doing a nice thing ,with good intentions .
-
The are a few simple ways of adding weapon kick.
The best way is through code.
to avoid confusion i added a new button command.
// // usercmd_t->button bits, many of which are generated by the client system, // so they aren't game/cgame only definitions // #define BUTTON_ATTACK 1 #define BUTTON_TALK 2 // displays talk balloon and disables actions #define BUTTON_USE_HOLDABLE 4 #define BUTTON_GESTURE 8 #define BUTTON_WALKING 16 #define BUTTON_USE 32 #define BUTTON_FORCEGRIP 64 #define BUTTON_ALT_ATTACK 128 #define BUTTON_ANY 256 #define BUTTON_FORCEPOWER 512 #define BUTTON_FORCE_LIGHTNING 1024 #define BUTTON_FORCE_DRAIN 2048 #define BUTTON_FREE 4096 //+button12 #define BUTTON_KICK 8192 //+button13 #define BUTTON_BLOCK 16384 //+button14 #define MOVE_RUN 120
dont forget to add the button to the menus
{"+button9", -1, -1, -1, -1}, {"+button10", -1, -1, -1, -1}, {"+button11", -1, -1, -1, -1}, {"+button12", -1, -1, -1, -1}, {"+button13", -1, -1, -1, -1}, {"+button14", -1, -1, -1, -1}, {"+button15", -1, -1, -1, -1}, {"victory", -1, -1, -1, -1}, {"dropsaber", -1, -1, -1, -1}, {"proneup", -1, -1, -1, -1}, {"pronedown", -1, -1, -1, -1}, {"saberdown", -1, -1, -1, -1}, };
then just pop the button command in bg pmove c
static void PM_Weapon( void ) { // make weapon function if ( pm->ps->weaponTime > 0 ) { pm->ps->weaponTime -= pml.msec; } else { if (pm->cmd.buttons & BUTTON_KICK) { //ok, try a kick I guess.//allow them to do the kick now! if (!BG_KickingAnim(pm->ps->torsoAnim) && !BG_KickingAnim(pm->ps->legsAnim) && !BG_InRoll(pm->ps, pm->ps->legsAnim) && !BG_KickMove( pm->ps->saberMove ) && pm->ps->groundEntityNum != ENTITYNUM_NONE) { int kickMove = PM_KickMoveForConditions(); if (kickMove != -1) { if ( pm->ps->groundEntityNum == ENTITYNUM_NONE ) {//if in air, convert kick to an in-air kick float gDist = PM_GroundDistance(); if ((!BG_FlippingAnim( pm->ps->legsAnim ) || pm->ps->legsTimer <= 0) && gDist > 64.0f && //strict minimum gDist > (-pm->ps->velocity[2])-64.0f) { switch ( kickMove ) { case LS_KICK_F: kickMove = LS_KICK_F_AIR; break; case LS_KICK_B: kickMove = LS_KICK_B_AIR; break; case LS_KICK_R: kickMove = LS_KICK_R_AIR; break; case LS_KICK_L: kickMove = LS_KICK_L_AIR; break; default: //oh well, can't do any other kick move while in-air kickMove = -1; break; } } else { //off ground, but too close to ground kickMove = -1; } } } if (kickMove != -1) { int kickAnim = saberMoveData[kickMove].animToUse; if (kickAnim != -1) { PM_SetAnim(SETANIM_BOTH, kickAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD,100); if (pm->ps->legsAnim == kickAnim) { pm->ps->weaponTime = pm->ps->legsTimer; return; } } } } //if got here then no move to do so put torso into leg idle or whatever if (pm->ps->torsoAnim != pm->ps->legsAnim) { PM_SetAnim(SETANIM_BOTH, pm->ps->legsAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD,100); } pm->ps->weaponTime = 0; return; } }
else if ((pm->cmd.buttons & BUTTON_KICK)|| (pm->cmd.buttons & BUTTON_ALT_ATTACK)) { //kicks if (!BG_KickingAnim(pm->ps->torsoAnim) && !BG_KickingAnim(pm->ps->legsAnim) && !BG_InRoll(pm->ps, pm->ps->legsAnim) && !BG_KickMove( pm->ps->saberMove ) && pm->ps->groundEntityNum != ENTITYNUM_NONE) { int kickMove = PM_KickMoveForConditions(); if (kickMove != -1) { if ( pm->ps->groundEntityNum == ENTITYNUM_NONE ) {//if in air, convert kick to an in-air kick float gDist = PM_GroundDistance(); //let's only allow air kicks if a certain distance from the ground //it's silly to be able to do them right as you land. //also looks wrong to transition from a non-complete flip anim... if ((!BG_FlippingAnim( pm->ps->legsAnim ) || pm->ps->legsTimer <= 0) && gDist > 64.0f && //strict minimum gDist > (-pm->ps->velocity[2])-64.0f //make sure we are high to ground relative to downward velocity as well ) { switch ( kickMove ) { case LS_KICK_F: kickMove = LS_KICK_F_AIR; break; case LS_KICK_B: kickMove = LS_KICK_B_AIR; break; case LS_KICK_R: kickMove = LS_KICK_R_AIR; break; case LS_KICK_L: kickMove = LS_KICK_L_AIR; break; default: //oh well, can't do any other kick move while in-air kickMove = -1; break; } } else { //off ground, but too close to ground kickMove = -1; } } } if (kickMove != -1) { int kickAnim = saberMoveData[kickMove].animToUse; if (kickAnim != -1) { PM_SetAnim(SETANIM_BOTH, kickAnim, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD,100); if (pm->ps->legsAnim == kickAnim) { pm->ps->weaponTime = pm->ps->legsTimer; return; } } } }
else if ( (pm->cmd.buttons & BUTTON_KICK) ) { //kick after doing a saberthrow,whalst saber is still being controlled if ( (pm->cmd.forwardmove||pm->cmd.rightmove)//trying to kick in a specific direction && PM_CheckAltKickAttack() )//trying to do a kick {//allow them to do the kick now! int kickMove = PM_KickMoveForConditions(); if (kickMove != -1) { pm->ps->weaponTime = 0; PM_SetSaberMove( kickMove ); return; } } } else if ( pm->ps->saberInFlight && pm->ps->saberEntityNum ) {//saber is already in flight continue moving it with the force. PM_SetAnim(SETANIM_TORSO, BOTH_SABERPULL, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD, 100); pm->ps->torsoTimer = 1; return; } else if ( pm->ps->weaponTime < 1&& pm->ps->saberCanThrow && //pm->ps->fd.forcePower >= forcePowerNeeded[pm->ps->fd.forcePowerLevel[FP_SABERTHROW]][FP_SABERTHROW] && !BG_HasYsalamiri(pm->gametype, pm->ps) && BG_CanUseFPNow(pm->gametype, pm->ps, pm->cmd.serverTime, FP_SABERTHROW) && pm->ps->fd.forcePowerLevel[FP_SABERTHROW] > 0 && PM_SaberPowerCheck() ) {
in bg saber
// Check for WEAPON ATTACK // ********************************************************* if((pm->cmd.buttons & BUTTON_ALT_ATTACK) && !(pm->cmd.buttons & BUTTON_ATTACK) && PM_DoKick()) { return; } else if(pm->ps->saberInFlight && pm->ps->forceHandExtend != HANDEXTEND_SABERPULL && pm->ps->fd.saberAnimLevel != SS_DUAL && (pm->cmd.buttons & BUTTON_ATTACK) ) {//don't have our saber so we can punch instead. PM_DoPunch(); return; } if ((pm->cmd.buttons & BUTTON_KICK)) { //ok, try a kick I guess. int kickMove = -1; if ( !BG_KickingAnim(pm->ps->torsoAnim) && !BG_KickingAnim(pm->ps->legsAnim) && !BG_InRoll(pm->ps, pm->ps->legsAnim) && pm->ps->saberMove == LS_READY && !(pm->ps->pm_flags&PMF_DUCKED)//not ducked && (pm->cmd.upmove >= 0 ) //not trying to duck )//&& pm->ps->groundEntityNum != ENTITYNUM_NONE) {//player kicks kickMove = PM_KickMoveForConditions(); } if (kickMove != -1) { if ( pm->ps->groundEntityNum == ENTITYNUM_NONE ) {//if in air, convert kick to an in-air kick float gDist = PM_GroundDistance(); //let's only allow air kicks if a certain distance from the ground //it's silly to be able to do them right as you land. //also looks wrong to transition from a non-complete flip anim... if ((!BG_FlippingAnim( pm->ps->legsAnim ) || pm->ps->legsTimer <= 0) && gDist > 64.0f && //strict minimum gDist > (-pm->ps->velocity[2])-64.0f //make sure we are high to ground relative to downward velocity as well ) { switch ( kickMove ) { case LS_KICK_F: kickMove = LS_KICK_F_AIR; break; case LS_KICK_B: kickMove = LS_KICK_B_AIR; break; case LS_KICK_R: kickMove = LS_KICK_R_AIR; break; case LS_KICK_L: kickMove = LS_KICK_L_AIR; break; default: //oh well, can't do any other kick move while in-air kickMove = -1; break; } } else {//leave it as a normal kick unless we're too high up if ( gDist > 128.0f || pm->ps->velocity[2] >= 0 ) { //off ground, but too close to ground kickMove = -1; } } } if (kickMove != -1) { PM_SetSaberMove( kickMove ); return; } } } //this is never a valid regular saber attack button pm->cmd.buttons &= ~BUTTON_KICK;
// make weapon function if ( pm->ps->weaponTime > 0 ) { pm->ps->weaponTime -= pml.msec; } else { if (pm->cmd.buttons & BUTTON_BLOCK && !PM_SaberInBounce( pm->ps->saberMove ) && !PM_SaberInKnockaway( pm->ps->saberMove ) && !PM_SaberInBrokenParry( pm->ps->saberMove ) && !PM_SaberInDamageMove(pm->ps->saberMove)) { if ( !pm->ps->SaberActive()) { pm->ps->SaberActivate(); }//set up the block position PM_SetBlock(); } else if (pm->cmd.buttons & BUTTON_KICK) {//allow them to do the kick now! pm->ps->weaponTime = 0; PM_CheckKick(); return; } else { pm->ps->weaponstate = WEAPON_READY; } }
there are a couple of ways to do it .hopefully this will get you started
Mand'alor likes this -
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.
-
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
-
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.
Circa likes this -
It is a bit of a nightmare,as I said "Mixed Results".
I've combined a extensive bot_class system ,with a heavily modded bot AI system,that uses small pieces of code moved from the NPC AI and slightly altered and placed in the bot AI system.
lots if issues.mixed results.
I might do a video when its worth looking at.
Stoiss has his finger on the pulse better than me with this one.
-
I'm not sure if the MP Code is set up to read NPC files.If not then it wont change anything if you alter the NPC file.
It is possible to set saberstyles for the bots,by building a simple class system in the code.
Stoiss did a class system in EoC and he built it so you could set the bots up in a similar fashion to NPC,s.
Bots can also be coded to run a way-point path-finding code on maps without bot routes.
The reason that NPC,s are shit at sabercombat is because some code is missing in MP Code that SP code has.
I have been looking in to a similar issue with bots and NPC,s for MP.
Im bridging the Bot code with a large portion if the NPC code, with a complex bot class system, Forcing the bots to use some NPC code in certain circumstances.
The results are Mixed, but its early days yet.
-
Ive started porting EoC/SJE over to OpenJk Code base.
First mission:
FIX: MP Sabertrace to match SP = Managed to port most of sp sabersystem in to MP about 80%.
Stabilize the bots by making them use as much NPC AI as possible = managed about 80%. Note:bot and Singleplayer NPC,s now act almost exactly the same in Combat.
Added manualblocking to MP +SP (See controls menu)
Added kick function and Melee to SP+MP
Add FULL support for Jedi Outcast (including Galak_Mech) = About 80% Finished
Here is a Pre Alpha tester if anyone is interested: http://www.mediafire.com/download/z2zy4gm8fbp1f1g/SerenityJediEngine-Openjk-Pr-Alpha+0.1.rar
-
Check out the first minute of this clip to see a NPC command system coded in to single player code.
Command "Stick Together" and "Attack" can be seen being used on the bespin Cops.
The code also contains "Stand Guard" But i didn't see it being used
https://www.youtube.com/watch?v=uiHMPhRRpEE&list=UUI2Ol6YCN70G6nN-XD-1Iug
-
Here's the ignition flare..I'm wondering if it should be whiter or slightly tinted to the saber colour.
I did a similar thing to this some time ago.
help yourself to the code if it may be of some help
http://www.moddb.com/mods/serenitysabersystems/addons/serenityjedienginesdk
-
I like this idea.
I always liked the class system in forcemod3 and the A.I for the bots that use jetpack is also very good.
but i dont know of any forcemod3 source.
A new mod using the best from many mods .
A Jedi Frankenstein mod
Keyten likes this -
What's the problem with the source being released? Your SP `mod` would never have existed if it wasn't. Just because the source is released doesn't mean people can't do their own things with it. Regardless of having the source made available or not. FWIW you only have to release the source if you actually make a release or give it out to anyone.
No problem at all.It was a monumental day for me when i got the sp sdk.Its like the biggest puzzle in the world ever,and i enjoy solving the puzzle to get the effect i want.
I noted a small issue in your code. In the beginning, you set variable w to be CG_DrawStrlen( va( "Civilian" ) ) * TINYCHAR_WIDTH; which is incorrect. You'll want to calculate w for every string that you use ("Rancor", "Protocol Droid", etc) so that it'll center correctly (currently it only centers correctly when the string is as long as "Civilian", which might lead to wonky positioning onscreen)
Also..um..
if ( cg_entities[cg.crosshairClientNum].currentState.eType == ET_ITEM ) { CG_DrawBigStringColor(320- w / 2,170,va( "Press to Use" ), colorTable[CT_LTGREY] ); return; }
... vs JKG's code ...
if ( cg_entities[cg.crosshairClientNum].currentState.eType == ET_ITEM ) { UI_DrawProportionalString (320, 170, "Press E to pick up weapon", UI_CENTER, colorTable[CT_WHITE], FONT_MEDIUM); return; }
I'd like to point out here that both examples are technically incorrect. The string is wrong ("Press E to pick up weapon" doesn't account for binds, and "Press to Use" is kinda weird language), the centering is incorrect on yours, and there isn't a distance calculation for either one, so you'll be able to highlight items from far away.
I like GSA's version of this, which accounted for binds, displayed a picture of the weapon and its name, and had colors to boot. It was quite beautiful, but a little bit buggy sometimes. Unfortunately I'm at work right now, or else I'd be able to pull it up as an example of the best way to do this. (I didn't code this chunk in JKG, I believe Pande or UniqueOne or someone else did this)
Firstly thanks for taking the time to look at the code .
Im always open to useful advice,corrections and tips that help me learn and correct mistakes i have made.
Firstly i can explain my thinking about w = CG_DrawStrlen( va( "Civilian" ) ) * TINYCHAR_WIDTH;
the three cases i used are
if ( crossEnt->client->playerTeam == TEAM_PLAYER )
if ( crossEnt->client->playerTeam == TEAM_ENEMY )
if ( crossEnt->client->playerTeam == TEAM_NEUTRAL || crossEnt->client->playerTeam == TEAM_FREE )
all end with
CG_DrawBigStringColor(320- w / 2,170,va( "Friend" ), colorTable[CT_WHITE] );
CG_DrawBigStringColor(320- w / 2,170,va( "Enemy" ), colorTable[CT_WHITE] );
CG_DrawBigStringColor(320- w / 2,170,va( "Civilian" ), colorTable[CT_WHITE] );
so i thought if i used the biggest word of the three = Civilian. Then the spacing would be enough as all the name are different lengths ,they wont end in the same place so the dont need to start in the same place ?
Also i have to be honest .The distance idea is something i didnt think of. So i have to say thankyou. After playtesting for some time i think a distance limit is a good idea.
As for my
CG_DrawBigStringColor(320- w / 2,170,va( "Press to Use" ), colorTable[CT_LTGREY] );
vs your
UI_DrawProportionalString (320, 170, "Press E to pick up weapon", UI_CENTER, colorTable[CT_WHITE], FONT_MEDIUM);
the simplest methods are the best
here the multiplayer version
/* ===================== CG_DrawCrosshairNames ===================== */ static void CG_DrawCrosshairNames( void ) { float *color; char *name; char sanitized[1024]; int baseColor; qboolean isVeh = qfalse; float w; if ( cg_drawCrosshair.integer < 0 ) { return; } if(in_camera) { return; } CG_ScanForCrosshairEntity(); if ( cg_entities[cg.crosshairClientNum].currentState.eType == ET_ITEM ) { UI_DrawProportionalString (320, 170, "Press to Use", UI_CENTER | UI_SMALLFONT, colorTable[CT_LTGREY]); return; } else if (cg.crosshairClientNum < ENTITYNUM_WORLD) { centity_t *veh = &cg_entities[cg.crosshairClientNum]; if (veh->currentState.eType == ET_NPC && veh->currentState.NPC_class == CLASS_VEHICLE && veh->currentState.owner < MAX_CLIENTS) { //draw the name of the pilot then cg.crosshairClientNum = veh->currentState.owner; cg.crosshairVehNum = veh->currentState.number; cg.crosshairVehTime = cg.time; isVeh = qtrue; } } if (cg_entities[cg.crosshairClientNum].currentState.powerups & (1 << PW_CLOAKED)) { return; } color = CG_FadeColor( cg.crosshairClientTime, 1000 ); if ( !color ) { trap_R_SetColor( NULL ); return; } name = cgs.clientinfo[ cg.crosshairClientNum ].name; w = CG_DrawStrlen( va( "Civilian" ) ) * TINYCHAR_WIDTH; if (cg.snap->ps.duelInProgress) { if (cg.crosshairClientNum != cg.snap->ps.duelIndex) { //grey out crosshair for everyone but your foe if you're in a duel baseColor = CT_BLACK; } } else if (cg_entities[cg.crosshairClientNum].currentState.bolt1) { //this fellow is in a duel. We just checked if we were in a duel above, so //this means we aren't and he is. Which of course means our crosshair greys out over him. baseColor = CT_BLACK; } CG_SanitizeString(name, sanitized); if (isVeh) { char str[MAX_STRING_CHARS]; Com_sprintf(str, MAX_STRING_CHARS, "%s (pilot)", sanitized); UI_DrawProportionalString(320, 170, str, UI_CENTER | UI_SMALLFONT, colorTable[CT_BLUE]); } else { if ( !cg_drawCrosshairNames.integer ) { return; } if ( ( cgs.clientinfo[ cg.crosshairClientNum ].team == TEAM_RED ) ) { CG_DrawSmallStringColor( 320 - w / 2, 170, name, colorTable[CT_RED] ); } else if ( ( cgs.clientinfo[ cg.crosshairClientNum ].team == TEAM_BLUE ) ) { CG_DrawSmallStringColor( 320 - w / 2, 170, name, colorTable[CT_GREEN] ); } else if ( ( cgs.clientinfo[ cg.crosshairClientNum ].team == TEAM_SPECTATOR ) ) { CG_DrawSmallStringColor( 320 - w / 2, 170, name , colorTable[CT_CYAN] ); } else { CG_DrawSmallStringColor( 320 - w / 2, 170, name, colorTable[CT_YELLOW] ); } } trap_R_SetColor( NULL ); }
note the
else if (cg.crosshairClientNum < ENTITYNUM_WORLD){centity_t *veh = &cg_entities[cg.crosshairClientNum];if (veh->currentState.eType == ET_NPC &&veh->currentState.NPC_class == CLASS_VEHICLE &&veh->currentState.owner < MAX_CLIENTS){ //draw the name of the pilot thencg.crosshairClientNum = veh->currentState.owner;cg.crosshairVehNum = veh->currentState.number;cg.crosshairVehTime = cg.time;isVeh = qtrue;}}i stole the idea from thiscurrentState.eType == ET_
i tried ET_MOVER also but it was too much info in screen .
I didn't want it to be like JKG with
"Press E to pick up weapon"
and i haven't thought of anything better than
Press to Use
I did think about "Touch to use" but it looks kinda gay
GSA's version sounds cool.
-
I like it,
the new effects are very nice
and the ability to see the NPC's name is rather good too.
You'd better release it as an addon to your mod man...
Well i have no plans to release anything........(for now)
Maybe next year if my hobby coding leads to something worth releasing.
Releasing mods is never going to be the same again now because the JKA/OPENJK code is always available to all .Meaning no more secrets / surprises.Or individuality.
However ,if you have downloaded the code for SJE/EoC http://www.moddb.com/mods/serenitysabersystems/addons/serenityjedienginesdk
Then i would be happy to post the code here for people to see or use,to add to there own code.
Somebody asked me today if the code is taken from JKG ?
The answer is no.But i admit when playing JKG it was something i liked about the mod. Multiplayer already has a functioning CG_DrawCrosshairNames code .
The only difference is, it is constructed to read the BOT names and the lettering design (FONT) is different.
So i looked in multiplayer code to see how this was done.
I didnt just copy code from A to B ,any coder will tell you ,it doesnt work like that.
Using the built in NPC CLASS system i just coded the names of the classes.
In my opinion the JKA CG_DrawCrosshairNames code is crap , useless and possibly neglected . "It Doesn't even Draw Player Names"
so i just fixed it...
It Kinda goes like this .
/* ===================== CG_DrawCrosshairNames ===================== */ static void CG_DrawCrosshairNames( void ) { qboolean scanAll = qfalse; float w; if ( cg_drawCrosshair.integer < 0 ) { return; } if(in_camera) { return; } CG_ScanForCrosshairEntity( scanAll ); w = CG_DrawStrlen( va( "Civilian" ) ) * TINYCHAR_WIDTH; if ( cg_entities[cg.crosshairClientNum].currentState.eType == ET_ITEM ) { CG_DrawBigStringColor(320- w / 2,170,va( "Press to Use" ), colorTable[CT_LTGREY] ); return; } if (cg_entities[cg.crosshairClientNum].currentState.powerups & (1 << PW_CLOAKED)) { return; } if ( cg_crosshairIdentifyTarget.integer ) { if ( !cg_drawCrosshairNames.integer ) { return; } gentity_t *crossEnt = &g_entities[g_crosshairEntNum]; if ( crossEnt->client ) { if ( crossEnt->client->playerTeam == TEAM_PLAYER ) {//Allies switch ( crossEnt->client->NPC_class ) { case CLASS_REBEL: CG_DrawBigStringColor(320- w / 2,170,va( "Rebel" ), colorTable[CT_GREEN] ); break; case CLASS_JEDI: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Knight" ), colorTable[CT_CYAN] ); break; case CLASS_KYLE: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Master" ), colorTable[CT_CYAN] ); break; case CLASS_LUKE: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Mentor" ), colorTable[CT_CYAN] ); break; case CLASS_JAN: CG_DrawBigStringColor(320- w / 2,170,va( "Jan Ors" ), colorTable[CT_MAGENTA] ); break; case CLASS_MONMOTHA: CG_DrawBigStringColor(320- w / 2,170,va( "Monmothma" ), colorTable[CT_GREEN] ); break; case CLASS_MORGANKATARN: CG_DrawBigStringColor(320- w / 2,170,va( "Morgan Katarn" ), colorTable[CT_LTORANGE] ); break; case CLASS_STORMTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Stormtrooper" ), colorTable[CT_RED] ); break; case CLASS_SWAMPTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Swamptrooper" ), colorTable[CT_RED] ); break; case CLASS_IMPWORKER: CG_DrawBigStringColor(320- w / 2,170,va( "ImpWorker" ), colorTable[CT_RED] ); break; case CLASS_IMPERIAL: CG_DrawBigStringColor(320- w / 2,170,va( "Imperial" ), colorTable[CT_RED] ); break; case CLASS_SHADOWTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Shadowtrooper" ), colorTable[CT_DKRED1] ); break; case CLASS_COMMANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Commando" ), colorTable[CT_RED] ); break; case CLASS_TAVION: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Boss" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_ALORA: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Warrior" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_DESANN: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Lord" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_REBORN: if ( Q_stricmp( "human_merc", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "scout" ), colorTable[CT_VLTPURPLE1] ); } else if ( Q_stricmp( "cultist_saber", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all_throw2", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "Dark Jedi" ), colorTable[CT_VLTPURPLE1] ); } else if ( Q_stricmp( "cultist", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "Commando" ), colorTable[CT_VLTPURPLE1] ); } else { CG_DrawBigStringColor(320- w / 2,170,va( "Sith" ), colorTable[CT_VLTPURPLE1] ); } break; case CLASS_BOBAFETT: CG_DrawBigStringColor(320- w / 2,170,va( "Bobafett" ), colorTable[CT_LTORANGE] ); break; case CLASS_MANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Mandolorian" ), colorTable[CT_LTORANGE] ); break; case CLASS_ATST: CG_DrawBigStringColor(320- w / 2,170,va( "Vehicle" ), colorTable[CT_BLUE] ); break; case CLASS_CLAW: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_FISH: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_FLIER2: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_GLIDER: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_HOWLER: CG_DrawBigStringColor(320- w / 2,170,va( "Howler" ), colorTable[CT_MDGREY] ); break; case CLASS_MINEMONSTER: CG_DrawBigStringColor(320- w / 2,170,va( "MineMonster" ), colorTable[CT_MDGREY] ); break; case CLASS_LIZARD: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_SWAMP: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_RANCOR: CG_DrawBigStringColor(320- w / 2,170,va( "Rancor" ), colorTable[CT_MDGREY] ); break; case CLASS_WAMPA: CG_DrawBigStringColor(320- w / 2,170,va( "Wampa" ), colorTable[CT_MDGREY] ); break; case CLASS_VEHICLE: CG_DrawBigStringColor(320- w / 2,170,va( "Vehicle" ), colorTable[CT_BLUE] ); break; case CLASS_BESPIN_COP: CG_DrawBigStringColor(320- w / 2,170,va( "Bespin Cop" ), colorTable[CT_GREEN] ); break; case CLASS_LANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Lando" ), colorTable[CT_GREEN] ); break; case CLASS_PRISONER: CG_DrawBigStringColor(320- w / 2,170,va( "Prisoner" ), colorTable[CT_GREEN] ); break; case CLASS_GALAK: CG_DrawBigStringColor(320- w / 2,170,va( "Galak" ), colorTable[CT_RED] ); break; case CLASS_GRAN: CG_DrawBigStringColor(320- w / 2,170,va( "Gran" ), colorTable[CT_RED] ); break; case CLASS_REELO: CG_DrawBigStringColor(320- w / 2,170,va( "Reelo" ), colorTable[CT_RED] ); break; case CLASS_MURJJ: CG_DrawBigStringColor(320- w / 2,170,va( "Murjj" ), colorTable[CT_RED] ); break; case CLASS_RODIAN: CG_DrawBigStringColor(320- w / 2,170,va( "Rodian" ), colorTable[CT_RED] ); break; case CLASS_TRANDOSHAN: CG_DrawBigStringColor(320- w / 2,170,va( "Trandoshan" ), colorTable[CT_RED] ); break; case CLASS_UGNAUGHT: CG_DrawBigStringColor(320- w / 2,170,va( "Ugnaught" ), colorTable[CT_GREEN] ); break; case CLASS_WEEQUAY: CG_DrawBigStringColor(320- w / 2,170,va( "Weequay" ), colorTable[CT_RED] ); break; case CLASS_BARTENDER: CG_DrawBigStringColor(320- w / 2,170,va( "Bartender" ), colorTable[CT_BLUE] ); break; case CLASS_JAWA: CG_DrawBigStringColor(320- w / 2,170,va( "Jawa" ), colorTable[CT_MAGENTA] ); break; case CLASS_PROTOCOL: CG_DrawBigStringColor(320- w / 2,170,va( "Protocol Droid" ), colorTable[CT_YELLOW] ); break; case CLASS_R2D2: CG_DrawBigStringColor(320- w / 2,170,va( "R2D2" ), colorTable[CT_YELLOW] ); break; case CLASS_PROBE: CG_DrawBigStringColor(320- w / 2,170,va( "Probe Droid" ), colorTable[CT_YELLOW] ); break; case CLASS_R5D2: CG_DrawBigStringColor(320- w / 2,170,va( "R5D2" ), colorTable[CT_YELLOW] ); break; case CLASS_DROIDEKA: CG_DrawBigStringColor(320- w / 2,170,va( "Droideka" ), colorTable[CT_MAGENTA] ); break; case CLASS_BATTLEDROID: CG_DrawBigStringColor(320- w / 2,170,va( "Battle Droid" ), colorTable[CT_MAGENTA] ); break; case CLASS_SBD: CG_DrawBigStringColor(320- w / 2,170,va( "Super Battle Droid" ), colorTable[CT_MAGENTA] ); break; case CLASS_ASSASSIN_DROID: CG_DrawBigStringColor(320- w / 2,170,va( "R5D2" ), colorTable[CT_YELLOW] ); break; case CLASS_SABER_DROID: CG_DrawBigStringColor(320- w / 2,170,va( "Saber Droid" ), colorTable[CT_MAGENTA] ); break; default: CG_DrawBigStringColor(320- w / 2,170,va( "Friend" ), colorTable[CT_WHITE] ); break; } } else if ( crossEnt->client->playerTeam == TEAM_ENEMY ) { switch ( crossEnt->client->NPC_class ) { case CLASS_REBEL: CG_DrawBigStringColor(320- w / 2,170,va( "Rebel" ), colorTable[CT_GREEN] ); break; case CLASS_JEDI: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Knight" ), colorTable[CT_CYAN] ); break; case CLASS_KYLE: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Master" ), colorTable[CT_CYAN] ); break; case CLASS_LUKE: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Mentor" ), colorTable[CT_CYAN] ); break; case CLASS_JAN: CG_DrawBigStringColor(320- w / 2,170,va( "Jan Ors" ), colorTable[CT_MAGENTA] ); break; case CLASS_MONMOTHA: CG_DrawBigStringColor(320- w / 2,170,va( "Monmothma" ), colorTable[CT_GREEN] ); break; case CLASS_MORGANKATARN: CG_DrawBigStringColor(320- w / 2,170,va( "Morgan Katarn" ), colorTable[CT_LTORANGE] ); break; case CLASS_STORMTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Stormtrooper" ), colorTable[CT_RED] ); break; case CLASS_SWAMPTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Swamptrooper" ), colorTable[CT_RED] ); break; case CLASS_IMPWORKER: CG_DrawBigStringColor(320- w / 2,170,va( "ImpWorker" ), colorTable[CT_RED] ); break; case CLASS_IMPERIAL: CG_DrawBigStringColor(320- w / 2,170,va( "Imperial" ), colorTable[CT_RED] ); break; case CLASS_SHADOWTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Shadowtrooper" ), colorTable[CT_DKRED1] ); break; case CLASS_COMMANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Commando" ), colorTable[CT_RED] ); break; case CLASS_TAVION: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Boss" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_ALORA: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Warrior" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_DESANN: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Lord" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_REBORN: if ( Q_stricmp( "human_merc", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "scout" ), colorTable[CT_VLTPURPLE1] ); } else if ( Q_stricmp( "cultist_saber", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all_throw2", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "Dark Jedi" ), colorTable[CT_VLTPURPLE1] ); } else if ( Q_stricmp( "cultist", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "Commando" ), colorTable[CT_VLTPURPLE1] ); } else { CG_DrawBigStringColor(320- w / 2,170,va( "Sith" ), colorTable[CT_VLTPURPLE1] ); } break; case CLASS_BOBAFETT: CG_DrawBigStringColor(320- w / 2,170,va( "Bobafett" ), colorTable[CT_LTORANGE] ); break; case CLASS_MANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Mandolorian" ), colorTable[CT_LTORANGE] ); break; case CLASS_ATST: CG_DrawBigStringColor(320- w / 2,170,va( "Vehicle" ), colorTable[CT_BLUE] ); break; case CLASS_CLAW: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_FISH: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_FLIER2: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_GLIDER: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_HOWLER: CG_DrawBigStringColor(320- w / 2,170,va( "Howler" ), colorTable[CT_MDGREY] ); break; case CLASS_MINEMONSTER: CG_DrawBigStringColor(320- w / 2,170,va( "MineMonster" ), colorTable[CT_MDGREY] ); break; case CLASS_LIZARD: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_SWAMP: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_RANCOR: CG_DrawBigStringColor(320- w / 2,170,va( "Rancor" ), colorTable[CT_MDGREY] ); break; case CLASS_WAMPA: CG_DrawBigStringColor(320- w / 2,170,va( "Wampa" ), colorTable[CT_MDGREY] ); break; case CLASS_VEHICLE: CG_DrawBigStringColor(320- w / 2,170,va( "Vehicle" ), colorTable[CT_BLUE] ); break; case CLASS_BESPIN_COP: CG_DrawBigStringColor(320- w / 2,170,va( "Bespin Cop" ), colorTable[CT_GREEN] ); break; case CLASS_LANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Lando" ), colorTable[CT_GREEN] ); break; case CLASS_PRISONER: CG_DrawBigStringColor(320- w / 2,170,va( "Prisoner" ), colorTable[CT_GREEN] ); break; case CLASS_GALAK: CG_DrawBigStringColor(320- w / 2,170,va( "Galak" ), colorTable[CT_RED] ); break; case CLASS_GRAN: CG_DrawBigStringColor(320- w / 2,170,va( "Gran" ), colorTable[CT_RED] ); break; case CLASS_REELO: CG_DrawBigStringColor(320- w / 2,170,va( "Reelo" ), colorTable[CT_RED] ); break; case CLASS_MURJJ: CG_DrawBigStringColor(320- w / 2,170,va( "Murjj" ), colorTable[CT_RED] ); break; case CLASS_RODIAN: CG_DrawBigStringColor(320- w / 2,170,va( "Rodian" ), colorTable[CT_RED] ); break; case CLASS_TRANDOSHAN: CG_DrawBigStringColor(320- w / 2,170,va( "Trandoshan" ), colorTable[CT_RED] ); break; case CLASS_UGNAUGHT: CG_DrawBigStringColor(320- w / 2,170,va( "Ugnaught" ), colorTable[CT_GREEN] ); break; case CLASS_WEEQUAY: CG_DrawBigStringColor(320- w / 2,170,va( "Weequay" ), colorTable[CT_RED] ); break; case CLASS_BARTENDER: CG_DrawBigStringColor(320- w / 2,170,va( "Bartender" ), colorTable[CT_BLUE] ); break; case CLASS_JAWA: CG_DrawBigStringColor(320- w / 2,170,va( "Jawa" ), colorTable[CT_MAGENTA] ); break; case CLASS_PROTOCOL: CG_DrawBigStringColor(320- w / 2,170,va( "Protocol Droid" ), colorTable[CT_YELLOW] ); break; case CLASS_R2D2: CG_DrawBigStringColor(320- w / 2,170,va( "R2D2" ), colorTable[CT_YELLOW] ); break; case CLASS_PROBE: CG_DrawBigStringColor(320- w / 2,170,va( "Probe Droid" ), colorTable[CT_YELLOW] ); break; case CLASS_R5D2: CG_DrawBigStringColor(320- w / 2,170,va( "R5D2" ), colorTable[CT_YELLOW] ); break; case CLASS_DROIDEKA: CG_DrawBigStringColor(320- w / 2,170,va( "Droideka" ), colorTable[CT_MAGENTA] ); break; case CLASS_BATTLEDROID: CG_DrawBigStringColor(320- w / 2,170,va( "Battle Droid" ), colorTable[CT_MAGENTA] ); break; case CLASS_SBD: CG_DrawBigStringColor(320- w / 2,170,va( "Super Battle Droid" ), colorTable[CT_MAGENTA] ); break; case CLASS_ASSASSIN_DROID: CG_DrawBigStringColor(320- w / 2,170,va( "R5D2" ), colorTable[CT_YELLOW] ); break; case CLASS_SABER_DROID: CG_DrawBigStringColor(320- w / 2,170,va( "Saber Droid" ), colorTable[CT_MAGENTA] ); break; default: CG_DrawBigStringColor(320- w / 2,170,va( "Enemy" ), colorTable[CT_WHITE] ); break; } } else if ( crossEnt->client->playerTeam == TEAM_NEUTRAL || crossEnt->client->playerTeam == TEAM_FREE ) { switch ( crossEnt->client->NPC_class ) { case CLASS_REBEL: CG_DrawBigStringColor(320- w / 2,170,va( "Rebel" ), colorTable[CT_GREEN] ); break; case CLASS_JEDI: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Knight" ), colorTable[CT_CYAN] ); break; case CLASS_KYLE: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Master" ), colorTable[CT_CYAN] ); break; case CLASS_LUKE: CG_DrawBigStringColor(320- w / 2,170,va( "Jedi Mentor" ), colorTable[CT_CYAN] ); break; case CLASS_JAN: CG_DrawBigStringColor(320- w / 2,170,va( "Jan Ors" ), colorTable[CT_MAGENTA] ); break; case CLASS_MONMOTHA: CG_DrawBigStringColor(320- w / 2,170,va( "Monmothma" ), colorTable[CT_GREEN] ); break; case CLASS_MORGANKATARN: CG_DrawBigStringColor(320- w / 2,170,va( "Morgan Katarn" ), colorTable[CT_LTORANGE] ); break; case CLASS_STORMTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Stormtrooper" ), colorTable[CT_RED] ); break; case CLASS_SWAMPTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Swamptrooper" ), colorTable[CT_RED] ); break; case CLASS_IMPWORKER: CG_DrawBigStringColor(320- w / 2,170,va( "ImpWorker" ), colorTable[CT_RED] ); break; case CLASS_IMPERIAL: CG_DrawBigStringColor(320- w / 2,170,va( "Imperial" ), colorTable[CT_RED] ); break; case CLASS_SHADOWTROOPER: CG_DrawBigStringColor(320- w / 2,170,va( "Shadowtrooper" ), colorTable[CT_DKRED1] ); break; case CLASS_COMMANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Commando" ), colorTable[CT_RED] ); break; case CLASS_TAVION: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Boss" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_ALORA: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Warrior" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_DESANN: CG_DrawBigStringColor(320- w / 2,170,va( "Sith Lord" ), colorTable[CT_VLTPURPLE1] ); break; case CLASS_REBORN: if ( Q_stricmp( "human_merc", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "scout" ), colorTable[CT_VLTPURPLE1] ); } else if ( Q_stricmp( "cultist_saber", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all_throw", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_med_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_strong_throw2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all2", crossEnt->NPC_type ) == 0 || Q_stricmp( "cultist_saber_all_throw2", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "Dark Jedi" ), colorTable[CT_VLTPURPLE1] ); } else if ( Q_stricmp( "cultist", crossEnt->NPC_type ) == 0 ) { CG_DrawBigStringColor(320- w / 2,170,va( "Commando" ), colorTable[CT_VLTPURPLE1] ); } else { CG_DrawBigStringColor(320- w / 2,170,va( "Sith" ), colorTable[CT_VLTPURPLE1] ); } break; case CLASS_BOBAFETT: CG_DrawBigStringColor(320- w / 2,170,va( "Bobafett" ), colorTable[CT_LTORANGE] ); break; case CLASS_MANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Mandolorian" ), colorTable[CT_LTORANGE] ); break; case CLASS_ATST: CG_DrawBigStringColor(320- w / 2,170,va( "Vehicle" ), colorTable[CT_BLUE] ); break; case CLASS_CLAW: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_FISH: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_FLIER2: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_GLIDER: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_HOWLER: CG_DrawBigStringColor(320- w / 2,170,va( "Howler" ), colorTable[CT_MDGREY] ); break; case CLASS_MINEMONSTER: CG_DrawBigStringColor(320- w / 2,170,va( "MineMonster" ), colorTable[CT_MDGREY] ); break; case CLASS_LIZARD: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_SWAMP: CG_DrawBigStringColor(320- w / 2,170,va( "Animal" ), colorTable[CT_MDGREY] ); break; case CLASS_RANCOR: CG_DrawBigStringColor(320- w / 2,170,va( "Rancor" ), colorTable[CT_MDGREY] ); break; case CLASS_WAMPA: CG_DrawBigStringColor(320- w / 2,170,va( "Wampa" ), colorTable[CT_MDGREY] ); break; case CLASS_VEHICLE: CG_DrawBigStringColor(320- w / 2,170,va( "Vehicle" ), colorTable[CT_BLUE] ); break; case CLASS_BESPIN_COP: CG_DrawBigStringColor(320- w / 2,170,va( "Bespin Cop" ), colorTable[CT_GREEN] ); break; case CLASS_LANDO: CG_DrawBigStringColor(320- w / 2,170,va( "Lando" ), colorTable[CT_GREEN] ); break; case CLASS_PRISONER: CG_DrawBigStringColor(320- w / 2,170,va( "Prisoner" ), colorTable[CT_GREEN] ); break; case CLASS_GALAK: CG_DrawBigStringColor(320- w / 2,170,va( "Galak" ), colorTable[CT_RED] ); break; case CLASS_GRAN: CG_DrawBigStringColor(320- w / 2,170,va( "Gran" ), colorTable[CT_RED] ); break; case CLASS_REELO: CG_DrawBigStringColor(320- w / 2,170,va( "Reelo" ), colorTable[CT_RED] ); break; case CLASS_MURJJ: CG_DrawBigStringColor(320- w / 2,170,va( "Murjj" ), colorTable[CT_RED] ); break; case CLASS_RODIAN: CG_DrawBigStringColor(320- w / 2,170,va( "Rodian" ), colorTable[CT_RED] ); break; case CLASS_TRANDOSHAN: CG_DrawBigStringColor(320- w / 2,170,va( "Trandoshan" ), colorTable[CT_RED] ); break; case CLASS_UGNAUGHT: CG_DrawBigStringColor(320- w / 2,170,va( "Ugnaught" ), colorTable[CT_GREEN] ); break; case CLASS_WEEQUAY: CG_DrawBigStringColor(320- w / 2,170,va( "Weequay" ), colorTable[CT_RED] ); break; case CLASS_BARTENDER: CG_DrawBigStringColor(320- w / 2,170,va( "Bartender" ), colorTable[CT_BLUE] ); break; case CLASS_JAWA: CG_DrawBigStringColor(320- w / 2,170,va( "Jawa" ), colorTable[CT_MAGENTA] ); break; case CLASS_PROTOCOL: CG_DrawBigStringColor(320- w / 2,170,va( "Protocol Droid" ), colorTable[CT_YELLOW] ); break; case CLASS_R2D2: CG_DrawBigStringColor(320- w / 2,170,va( "R2D2" ), colorTable[CT_YELLOW] ); break; case CLASS_PROBE: CG_DrawBigStringColor(320- w / 2,170,va( "Probe Droid" ), colorTable[CT_YELLOW] ); break; case CLASS_R5D2: CG_DrawBigStringColor(320- w / 2,170,va( "R5D2" ), colorTable[CT_YELLOW] ); break; case CLASS_DROIDEKA: CG_DrawBigStringColor(320- w / 2,170,va( "Droideka" ), colorTable[CT_MAGENTA] ); break; case CLASS_BATTLEDROID: CG_DrawBigStringColor(320- w / 2,170,va( "Battle Droid" ), colorTable[CT_MAGENTA] ); break; case CLASS_SBD: CG_DrawBigStringColor(320- w / 2,170,va( "Super Battle Droid" ), colorTable[CT_MAGENTA] ); break; case CLASS_ASSASSIN_DROID: CG_DrawBigStringColor(320- w / 2,170,va( "R5D2" ), colorTable[CT_YELLOW] ); break; case CLASS_SABER_DROID: CG_DrawBigStringColor(320- w / 2,170,va( "Saber Droid" ), colorTable[CT_MAGENTA] ); break; default: CG_DrawBigStringColor(320- w / 2,170,va( "Civilian" ), colorTable[CT_WHITE] ); break; } } else { CG_DrawBigStringColor(320- w / 2,170,va( "Civilian" ), colorTable[CT_WHITE] ); } } } cgi_R_SetColor( NULL ); }
The is probably a much cleaner or better way to do this.
But if it works ....Dont fix it
Smoo likes this
Adding Force fall sp/mp
in Coding
Posted
This is an easy one as you only need to alter bg_pmove.cpp (sp) or bg_pmove.c (mp)
first locate this piece of code in bg_pmove.cpp (sp) or bg_pmove.c (mp)
under this add the following in bg_pmove.cpp (sp) or this bg_pmove.c (mp) Now we have to add 2 more check sLocate this piece of code in bg_pmove.cpp (sp) or bg_pmove.c (mp)
and now add this and finally Locate this piece of code in bg_pmove.cpp (sp) or bg_pmove.c (mp) at the very bottom of this piece of code add this Now compile the code and do some Massive jumps