void TBI_SpawnDie(edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point) { if (self->deadflag != DEAD_DEAD) { int i_maxclients = maxclients->value; self->svflags |= SVF_NOCLIENT; self->solid = SOLID_NOT; self->takedamage = DAMAGE_NO; self->deadflag = DEAD_DEAD; G_PrintGreenText(va("A %s spawn has been destroyed. %d/%d left.", self->teamnum == RED_TEAM ? "red" : "blue", self->teamnum == RED_TEAM ? tbi_game.RedSpawns-1 : tbi_game.BlueSpawns-1, // left self->teamnum == RED_TEAM ? tbi_game.TotalRedSpawns : tbi_game.TotalBlueSpawns) // team ); // of total // Give some experience. TBI_AwardTeam(self->teamnum == RED_TEAM? BLUE_TEAM : RED_TEAM, DESTROYSPAWN_EXP, false); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_EXPLOSION1); gi.WritePosition (self->s.origin); gi.multicast (self->s.origin, MULTICAST_PVS); if (!TBI_CheckRules(self)) gi.sound(g_edicts, CHAN_VOICE, gi.soundindex(va("bosstank/BTKUNQV%d.wav", GetRandom(1, 2))), 1, ATTN_NONE, 0); } }
void boss_spawn_tank (edict_t *ent) { char userinfo[MAX_INFO_STRING]; //edict_t *tank; //gi.dprintf("boss_spawn_tank()\n"); if (G_EntExists(ent->owner) && (ent->owner->mtype == BOSS_TANK)) { G_PrintGreenText(va("%s got bored and left the game.", ent->client->pers.netname)); BecomeTE(ent->owner); ent->svflags &= ~SVF_NOCLIENT; ent->viewheight = 22; ent->movetype = MOVETYPE_WALK; ent->solid = SOLID_BBOX; ent->takedamage = DAMAGE_AIM; // recover player info memcpy(userinfo, ent->client->pers.userinfo, sizeof(userinfo)); InitClientPersistant(ent->client); ClientUserinfoChanged(ent, userinfo); modify_max(ent); Pick_respawnweapon(ent); ent->owner = NULL; return; } CreateBoss(ent); }
void Boss_ReadyPlayer (edict_t *player, edict_t *boss) { if (!boss || !player) return; //gi.dprintf("getting boss ready\n"); boss->activator = player; boss->owner = player; VectorCopy(player->s.angles, boss->s.angles); boss->s.angles[PITCH] = 0; VectorCopy(player->s.origin, boss->s.origin); VectorCopy(player->s.old_origin, boss->s.old_origin); gi.linkentity(boss); //gi.dprintf("getting player ready\n"); player->owner = boss; // make the player into a ghost player->svflags |= SVF_NOCLIENT; player->viewheight = 0; player->movetype = MOVETYPE_NOCLIP; player->solid = SOLID_NOT; player->takedamage = DAMAGE_NO; player->client->ps.gunindex = 0; memset (player->client->pers.inventory, 0, sizeof(player->client->pers.inventory)); player->client->pers.weapon = NULL; G_PrintGreenText(va("A level %d boss known as %s has spawned!", boss->monsterinfo.level, player->client->pers.netname)); //gi.dprintf("DEBUG: player and boss ready\n"); }
void BossCheck(edict_t *e, edict_t *self) { if (!(invasion_difficulty_level % 5))// every 5 levels, spawn a boss { int bcount = 0; int iter = 0; while (((e = INV_GetMonsterSpawn(e)) != NULL) && (bcount < 1)) { if (!invasion_data.boss) { if(! (invasion_data.boss = INV_SpawnDrone(self, e, 30)) ) { iter++; if (iter < 256) // 256 tries before quitting with spawning this boss continue; else break; } bcount ++; total_monsters++; invasion_data.mspawned++; invasion_data.boss->die = invasiontank_die; G_PrintGreenText(va("A level %d tank commander has spawned!", invasion_data.boss->monsterinfo.level)); break; } } }else invasion_data.boss = NULL; }
void AwardBossKill (edict_t *boss) { int i, damage, exp_points, credits; float levelmod, dmgmod; edict_t *player; dmglist_t *slot=NULL; // find the player that did the most damage slot = findHighestDmgPlayer(boss); for (i=0; i<game.maxclients; i++) { player = g_edicts+1+i; if (!player->inuse) continue; levelmod = ((float)boss->monsterinfo.level+1) / ((float)player->myskills.level+1); damage = GetPlayerBossDamage(player, boss); if (damage < 1) continue; // they get nothing if they didn't touch the boss dmgmod = (float)damage / GetTotalBossDamage(boss); exp_points = levelmod*dmgmod*PVB_BOSS_EXPERIENCE; credits = levelmod*dmgmod*PVB_BOSS_CREDITS; // award extra points for the player that did the most damage if (slot && (player == slot->player)) { dmgmod = 100*(slot->damage/GetTotalBossDamage(boss)); G_PrintGreenText(va("%s got a hi-damage bonus! %d damage (%.1f%c)", slot->player->client->pers.netname, (int)slot->damage, dmgmod, '%')); exp_points *= BOSS_DAMAGE_BONUSMOD; } if (exp_points > PVB_BOSS_MAX_EXP) exp_points = PVB_BOSS_MAX_EXP; else if (exp_points < PVB_BOSS_MIN_EXP) exp_points = PVB_BOSS_MIN_EXP; player->myskills.credits += credits; V_AddFinalExp(player, exp_points); safe_cprintf(player, PRINT_HIGH, "You gained %d experience and %d credits!\n", exp_points, credits); } }
void init_drone_commander (edict_t *self) { init_drone_tank(self); // modify health and armor //self->health = 1000*self->monsterinfo.level; //self->max_health = self->health; //self->monsterinfo.power_armor_power = 1000*self->monsterinfo.level; //self->monsterinfo.max_armor = self->monsterinfo.power_armor_power; self->monsterinfo.control_cost = 4; self->monsterinfo.cost = M_COMMANDER_COST; self->mtype = M_COMMANDER; self->s.skinnum = 2; G_PrintGreenText(va("A level %d tank commander has spawned!", self->monsterinfo.level)); }
void INV_SpawnMonsters (edict_t *self) { int players, max_monsters; edict_t *e=NULL; PVM_TotalMonsters(self, true); players = max_monsters = total_players(); // there are still monsters alive if ((self->num_monsters_real > 0) && (self->count == MONSTERSPAWN_STATUS_IDLE)) { // if there's nobody playing, remove all monsters if (players < 1) { PVM_RemoveAllMonsters(self); return; // don't spawn any monsters. } if (level.intermissiontime) { if (self->num_monsters_real) PVM_RemoveAllMonsters(self); return; } if (invasion_data.limitframe > level.time) // we still got time? { self->nextthink = level.time + FRAMETIME; return; }else { gi.bprintf(PRINT_HIGH, "Time's up!\n"); if (invasion_data.boss && invasion_data.boss->deadflag != DEAD_DEAD) // out of time for the boss. { G_PrintGreenText(va("You failed to eliminate the commander soon enough!\n")); gi.WriteByte (svc_temp_entity); gi.WriteByte (TE_BOSSTPORT); gi.WritePosition (invasion_data.boss->s.origin); gi.multicast (invasion_data.boss->s.origin, MULTICAST_PVS); gi.unlinkentity(invasion_data.boss); G_FreeEdict(invasion_data.boss); invasion_data.boss = NULL; } // increase the difficulty level for the next wave if (invasion->value == 1) invasion_difficulty_level += 1; else invasion_difficulty_level += 2; // Hard mode. invasion_data.printedmessage = 0; gi.sound(&g_edicts[0], CHAN_VOICE, gi.soundindex("misc/tele_up.wav"), 1, ATTN_NONE, 0); } }else // Timeout has happened or all monsters eliminated { self->count = MONSTERSPAWN_STATUS_WORKING; invasion_data.mspawned = self->num_monsters_real; } if (players < 1) { // if there's nobody playing, then wait until some join self->nextthink = level.time + FRAMETIME; return; } switch (invasion_difficulty_level) { case 1: max_monsters = 10; break; case 2: max_monsters = 20; break; case 3: max_monsters = 25; break; case 4: max_monsters = 30; break; case 5: case 6: case 7: case 8: case 9: case 10: max_monsters = 35; break; // vrxcl 3.2b decrease for not saturating the server hard. default: max_monsters = 40; } if (!(invasion_difficulty_level % 5)) { if (invasion->value == 1) max_monsters = 4*(ActivePlayers()-1); else if (invasion->value == 2) max_monsters = 6*(ActivePlayers()-1); } if (!invasion_data.printedmessage) { invasion_data.limitframe = level.time + TimeFormula(); if (invasion_difficulty_level == 1) { if (invasion->value == 1) gi.bprintf(PRINT_HIGH, "The invasion begins!\n"); else gi.bprintf(PRINT_HIGH, "The invasion... begins.\n"); } if (invasion_difficulty_level % 5) gi.bprintf(PRINT_HIGH, "Welcome to level %d. %d monsters incoming!\n", invasion_difficulty_level, max_monsters); else gi.bprintf(PRINT_HIGH, "Welcome to level %d.\n", invasion_difficulty_level, max_monsters); G_PrintGreenText(va("Timelimit: %dm %ds.\n", (int)TimeFormula() / 60, (int)TimeFormula() % 60)); gi.sound(&g_edicts[0], CHAN_VOICE, gi.soundindex("misc/talk1.wav"), 1, ATTN_NONE, 0); BossCheck(e, self); invasion_data.printedmessage = 1; } while ( ((e = INV_GetMonsterSpawn(e)) != NULL) && invasion_data.mspawned < max_monsters) { int randomval = GetRandom(1, 9); if (invasion_difficulty_level % 5 && invasion->value == 1) // nonboss stage? easy mode? { while ( randomval == 5 ) // disallow medics { randomval = GetRandom(1, 8); } } if (!INV_SpawnDrone(self, e, randomval)) continue; else invasion_data.mspawned++; } if (invasion_data.mspawned == max_monsters) { // increase the difficulty level for the next wave invasion_difficulty_level += 1; invasion_data.printedmessage = 0; invasion_data.mspawned = 0; self->count = MONSTERSPAWN_STATUS_IDLE; } self->nextthink = level.time + FRAMETIME; }