void CGameContext::ConTimes(IConsole::IResult *pResult, void *pUserData) { if(!CheckClientID(pResult->m_ClientID)) return; CGameContext *pSelf = (CGameContext *)pUserData; #if defined(CONF_SQL) if(pSelf->m_apPlayers[pResult->m_ClientID] && g_Config.m_SvUseSQL) if(pSelf->m_apPlayers[pResult->m_ClientID]->m_LastSQLQuery + pSelf->Server()->TickSpeed() >= pSelf->Server()->Tick()) return; #endif if(g_Config.m_SvUseSQL) { CSqlScore *pScore = (CSqlScore *)pSelf->Score(); CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID]; if(!pPlayer) return; if(pResult->NumArguments() == 0) { pScore->ShowTimes(pPlayer->GetCID(),1); return; } else if(pResult->NumArguments() < 3) { if (pResult->NumArguments() == 1) { if(pResult->GetInteger(0) != 0) pScore->ShowTimes(pPlayer->GetCID(),pResult->GetInteger(0)); else pScore->ShowTimes(pPlayer->GetCID(), (str_comp(pResult->GetString(0), "me") == 0) ? pSelf->Server()->ClientName(pResult->m_ClientID) : pResult->GetString(0),1); return; } else if (pResult->GetInteger(1) != 0) { pScore->ShowTimes(pPlayer->GetCID(), (str_comp(pResult->GetString(0), "me") == 0) ? pSelf->Server()->ClientName(pResult->m_ClientID) : pResult->GetString(0),pResult->GetInteger(1)); return; } } pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "times", "/times needs 0, 1 or 2 parameter. 1. = name, 2. = start number"); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "times", "Example: /times, /times me, /times Hans, /times \"Papa Smurf\" 5"); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "times", "Bad: /times Papa Smurf 5 # Good: /times \"Papa Smurf\" 5 "); #if defined(CONF_SQL) if(pSelf->m_apPlayers[pResult->m_ClientID] && g_Config.m_SvUseSQL) pSelf->m_apPlayers[pResult->m_ClientID]->m_LastSQLQuery = pSelf->Server()->Tick(); #endif } }
void CGameControllerOpenFNG::HandleFreeze(int Killer, int Victim) { CCharacter *pVictim = CHAR(Victim); if (!pVictim) // for odd reasons, this can happen (confirmed by segfault). didn't yet track down why { D("no pVictim in HandleFreeze(%d, %d)", Killer, Victim); return; } if (CFG(BleedOnFreeze)) { pVictim->Bleed(1); GS->CreateSound(pVictim->m_Pos, SOUND_CTF_RETURN); } int FailTeam = pVictim->GetPlayer()->GetTeam() & 1; m_aTeamscore[1 - FailTeam] += CFG(FreezeTeamscore); if (CFG(FreezeTeamscore) && CFG(FreezeBroadcast)) //probably of no real use but for completeness... { char aBuf[64]; str_format(aBuf, sizeof aBuf, "%s froze (%+d)", GetTeamName(1-FailTeam), CFG(FreezeTeamscore)); m_Broadcast.Update(-1, aBuf, CFG(BroadcastTime) * TS); } CPlayer *pPlKiller = TPLAYER(Killer); CPlayer *pPlVictim = TPLAYER(Victim); if (!pPlKiller || !pVictim) return; //freezing counts as a hostile interaction m_aLastInteraction[pVictim->GetPlayer()->GetCID()] = pPlKiller->GetCID(); pPlKiller->m_Score += CFG(FreezeScore); pPlVictim->m_Score += CFG(FreezeScoreVic); SendFreezeKill(Killer, Victim, WEAPON_RIFLE); if (pPlKiller->GetCharacter()) { GS->CreateSound(pPlKiller->GetCharacter()->m_Pos, SOUND_HIT, (1<<pPlKiller->GetCID())); if (CFG(FreezeLoltext) && CFG(FreezeScore)) { char aBuf[64]; str_format(aBuf, sizeof aBuf, "%+d", CFG(FreezeScore)); GS->CreateLolText(pPlKiller->GetCharacter(), false, vec2(0.f, -50.f), vec2(0.f, 0.f), 50, aBuf); } } }
void CGameControllerOpenFNG::HandleSacr(int Killer, int Victim, int ShrineTeam) {//assertion: Killer >= 0, victim anyways CCharacter *pVictim = CHAR(Victim); if (!pVictim) //due to HandleFreeze, i suspect this COULD also possibly happen. { D("no pVictim in HandleSacr(%d, %d, %d)", Killer, Victim, ShrineTeam); return; } int FailTeam = pVictim->GetPlayer()->GetTeam(); bool Wrong = ShrineTeam != -1 && FailTeam == ShrineTeam; m_aTeamscore[1-FailTeam] += Wrong?CFG(WrongSacrTeamscore):(ShrineTeam == -1 ? CFG(SacrTeamscore) : CFG(RightSacrTeamscore)); if (!Wrong) { if (CFG(SacrSound) == 1) GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE); else if (CFG(SacrSound) == 2) GameServer()->CreateSound(pVictim->m_Pos, SOUND_CTF_CAPTURE); } if (((Wrong && CFG(WrongSacrTeamscore)) || (!Wrong && (ShrineTeam == -1 ? CFG(SacrTeamscore) : CFG(RightSacrTeamscore)))) && CFG(SacrBroadcast)) { char aBuf[64]; str_format(aBuf, sizeof aBuf, "%s sacrificed%s (%+d)", GetTeamName(1-FailTeam), Wrong?" in wrong shrine":(ShrineTeam == -1 ? "" : ", pleasing their gods"), Wrong?CFG(WrongSacrTeamscore):(ShrineTeam == -1 ? CFG(SacrTeamscore):CFG(RightSacrTeamscore))); m_Broadcast.Update(-1, aBuf, CFG(BroadcastTime) * TS); } CPlayer *pPlKiller = TPLAYER(Killer); if (!pPlKiller) return; pPlKiller->m_Score += Wrong?CFG(WrongSacrScore):(ShrineTeam == -1 ? CFG(SacrScore) : CFG(RightSacrScore)); SendKill(Killer, Victim, WEAPON_NINJA); if(!Wrong && pPlKiller->GetCharacter()) GameServer()->GetPlayerChar(Killer)->AddSpree(); if (Wrong && pPlKiller->GetCharacter() && CFG(PunishWrongSacr)) { pPlKiller->GetCharacter()->Freeze(CFG(PunishWrongSacr) * TS); GS->CreateSound(pPlKiller->GetCharacter()->m_Pos, SOUND_PLAYER_PAIN_LONG); GS->SendChatTarget(pPlKiller->GetCID(), "The gods are not pleased with this sacrifice!"); } if (!Wrong && pPlKiller->GetCharacter()) pPlKiller->GetCharacter()->SetEmote(EMOTE_HAPPY, TICK + TS * 2); if (pPlKiller->GetCharacter() && CFG(SacrLoltext) && ((!Wrong && CFG(SacrScore)) || (Wrong && CFG(WrongSacrScore)))) { char aBuf[64]; str_format(aBuf, sizeof aBuf, "%+d", Wrong?CFG(WrongSacrScore):(ShrineTeam == -1 ? CFG(SacrScore) : CFG(RightSacrScore))); GS->CreateLolText(pPlKiller->GetCharacter(), false, vec2(0.f, -50.f), vec2(0.f, 0.f), 50, aBuf); } }
void IGameController::DoTeamBalance() { if(!IsTeamplay() || !g_Config.m_SvTeambalanceTime || absolute(m_aTeamSize[TEAM_RED]-m_aTeamSize[TEAM_BLUE]) < NUM_TEAMS) return; GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", "Balancing teams"); float aTeamScore[NUM_TEAMS] = {0}; float aPlayerScore[MAX_CLIENTS] = {0.0f}; // gather stats for(int i = 0; i < MAX_CLIENTS; i++) { if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS) { aPlayerScore[i] = GameServer()->m_apPlayers[i]->m_Score*Server()->TickSpeed()*60.0f/ (Server()->Tick()-GameServer()->m_apPlayers[i]->m_ScoreStartTick); aTeamScore[GameServer()->m_apPlayers[i]->GetTeam()] += aPlayerScore[i]; } } int BiggerTeam = (m_aTeamSize[TEAM_RED] > m_aTeamSize[TEAM_BLUE]) ? TEAM_RED : TEAM_BLUE; int NumBalance = absolute(m_aTeamSize[TEAM_RED]-m_aTeamSize[TEAM_BLUE]) / NUM_TEAMS; // balance teams do { CPlayer *pPlayer = 0; float ScoreDiff = aTeamScore[BiggerTeam]; for(int i = 0; i < MAX_CLIENTS; i++) { if(!GameServer()->m_apPlayers[i] || !CanBeMovedOnBalance(i)) continue; // remember the player whom would cause lowest score-difference if(GameServer()->m_apPlayers[i]->GetTeam() == BiggerTeam && (!pPlayer || absolute((aTeamScore[BiggerTeam^1]+aPlayerScore[i]) - (aTeamScore[BiggerTeam]-aPlayerScore[i])) < ScoreDiff)) { pPlayer = GameServer()->m_apPlayers[i]; ScoreDiff = absolute((aTeamScore[BiggerTeam^1]+aPlayerScore[i]) - (aTeamScore[BiggerTeam]-aPlayerScore[i])); } } // move the player to the other team if(pPlayer) { int Temp = pPlayer->m_LastActionTick; DoTeamChange(pPlayer, BiggerTeam^1); pPlayer->m_LastActionTick = Temp; pPlayer->Respawn(); GameServer()->SendGameMsg(GAMEMSG_TEAM_BALANCE_VICTIM, pPlayer->GetTeam(), pPlayer->GetCID()); } } while(--NumBalance); m_UnbalancedTick = TBALANCE_OK; GameServer()->SendGameMsg(GAMEMSG_TEAM_BALANCE, -1); }
void CGameContext::ConRescue(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *) pUserData; if (!CheckClientID(pResult->m_ClientID)) return; CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID]; if (!pPlayer) return; CCharacter* pChr = pPlayer->GetCharacter(); if (!pChr) return; if (!g_Config.m_SvRescue) { pSelf->SendChatTarget(pPlayer->GetCID(), "Rescue is not enabled on this server"); return; } pChr->Rescue(); }
void CGameControllerCSBB::Tick() { IGameController::Tick(); if(GameServer()->m_World.m_ResetRequested || GameServer()->m_World.m_Paused) return; m_RoundTick++; // no actual players (bots kicked if human_players == 0) if (CountPlayers() < 1 || m_NewGame) { GameServer()->m_CanRespawn = true; if (m_Round != 0 || m_GameState != CSBB_NEWBASE) Restart(); m_RoundTick = 0; } else { if (CountPlayers() == 1) { Restart(); AutoBalance(); return; } AutoBalance(); if (m_GameState == CSBB_NEWBASE) { CaptureBase(); if (GameServer()->m_pArrow) { GameServer()->m_pArrow->m_Hide = false; GameServer()->m_pArrow->m_Target = m_apBombArea[m_Base]->m_Pos; } } if (m_GameState == CSBB_DEFENDING) { if (GameServer()->m_pArrow) { GameServer()->m_pArrow->m_Hide = false; GameServer()->m_pArrow->m_Target = m_apBombArea[m_Base]->m_Pos; } RoundWinLose(); } if (m_GameState == CSBB_ENDING) { if (m_RoundTick >= g_Config.m_SvPreroundTime*Server()->TickSpeed()) { if (m_aTeamscore[TEAM_RED] >= g_Config.m_SvNumRounds || m_aTeamscore[TEAM_BLUE] >= g_Config.m_SvNumRounds) { EndRound(); m_NewGame = true; return; } NewBase(); //AutoBalance(); if (GameServer()->m_pArrow) GameServer()->m_pArrow->m_Hide = true; } } } GameServer()->UpdateAI(); // warm welcome for (int c = 0; c < MAX_CLIENTS; c++) { CPlayer *pPlayer = GameServer()->m_apPlayers[c]; if(!pPlayer) continue; if (!pPlayer->m_Welcomed && !pPlayer->m_IsBot) { GameServer()->SendBroadcast("Welcome to Counter-Strike: Base Bombing", pPlayer->GetCID(), true); pPlayer->m_Welcomed = true; } } // the bomb (red flag) CBomb *B = m_pBomb; if (!B) return; /* // always update bomb position if(B->m_pCarryingCharacter) { B->m_Pos = B->m_pCarryingCharacter->m_Pos; } else { if (B->m_Status == BOMB_CARRYING || B->m_Status == BOMB_IDLE) { B->m_Vel.y += GameServer()->m_World.m_Core.m_Tuning.m_Gravity; GameServer()->Collision()->MoveBox(&B->m_Pos, &B->m_Vel, vec2(B->ms_PhysSize, B->ms_PhysSize), 0.5f); B->m_Status = BOMB_IDLE; } } */ if (m_Timeout || m_BombDefused || m_GameState != CSBB_DEFENDING) return; if (B->m_Status == BOMB_PLANTED) { B->m_Timer++; // bomb ticking sound int Time = Server()->TickSpeed(); if (Server()->TickSpeed() / 30 + GetTimeLeft()*8 < Time) Time = Server()->TickSpeed() / 20 + GetTimeLeft()*4; if (++m_BombSoundTimer >= Time) { m_BombSoundTimer = 0; GameServer()->CreateSound(B->m_Pos, SOUND_CHAT_SERVER); GameServer()->CreateSound(B->m_Pos, SOUND_CHAT_SERVER); } // bomb defusing //CCharacter *apCloseCCharacters[MAX_CLIENTS]; //int Num = GameServer()->m_World.FindEntities(B->m_Pos, CFlag::ms_PhysSize * 2, (CEntity**)apCloseCCharacters, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER); bool DefusingBomb = false; for (int i = 0; i < MAX_CLIENTS; i++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; CCharacter *pCharacter = pPlayer->GetCharacter(); if (!pCharacter) continue; if(!pCharacter->IsAlive() || pPlayer->GetTeam() != m_DefendingTeam) continue; // check distance if (abs(pCharacter->m_Pos.x - B->m_Pos.x) < 150 && abs(pCharacter->m_Pos.y - B->m_Pos.y) < 150 && pCharacter->IsGrounded()) { DefusingBomb = true; m_aDefusing[i] = true; pPlayer->m_InterestPoints += 7; if (m_BombDefuseTimer == 0) { GameServer()->SendBroadcast("Defusing bomb", pPlayer->GetCID()); //GameServer()->CreateSoundGlobal(SOUND_CTF_DROP, pPlayer->GetCID()); } } else { if (m_aDefusing[i]) { m_aDefusing[i] = false; GameServer()->SendBroadcast("", pPlayer->GetCID()); } } } if (DefusingBomb) { // bomb defusing sound if (++m_BombActionTimer >= Server()->TickSpeed()/4) { m_BombActionTimer = 0; GameServer()->CreateSound(B->m_Pos, SOUND_BODY_LAND); } if (++m_BombDefuseTimer >= g_Config.m_SvBombDefuseTime*Server()->TickSpeed()) { B->m_Hide = true; m_BombDefused = true; if (m_DefendingTeam == TEAM_RED) GameServer()->SendBroadcast("Bomb defused - Terrorists score!", -1, true); if (m_DefendingTeam == TEAM_BLUE) GameServer()->SendBroadcast("Bomb defused - Counter-terrorists score!", -1, true); GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_PL, -1); m_RoundTimeLimit = 0; // gamecontroller m_ResetTime = true; // gamecontroller } } else { m_BombDefuseTimer = 0; } return; } else { for (int c = 0; c < MAX_CLIENTS; c++) { bool BombPlantable = false; CPlayer *pPlayer = GameServer()->m_apPlayers[c]; if(!pPlayer) continue; if(pPlayer->GetTeam() == m_DefendingTeam) continue; CCharacter *pCharacter = pPlayer->GetCharacter(); if (!pCharacter) continue; if(!pCharacter->IsAlive() || pPlayer->GetTeam() == m_DefendingTeam) continue; if (m_Base >= 0) { if (m_apBombArea[m_Base] && !m_apBombArea[m_Base]->m_Hide) { // check distance if (abs(m_apBombArea[m_Base]->m_Pos.x - pCharacter->m_Pos.x) < 200 && abs(m_apBombArea[m_Base]->m_Pos.y - pCharacter->m_Pos.y) < 200 && pCharacter->IsGrounded()) { BombPlantable = true; //GameServer()->SendBroadcast("Inside range", pPlayer->GetCID()); if (pCharacter->m_BombStatus != BOMB_PLANTING) { pCharacter->m_BombStatus = BOMB_PLANTING; m_aPlanting[c] = 0; GameServer()->SendBroadcast("Planting bomb", pPlayer->GetCID()); } else if (pCharacter->m_BombStatus == BOMB_PLANTING) { // bomb planting sound if (++m_aBombActionTimer[c] >= Server()->TickSpeed()/4) { m_aBombActionTimer[c] = 0; GameServer()->CreateSound(B->m_Pos, SOUND_BODY_LAND); } pPlayer->m_InterestPoints += 6; if (++m_aPlanting[c] >= g_Config.m_SvBombPlantTime*Server()->TickSpeed()) { pPlayer->m_InterestPoints += 120; B->m_pCarryingCharacter = NULL; B->m_Status = BOMB_PLANTED; pCharacter->m_BombStatus = BOMB_PLANTED; m_aPlanting[c] = 0; B->m_Timer = 0; GameServer()->SendBroadcast("Bomb planted!", -1, true); GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_PL, -1); B->m_Hide = false; B->m_Pos = pCharacter->m_Pos; B->m_Owner = c; m_RoundTimeLimit = g_Config.m_SvBombTime; // gamecontroller m_ResetTime = true; // gamecontroller return; } } } } } if (!BombPlantable) { pCharacter->m_BombStatus = BOMB_CARRYING; if (m_aPlanting[c] > 0) GameServer()->SendBroadcast("", c); m_aPlanting[c] = 0; } } } // don't add anything relevant here! possible return; above! }
void CGameControllerCSBB::CaptureBase() { if (m_Base < 0 || m_Base >= m_BombAreaCount) { NewBase(); return; } if (!m_apBombArea[m_Base]) { NewBase(); return; } bool Red = false; bool Blue = false; // check for players within base range for (int i = 0; i < MAX_CLIENTS; i++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; CCharacter *pCharacter = pPlayer->GetCharacter(); if (!pCharacter) continue; if (!pCharacter->IsAlive()) continue; if (distance(m_apBombArea[m_Base]->m_Pos, pCharacter->m_Pos) < g_Config.m_SvBaseCaptureDistance && pCharacter->m_Pos.y < m_apBombArea[m_Base]->m_Pos.y+48) { if (pPlayer->GetTeam() == TEAM_RED) Red = true; if (pPlayer->GetTeam() == TEAM_BLUE) Blue = true; } } if (Red && Blue) { m_RedCaptureTime = 0; m_BlueCaptureTime = 0; } if (!Red) { m_RedCaptureTime = 0; if (Blue) { // blue team capturing the base m_BlueCaptureTime++; } } if (!Blue) { m_BlueCaptureTime = 0; if (Red) { // red team capturing the base m_RedCaptureTime++; } } // broadcast to players capturing the base for (int i = 0; i < MAX_CLIENTS; i++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; CCharacter *pCharacter = pPlayer->GetCharacter(); if (!pCharacter) continue; if (!pCharacter->IsAlive() || pPlayer->m_IsBot) continue; if (((pPlayer->GetTeam() == TEAM_RED && Red && !Blue) || (pPlayer->GetTeam() == TEAM_BLUE && Blue && !Red)) && (distance(m_apBombArea[m_Base]->m_Pos, pCharacter->m_Pos) < g_Config.m_SvBaseCaptureDistance && pCharacter->m_Pos.y < m_apBombArea[m_Base]->m_Pos.y+48)) { pPlayer->m_BroadcastingCaptureStatus = true; GameServer()->SendBroadcast("Capturing the base", pPlayer->GetCID()); } else if (pPlayer->m_BroadcastingCaptureStatus) { pPlayer->m_BroadcastingCaptureStatus = false; GameServer()->SendBroadcast("", pPlayer->GetCID()); } } bool BaseCaptured = false; if (m_RedCaptureTime > g_Config.m_SvBaseCaptureTime*Server()->TickSpeed()) { GameServer()->SendBroadcast("Terrorists captured the base!", -1, true); BaseCaptured = true; m_DefendingTeam = TEAM_RED; for (int i = 0; i < MAX_BOMBAREAS; i++) { if (m_apBombArea[i]) m_apBombArea[i]->m_Team = TEAM_RED; } if (m_pBomb) m_pBomb->m_Team = TEAM_BLUE; } else if (m_BlueCaptureTime > g_Config.m_SvBaseCaptureTime*Server()->TickSpeed()) { GameServer()->SendBroadcast("Counter-terrorists captured the base!", -1, true); BaseCaptured = true; m_DefendingTeam = TEAM_BLUE; for (int i = 0; i < MAX_BOMBAREAS; i++) { if (m_apBombArea[i]) m_apBombArea[i]->m_Team = TEAM_BLUE; } if (m_pBomb) m_pBomb->m_Team = TEAM_RED; } if (BaseCaptured) { m_BlueCaptureTime = 0; m_RedCaptureTime = 0; m_GameState = CSBB_DEFENDING; m_RoundTick = 0; m_RoundTimeLimit = g_Config.m_SvRoundTime; m_ResetTime = true; GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE, -1); GiveBombToPlayer(); } }
void CGameContext::ConJoinTeam(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *) pUserData; if (!CheckClientID(pResult->m_ClientID)) return; CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID]; if (!pPlayer) return; if (pSelf->m_VoteCloseTime && pSelf->m_VoteCreator == pResult->m_ClientID && (pSelf->m_VoteKick || pSelf->m_VoteSpec)) { pSelf->Console()->Print( IConsole::OUTPUT_LEVEL_STANDARD, "join", "You are running a vote please try again after the vote is done!"); return; } else if (g_Config.m_SvTeam == 0 || g_Config.m_SvTeam == 3) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "Admin has disabled teams"); return; } else if (g_Config.m_SvTeam == 2 && pResult->GetInteger(0) == 0 && pPlayer->GetCharacter() && pPlayer->GetCharacter()->m_LastStartWarning < pSelf->Server()->Tick() - 3 * pSelf->Server()->TickSpeed()) { pSelf->Console()->Print( IConsole::OUTPUT_LEVEL_STANDARD, "join", "You must join a team and play with somebody or else you can\'t play"); pPlayer->GetCharacter()->m_LastStartWarning = pSelf->Server()->Tick(); } if (pResult->NumArguments() > 0) { if (pPlayer->GetCharacter() == 0) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "You can't change teams while you are dead/a spectator."); } else { if (pPlayer->m_Last_Team + pSelf->Server()->TickSpeed() * g_Config.m_SvTeamChangeDelay > pSelf->Server()->Tick()) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "You can\'t change teams that fast!"); } else if(pResult->GetInteger(0) > 0 && pResult->GetInteger(0) < MAX_CLIENTS && ((CGameControllerDDRace*) pSelf->m_pController)->m_Teams.TeamLocked(pResult->GetInteger(0))) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "This team is locked using /lock. Only members of the team can unlock it using /lock."); } else if(pResult->GetInteger(0) > 0 && pResult->GetInteger(0) < MAX_CLIENTS && ((CGameControllerDDRace*) pSelf->m_pController)->m_Teams.Count(pResult->GetInteger(0)) >= g_Config.m_SvTeamMaxSize) { char aBuf[512]; str_format(aBuf, sizeof(aBuf), "This team already has the maximum allowed size of %d players", g_Config.m_SvTeamMaxSize); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", aBuf); } else if (((CGameControllerDDRace*) pSelf->m_pController)->m_Teams.SetCharacterTeam( pPlayer->GetCID(), pResult->GetInteger(0))) { char aBuf[512]; str_format(aBuf, sizeof(aBuf), "%s joined team %d", pSelf->Server()->ClientName(pPlayer->GetCID()), pResult->GetInteger(0)); pSelf->SendChat(-1, CGameContext::CHAT_ALL, aBuf); pPlayer->m_Last_Team = pSelf->Server()->Tick(); } else { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "You cannot join this team at this time"); } } } else { char aBuf[512]; if (!pPlayer->IsPlaying()) { pSelf->Console()->Print( IConsole::OUTPUT_LEVEL_STANDARD, "join", "You can't check your team while you are dead/a spectator."); } else { str_format( aBuf, sizeof(aBuf), "You are in team %d", ((CGameControllerDDRace*) pSelf->m_pController)->m_Teams.m_Core.Team( pResult->m_ClientID)); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", aBuf); } } }
void CGameControllerDOM::Tick() { IGameController::Tick(); AutoBalance(); GameServer()->UpdateAI(); BaseTick(); if (m_ScoreTick + Server()->TickSpeed()*5 <= Server()->Tick()) { m_ScoreTick = Server()->Tick(); m_aTeamscore[TEAM_RED] += CountBases(TEAM_RED); m_aTeamscore[TEAM_BLUE] += CountBases(TEAM_BLUE); } int PlayerCount = 0; // warm welcome for (int c = 0; c < MAX_CLIENTS; c++) { CPlayer *pPlayer = GameServer()->m_apPlayers[c]; if(!pPlayer) continue; PlayerCount++; if (!pPlayer->m_Welcomed && !pPlayer->m_IsBot) { GameServer()->SendBroadcast("Welcome to Domination++", pPlayer->GetCID(), true); pPlayer->m_Welcomed = true; } } if (PlayerCount == 0) { m_aTeamscore[TEAM_RED] = 0; m_aTeamscore[TEAM_BLUE] = 0; } // dont show more than one base (flag) to a player for (int f = 0; f < MAX_BASES; f++) { if (m_apBase[f]) m_apBase[f]->ResetDistanceInfo(); } // find the closest base to a player (and snap it later) for (int c = 0; c < MAX_CLIENTS; c++) { CPlayer *pPlayer = GameServer()->m_apPlayers[c]; if(!pPlayer) continue; CCharacter *pCharacter = pPlayer->GetCharacter(); if (!pCharacter) continue; CFlag *pClosestBase = GetClosestBase(pCharacter->m_Pos); if (pClosestBase) pClosestBase->m_ClosestFlagToCharacter[c] = true; } }
void CGameControllerDOM::BaseTick() { for (int i = 0; i < MAX_BASES; i++) { if (m_apBase[i]) { m_aDefenders[i] = 0; int Capturing = 0; for (int c = 0; c < MAX_CLIENTS; c++) { CPlayer *pPlayer = GameServer()->m_apPlayers[c]; if(!pPlayer) continue; if(!pPlayer->GetCharacter()) continue; if (distance(m_apBase[i]->m_Pos, pPlayer->GetCharacter()->m_Pos) > g_Config.m_SvBaseCaptureDistance) { if (m_aCapturing[c] == i) { m_aCapturing[c] = -1; GameServer()->SendBroadcast("", pPlayer->GetCID()); } continue; } else { if (GameServer()->Collision()->IntersectLine(m_apBase[i]->m_Pos, pPlayer->GetCharacter()->m_Pos, NULL, NULL)) { if (m_aCapturing[c] == i) { m_aCapturing[c] = -1; GameServer()->SendBroadcast("", pPlayer->GetCID()); } continue; } } int Team = pPlayer->GetTeam(); // capturing if (Team == TEAM_RED) { m_apBase[i]->m_CapturePoints -= 1; Capturing = -1; } if (Team == TEAM_BLUE) { m_apBase[i]->m_CapturePoints += 1; Capturing = 1; } if (Team != m_apBase[i]->m_CaptureTeam) { int p = (g_Config.m_SvBaseCaptureTreshold + m_apBase[i]->m_CapturePoints * (Team == TEAM_RED ? -1 : 1)) * 50 / g_Config.m_SvBaseCaptureTreshold; char aBuf[128]; str_format(aBuf, sizeof(aBuf), "Capturing the base! %d%%", p); GameServer()->SendBroadcast(aBuf, pPlayer->GetCID()); m_aCapturing[c] = i; } else { m_aDefenders[i]++; } } if (Capturing == 0) m_apBase[i]->m_CapturePoints *= 0.95f; // captured if (m_apBase[i]->m_CapturePoints <= -g_Config.m_SvBaseCaptureTreshold) { m_apBase[i]->m_CapturePoints = -g_Config.m_SvBaseCaptureTreshold; if (m_apBase[i]->m_CaptureTeam != TEAM_RED) { m_apBase[i]->m_CaptureTeam = TEAM_RED; char aBuf[128]; str_format(aBuf, sizeof(aBuf), "Red team captured base %d!", i+1); GameServer()->SendBroadcast(aBuf, -1, true); // play sound for (int x = 0; x < MAX_CLIENTS; x++) { CPlayer *P = GameServer()->m_apPlayers[x]; if(!P) continue; if (P->GetTeam() == TEAM_RED) GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE, x); else GameServer()->CreateSoundGlobal(SOUND_CTF_DROP, x); } } } if (m_apBase[i]->m_CapturePoints >= g_Config.m_SvBaseCaptureTreshold) { m_apBase[i]->m_CapturePoints = g_Config.m_SvBaseCaptureTreshold; if (m_apBase[i]->m_CaptureTeam != TEAM_BLUE) { m_apBase[i]->m_CaptureTeam = TEAM_BLUE; char aBuf[128]; str_format(aBuf, sizeof(aBuf), "Blue team captured base %d!", i+1); GameServer()->SendBroadcast(aBuf, -1, true); // play sound for (int x = 0; x < MAX_CLIENTS; x++) { CPlayer *P = GameServer()->m_apPlayers[x]; if(!P) continue; if (P->GetTeam() == TEAM_BLUE) GameServer()->CreateSoundGlobal(SOUND_CTF_CAPTURE, x); else GameServer()->CreateSoundGlobal(SOUND_CTF_DROP, x); } } } } } }
bool CGameControllerMOD::PreSpawn(CPlayer* pPlayer, vec2 *pOutPos) { // spectators can't spawn if(pPlayer->GetTeam() == TEAM_SPECTATORS) return false; if(m_InfectedStarted) { pPlayer->StartInfection(); } else { pPlayer->m_WasHumanThisRound = true; } if(pPlayer->IsInfected() && m_ExplosionStarted) return false; if(m_InfectedStarted && pPlayer->IsInfected() && rand()%3 > 0) { for(int i = 0; i < MAX_CLIENTS; i ++) { CPlayer *pWitch = GameServer()->m_apPlayers[i]; if(!pWitch) continue; if(pWitch->GetCID() == pPlayer->GetCID()) continue; if(pWitch->GetClass() != PLAYERCLASS_WITCH) continue; if(!pWitch->GetCharacter()) continue; vec2 spawnTile = vec2(16.0f, 16.0f) + vec2( static_cast<float>(static_cast<int>(round(pWitch->GetCharacter()->m_Pos.x))/32)*32.0, static_cast<float>(static_cast<int>(round(pWitch->GetCharacter()->m_Pos.y))/32)*32.0); for(int j=-1; j<=1; j++) { if(IsSpawnable(vec2(spawnTile.x + j*32.0, spawnTile.y-64.0))) { *pOutPos = spawnTile + vec2(j*32.0, -64.0); return true; } if(IsSpawnable(vec2(spawnTile.x + j*32.0, spawnTile.y+64.0))) { *pOutPos = spawnTile + vec2(j*32.0, 64.0); return true; } if(IsSpawnable(vec2(spawnTile.x-64.0, spawnTile.y + j*32.0))) { *pOutPos = spawnTile + vec2(-64.0, j*32.0); return true; } if(IsSpawnable(vec2(spawnTile.x+64.0, spawnTile.y + j*32.0))) { *pOutPos = spawnTile + vec2(64.0, j*32.0); return true; } } } } CSpawnEval Eval; int Team = (pPlayer->IsInfected() ? TEAM_RED : TEAM_BLUE); Eval.m_FriendlyTeam = Team; // first try own team spawn, then normal spawn and then enemy EvaluateSpawnType(&Eval, Team); *pOutPos = Eval.m_Pos; return Eval.m_Got; }
int CGameControllerMOD::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon) { // do scoreing if(!pKiller || Weapon == WEAPON_GAME) return 0; if(pKiller == pVictim->GetPlayer()) { if(!pVictim->IsInfected()) { pVictim->GetPlayer()->IncreaseScore(-1); // suicide } } else if(pKiller->IsInfected()) { CPlayer* pVictimPlayer = pVictim->GetPlayer(); if(pVictimPlayer) { if(!pVictim->IsInfected() && Weapon == WEAPON_NINJA) { GameServer()->SendChatTarget_Language_s(pKiller->GetCID(), "You have infected %s, +3 points", Server()->ClientName(pVictimPlayer->GetCID())); pKiller->IncreaseScore(3); pKiller->IncreaseNbInfection(1); } } } else if(!pKiller->IsInfected()) { if(pVictim->GetClass() == PLAYERCLASS_WITCH) { GameServer()->SendChatTarget_Language(pKiller->GetCID(), "You have killed a witch, +5 points"); pKiller->IncreaseScore(5); } else pKiller->IncreaseScore(1); //Add bonus point for ninja if(pVictim->IsFrozen() && pVictim->m_LastFreezer >= 0) { CPlayer* pFreezer = GameServer()->m_apPlayers[pVictim->m_LastFreezer]; if(pFreezer) { pFreezer->IncreaseScore(1); } } } if(Weapon == WEAPON_SELF) pVictim->GetPlayer()->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()*3.0f; return 0; }
void CMonster::TickBotAI() { //Sounds if (Server()->Tick() - m_BotTimeLastSound > Server()->TickSpeed()*5.0f && !(rand()%50)) { PlaySound(); m_BotTimeLastSound = Server()->Tick(); } //Clean m_Input m_Input.m_Hook = 0; m_Input.m_Fire = 0; m_Input.m_Jump = 0; //Run actions RunAction(); //Interact with users bool PlayerClose = false; bool PlayerFound = false; float LessDist = 500.0f; m_BotClientIDFix = -1; for (int i=0; i<g_Config.m_SvMaxClients; i++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if (!pPlayer || !pPlayer->GetCharacter() || pPlayer->IsBot()) continue; int Dist = distance(pPlayer->GetCharacter()->m_Pos, m_Pos); if (Dist < LessDist) LessDist = Dist; else continue; if (m_pPlayer->GetBotSubType() == BOT_MONSTER_EYE && Dist < 600.0f) { const vec2 dir = normalize(pPlayer->GetCharacter()->m_Pos-m_Pos); m_Core.m_Vel = dir*6.0f; } if (Dist < 280.0f) { if (Dist > 120.0f) { vec2 DirPlayer = normalize(pPlayer->GetCharacter()->m_Pos - m_Pos); if (m_pPlayer->GetBotSubType() == BOT_MONSTER_SKELETEE) { m_BotDir = 0; m_BotClientIDFix = pPlayer->GetCID(); } else { if (DirPlayer.x < 0) m_BotDir = -1; else m_BotDir = 1; } } else { PlayerClose = true; if (m_pPlayer->GetBotSubType() == BOT_MONSTER_TEEPER) m_BotDir = 0; else if ((m_pPlayer->GetBotSubType() == BOT_MONSTER_ZOMBITEE || m_pPlayer->GetBotSubType() == BOT_MONSTER_EYE) && Dist < 42.0f) { m_BotDir = 0; m_BotClientIDFix = pPlayer->GetCID(); } } m_Input.m_TargetX = static_cast<int>(pPlayer->GetCharacter()->m_Pos.x - m_Pos.x); m_Input.m_TargetY = static_cast<int>(pPlayer->GetCharacter()->m_Pos.y - m_Pos.y); PlayerFound = true; } } //Fix target if (!PlayerFound) { m_Input.m_TargetX = m_BotDir; m_Input.m_TargetY = 0; } else if (m_BotClientIDFix != -1) { CPlayer *pPlayer = GameServer()->m_apPlayers[m_BotClientIDFix]; if (pPlayer && pPlayer->GetCharacter() && m_Pos.y > pPlayer->GetCharacter()->m_Pos.y) // Jump to player m_Input.m_Jump = 1; } //Random Actions if (!PlayerFound) { if (Server()->Tick()-m_BotTimeLastOption > Server()->TickSpeed()*10.0f) { int Action = rand()%3; if (Action == 0) m_BotDir = -1; else if (Action == 1) m_BotDir = 1; else if (Action == 2) m_BotDir = 0; m_BotTimeLastOption = Server()->Tick(); } } //Interact with the envirionment float radiusZ = ms_PhysSize/2.0f; if (distance(m_Pos, m_BotLastPos) < radiusZ || abs(m_Pos.x-m_BotLastPos.x) < radiusZ) { if (Server()->Tick() - m_BotLastStuckTime > Server()->TickSpeed()*0.5f) { m_BotStuckCount++; if (m_BotStuckCount == 15) { if (!m_BotJumpTry) { m_Input.m_Jump = 1; m_BotJumpTry = true; } else { m_BotDir = (!(rand()%2))?1:-1; m_BotJumpTry = false; } m_BotStuckCount = 0; m_BotLastStuckTime = Server()->Tick(); } } } //Fix Stuck if (IsGrounded()) m_BotTimeGrounded = Server()->Tick(); //Falls if (m_pPlayer->GetBotSubType() != BOT_MONSTER_ZOMBITEE && m_Core.m_Vel.y > GameServer()->Tuning()->m_Gravity) { if (m_BotClientIDFix != -1) { CPlayer *pPlayer = GameServer()->m_apPlayers[m_BotClientIDFix]; if (pPlayer && pPlayer->GetCharacter() && m_Pos.y > pPlayer->GetCharacter()->m_Pos.y) m_Input.m_Jump = 1; else m_Input.m_Jump = 0; } else m_Input.m_Jump = 1; } // Fluids if (GameServer()->m_BlockManager.IsFluid(GameServer()->Collision()->GetMineTeeTileIndexAt(m_Pos))) m_Input.m_Jump = 1; //Limits int tx = m_Pos.x+m_BotDir*45.0f; if (tx < 0) m_BotDir = 1; else if (tx >= GameServer()->Collision()->GetWidth()*32.0f) m_BotDir = -1; //Delay of actions if (!PlayerClose) m_BotTimePlayerFound = Server()->Tick(); // Disables if (m_pPlayer->GetBotSubType() == BOT_MONSTER_EYE) { m_Input.m_Jump = 0; } //Set data m_Input.m_Direction = m_BotDir; m_Input.m_PlayerFlags = PLAYERFLAG_PLAYING; //Check for legacy input if (m_LatestPrevInput.m_Fire && m_Input.m_Fire) m_Input.m_Fire = 0; if (m_LatestInput.m_Jump && m_Input.m_Jump) m_Input.m_Jump = 0; //Ceck Double Jump if (m_Input.m_Jump && (m_Jumped&1) && !(m_Jumped&2) && m_Core.m_Vel.y < GameServer()->Tuning()->m_Gravity) m_Input.m_Jump = 0; m_LatestPrevInput = m_LatestInput; m_LatestInput = m_Input; m_BotLastPos = m_Pos; CCharacter::FireWeapon(); }
int CGameControllerMOD::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon) { // do scoreing if(!pKiller || Weapon == WEAPON_GAME) return 0; if(pKiller->IsInfected()) { CPlayer* pVictimPlayer = pVictim->GetPlayer(); if(pVictimPlayer) { if(!pVictim->IsInfected()) { GameServer()->SendChatTarget_Localization(pKiller->GetCID(), CHATCATEGORY_SCORE, _("You have infected {str:VictimName}, +3 points"), "VictimName", Server()->ClientName(pVictimPlayer->GetCID()), NULL); Server()->RoundStatistics()->OnScoreEvent(pKiller->GetCID(), SCOREEVENT_INFECTION, pKiller->GetClass()); GameServer()->SendScoreSound(pKiller->GetCID()); //Search for hook for(CCharacter *pHook = (CCharacter*) GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER); pHook; pHook = (CCharacter *)pHook->TypeNext()) { if( pHook->GetPlayer() && pHook->m_Core.m_HookedPlayer == pVictim->GetPlayer()->GetCID() && pHook->GetPlayer()->GetCID() != pKiller->GetCID() ) { Server()->RoundStatistics()->OnScoreEvent(pHook->GetPlayer()->GetCID(), SCOREEVENT_HELP_HOOK_INFECTION, pHook->GetClass()); GameServer()->SendScoreSound(pHook->GetPlayer()->GetCID()); } } } } } else { if(pKiller == pVictim->GetPlayer()) { Server()->RoundStatistics()->OnScoreEvent(pKiller->GetCID(), SCOREEVENT_HUMAN_SUICIDE, pKiller->GetClass()); } if(pVictim->GetClass() == PLAYERCLASS_WITCH) { GameServer()->SendChatTarget_Localization(pKiller->GetCID(), CHATCATEGORY_SCORE, _("You have killed a witch, +5 points"), NULL); Server()->RoundStatistics()->OnScoreEvent(pKiller->GetCID(), SCOREEVENT_KILL_WITCH, pKiller->GetClass()); GameServer()->SendScoreSound(pKiller->GetCID()); } else if(pKiller->GetClass() == PLAYERCLASS_NINJA && pVictim->GetPlayer()->GetCID() == GameServer()->GetTargetToKill()) { GameServer()->SendChatTarget_Localization(pKiller->GetCID(), CHATCATEGORY_SCORE, _("You have eliminated your target, +3 points"), NULL); Server()->RoundStatistics()->OnScoreEvent(pKiller->GetCID(), SCOREEVENT_KILL_TARGET, pKiller->GetClass()); GameServer()->SendScoreSound(pKiller->GetCID()); GameServer()->TargetKilled(); } else if(pVictim->IsInfected()) { Server()->RoundStatistics()->OnScoreEvent(pKiller->GetCID(), SCOREEVENT_KILL_INFECTED, pKiller->GetClass()); GameServer()->SendScoreSound(pKiller->GetCID()); } } //Add bonus point for ninja if(pVictim->IsInfected() && pVictim->IsFrozen() && pVictim->m_LastFreezer >= 0 && pVictim->m_LastFreezer != pKiller->GetCID()) { CPlayer* pFreezer = GameServer()->m_apPlayers[pVictim->m_LastFreezer]; if(pFreezer) { Server()->RoundStatistics()->OnScoreEvent(pFreezer->GetCID(), SCOREEVENT_HELP_FREEZE, pFreezer->GetClass()); GameServer()->SendScoreSound(pFreezer->GetCID()); } } if(Weapon == WEAPON_SELF) pVictim->GetPlayer()->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()*3.0f; return 0; }
void CGameContext::ConJoinTeam(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *) pUserData; if (!CheckClientID(pResult->m_ClientID)) return; CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID]; if (pSelf->m_VoteCloseTime && pSelf->m_VoteCreator == pResult->m_ClientID) { pSelf->Console()->Print( IConsole::OUTPUT_LEVEL_STANDARD, "join", "You are running a vote please try again after the vote is done!"); return; } else if (g_Config.m_SvTeam == 0) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "Admin has disabled teams"); return; } else if (g_Config.m_SvTeam == 2 && pResult->GetInteger(0) == 0 && pPlayer->GetCharacter()->m_LastStartWarning < pSelf->Server()->Tick() - 3 * pSelf->Server()->TickSpeed()) { pSelf->Console()->Print( IConsole::OUTPUT_LEVEL_STANDARD, "join", "You must join a team and play with somebody or else you can\'t play"); pPlayer->GetCharacter()->m_LastStartWarning = pSelf->Server()->Tick(); } if (pResult->NumArguments() > 0) { if (pPlayer->GetCharacter() == 0) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "You can't change teams while you are dead/a spectator."); } else { CGameTeams& teams = ((CGameControllerDDRace*) pSelf->m_pController)->m_Teams; int team = pResult->GetInteger(0); if (pPlayer->m_Last_Team + pSelf->Server()->TickSpeed() * g_Config.m_SvTeamChangeDelay > pSelf->Server()->Tick()) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "You can\'t change teams that fast!"); } else { if(team < 10) { if(team == 0 && teams.m_Core.Team(pPlayer->GetCID()) >= 10) { pPlayer->GetCharacter()->Teams()->m_Core.Team(pPlayer->GetCID(), team); } else if (teams.SetCharacterTeam(pPlayer->GetCID(), team)) { char aBuf[512]; str_format(aBuf, sizeof(aBuf), "%s joined team %d", pSelf->Server()->ClientName(pPlayer->GetCID()), team); pSelf->SendChat(-1, CGameContext::CHAT_ALL, aBuf); pPlayer->m_Last_Team = pSelf->Server()->Tick(); } else { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "You cannot join this team"); } } else if(team < MAX_CLIENTS && (teams.m_Core.Team(pPlayer->GetCID()) >= 10 || teams.m_Core.Team(pPlayer->GetCID()) == 0)) { pPlayer->GetCharacter()->Teams()->m_Core.Team(pPlayer->GetCID(), team); } else { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", "You cannot join this team"); } } } } else { char aBuf[512]; if (!pPlayer->IsPlaying()) { pSelf->Console()->Print( IConsole::OUTPUT_LEVEL_STANDARD, "join", "You can't check your team while you are dead/a spectator."); } else { str_format( aBuf, sizeof(aBuf), "You are in team %d", ((CGameControllerDDRace*) pSelf->m_pController)->m_Teams.m_Core.Team( pResult->m_ClientID)); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "join", aBuf); } } }