Page 9 of 34

Re: Here's a wild idea: EntityPlus

Posted: Mon Apr 25, 2011 12:54 pm
by DaEngineer
I tried out the new version. There are some things I have to ask you about.

1. Can a func_breakable spit out the debris models when destroyed without having to target it a target_debrisemitter?
2. Is there a limit how many debris models are allowed to exist at the same time? When I target two target_debrisemitters, there are two fountains of debris and everything works fine. But as soon as I use three or more emitters, the debris models disappear a short moment after spawning
3. You wrote that damage scaling of bots is enabled now. But Visor pretty much owned me. How can the difficulty be changed?
4. Bots teleport out of the game when they die, which is very uncommon for SP enemies. Can you remove this effect and just let them stay where they are when they've died? Or let them sink into the ground?

Re: Here's a wild idea: EntityPlus

Posted: Mon Apr 25, 2011 2:59 pm
by obsidian
Eraser wrote:One thing: all 2D graphics are rendered to a 640x480 virtual screen which is then resized to the appropriate resolution. So keep in mind that if you make a 640x480 overlay, it'll cover the entire screen, no matter at what resolution your game is rendering.
Wouldn't it be best for all graphics be created on power-of-two dimensions? It still needs to be loaded into video memory and I assume that like textures, it will downsize dimensions to the nearest power-of-two. A 640x480 texture will be loaded into memory as a 512x256 block. That's why levelshots in Q3 are also in power-of-twos.

(Unless of course the "virtual screen" is some sort of workaround for this)

Hipshot wrote:I think it's a huge difference between the current shader and when I had another stage in them. Could you please replace the current with the following, then look at especially the gold and silver key.
Hmm... I only tested with the master key and couldn't see any difference. Reducing the number of texture stages can help with performance so I tried to minimize them with little visual difference, but didn't realize there may have been a bigger visual effect with the other keys.

BTW, you're using rgbGen vertex again on the first stage. Change this to rgbGen lightingDiffuse.

Re: Here's a wild idea: EntityPlus

Posted: Mon Apr 25, 2011 4:30 pm
by Eraser
I wouldn't know about the powers of two thing. I recall there being 2D assets that aren't in powers of 2 but I could be mistaken. My overlay is 512x192 and that works, but perhaps its not optimal memory wise?

I don't think the 640x480 thing is related to this. It just makes it easier to make and position assets if you can base everything on one resolution and have the scaling to the right res be a post processing step on the whole thing.

Re: Here's a wild idea: EntityPlus

Posted: Mon Apr 25, 2011 7:53 pm
by o'dium
Any 2d image is loaded in power of two, regardless of what resolution it actually is. This means a 640x480 texture will downsample to its nearest neighbour, meaning it will render at 512x256 ingame. Thus, it makes MUCH more sense to resize it to 512x512 while keeping the correct aspect ratio.

When loading any 2d image that isn't power of two keep in mind that not only is it going to look worse as the end result will be down sampled badly, but it will also be more system intensive, meaning it really doesn't pay at all to even bother doing it that way.

The 640x480 thing you sound like you are on about is screen sapce GUI coords. It makes sense to build a GUIat 640x480 as thats usually the lowest resoltion you will view it in. This is just for scaling pictures and positioning them onto the GUI. You could, for example, scale a 1024x1024 picture to 26x47 at X/Y coords on this UI and it would be fine (Although would look fucking horrible thanks to the resolution never matching).

Re: Here's a wild idea: EntityPlus

Posted: Mon Apr 25, 2011 9:31 pm
by ^misantropia^
I denounce this power-of-two heresy! From now on, we will only use image sizes that are powers of one!

Re: Here's a wild idea: EntityPlus

Posted: Mon Apr 25, 2011 11:51 pm
by spookmineer
Pong...?

Re: Here's a wild idea: EntityPlus

Posted: Tue Apr 26, 2011 8:33 am
by Eraser
I've been looking at Q3's 2D assets and o'dium is right. All of them are created in resolutions of powers of 2.

So my 512x192 placeholder overlay is not a good example. Then again, it's only a placeholder.

Re: Here's a wild idea: EntityPlus

