void teleporter_touch(edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { edict_t *dest; int i; if (!other->client) { return; } dest = G_Find(NULL, FOFS(targetname), self->target); if (!dest) { gi.dprintf("Couldn't find destination\n"); return; } CTFPlayerResetGrapple(other); /* unlink to make sure it can't possibly interfere with KillBox */ gi.unlinkentity(other); VectorCopy(dest->s.origin, other->s.origin); VectorCopy(dest->s.origin, other->s.old_origin); other->s.origin[2] += 10; /* clear the velocity and hold them in place briefly */ VectorClear(other->velocity); other->client->ps.pmove.pm_time = 160 >> 3; /* hold time */ other->client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT; /* draw the teleport splash at source and on the player */ self->owner->s.event = EV_PLAYER_TELEPORT; other->s.event = EV_PLAYER_TELEPORT; /* set angles */ for (i = 0; i < 3; i++) { other->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(dest->s.angles[i] - other->client->resp.cmd_angles[i]); } VectorClear(other->s.angles); VectorClear(other->client->ps.viewangles); VectorClear(other->client->v_angle); /* kill anything at the destination */ KillBox(other); gi.linkentity(other); }
/* ================== player_die ================== */ void player_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { int n; VectorClear (self->avelocity); self->takedamage = DAMAGE_YES; self->movetype = MOVETYPE_TOSS; self->s.modelindex2 = 0; // remove linked weapon model //ZOID self->s.modelindex3 = 0; // remove linked ctf flag //ZOID self->s.angles[0] = 0; self->s.angles[2] = 0; self->s.sound = 0; self->client->weapon_sound = 0; self->maxs[2] = -8; // self->solid = SOLID_NOT; self->svflags |= SVF_DEADMONSTER; if (!self->deadflag) { self->client->respawn_time = level.time + 1.0; LookAtKiller (self, inflictor, attacker); self->client->ps.pmove.pm_type = PM_DEAD; ClientObituary (self, inflictor, attacker); //ZOID CTFFragBonuses(self, inflictor, attacker); //ZOID TossClientWeapon (self); //ZOID CTFPlayerResetGrapple(self); CTFDeadDropFlag(self); CTFDeadDropTech(self); //ZOID if (deathmatch->value && !self->client->showscores) Cmd_Help_f (self); // show scores } // remove powerups self->client->quad_framenum = 0; self->client->invincible_framenum = 0; self->client->breather_framenum = 0; self->client->enviro_framenum = 0; // clear inventory memset(self->client->pers.inventory, 0, sizeof(self->client->pers.inventory)); if (self->health < -40) { // gib gi.sound (self, CHAN_BODY, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0); for (n= 0; n < 4; n++) ThrowGib (self, "models/objects/gibs/sm_meat/tris.md2", damage, GIB_ORGANIC); ThrowClientHead (self, damage); //ZOID self->client->anim_priority = ANIM_DEATH; self->client->anim_end = 0; //ZOID self->takedamage = DAMAGE_NO; } else { // normal death if (!self->deadflag) { static int i; i = (i+1)%3; // start a death animation self->client->anim_priority = ANIM_DEATH; if (self->client->ps.pmove.pm_flags & PMF_DUCKED) { self->s.frame = FRAME_crdeath1-1; self->client->anim_end = FRAME_crdeath5; } else switch (i) { case 0: self->s.frame = FRAME_death101-1; self->client->anim_end = FRAME_death106; break; case 1: self->s.frame = FRAME_death201-1; self->client->anim_end = FRAME_death206; break; case 2: self->s.frame = FRAME_death301-1; self->client->anim_end = FRAME_death308; break; } gi.sound (self, CHAN_VOICE, gi.soundindex(va("*death%i.wav", (rand()%4)+1)), 1, ATTN_NORM, 0); } } self->deadflag = DEAD_DEAD; gi.linkentity (self); }
/////////////////////////////////////////////////////////////////////// // Main movement code. (following node path) /////////////////////////////////////////////////////////////////////// void ACEMV_Move(edict_t *self, usercmd_t *ucmd) { vec3_t dist; int current_node_type=-1; int next_node_type=-1; int i; // Get current and next node back from nav code. if(!ACEND_FollowPath(self)) { self->state = STATE_WANDER; self->wander_timeout = level.time + 1.0; return; } current_node_type = nodes[self->current_node].type; next_node_type = nodes[self->next_node].type; /////////////////////////// // Move To Goal /////////////////////////// if (self->movetarget) ACEMV_MoveToGoal(self,ucmd); //////////////////////////////////////////////////////// // Grapple /////////////////////////////////////////////////////// if(next_node_type == NODE_GRAPPLE) { ACEMV_ChangeBotAngle(self); ACEIT_ChangeWeapon(self,FindItem("grapple")); ucmd->buttons = BUTTON_ATTACK; return; } // Reset the grapple if hangin on a graple node if(current_node_type == NODE_GRAPPLE) { CTFPlayerResetGrapple(self); return; } // Platforms /////////////////////////////////////////////////////// if(current_node_type != NODE_PLATFORM && next_node_type == NODE_PLATFORM) { // check to see if lift is down? for(i=0;i<num_items;i++) if(item_table[i].node == self->next_node) if(item_table[i].ent->moveinfo.state != STATE_BOTTOM) return; // Wait for elevator } if(current_node_type == NODE_PLATFORM && next_node_type == NODE_PLATFORM) { // Move to the center self->move_vector[2] = 0; // kill z movement if(VectorLength(self->move_vector) > 10) ucmd->forwardmove = 200; // walk to center ACEMV_ChangeBotAngle(self); return; // No move, riding elevator } //////////////////////////////////////////////////////// // Jumpto Nodes /////////////////////////////////////////////////////// if(next_node_type == NODE_JUMP || (current_node_type == NODE_JUMP && next_node_type != NODE_ITEM && nodes[self->next_node].origin[2] > self->s.origin[2])) { // Set up a jump move ucmd->forwardmove = 400; ucmd->upmove = 400; ACEMV_ChangeBotAngle(self); VectorCopy(self->move_vector,dist); VectorScale(dist,440,self->velocity); return; } //////////////////////////////////////////////////////// // Ladder Nodes /////////////////////////////////////////////////////// if(next_node_type == NODE_LADDER && nodes[self->next_node].origin[2] > self->s.origin[2]) { // Otherwise move as fast as we can ucmd->forwardmove = 400; self->velocity[2] = 320; ACEMV_ChangeBotAngle(self); return; } // If getting off the ladder if(current_node_type == NODE_LADDER && next_node_type != NODE_LADDER && nodes[self->next_node].origin[2] > self->s.origin[2]) { ucmd->forwardmove = 400; ucmd->upmove = 200; self->velocity[2] = 200; ACEMV_ChangeBotAngle(self); return; } //////////////////////////////////////////////////////// // Water Nodes /////////////////////////////////////////////////////// if(current_node_type == NODE_WATER) { // We need to be pointed up/down ACEMV_ChangeBotAngle(self); // If the next node is not in the water, then move up to get out. if(next_node_type != NODE_WATER && !(gi.pointcontents(nodes[self->next_node].origin) & MASK_WATER)) // Exit water ucmd->upmove = 400; ucmd->forwardmove = 300; return; } // Falling off ledge? if(!self->groundentity) { ACEMV_ChangeBotAngle(self); self->velocity[0] = self->move_vector[0] * 360; self->velocity[1] = self->move_vector[1] * 360; return; } // Check to see if stuck, and if so try to free us // Also handles crouching if(VectorLength(self->velocity) < 37) { // Keep a random factor just in case.... if(random() > 0.1 && ACEMV_SpecialMove(self, ucmd)) return; self->s.angles[YAW] += random() * 180 - 90; ucmd->forwardmove = 400; return; } // Otherwise move as fast as we can ucmd->forwardmove = 400; ACEMV_ChangeBotAngle(self); }