Quake3World.com Forums
     Programming Discussion
        Entity flags aren't being transmitted / cgame issues


Post new topicReply to topic
Login | Profile | | FAQ | Search | IRC




Print view Previous topic | Next topic 
Topic Starter Topic: Entity flags aren't being transmitted / cgame issues

Insane Quaker
Insane Quaker
Joined: 16 Sep 2010
Posts: 384
PostPosted: 06-06-2018 09:54 AM           Profile Send private message  E-mail  Edit post Reply with quote


Hello! I haven't been here in a while, but I've recently released the first version of a mod I've been working on called Uber Arena, which you can read about here: http://www.celephais.net/board/view_thread.php?id=61575

So the development of the mod has mostly been going pretty smooth so far, but I recently ran into a huge roadblock that's preventing me from implementing a very important visual clarity feature in the mod, and I've tried for 3 days coming up with various complicated attempted solutions that either don't work or present other issues.

This will be a lengthy post, so hopefully I've gotten all the relevant information in here. Anyway...

To start things off, the trademark mechanic of this mod is uberweapons, which work like this: you collect 3 of the same weapon without dying in between, and that weapon gets upgraded into its uberweapon version. The way this mechanic works in the code is that it uses a set of integer counters corresponding to each non-starter weapon, located in the gclient_s structure in g_local.h. Each time a weapon is picked up, that weapon's corresponding counter is incremented. Once the counter reaches 3, any uberweapon-specific functionality will start running. The uberweapons are not technically new, separate weapons - that would be impossible for me to do, because that would require defining 7 new weapons in weapon_t, which would exceed the MAX_WEAPONS limit of 16 as defined in q_shared.h - and of course I can't change that limit without totally screwing up the entire game. q_shared.h is pretty much untouchable for mods apart from a very few select sections.

Now, from a pure gameplay perspective, all of the uberweapon-related mechanics work just fine. But now I'm moving onto visual / audio coding, which of course involves doing a lot of work in cgame. To attempt to communicate with the client game, I defined 7 new entity flags in bg_public.h, which can be set in game and then - well, in theory anyway (more on that in a minute) - be read in cgame. Each time an uberweapon counter hits 3, the game will turn on the appropriate uberweapon flag with the intention of allowing cgame to know that the player has an uberweapon. Here are the flags and their values, respectively (they follow the hex notation format and sequencing as with the other eflags):

Code:
#define EF_UW_SHOTGUN 0x01000000 // explosive shotgun
#define EF_UW_GRENADE 0x02000000 // multi grenade
#define EF_UW_ROCKET 0x04000000 // homing rocket
#define EF_UW_LIGHTNING 0x08000000 // arc lightning
#define EF_UW_PLASMA 0x10000000 // ion plasma
#define EF_UW_RAIL 0x20000000 // toxic rail
#define EF_UW_BFG 0x40000000 // bfg30k


So when a player holds an uberweapon I want to draw a ring model with an energy orb shader that moves around the torso of the player. In theory, I should be able to do this by accessing EF_UW_SHOTGUN flag from cent->currentState.eFlags. I have the following code in the CG_Player function in cg_players.c:

Code:
if (cent->currentState.weapon == WP_SHOTGUN && (cent->currentState.eFlags & EF_UW_SHOTGUN))
{         
memcpy(&orbs, &torso, sizeof(torso));      
orbs.hModel = cgs.media.uberShotgunOrbModel;      
orbs.customSkin = 0;      
VectorCopy(torso.origin, orbs.origin);      
spinAngles[1] = cg.time * -0.2;      
AnglesToAxis(spinAngles, orbs.axis);      
trap_R_AddRefEntityToScene(&orbs);   
}


Now, without the (cent->currentState.eFlags & EF_UW_SHOTGUN) in the if condition, the game does correctly respond to the player having the shotgun currently in use or not. So it can clearly read what player the weapon is using just fine. However, with the condition checking for the EF_UW_SHOTGUN flag, the code doesn't execute at all. I did a CG_Printf test of the value returned by (cent->currentState.eFlags & EF_UW_SHOTGUN) above the if statement and it returns 0 even if I have an uberweapon, proving that the cgame code isn't responding to the changes in cent->currentState.eFlags.

I tried several methods to get this to work. Then I wrote this code in the PmoveSingle function in bg_pmove.c and it somehow started working:

Code:
if (pm->ps->stats[STAT_UBERS] & UW_SHOTGUN)
{      
pm->ps->eFlags |= EF_UW_SHOTGUN;   
}


So this kind of works, but the problem is that only -> I <- have this effect (checking with cg_thirdperson 1). But if you look at another player who is currently using an uberweapon, the effect does not show up on them, even though they too should have those flags set. I tried messing with the renderfx settings like RF_THIRD_PERSON and RF_FIRST_PERSON, but none of those have worked. I don't know why, because there's this section of Team Arena code also in the CG_Player function that controls the floating skull heads that appear when a player has Kamikaze:

Code:
if ( cent->currentState.eFlags & EF_KAMIKAZE )
{
memset( &skull, 0, sizeof(skull) );      
VectorCopy( cent->lerpOrigin, skull.lightingOrigin );      
skull.shadowPlane = shadowPlane;      
skull.renderfx = renderfx;      

if ( cent->currentState.eFlags & EF_DEAD ) {         
// one skull bobbing above the dead body         
angle = ((cg.time / 7) & 255) * (M_PI * 2) / 255;         
if (angle > M_PI * 2)            
angle -= (float)M_PI * 2;         
dir[0] = sin(angle) * 20;         
dir[1] = cos(angle) * 20;         
angle = ((cg.time / 4) & 255) * (M_PI * 2) / 255;         
dir[2] = 15 + sin(angle) * 8;      
VectorAdd(torso.origin, dir, skull.origin);
<goes on from here...>


This isn't the full code, but you can still see that also relies on flags (EF_KAMIKAZE and EF_DEAD), and it works fine there. In Team Arena, if another player has Kamikaze - in other words, they have EF_KAMIKAZE enabled, you can see the floating skulls around them, and it also reacts appropriately if the player is dead. But in my mod, if another player has an uberweapon and its respective flag enabled, I can't see their uberweapon effect, only my own (from my point of view, in cg_thirdperson 1). Why does it work in the former case, and not in my case?

Here's another problem: Even though the CG_Player function can now read (cent->currentState.eFlags & EF_UW_SHOTGUN) because of the code I put in bg_pmove.c from earlier, it doesn't seem to be reflected everywhere in cgame. In cg_ents.c, in the CG_Missile function, it seems like it can't read cent->currentState.eFlags, even though CG_Player can. In this case I want homing rockets fired from an upgraded rocket launcher to play a beeping noise. As with EF_UW_SHOTGUN, I put the following code in PmoveSingle, right underneath the one for the shotgun:

Code:
if (pm->ps->stats[STAT_UBERS] & UW_ROCKET)
{   
pm->ps->eFlags |= EF_UW_ROCKET;   
}


And here is a snippet of the missile code, with my tracking code at the bottom:

Code:
// add missile sound   
if ( weapon->missileSound )
{      
vec3_t   velocity;      
BG_EvaluateTrajectoryDelta( &cent->currentState.pos, cg.time, velocity );      
trap_S_AddLoopingSound( cent->currentState.number, cent->lerpOrigin, velocity, weapon->missileSound );
// right below is my code            
if (weapon->trackSound && cent->currentState.eFlags & EF_UW_ROCKET) {         
trap_S_AddLoopingSound(cent->currentState.number, cent->lerpOrigin, velocity, weapon->trackSound);      
}   
}


It is perfectly capable of reading and retrieving values from its position and entity index (cent->currentState.pos and cent->currentState.number, respectively). However, it seems to completely ignore the entity flags I set for it (cent->currentState.eFlags & EF_UW_ROCKET). Why does it read the position / entity index properly, but not my flags? What's even stranger is that in CG_AddEntity, the function that calls CG_Missile, when I do a CG_Printf debug test to check the value of (cent->currentState.eFlags & EF_UW_ROCKET), it prints the int value of its hex constant, so it reads it properly there, just that for some reason it completely drops it when it gets passed into CG_Missile. And yes I tried stuff like assigning it to a boolean variable and passing it into CG_Missile (both by value and via a pointer to its address), but it always ends up coming out false after being passed, even if it was true in CG_AddEntity. Kind of defeats one of the main purposes of a function if it's just going to drop whatever I pass in, no?

This is a lot to take in, so I'll just summarize my goals here - I want to:

- Create a visual effect that displays on any player that is currently using an uberweapon.
- Make homing rockets play a targeting alert sound if they are fired by a player using a Homing Rocket Launcher.

Two goals that sound very simple to achieve in theory, but apparently are monstrously difficult in practice.

Thanks for any assistance in advance!



_________________
EmeraldProductions
http://emeraldproductions.weebly.com/index.html


Top
                 

Grunt
Grunt
Joined: 19 Sep 2012
Posts: 64
PostPosted: 06-08-2018 01:05 AM           Profile Send private message  E-mail  Edit post Reply with quote


Don't take this as guaranteed but as far as I know flags beyond 0x00800000 aren't tansmitted. There is a small hint at bg_public.h in Enemy Territory source code (should be the same for Q3): https://github.com/etlegacy/etlegacy/bl ... lic.h#L736
I didn't test your code though...
Do you have set up a github project?




Top
                 

Insane Quaker
Insane Quaker
Joined: 16 Sep 2010
Posts: 384
PostPosted: 06-11-2018 01:47 PM           Profile Send private message  E-mail  Edit post Reply with quote


Haven't previously, but I took the time to get one quickly set up here:
https://github.com/EmeraldTiger/Uber-Arena

(First time using GitHub to upload a real project, so forgive me if it's a bit messy :p)

Has a Visual Studio solution file provided in the /code folder.

As for the flags, I did a test by replacing the EF_UW_ROCKET flag with EF_AWARD_DENIED flag (since the game never uses it) which is below the client threshold, but it still demonstrates the same issues.



_________________
EmeraldProductions
http://emeraldproductions.weebly.com/index.html


Top
                 

Grunt
Grunt
Joined: 19 Sep 2012
Posts: 64
PostPosted: 06-11-2018 04:12 PM           Profile Send private message  E-mail  Edit post Reply with quote


Okay, I had a quick look at your code, but I have to investigate all the details...
Meanwhile I did a simple test to archive what you are looking for, the good news, it works well!
The bad news: currently I don't know why it doesn't work with your code changes.

Meanwhile you can do he following (just a suggestion):

1. Use an unmodiefied code as base.
2. Put in the code you wrote in 'Pickup_Weapon' like:
int increase;

if (ent->item->giTag == WP_ROCKET_LAUNCHER) {
if (other->client->rocketCounter < 3) {
other->client->rocketCounter += increase;

if (other->client->rocketCounter == 3) {
other->client->ps.eFlags |= EF_UW_ROCKET;
}
}
}
3. Now replace EF_UW_ROCKET with EF_KAMIKAZE (just to test the code)
4. Compile the code and start the game (and the mod), best to start any map in CTF mode.
5. You'll see that as soon as you picked up the RL 3 times, the Kamikaze skulls will spin around you player model. Add a few teammates and let them pick up the RL 3 times too, they also have spinning skulls now :)

So, your idea is doable, it is working, the reason why it isn't working with all the changes you made is not clear to me atm. Maybe you 'overdo' something. You see you only Need an EF_XX flag to transmit this to cgame. You have a bunch of EF_ flags, you have EV (events) and a STAT_ field. All of those are possible to do the same (transmit the thing you want to transmit), probably I don't understand exactly what you want to do, or why you Need all of them, but I think this is too much. If you only want to have a cgame effect (rings) and possibly a Sound than an entity flag (EF_) is enough.




Attachments:
emerald_test_01.jpg
emerald_test_01.jpg [ 101.33 KB | Viewed 54 times ]
Top
                 

Grunt
Grunt
Joined: 19 Sep 2012
Posts: 64
PostPosted: 06-13-2018 10:58 AM           Profile Send private message  E-mail  Edit post Reply with quote


Okay, I had a closer look on the code changes you made.
Please don't get me wrong, but I really think you should start from scratch. There are a few things that aren't done well.
For example you modiefied things in bg_pmove that won't work 'Pmove', 'PmoveSingle', or at least I don't understand what the changes are made for, (the same is true for 'PM_Weapon(finished)', for what is 'finished' for, ist not used)?
NOTE: for the visual effect that displays on any player that he is currently using an uberweapon, no changes are required in bg_pmove. As a general rule, try to modify bg_pmove ONLY if you really know what you are doing!

In my last post I said I don't know what prevents your code from working, well, I'm still not sure but I think the main problem is caused by the changes you made (mainly) in the game module (g_active.c, g_items.c and bg_pmove.c). For example, I don't understand why you set the EF_UW flags in 'ClientEvents', was this a test, or is this needed for some other aspect of your code changes to work? BTW, why do you move the code dealing with the holdable item usage from bg_pmove.c to g_active.c? I think this causes various issues.

Well, to make things short, your code changes aren't that much, so again I highly recommend to start from scratch. Fixing your project seems like a huge task (at least for me), so I'm really sorry!
But wait, you are on Github now :up: . This makes things easier, for you, and for people that should help you. So here are again a few things I highly recommend. Please keep in mind that these are only personal thoughts and well-intentioned tips, I do not want to sound overbearing.

1. If you only want to make a mod (not a total conversation) you can also use ioquake3 as base for your mod. ioquake3 game modules are updated and are bugfixed in many ways. Mods based on ioquake3 source code still work with Q3a (at least in theory).
2. Upload an umodified (ioquake3) source code onto Github, and start from scratch.
3. Do whatever you want to do with the code, you can easily check the changes due to Github's history, representing your changes, and you can easily revert bad changes.
4. Whenever you change your code make a comment of what is changing and why you change it (this will help people to understand your intention when they try to help you), and I suggest to not write print messages with 'eeee' or 'can you read' this, you won't benefit when hunting down nasty issues :)
5. If you copy code from other projects it is okay (as long as the GPL says so), but copy all the things that are necessary, somehow it seems to me you copied only parts of a features from other mods (?), maybe I'm wrong.
6. You have a 'very indiviual' coding style imo (e.g.: in cg_weapons.c you don't really need STAT_UBERS just to change the weapon name, I mean it's okay, but unusal. This is some kind of coding style/preference, which can influence bugtracking as your project grows... So maybe it would be better to keep the current way of how the idtech3 code is structured.
7. Github also has an issue tracker, if people are interested in what you are working on they eventually will participate and help.

Okay, I still think you have cool ideas, and I'm really interested in your mod, but I'm a bit lost with your code changes, and I can't fix your code easily.
I hope I didn't sound too harsh! Good luck!




Top
                 

Insane Quaker
Insane Quaker
Joined: 16 Sep 2010
Posts: 384
PostPosted: 06-13-2018 11:54 AM           Profile Send private message  E-mail  Edit post Reply with quote


Hey man, no problem. I really appreciate your honesty and insight, and you're absolutely right - the mod was very much built with a "solitary" mindset and much of what I wrote was simply trying to get things to work without looking at the bigger picture of maintainability or collaboration.

There's a bunch of experimental stuff that I wrote in an attempt to make the uberweapon effect code work that I ended up leaving behind. The ClientEvents stuff, for example, was one of those attempts - which kind of worked, but the player's shader effect would constantly "blink" and once the player had more than two uberweapons it would start to not render other uberweapon effects, probably because of too many events. Similar code in pmove was yet another example that didn't work out. (There's also a bunch of code for so-far failed attempts or experiments at features that never made it in, such as upside-down gravity surfaces)

As for moving the holdable code to g_active, I did this because I had to access code that was not accessible in bg_pmove.c, since that module only has access to game information common between game and cgame. I wouldn't be able to access the uberweapon Counters in bg_pmove.c, for example, because they're declared in g_local.h, which bg_pmove.c has no access to. In general I found that being in bg_pmove.c was too restrictive for my purposes, which is why I moved it. So far I haven't had any issues that would seem to stem from it, and it has worked okay for me, but I'm sure there's probably a better way of doing it (though I'm not sure what it'd be). The only other method I can think of would be keeping it in bg_pmove.c but passing in variables from g_active.c to the Pmove function, then to PmoveSingle, and then finally to PWeapon, but just straight-up moving the code seemed simpler to me.

I did use a fresh, from-scratch codebase to test the kamikaze stuff, and the skulls appear fine with EF_KAMIKAZE. But then I did a test where I replaced all instances of EF_KAMIKAZE in the source with my own custom flag (apart from the initial declaration, of course), and suddenly it stops working. Same thing happens when I replace it with the otherwise unused EF_AWARD_DENIED. Which is weird since in theory it should still work, as the only thing different is the flag being set.

I'll be the first to admit that I have never worked in a collaborative programming environment, nor have I really took the time to use a proper versioning system, use pull requests, etc. I can see now that it is something I should take more seriously, so I'll definitely make an effort to learn more about how to make a more maintainable programming environment. I was always a bit intimidated by it but hopefully it isn't as difficult as I think it is (in the long run it would make things easier, I realize).

I'll also give ioquake3 source a try and see if it may work better / solve my issues. The codebase I've been using is based on https://github.com/id-Software/Quake-III-Arena. If I can get ioquake3 set up for Visual Studio 2017 then that'd be awesome.

Once again, many thanks for your honesty and suggestions. I think a wake-up call is exactly what I needed. Even if I start from scratch it shouldn't take too long to get things back up to where they are now, but hopefully it will be a lot cleaner.

EDIT: Just downloaded the pure ioq3 source and tested the Kamikaze effect with my own entity flag as before (no other code changes). Still not showing up for any flag other than EF_KAMIKAZE. Very strange.



_________________
EmeraldProductions
http://emeraldproductions.weebly.com/index.html


Top
                 

Insane Quaker
Insane Quaker
Joined: 16 Sep 2010
Posts: 384
PostPosted: 07-26-2018 03:23 PM           Profile Send private message  E-mail  Edit post Reply with quote


(disregard; got some help over on ioquake3 for an issue related to .qvm compiling)



_________________
EmeraldProductions
http://emeraldproductions.weebly.com/index.html


Top
                 

Grunt
Grunt
Joined: 19 Sep 2012
Posts: 64
PostPosted: 08-09-2018 02:33 PM           Profile Send private message  E-mail  Edit post Reply with quote


Yeah, I'm following you at Github, and I followed your discussion at the ioquake3 forum.
I'm glad to see you making progress. Well done soldier!




Top
                 
Quake3World.com | Forum Index | Programming Discussion


Post new topic Reply to topic


cron
Quake3World.com
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group