Posted: Tue Apr 26, 2011 10:04 am
by Eraser
DaEngineer wrote:I tried out the new version. There are some things I have to ask you about.

1. Can a func_breakable spit out the debris models when destroyed without having to target it a target_debrisemitter?
Right now, unfortunately not. I tried getting this to work but have been successful so far. The thing is, a func_breakable is a brush entity that doesn't have an origin and the origin is needed to determine where the debris should be emitted from. You can set an origin key (or use an origin brush, but q3map translates that to an origin key) but for some reason, any entity with an origin key is made non-solid by q3map, so there's not much I can do about that.

I might be able to get this working if I dig a little deeper, but for now, my understanding of how "movers" work in Q3 is too limited to fix this.
DaEngineer wrote: 2. Is there a limit how many debris models are allowed to exist at the same time? When I target two target_debrisemitters, there are two fountains of debris and everything works fine. But as soon as I use three or more emitters, the debris models disappear a short moment after spawning
I'm not sure. I didn't put in a hard limit myself. Could be that the engine limits it. You could use the count key on target_debrisemitter to emit less bits of debris per entity.
DaEngineer wrote: 3. You wrote that damage scaling of bots is enabled now. But Visor pretty much owned me. How can the difficulty be changed?
Change the g_spskill cvar through the console. It ranges from 1 (easy) to 5 (hard) I think.
DaEngineer wrote: 4. Bots teleport out of the game when they die, which is very uncommon for SP enemies. Can you remove this effect and just let them stay where they are when they've died? Or let them sink into the ground?
Yeah good point, I'll look into this.

Re: Here's a wild idea: EntityPlus

Posted: Tue Apr 26, 2011 2:12 pm
by obsidian
^misantropia^ wrote:From now on, we will only use image sizes that are powers of one!
Voxels?

Re: Here's a wild idea: EntityPlus

Posted: Tue Apr 26, 2011 3:33 pm
by monaster
Great, now you got me thinking of starting a round of minecraft again. Goodbye real-life obligations :paranoid:

Re: Here's a wild idea: EntityPlus

Posted: Tue Apr 26, 2011 7:42 pm
by EmeraldTiger
obsidian wrote:
^misantropia^ wrote:From now on, we will only use image sizes that are powers of one!
Voxels?
id tech 6! :up:

Just looked at the new version. Even though it`s still very early on I think this mod has gone quite far since you first started it, with each update. Also, to Hipshot, Obsidian, and DaEngineer: very snazzy model work!

Dunno if this is tacked down yet, but if you gauntlet a bot (enemy), you still recieve a Humilation medal. I`m not sure if you want to keep this or not, but throwing it in just in case.

It would also be nice to have a message appearing if you don`t have the required key to open the door. It would make it more clear to the player that he was missing the key.

Good job. :up:

Re: Here's a wild idea: EntityPlus

Posted: Thu Apr 28, 2011 9:41 am
by akm
Great project, reminds of Quake1. Been watching this thread closely, hope it goes far :D

Re: Here's a wild idea: EntityPlus

Posted: Sat Apr 30, 2011 4:09 pm
by ShadoW_86
What's exactly the reason why there is no hud or crosshair :)?

Can I control bots so they won't jump or run?

Re: Here's a wild idea: EntityPlus

Posted: Sun May 01, 2011 6:13 am
by Eraser
ShadoW_86 wrote:What's exactly the reason why there is no hud or crosshair :)?
err, the reason is most likely that you have cg_draw2d set to 0? :paranoid:
ShadoW_86 wrote:Can I control bots so they won't jump or run?
Not at this time, no. The AI can be made a lot more SP-like, but I really have to sink my teeth in there because AI programming is something have have absolutely zilch knowledge on.

Re: Here's a wild idea: EntityPlus

Posted: Sun May 01, 2011 6:44 am
by Eraser
EmeraldTiger wrote:Dunno if this is tacked down yet, but if you gauntlet a bot (enemy), you still recieve a Humilation medal. I`m not sure if you want to keep this or not, but throwing it in just in case.
Yeah I noticed that the medal awards get kind of annoying, especially when gunning down hordes of enemies and the excellent award just keeps coming. So I removed all awards for single player mode.

