Putting the Red and Blue Pent/Quad globes into NQ (by J.Dale) ============================================================= The blue quad globe and red pent globe (and purple when you have them both) look great in GLQW, heres how to get them into NQ. Unfortunetly they must be programmed into the QC too, so this wont make them suddenly appear in your old mods :( Open gl_model.h and below the line #define EF_DIMLIGHT 8 add the following 2 lines #define EF_BLUE 64 #define EF_RED 128 Next open client.h and find and change the typdef struct of dlight_t to look like this: typedef struct { vec3_t origin; float radius; float die; // stop lighting after this time float decay; // drop this each second float minlight; // don't add when contributing less int key; float color[4]; //Added to allow coloured Globes #ifdef QUAKE2 qboolean dark; // subtracts light instead of adding #endif } dlight_t; Now open gl_rlight.c and find the R_RenderDlight function. Edit it to look like this : void R_RenderDlight (dlight_t *light) { int i, j; float a; vec3_t v; float rad; rad = light->radius * 0.35; VectorSubtract (light->origin, r_origin, v); if (Length (v) < rad) { // view is inside the dlight AddLightBlend (1, 0.5, 0, light->radius * 0.0003); return; } glBegin (GL_TRIANGLE_FAN); //glColor3f (0.2,0.1,0.0); Commented out the old single color globe method //Use the following line to allow multiple coloured dlights/globes. glColor4f (light->color[0], light->color[1], light->color[2], light->color[3]); for (i=0 ; i<3 ; i++) v[i] = light->origin[i] - vpn[i]*rad; glVertex3fv (v); glColor3f (0,0,0); for (i=16 ; i>=0 ; i--) { a = i/16.0 * M_PI*2; for (j=0 ; j<3 ; j++) v[j] = light->origin[j] + vright[j]*cos(a)*rad + vup[j]*sin(a)*rad; glVertex3fv (v); } glEnd (); } OK, finally you have to make the right colours get assigned to the right entities. Open cl_main.c and find the CL_RelinkEntities function. Change it to look like this : /* =============== CL_RelinkEntities =============== */ void CL_RelinkEntities (void) { entity_t *ent; int i, j; float frac, f, d; vec3_t delta; float bobjrotate; vec3_t oldorg; dlight_t *dl; // determine partial update time frac = CL_LerpPoint (); cl_numvisedicts = 0; // // interpolate player info // for (i=0 ; i<3 ; i++) cl.velocity[i] = cl.mvelocity[1][i] + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); if (cls.demoplayback) { // interpolate the angles for (j=0 ; j<3 ; j++) { d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; if (d > 180) d -= 360; else if (d < -180) d += 360; cl.viewangles[j] = cl.mviewangles[1][j] + frac*d; } } bobjrotate = anglemod(100*cl.time); // start on the entity after the world for (i=1,ent=cl_entities+1 ; imodel) { // empty slot if (ent->forcelink) R_RemoveEfrags (ent); // just became empty continue; } // if the object wasn't included in the last packet, remove it if (ent->msgtime != cl.mtime[0]) { ent->model = NULL; continue; } VectorCopy (ent->origin, oldorg); if (ent->forcelink) { // the entity was not updated in the last message // so move to the final spot VectorCopy (ent->msg_origins[0], ent->origin); VectorCopy (ent->msg_angles[0], ent->angles); } else { // if the delta is large, assume a teleport and don't lerp f = frac; for (j=0 ; j<3 ; j++) { delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j]; if (delta[j] > 100 || delta[j] < -100) f = 1; // assume a teleportation, not a motion } // interpolate the origin and angles for (j=0 ; j<3 ; j++) { ent->origin[j] = ent->msg_origins[1][j] + f*delta[j]; d = ent->msg_angles[0][j] - ent->msg_angles[1][j]; if (d > 180) d -= 360; else if (d < -180) d += 360; ent->angles[j] = ent->msg_angles[1][j] + f*d; } } // rotate binary objects locally if (ent->model->flags & EF_ROTATE) ent->angles[1] = bobjrotate; if (ent->effects & EF_BRIGHTFIELD) R_EntityParticles (ent); #ifdef QUAKE2 if (ent->effects & EF_DARKFIELD) R_DarkFieldParticles (ent); #endif /* OK from here down there are changes to assign globe colours. Note that now we have to set colours for the old default coloured globes or they dont appear at all. You could set different colours for rockets and muzzle flashes etc if it took your fancy. */ if (ent->effects & EF_MUZZLEFLASH) { vec3_t fv, rv, uv; dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->origin[2] += 16; AngleVectors (ent->angles, fv, rv, uv); VectorMA (dl->origin, 18, fv, dl->origin); dl->radius = 200 + (rand()&31); dl->minlight = 32; dl->die = cl.time + 0.1; dl->color[0] = 0.2; dl->color[1] = 0.1; dl->color[2] = 0.05; dl->color[3] = 0.7; } if (ent->effects & EF_BRIGHTLIGHT) { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->origin[2] += 16; dl->radius = 400 + (rand()&31); dl->die = cl.time + 0.001; dl->color[0] = 0.2; dl->color[1] = 0.1; dl->color[2] = 0.05; dl->color[3] = 0.7; } if (ent->effects & EF_DIMLIGHT) { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->radius = 200 + (rand()&31); dl->die = cl.time + 0.001; dl->color[0] = 0.2; dl->color[1] = 0.1; dl->color[2] = 0.05; dl->color[3] = 0.7; } if (ent->effects & EF_BLUE) { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->radius = 200 + (rand()&31); dl->die = cl.time + 0.001; dl->color[0] = 0.05; dl->color[1] = 0.05; dl->color[2] = 0.3; dl->color[3] = 0.7; } if (ent->effects & EF_RED) { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->radius = 200 + (rand()&31); dl->die = cl.time + 0.001; dl->color[0] = 0.5; dl->color[1] = 0.05; dl->color[2] = 0.05; dl->color[3] = 0.7; } if ((ent->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED)) { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->radius = 200 + (rand()&31); dl->die = cl.time + 0.001; dl->color[0]=0.5; dl->color[1] = 0.05; dl->color[2] = 0.4; dl->color[3] = 0.7; } #ifdef QUAKE2 if (ent->effects & EF_DARKLIGHT) { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->radius = 200.0 + (rand()&31); dl->die = cl.time + 0.001; dl->dark = true; } if (ent->effects & EF_LIGHT) { dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->radius = 200; dl->die = cl.time + 0.001; } #endif if (ent->model->flags & EF_GIB) R_RocketTrail (oldorg, ent->origin, 2); else if (ent->model->flags & EF_ZOMGIB) R_RocketTrail (oldorg, ent->origin, 4); else if (ent->model->flags & EF_TRACER) R_RocketTrail (oldorg, ent->origin, 3); else if (ent->model->flags & EF_TRACER2) R_RocketTrail (oldorg, ent->origin, 5); else if (ent->model->flags & EF_ROCKET) { R_RocketTrail (oldorg, ent->origin, 0); dl = CL_AllocDlight (i); VectorCopy (ent->origin, dl->origin); dl->radius = 200; dl->die = cl.time + 0.01; dl->color[0] = 0.2; dl->color[1] = 0.1; dl->color[2] = 0.05; dl->color[3] = 0.7; } else if (ent->model->flags & EF_GRENADE) R_RocketTrail (oldorg, ent->origin, 1); else if (ent->model->flags & EF_TRACER3) R_RocketTrail (oldorg, ent->origin, 6); ent->forcelink = false; if (i == cl.viewentity && !chase_active.value) continue; #ifdef QUAKE2 if ( ent->effects & EF_NODRAW ) continue; #endif if (cl_numvisedicts < MAX_VISEDICTS) { cl_visedicts[cl_numvisedicts] = ent; cl_numvisedicts++; } } } OK, now compile, and if I havent missed out anything it should work :P Note that I havent added colour info to the effects within the #ifdef quake2 bits. If you were using these just add some dl->colour lines to get the working right again. If you are looking at and understanding the code you have been changing that shouldnt be a problem for you. For homework try to add EF_GREEN yourself. If u try and fail u can get the code from me. color[0] is the transparency level. Altering QC to put the effects into the game ============================================ I have only done this with frogbot source QC so far, but it ought to be similar for basic QC. Open defs.qc and do a find on EF_BLUE. It will be within a #ifdef QUAKEWORLD. Comment out the #ifdef and the #endif : //#ifdef QUAKEWORLD // GLQuakeWorld Stuff float EF_BLUE = 64; // Blue Globe effect for Quad float EF_RED = 128; // Red Globe effect for Pentagram float EF_DIMLIGHT_BLUE = 72; float EF_DIMLIGHT_RED = 136; float NOT_EF_BLUE = 16777151; float NOT_EF_RED = 16777087; //#endif // QUAKEWORLD If you are adding this to non frogbot code, FIND on EF_DIMLIGHT and add the above below it. I've only added it to frogbot code so I don't know for sure that would work, sorry. OK finally open items.qc and change the item functions to set the entity attributes. This is what frogbot code should look like once you are finished. /* =============================================================================== POWERUPS =============================================================================== */ void() powerup_touch = { if (other.client_) { if (marker_time) check_marker(); #ifdef MANUAL if (manual_mode) return; #endif // MANUAL if (self.nextthink) return; if (other.takedamage) { if (other.goalentity == self) other.goal_refresh_time = 0; self.nextthink = self.goal_respawn_time = time + self.aflag; AssignVirtualGoal(); msg_entity = other; msg_level = PRINT_LOW; sprint ("You got the "); sprint (self.netname); sprint ("\n"); sound (CHAN_VOICE, self.noise, 1, ATTN_NORM); bf(); self.model = ""; items_ = self.items; // do the apropriate action if (items_ == IT_INVISIBILITY) { // use the eyes #ifdef QUAKE if (other.flags & FL_PLAYER) { if (game_skinfix) { other.modelindex = 0; other.aiment.modelindex = modelindex_eyes; msg_entity = other; WriteByte(MSG_ONE, SVC_SETVIEWPORT); WriteEntity(MSG_ONE, other.aiment); } else other.modelindex = modelindex_eyes; } else { other.aiment.modelindex = 0; other.modelindex = modelindex_eyes; } #endif // QUAKE #ifdef QUAKEWORLD other.modelindex = modelindex_eyes; #endif // QUAKEWORLD other.invisible_time = 1; other.invisible_finished = time + 30; } else if (items_ == IT_SUIT) { other.rad_time = 1; other.radsuit_finished = time + 30; } else if (items_ == IT_INVULNERABILITY) { other.invincible_time = 1; other.invincible_finished = time + 30; #ifdef QUAKE other.effects = other.aiment.effects = other.effects | EF_DIMLIGHT_RED; #endif // QUAKE #ifdef QUAKEWORLD other.effects = other.effects | EF_DIMLIGHT_RED; #endif // QUAKEWORLD } else if (items_ == IT_QUAD) { other.super_time = 1; other.super_damage_finished = time + 30; #ifdef QUAKE other.effects = other.aiment.effects = other.effects | EF_DIMLIGHT_BLUE; #endif // QUAKE #ifdef QUAKEWORLD other.effects = other.effects | EF_DIMLIGHT_BLUE; #endif // QUAKEWORLD } other.items = other.items | items_; UpdateGoalEntity(); } } }; /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32) Player is invulnerable for 30 seconds */ void() item_artifact_invulnerability = { if (game_disable_powerups) self.flags = self.flags | FL_REMOVE; self.touch = powerup_touch; precache_model ("progs/invulner.mdl"); self.noise = "items/protect.wav"; setmodel (self, "progs/invulner.mdl"); self.netname = "Pentagram of Protection"; //#ifdef QUAKEWORLD self.effects = self.effects | EF_RED; //#endif // QUAKEWORLD self.items = IT_INVULNERABILITY; setsize (self, '-16 -16 -24', '16 16 32'); self.aflag = 300; self.desire = goal_NULL; StartItem (); }; void() lose_artifact_invulnerability = { self.items = self.items & IT_NOT_INVULNERABILITY; self.invincible_time = 0; self.invincible_finished = 0; if (!self.super_damage_finished) if (!(self.player_flag & ITEM_ENEMY_FLAG)) { #ifdef QUAKE self.effects = self.aiment.effects = self.effects & NOT_EF_DIMLIGHT; #endif // QUAKE #ifdef QUAKEWORLD self.effects = self.effects & NOT_EF_DIMLIGHT; #endif // QUAKEWORLD } #ifdef QUAKE self.effects = self.aiment.effects = self.effects & NOT_EF_RED; #endif // QUAKE #ifdef QUAKEWORLD self.effects = self.effects & NOT_EF_RED; #endif // QUAKEWORLD }; void() item_artifact_super_damage = { if (game_disable_powerups) self.flags = self.flags | FL_REMOVE; self.touch = powerup_touch; precache_model ("progs/quaddama.mdl"); precache_sound ("items/damage.wav"); precache_sound ("items/damage2.wav"); precache_sound ("items/damage3.wav"); self.noise = "items/damage.wav"; setmodel (self, "progs/quaddama.mdl"); if (quad_factor == 4) self.netname = "Quad Damage"; else self.netname = "OctaPower"; //#ifdef QUAKEWORLD self.effects = self.effects | EF_BLUE; //#endif // QUAKEWORLD self.items = IT_QUAD; setsize (self, '-16 -16 -24', '16 16 32'); self.aflag = 60; self.desire = goal_artifact_super_damage; StartItem (); }; void() lose_artifact_super_damage = { self.items = self.items & IT_NOT_QUAD; self.super_damage_finished = 0; self.super_time = 0; if (!self.invincible_finished) if (!(self.player_flag & ITEM_ENEMY_FLAG)) { #ifdef QUAKE self.effects = self.aiment.effects = self.effects & NOT_EF_DIMLIGHT; #endif // QUAKE #ifdef QUAKEWORLD self.effects = self.effects & NOT_EF_DIMLIGHT; #endif // QUAKEWORLD } #ifdef QUAKE self.effects = self.aiment.effects = self.effects & NOT_EF_BLUE; #endif // QUAKE #ifdef QUAKEWORLD self.effects = self.effects & NOT_EF_BLUE; #endif // QUAKEWORLD }; Now enjoy a proper blue/red quad/pent. Now why didnt iD do this for quake?