void trigger_counter_use(edict_t *self, edict_t *other, edict_t *activator) { if (self->count == 0) return; self->count--; if (self->count) { if (! (self->spawnflags & 1)) { safe_centerprintf(activator, "%i more to go...", self->count); gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); } return; } if (! (self->spawnflags & 1)) { safe_centerprintf(activator, "Sequence completed!"); gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); } self->activator = activator; multi_trigger (self); }
void target_lock_use (edict_t *self, edict_t *other, edict_t *activator) { edict_t *e; int n; char current[16]; char *copy_message; memset(current,0,16); for (e = self->teammaster; e; e = e->teamchain) { if (!e->count) continue; n = e->count - 1; current[n] = '0' + e->s.frame; } if(strcmp(current,self->key_message)==0) { copy_message = self->message; self->message = NULL; G_UseTargets(self,activator); self->message = copy_message; } else { if(self->message) safe_centerprintf(activator,self->message); if(self->pathtarget) { e = G_Find(NULL,FOFS(targetname),self->pathtarget); if(e) e->use(e,other,activator); } else { BeepBeep(activator); } } }
void GetChaseTarget(edict_t *ent) { int i; edict_t *other; for (i = 1; i <= maxclients->value; i++) { other = g_edicts + i; if (other->inuse && !other->client->resp.spectator) { ent->client->chase_target = other; ent->client->update_chase = true; UpdateChaseCam(ent); return; } } safe_centerprintf(ent, "No other players to chase."); }
/* ===================== ClientBeginDeathmatch A client has just connected to the server in deathmatch mode, so clear everything out before starting them. ===================== */ void ClientBeginDeathmatch (edict_t *ent) { #ifdef WITH_ACEBOT // ACEBOT_ADD static char current_map[55]; // ACEBOT_END #endif G_InitEdict (ent); #ifdef WITH_ACEBOT // ACEBOT_ADD ACEIT_PlayerAdded(ent); // ACEBOT_END #endif InitClientResp (ent->client); // locate ent at a spawn point PutClientInServer (ent); // send effect gi.WriteByte (svc_muzzleflash); gi.WriteShort (ent-g_edicts); gi.WriteByte (MZ_LOGIN); gi.multicast (ent->s.origin, MULTICAST_PVS); #ifdef WITH_ACEBOT safe_bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); safe_centerprintf(ent,"\nQ2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2\n\nZaero Bots\n\n\n'sv addbot' to add a new bot.\n\n'sv removebot <name>' to remove bot.\n\n\nhttp://qudos.quakedev.com\n\n\nQ2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2 Q2\n\n"); // If the map changes on us, init and reload the nodes if(strcmp(level.mapname,current_map)) { ACEND_InitNodes(); ACEND_LoadNodes(); if (botauto_respawn->value) { ACESP_LoadBots(); } strcpy(current_map,level.mapname); } safe_bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); // ACEBOT_END #else gi.bprintf (PRINT_HIGH, "%s entered the game\n", ent->client->pers.netname); #endif // make sure all view stuff is valid ClientEndServerFrame (ent); }
void crane_control_action(edict_t *control, edict_t *activator, vec3_t point) { float Z; int dir; int row, column; int content; edict_t *beam, *cable, *cargo, *hoist, *hook; trace_t tr; vec3_t center, v; vec3_t end, forward, start, pt; vec3_t bonk, mins, maxs; if(!(control->spawnflags & 1)) { if(control->message) safe_centerprintf(activator,"%s\n",control->message); else safe_centerprintf(activator,"No power\n"); return; } if(control->busy) return; // First make sure player (activator) is on the panel side of the // control panel // Also get center point of panel side switch (control->style) { case 0: if(activator->s.origin[0] > control->absmax[0]) return; center[0] = control->absmin[0]; center[1] = (control->absmin[1] + control->absmax[1])/2; center[2] = (control->absmin[2] + control->absmax[2])/2; break; case 1: if(activator->s.origin[1] > control->absmax[1]) return; center[0] = (control->absmin[0] + control->absmax[0])/2; center[1] = control->absmin[1]; center[2] = (control->absmin[2] + control->absmax[2])/2; break; case 2: if(activator->s.origin[0] < control->absmin[0]) return; center[0] = control->absmax[0]; center[1] = (control->absmin[1] + control->absmax[1])/2; center[2] = (control->absmin[2] + control->absmax[2])/2; break; case 3: if(activator->s.origin[1] < control->absmin[1]) return; center[0] = (control->absmin[0] + control->absmax[0])/2; center[1] = control->absmax[1]; center[2] = (control->absmin[2] + control->absmax[2])/2; break; } // now check distance from player to panel VectorSubtract(activator->s.origin,center,v); if(VectorLength(v) > 64) return; beam = control->crane_beam; cable = control->crane_cable; hoist = control->crane_hoist; hook = control->crane_hook; cargo = hook->crane_cargo; if(cargo) cargo->gravity = 0.0; // reset after making it float up, // otherwise things get jammed up control->activator = activator; // if any part of crane is currently moving, do nothing. if(VectorLength(control->velocity) > 0.) return; if(VectorLength(beam->velocity) > 0.) return; if(VectorLength(hoist->velocity) > 0.) return; if(VectorLength(hook->velocity) > 0.) return; // now find which row and column of buttons corresponds to "point" row = (2*(point[2] - control->absmin[2]))/(control->absmax[2]-control->absmin[2]); if(row < 0) row = 0; if(row > 1) row = 1; switch (control->style) { case 1: column = (4*(point[0]-control->absmin[0]))/(control->absmax[0]-control->absmin[0]); break; case 2: column = (4*(point[1]-control->absmin[1]))/(control->absmax[1]-control->absmin[1]); break; case 3: column = (4*(point[0]-control->absmax[0]))/(control->absmin[0]-control->absmax[0]); break; default: column = (4*(point[1]-control->absmax[1]))/(control->absmin[1]-control->absmax[1]); break; } if(column < 0) column = 0; if(column > 3) column = 3; // adjust for controller facing beam movement direction if( beam->movedir[0] > 0 && (control->style == 0 || control->style == 2)) { if(column == 0 || column == 1) { column = 1-column; row = 1-row; } } if( beam->movedir[1] > 0 && (control->style == 1 || control->style == 3)) { if(column == 0 || column == 1) { column = 1-column; row = 1-row; } } switch(column) { case 0: //================== // move hoist //================== if(row) { // hoist away if(control->style == 0 || control->style == 1) control->crane_increment = 1; else control->crane_increment = -1; } else { // hoist toward if(control->style == 0 || control->style == 1) control->crane_increment = -1; else control->crane_increment = 1; } if(hoist->movedir[0] > 0) { // hoist travels in X dir = 0; if(control->crane_increment > 0) { if(Crane_Hook_Bonk(hook,0,1,bonk)) { bonk[0] += hoist->absmax[0] - hook->absmax[0]; hoist->crane_bonk = min(bonk[0],hoist->pos2[0]); } else hoist->crane_bonk = hoist->pos2[0]; hoist->crane_bonk += hoist->absmin[0] - hoist->absmax[0]; } else { if(Crane_Hook_Bonk(hook,0,-1,bonk)) { bonk[0] += hoist->absmin[0] - hook->absmin[0]; hoist->crane_bonk = max(bonk[0],hoist->pos1[0]); } else hoist->crane_bonk = hoist->pos1[0]; } } else { // travels in Y dir = 1; if(control->crane_increment > 0) { if(Crane_Hook_Bonk(hook,1,1,bonk)) { bonk[1] += hoist->absmax[1] - hook->absmax[1]; hoist->crane_bonk = min(bonk[1],hoist->pos2[1]); } else hoist->crane_bonk = hoist->pos2[1]; hoist->crane_bonk += hoist->absmin[1] - hoist->absmax[1]; } else { if(Crane_Hook_Bonk(hook,1,-1,bonk)) { bonk[1] += hoist->absmin[1] - hook->absmin[1]; hoist->crane_bonk = max(bonk[1],hoist->pos1[1]); } else hoist->crane_bonk = hoist->pos1[1]; } } hoist->crane_dir = dir; hoist->moveinfo.remaining_distance = control->crane_increment * (hoist->crane_bonk - hoist->absmin[dir]); if(hoist->moveinfo.remaining_distance <= 0) return; hoist->moveinfo.remaining_distance = min(hoist->moveinfo.remaining_distance,STEPSIZE); Crane_AdjustSpeed(hoist); VectorSet(hoist->moveinfo.dir, hoist->movedir[0]*control->crane_increment, hoist->movedir[1]*control->crane_increment, 0); hoist->crane_control = control; hook->crane_dir = dir; hook->crane_bonk = hoist->crane_bonk + hook->absmin[dir] - hoist->absmin[dir]; hook->crane_control = control; memcpy(&hook->moveinfo,&hoist->moveinfo,sizeof(moveinfo_t)); cable->crane_dir = dir; cable->crane_bonk = hoist->crane_bonk + cable->absmin[dir] - hoist->absmin[dir]; cable->crane_control = control; memcpy(&cable->moveinfo,&hoist->moveinfo,sizeof(moveinfo_t)); if(cargo) { cargo->movetype = MOVETYPE_PUSH; cargo->crane_dir = dir; cargo->crane_bonk = hoist->crane_bonk + cargo->absmin[dir] - hoist->absmin[dir]; cargo->crane_control = control; memcpy(&cargo->moveinfo,&hoist->moveinfo,sizeof(moveinfo_t)); } Crane_Move_Begin(hoist); Crane_Move_Begin(hook); if(cargo) Crane_Move_Begin(cargo); break; case 1: //================== // move beam //================== // first re-parent associated speaker, if any if(beam->speaker && control == beam->crane_onboard_control) { beam->speaker->owner = control; VectorAdd(control->absmin,control->absmax,beam->speaker->s.origin); VectorScale(beam->speaker->s.origin,0.5,beam->speaker->s.origin); VectorSubtract(beam->speaker->s.origin,control->s.origin,beam->speaker->offset); control->noise_index = beam->noise_index; } if(row) { // left arrow if(control->style == 0 || control->style == 3) control->crane_increment = 1; else control->crane_increment = -1; } else { // right arrow if(control->style == 0 || control->style == 3) control->crane_increment = -1; else control->crane_increment = 1; } if(beam->movedir[0] > 0) { // travels in X dir = 0; if(control->crane_increment > 0) { if(Crane_Hook_Bonk(hook,0,1,bonk)) { bonk[0] += beam->absmax[0] - hook->absmax[0]; beam->crane_bonk = min(bonk[0],beam->pos2[0]); } else beam->crane_bonk = beam->pos2[0]; beam->crane_bonk += beam->absmin[0] - beam->absmax[0]; } else { if(Crane_Hook_Bonk(hook,0,-1,bonk)) { bonk[0] += beam->absmin[0] - hook->absmin[0]; beam->crane_bonk = max(bonk[0],beam->pos1[0]); } else beam->crane_bonk = beam->pos1[0]; } } else { // travels in Y dir = 1; if(control->crane_increment > 0) { if(Crane_Hook_Bonk(hook,1,1,bonk)) { bonk[1] += beam->absmax[1] - hook->absmax[1]; beam->crane_bonk = min(bonk[1],beam->pos2[1]); } else beam->crane_bonk = beam->pos2[1]; beam->crane_bonk += beam->absmin[1] - beam->absmax[1]; } else { if(Crane_Hook_Bonk(hook,1,-1,bonk)) { bonk[1] += beam->absmin[1] - hook->absmin[1]; beam->crane_bonk = max(bonk[1],beam->pos1[1]); } else beam->crane_bonk = beam->pos1[1]; } } beam->crane_dir = dir; beam->moveinfo.remaining_distance = control->crane_increment * (beam->crane_bonk - beam->absmin[dir]); // gi.dprintf("remaining distance = %g\n",beam->moveinfo.remaining_distance); if(beam->moveinfo.remaining_distance <= 0) return; beam->moveinfo.remaining_distance = min(beam->moveinfo.remaining_distance,STEPSIZE); Crane_AdjustSpeed(beam); VectorSet(beam->moveinfo.dir, beam->movedir[0]*control->crane_increment, beam->movedir[1]*control->crane_increment, 0); beam->crane_control = control; hoist->crane_dir = dir; hoist->crane_bonk = beam->crane_bonk + hoist->absmin[dir] - beam->absmin[dir]; hoist->crane_control = control; memcpy(&hoist->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); hook->crane_dir = dir; hook->crane_bonk = beam->crane_bonk + hook->absmin[dir] - beam->absmin[dir]; hook->crane_control = control; memcpy(&hook->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); cable->crane_dir = dir; cable->crane_bonk = beam->crane_bonk + cable->absmin[dir] - beam->absmin[dir]; cable->crane_control = control; memcpy(&cable->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); if(beam->crane_onboard_control) { beam->crane_onboard_control->crane_dir = dir; beam->crane_onboard_control->crane_bonk = beam->crane_bonk + beam->crane_onboard_control->absmin[dir] - beam->absmin[dir]; beam->crane_onboard_control->crane_control = control; memcpy(&beam->crane_onboard_control->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); } if(cargo) { cargo->movetype = MOVETYPE_PUSH; cargo->crane_dir = dir; cargo->crane_bonk = beam->crane_bonk + cargo->absmin[dir] - beam->absmin[dir]; cargo->crane_control = control; memcpy(&cargo->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); } Crane_Move_Begin(beam); Crane_Move_Begin(hoist); Crane_Move_Begin(hook); if(beam->crane_onboard_control) Crane_Move_Begin(beam->crane_onboard_control); if(cargo) Crane_Move_Begin(cargo); break; case 2: //================== // hook up/down //================== hook->crane_dir = dir = 2; if(row) { // hook up control->crane_increment = 1; if(Crane_Hook_Bonk(hook,2,1,bonk)) hook->crane_bonk = min(bonk[2],hook->pos2[2]); else hook->crane_bonk = hook->pos2[2]; hook->crane_bonk += hook->absmin[2] - hook->absmax[2]; } else { // hook down if(cargo) { pt[0] = (cargo->absmin[0] + cargo->absmax[0])/2; pt[1] = (cargo->absmin[1] + cargo->absmax[1])/2; pt[2] = cargo->absmin[2] - 0.125; content = gi.pointcontents(pt); if(content & MASK_SOLID) { BeepBeep(activator); return; } } control->crane_increment = -1; if(Crane_Hook_Bonk(hook,2,-1,bonk)) hook->crane_bonk = max(bonk[2],hook->pos1[2]); else hook->crane_bonk = hook->pos1[2]; } hook->moveinfo.remaining_distance = control->crane_increment * (hook->crane_bonk - hook->absmin[hook->crane_dir]); if(hook->moveinfo.remaining_distance <= 0) { BeepBeep(activator); return; } hook->moveinfo.remaining_distance = min(hook->moveinfo.remaining_distance,STEPSIZE); Crane_AdjustSpeed(hook); VectorSet(hook->moveinfo.dir,0.,0.,(float)(control->crane_increment)); hook->crane_control = control; if(cargo) { cargo->movetype = MOVETYPE_PUSH; cargo->crane_dir = dir; cargo->crane_bonk = hook->crane_bonk + cargo->absmin[dir] - hook->absmin[dir]; cargo->crane_control = control; VectorSubtract(cargo->s.origin,hook->s.origin,cargo->offset); memcpy(&cargo->moveinfo,&hook->moveinfo,sizeof(moveinfo_t)); } cable->think = Cable_Think; cable->nextthink = level.time + FRAMETIME; Crane_Move_Begin(hook); if(cargo) Crane_Move_Begin(cargo); break; case 3: //================== // hook/unhook //================== if(row) { // pickup cargo if(hook->crane_cargo) { // already carrying something BeepBeep(activator); return; } VectorAdd(hook->absmin,hook->absmax,start); VectorScale(start,0.5,start); VectorSet(forward,0.,0.,-1.); VectorMA(start, 8192, forward, end); VectorSubtract(hook->absmin,start,mins); VectorSubtract(hook->absmax,start,maxs); // 06/03/00 change: Use 1/3 the bounding box to force a better hit VectorScale(mins,0.3333,mins); VectorScale(maxs,0.3333,maxs); // end 06/03/00 change tr=gi.trace(start, mins, maxs, end, hook, MASK_SOLID); if((tr.fraction < 1) && (tr.ent) && (tr.ent->classname) && (tr.ent->movetype == MOVETYPE_PUSHABLE) ) { Z = hook->absmin[2] - tr.ent->absmax[2]; if(Z > MAX_PICKUP_DISTANCE) { safe_centerprintf(activator,"Too far\n"); return; } if(CrateOnTop(NULL,tr.ent)) { BeepBeep(activator); gi.dprintf("Too heavy\n"); return; } // run a trace from top of cargo up... if first entity hit is NOT // the hook, we can't get there from here. if( Z > 0 ) { trace_t tr2; VectorMA(tr.ent->mins,0.5,tr.ent->size,start); start[2] = tr.ent->maxs[2]; VectorCopy(tr.ent->size,mins); VectorScale(mins,-0.5,mins); VectorCopy(tr.ent->size,maxs); VectorScale(maxs,0.5,maxs); mins[2] = maxs[2] = 0; mins[0] += 1; mins[1] += 1; maxs[0] -= 1; maxs[1] -= 1; VectorCopy(start,end); end[2] += Z + 1; tr2=gi.trace(start, mins, maxs, end, hook, MASK_SOLID); if((tr2.fraction < 1) && tr2.ent && (tr2.ent != hook)) { safe_centerprintf(activator,"Blocked!\n"); return; } } Z -= CARGO_BUFFER; // leave a buffer between hook and cargo hook->crane_cargo = cargo = tr.ent; cargo->groundentity = NULL; cargo->crane_control = control; cargo->crane_hook = hook; cargo->movetype = MOVETYPE_PUSH; cargo->touch = NULL; // Make cargo float up to the hook if(Z > 0) { control->busy = true; cargo->attracted = true; cargo->gravity = 0.0; cargo->velocity[2] = 0.0; cargo->think = Cargo_Float_Up; cargo->blocked = cargo_blocked; cargo->goal_frame = level.framenum; cargo->nextthink = level.time + FRAMETIME; gi.linkentity(cargo); } else { gi.positioned_sound (start, cargo, CHAN_VOICE, gi.soundindex("tank/thud.wav"), 1, 1, 0); } } else BeepBeep(activator); } else { // drop cargo if(hook->crane_cargo) { hook->crane_cargo->gravity = 1.0; hook->crane_cargo->movetype = MOVETYPE_PUSHABLE; hook->crane_cargo->touch = box_touch; hook->crane_cargo->crane_control = NULL; gi.linkentity(hook->crane_cargo); box_movestep (hook->crane_cargo, vec3_origin, true); hook->crane_cargo = NULL; } else BeepBeep(activator); } } }
void crane_reset_use (edict_t *self, edict_t *other, edict_t *activator) { float d1, d2; int dir; edict_t *delay; edict_t *crane; edict_t *control, *beam, *cable, *cargo, *hoist, *hook; vec3_t bonk, v1, v2; crane = G_Find (NULL, FOFS(targetname), self->target); if(!crane) { gi.dprintf("Cannot find target of crane_reset at %s\n",vtos(self->s.origin)); return; } control = crane->crane_control; control->activator = activator; if(!(control->spawnflags & 1)) { if(control->message) safe_centerprintf(activator,"%s\n",control->message); else safe_centerprintf(activator,"No power\n"); return; } beam = control->crane_beam; hoist = control->crane_hoist; hook = control->crane_hook; cable = control->crane_cable; cargo = hook->crane_cargo; VectorSubtract(beam->pos1,self->s.origin,v1); VectorSubtract(beam->pos2,self->s.origin,v2); d1 = VectorLength(v1); d2 = VectorLength(v2); if(d2 < d1) control->crane_increment = 1; else control->crane_increment = -1; if(beam->movedir[0] > 0) { // travels in X dir = 0; if(control->crane_increment > 0) { if(Crane_Hook_Bonk(hook,0,1,bonk)) { bonk[0] += beam->absmax[0] - hook->absmax[0]; beam->crane_bonk = min(bonk[0],beam->pos2[0]); } else beam->crane_bonk = beam->pos2[0]; beam->crane_bonk += beam->absmin[0] - beam->absmax[0]; } else { if(Crane_Hook_Bonk(hook,0,-1,bonk)) { bonk[0] += beam->absmin[0] - hook->absmin[0]; beam->crane_bonk = max(bonk[0],beam->pos1[0]); } else beam->crane_bonk = beam->pos1[0]; } } else { // travels in Y dir = 1; if(control->crane_increment > 0) { if(Crane_Hook_Bonk(hook,1,1,bonk)) { bonk[1] += beam->absmax[1] - hook->absmax[1]; beam->crane_bonk = min(bonk[1],beam->pos2[1]); } else beam->crane_bonk = beam->pos2[1]; beam->crane_bonk += beam->absmin[1] - beam->absmax[1]; } else { if(Crane_Hook_Bonk(hook,1,-1,bonk)) { bonk[1] += beam->absmin[1] - hook->absmin[1]; beam->crane_bonk = max(bonk[1],beam->pos1[1]); } else beam->crane_bonk = beam->pos1[1]; } } if(beam->speaker && beam->crane_onboard_control) { beam->speaker->owner = beam->crane_onboard_control; VectorAdd(beam->crane_onboard_control->absmin, beam->crane_onboard_control->absmax, beam->speaker->s.origin); VectorScale(beam->speaker->s.origin,0.5,beam->speaker->s.origin); VectorSubtract(beam->speaker->s.origin, beam->crane_onboard_control->s.origin,beam->speaker->offset); beam->speaker->owner->noise_index = beam->noise_index; } beam->crane_dir = dir; beam->moveinfo.remaining_distance = control->crane_increment * (beam->crane_bonk - beam->absmin[dir]); if(beam->moveinfo.remaining_distance <= 0) return; Crane_AdjustSpeed(beam); VectorSet(beam->moveinfo.dir, beam->movedir[0]*control->crane_increment, beam->movedir[1]*control->crane_increment, 0); beam->crane_control = control; hoist->crane_dir = dir; hoist->crane_bonk = beam->crane_bonk + hoist->absmin[dir] - beam->absmin[dir]; hoist->crane_control = control; memcpy(&hoist->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); hook->crane_dir = dir; hook->crane_bonk = beam->crane_bonk + hook->absmin[dir] - beam->absmin[dir]; hook->crane_control = control; memcpy(&hook->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); cable->crane_dir = dir; cable->crane_bonk = beam->crane_bonk + cable->absmin[dir] - beam->absmin[dir]; cable->crane_control = control; memcpy(&cable->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); if(beam->crane_onboard_control) { beam->crane_onboard_control->crane_dir = dir; beam->crane_onboard_control->crane_bonk = beam->crane_bonk + beam->crane_onboard_control->absmin[dir] - beam->absmin[dir]; beam->crane_onboard_control->crane_control = control; memcpy(&beam->crane_onboard_control->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); } if(cargo) { cargo->crane_dir = dir; cargo->crane_bonk = beam->crane_bonk + cargo->absmin[dir] - beam->absmin[dir]; cargo->crane_control = control; memcpy(&cargo->moveinfo,&beam->moveinfo,sizeof(moveinfo_t)); } delay = G_Spawn(); delay->owner = control; delay->think = crane_reset_go; delay->nextthink = level.time + FRAMETIME; gi.linkentity(delay); self->count--; if(!self->count) { self->think = G_FreeEdict; self->nextthink = level.time + 1; } }
/*QUAKED trigger_key (.5 .5 .5) (-8 -8 -8) (8 8 8) A relay trigger that only fires it's targets if player has the proper key. Use "item" to specify the required key, for example "key_data_cd" */ void trigger_key_use (edict_t *self, edict_t *other, edict_t *activator) { int index; if (!self->item) return; if (!activator->client) return; index = ITEM_INDEX(self->item); if (!activator->client->pers.inventory[index]) { if (level.time < self->touch_debounce_time) return; self->touch_debounce_time = level.time + 5.0; safe_centerprintf (activator, "You need the %s", self->item->pickup_name); gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keytry.wav"), 1, ATTN_NORM, 0); return; } gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/keyuse.wav"), 1, ATTN_NORM, 0); if (coop->value) { int player; edict_t *ent; if (strcmp(self->item->classname, "key_power_cube") == 0) { int cube; for (cube = 0; cube < 8; cube++) // if (activator->client->pers.power_cubes & (1 << cube)) // break; for (player = 1; player <= game.maxclients; player++) { ent = &g_edicts[player]; if (!ent->inuse) continue; if (!ent->client) continue; // if (ent->client->pers.power_cubes & (1 << cube)) // { // ent->client->pers.inventory[index]--; // ent->client->pers.power_cubes &= ~(1 << cube); // } } } else { for (player = 1; player <= game.maxclients; player++) { ent = &g_edicts[player]; if (!ent->inuse) continue; if (!ent->client) continue; ent->client->pers.inventory[index] = 0; } } } else { activator->client->pers.inventory[index]--; } G_UseTargets (self, activator); self->use = NULL; }
void G_UseTarget (edict_t *ent, edict_t *activator, edict_t *target) { edict_t *t; // // check for a delay // if (ent->delay) { // create a temp object to fire at a later time t = G_Spawn(); t->classname = "DelayedUse"; t->nextthink = level.time + ent->delay; t->think = Think_Delay_Single; t->activator = activator; t->target_ent = target; if (!activator) gi.dprintf ("Think_Delay_Single with no activator\n"); t->message = ent->message; t->target = ent->target; t->killtarget = ent->killtarget; t->noise_index = ent->noise_index; return; } // // print the message // if ((ent->message) && !(activator->svflags & SVF_MONSTER)) { safe_centerprintf (activator, "%s", ent->message); if (ent->noise_index > 0) gi.sound (activator, CHAN_AUTO, ent->noise_index, 1, ATTN_NORM, 0); else if (ent->noise_index == 0) gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); } // // kill killtargets // if (ent->killtarget) { t = NULL; while ((t = G_Find (t, FOFS(targetname), ent->killtarget))) { // Lazarus: remove killtargeted monsters from total_monsters if(t->svflags & SVF_MONSTER) { if(!t->dmgteam || strcmp(t->dmgteam,"player")) if(!(t->monsterinfo.aiflags & AI_GOOD_GUY)) level.total_monsters--; } G_FreeEdict (t); if (!ent->inuse) { gi.dprintf("entity was removed while using killtargets\n"); return; } } } // // fire target // if (target) { // doors fire area portals in a specific way if (!Q_strcasecmp(target->classname, "func_areaportal") && (!Q_strcasecmp(ent->classname, "func_door") || !Q_strcasecmp(ent->classname, "func_door_rotating") || !Q_strcasecmp(ent->classname,"func_door_rot_dh"))) return; if (target == ent) { gi.dprintf ("WARNING: Entity used itself.\n"); } else { if (target->use) target->use (target, ent, activator); } if (!ent->inuse) { gi.dprintf("entity was removed while using target\n"); return; } } }
/* ============================== G_UseTargets the global "activator" should be set to the entity that initiated the firing. If self.delay is set, a DelayedUse entity will be created that will actually do the SUB_UseTargets after that many seconds have passed. Centerprints any self.message to the activator. Search for (string)targetname in all entities that match (string)self.target and call their .use function ============================== */ void G_UseTargets (edict_t *ent, edict_t *activator) { edict_t *t; // // check for a delay // if (ent->delay) { // create a temp object to fire at a later time t = G_Spawn(); t->classname = "DelayedUse"; t->nextthink = level.time + ent->delay; t->think = Think_Delay; t->activator = activator; if (!activator) gi.dprintf ("Think_Delay with no activator\n"); t->message = ent->message; t->target = ent->target; t->killtarget = ent->killtarget; t->noise_index = ent->noise_index; return; } // // print the message // if ((ent->message) && !(activator->svflags & SVF_MONSTER)) { // Lazarus - change so that noise_index < 0 means no sound safe_centerprintf (activator, "%s", ent->message); if (ent->noise_index > 0) gi.sound (activator, CHAN_AUTO, ent->noise_index, 1, ATTN_NORM, 0); else if (ent->noise_index == 0) gi.sound (activator, CHAN_AUTO, gi.soundindex ("misc/talk1.wav"), 1, ATTN_NORM, 0); } // // kill killtargets // if (ent->killtarget) { t = NULL; while ((t = G_Find (t, FOFS(targetname), ent->killtarget))) { // Lazarus: remove LIVE killtargeted monsters from total_monsters if((t->svflags & SVF_MONSTER) && (t->deadflag == DEAD_NO)) { if(!t->dmgteam || strcmp(t->dmgteam,"player")) if(!(t->monsterinfo.aiflags & AI_GOOD_GUY)) level.total_monsters--; } // and decrement secret count if target_secret is removed else if(!Q_strcasecmp(t->classname,"target_secret")) level.total_secrets--; // same deal with target_goal, but also turn off CD music if applicable else if(!Q_strcasecmp(t->classname,"target_goal")) { level.total_goals--; if (level.found_goals >= level.total_goals) gi.configstring (CS_CDTRACK, "0"); } G_FreeEdict (t); if (!ent->inuse) { gi.dprintf("entity was removed while using killtargets\n"); return; } } } // // fire targets // if (ent->target) { t = NULL; while ((t = G_Find (t, FOFS(targetname), ent->target))) { // doors fire area portals in a specific way if (!Q_strcasecmp(t->classname, "func_areaportal") && (!Q_strcasecmp(ent->classname, "func_door") || !Q_strcasecmp(ent->classname, "func_door_rotating") /*DWH*/ || !Q_strcasecmp(ent->classname,"func_door_rot_dh"))) continue; if (t == ent) { gi.dprintf ("WARNING: Entity used itself.\n"); } else { if (t->use) t->use (t, ent, activator); } if (!ent->inuse) { gi.dprintf("entity was removed while using targets\n"); return; } } } }
void Weapon_Sandbag_Fire (edict_t *ent) { edict_t *sandbag; ent->client->ps.gunframe++; if (ent->client->resp.team_on->index == 0) { if (allied_sandbags >= sandbaglimit->value) { safe_centerprintf(ent, "Your team is at the sandbag limit!\n"); return; } } else if (ent->client->resp.team_on->index == 1) { if (axis_sandbags >= sandbaglimit->value) { safe_centerprintf(ent, "Your team is at the sandbag limit!\n"); return; } } if (VectorCompare (ent->client->sandbag_pos , vec3_origin)) { safe_centerprintf(ent, "There's no space for sandbags there!\n"); return; } ent->client->pers.inventory[ITEM_INDEX(FindItem("Sandbags"))]--; sandbag = G_Spawn(); VectorCopy (ent->client->sandbag_preview->mins, sandbag->mins); VectorCopy (ent->client->sandbag_preview->maxs, sandbag->maxs); VectorCopy (ent->client->sandbag_preview->s.angles, sandbag->s.angles); sandbag->classnameb = SANDBAGS; sandbag->movetype = MOVETYPE_TOSS; sandbag->solid = SOLID_BBOX; sandbag->s.modelindex = gi.modelindex ("models/objects/sandbag/tris.md2"); sandbag->think = sandbag_think; sandbag->nextthink = level.time +.1; // ent->s.frame = rand() % 16; // ent->s.frame = 1; sandbag->mass = 300; sandbag->touch = sandbag_touch; sandbag->health = 2000; sandbag->takedamage = DAMAGE_YES; sandbag->die = sandbag_die; sandbag->s.skinnum = 0; sandbag->s.frame = 0; // VectorSet (sandbag->mins, -19, -9, -10); // VectorSet (sandbag->maxs, 19, 9, 8); VectorCopy (ent->client->sandbag_pos, sandbag->s.origin); sandbag->clipmask = MASK_SHOT; sandbag->spawnflags = 1; if (ent->client->resp.team_on) sandbag->obj_owner = ent->client->resp.team_on->index; if (ent->client->resp.team_on->index == 0) allied_sandbags++; else if (ent->client->resp.team_on->index == 1) axis_sandbags++; sandbag->obj_time = level.time; gi.linkentity (sandbag); if (ent->client->pers.inventory[ITEM_INDEX(FindItem("Sandbags"))] ==0) { ent->client->weaponstate=WEAPON_LOWER; ent->client->ps.gunframe = 20; Use_Weapon (ent, FindItem("fists")); return; } G_FreeEdict (ent->client->sandbag_preview); ent->client->sandbag_preview = NULL; }
void camera_on(edict_t *ent) { gclient_t *cl; edict_t *faker; edict_t *monster; edict_t *camera; int i; vec3_t forward, left, up; if (!ent->client) { return; } if (!ent->client->spycam) { return; } // "viewer" can control camera aim (2nd player to come along and use // camera cannot) camera = ent->client->spycam; if (camera->monsterinfo.aiflags & AI_ACTOR) { camera->flags |= FL_ROBOT; } if (!camera->viewer) { camera->viewer = ent; } // save current viewangles and restore them with camera_off VectorCopy(ent->client->v_angle, ent->client->org_viewangles); // copy over all important player data to fake player ent->client->camplayer = G_Spawn(); faker = ent->client->camplayer; faker->s.frame = ent->s.frame; VectorCopy(ent->s.origin, faker->s.origin); VectorCopy(ent->velocity, faker->velocity); VectorCopy(ent->s.angles, faker->s.angles); faker->s = ent->s; faker->takedamage = DAMAGE_AIM; faker->movetype = MOVETYPE_WALK; faker->groundentity = ent->groundentity; faker->viewheight = ent->viewheight; faker->inuse = true; faker->classname = "camplayer"; faker->mass = ent->mass; faker->solid = SOLID_BBOX; faker->deadflag = DEAD_NO; faker->clipmask = MASK_PLAYERSOLID; faker->health = ent->health; faker->light_level = ent->light_level; faker->think = faker_animate; faker->nextthink = level.time + FRAMETIME; VectorCopy(ent->mins, faker->mins); VectorCopy(ent->maxs, faker->maxs); // create a client so you can pick up items/be shot/etc while in camera cl = (gclient_t *)malloc(sizeof(gclient_t)); memset(cl, 0, sizeof(gclient_t)); ent->client->camplayer->client = cl; ent->client->camplayer->target_ent = ent; gi.linkentity(faker); AngleVectors(camera->s.angles, forward, left, up); VectorMA(camera->s.origin, camera->move_origin[0], forward, ent->s.origin); VectorMA(ent->s.origin, -camera->move_origin[1], left, ent->s.origin); VectorMA(ent->s.origin, camera->move_origin[2], up, ent->s.origin); ent->movetype = MOVETYPE_NOCLIP; ent->clipmask = 0; ent->solid = SOLID_NOT; VectorClear(ent->velocity); ent->client->ps.gunindex = 0; ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION; #ifdef KMQUAKE2_ENGINE_MOD // Knightmare- Camera effect and letterboxing if (ent->client->monitor->spawnflags & 64) { ent->client->ps.rdflags |= RDF_CAMERAEFFECT; } if (ent->client->monitor->spawnflags & 128) { ent->client->ps.rdflags |= RDF_LETTERBOX; } #endif ent->svflags |= SVF_NOCLIENT; // check to see if we're the enemy of any monster. If so, make the // faker the enemy for (i = maxclients->value + 1, monster = g_edicts + i; i < globals.num_edicts; i++, monster++) { if (!monster->inuse) { continue; } if (!(monster->svflags & SVF_MONSTER)) { continue; } if (monster->enemy == ent) { monster->enemy = faker; FoundTarget(monster); } } if (ent->client->spycam->viewmessage) { safe_centerprintf(ent, ent->client->spycam->viewmessage); } }
/* ================= Cmd_Arty_f CCH: new function to call in airstrikes ================= */ void Cmd_Arty_f (edict_t *ent) { /* vec3_t start; vec3_t forward; vec3_t end; vec3_t world_up; edict_t *airstrike;//faf trace_t tr;*/ //int randnum; vec3_t v; edict_t *check; int e; edict_t *t; vec3_t vdist; float tdist; int i; if (!ent->client) return; if (!IsValidPlayer(ent)) return; if (ent->deadflag) return; if (!ent->client->resp.team_on) return; for (i=0 ; i<game.maxentities ; i++) { vec3_t neworg; t = &g_edicts[i]; if (!t->inuse) continue; if (!t->classnameb) continue; if (t->classnameb != TNT) continue; VectorCopy (ent->s.origin, neworg); neworg[2]+= ent->viewheight; VectorSubtract (t->s.origin, neworg, vdist); tdist = VectorLength (vdist); if (tdist > 40) continue; if (infront (ent, t)) { t->think = G_FreeEdict; t->nextthink = level.time + 2; t->s.sound = 0; t->s.effects = 0; safe_centerprintf (ent, "You defused the TNT!\n"); } } Spawn_Chute_Special (ent); //faf: turret stuff if (!ent->client->turret && !ent->client->grenade) { if (CheckForTurret(ent)) { Use_Weapon (ent, FindItem("Fists")); CheckForTurret(ent); return; } } else { turret_off(ent); return; } if (ent->client && ent->client->pers.weapon && ent->client->pers.weapon->classnameb == WEAPON_ARISAKA) { if (ent->client->weaponstate == WEAPON_READY && ent->client->ps.gunframe < 99 && !ent->client->aim) { ent->client->ps.gunframe = 99; Weapon_Bayonet_Fire1 (ent); return; } return; } if (ent->client && ent->client->pers.weapon && ent->client->pers.weapon->classnameb == WEAPON_CARCANO) { if (ent->client->weaponstate == WEAPON_READY && ent->client->ps.gunframe < 104 && !ent->client->aim) { ent->client->ps.gunframe = 104; Weapon_Bayonet_Fire1 (ent); return; } return; } if (ent->client && ent->client->pers.weapon && ent->client->pers.weapon->classnameb == WEAPON_ENFIELD) { if (ent->client->weaponstate == WEAPON_READY && ent->client->ps.gunframe < 107 //&& )//!ent->client->aim) { ent->client->aim = false; ent->client->ps.gunframe = 107; Weapon_Bayonet_Fire1 (ent); return; } return; } if (ent->client && ent->client->pers.weapon && ent->client->pers.weapon->classnameb == WEAPON_SVT) { if (ent->client->weaponstate == WEAPON_READY && ent->client->ps.gunframe < 89 && !ent->client->aim) { ent->client->ps.gunframe = 89; Weapon_Bayonet_Fire1 (ent); return; } return; } if (ent->client->airstrike) { safe_cprintf(ent, PRINT_HIGH, "Airstrike cancelled sir!\n"); G_FreeEdict(ent->client->airstrike); ent->client->airstrike = NULL; return; } else if ((ent->client->pers.weapon && ent->client->pers.weapon->classnameb) && ent->client->pers.weapon->classnameb == WEAPON_BINOCULARS) { if (ent->client->aim) safe_cprintf(ent, PRINT_HIGH, "Press fire to call an airstrike!\n"); else safe_cprintf(ent, PRINT_HIGH, "Aim and then press fire to call an airstrike!\n"); } // if (ent->client->resp.mos != OFFICER) { // safe_cprintf(ent, PRINT_HIGH, "You're not an officer, soldier!\n"); // return; // } if (ent->deadflag || ent->client->limbo_mode ) { safe_cprintf(ent, PRINT_HIGH, "You are dead!\n"); return; } //faf: moving this up so you dont have to look through binocs to cancel arty // make sure artillary hasn't already been called check = g_edicts+1; for (e = 1; e < globals.num_edicts; e++, check++) { if (!check->inuse) continue; if (check->health < 1) continue; if (strcmp(check->classname, "misc_civilian")) continue; VectorSubtract (ent->s.origin, check->s.origin, v); if (VectorLength (v)< 100) { //gi.dprintf(DEVELOPER_MSG_GAME, "CIV FOUND\n"); if (check->master == ent) { check->master = NULL; //gi.dprintf(DEVELOPER_MSG_GAME, "STAY\n"); gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/trigger1.wav"), .5, ATTN_STATIC, 0); check->goalentity = NULL; check->movetarget = NULL; check->enemy = NULL; check->monsterinfo.currentmove = &civilian_move_stand; } else { if (check->master && check->obj_owner == ent->client->resp.team_on->index) return; // can't steal civilian from teammate gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/trigger1.wav"), .5, ATTN_STATIC, 0); check->master = ent; //gi.dprintf(DEVELOPER_MSG_GAME, "FOLLOW\n"); if (check->obj_owner != ent->client->resp.team_on->index) { level.obj_team = ent->client->resp.team_on->index; check->obj_owner = ent->client->resp.team_on->index; check->wait =level.time; //if (!check->wait) check->wait =level.time; } } check->obj_owner = ent->client->resp.team_on->index; } } }