void Tracker::CheckPlayerForTracker(Player * plr, bool online) { if( !IsValidPlayer(plr) || !IsBeingTracked(plr) ) // No tracker found on user! return; char text[1024]; TrackedPlr * tracker = GetTrackerByIP(plr->GetSession()->GetSocket()->GetIP()); if ( !tracker ) return; // No tracker found on user! sprintf(text, "%sTracker:|r %s has %s on character %s", MSG_COLOR_CYAN, tracker->Name.c_str(), (online?"come online":"gone offline"), plr->GetName()); uint32 textLen = (uint32)strlen((char*)text) + 1; WorldPacket data(textLen + 40); data.Initialize(SMSG_MESSAGECHAT); data << uint8(CHAT_MSG_SYSTEM); data << uint32(LANG_UNIVERSAL); data << (uint64)0; data << (uint32)0; data << (uint64)0; data << textLen; data << text; data << uint8(0); sWorld.SendAdministratorMessage(&data); }
int GetTeam (edict_t *ent) { // SyPB Pro P.1 // new get team off set, return player true team int client = ENTINDEX (ent) - 1, player_team; // SyPB Pro P.5 if (!IsValidPlayer (ent)) { player_team = 0; edict_t *entity = null; ITERATE_ARRAY (g_entityName, j) { while (!FNullEnt (entity = FIND_ENTITY_BY_CLASSNAME (entity, g_entityName[j]))) { if (ent == entity) { player_team = g_entityTeam[j]; break; } } } player_team--; if (GetGameMod () == 99 && g_DelayTimer > engine->GetTime ()) player_team = 2; return player_team; }
/* ======================== objective_area ======================== */ void objective_area_think (edict_t *self) { edict_t *ent = NULL; int count = 0; int newteam = 0; int delay; self->nextthink = level.time + FRAMETIME; if (self->delay) // if there's a counter running { } while ((ent = findradius(ent, self->s.origin, self->obj_area)) != NULL) { if (!ent->inuse) continue; if (!IsValidPlayer(ent)) continue; newteam = ent->client->resp.team_on->index; if (newteam != self->obj_owner) count++; //gi.dprintf(DEVELOPER_MSG_GAME, "Found %d players\n", count); } if (count >= self->obj_count) { team_list[self->obj_owner]->score -= self->obj_loss; self->obj_owner = team_list[newteam]->index; team_list[self->obj_owner]->score += self->obj_gain; if (team_list[self->obj_owner]->time_to_win) // If there already is a counter somwhere else { if (team_list[self->obj_owner]->time_to_win > (self->obj_time + level.time) ) // If the counter is longer, shorten it up to this one team_list[self->obj_owner]->time_to_win = (self->obj_time + level.time); } else // there is no counter team_list[self->obj_owner]->time_to_win = (self->obj_time + level.time); delay = (int)(team_list[self->obj_owner]->time_to_win - level.time); if ((delay/60) >= 1) safe_bprintf(PRINT_HIGH, "Team %s has %i minutes before they win the battle.\n", team_list[self->obj_owner]->teamname, (delay/60)); else safe_bprintf(PRINT_HIGH, "Team %s has %i seconds before they win the battle.\n", team_list[self->obj_owner]->teamname, delay); gi.sound(self, CHAN_NO_PHS_ADD, gi.soundindex(va("%s/objectives/area_cap.wav", team_list[self->obj_owner]->teamid)), 1, 0, 0); if (dedicated->value) safe_cprintf(NULL, PRINT_HIGH, "Objective %s taken by team %s!\n", self->obj_name, team_list[self->obj_owner]->teamname); centerprintall("Objective %s taken\n by team %s!\n", self->obj_name, team_list[self->obj_owner]->teamname); } }
bool Tracker::IsBeingTracked(Player *plr) { if( !IsValidPlayer(plr) ) // No tracker found on user! return false; TrackedPlr * tracker = GetTrackerByIP(plr->GetSession()->GetSocket()->GetIP()); return ( tracker != NULL ); // No tracker found on user! }
void DisplayMenuToClient (edict_t *ent, MenuText *menu) { if (!IsValidPlayer (ent)) return; int clientIndex = ENTINDEX (ent) - 1; if (menu != null) { String tempText = String (menu->menuText); tempText.Replace ("\v", "\n"); char *text = g_localizer->TranslateInput (tempText); tempText = String (text); // make menu looks best for (int i = 0; i <= 9; i++) tempText.Replace (FormatBuffer ("%d.", i), FormatBuffer ("\\r%d.\\w", i)); text = tempText; while (strlen (text) >= 64) { MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, g_netMsg->GetId (NETMSG_SHOWMENU), null, ent); WRITE_SHORT (menu->validSlots); WRITE_CHAR (-1); WRITE_BYTE (1); for (int i = 0; i <= 63; i++) WRITE_CHAR (text[i]); MESSAGE_END (); text += 64; } MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, g_netMsg->GetId (NETMSG_SHOWMENU), null, ent); WRITE_SHORT (menu->validSlots); WRITE_CHAR (-1); WRITE_BYTE (0); WRITE_STRING (text); MESSAGE_END(); g_clients[clientIndex].menu = menu; } else { MESSAGE_BEGIN (MSG_ONE_UNRELIABLE, g_netMsg->GetId (NETMSG_SHOWMENU), null, ent); WRITE_SHORT (0); WRITE_CHAR (0); WRITE_BYTE (0); WRITE_STRING (""); MESSAGE_END(); g_clients[clientIndex].menu = null; } CLIENT_COMMAND (ent, "speak \"player/geiger1\"\n"); // Stops others from hearing menu sounds.. }
int GetTeam (edict_t *ent) { // SyPB Pro P.1 // new get team off set, return player true team int client = ENTINDEX (ent) - 1, player_team; // SyPB Pro P.5 if (!IsValidPlayer (ent)) { player_team = 0; edict_t *entity = null; ITERATE_ARRAY (g_entityName, j) { while (!FNullEnt (entity = FIND_ENTITY_BY_CLASSNAME (entity, g_entityName[j]))) { if (ent == entity) { player_team = g_entityTeam[j]; break; } } } // SyPB Pro P.40 - AMXX API ITERATE_ARRAY(g_entityIdAPI, j) { if (ent == INDEXENT(g_entityIdAPI[j])) { player_team = g_entityTeamAPI[j]; break; } } player_team--; return player_team; }
bool Bot::LookupEnemy (void) { // this function tries to find the best suitable enemy for the bot m_visibility = 0; // SyPB Pro P.1 if (m_enemy != null && (GetTeam (GetEntity ()) == GetTeam (m_enemy) || Attack_Invisible(m_enemy))) { m_enemy = null; return false; } // SyPB Pro P.4 if (GetEnemyEntity ()) return true; // do not search for enemies while we're blinded, or shooting disabled by user if (m_blindTime > engine->GetTime () || sypb_noshots.GetBool ()) return false; // do not check for new enemy too fast if (!FNullEnt (m_enemy) && m_enemyUpdateTime > engine->GetTime () && !(m_states & STATE_SUSPECTENEMY)) { m_aimFlags |= AIM_ENEMY; return true; } edict_t *player, *newEnemy = null; float nearestDistance = m_viewDistance; int i, team = GetTeam (GetEntity ()); // setup potentially visible set for this bot Vector potentialVisibility = EyePosition (); if (pev->flags & FL_DUCKING) potentialVisibility = potentialVisibility + (VEC_HULL_MIN - VEC_DUCK_HULL_MIN); uint8_t *pvs = ENGINE_SET_PVS (reinterpret_cast <float *> (&potentialVisibility)); // clear suspected flag if (m_seeEnemyTime + 4.0f < engine->GetTime ()) m_states &= ~STATE_SUSPECTENEMY; if (!FNullEnt (m_enemy)) { player = m_enemy; // is player is alive if (IsAlive (player) && IsEnemyViewable (player)) newEnemy = player; } // the old enemy is no longer visible or if (FNullEnt (newEnemy)) { m_enemyUpdateTime = engine->GetTime () + 0.25f; // some shield stuff Array <edict_t *> enemies; // search the world for players... for (i = 0; i < engine->GetMaxClients (); i++) { if (!(g_clients[i].flags & CFLAG_USED) || !(g_clients[i].flags & CFLAG_ALIVE) || (g_clients[i].team == team) || (g_clients[i].ent == GetEntity ())) continue; player = g_clients[i].ent; // let the engine check if this player is potentially visible if (!ENGINE_CHECK_VISIBILITY (player, pvs)) continue; // skip glowed players, in free for all mode, we can't hit them if (player->v.renderfx == kRenderFxGlowShell && GetGameMod() == 1) continue; // do some blind by smoke grenade if (IsBehindSmokeClouds (player) && m_blindRecognizeTime < engine->GetTime ()) m_blindRecognizeTime = engine->GetTime () + engine->RandomFloat (2.0, 3.0f); if (player->v.button & (IN_ATTACK | IN_ATTACK2)) m_blindRecognizeTime = engine->GetTime () - 0.1f; // see if bot can see the player... if (m_blindRecognizeTime < engine->GetTime () && IsEnemyViewable (player)) { float distance = (player->v.origin - pev->origin).GetLength (); if (distance < nearestDistance) { enemies.Push (player); if (IsEnemyProtectedByShield (player)) continue; nearestDistance = distance; newEnemy = player; // aim VIP first on AS maps... if ((g_mapType & MAP_AS) && *(INFOKEY_VALUE (GET_INFOKEYBUFFER (player), "model")) == 'v') break; } } } // if we got no enemies with no shield, and got enemies with target them if (enemies.GetElementNumber () != 0 && !IsValidPlayer (newEnemy)) newEnemy = enemies[0]; } if (IsValidPlayer (newEnemy)) { g_botsCanPause = true; m_aimFlags |= AIM_ENEMY; if (newEnemy == m_enemy) { // if enemy is still visible and in field of view, keep it keep track of when we last saw an enemy m_seeEnemyTime = engine->GetTime (); // zero out reaction time m_actualReactionTime = 0.0f; m_lastEnemy = newEnemy; m_lastEnemyOrigin = newEnemy->v.origin; m_GetNewEnemyTimer = engine->GetTime () + 0.8; return true; } else { if (m_seeEnemyTime + 3.0f < engine->GetTime () && (pev->weapons & (1 << WEAPON_C4) || HasHostage () || !FNullEnt (m_targetEntity))) RadioMessage (Radio_EnemySpotted); m_targetEntity = null; // stop following when we see an enemy... if (engine->RandomInt (0, 100) < m_skill) m_enemySurpriseTime = engine->GetTime () + (m_actualReactionTime / 3); else m_enemySurpriseTime = engine->GetTime () + m_actualReactionTime; // zero out reaction time m_actualReactionTime = 0.0f; m_enemy = newEnemy; m_lastEnemy = newEnemy; m_lastEnemyOrigin = newEnemy->v.origin; m_enemyReachableTimer = 0.0f; // keep track of when we last saw an enemy m_seeEnemyTime = engine->GetTime (); // now alarm all teammates who see this bot & don't have an actual enemy of the bots enemy should simulate human players seeing a teammate firing for (int j = 0; j < engine->GetMaxClients (); j++) { if (!(g_clients[j].flags & CFLAG_USED) || !(g_clients[j].flags & CFLAG_ALIVE) || g_clients[j].team != team || g_clients[j].ent == GetEntity ()) continue; Bot *friendBot = g_botManager->GetBot (g_clients[j].ent); if (friendBot != null) { if (friendBot->m_seeEnemyTime + 2.0f < engine->GetTime () || FNullEnt (friendBot->m_lastEnemy)) { if (IsVisible (pev->origin, ENT (friendBot->pev))) { friendBot->m_lastEnemy = newEnemy; friendBot->m_lastEnemyOrigin = m_lastEnemyOrigin; friendBot->m_seeEnemyTime = engine->GetTime (); } } } } m_GetNewEnemyTimer = engine->GetTime () + 1.6; return true; } } else if (!FNullEnt (m_enemy)) { newEnemy = m_enemy; m_lastEnemy = newEnemy; m_GetNewEnemyTimer = engine->GetTime () + 0.8; if (!IsAlive (newEnemy)) { m_enemy = null; // shoot at dying players if no new enemy to give some more human-like illusion if (m_seeEnemyTime + 0.1 > engine->GetTime ()) { if (!UsesSniper ()) { m_shootAtDeadTime = engine->GetTime () + 0.2f; m_actualReactionTime = 0.0f; m_states |= STATE_SUSPECTENEMY; return true; } return false; } else if (m_shootAtDeadTime > engine->GetTime ()) { m_actualReactionTime = 0.0f; m_states |= STATE_SUSPECTENEMY; return true; } return false; } // if no enemy visible check if last one shoot able through wall if (sypb_thruwalls.GetBool () && engine->RandomInt (1, 100) < g_skillTab[m_skill / 20].seenShootThruProb) { if (IsShootableThruObstacle (newEnemy->v.origin)) { m_seeEnemyTime = engine->GetTime () - 0.2f; m_states |= STATE_SUSPECTENEMY; m_aimFlags |= AIM_LASTENEMY; m_enemy = newEnemy; m_lastEnemy = newEnemy; m_lastEnemyOrigin = newEnemy->v.origin; return true; } } } // check if bots should reload... if ((m_aimFlags <= AIM_PREDICTENEMY && m_seeEnemyTime + 4.0f < engine->GetTime () && !(m_states & (STATE_SEEINGENEMY | STATE_HEARENEMY)) && FNullEnt (m_lastEnemy) && FNullEnt (m_enemy) && GetCurrentTask ()->taskID != TASK_DESTROYBREAKABLE && GetCurrentTask ()->taskID != TASK_PLANTBOMB && GetCurrentTask ()->taskID != TASK_DEFUSEBOMB) || g_roundEnded) { if (!m_reloadState) m_reloadState = RSTATE_PRIMARY; } // is the bot using a sniper rifle or a zoomable rifle? if ((UsesSniper () || UsesZoomableRifle ()) && m_zoomCheckTime + 1.0f < engine->GetTime ()) { if (pev->fov < 90) // let the bot zoom out pev->button |= IN_ATTACK2; else m_zoomCheckTime = 0.0f; } return false; }
void NetworkMsg::Execute (void *p) { if (m_message == NETMSG_UNDEFINED) return; // no message or not for bot, return // some needed variables static uint8_t r, g, b; static uint8_t enabled; static int damageArmor, damageTaken, damageBits; static int killerIndex, victimIndex, playerIndex; static int index, numPlayers; static int state, id, clip; static Vector damageOrigin; static WeaponProperty weaponProp; // now starts of netmessage execution switch (m_message) { case NETMSG_VGUI: // this message is sent when a VGUI menu is displayed. if (m_state == 0) { switch (PTR_TO_INT (p)) { case GMENU_TEAM: m_bot->m_startAction = CMENU_TEAM; break; case GMENU_TERRORIST: case GMENU_COUNTER: m_bot->m_startAction = CMENU_CLASS; break; } } break; case NETMSG_SHOWMENU: // this message is sent when a text menu is displayed. if (m_state < 3) // ignore first 3 fields of message break; if (strcmp (PTR_TO_STR (p), "#Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select_Spect") == 0) // team select menu? m_bot->m_startAction = CMENU_TEAM; else if (strcmp (PTR_TO_STR (p), "#Terrorist_Select") == 0) // T model select? m_bot->m_startAction = CMENU_CLASS; else if (strcmp (PTR_TO_STR (p), "#CT_Select") == 0) // CT model select menu? m_bot->m_startAction = CMENU_CLASS; break; case NETMSG_WLIST: // this message is sent when a client joins the game. All of the weapons are sent with the weapon ID and information about what ammo is used. switch (m_state) { case 0: strcpy (weaponProp.className, PTR_TO_STR (p)); break; case 1: weaponProp.ammo1 = PTR_TO_INT (p); // ammo index 1 break; case 2: weaponProp.ammo1Max = PTR_TO_INT (p); // max ammo 1 break; case 5: weaponProp.slotID = PTR_TO_INT (p); // slot for this weapon break; case 6: weaponProp.position = PTR_TO_INT (p); // position in slot break; case 7: weaponProp.id = PTR_TO_INT (p); // weapon ID break; case 8: weaponProp.flags = PTR_TO_INT (p); // flags for weapon (WTF???) g_weaponDefs[weaponProp.id] = weaponProp; // store away this weapon with it's ammo information... break; } break; case NETMSG_CURWEAPON: // this message is sent when a weapon is selected (either by the bot chosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased switch (m_state) { case 0: state = PTR_TO_INT (p); // state of the current weapon (WTF???) break; case 1: id = PTR_TO_INT (p); // weapon ID of current weapon break; case 2: clip = PTR_TO_INT (p); // ammo currently in the clip for this weapon if (id <= 31) { if (state != 0) m_bot->m_currentWeapon = id; // ammo amount decreased ? must have fired a bullet... if (id == m_bot->m_currentWeapon && m_bot->m_ammoInClip[id] > clip) { // time fired with in burst firing time ? if (m_bot->m_timeLastFired + 1.0f > engine->GetTime ()) m_bot->m_burstShotsFired++; m_bot->m_timeLastFired = engine->GetTime (); // remember the last bullet time } m_bot->m_ammoInClip[id] = clip; } break; } break; case NETMSG_AMMOX: // this message is sent whenever ammo amounts are adjusted (up or down). NOTE: Logging reveals that CS uses it very unreliable! switch (m_state) { case 0: index = PTR_TO_INT (p); // ammo index (for type of ammo) break; case 1: m_bot->m_ammo[index] = PTR_TO_INT (p); // store it away break; } break; case NETMSG_AMMOPICK: // this message is sent when the bot picks up some ammo (AmmoX messages are also sent so this message is probably // not really necessary except it allows the HUD to draw pictures of ammo that have been picked up. The bots // don't really need pictures since they don't have any eyes anyway. switch (m_state) { case 0: index = PTR_TO_INT (p); break; case 1: m_bot->m_ammo[index] = PTR_TO_INT (p); break; } break; case NETMSG_DAMAGE: // this message gets sent when the bots are getting damaged. switch (m_state) { case 0: damageArmor = PTR_TO_INT (p); break; case 1: damageTaken = PTR_TO_INT (p); break; case 2: damageBits = PTR_TO_INT (p); if (damageArmor > 0 || damageTaken > 0) m_bot->TakeDamage (m_bot->pev->dmg_inflictor, damageTaken, damageArmor, damageBits); break; } break; case NETMSG_MONEY: // this message gets sent when the bots money amount changes if (m_state == 0) m_bot->m_moneyAmount = PTR_TO_INT (p); // amount of money break; case NETMSG_STATUSICON: switch (m_state) { case 0: enabled = PTR_TO_BYTE(p); break; case 1: // SyPB Pro P.34 - Base Change if (GetGameMod() == 0) { if (strcmp(PTR_TO_STR(p), "defuser") == 0) m_bot->m_hasDefuser = (enabled != 0); else if (strcmp(PTR_TO_STR(p), "buyzone") == 0) { m_bot->m_inBuyZone = (enabled != 0); m_bot->EquipInBuyzone(0); } else if (strcmp(PTR_TO_STR(p), "vipsafety") == 0) m_bot->m_inVIPZone = (enabled != 0); else if (strcmp(PTR_TO_STR(p), "c4") == 0) m_bot->m_inBombZone = (enabled == 2); } else { m_bot->m_hasDefuser = false; m_bot->m_inVIPZone = false; m_bot->m_inBombZone = false; if (strcmp(PTR_TO_STR(p), "buyzone") == 0) { m_bot->m_inBuyZone = (enabled != 0); m_bot->EquipInBuyzone(0); } } break; } break; case NETMSG_DEATH: // this message sends on death switch (m_state) { case 0: killerIndex = PTR_TO_INT (p); break; case 1: victimIndex = PTR_TO_INT (p); break; case 2: // SyPB Pro P.40 - Death Msg improve if (killerIndex != victimIndex) { edict_t *killer = INDEXENT(killerIndex); edict_t *victim = INDEXENT(victimIndex); if (FNullEnt(killer) || FNullEnt(victim) || !IsValidPlayer(victim)) break; Bot *victimer = g_botManager->GetBot(victim); if (victimer != null) { victimer->GetCurrentTask()->data = -1; victimer->DeleteSearchNodes(); } if (!IsZombieEntity(victim) && IsAlive(victim)) break; for (int i = 0; i < engine->GetMaxClients(); i++) { Bot *bot = g_botManager->GetBot(i); if (bot == null || !IsAlive(bot->GetEntity())) continue; if (IsZombieEntity(bot->GetEntity())) continue; if (GetGameMod() == 0 && killer != bot->GetEntity() && bot->EntityIsVisible(GetEntityOrigin(victim)) && GetTeam(killer) == GetTeam(bot->GetEntity()) && GetTeam(killer) != GetTeam(victim)) { if (killer == g_hostEntity) bot->HandleChatterMessage("#Bot_NiceShotCommander"); else bot->HandleChatterMessage("#Bot_NiceShotPall"); break; } if (GetTeam(bot->GetEntity()) == GetTeam(victim) && IsVisible(GetEntityOrigin(killer), bot->GetEntity()) && FNullEnt(bot->m_enemy) && GetTeam(killer) != GetTeam(victim)) { // SyPB Pro P.30 - AMXX API if (bot->m_blockCheckEnemyTime > engine->GetTime()) continue; bot->m_actualReactionTime = 0.0f; bot->m_seeEnemyTime = engine->GetTime(); bot->m_enemy = killer; bot->SetLastEnemy(killer); } } Bot *bot = g_botManager->GetBot(killer); if (bot != null) bot->m_lastVictim = victim; else if (GetGameMod () == 0) { if (victimer != null) { if (GetTeam(killer) == GetTeam(victim)) victimer->m_voteKickIndex = killerIndex; victimer->m_notKilled = false; } } } break; } break; case NETMSG_SCREENFADE: // this message gets sent when the Screen fades (Flashbang) switch (m_state) { case 3: r = PTR_TO_BYTE (p); break; case 4: g = PTR_TO_BYTE (p); break; case 5: b = PTR_TO_BYTE (p); break; case 6: m_bot->TakeBlinded (Vector (r, g, b), PTR_TO_BYTE (p)); break; } break; case NETMSG_HLTV: // round restart in steam cs switch (m_state) { case 0: numPlayers = PTR_TO_INT(p); break; case 1: if (numPlayers == 0 && PTR_TO_INT(p) == 0) RoundInit(); break; } break; case NETMSG_RESETHUD: #if 0 if (m_bot != null) m_bot->NewRound (); #endif break; case NETMSG_TEXTMSG: if (m_state == 1) { if (FStrEq (PTR_TO_STR (p), "#CTs_Win") || FStrEq (PTR_TO_STR (p), "#Bomb_Defused") || FStrEq (PTR_TO_STR (p), "#Terrorists_Win") || FStrEq (PTR_TO_STR (p), "#Round_Draw") || FStrEq (PTR_TO_STR (p), "#All_Hostages_Rescued") || FStrEq (PTR_TO_STR (p), "#Target_Saved") || FStrEq (PTR_TO_STR (p), "#Hostages_Not_Rescued") || FStrEq (PTR_TO_STR (p), "#Terrorists_Not_Escaped") || FStrEq (PTR_TO_STR (p), "#VIP_Not_Escaped") || FStrEq (PTR_TO_STR (p), "#Escaping_Terrorists_Neutralized") || FStrEq (PTR_TO_STR (p), "#VIP_Assassinated") || FStrEq (PTR_TO_STR (p), "#VIP_Escaped") || FStrEq (PTR_TO_STR (p), "#Terrorists_Escaped") || FStrEq (PTR_TO_STR (p), "#CTs_PreventEscape") || FStrEq (PTR_TO_STR (p), "#Target_Bombed") || FStrEq (PTR_TO_STR (p), "#Game_Commencing") || FStrEq (PTR_TO_STR (p), "#Game_will_restart_in")) { g_roundEnded = true; if (FStrEq (PTR_TO_STR (p), "#Game_Commencing")) g_isCommencing = true; // SyPB Pro P.29 - msg setting if (GetGameMod() == 0) { if (FStrEq(PTR_TO_STR(p), "#CTs_Win")) g_botManager->SetLastWinner(TEAM_COUNTER); // update last winner for economics if (FStrEq(PTR_TO_STR(p), "#Terrorists_Win")) g_botManager->SetLastWinner(TEAM_TERRORIST); // update last winner for economics } g_waypoint->SetBombPosition (true); } else if (!g_bombPlanted && FStrEq (PTR_TO_STR (p), "#Bomb_Planted")) { g_bombPlanted = true; g_bombSayString = true; g_timeBombPlanted = engine->GetTime (); for (int i = 0; i < engine->GetMaxClients (); i++) { Bot *bot = g_botManager->GetBot (i); if (bot != null && IsAlive (bot->GetEntity ())) { bot->DeleteSearchNodes (); bot->ResetTasks (); if (engine->RandomInt (0, 100) < 85 && GetTeam (bot->GetEntity ()) == TEAM_COUNTER) bot->ChatterMessage (Chatter_WhereIsTheBomb); } } g_waypoint->SetBombPosition (); } else if (m_bot != null && FStrEq (PTR_TO_STR (p), "#Switch_To_BurstFire")) m_bot->m_weaponBurstMode = BURST_ENABLED; else if (m_bot != null && FStrEq (PTR_TO_STR (p), "#Switch_To_SemiAuto")) m_bot->m_weaponBurstMode = BURST_DISABLED; } break; case NETMSG_SCOREINFO: switch (m_state) { case 0: playerIndex = PTR_TO_INT(p); break; case 4: // SyPB Pro P.29 - msg set team if (playerIndex >= 0 && playerIndex <= engine->GetMaxClients()) GetTeam(ENT(playerIndex)); } break; case NETMSG_BARTIME: if (m_state == 0) { // SyPB Pro P.34 - Base Change if (GetGameMod() == 0) { if (PTR_TO_INT(p) > 0) m_bot->m_hasProgressBar = true; // the progress bar on a hud else if (PTR_TO_INT(p) == 0) m_bot->m_hasProgressBar = false; // no progress bar or disappeared } else m_bot->m_hasProgressBar = false; } break; default: AddLogEntry (true, LOG_FATAL, "Network message handler error. Call to unrecognized message id (%d).\n", m_message); } m_state++; // and finally update network message state }
void NPC::DebugModeMsg(void) { if (FNullEnt(g_hostEntity)) return; if (IsValidPlayer(INDEXENT(g_hostEntity->v.iuser2))) return; char gamemodName[12]; switch (GetGameMode()) { case 0: sprintf(gamemodName, "Normal"); break; case 1: sprintf(gamemodName, "Dm"); break; case 2: sprintf(gamemodName, "ZP"); break; case 3: sprintf(gamemodName, "VS Npc"); break; case 4: sprintf(gamemodName, "ZH"); break; } char taskName[33]; if (m_task & TASK_ENEMY) sprintf(taskName, "TASK_ENEMY"); else if (m_task & TASK_MOVETOTARGET) sprintf(taskName, "TASK_MOVETOTARGET"); else sprintf(taskName, "TASK_NORMAL"); char enemyName[33]; if (!FNullEnt(m_enemy)) strcat(enemyName, GetEntityName(m_enemy)); else if (!FNullEnt(m_moveTargetEntity)) strcat(enemyName, GetEntityName(m_moveTargetEntity)); else strcpy(enemyName, " (null)"); // P.45 - Debugs Mode improve char npcTeam[33]; if (m_npcTeam == 0) sprintf(npcTeam, "TR"); else if (m_npcTeam == 1) sprintf(npcTeam, "CT"); else sprintf(npcTeam, "Team-%d", m_npcTeam); int navIndex[2] = { -1, -1 }; PathNode *navid = &m_navNode[0]; while (navid != null) { if (navIndex[0] == -1) navIndex[0] = navid->index; else if (navIndex[1] == -1) { navIndex[1] = navid->index; break; } navid = navid->next; } char outputBuffer[512]; sprintf(outputBuffer, "\n\n\n\n\n\n\n Game Mode: %s" "\n [%s] \n Task: %s\n" "Enemy: %s Team: %s\n" "CWI: %d GI: %d\n" "Nav: %d Next Nav :%d\n" "Move Speed: %.2f Speed: %.2f\n" "Attack Distance : %.2f" "", gamemodName, GetEntityName(GetEntity()), taskName, enemyName, npcTeam, m_currentWaypointIndex, m_goalWaypoint, navIndex[0], navIndex[1], m_moveSpeed, GetDistance2D(pev->velocity), m_attackDistance); MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, null, g_hostEntity); WRITE_BYTE(TE_TEXTMESSAGE); WRITE_BYTE(1); WRITE_SHORT(FixedSigned16(-1, 1 << 13)); WRITE_SHORT(FixedSigned16(0, 1 << 13)); WRITE_BYTE(0); WRITE_BYTE(255); WRITE_BYTE(100); WRITE_BYTE(255); WRITE_BYTE(0); WRITE_BYTE(255); WRITE_BYTE(255); WRITE_BYTE(255); WRITE_BYTE(0); WRITE_SHORT(FixedUnsigned16(0, 1 << 8)); WRITE_SHORT(FixedUnsigned16(0, 1 << 8)); WRITE_SHORT(FixedUnsigned16(1.0, 1 << 8)); WRITE_STRING(const_cast <const char *> (&outputBuffer[0])); MESSAGE_END(); if (!FNullEnt (m_enemy)) DrawLine(g_hostEntity, pev->origin, GetEntityOrigin (m_enemy), Color(255, 0, 0, 200), 10, 0, 5, 1, LINE_SIMPLE); if (!FNullEnt (m_moveTargetEntity)) DrawLine(g_hostEntity, pev->origin, GetEntityOrigin (m_moveTargetEntity), Color(0, 255, 0, 200), 10, 0, 5, 1, LINE_SIMPLE); PathNode *node = &m_navNode[0]; Vector src = nullvec; while (node != null) { int wpIndex = node->index; src = g_waypoint->g_waypointPointOrigin[node->index]; node = node->next; if (node != null) { bool jumpPoint = false; for (int j = 0; j < Const_MaxPathIndex; j++) { if (g_waypoint->g_wpConnectionIndex[wpIndex][j] != node->index) continue; if (g_waypoint->g_wpConnectionFlags[wpIndex][j] & PATHFLAG_JUMP) { jumpPoint = true; break; } } if (!jumpPoint) DrawLine(g_hostEntity, src, g_waypoint->g_waypointPointOrigin[node->index], Color(255, 100, 55, 20), 15, 0, 8, 1, LINE_SIMPLE); else DrawLine(g_hostEntity, src, g_waypoint->g_waypointPointOrigin[node->index], Color(255, 0, 0, 20), 15, 0, 8, 1, LINE_SIMPLE); } else DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(255, 255, 255, 100), 15, 0, 8, 1, LINE_SIMPLE); } if (g_waypoint->GetEntityWpIndex(GetEntity()) != -1) { src = g_waypoint->g_waypointPointOrigin[g_waypoint->GetEntityWpIndex(GetEntity())]; DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(255, 0, 0, 100), 15, 0, 8, 1, LINE_SIMPLE); } if (m_currentWaypointIndex != -1) { src = g_waypoint->g_waypointPointOrigin[m_currentWaypointIndex]; DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(0, 255, 0, 100), 15, 0, 8, 1, LINE_SIMPLE); } if (m_waypointOrigin != nullvec) { src = m_waypointOrigin; DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(255, 0, 255, 100), 15, 0, 8, 1, LINE_SIMPLE); } if (m_goalWaypoint != -1) { src = g_waypoint->g_waypointPointOrigin[m_goalWaypoint]; DrawLine(g_hostEntity, src, src + Vector(0, 0, 40), Color(0, 0, 255, 100), 15, 0, 8, 1, LINE_SIMPLE); } }
void Bot::FireWeapon(void) { // this function will return true if weapon was fired, false otherwise float distance = (m_lookAt - EyePosition()).GetLength(); // how far away is the enemy? // if using grenade stop this if (m_isUsingGrenade) { m_shootTime = engine->GetTime() + 0.1f; return; } // or if friend in line of fire, stop this too but do not update shoot time if (!FNullEnt(m_enemy) && IsFriendInLineOfFire(distance)) return; FireDelay *delay = &g_fireDelay[0]; WeaponSelect *selectTab = &g_weaponSelect[0]; edict_t *enemy = m_enemy; int selectId = WEAPON_KNIFE, selectIndex = 0, chosenWeaponIndex = 0; int weapons = pev->weapons; // if jason mode use knife only if (sypb_knifemode.GetBool()) goto WeaponSelectEnd; /* // use knife if near and good skill (l33t dude!) if (m_skill > 80 && !FNullEnt(enemy) && distance < 80.0f && pev->health > 80 && pev->health >= enemy->v.health && !IsGroupOfEnemies(pev->origin) && !::IsInViewCone(pev->origin, enemy)) goto WeaponSelectEnd; */ // SyPB Pro P.36 - Attack Ai if (!FNullEnt(enemy) && IsValidPlayer (enemy)) { if (GetGameMod() == 0 && m_skill > 80 && distance < 70.0f && enemy->v.health <= 30 && pev->health >= enemy->v.health && !IsGroupOfEnemies(pev->origin) && !::IsInViewCone(pev->origin, enemy)) goto WeaponSelectEnd; else if (GetGameMod() == 1 && m_skill > 90 && distance < 50.0f && enemy->v.health <= 20 && !::IsInViewCone(pev->origin, enemy)) goto WeaponSelectEnd; else if (GetGameMod () == 2 && IsZombieBot (GetEntity ())) goto WeaponSelectEnd; } // loop through all the weapons until terminator is found... while (selectTab[selectIndex].id) { // is the bot carrying this weapon? if (weapons & (1 << selectTab[selectIndex].id)) { // is enough ammo available to fire AND check is better to use pistol in our current situation... if ((m_ammoInClip[selectTab[selectIndex].id] > 0) && !IsWeaponBadInDistance(selectIndex, distance)) chosenWeaponIndex = selectIndex; } selectIndex++; } selectId = selectTab[chosenWeaponIndex].id; // if no available weapon... if (chosenWeaponIndex == 0) { selectIndex = 0; // loop through all the weapons until terminator is found... while (selectTab[selectIndex].id) { int id = selectTab[selectIndex].id; // is the bot carrying this weapon? if (weapons & (1 << id)) { if (g_weaponDefs[id].ammo1 != -1 && m_ammo[g_weaponDefs[id].ammo1] >= selectTab[selectIndex].minPrimaryAmmo) { // available ammo found, reload weapon if (m_reloadState == RSTATE_NONE || m_reloadCheckTime > engine->GetTime() || GetCurrentTask()->taskID != TASK_ESCAPEFROMBOMB) { m_isReloading = true; m_reloadState = RSTATE_PRIMARY; m_reloadCheckTime = engine->GetTime(); m_fearLevel = 1.0f; // SyPB Pro P.7 RadioMessage(Radio_NeedBackup); } return; } } selectIndex++; } selectId = WEAPON_KNIFE; // no available ammo, use knife! } WeaponSelectEnd: // we want to fire weapon, don't reload now if (!m_isReloading) { m_reloadState = RSTATE_NONE; m_reloadCheckTime = engine->GetTime() + 3.0f; } // SyPB Pro P.29 - Zombie Mode if (GetGameMod() == 2 && !IsZombieBot(GetEntity()) && selectId == WEAPON_KNIFE) { m_reloadState = RSTATE_PRIMARY; m_reloadCheckTime = engine->GetTime() + 0.1f; return; } // SyPB Pro P.34 - Sniper Attack Ai if (m_currentWeapon != WEAPON_AWP) { if (m_currentWeapon != selectId) { SelectWeaponByName(g_weaponDefs[selectId].className); // reset burst fire variables m_firePause = 0.0f; m_timeLastFired = 0.0f; m_burstShotsFired = 0; return; } if (delay[chosenWeaponIndex].weaponIndex != selectId) return; } else { if (delay[chosenWeaponIndex].weaponIndex != selectId) { if (m_currentWeapon != selectId) { SelectWeaponByName(g_weaponDefs[selectId].className); // reset burst fire variables m_firePause = 0.0f; m_timeLastFired = 0.0f; m_burstShotsFired = 0; } return; } } if (selectTab[chosenWeaponIndex].id != selectId) { chosenWeaponIndex = 0; // loop through all the weapons until terminator is found... while (selectTab[chosenWeaponIndex].id) { if (selectTab[chosenWeaponIndex].id == selectId) break; chosenWeaponIndex++; } } /* // select this weapon if it isn't already selected if (m_currentWeapon != selectId) { SelectWeaponByName (g_weaponDefs[selectId].className); // reset burst fire variables m_firePause = 0.0f; m_timeLastFired = 0.0f; m_burstShotsFired = 0; return; } if (delay[chosenWeaponIndex].weaponIndex != selectId) return; if (selectTab[chosenWeaponIndex].id != selectId) { chosenWeaponIndex = 0; // loop through all the weapons until terminator is found... while (selectTab[chosenWeaponIndex].id) { if (selectTab[chosenWeaponIndex].id == selectId) break; chosenWeaponIndex++; } } */ // if we're have a glock or famas vary burst fire mode CheckBurstMode(distance); if (HasShield() && m_shieldCheckTime < engine->GetTime() && GetCurrentTask()->taskID != TASK_CAMP) // better shield gun usage { if ((distance > 550) && !IsShieldDrawn()) pev->button |= IN_ATTACK2; // draw the shield else if (IsShieldDrawn() || (!FNullEnt(m_enemy) && (m_enemy->v.button & IN_RELOAD))) pev->button |= IN_ATTACK2; // draw out the shield m_shieldCheckTime = engine->GetTime() + 1.0f; } if (UsesSniper() && m_zoomCheckTime < engine->GetTime()) // is the bot holding a sniper rifle? { if (distance > 1500 && pev->fov >= 40) // should the bot switch to the long-range zoom? pev->button |= IN_ATTACK2; else if (distance > 150 && pev->fov >= 90) // else should the bot switch to the close-range zoom ? pev->button |= IN_ATTACK2; else if (distance <= 150 && pev->fov < 90) // else should the bot restore the normal view ? pev->button |= IN_ATTACK2; m_zoomCheckTime = engine->GetTime(); if (!FNullEnt(m_enemy) && (pev->velocity.x != 0 || pev->velocity.y != 0 || pev->velocity.z != 0) && (pev->basevelocity.x != 0 || pev->basevelocity.y != 0 || pev->basevelocity.z != 0)) { m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; m_navTimeset = engine->GetTime(); } } else if (UsesZoomableRifle() && m_zoomCheckTime < engine->GetTime() && m_skill < 90) // else is the bot holding a zoomable rifle? { if (distance > 800 && pev->fov >= 90) // should the bot switch to zoomed mode? pev->button |= IN_ATTACK2; else if (distance <= 800 && pev->fov < 90) // else should the bot restore the normal view? pev->button |= IN_ATTACK2; m_zoomCheckTime = engine->GetTime(); } const float baseDelay = delay[chosenWeaponIndex].primaryBaseDelay; const float minDelay = delay[chosenWeaponIndex].primaryMinDelay[abs((m_skill / 20) - 5)]; const float maxDelay = delay[chosenWeaponIndex].primaryMaxDelay[abs((m_skill / 20) - 5)]; // need to care for burst fire? if (distance < 256.0f || m_blindTime > engine->GetTime()) { if (selectId == WEAPON_KNIFE) KnifeAttack(m_enemy); else { if (selectTab[chosenWeaponIndex].primaryFireHold) // if automatic weapon, just press attack pev->button |= IN_ATTACK; else // if not, toggle buttons { if ((pev->oldbuttons & IN_ATTACK) == 0) pev->button |= IN_ATTACK; } } if (pev->button & IN_ATTACK) m_shootTime = engine->GetTime(); } else { if (DoFirePause(distance, &delay[chosenWeaponIndex])) return; // don't attack with knife over long distance if (selectId == WEAPON_KNIFE) return; // SyPB Pro P.34 - Sniper Skill Ai if (UsesSniper()) { m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; m_checkTerrain = false; m_navTimeset = engine->GetTime(); pev->button &= ~(IN_JUMP | IN_MOVELEFT | IN_MOVERIGHT | IN_FORWARD | IN_BACK); if (pev->velocity.GetLength() != 0.0f)// || pev->basevelocity.GetLength() != 0.0f) { m_shootTime = engine->GetTime() + 0.1f; return; } } /* // SyPB Pro P.26 - Sniper Skill if (UsesSniper()) { m_moveSpeed = 0.0f; m_strafeSpeed = 0.0f; m_checkTerrain = false; // SyPB Pro P.32 - Sniper Skill pev->button &= ~IN_JUMP; m_isStuck = false; m_navTimeset = engine->GetTime(); if (pev->velocity.GetLength() != 0.0f || pev->basevelocity.GetLength() != 0.0f) // SyPB Pro P.30 - Sniper Skill //if (pev->velocity.GetLength() != 0.0f && pev->basevelocity.GetLength () != 0.0f) { m_shootTime = engine->GetTime() + 0.1f; return; } } */ if (selectTab[chosenWeaponIndex].primaryFireHold) { m_shootTime = engine->GetTime(); m_zoomCheckTime = engine->GetTime(); pev->button |= IN_ATTACK; // use primary attack } else { pev->button |= IN_ATTACK; // use primary attack m_shootTime = engine->GetTime() + baseDelay + engine->RandomFloat(minDelay, maxDelay); m_zoomCheckTime = engine->GetTime(); } } // SyPB Pro P.34 - Sniper Attack Ai if (m_currentWeapon == WEAPON_AWP) { if (m_currentWeapon != selectId) { SelectWeaponByName(g_weaponDefs[selectId].className); // reset burst fire variables m_firePause = 0.0f; m_timeLastFired = 0.0f; m_burstShotsFired = 0; } } }
// SyPB Pro P.29 - Aim OS Change Vector Bot::GetAimPosition(void) { if (IsZombieBot(GetEntity())) return m_enemyOrigin = m_lastEnemyOrigin = GetEntityOrigin (m_enemy); // SyPB Pro P.30 - Fix Bugs Vector enemyOrigin = GetEntityOrigin(m_enemy); if (enemyOrigin == nullvec) return m_enemyOrigin = m_lastEnemyOrigin; Vector headOrigin = enemyOrigin; // SyPB Pro P.30 - NPC Fixed if (!IsValidPlayer(m_enemy)) return m_enemyOrigin = m_lastEnemyOrigin = GetEntityOrigin (m_enemy); int client = ENTINDEX(m_enemy) - 1; if (g_clients[client].headOrigin != nullvec) headOrigin = g_clients[client].headOrigin; if ((m_states & STATE_SUSPECTENEMY) && !(m_states & STATE_SEEINGENEMY)) { enemyOrigin.x += engine->RandomFloat(m_enemy->v.mins.x, m_enemy->v.maxs.x); enemyOrigin.y += engine->RandomFloat(m_enemy->v.mins.y, m_enemy->v.maxs.y); enemyOrigin.z += engine->RandomFloat(m_enemy->v.mins.z, m_enemy->v.maxs.z); } else { if ((m_visibility & (VISIBILITY_HEAD | VISIBILITY_BODY))) { if ((GetGameMod() == 0 || GetGameMod() == 1) && m_currentWeapon == WEAPON_AWP) enemyOrigin = GetEntityOrigin (m_enemy) + Vector(0, 0, 6); else if (m_skill >= 80 || GetGameMod() == 2) enemyOrigin = headOrigin; else enemyOrigin = GetEntityOrigin(m_enemy); } else if (m_visibility & VISIBILITY_HEAD) enemyOrigin = headOrigin; else if (m_visibility & VISIBILITY_BODY) enemyOrigin = GetEntityOrigin(m_enemy) + Vector(0, 0, 6); else if (m_visibility & VISIBILITY_OTHER) enemyOrigin = m_enemyOrigin; else enemyOrigin = m_lastEnemyOrigin; if (m_skill < 60 && (GetGameMod () == 0 || GetGameMod () == 1)) { enemyOrigin.x += engine->RandomFloat(m_enemy->v.mins.x, m_enemy->v.maxs.x); enemyOrigin.y += engine->RandomFloat(m_enemy->v.mins.y, m_enemy->v.maxs.y); enemyOrigin.z += engine->RandomFloat(m_enemy->v.mins.z, m_enemy->v.maxs.z); if (m_skill < 50) { enemyOrigin.x += engine->RandomFloat(8.0, -8.0); enemyOrigin.y += engine->RandomFloat(8.0, -8.0); enemyOrigin.z += engine->RandomFloat(8.0, -8.0); } } m_lastEnemyOrigin = enemyOrigin; } m_enemyOrigin = enemyOrigin; return m_enemyOrigin; }
//faf void Spawn_Plane(edict_t *ent) { //faf vec3_t start; vec3_t end; vec3_t left,right,forward,back; vec3_t temp, longest, direction, plane_start; float speed; // int i,j; trace_t tr; edict_t *plane; if (IsValidPlayer(ent) && ent->client && ent->client->arty_entry) { VectorCopy(ent->client->arty_entry, start); } else return; VectorClear(plane_start);/* silence compiler */ VectorClear(longest); /* for(i=-1; i<=1 ;i++) //faf: goes through all direction n, ne, e, se etc. { for(j=-1; j<=1 ;j++) { if (i ==0 && j == 0) break; VectorSet (test, i, j, 0); VectorMA(start, 8192, test, end); tr = gi.trace(start, NULL, NULL, end, ent, MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA); VectorSubtract (tr.endpos, start, temp); // safe_bprintf (PRINT_HIGH, "%s %f\n", vtos(test), VectorLength(temp)); if (VectorLength(temp) > VectorLength(longest)) { VectorCopy (temp, longest); VectorCopy (test, direction); direction[0]= -1 * direction[0];//reverse it direction[1]= -1 * direction[1]; // VectorSet (direction, (-1 * test[0]), (-1 * test[1]), 0);//reversed VectorCopy (tr.endpos, plane_start); } } }*/ // safe_bprintf (PRINT_HIGH, "%s\n", vtos(direction)); VectorSet(left, 1, 0, 0); VectorSet(right, -1, 0, 0); VectorSet(forward, 0, 1, 0); VectorSet(back, 0, -1, 0); VectorMA(start, 8192, left, end); tr = gi.trace(start, NULL, NULL, end, ent, MASK_ALL);//MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA); VectorSubtract (tr.endpos, start, temp); if (VectorLength(temp) > VectorLength(longest) && VectorLength(temp)< 8000) { VectorCopy (temp, longest); VectorCopy (right, direction); VectorCopy (tr.endpos, plane_start); } VectorMA(start, 8192, right, end); tr = gi.trace(start, NULL, NULL, end, ent, MASK_ALL);//MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA); VectorSubtract (tr.endpos, start, temp); if (VectorLength(temp) > VectorLength(longest) && VectorLength(temp)< 8000) { VectorCopy (temp, longest); VectorCopy (tr.endpos, plane_start); VectorCopy (left, direction); } VectorMA(start, 8192, forward, end); tr = gi.trace(start, NULL, NULL, end, ent, MASK_ALL);//MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA); VectorSubtract (tr.endpos, start, temp); if (VectorLength(temp) > VectorLength(longest) && VectorLength(temp)< 8000) { VectorCopy (temp, longest); VectorCopy (tr.endpos, plane_start); VectorCopy (back, direction); } VectorMA(start, 8192, back, end); tr = gi.trace(start, NULL, NULL, end, ent, MASK_ALL);//MASK_SHOT|CONTENTS_SLIME|CONTENTS_LAVA); VectorSubtract (tr.endpos, start, temp); if (VectorLength(temp) > VectorLength(longest) && VectorLength(temp)< 8000) { VectorCopy (temp, longest); VectorCopy (tr.endpos, plane_start); VectorCopy (forward, direction); } // safe_bprintf (PRINT_HIGH, "%f .\n", VectorLength(longest)); // safe_bprintf (PRINT_HIGH, "%s .\n", vtos(direction)); plane = G_Spawn(); plane->movetype = MOVETYPE_PUSH; plane->solid = SOLID_TRIGGER; plane->s.modelindex = gi.modelindex ("models/ships/viper/tris.md2"); //faf: requires models plane->s.modelindex = gi.modelindex (va("models/ships/%splane/tris.md2", team_list[ent->client->resp.team_on->index]->teamid)); plane->owner = ent; VectorClear (plane->mins); VectorClear (plane->maxs); /* plane->solid = SOLID_BBOX; VectorSet (plane->mins, -60, -60, -60); VectorSet (plane->maxs, 30, 30, 30); plane->health = 1000; plane->takedamage = DAMAGE_YES; plane->die = plane_die; */ plane->classname = "plane"; plane->think = Plane_Think; plane->nextthink = level.time +.1; VectorCopy (direction, plane->movedir); vectoangles (direction, plane->s.angles); if (VectorLength(longest) > 4000) speed = 800; else if (VectorLength(longest) > 2000) speed = 600; else speed = 450; VectorScale (direction, speed, plane->velocity); // VectorScale (direction, 450, plane->velocity); // VectorScale (direction, 50, plane->velocity); plane->s.sound = gi.soundindex ("dinant/tank.wav"); VectorCopy (plane_start, plane->s.origin); // plane->s.origin[2] -= 1; plane->leave_limbo_time = level.time; plane->s.renderfx = RF_FULLBRIGHT; gi.linkentity (plane); }
void Plane_Think (edict_t *ent) { vec3_t length; float distance; edict_t *botwarn; if (!ent->owner || !ent->owner->client || ent->flyingnun) { G_FreeEdict(ent); return; } VectorSubtract(ent->s.origin, ent->owner->client->arty_entry, length); distance = VectorLength(length); if (distance < 1000) { if (ent->s.angles[2] == 0 && ent->avelocity[2] == 0) //not spinning yet { //warn bots to run! botwarn = G_Spawn(); botwarn->movetype = MOVETYPE_NONE; botwarn->solid = SOLID_TRIGGER; botwarn->think = G_FreeEdict; botwarn->nextthink = level.time + 4; VectorClear (botwarn->mins); VectorClear (botwarn->maxs); botwarn->classname = "botwarn"; botwarn->classnameb = BOTWARN; VectorCopy (ent->owner->client->arty_entry, botwarn->s.origin); //tilt plane if (random() < .5) { VectorSet (ent->avelocity, 0, 0, -10);//faf } else { VectorSet (ent->avelocity, 0, 0, 10);//faf } } } if (ent->s.angles[2] > 15) //don't tip too far { VectorSet (ent->avelocity, 0, 0, 0);//faf } if (ent->s.angles[2] < -15) { VectorSet (ent->avelocity, 0, 0, 0);//faf } // safe_bprintf (PRINT_HIGH, "%s \n", vtos(ent->s.angles)); if (distance < 200) { ent->think = Plane_Fire; ent->nextthink = level.time +.1; if (IsValidPlayer(ent)) gi.sound(ent->owner, CHAN_AUTO, gi.soundindex(va("%s/arty/hit%i.wav", ent->owner->client->resp.team_on->teamid, 1)), 1, ATTN_NORM, 0); } else ent->nextthink = level.time +.1; }
/* ================= Cmd_Arty_f CCH: new function to call in airstrikes ================= */ void Cmd_Arty_f (edict_t *ent) { /* vec3_t start; vec3_t forward; vec3_t end; vec3_t world_up; edict_t *airstrike;//faf trace_t tr;*/ //int randnum; vec3_t v; edict_t *check; int e; edict_t *t; vec3_t vdist; float tdist; int i; if (!ent->client) return; if (!IsValidPlayer(ent)) return; if (ent->deadflag) return; if (!ent->client->resp.team_on) return; for (i=0 ; i<game.maxentities ; i++) { vec3_t neworg; t = &g_edicts[i]; if (!t->inuse) continue; if (!t->classnameb) continue; if (t->classnameb != TNT) continue; VectorCopy (ent->s.origin, neworg); neworg[2]+= ent->viewheight; VectorSubtract (t->s.origin, neworg, vdist); tdist = VectorLength (vdist); if (tdist > 40) continue; if (infront (ent, t)) { t->think = G_FreeEdict; t->nextthink = level.time + 2; t->s.sound = 0; t->s.effects = 0; safe_centerprintf (ent, "You defused the TNT!\n"); } } Spawn_Chute_Special (ent); //faf: turret stuff if (!ent->client->turret && !ent->client->grenade) { if (CheckForTurret(ent)) { Use_Weapon (ent, FindItem("Fists")); CheckForTurret(ent); return; } } else { turret_off(ent); return; } if (ent->client && ent->client->pers.weapon && ent->client->pers.weapon->classnameb == WEAPON_ARISAKA) { if (ent->client->weaponstate == WEAPON_READY && ent->client->ps.gunframe < 99 && !ent->client->aim) { ent->client->ps.gunframe = 99; Weapon_Bayonet_Fire1 (ent); return; } return; } if (ent->client && ent->client->pers.weapon && ent->client->pers.weapon->classnameb == WEAPON_CARCANO) { if (ent->client->weaponstate == WEAPON_READY && ent->client->ps.gunframe < 104 && !ent->client->aim) { ent->client->ps.gunframe = 104; Weapon_Bayonet_Fire1 (ent); return; } return; } if (ent->client && ent->client->pers.weapon && ent->client->pers.weapon->classnameb == WEAPON_ENFIELD) { if (ent->client->weaponstate == WEAPON_READY && ent->client->ps.gunframe < 107 //&& )//!ent->client->aim) { ent->client->aim = false; ent->client->ps.gunframe = 107; Weapon_Bayonet_Fire1 (ent); return; } return; } if (ent->client && ent->client->pers.weapon && ent->client->pers.weapon->classnameb == WEAPON_SVT) { if (ent->client->weaponstate == WEAPON_READY && ent->client->ps.gunframe < 89 && !ent->client->aim) { ent->client->ps.gunframe = 89; Weapon_Bayonet_Fire1 (ent); return; } return; } if (ent->client->airstrike) { safe_cprintf(ent, PRINT_HIGH, "Airstrike cancelled sir!\n"); G_FreeEdict(ent->client->airstrike); ent->client->airstrike = NULL; return; } else if ((ent->client->pers.weapon && ent->client->pers.weapon->classnameb) && ent->client->pers.weapon->classnameb == WEAPON_BINOCULARS) { if (ent->client->aim) safe_cprintf(ent, PRINT_HIGH, "Press fire to call an airstrike!\n"); else safe_cprintf(ent, PRINT_HIGH, "Aim and then press fire to call an airstrike!\n"); } // if (ent->client->resp.mos != OFFICER) { // safe_cprintf(ent, PRINT_HIGH, "You're not an officer, soldier!\n"); // return; // } if (ent->deadflag || ent->client->limbo_mode ) { safe_cprintf(ent, PRINT_HIGH, "You are dead!\n"); return; } //faf: moving this up so you dont have to look through binocs to cancel arty // make sure artillary hasn't already been called check = g_edicts+1; for (e = 1; e < globals.num_edicts; e++, check++) { if (!check->inuse) continue; if (check->health < 1) continue; if (strcmp(check->classname, "misc_civilian")) continue; VectorSubtract (ent->s.origin, check->s.origin, v); if (VectorLength (v)< 100) { //gi.dprintf(DEVELOPER_MSG_GAME, "CIV FOUND\n"); if (check->master == ent) { check->master = NULL; //gi.dprintf(DEVELOPER_MSG_GAME, "STAY\n"); gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/trigger1.wav"), .5, ATTN_STATIC, 0); check->goalentity = NULL; check->movetarget = NULL; check->enemy = NULL; check->monsterinfo.currentmove = &civilian_move_stand; } else { if (check->master && check->obj_owner == ent->client->resp.team_on->index) return; // can't steal civilian from teammate gi.sound (ent, CHAN_AUTO, gi.soundindex("misc/trigger1.wav"), .5, ATTN_STATIC, 0); check->master = ent; //gi.dprintf(DEVELOPER_MSG_GAME, "FOLLOW\n"); if (check->obj_owner != ent->client->resp.team_on->index) { level.obj_team = ent->client->resp.team_on->index; check->obj_owner = ent->client->resp.team_on->index; check->wait =level.time; //if (!check->wait) check->wait =level.time; } } check->obj_owner = ent->client->resp.team_on->index; } } }
void timed_objective_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { int otherteam; //edict_t *entC = NULL; if (!IsValidPlayer(other)) return; // gi.dprintf(DEVELOPER_MSG_GAME, "touch %i:%i (%i)\n", level.framenum, self->obj_count, (level.framenum - self->obj_count)); if (self->obj_owner ==-1 || other->client->resp.team_on->index != self->obj_owner) { if ((level.framenum - self->obj_count) <= 15) // its been at least a frame since own team touched it return; self->wait =level.time; // if (self->obj_owner < MAX_TEAMS) // undefined teams // team_list[self->obj_owner]->score -= self->dmg; self->obj_owner = other->client->resp.team_on->index; // team_list[self->obj_owner]->score += self->health; otherteam = (self->obj_owner+1)%2; if ((!team_list[otherteam]->kills_and_points && team_list[otherteam]->score < team_list[otherteam]->need_points) || (team_list[otherteam]->kills_and_points && team_list[otherteam]->kills < team_list[otherteam]->need_kills)) gi.sound(self, CHAN_NO_PHS_ADD, gi.soundindex(va("%s/objectives/touch_cap.wav", team_list[self->obj_owner]->teamid)), 1, 0, 0); if (dedicated->value) safe_cprintf(NULL, PRINT_HIGH, "%s taken by %s [%s]\n", self->message, other->client->pers.netname, team_list[self->obj_owner]->teamname); centerprintall("%s taken by:\n\n%s\n%s", self->message, other->client->pers.netname, team_list[self->obj_owner]->teamname); self->obj_count = level.framenum; // reset the touch count /* if (self->obj_owner == 1 && self->style == 2)//hack so axis don't trigger flag on first cap self->style = 0; else { self->style = 0; G_UseTargets (self, other); //faf } */ if (self->obj_owner == 1 && self->style == 2) { edict_t *t; self->style = 0; //trigger spawn_toggle only t = NULL; while ((t = G_Find (t, FOFS(targetname), self->target))) { if (t->use) { if (!strcmp(t->classname,"spawn_toggle")) t->use (t,self, other); } } } else { self->style = 0; G_UseTargets (self, other); //faf } } else // own team touched it { //gi.dprintf(DEVELOPER_MSG_GAME, "%s deadflag: %i\n", other->client->pers.netname, other->deadflag); if (other->deadflag == DEAD_NO) self->obj_count = level.framenum; // update the last time team touched it } }
/* ======================== objective_touch ======================== */ void objective_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf) { int otherteam; //edict_t *entC = NULL; if (!IsValidPlayer(other)) return; //with this type, will only be recapped by obj_perm_owner when they respawn if (self->style%3 == 2 && self->obj_perm_owner && self->obj_perm_owner%2 == other->client->resp.team_on->index && other->client->respawn_time < level.time -.5) return; //gi.dprintf(DEVELOPER_MSG_GAME, "touch %i:%i (%i)\n", level.framenum, self->obj_count, (level.framenum - self->obj_count)); if (other->client->resp.team_on->index != self->obj_owner) { if (self->style%5 == 3)//hill fix { if ((level.framenum - self->obj_count) <= 100) //team recaps after 10 seconds even if other team still in area return; } else if ((level.framenum - self->obj_count) <= self->delay)//15) // its been at least a frame since own team touched it return; if (self->obj_perm_owner) { // if (team_list[self->obj_owner]) // team_list[self->obj_owner]->score -= self->dmg; self->obj_owner = other->client->resp.team_on->index; if (self->obj_perm_owner%2 != other->client->resp.team_on->index) if (team_list[self->obj_owner]) { team_list[self->obj_owner]->score += self->health; } } else { if (team_list[self->obj_owner]) team_list[self->obj_owner]->score -= self->dmg; self->obj_owner = other->client->resp.team_on->index; team_list[self->obj_owner]->score += self->health; } otherteam = (self->obj_owner); if (!team_list[otherteam]->need_points || (!team_list[otherteam]->kills_and_points && team_list[otherteam]->score < team_list[otherteam]->need_points) || (team_list[otherteam]->kills_and_points && team_list[otherteam]->kills < team_list[otherteam]->need_kills)) gi.sound(self, CHAN_NO_PHS_ADD, gi.soundindex(va("%s/objectives/touch_cap.wav", team_list[self->obj_owner]->teamid)), 1, 0, 0); if (dedicated->value) safe_cprintf(NULL, PRINT_HIGH, "%s taken by %s [%s]\n", self->message, other->client->pers.netname, team_list[self->obj_owner]->teamname); centerprintall("%s taken by:\n\n%s\n%s", self->message, other->client->pers.netname, team_list[self->obj_owner]->teamname); self->obj_count = level.framenum; // reset the touch count G_UseTargets (self, other); //faf if (self->delay == -1) self->touch = NULL; } else // own team touched it { //gi.dprintf(DEVELOPER_MSG_GAME, "%s deadflag: %i\n", other->client->pers.netname, other->deadflag); if (self->style%5==3)return; //HILL FIX if (other->deadflag == DEAD_NO) self->obj_count = level.framenum; // update the last time team touched it } }