X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Fgamemodes%2Fgamemode%2Fonslaught%2Fsv_onslaught.qc;h=223a81f7c4d4dfb6039a3ea6b2189b0df864dfd0;hb=7e474d576080259e21690de30778b17029b5c0f2;hp=a18ce34c5d06e83ad98d95a2e606f0034b5bc333;hpb=f366b93e1d9e8ebdff81c9277f9958178dcb38d0;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc b/qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc index a18ce34c5..223a81f7c 100644 --- a/qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc +++ b/qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc @@ -28,11 +28,27 @@ float autocvar_g_onslaught_spawn_choose; float autocvar_g_onslaught_click_radius; void FixSize(entity e); +entity cam; // ======================= // CaptureShield Functions // ======================= +bool clientcamera_send(entity this, entity to, int sf) +{ + WriteHeader(MSG_ENTITY, ENT_ONSCAMERA); + + WriteCoord(MSG_ENTITY, this.origin_x); + WriteCoord(MSG_ENTITY, this.origin_y); + WriteCoord(MSG_ENTITY, this.origin_z); + + WriteAngle(MSG_ENTITY, this.angles_x); + WriteAngle(MSG_ENTITY, this.angles_y); + WriteAngle(MSG_ENTITY, this.angles_z); + + return true; +} + bool ons_CaptureShield_Customize(entity this, entity client) { entity e = WaypointSprite_getviewentity(client); @@ -127,8 +143,8 @@ void onslaught_updatelinks() { l.islinked = false; l.isshielded = true; - int i; - for(i = 0; i < 17; ++i) { l.isgenneighbor[i] = false; l.iscpneighbor[i] = false; } + l.aregensneighbor = 0; + l.arecpsneighbor = 0; LOG_DEBUG(etos(l), " (point) belongs to team ", ftos(l.team)); l.sprite.SendFlags |= 16; } @@ -172,9 +188,9 @@ void onslaught_updatelinks() l.enemy.isshielded = false; } if(l.goalentity.classname == "onslaught_generator") - l.enemy.isgenneighbor[l.goalentity.team] = true; + l.enemy.aregensneighbor |= BIT(l.goalentity.team); else - l.enemy.iscpneighbor[l.goalentity.team] = true; + l.enemy.arecpsneighbor |= BIT(l.goalentity.team); } if (l.enemy.islinked) { @@ -184,9 +200,9 @@ void onslaught_updatelinks() l.goalentity.isshielded = false; } if(l.enemy.classname == "onslaught_generator") - l.goalentity.isgenneighbor[l.enemy.team] = true; + l.goalentity.aregensneighbor |= BIT(l.enemy.team); else - l.goalentity.iscpneighbor[l.enemy.team] = true; + l.goalentity.arecpsneighbor |= BIT(l.enemy.team); } } // now update the generators @@ -312,8 +328,8 @@ void ons_DelayedLinkSetup(entity this) int ons_ControlPoint_CanBeLinked(entity cp, int teamnumber) { - if(cp.isgenneighbor[teamnumber]) { return 2; } - if(cp.iscpneighbor[teamnumber]) { return 1; } + if(cp.aregensneighbor & BIT(teamnumber)) return 2; + if(cp.arecpsneighbor & BIT(teamnumber)) return 1; return 0; } @@ -537,7 +553,7 @@ void ons_ControlPoint_Icon_BuildThink(entity this) if(IS_PLAYER(this.owner.ons_toucher)) { Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ONSLAUGHT_CAPTURE, this.owner.ons_toucher.netname, this.owner.message); - Send_Notification(NOTIF_ALL_EXCEPT, this.owner.ons_toucher, MSG_CENTER, APP_TEAM_NUM(this.owner.ons_toucher.team, CENTER_ONS_CAPTURE), this.owner.message); + Send_Notification(NOTIF_ALL_EXCEPT, this.owner.ons_toucher, MSG_CENTER, APP_TEAM_NUM(this.owner.ons_toucher.team, CENTER_ONS_CAPTURE_TEAM), this.owner.message); Send_Notification(NOTIF_ONE, this.owner.ons_toucher, MSG_CENTER, CENTER_ONS_CAPTURE, this.owner.message); PlayerScore_Add(this.owner.ons_toucher, SP_ONS_CAPS, 1); PlayerTeamScore_AddScore(this.owner.ons_toucher, 10); @@ -817,11 +833,46 @@ void ons_Generator_UpdateSprite(entity e) } } +void ons_camSetup(entity this) +{ + vector dir; + vector ang = '0 0 0'; + vector best_ang = '0 0 0'; + float best_trace_fraction = 0; + while(ang.y < 360) + { + dir = vec2(cos(ang.y * DEG2RAD), sin(ang.y * DEG2RAD)); + dir *= 500; + traceline(this.origin, this.origin - dir, MOVE_WORLDONLY, this); + if(trace_fraction > best_trace_fraction) + { + best_trace_fraction = trace_fraction; + best_ang = ang; + if(trace_fraction == 1) + break; + } + ang.y += 90; + if(ang.y == 360) + ang.y = 45; + } + cam.origin = this.origin; + setorigin(cam, cam.origin); + cam.angles = best_ang; + Net_LinkEntity(cam, false, 0, clientcamera_send); + + FOREACH_CLIENT(true, it.clientcamera = cam;); + + WriteByte(MSG_ALL, SVC_SETVIEWANGLES); + WriteAngle(MSG_ALL, cam.angles_x); + WriteAngle(MSG_ALL, cam.angles_y); + WriteAngle(MSG_ALL, cam.angles_z); +} + void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) { - if(damage <= 0) { return; } - if(warmup_stage || gameover) { return; } - if(!round_handler_IsRoundStarted()) { return; } + if(damage <= 0) return; + if(warmup_stage || game_stopped) return; + if(!round_handler_IsRoundStarted()) return; if (attacker != this) { @@ -877,6 +928,8 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d //WaypointSprite_Kill(this.sprite); // can't do this yet, code too poor onslaught_updatelinks(); + + ons_camSetup(this); } // Throw some flaming gibs on damage, more damage = more chance for gib @@ -902,7 +955,7 @@ void ons_GeneratorDamage(entity this, entity inflictor, entity attacker, float d void ons_GeneratorThink(entity this) { this.nextthink = time + GEN_THINKRATE; - if (!gameover) + if (!game_stopped) { if(!this.isshielded && this.wait < time) { @@ -926,7 +979,8 @@ void ons_GeneratorReset(entity this) this.lasthealth = this.max_health = this.health = autocvar_g_onslaught_gen_health; this.takedamage = DAMAGE_AIM; this.bot_attack = true; - IL_PUSH(g_bot_targets, this); + if(!IL_CONTAINS(g_bot_targets, this)) + IL_PUSH(g_bot_targets, this); this.iscaptured = true; this.islinked = true; this.isshielded = true; @@ -985,6 +1039,7 @@ void ons_GeneratorSetup(entity gen) // called when spawning a generator entity o gen.classname = "onslaught_generator"; gen.solid = SOLID_BBOX; gen.team_saved = teamnumber; + IL_PUSH(g_saved_team, gen); set_movetype(gen, MOVETYPE_NONE); gen.lasthealth = gen.max_health = gen.health = autocvar_g_onslaught_gen_health; gen.takedamage = DAMAGE_AIM; @@ -1141,6 +1196,7 @@ bool Onslaught_CheckWinner() nades_Clear(it); }); + game_stopped = true; return 1; } @@ -1252,7 +1308,7 @@ void havocbot_goalrating_ons_controlpoints_attack(entity this, float ratingscale continue; // Ignore owned controlpoints - if(!(cp2.isgenneighbor[this.team] || cp2.iscpneighbor[this.team])) + if(!((cp2.aregensneighbor & BIT(this.team)) || (cp2.arecpsneighbor & BIT(this.team)))) continue; // Count team mates interested in this control point @@ -1584,7 +1640,7 @@ bool ons_Teleport(entity player, entity tele_target, float range, bool tele_effe loc += tele_target.origin + '0 0 128' * iteration_scale; - tracebox(loc, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), loc, MOVE_NORMAL, player); + tracebox(loc, STAT(PL_MIN, player), STAT(PL_MAX, player), loc, MOVE_NORMAL, player); if(trace_fraction == 1.0 && !trace_startsolid) { traceline(tele_target.origin, loc, MOVE_NOMONSTERS, tele_target); // double check to make sure we're not spawning outside the NULL @@ -1621,6 +1677,7 @@ MUTATOR_HOOKFUNCTION(ons, reset_map_global) STAT(ROUNDLOST, it) = false; it.ons_deathloc = '0 0 0'; PutClientInServer(it); + it.clientcamera = it; }); return false; } @@ -1702,7 +1759,7 @@ MUTATOR_HOOKFUNCTION(ons, PlayerSpawn) iteration_scale -= i / 10; loc = closest_target.origin + '0 0 96' * iteration_scale; loc += ('0 1 0' * random()) * 128 * iteration_scale; - tracebox(loc, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), loc, MOVE_NORMAL, player); + tracebox(loc, STAT(PL_MIN, player), STAT(PL_MAX, player), loc, MOVE_NORMAL, player); if(trace_fraction == 1.0 && !trace_startsolid) { traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the NULL @@ -1753,7 +1810,7 @@ MUTATOR_HOOKFUNCTION(ons, PlayerSpawn) iteration_scale -= i / 10; loc = closest_target.origin + '0 0 128' * iteration_scale; loc += ('0 1 0' * random()) * 256 * iteration_scale; - tracebox(loc, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), loc, MOVE_NORMAL, player); + tracebox(loc, STAT(PL_MIN, player), STAT(PL_MAX, player), loc, MOVE_NORMAL, player); if(trace_fraction == 1.0 && !trace_startsolid) { traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the NULL @@ -1966,7 +2023,7 @@ MUTATOR_HOOKFUNCTION(ons, SV_ParseClientCommand) MUTATOR_HOOKFUNCTION(ons, PlayerUseKey) { - if(MUTATOR_RETURNVALUE || gameover) { return false; } + if(MUTATOR_RETURNVALUE || game_stopped) return false; entity player = M_ARGV(0, entity); @@ -2137,5 +2194,7 @@ void ons_Initialize() g_onslaught = true; ons_captureshield_force = autocvar_g_onslaught_shield_force; + cam = new(objective_camera); + InitializeEntity(NULL, ons_DelayedInit, INITPRIO_GAMETYPE); }