Re: Here's a wild idea: EntityPlus

Posted: Sun May 01, 2011 10:50 am
by DaEngineer
Eraser wrote:
ShadoW_86 wrote:Can I control bots so they won't jump or run?
Not at this time, no. The AI can be made a lot more SP-like, but I really have to sink my teeth in there because AI programming is something have have absolutely zilch knowledge on.
This is something that could easily be changed by adding new bots with different behaviours to the bot list with the Bot Maker of yours. Of course it won't address the behaviour in general, but at least jumping and running could be fixed.

Re: Here's a wild idea: EntityPlus

Posted: Sun May 01, 2011 12:22 pm
by ShadoW_86
Eraser wrote:
ShadoW_86 wrote:What's exactly the reason why there is no hud or crosshair :)?
err, the reason is most likely that you have cg_draw2d set to 0? :paranoid:
Epic fail xP.

About bots - in lower skill modes they tend to not jump or even run (play with Crash on q3dm0 on lowest skill level). Maybe you could use that, and look into bot behaviour files to see why they don't do some things in lower skill levels. I remember there were bot files defining how to behave and what are they weapon preferances.

Also for the future - some kind of bot navigation system would be great :). The best scenario would be if we had new entity (or mybe even use info_bot_roam) with which we could set up simple paths and routes for bots navigation.

Also, there should be a sound when key_entity is used.

Re: Here's a wild idea: EntityPlus

Posted: Sun May 01, 2011 1:32 pm
by Perle
I have integrated debris in my mod. works well. But i don“t have the smoke trails. Is this set by the mapper in Radiant?

And why you have coded your breakable without launching something? This would be easier as doing the trigger thing with the debrisemitter.

Re: Here's a wild idea: EntityPlus

Posted: Sun May 01, 2011 2:09 pm
by Eraser
Perle wrote:And why you have coded your breakable without launching something? This would be easier as doing the trigger thing with the debrisemitter.
Explained before in this post.
I will some time look into a solution, but it's not a priority at this moment

Re: Here's a wild idea: EntityPlus

Posted: Sun May 01, 2011 6:21 pm
by Perle
Look at my Q3Rally Code. I have breakables with lauching particles.

http://q3rallysa.svn.sourceforge.net/viewvc/q3rallysa/

Re: Here's a wild idea: EntityPlus

Posted: Sun May 01, 2011 8:27 pm
by Eraser
Sorry if this seems like a dumb question, but where are your G_BreakGlass, G_BREAKWOOD and G_BREAKMETAL functions implemented? Also, I see my func_breakable code is in there. Seems identical to what I have except for calls to the above methods in g_combat.c, but I'm not sure they're related?

Re: Here's a wild idea: EntityPlus

Posted: Mon May 02, 2011 6:34 pm
by Perle
Look in g_misc.c there you can find the following code. :-)

Code: Select all

/*
 =================
 G_BreakGlass
 =================
 */
 void G_BreakGlass(gentity_t *ent, vec3_t point, int mod) {
	gentity_t   *tent;
    vec3_t      size;
	vec3_t      center;
    qboolean    splashdmg;
    
	// Lanz: Cleaned up compiler errors.

    // Get the center of the glass
    VectorSubtract(ent->r.maxs, ent->r.mins, size);
    VectorScale(size, 0.5, size);
    VectorAdd(ent->r.mins, size, center);
 
    // if the health of our glass brush is at 0 we'll break it
    if( ent->health <= 0 ) {
		G_FreeEntity( ent );
   
		switch( mod ) {
			case MOD_GAUNTLET:
				splashdmg = qfalse;
				break;
			default:
				splashdmg = qtrue;
				break;
		}

        // Now we call our EVs(Events) so that cgame can work on it
        switch( splashdmg ){
			case qtrue:
				tent = G_TempEntity( center, EV_BREAK_GLASS );
				tent->s.eventParm = 0;
				break;
			case qfalse:
				tent = G_TempEntity( point, EV_BREAK_GLASS );
				tent->s.eventParm = 0;
				break;
		}
     }
 }
  /*QUAKED func_breakwood (1 0 0) (-16 -16 -16) (16 16 16)
    we have breakable wood  
  */
 void SP_func_breakwood( gentity_t *ent ) {
  int health;
 
  // It's a model brush , show it
  trap_SetBrushModel( ent, ent->model );
  // the default health will be set to 25
  G_SpawnInt( "health", "0", &health );
  if( health <= 0 )
   health = 50;
 
  // set health on the function
  ent->health = health;
  // our function can receive damage
  ent->takedamage = qtrue;
  // that's our new ET(EntityType)
  ent->s.eType = ET_BREAKWOOD;
  // additional brush model
  if ( ent->model2 ) {
      ent->s.modelindex2 = G_ModelIndex( ent->model2 );
  }
  // link the entity ( otherwise nothing will work :) )
  trap_LinkEntity (ent);
 }

 /*
 =================
 G_BREAKWOOD
 =================
 */
