void CGameControllerOpenFNG::HandleMelt(int Melter, int Meltee) { CCharacter *pMeltee = CHAR(Meltee); if (!pMeltee) //due to HandleFreeze, i suspect this COULD also possibly happen. { D("no pMeltee in HandleMelt(%d, %d)", Melter, Meltee); return; } int MeltTeam = pMeltee->GetPlayer()->GetTeam()&1; m_aTeamscore[MeltTeam] += CFG(MeltTeamscore); if (CFG(MeltTeamscore) && CFG(MeltBroadcast)) { char aBuf[64]; str_format(aBuf, sizeof aBuf, "%s melted (%+d)", GetTeamName(MeltTeam), CFG(MeltTeamscore)); m_Broadcast.Update(-1, aBuf, CFG(BroadcastTime) * TS); } CPlayer *pPlMelter = TPLAYER(Melter); if (!pPlMelter) return; pPlMelter->m_Score += CFG(MeltScore); SendFreezeKill(Melter, Meltee, WEAPON_HAMMER); if (pPlMelter->GetCharacter() && CFG(MeltLoltext) && CFG(MeltScore)) { char aBuf[64]; str_format(aBuf, sizeof aBuf, "%+d", CFG(MeltScore)); GS->CreateLolText(pPlMelter->GetCharacter(), false, vec2(0.f, -50.f), vec2(0.f, 0.f), 50, aBuf); } }
void CGameControllerSoloFNG::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)", Server()->ClientName(Killer)/*GetTeamName(1-FailTeam), Wrong?" in wrong shrine":*/, (ShrineTeam == -1 ? "" : ", pleasing the god"),(ShrineTeam == -1 ?CFG(SacrScore) : CFG(RightSacrScore)) /*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)); SendFreezeKill(Killer, Victim, WEAPON_NINJA); /* 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 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 IGameController::Snap(int SnappingClient) { CNetObj_GameInfo *pGameInfoObj = (CNetObj_GameInfo *)Server()->SnapNewItem(NETOBJTYPE_GAMEINFO, 0, sizeof(CNetObj_GameInfo)); if(!pGameInfoObj) return; pGameInfoObj->m_GameFlags = m_GameFlags; pGameInfoObj->m_GameStateFlags = 0; if(m_GameOverTick != -1) pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_GAMEOVER; if(m_SuddenDeath) pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_SUDDENDEATH; if(GameServer()->m_World.m_Paused) pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_PAUSED; pGameInfoObj->m_RoundStartTick = m_RoundStartTick; pGameInfoObj->m_WarmupTimer = m_Warmup; //pGameInfoObj->m_ScoreLimit = g_Config.m_SvScorelimit; //pGameInfoObj->m_TimeLimit = g_Config.m_SvTimelimit; pGameInfoObj->m_RoundNum = /*(str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap :*/ 0; pGameInfoObj->m_RoundCurrent = m_RoundCount+1; CCharacter *pChr; CPlayer *pPlayer = GameServer()->m_apPlayers[SnappingClient]; if(pPlayer && (pPlayer->m_TimerType == 0 || pPlayer->m_TimerType == 2) && SnappingClient >= 0) if((pChr = pPlayer->GetCharacter())) pGameInfoObj->m_RoundStartTick = (pChr->m_DDRaceState == DDRACE_STARTED)?pChr->m_StartTime:m_RoundStartTick; }
void CGameControllerCSBB::GiveBombToPlayer() { GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "csbb", "Giving bomb to a player"); if (!m_pBomb) return; m_pBomb->m_Hide = true; m_pBomb->m_Owner = -1; m_pBomb->m_pCarryingCharacter = NULL; m_pBomb->m_Status = BOMB_CARRYING; for (int i = 0; i < MAX_CLIENTS; i++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; CCharacter *pCharacter = pPlayer->GetCharacter(); if (!pCharacter) continue; pCharacter->m_BombStatus = BOMB_CARRYING; } }
void CGameContext::ConTogglePause(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *)pUserData; if(!CheckClientID(pResult->m_ClientID)) return; char aBuf[128]; CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID]; if(!pPlayer) return; if (pPlayer->GetCharacter() == 0) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "pause", "You can't pause while you are dead/a spectator."); return; } if(pPlayer->m_Paused == CPlayer::PAUSED_FORCE) { str_format(aBuf, sizeof(aBuf), "You are force-paused. %ds left.", pPlayer->m_ForcePauseTime/pSelf->Server()->TickSpeed()); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "pause", aBuf); return; } pPlayer->m_Paused = (pPlayer->m_Paused == CPlayer::PAUSED_SPEC) ? CPlayer::PAUSED_NONE : CPlayer::PAUSED_SPEC; }
void CGameContext::ConSayTimeAll(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(pChr->m_DDRaceState != DDRACE_STARTED) return; char aBuftime[64]; int IntTime = (int) ((float) (pSelf->Server()->Tick() - pChr->m_StartTime) / ((float) pSelf->Server()->TickSpeed())); str_format(aBuftime, sizeof(aBuftime), "%s\'s current race time is %s%d:%s%d", pSelf->Server()->ClientName(pResult->m_ClientID), ((IntTime / 60) > 9) ? "" : "0", IntTime / 60, ((IntTime % 60) > 9) ? "" : "0", IntTime % 60); pSelf->SendChat(-1, CGameContext::CHAT_ALL, aBuftime, pResult->m_ClientID); }
CGrottoCharacter* CGrottoGame::GetLocalPlayerCharacter() { CPlayer* pPlayer = GetLocalPlayer(); if (!pPlayer) return nullptr; return static_cast<CGrottoCharacter*>(pPlayer->GetCharacter()); }
void CTeslacoil::Fire() { m_AttackTick = Server()->Tick(); vec2 TurretPos = m_Pos+vec2(0, -67*m_FlipY); bool Sound = false; for (int i = 0; i < MAX_CLIENTS; i++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; if (pPlayer->GetTeam() == m_Team && GameServer()->m_pController->IsTeamplay()) continue; CCharacter *pCharacter = pPlayer->GetCharacter(); if (!pCharacter) continue; if ((!pCharacter->IsAlive() || pCharacter->GetPlayer()->GetCID() == m_OwnerPlayer) && !GameServer()->m_pController->IsTeamplay()) continue; if (GameServer()->m_pController->IsCoop()) { if (!pCharacter->m_IsBot && m_Team >= 0) continue; if (pCharacter->m_IsBot && m_Team < 0) continue; } if (pCharacter->Invisible()) continue; int Distance = distance(pCharacter->m_Pos, TurretPos); if (Distance < 700 && !GameServer()->Collision()->FastIntersectLine(pCharacter->m_Pos, TurretPos)) { new CLightning(GameWorld(), TurretPos, pCharacter->m_Pos); pCharacter->TakeDamage(m_OwnerPlayer, GetBuildingWeapon(BUILDING_TESLACOIL), 5, vec2(0, 0), vec2(0, 0)); //pCharacter->TakeDamage(vec2(0, 0), 5, m_DamageOwner, DEATHTYPE_TESLACOIL, vec2(0, 0), DAMAGETYPE_ELECTRIC, false); Sound = true; } } if (Sound) GameServer()->CreateSound(m_Pos + vec2(0, -50*m_FlipY), SOUND_TESLACOIL_FIRE); }
void CGameContext::ConToggleFly(IConsole::IResult *pResult, void *pUserData) { if(!CheckClientID(pResult->m_ClientID)) return; CGameContext *pSelf = (CGameContext *)pUserData; CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID]; if(!pPlayer) return; CCharacter* pChr = pPlayer->GetCharacter(); if(!pChr) return; if(pChr->m_Super) { pChr->m_Fly = !pChr->m_Fly; pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", (pChr->m_Fly) ? "Fly enabled" : "Fly disabled"); } }
void CGameContext::ConSolo(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) { pChr->m_Solo = !pChr->m_Solo; pSelf->SendChatTarget(pResult->m_ClientID, pChr->m_Solo ? "You are now in solo" : "You are now out of solo"); } }
void CGameContext::ConSayTime(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *) pUserData; if (!CheckClientID(pResult->m_ClientID)) return; int ClientID; char aBufname[MAX_NAME_LENGTH]; if (pResult->NumArguments() > 0) { for(ClientID = 0; ClientID < MAX_CLIENTS; ClientID++) if (str_comp(pResult->GetString(0), pSelf->Server()->ClientName(ClientID)) == 0) break; if(ClientID == MAX_CLIENTS) return; str_format(aBufname, sizeof(aBufname), "%s's", pSelf->Server()->ClientName(ClientID)); } else { str_copy(aBufname, "Your", sizeof(aBufname)); ClientID = pResult->m_ClientID; } CPlayer *pPlayer = pSelf->m_apPlayers[ClientID]; if (!pPlayer) return; CCharacter* pChr = pPlayer->GetCharacter(); if (!pChr) return; if(pChr->m_DDRaceState != DDRACE_STARTED) return; char aBuftime[64]; int IntTime = (int) ((float) (pSelf->Server()->Tick() - pChr->m_StartTime) / ((float) pSelf->Server()->TickSpeed())); str_format(aBuftime, sizeof(aBuftime), "%s time is %s%d:%s%d", aBufname, ((IntTime / 60) > 9) ? "" : "0", IntTime / 60, ((IntTime % 60) > 9) ? "" : "0", IntTime % 60); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "time", aBuftime); }
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 CGameContext::ConForcePause(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *) pUserData; // if(!CheckClientID(pResult->m_ClientID)) return; CServer* pServ = (CServer*) pSelf->Server(); int Victim = pResult->GetVictim(); int Seconds = 0; char aBuf[128]; if (pResult->NumArguments() > 0 && pResult->m_ClientID < 0) Seconds = clamp(pResult->GetInteger(0), 0, 15); //else if(pResult->NumArguments() > 0 && CheckClientID(pResult->m_ClientID)) //Seconds = clamp(pResult->GetInteger(1), 0, 360); CPlayer *pPlayer = pSelf->m_apPlayers[Victim]; if (!pPlayer || (!Seconds && pResult->m_ClientID >= 0)) return; CCharacter* pChr = pPlayer->GetCharacter(); if (!pPlayer->GetTeam() && pChr && !pPlayer->m_InfoSaved && pResult->m_ClientID < 0) { pPlayer->SaveCharacter(); pPlayer->m_InfoSaved = true; pPlayer->SetTeam(TEAM_SPECTATORS); pPlayer->m_ForcePauseTime = Seconds * pServ->TickSpeed(); } else { pPlayer->m_ForcePauseTime = Seconds * pServ->TickSpeed(); } if (pResult->m_ClientID < 0) str_format(aBuf, sizeof(aBuf), "'%s' has been force-paused for %d seconds", pServ->ClientName(Victim), Seconds); else str_format(aBuf, sizeof(aBuf), "Force-pause of '%s' have been removed by '%s'", pServ->ClientName(Victim), pServ->ClientName(pResult->m_ClientID)); pSelf->SendChat(-1, CHAT_ALL, aBuf); }
void CGameContext::ConTime(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; char aBuftime[64]; int IntTime = (int) ((float) (pSelf->Server()->Tick() - pChr->m_StartTime) / ((float) pSelf->Server()->TickSpeed())); str_format(aBuftime, sizeof(aBuftime), "Your time is %s%d:%s%d", ((IntTime / 60) > 9) ? "" : "0", IntTime / 60, ((IntTime % 60) > 9) ? "" : "0", IntTime % 60); pSelf->SendBroadcast(aBuftime, pResult->m_ClientID); }
int CGameControllerCSBB::CountPlayersAlive() { int NumPlayersAlive = 0; 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; NumPlayersAlive++; } return NumPlayersAlive; }
void CGameContext::ConSayTime(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(pChr->m_DDRaceState != DDRACE_STARTED) return; char aBuftime[64]; int IntTime = (int) ((float) (pSelf->Server()->Tick() - pChr->m_StartTime) / ((float) pSelf->Server()->TickSpeed())); str_format(aBuftime, sizeof(aBuftime), "Your Time is %s%d:%s%d", ((IntTime / 60) > 9) ? "" : "0", IntTime / 60, ((IntTime % 60) > 9) ? "" : "0", IntTime % 60); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "time", aBuftime); }
void CGameContext::ConProtectedKill(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; int CurrTime = (pSelf->Server()->Tick() - pChr->m_StartTime) / pSelf->Server()->TickSpeed(); if(g_Config.m_SvKillProtection != 0 && CurrTime >= (60 * g_Config.m_SvKillProtection) && pChr->m_DDRaceState == DDRACE_STARTED) { pPlayer->KillCharacter(WEAPON_SELF); //char aBuf[64]; //str_format(aBuf, sizeof(aBuf), "You killed yourself in: %s%d:%s%d", // ((CurrTime / 60) > 9) ? "" : "0", CurrTime / 60, // ((CurrTime % 60) > 9) ? "" : "0", CurrTime % 60); //pSelf->SendChatTarget(pResult->m_ClientID, aBuf); } }
bool CGameControllerEXP::Use(int ClientID, const char *aCommand) { CPlayer *p = GameServer()->m_apPlayers[ClientID]; if(str_find_nocase(aCommand, "Life")) { if(p->m_GameExp.m_Items.m_Lives > 0) { if(p->GetTeam() != -1 && !p->GetCharacter()) { p->m_GameExp.m_Items.m_Lives--; p->LoadGame(p->m_ViewPos, p->m_GameExp.m_LastFlag, p->m_Score, p->m_GameExp.m_Time, p->m_GameExp.m_ArmorMax, p->m_GameExp.m_Weapons, p->m_GameExp.m_Items, p->m_GameExp.m_BossHitter, p->m_GameExp.m_BossKiller); char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Life used. %d lives left.", p->m_GameExp.m_Items.m_Lives); GameServer()->SendChatTarget(ClientID, aBuf); } else GameServer()->SendChatTarget(ClientID, "You are not dead!"); } else GameServer()->SendChatTarget(ClientID, "You haven't got a life!"); return true; } else if(str_find_nocase(aCommand, "Minor Potion")) { if(p->GetCharacter()) { if(p->m_GameExp.m_Items.m_MinorPotions > 0) { if(p->GetCharacter()->m_Health < 10) { p->m_GameExp.m_Items.m_MinorPotions--; p->GetCharacter()->m_Health = 10; char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Minor Potion used. You have %d Minor Potions left.", p->m_GameExp.m_Items.m_MinorPotions); GameServer()->SendChatTarget(ClientID, aBuf); } else GameServer()->SendChatTarget(ClientID, "You don't need to use that now!"); } else GameServer()->SendChatTarget(ClientID, "You haven't got a Minor Potion!"); } return true; } else if(str_find_nocase(aCommand, "Greater Potion")) { if(p->GetCharacter()) { if(p->m_GameExp.m_Items.m_GreaterPotions > 0) { if(p->GetCharacter()->m_Health < 10 || p->GetCharacter()->m_Armor < p->m_GameExp.m_ArmorMax) { p->m_GameExp.m_Items.m_GreaterPotions--; p->GetCharacter()->m_Health = 10; p->GetCharacter()->m_Armor = p->m_GameExp.m_ArmorMax; char aBuf[256]; str_format(aBuf, sizeof(aBuf), "Greater Potion used. You have %d Greater Potions left.", p->m_GameExp.m_Items.m_GreaterPotions); GameServer()->SendChatTarget(ClientID, aBuf); } else GameServer()->SendChatTarget(ClientID, "You don't need to use that now!"); } else GameServer()->SendChatTarget(ClientID, "You haven't got a Greater Potion!"); } return true; } return false; }
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); } } }
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(); }
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 CGameControllerMOD::Tick() { IGameController::Tick(); m_HumanCounter = 0; m_InfectedCounter = 0; //Count type of players for(int i = 0; i < MAX_CLIENTS; i ++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue; if(pPlayer->IsInfected()) m_InfectedCounter++; else m_HumanCounter++; } m_InfectedStarted = false; //If the game can start ... if(m_GameOverTick == -1 && m_HumanCounter + m_InfectedCounter >= 2) { //If the infection started if(m_RoundStartTick + Server()->TickSpeed()*10 < Server()->Tick()) { m_InfectedStarted = true; for(int i = 0; i < MAX_CLIENTS; i ++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; if(pPlayer->GetTeam() == TEAM_SPECTATORS) { pPlayer->StartInfection(); } else if(pPlayer->GetClass() == PLAYERCLASS_NONE) { pPlayer->SetClass(ChooseHumanClass(pPlayer)); if(pPlayer->GetCharacter()) pPlayer->GetCharacter()->IncreaseArmor(10); } } //If needed, infect players int nbInfectedNeeded = 2; if(m_InfectedCounter + m_HumanCounter < 4) { nbInfectedNeeded = 1; } while(m_InfectedCounter < nbInfectedNeeded) { float InfectionProb = 1.0/static_cast<float>(m_HumanCounter); float random = frandom(); //Fair infection bool FairInfectionFound = false; for(int i = 0; i < MAX_CLIENTS; i ++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue; if(pPlayer->IsInfected()) continue; if(!Server()->IsClientInfectedBefore(i)) { Server()->InfecteClient(i); GameServer()->m_apPlayers[i]->StartInfection(); m_InfectedCounter++; m_HumanCounter--; GameServer()->SendChatTarget_Language_s(-1, "%s has been infected", Server()->ClientName(i)); FairInfectionFound = true; break; } } //Unfair infection if(!FairInfectionFound) { for(int i = 0; i < MAX_CLIENTS; i ++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue; if(pPlayer->IsInfected()) continue; if(random < InfectionProb) { Server()->InfecteClient(i); GameServer()->m_apPlayers[i]->StartInfection(); m_InfectedCounter++; m_HumanCounter--; GameServer()->SendChatTarget_Language_s(-1, "%s has been infected", Server()->ClientName(i)); break; } else { random -= InfectionProb; } } } } } else { for(int i = 0; i < MAX_CLIENTS; i ++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; if(pPlayer->GetTeam() == TEAM_SPECTATORS) { pPlayer->SetClass(PLAYERCLASS_NONE); } } } //Win check if(m_InfectedStarted && m_HumanCounter == 0 && m_InfectedCounter > 1) { float RoundDuration = static_cast<float>((Server()->Tick()-m_RoundStartTick)/((float)Server()->TickSpeed()))/60.0f; int Minutes = static_cast<int>(RoundDuration); int Seconds = static_cast<int>((RoundDuration - Minutes)*60.0f); GameServer()->SendChatTarget_Language_ii(-1, "Infected won the round in %i:%02i minutes", Minutes, Seconds); EndRound(); } //Start the final explosion if the time is over if(m_InfectedStarted && !m_ExplosionStarted && g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60) { for(CCharacter *p = (CCharacter*) GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER); p; p = (CCharacter *)p->TypeNext()) { if(p->IsInfected()) { GameServer()->SendEmoticon(p->GetPlayer()->GetCID(), EMOTICON_GHOST); } else { GameServer()->SendEmoticon(p->GetPlayer()->GetCID(), EMOTICON_EYES); } } m_ExplosionStarted = true; } //Do the final explosion if(m_ExplosionStarted) { bool NewExplosion = false; for(int j=0; j<m_MapHeight; j++) { for(int i=0; i<m_MapWidth; i++) { if((m_GrowingMap[j*m_MapWidth+i] & 1) && ( (i > 0 && m_GrowingMap[j*m_MapWidth+i-1] & 2) || (i < m_MapWidth-1 && m_GrowingMap[j*m_MapWidth+i+1] & 2) || (j > 0 && m_GrowingMap[(j-1)*m_MapWidth+i] & 2) || (j < m_MapHeight-1 && m_GrowingMap[(j+1)*m_MapWidth+i] & 2) )) { NewExplosion = true; m_GrowingMap[j*m_MapWidth+i] |= 8; m_GrowingMap[j*m_MapWidth+i] &= ~1; if(rand()%10 == 0) { vec2 TilePos = vec2(16.0f, 16.0f) + vec2(i*32.0f, j*32.0f); GameServer()->CreateExplosion(TilePos, -1, WEAPON_GAME, true); GameServer()->CreateSound(TilePos, SOUND_GRENADE_EXPLODE); } } } } for(int j=0; j<m_MapHeight; j++) { for(int i=0; i<m_MapWidth; i++) { if(m_GrowingMap[j*m_MapWidth+i] & 8) { m_GrowingMap[j*m_MapWidth+i] &= ~8; m_GrowingMap[j*m_MapWidth+i] |= 2; } } } for(CCharacter *p = (CCharacter*) GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER); p; p = (CCharacter *)p->TypeNext()) { if(!p->IsInfected()) continue; int tileX = static_cast<int>(round(p->m_Pos.x))/32; int tileY = static_cast<int>(round(p->m_Pos.y))/32; if(tileX < 0) tileX = 0; if(tileX >= m_MapWidth) tileX = m_MapWidth-1; if(tileY < 0) tileY = 0; if(tileY >= m_MapHeight) tileY = m_MapHeight-1; if(m_GrowingMap[tileY*m_MapWidth+tileX] & 2 && p->GetPlayer()) { p->Die(p->GetPlayer()->GetCID(), WEAPON_GAME); } } //If no more explosions, game over, decide who win if(!NewExplosion) { if(m_HumanCounter) { if(m_HumanCounter <= 1) { GameServer()->SendChatTarget_Language(-1, "One human won the round"); } else { GameServer()->SendChatTarget_Language_i(-1, "%i humans won the round", m_HumanCounter); } for(int i = 0; i < MAX_CLIENTS; i ++) { CPlayer *pPlayer = GameServer()->m_apPlayers[i]; if(!pPlayer) continue; if(pPlayer->GetTeam() == TEAM_SPECTATORS) continue; if(!pPlayer->IsInfected()) { pPlayer->IncreaseScore(5); pPlayer->m_WinAsHuman++; GameServer()->SendChatTarget_Language(i, "You have survived, +5 points"); } } } else { GameServer()->SendChatTarget_Language_ii(-1, "Infected won the round in %i:%02i minutes", g_Config.m_SvTimelimit, 0); } EndRound(); } } } else { m_RoundStartTick = Server()->Tick(); } }
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(); } }
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; }
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::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); } } } } } }
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 CAnimal::TickBotAI() { //Sounds if (Server()->Tick() - m_BotTimeLastSound > Server()->TickSpeed()*5.0f) { if (m_pPlayer->GetTeam() == TEAM_ANIMAL_TEECOW) GameServer()->CreateSound(m_Pos, SOUND_ANIMAL_TEECOW); m_BotTimeLastSound = Server()->Tick(); } //Clean m_Input m_Input.m_Hook = 0; m_Input.m_Fire = 0; m_Input.m_Jump = 0; //Interact with users bool PlayerClose = false; bool PlayerFound = false; float LessDist = 500.0f; m_BotClientIDFix = -1; for (int i=0; i<MAX_CLIENTS-MAX_BOTS; 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 (Dist < 280.0f) { if (Dist > 120.0f) { vec2 DirPlayer = normalize(pPlayer->GetCharacter()->m_Pos - m_Pos); bool isHooked = false; for (int e=0; e<MAX_CLIENTS-MAX_BOTS; e++) { if (!GameServer()->m_apPlayers[e] || !GameServer()->m_apPlayers[e]->GetCharacter()) continue; int HookedPL = GameServer()->m_apPlayers[e]->GetCharacter()->GetCore()->m_HookedPlayer; if (HookedPL < 0 || HookedPL != m_pPlayer->GetCID() || !GameServer()->m_apPlayers[HookedPL]) continue; if (GameServer()->m_apPlayers[HookedPL]->GetTeam() == TEAM_ANIMAL_TEECOW || GameServer()->m_apPlayers[HookedPL]->GetTeam() == TEAM_ANIMAL_TEEPIG) { isHooked = true; break; } } m_BotDir = 0; } else PlayerClose = true; 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; } //Random Actions to animals 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(); // Fluids if (GameServer()->m_BlockManager.IsFluid(GameServer()->Collision()->GetMineTeeTileAt(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(); //Set data m_Input.m_Direction = m_BotDir; m_Input.m_PlayerFlags = PLAYERFLAG_PLAYING; //Check for legacy input if (m_LatestInput.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_Input; m_BotLastPos = m_Pos; }