void p_medic_reanimate (edict_t *ent, edict_t *target) { int skill_level; vec3_t bmin, bmax; edict_t *e; skill_level = floattoint((1.0+MEDIC_RESURRECT_BONUS)*ent->myskills.abilities[MEDIC].current_level); if (!strcmp(target->classname, "drone") && (ent->num_monsters + target->monsterinfo.control_cost <= MAX_MONSTERS)) { target->monsterinfo.level = skill_level; M_SetBoundingBox(target->mtype, bmin, bmax); if (G_IsValidLocation(target, target->s.origin, bmin, bmax) && M_Initialize(ent, target)) { // restore this drone target->monsterinfo.slots_freed = false; // reset freed flag target->health = 0.33*target->max_health; target->monsterinfo.power_armor_power = 0.33*target->monsterinfo.max_armor; target->monsterinfo.resurrected_time = level.time + 2.0; target->activator = ent; // transfer ownership! target->nextthink = level.time + MEDIC_RESURRECT_DELAY; gi.linkentity(target); target->monsterinfo.stand(target); ent->num_monsters += target->monsterinfo.control_cost; safe_cprintf(ent, PRINT_HIGH, "Resurrected a %s. (%d/%d)\n", target->classname, ent->num_monsters, MAX_MONSTERS); } } else if ((!strcmp(target->classname, "bodyque") || !strcmp(target->classname, "player")) && (ent->num_monsters + 1 <= MAX_MONSTERS)) { int random=GetRandom(1, 3); vec3_t start; e = G_Spawn(); VectorCopy(target->s.origin, start); // kill the corpse T_Damage(target, target, target, vec3_origin, target->s.origin, vec3_origin, 10000, 0, DAMAGE_NO_PROTECTION, 0); //4.2 random soldier type with different weapons if (random == 1) { // blaster e->mtype = M_SOLDIER; e->s.skinnum = 0; } else if (random == 2) { // rocket e->mtype = M_SOLDIERLT; e->s.skinnum = 4; } else { // shotgun e->mtype = M_SOLDIERSS; e->s.skinnum = 2; } e->activator = ent; e->monsterinfo.level = skill_level; M_Initialize(ent, e); e->health = 0.2*e->max_health; e->monsterinfo.power_armor_power = 0.2*e->monsterinfo.max_armor; e->s.skinnum |= 1; // injured skin e->monsterinfo.stand(e); if (!G_IsValidLocation(target, start, e->mins, e->maxs)) { start[2] += 24; if (!G_IsValidLocation(target, start, e->mins, e->maxs)) { G_FreeEdict(e); return; } } VectorCopy(start, e->s.origin); gi.linkentity(e); e->nextthink = level.time + MEDIC_RESURRECT_DELAY; ent->num_monsters += e->monsterinfo.control_cost; safe_cprintf(ent, PRINT_HIGH, "Resurrected a soldier. (%d/%d)\n", ent->num_monsters, MAX_MONSTERS); } else if (!strcmp(target->classname, "spiker") && ent->num_spikers + 1 <= SPIKER_MAX_COUNT) { e = CreateSpiker(ent, skill_level); // make sure the new entity fits if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs)) { ent->num_spikers--; G_FreeEdict(e); return; } VectorCopy(target->s.angles, e->s.angles); e->s.angles[PITCH] = 0; e->monsterinfo.cost = target->monsterinfo.cost; e->health = 0.33 * e->max_health; e->s.frame = 4; VectorCopy(target->s.origin, e->s.origin); gi.linkentity(e); organ_remove(target, false); } else if (!strcmp(target->classname, "obstacle") && ent->num_obstacle + 1 <= OBSTACLE_MAX_COUNT) { e = CreateObstacle(ent, skill_level); // make sure the new entity fits if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs)) { ent->num_obstacle--; G_FreeEdict(e); return; } VectorCopy(target->s.angles, e->s.angles); e->s.angles[PITCH] = 0; e->monsterinfo.cost = target->monsterinfo.cost; e->health = 0.33 * e->max_health; e->s.frame = 6; VectorCopy(target->s.origin, e->s.origin); gi.linkentity(e); organ_remove(target, false); } else if (!strcmp(target->classname, "gasser") && ent->num_gasser + 1 <= GASSER_MAX_COUNT) { e = CreateGasser(ent, skill_level); // make sure the new entity fits if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs)) { ent->num_gasser--; G_FreeEdict(e); return; } VectorCopy(target->s.angles, e->s.angles); e->s.angles[PITCH] = 0; e->monsterinfo.cost = target->monsterinfo.cost; e->health = 0.33 * e->max_health; e->s.frame = 0; VectorCopy(target->s.origin, e->s.origin); gi.linkentity(e); organ_remove(target, false); } }
void M_Reanimate (edict_t *ent, edict_t *target, int r_level, float r_modifier, qboolean printMsg) { vec3_t bmin, bmax; edict_t *e; if (!strcmp(target->classname, "drone")) { // if the summoner is a player, check for sufficient monster slots if (ent->client && (ent->num_monsters + target->monsterinfo.control_cost > MAX_MONSTERS)) return; target->monsterinfo.level = r_level; M_SetBoundingBox(target->mtype, bmin, bmax); if (G_IsValidLocation(target, target->s.origin, bmin, bmax) && M_Initialize(ent, target)) { // restore this drone target->monsterinfo.slots_freed = false; // reset freed flag target->health = r_modifier*target->max_health; target->monsterinfo.power_armor_power = r_modifier*target->monsterinfo.max_armor; target->monsterinfo.resurrected_time = level.time + 10.0; target->activator = ent; // transfer ownership! target->nextthink = level.time + 1.0; gi.linkentity(target); target->monsterinfo.stand(target); ent->num_monsters += target->monsterinfo.control_cost; // make sure invasion monsters hunt for navi if (invasion->value && !ent->client && ent->activator && !ent->activator->client) { target->monsterinfo.aiflags &= ~AI_STAND_GROUND; target->monsterinfo.aiflags |= AI_FIND_NAVI; } if (ent->client && printMsg) gi.cprintf(ent, PRINT_HIGH, "Resurrected a %s. (%d/%d)\n", target->classname, ent->num_monsters, MAX_MONSTERS); } } else if ((!strcmp(target->classname, "bodyque") || !strcmp(target->classname, "player"))) { int random=GetRandom(1, 3); vec3_t start; // if the summoner is a player, check for sufficient monster slots if (ent->client && (ent->num_monsters + 1 > MAX_MONSTERS)) return; e = G_Spawn(); VectorCopy(target->s.origin, start); // kill the corpse T_Damage(target, target, target, vec3_origin, target->s.origin, vec3_origin, 10000, 0, DAMAGE_NO_PROTECTION, 0); //4.2 random soldier type with different weapons if (random == 1) { // blaster e->mtype = M_SOLDIER; e->s.skinnum = 0; } else if (random == 2) { // rocket e->mtype = M_SOLDIERLT; e->s.skinnum = 4; } else { // shotgun e->mtype = M_SOLDIERSS; e->s.skinnum = 2; } e->activator = ent; e->monsterinfo.level = r_level; M_Initialize(ent, e); e->health = r_modifier*e->max_health; e->monsterinfo.power_armor_power = r_modifier*e->monsterinfo.max_armor; e->monsterinfo.resurrected_time = level.time + 10.0; e->s.skinnum |= 1; // injured skin e->monsterinfo.stand(e); if (!G_IsValidLocation(target, start, e->mins, e->maxs)) { start[2] += 24; if (!G_IsValidLocation(target, start, e->mins, e->maxs)) { G_FreeEdict(e); return; } } VectorCopy(start, e->s.origin); gi.linkentity(e); e->nextthink = level.time + 1.0; ent->num_monsters += e->monsterinfo.control_cost; // make sure invasion monsters hunt for navi if (invasion->value && !ent->client && ent->activator && !ent->activator->client) { target->monsterinfo.aiflags &= ~AI_STAND_GROUND; target->monsterinfo.aiflags |= AI_FIND_NAVI; } if (ent->client && printMsg) gi.cprintf(ent, PRINT_HIGH, "Resurrected a soldier. (%d/%d)\n", ent->num_monsters, MAX_MONSTERS); } else if (!strcmp(target->classname, "spiker")) { // if the summoner is a player, check for sufficient spiker slots if (ent->client && (ent->num_spikers + 1 > SPIKER_MAX_COUNT)) return; e = CreateSpiker(ent, r_level); // make sure the new entity fits if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs)) { ent->num_spikers--; G_FreeEdict(e); return; } VectorCopy(target->s.angles, e->s.angles); e->s.angles[PITCH] = 0; e->monsterinfo.cost = target->monsterinfo.cost; e->health = r_modifier * e->max_health; e->monsterinfo.resurrected_time = level.time + 10.0; e->s.frame = 4; VectorCopy(target->s.origin, e->s.origin); gi.linkentity(e); organ_remove(target, false); if (ent->client && printMsg) gi.cprintf(ent, PRINT_HIGH, "Resurrected a spiker. (%d/%d)\n", ent->num_spikers, SPIKER_MAX_COUNT); } else if (!strcmp(target->classname, "obstacle")) { // if the summoner is a player, check for sufficient obstacle slots if (ent->client && (ent->num_obstacle + 1 > OBSTACLE_MAX_COUNT)) return; e = CreateObstacle(ent, r_level); // make sure the new entity fits if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs)) { ent->num_obstacle--; G_FreeEdict(e); return; } VectorCopy(target->s.angles, e->s.angles); e->s.angles[PITCH] = 0; e->monsterinfo.cost = target->monsterinfo.cost; e->monsterinfo.resurrected_time = level.time + 10.0; e->health = r_modifier * e->max_health; e->s.frame = 6; VectorCopy(target->s.origin, e->s.origin); gi.linkentity(e); organ_remove(target, false); if (ent->client && printMsg) gi.cprintf(ent, PRINT_HIGH, "Resurrected an obstacle. (%d/%d)\n", ent->num_obstacle, OBSTACLE_MAX_COUNT); } else if (!strcmp(target->classname, "gasser")) { // if the summoner is a player, check for sufficient gasser slots if (ent->client && (ent->num_gasser + 1 > GASSER_MAX_COUNT)) return; e = CreateGasser(ent, r_level); // make sure the new entity fits if (!G_IsValidLocation(target, target->s.origin, e->mins, e->maxs)) { ent->num_gasser--; G_FreeEdict(e); return; } VectorCopy(target->s.angles, e->s.angles); e->s.angles[PITCH] = 0; e->monsterinfo.cost = target->monsterinfo.cost; e->monsterinfo.resurrected_time = level.time + 10.0; e->health = r_modifier * e->max_health; e->s.frame = 0; VectorCopy(target->s.origin, e->s.origin); gi.linkentity(e); organ_remove(target, false); if (ent->client && printMsg) gi.cprintf(ent, PRINT_HIGH, "Resurrected a gasser. (%d/%d)\n", ent->num_gasser, GASSER_MAX_COUNT); } }