void G_BREAKWOOD(gentity_t *ent, vec3_t point, int mod) {
	gentity_t   *tent;
    vec3_t      size;
    vec3_t      center;
    qboolean    splashdmg;
    
	// Lanz: cleaned up compiler errors.

    // Get the center of the BOX
    VectorSubtract(ent->r.maxs, ent->r.mins, size);
    VectorScale(size, 0.5, size);
    VectorAdd(ent->r.mins, size, center);
 
    // if the health of our wood brush is at 0 we'll move it
    if( ent->health <= 0 ) {
		G_FreeEntity( ent );
   
		switch( mod ) {
			case MOD_GAUNTLET:
				splashdmg = qfalse;
				break;
			default:
				splashdmg = qtrue;
				break;
		}
        
		// Now we call our EVs(Events) so that cgame can work on it
        switch( splashdmg ){
			case qtrue:
				tent = G_TempEntity( center, EV_BREAKWOOD );
				tent->s.eventParm = 0;
				break;
			case qfalse:
				tent = G_TempEntity( point, EV_BREAKWOOD );
				tent->s.eventParm = 0;
				break;
		}
     }
 }

/*QUAKED func_breakmetal (1 0 0) (-16 -16 -16) (16 16 16)
  We have breakable metal in our mod , if you hit it till health 0 it will explode and spawn models
 */
 void SP_func_breakmetal( gentity_t *ent ) {
  int health;
 
  // It's a model brush , show it
  trap_SetBrushModel( ent, ent->model );
  // the default health will be set to 25
  G_SpawnInt( "health", "0", &health );
  if( health <= 0 )
   health = 50;
 
  // set health on the function
  ent->health = health;
  // our function can receive damage
  ent->takedamage = qtrue;
  // that's our new ET(EntityType)
  ent->s.eType = ET_BREAKMETAL;
  // additional brush model
  if ( ent->model2 ) {
      ent->s.modelindex2 = G_ModelIndex( ent->model2 );
  }
  // link the entity ( otherwise nothing will work :) )
  trap_LinkEntity (ent);
 }

 /*
 =================
 G_BreakMetal
 =================
 */
 void G_BREAKMETAL(gentity_t *ent, vec3_t point, int mod) {
	gentity_t   *tent;
    vec3_t      size;
	vec3_t      center;
    qboolean    splashdmg;
    
	// Lanz: Cleaned up compiler errors.

    // Get the center of the metal
    VectorSubtract(ent->r.maxs, ent->r.mins, size);
    VectorScale(size, 0.5, size);
    VectorAdd(ent->r.mins, size, center);
 
    // if the health of our metal brush is at 0 we'll break it
    if( ent->health <= 0 ) {
		G_FreeEntity( ent );
   
		switch( mod ) {
			case MOD_GAUNTLET:
				splashdmg = qfalse;
				break;
			default:
				splashdmg = qtrue;
				break;
		}

        // Now we call our EVs(Events) so that cgame can work on it
        switch( splashdmg ){
			case qtrue:
				tent = G_TempEntity( center, EV_BREAKMETAL );
				tent->s.eventParm = 0;
				break;
			case qfalse:
				tent = G_TempEntity( point, EV_BREAKMETAL );
				tent->s.eventParm = 0;
				break;
		}
	}
}

Re: Here's a wild idea: EntityPlus

