/* ================== CG_LaunchGib ================== */ void CG_LaunchGib( centity_t *cent, vec3_t origin, vec3_t angles, vec3_t velocity, qhandle_t hModel, float sizeScale, int breakCount ) { localEntity_t *le; refEntity_t *re; int i; if ( !cg_blood.integer ) { return; } le = CG_AllocLocalEntity(); re = &le->refEntity; le->leType = LE_FRAGMENT; le->startTime = cg.time; // le->endTime = le->startTime + 60000 + random() * 60000; le->endTime = le->startTime + 20000 + (crandom() * 5000); le->breakCount = breakCount; le->sizeScale = sizeScale; VectorCopy( angles, le->angles.trBase ); VectorCopy( origin, re->origin ); AnglesToAxis( angles, re->axis ); if (sizeScale != 1.0) { for (i=0;i<3;i++) VectorScale( re->axis[i], sizeScale, re->axis[i] ); } re->hModel = hModel; // re->fadeStartTime = le->endTime - 3000; re->fadeStartTime = le->endTime - 1000; re->fadeEndTime = le->endTime; le->leBounceSoundType = LEBS_BLOOD; le->leMarkType = LEMT_BLOOD; le->pos.trType = TR_GRAVITY; le->angles.trDelta[0] = (10 + (rand()&50)) - 30; // le->angles.trDelta[0] = (100 + (rand()&500)) - 300; // pitch le->angles.trDelta[1] = (100 + (rand()&500)) - 300; // (SA) this is the safe one right now (yaw) turn the others up when I have tumbling things landing properly le->angles.trDelta[2] = (10 + (rand()&50)) - 30; // le->angles.trDelta[2] = (100 + (rand()&500)) - 300; // roll le->bounceFactor = 0.3; VectorCopy( origin, le->pos.trBase ); VectorCopy( velocity, le->pos.trDelta ); le->pos.trTime = cg.time; le->angles.trType = TR_LINEAR; le->angles.trTime = cg.time; le->ownerNum = cent->currentState.number; // Ridah, if the player is on fire, then spawn some flaming gibs if (cent && CG_EntOnFire(cent)) { le->onFireStart = cent->currentState.onFireStart; le->onFireEnd = re->fadeEndTime+1000; } }
/* =============== CG_TransitionEntity cent->nextState is moved to cent->currentState and events are fired =============== */ static void CG_TransitionEntity( centity_t *cent ) { // Ridah, update the fireDir if it's on fire if ( CG_EntOnFire( cent ) ) { vec3_t newDir, newPos, oldPos; float adjust; // BG_EvaluateTrajectory( ¢->nextState.pos, cg.snap->serverTime, newPos ); BG_EvaluateTrajectory( ¢->currentState.pos, cg.snap->serverTime, oldPos ); // update the fireRiseDir VectorSubtract( oldPos, newPos, newDir ); // fire should go upwards if travelling slow newDir[2] += 2; if ( VectorNormalize( newDir ) < 1 ) { VectorClear( newDir ); newDir[2] = 1; } // now move towards the newDir adjust = 0.3; VectorMA( cent->fireRiseDir, adjust, newDir, cent->fireRiseDir ); if ( VectorNormalize( cent->fireRiseDir ) <= 0.1 ) { VectorCopy( newDir, cent->fireRiseDir ); } } //----(SA) the ent lost or gained some part(s), do any necessary effects //TODO: check for ai first if ( cent->currentState.dmgFlags != cent->nextState.dmgFlags ) { CG_AttachedPartChange( cent ); } cent->currentState = cent->nextState; cent->currentValid = qtrue; // reset if the entity wasn't in the last frame or was teleported if ( !cent->interpolate ) { CG_ResetEntity( cent ); } // clear the next state. if will be set by the next CG_SetNextSnap cent->interpolate = qfalse; // check for events CG_CheckEvents( cent ); }
/* ============== CG_LoseHat ============== */ void CG_LoseHat(centity_t *cent, vec3_t dir) { clientInfo_t *ci; int clientNum; // int i, count, tagIndex, gibIndex; int tagIndex; vec3_t origin, velocity; bg_character_t *character; clientNum = cent->currentState.clientNum; if (clientNum < 0 || clientNum >= MAX_CLIENTS) { CG_Error("Bad clientNum on player entity"); } ci = &cgs.clientinfo[clientNum]; character = CG_CharacterForClientinfo(ci, cent); // don't launch anything if they don't have one if (!character->accModels[ACC_HAT]) { return; } tagIndex = CG_GetOriginForTag(cent, ¢->pe.headRefEnt, "tag_mouth", 0, origin, NULL); velocity[0] = dir[0] * (0.75 + random()) * GIB_VELOCITY; velocity[1] = dir[1] * (0.75 + random()) * GIB_VELOCITY; velocity[2] = GIB_JUMP - 50 + dir[2] * (0.5 + random()) * GIB_VELOCITY; { localEntity_t *le; refEntity_t *re; le = CG_AllocLocalEntity(); re = &le->refEntity; le->leType = LE_FRAGMENT; le->startTime = cg.time; le->endTime = le->startTime + 20000 + (crandom() * 5000); VectorCopy(origin, re->origin); AxisCopy(axisDefault, re->axis); re->hModel = character->accModels[ACC_HAT]; re->customSkin = character->accSkins[ACC_HAT]; re->fadeStartTime = le->endTime - 1000; re->fadeEndTime = le->endTime; // (SA) FIXME: origin of hat md3 is offset from center. need to center the origin when you toss it le->pos.trType = TR_GRAVITY; VectorCopy(origin, le->pos.trBase); VectorCopy(velocity, le->pos.trDelta); le->pos.trTime = cg.time; // spin it a bit le->angles.trType = TR_LINEAR; VectorCopy(tv(0, 0, 0), le->angles.trBase); le->angles.trDelta[0] = 0; le->angles.trDelta[1] = (100 + (rand() & 500)) - 300; // le->angles.trDelta[2] = 0; le->angles.trDelta[2] = 400; // (SA) this is set with a very particular value to try to get it // to flip exactly once before landing (based on player alive // (standing) and on level ground) and will be unnecessary when // I have things landing properly on their own le->angles.trTime = cg.time; le->bounceFactor = 0.2; // Ridah, if the player is on fire, then make the hat on fire if (cent && CG_EntOnFire(cent)) { le->onFireStart = cent->currentState.onFireStart; le->onFireEnd = cent->currentState.onFireEnd + 4000; } } }