Jump to content

skew

Members
  • Posts

    24
  • Joined

  • Last visited

Everything posted by skew

  1. Haha, awesome idea! I was planning on adding something that would make it work. Right now the fighter programs control your own client on the server but I was going to add an operation to fire off a program on your opponent. That way I could do proper grabs and stuff. Fatalities would be icing on the cake.
  2. Yes, but they're all done via code. I didn't make any animations in the traditional sense. In game I'm accomplishing the breathing by manipulating the viewangles, because those cause the skeleton to look as if it were breathing. The code was really credue and needs my more refined method from the UI. Game code here: // adnan - make them seem as if theyre breathing // add some randomness to this! if(pm->ps->stats[STAT_HEALTH] <= 0) { breatheScale = 0; } else if(pm->ps->stats[STAT_HEALTH] < 25) { breatheScale = 2; } else if(pm->ps->stats[STAT_HEALTH] < 50) { breatheScale = 1.5; } else if(pm->ps->stats[STAT_HEALTH] < 75) { breatheScale = 1.25; } else { breatheScale = 1; } pm->ps->viewangles[PITCH] = breatheScale * 10 * sin(breatheScale * (pm->cmd.serverTime)/600.0f); In the main menu (and the fighter selection screen), I'm doing it via bones directly. I also did blinking, neck tilting, saber re-gripping, etc via the code here. It's not super efficient, but generally works too. viewAngles[YAW] = 0; viewAngles[PITCH] = 2.0f * sin(time / 700.0f + ui_jf_seed.integer) + 1.0f; viewAngles[ROLL] = 0; //distribute the angles differently up the spine //NOTE: each of these distributions must add up to 1.0f thoracicAngles[PITCH] = viewAngles[PITCH] * 0.20f; llAngles[PITCH] = viewAngles[PITCH] * 0.40f; ulAngles[PITCH] = viewAngles[PITCH] * 0.40f; craniumAngles[PITCH] = viewAngles[PITCH] * -0.8f; pelvisAngles[PITCH] = viewAngles[PITCH] * -0.2f; eyeAngles[PITCH] = -craniumAngles[PITCH] + 20.0f; thoracicAngles[YAW] = viewAngles[YAW] * 0.20f; ulAngles[YAW] = viewAngles[YAW] * 0.35f; llAngles[YAW] = viewAngles[YAW] * 0.45f; craniumAngles[YAW] = viewAngles[YAW] * -0.8f; pelvisAngles[YAW] = viewAngles[YAW] * 0.1f; eyeAngles[YAW] = -craniumAngles[YAW]; thoracicAngles[ROLL] = viewAngles[ROLL] * 0.20f; ulAngles[ROLL] = viewAngles[ROLL] * 0.35f; llAngles[ROLL] = viewAngles[ROLL] * 0.45f; craniumAngles[ROLL] = viewAngles[ROLL] * -0.8f; pelvisAngles[ROLL] = viewAngles[ROLL] * -0.1f; eyeAngles[ROLL] = -craniumAngles[ROLL]; // blink in 150 ms every 5 seconds if (time % 5000 < 150) eyeAngles[PITCH] -= 40.0f * fabs(sin(2*M_PI * 1000/300.0f * (time % 5000) / 1000.0f)); // regrip pinky for half a second every 7 seconds if (time % 7000 < 500) pinkyFingerAngle[PITCH] = -40.0f * fabs(sin(2 * M_PI * 1000 / 1000.0f * (time % 7000) / 1000.0f)); else pinkyFingerAngle[PITCH] = 0.0f; pinkyFingerAngle[ROLL] = 0; pinkyFingerAngle[YAW] = 0; // regrip thumb and forefingers for half a second every 7 seconds, 250 ms after with the forefingers if ((time % 7000 < 750) && (time % 7000 > 250)) pointerFingerAngle[PITCH] = -40.0f * fabs(sin(2 * M_PI * 1000 / 1000.0f * ((time % 7000) - 250) / 1000.0f)); else pointerFingerAngle[PITCH] = 0.0f; pointerFingerAngle[ROLL] = 0; pointerFingerAngle[YAW] = 0; thumbAngle[YAW] = pointerFingerAngle[YAW]; thumbAngle[PITCH] = pointerFingerAngle[PITCH]; thumbAngle[ROLL] = pointerFingerAngle[ROLL]; // tilt the head every 40 seconds for 2 seconds if (time % 40000 < 2000) craniumAngles[ROLL] += -25.0f * sin(2 * M_PI * 1000 / 2000.0f * (time % 40000) / 1000.0f); //else // craniumAngles[ROLL] = 0.0f; trap_G2API_SetBoneAngles(item->ghoul2, 0, "lower_lumbar", &llAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); trap_G2API_SetBoneAngles(item->ghoul2, 0, "upper_lumbar", &ulAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); trap_G2API_SetBoneAngles(item->ghoul2, 0, "cranium", &craniumAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); trap_G2API_SetBoneAngles(item->ghoul2, 0, "thoracic", &thoracicAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); trap_G2API_SetBoneAngles(item->ghoul2, 0, "pelvis", &pelvisAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); trap_G2API_SetBoneAngles(item->ghoul2, 0, "r_d1_j2", &thumbAngle, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); trap_G2API_SetBoneAngles(item->ghoul2, 0, "r_d2_j2", &pointerFingerAngle, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); trap_G2API_SetBoneAngles(item->ghoul2, 0, "r_d4_j2", &pinkyFingerAngle, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); eyeAngles[YAW] = -5.0f; trap_G2API_SetBoneAngles(item->ghoul2, 0, "leye", &eyeAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime); eyeAngles[YAW] = 5.0f; trap_G2API_SetBoneAngles(item->ghoul2, 0, "reye", &eyeAngles, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, 0, 0, uiInfo.uiDC.realTime);
  3. You're totally right, no botroutes included. I tried to include some by following a super old tutorial on laying them out and got the bots to move naturally throughout the maps, but it wasn't working correctly. They would run right up to your face and would only attack when outside of arms reach but closer than some distance. Ultimately I figured their random flailing was better than impaling themselves on your saber :\ I'll look around for a better tutorial on how to do that. If anyone has any links handy I'd appreciate it.
  4. Hi everybody, I've been working on a 2D fighting game mod for Jedi Academy called Jedi Fighter (something I started while in university and decided to finish near the release of TFA). Beta 2 was just released on Jan. 21, 2016 on moddb. I'd love to get the JKHub community to download it, try it out, and give me feedback. It's incredible that Jedi Academy still has such a vibrant modding scene and that you all are still putting out such high quality content, which is what spurred me to continue with the release. Some of the player models and lightsbaer models I'm using came from the downloads section on this site, and only in the case that the download states that permission is given to freely redistribute if credit is provided. I've cited you guys in the credits by name in game, in a CREDITS.txt, and in the README.txt. If anyone has any issue with their content being included, please let me know and I can remove it. Teaser video Note that I didn't touch the AI and didn't include botroutes (because apparently I was doing something wrong... bots would run up and not attack at all) so you'll want to play multiplayer for now. ---- BEGIN MARKETING ---- Features in beta 2 Fight as 10 characters from the Star Wars movies and expanded universe, each armed with unique force powers and devastating special movesFight in 5 arenas, from a Tie hangar bay, to turbolifts in the Deathstar, to the aftermath on HothFull widescreen support for 16:9 (1080p and 720p), 16:10, 4K and 21:9 resolutions! Or any custom resolution!A dynamic camera that gives a cinematic view of the actionAwesome title musicand much, much more!Feedback Your honest feedback is incredibly important and very much appreciated! Please post comments to the forums. I'll be checking them regularly so your comments will help shape the direction of the mod! If you would like to contribute by making maps, please reach out to me via email or messages, or post to the forums. I'd appreciate the help! Requirements: You'll need to install Jedi Academy, the OpenJK engine, and Jedi Fighter beta 2 to play. OpenJK download link (proper licenses included): JEDI FIGHTER beta 2 download link: Installation: Check out these installation instructions to get started. Unzip both Jedi Fighter beta 2 and the OpenJK engine to your Jedi Academy\gamedata directory. Right click on SETUP.BAT in the Jedi Academy\gamedata\jedifighter directory and choose "Run as Administrator".Run JF_CLIENT_OJK.BAT in your Jedi Academy\gamedata\jedifighter directory to get started. Configure your controls, max out your video settings and resolution, and have fun! If you have any issues, check out the detailed instructions in jedifighter\_README_.txt. If you still have problems, feel free to post in the forums or here. Future plans: I'll try to get some dedicated servers running in the next few weeks, and will be setting up some play sessions on my own machine. Stay tuned to moddb for details! JEDI FIGHTER will continue to be improved until the v1.0 release near June, 2016, with a beta 3 in the next two months. Beta 3 will focus on a few key areas: improved AI based on neural networksbalancing and adding fighters (including from Star Wars: The Force Awakens)improved user experience with the server browser and match making---- END MARKETING ---- Feature details Since this is JKHUB, I can go into technical details on of the features. Yay! I'm planning on making sure all of my own asset sources and the full source code are eventually made available. Right now I've got a local SVN repo that is 12 years old so want to make sure I don't lose history converting it to git and putting it up. Customizable fighter sets: The fighters are defined in jedifighter/fighters/%FIGHTER_SET_NAME%/*.fighters text files. The %FIGHTER_SET_NAME% is stored in a server CVAR and sent over to the clients for loading files. However, I hardcoded the value of that CVAR to "default" in beta 2 but it will be hopefully unlocked in beta 3. The intention of this is to allow server operators to make their own fighters altogether. An example of a .fighter file is shown below. The format sucks since I was naive about 10 years ago when I came up with it. but it "works" for now. The format shows that each fighter has a fighterinfo block that define models, skins, sabers, and the saberstyle enforced on the client, and then a moves section. Each move has an attack or a "program" that is triggered when the combo is matched (more on "programs" below). Combos are defined as a string of buttons that must be pressed in sequence, with the min and max time from the previous button being defined. I am going consider coming up with a way to customize fighters in game while on a server with some kind of constraints (e.g. powerful moves require a certain combo complexity, and measure the complexity of the combo based on adjacency of buttons, time between presses, length of combo, etc). fighter Carnor_Jax { fighterinfo { description 'Blah blah' alignment dark model_path carnor_jax skin_path default saberstyle staff saber1 jf_carnorjax saber2 none } moves 12 { inherits none move Kanos'_Revenge { attack LS_A_JUMP_T__B_ combo { comboinfo { clearable yes min_input_time 20 max_input_time -1 } buttons 4 { button BUTTON_RIGHT -1 -1 button BUTTON_DOWN 10 2000 button BUTTON_RIGHT 10 600 button BUTTON_VERTICAL_ATTACK -1 -1 } } } move Lunge { attack LS_A_LUNGE combo { comboinfo { clearable yes min_input_time 20 max_input_time -1 } buttons 3 { button BUTTON_DOWN -1 -1 button BUTTON_RIGHT 10 600 button BUTTON_HORIZONTAL_ATTACK -1 -1 } } } move Back_Stab { attack LS_A_BACKSTAB combo { comboinfo { clearable yes min_input_time -1 max_input_time -1 } buttons 3 { button BUTTON_DOWN -1 -1 button BUTTON_LEFT 10 600 button BUTTON_HORIZONTAL_ATTACK -1 -1 } } } move Backward_Kick { attack LS_KICK_B combo { comboinfo { clearable no min_input_time -1 max_input_time -1 } buttons 2 { button BUTTON_LEFT -1 -1 button BUTTON_ALT_ATTACK 10 600 } } } move Spin_Kick { attack LS_KICK_S combo { comboinfo { clearable yes min_input_time -1 max_input_time -1 } buttons 3 { button BUTTON_DOWN -1 -1 button BUTTON_LEFT 10 600 button BUTTON_ALT_ATTACK -1 -1 } } } move Forward_Kick { attack LS_KICK_F combo { comboinfo { clearable no min_input_time -1 max_input_time -1 } buttons 1 { button BUTTON_ALT_ATTACK -1 -1 } } } move Horizontal_Slash { attack LS_A_L2R combo { comboinfo { clearable no min_input_time -1 max_input_time -1 } buttons 1 { button BUTTON_HORIZONTAL_ATTACK -1 -1 } } } move Vertical_Slash { attack LS_A_T2B combo { comboinfo { clearable no min_input_time -1 max_input_time -1 } buttons 1 { button BUTTON_VERTICAL_ATTACK -1 -1 } } } move Schmetterling { program LS_BUTTERFLY_LEFT permissives 3 combo { comboinfo { clearable yes min_input_time -1 max_input_time -1 } buttons 3 { button BUTTON_DOWN -1 -1 button BUTTON_LEFT 10 600 button BUTTON_VERTICAL_ATTACK -1 -1 } } } move Hammer_Blow { program LS_A3_SPECIAL permissives 3 combo { comboinfo { clearable yes min_input_time -1 max_input_time -1 } buttons 3 { button BUTTON_RIGHT -1 -1 button BUTTON_RIGHT 10 600 button BUTTON_VERTICAL_ATTACK -1 -1 } } } move Kanos_Killer { program LS_STAFF_SOULCAL permissives 3 combo { comboinfo { clearable yes min_input_time -1 max_input_time -1 } buttons 3 { button BUTTON_DOWN -1 -1 button BUTTON_RIGHT 10 600 button BUTTON_VERTICAL_ATTACK -1 -1 } } } move Force_Saber_Throw { program FORCE_SABER_THROW permissives 1 combo { comboinfo { clearable yes min_input_time -1 max_input_time -1 } buttons 3 { button BUTTON_DOWN -1 -1 button BUTTON_RIGHT 10 600 button BUTTON_ALT_ATTACK -1 -1 } } } } } Fighter "programs" and an interpreter to perform the special moves Fighter programs are text files found in jedifighter/fighters/%FIGHTER_SET_NAME%/programs/*.program that the character designer can use to create special moves. The files contain a set of instructions that are run in a fighter program interpreter on the server to enforce player movement, jumping, force power selections and activation, saber move execution, etc. when the special move is triggered. With this, I had a lot of flexibility to do timing correction to get rid of sliding feet, fire of particular moves, combine saber moves and force powers, etc. Not to mention it let me finish up defining all of the force power and other special moves in about 5 minutes apiece. Well worth the time to implement the interpreter 3 days before release so I could get it done in time! Each program can have up to 32 commands, and there can be a total of 256 programs on a server at any point in time. Any client can only execute one program at a time right now, but that's all I needed for now. The execution of a program is a bit strange. When a fighter executes a move with an associated program, a pointer to that program is added to the client and an instruction pointer is created which iterates through the instructions. Instructions will all be run at the same moment in time by wall clock unless a WAIT or WAITUNTIL command is encountered, in which case it will wait to resume execution. This was needed to simultaneously activate force powers, start saber moves, enforce movement speeds, and then wait for a particular animation keyframe to change speeds, terminate the move, etc. All of the supported opcodes are listed below. Ones other than this will be ignored, and comments can be included in the files. typedef enum { JFOP_NOP, // nothing JFOP_WAIT, // time period (ms) JFOP_WAITUNTIL, // absolute time since start (ms) JFOP_SETMOVE, // up, right, forward vector for pmove JFOP_CLEARMOVE, // nothing, unsets the JF_PROGRAMSTATE_MOVING bit from the fighter program state JFOP_JUMP, // velocity JFOP_PLAYSOUND, // sound JFOP_PLAYANIM, // target (legs, torso, or both), anim, start frame, end frame, speed scale JFOP_SETSABERMOVE, // move number JFOP_SETFORCEPOWER, // force power index to become active, the force level, and start using it by setting JF_PROGRAMSTATE_FORCEON JFOP_CLEARFORCEPOWER, // stop using the active force power JFOP_MAX } fighterOpCodes_e; An example fighter program is listed below. program PAPILLON { JFOP_SETSABERMOVE 24 JFOP_SETMOVE 0 0 127 JFOP_WAITUNTIL 550 JFOP_SETMOVE 0 0 60 JFOP_WAITUNTIL 900 JFOP_SETMOVE 0 0 127 JFOP_WAITUNTIL 1500 JFOP_SETMOVE 0 0 80 JFOP_WAITUNTIL 2350 JFOP_SETMOVE 0 0 60 JFOP_WAITUNTIL 2700 JFOP_SETMOVE 0 0 0 JFOP_WAITUNTIL 2800 JFOP_SETSABERMOVE 0 JFOP_CLEARSABERMOVE } Cinematic camera There is a third person camera which has a ton of CVARs to control the FOV, origin offsets from the target, absolute viewangle offsets, settling times (using an ideal low pass filter on the position and viewangles setpoints to create the current position and viewangles -- smoothing), and others. All of the relevant CVARs are shown below, but use them with caution because fighting is constrained to a particular fighting plane orientation and you could end up with the camera pointing off to nowhere! vmCvar_t cg_jediFighterCam; vmCvar_t cg_jediFighterCamInterpolate; vmCvar_t cg_jediFighterCamSettlingTime; vmCvar_t cg_jediFighterCamFollowEnemyZ; vmCvar_t cg_jediFighterCamAutoYaw; vmCvar_t cg_jediFighterCamYaw; vmCvar_t cg_jediFighterCamPitch; vmCvar_t cg_jediFighterCamRoll; vmCvar_t cg_jediFighterCamOffsetX; vmCvar_t cg_jediFighterCamOffsetY; vmCvar_t cg_jediFighterCamOffsetZ; vmCvar_t cg_jediFighterCamRangeX; vmCvar_t cg_jediFighterCamRangeY; vmCvar_t cg_jediFighterCamRangeZ; vmCvar_t cg_jediFighterCamFovX; vmCvar_t cg_jediFighterCamFovY; Map entities and fighter plane The maps all have their .map source included in jedifighter\maps\mp\*.map. A special spawn point entity was added for jedifighter to define where the spawn will happen, and if the spawn is the left side or the right side. If these don't exist, your map will cause a client to exit the server with an error. Examples of the info_jedifighter_start entities from jf_test.map are shown below, where side 0 corresponds to the left, and side 1 corresponds to the right. // entity 15 { "classname" "info_jedifighter_start" "origin" "-56 0 -16" "side" "0" } // entity 16 { "classname" "info_jedifighter_start" "origin" "64 0 -16" "side" "1" } Right now, the fighters are constrained to 2D motion in one particular plane orientation. The plane normal is along the Y axis. This means you need the Y and Z components of the origin key for the info_jedifighter_start entities to be the same. In the future, I'll consider allowing them to fight along a dynamic fighter plane (and possibly add sidestepping), enabled by a CVAR for a map, but for now this is a hard rule or things won't work right... Map autorun scripts: When a map is loaded, a corresponding .jedifighter script (console commands) from the same directory is executed on the server and on each client. For example, if maps/mp/jf_test.bsp was loaded, then maps/mp/jf_test.jedifighter would get executed. In this script you can set any CVARs. The intention of this was to customize the number of rounds, camera settings, fighter sets, or anything else particular to that map. An example of a .jedifighter file for jedifighter/maps/mp/jf2_fire.jedifighter is shown below: seta cg_thirdperson "1" seta cg_jediFighterCam "1" seta cg_jediFighterCamYaw "0" seta cg_jediFighterCamPitch "0" seta cg_jediFighterCamRoll "0" seta cg_jediFighterCamOffsetX "0" seta cg_jediFighterCamOffsetY "100" seta cg_jediFighterCamOffsetZ "4" seta cg_jediFighterCamRangeX "0" seta cg_jediFighterCamRangeY "0" seta cg_jediFighterCamRangeZ "0" seta cg_jediFighterCamFovX "0" seta cg_jediFighterCamFovY "0" seta cg_jediFighterCamInterpolate "1" seta cg_jediFighterCamFollowEnemyZ "0" seta cg_jediFighterCamAutoYaw "1" g_jf_timelimit 60 g_jf_rounds 3 r_drawfog 1 r_we gustingwind r_we gustingwind There are more novelties which I'll post about later. As always, thank you for taking the time to read this, playing, and for your feedback! -- Adnan
×
×
  • Create New...