Posted: Mon May 02, 2011 6:37 pm
by Perle
And in cg_effects.c you can find this.

Code: Select all

/*
 ==================
 CG_LaunchShard
 ==================
 */
 void CG_LaunchShard( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
    int             bounce;
   localEntity_t   *le;
    refEntity_t      *re;
 
    le = CG_AllocLocalEntity();
    re = &le->refEntity;
 
    le->leType = LE_FRAGMENT;
    le->startTime = cg.time;
    le->endTime = le->startTime + 30000 + random() * 3000;
 
    VectorCopy( origin, re->origin );
    AxisCopy( axisDefault, re->axis );
    re->hModel = hModel;
 
    le->pos.trType = TR_GRAVITY;
    VectorCopy( origin, le->pos.trBase );
    VectorCopy( velocity, le->pos.trDelta );
    le->pos.trTime = cg.time;
 
    bounce = le->bounceFactor;
   bounce = 0.3;
 
    le->leFlags = LEF_TUMBLE;
    le->leBounceSoundType = LEBS_BRASS;
    le->leMarkType = LEMT_NONE;
 }
 
 


 /*
 ===================
 CG_BreakGlass
 
 Breaks our brush and generates a few models on launches them all over the map :)
 ===================
 */

 #define   GLASS_VELOCITY   175 //175
 #define   GLASS_JUMP      125 //125

 void CG_BreakGlass( vec3_t playerOrigin ) {
    vec3_t    origin, velocity;
        int     value;
     int     count = 20; //20
    int     states[] = {1,2,3};
        int     numstates = sizeof(states)/sizeof(states[0]);
 
    while ( count-- ) {
    
    value = states[rand()%numstates];
    VectorCopy( playerOrigin, origin );
    velocity[0] = crandom() *  165; //165
    velocity[1] = crandom() *  125; //125
	//velocity[2] = 0; //GLASS_JUMP + crandom() * 1; //165
    velocity[2] = GLASS_JUMP + crandom() * 165; //165
    
   switch (value) {
    case 1:
      CG_LaunchShard( origin, velocity, cgs.media.glass01 );
        break;
    case 2:
       CG_LaunchShard( origin, velocity, cgs.media.glass02 );
        break;
    case 3:
       CG_LaunchShard( origin, velocity, cgs.media.glass03 );
    break;
      }
   }
}

  /*
 ==================
 CG_LaunchWood
 ==================
 */
 void CG_LaunchWood( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
    int             bounce;
   localEntity_t   *le;
    refEntity_t      *re;
 
    le = CG_AllocLocalEntity();
    re = &le->refEntity;
 
    le->leType = LE_FRAGMENT;
    le->startTime = cg.time;
    le->endTime = le->startTime + 30000 + random() * 3000;
 
    VectorCopy( origin, re->origin );
    AxisCopy( axisDefault, re->axis );
    re->hModel = hModel;
 
    le->pos.trType = TR_GRAVITY;
    VectorCopy( origin, le->pos.trBase );
    VectorCopy( velocity, le->pos.trDelta );
    le->pos.trTime = cg.time;
 
   bounce = le->bounceFactor;
   bounce = 0.9; //0.3
   //newq3ball	
  /* pm->ps->velocity[2] = -vel * 0.5; //2
	if (pm->ps->velocity[2] <= 0.001) {
    pm->ps->velocity[2] = 0;
 */
 //endnew
    le->leFlags = LEF_TUMBLE;
    le->leBounceSoundType = LEBS_BRASS;
    le->leMarkType = LEMT_NONE;
 }
 
 


 /*
 ===================
 CG_BREAKWOOD
 
 Breaks our brush and generates a few (here 1 model) on launches them all over the map :)
 ===================
 */

 #define   BOX_VELOCITY   60 //175
 #define   BOX_JUMP      85 //125

 void CG_BREAKWOOD( vec3_t playerOrigin ) {
    vec3_t    origin, velocity;
     int     value;
     int     count = 8; //20
     int     states[] = {1,2,3};
        int     numstates = sizeof(states)/sizeof(states[0]);
 
    while ( count-- ) {
    
    value = states[rand()%numstates];
    VectorCopy( playerOrigin, origin );
    velocity[0] = crandom() *  80; //165
    velocity[1] = crandom() *  125; //125
    velocity[2] = BOX_JUMP + crandom() * 165;  //165
    //velocity[2] = 165;  //165
	   //newq3ball	
//  velocity[2] = -velocity[0] * 0.5; //2
// if (velocity[2] <= 0.001) {
 // velocity[2] = 0;
// }
 //endnew
   switch (value) {
    case 1:
      CG_LaunchWood( origin, velocity, cgs.media.wood01 );
        break;
    case 2:
       CG_LaunchWood( origin, velocity, cgs.media.wood02 );
        break;
    case 3:
       CG_LaunchWood( origin, velocity, cgs.media.wood03 );
    break;
      }
   }
}

  /*
 ==================
 CG_LaunchMetal
 ==================
 */
 void CG_LaunchMetal( vec3_t origin, vec3_t velocity, qhandle_t hModel ) {
    int             bounce;
   localEntity_t   *le;
    refEntity_t      *re;
 
    le = CG_AllocLocalEntity();
    re = &le->refEntity;
 
    le->leType = LE_FRAGMENT;
    le->startTime = cg.time;
    le->endTime = le->startTime + 30000 + random() * 3000;
 
    VectorCopy( origin, re->origin );
    AxisCopy( axisDefault, re->axis );
    re->hModel = hModel;
 
    le->pos.trType = TR_GRAVITY;
    VectorCopy( origin, le->pos.trBase );
    VectorCopy( velocity, le->pos.trDelta );
    le->pos.trTime = cg.time;
 
   bounce = le->bounceFactor;
   bounce = 0.9; //0.3

    le->leFlags = LEF_TUMBLE;
    le->leBounceSoundType = LEBS_BRASS;
    le->leMarkType = LEMT_NONE;
 }


