Fardreamer Posted August 9, 2002 Share Posted August 9, 2002 I'm trying to find the code that checks whether the attack button has been let go of before having been pressed again, i.e., how you can tell the difference between semi- and auto fire modes. The idea is to force a new button press for every saber move. Any ideas where it's located? Link to comment Share on other sites More sharing options...
ASk Posted August 9, 2002 Share Posted August 9, 2002 you use 2 things: 1) add a qboolean variable in gentity_t struct to set if the client has fired. Set it to true in the function 2) in g_active.c put code similar to: if ( (pm.cmd.buttons & BUTTON_ATTACK) && ent->client->ps.pm_type != PM_DEAD && ent->client->fired==qfalse) { // your code here to call the firing function this will fire when USE button is pressed. 3) in g_active.c: if ( !(pm.cmd.buttons & BUTTON_ATTACK) ) { fired=qfalse; } or similar method. This may not work, I never tested it, but basically: on first call set a var to true. call subsequent calls only if it is false. on button release set it to false. Link to comment Share on other sites More sharing options...
Fardreamer Posted August 9, 2002 Author Share Posted August 9, 2002 Well, sure, that's all very nice, but where would you put that in g_active.c? I've tried many similar things, but none were very successful... that's why I'm trying to go deeper by manipulating the code that sets the BUTTON_ATTACK bitflag. Link to comment Share on other sites More sharing options...
ASk Posted August 9, 2002 Share Posted August 9, 2002 my code for similar function is in: void ClientThink_real( gentity_t *ent ) after this line: SendPendingPredictableEvents( &ent->client->ps ); Link to comment Share on other sites More sharing options...
Fardreamer Posted August 9, 2002 Author Share Posted August 9, 2002 That won't work because in bg_saber.c I have no access to the client data. If I had, I'd use ent->client->oldbuttons which is a bitflag table of the buttons pressed the previous time ClientThink_real was called. Link to comment Share on other sites More sharing options...
Subject452 Posted August 9, 2002 Share Posted August 9, 2002 That won't work because in bg_saber.c I have no access to the client data. If I had, I'd use ent->client->oldbuttons which is a bitflag table of the buttons pressed the previous time ClientThink_real was called. cough*pm->cmd.buttons*cough Link to comment Share on other sites More sharing options...
ASk Posted August 9, 2002 Share Posted August 9, 2002 2) in g_active.c put code similar to: if ( (pm.cmd.buttons & BUTTON_ATTACK) && ent->client->ps.pm_type != PM_DEAD && ent->client->fired==qfalse) { // your code here to call the firing function Didn't I say that too??? Link to comment Share on other sites More sharing options...
Fardreamer Posted August 9, 2002 Author Share Posted August 9, 2002 I was tricked by that too... ucmd.buttons is not client->buttons, it's two different structs. One is everything relevant to the commands a local player is sending and the other is all the info pertaining the client in general. en->client has an oldbuttons value that keeps track of the buttons held down the previous time the function was called. Anyway, I solved it by adding a new player state to pm->ps. Thanks for your help! Link to comment Share on other sites More sharing options...
RenegadeOfPhunk Posted August 10, 2002 Share Posted August 10, 2002 Originally posted by Fardreamer Anyway, I solved it by adding a new player state to pm->ps. Thanks for your help! Can you elaborate on this a bit Fardreamer... I want to do a similar thing, but it says in code that you can't add anything to the playerState_t structure. (pm->ps). I tried - it causes a crash when you spawn a player... So what structure did you actually modify? So far, I've been using the eFlags member of the playerState_t, adding my own flag bits, but the eFlags bitfield seems to get reset or otherwise modified, so that I can't be sure the bit I set is going to STAY set...!! Link to comment Share on other sites More sharing options...
RenegadeOfPhunk Posted August 10, 2002 Share Posted August 10, 2002 Please ignore my last post. I've just realised my cgame project wasn't creating it's dll in the right place - so I wasn't actually running it!!!!!! *slaps forehead several times!!!* No wonder I was getting strange results...! Using eFlags seems to work fine, and are avaliable in both the areas of code previously talked about. (Well - I've got it to work anyway - so...) Link to comment Share on other sites More sharing options...
ASk Posted August 10, 2002 Share Posted August 10, 2002 you can't change the playerstate_t struct...it creates prediction problems. If they would include msg.c file, you could change them both, but msg.c is a part of the exe. Link to comment Share on other sites More sharing options...
Fardreamer Posted August 11, 2002 Author Share Posted August 11, 2002 It creates prediction problems? I've been using it up to now and it seems to work fine. Can you elaborate on this? I'm changing the whole system to queue-based: ClientThink_real adds any new button presses to a queue which is a member of playerState_t. The saber code then goes through the queue, each time popping the first one and reacting accordingly. My goal is to have one unique button press per saber move, but to avoid having to time your button presses perfectly. I.e, tapping left-mouse , right-mouse, left-mouse will do a left-to-right, right to-left, left to right three-slash-combo. Link to comment Share on other sites More sharing options...
Fardreamer Posted August 11, 2002 Author Share Posted August 11, 2002 Oh, and Renegade, could you elaborate as well on your use of eFlags? They didn't seem to work for me very well. Link to comment Share on other sites More sharing options...
RenegadeOfPhunk Posted August 11, 2002 Share Posted August 11, 2002 What I wanted to do was bind a 'defensive' mode to the right mouse button. But, I didn't want to hard-code this defensive mode straight to the right mouse button, in case I wanted to dynamically change it, or activate defensive mode from other sources other than user input. So - I wanted a flag which could be set in one place - i.e. the eFlag! The existing eFlags are all defines in bg_public.h. (About 1/3 of the way down the file...). They start with these lines: #define EF_DEAD 0x00000001 #define EF_BOUNCE_SHRAPNEL 0x00000002 #define EF_TELEPORT_BIT 0x00000004 Note that ones with the comment... //doesn't do anything ...above them are free to be used. So, I added a new flag: //RenegadeOfPhunk's new eFlags!! Rock on! #define ROP_DEFENDING_AGAINST_ENEMY 0x00008000 //Markes that we are currently in defensive mode I then set / unset this flag when the right mouse button is pressed in g_active.c: for ( i = 0 ; i < MAX_CLIENTS ; i++ ) { if (g_entities.inuse && g_entities.client) { pm.bgClients = &g_entities.client->ps; } } if(ent->client->buttons & BUTTON_ALT_ATTACK) { ent->client->ps.eFlags |= ROP_DEFENDING_AGAINST_ENEMY; } else { ent->client->ps.eFlags &= ~ROP_DEFENDING_AGAINST_ENEMY; } if (ent->client->ps.saberLockTime > level.time) { And then to check whether the flag is set: (e.g. in bg_saber.c - where I've made the player put the saber into the 'defensive' stance when in defensive mode) if (anim == BOTH_WALKBACK1 || anim == BOTH_WALKBACK2) { //normal stance when walking backward so saber doesn't look like it's cutting through leg anim = PM_GetSaberStance(); } if ((pm->ps->eFlags & ROP_DEFENDING_AGAINST_ENEMY) && !(pm->ps->inAirAnim)) { //For the moment, we want this stance all the time (except when jumping) //To look like were in a 'defensive' stance while moving //We might want to embellish this a bit later on... anim = PM_GetSaberStance(); } Hope that helps. (This seems to work fine for me...) Link to comment Share on other sites More sharing options...
ASk Posted August 11, 2002 Share Posted August 11, 2002 what i mean is: if you add another var or change the order of the existing vars, the game WILL go haywire. aka: // playerState_t is the information needed by both the client and server // to predict player motion and actions // nothing outside of pmove should modify these, or some degree of prediction error // will occur // you can't add anything to this without modifying the code in msg.c the above line is true. msg.c is a part of the engine source, which apparently states the server->client and client->server message format. That means, if we change the message size beyond expected, both the server and the client will have trouble getting and parsing the message. Which leads to deadly prediction errors and breaks the game totally. You ARE playing with fire here Link to comment Share on other sites More sharing options...
RenegadeOfPhunk Posted August 11, 2002 Share Posted August 11, 2002 Ask - I'm NOT changing ANYTHING about the playerState_t structure - I'm just setting one of the unused bits in the eFlags integer bitfield. How is that playing with fire...? Yes - if I was adding a new var to the structure then it will go wrong. (As I've found out already...). But setting a new eFlag doesn't make it go wrong - I know because I've done it... Link to comment Share on other sites More sharing options...
Fardreamer Posted August 11, 2002 Author Share Posted August 11, 2002 That's funny, because I added vars and it worked fine. But then I didn't run an online test. So how do you suggest I retrieve ent->client from the saber code without having to add a parameter to WeaponLightsaber()? Link to comment Share on other sites More sharing options...
RenegadeOfPhunk Posted August 11, 2002 Share Posted August 11, 2002 If you add a var to the playerState_t structure, it will compile fine. But the game crashes when you run it - for the reasons that Ask has already pointed out. (Specifically, for me anyway, it crashed when I tried to add a bot to the game...) But setting eFlags DOESN'T actually alter the playerState_t structure, so that's perfectly allowed, and it works... You cannot access the structure you specified (ent->client) from a lot of areas. (Like moving code and saber code) - BUT you can get access to the playerState_t structure from these areas - in the manner I have already specified earlier... (the bg_saber.c example) Link to comment Share on other sites More sharing options...
Fardreamer Posted August 11, 2002 Author Share Posted August 11, 2002 Compile doesn't check for logic errors, I know that. But I'm telling you it actually worked - as in, I played my mod. But it could be buggy when playing with a real opponent as opposed to a bot. In any case, your system won't work for me because I need a message queue which is an array of a new data type I defined. Link to comment Share on other sites More sharing options...
RenegadeOfPhunk Posted August 11, 2002 Share Posted August 11, 2002 If it did run, then I can only assume you didn't try to add a bot or play against other players - 'cos at that point it should crash... And I see that eFlags aren't gonna solve your particular problem. If I start trying to do something like that and I find the answer, I'll be sure to let you know... [edit] Just checked your post again. So you did spawn a bot and you played against it with the playerState_t structure changed..?! Can you please post EXACTLY what changes you made to the structure? [/edit] Link to comment Share on other sites More sharing options...
Fardreamer Posted August 11, 2002 Author Share Posted August 11, 2002 I added these two lines: struct attack_t saberAttackQueue[ATTACK_QUEUE_LENGTH]; int saberLastAttackTime; which were accessed and modified in ClientThing() and in WeaponLightsaber(). How about if added this stuff to pmove_t? Then I could access it from the saber code. edit: that stuff above didn't work properly... what worked was int saberLastAttackTime; int saberCurrentAttackTime; at the bottom of the struct - that was before I added the queue system. And pmove_t is cleared every frame so I guess that's no good. Link to comment Share on other sites More sharing options...
Fardreamer Posted August 12, 2002 Author Share Posted August 12, 2002 Well, in case you were wondering, I succeeded in implementing the queue by handling all the checking and queueing actions in ClientThink. When a queued attack needs to be executed, it sets an eFlag (as Renegade suggested) that tells the saber code that an attack is pending. The saber code performs the attack and clears this flag. Thanks for your help Link to comment Share on other sites More sharing options...
RenegadeOfPhunk Posted August 12, 2002 Share Posted August 12, 2002 No probs man - glad I could help Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.