/*
 ===================
 CG_BREAKMETAL
 
 Breaks our brush and generates a few (here 1 model) on launches them all over the map :)
 ===================
 */

#define   METAL_VELOCITY   60 //175
 #define   METAL_JUMP      85 //125

 void CG_BREAKMETAL( vec3_t playerOrigin ) {
    vec3_t    origin, velocity;
     int     value;
     int     count = 8; //20
     int     states[] = {1,2,3};
        int     numstates = sizeof(states)/sizeof(states[0]);
 
    while ( count-- ) {
    
    value = states[rand()%numstates];
    VectorCopy( playerOrigin, origin );
    velocity[0] = crandom() *  80; //165
    velocity[1] = crandom() *  125; //125
    velocity[2] = METAL_JUMP + crandom() * 165;  //165
    //velocity[2] = 165;  //165
	   //newq3ball	
//  velocity[2] = -velocity[0] * 0.5; //2
// if (velocity[2] <= 0.001) {
 // velocity[2] = 0;
// }
 //endnew
   switch (value) {
    case 1:
      CG_LaunchMetal( origin, velocity, cgs.media.metal01 );
        break;
    case 2:
       CG_LaunchMetal( origin, velocity, cgs.media.metal02 );
        break;
    case 3:
       CG_LaunchMetal( origin, velocity, cgs.media.metal03 );
    break;
      }
   }
}
And they are prototyped in cg_local.h

Code: Select all

void CG_BreakGlass( vec3_t playerOrigin );
void CG_BREAKWOOD( vec3_t playerOrigin );
void CG_BREAKMETAL( vec3_t playerOrigin );

Re: Here's a wild idea: EntityPlus

Posted: Tue May 03, 2011 8:57 am
by Eraser
Thanks a lot sir. It was basically just this bit of code I needed:

Code: Select all

// Get the center of the glass
VectorSubtract(ent->r.maxs, ent->r.mins, size);
VectorScale(size, 0.5, size);
vectorAdd(ent->r.mins, size, center);
Now there's no longer need for a target_debrisemitter for func_breakable.
I'll leave the target_debrisemitter in there though.

Re: Here's a wild idea: EntityPlus

Posted: Tue May 03, 2011 1:51 pm
by Perle
I also leave it in my code. With other models it could be useful for some other stuff.

EDIT : You credit me in your readme. Nice. Thanks.