void CGameContext::ConFreeze(IConsole::IResult *pResult, void *pUserData) { if(!CheckRights(pResult->m_ClientID, pResult->GetVictim(), (CGameContext *)pUserData)) return; CGameContext *pSelf = (CGameContext *)pUserData; int Seconds = -1; int Victim = pResult->GetVictim(); char aBuf[128]; if(pResult->NumArguments() == 1) Seconds = clamp(pResult->GetInteger(0), -2, 9999); CCharacter* pChr = pSelf->GetPlayerChar(Victim); if(!pChr) return; if(pSelf->m_apPlayers[Victim]) { pChr->Freeze(Seconds); pChr->GetPlayer()->m_RconFreeze = Seconds != -2; CServer* pServ = (CServer*)pSelf->Server(); if(Seconds >= 0) str_format(aBuf, sizeof(aBuf), "'%s' ClientID=%d has been Frozen for %d.", pServ->ClientName(Victim), Victim, Seconds); else if(Seconds == -2) { pChr->m_DeepFreeze = true; str_format(aBuf, sizeof(aBuf), "'%s' ClientID=%d has been Deep Frozen.", pServ->ClientName(Victim), Victim); } else str_format(aBuf, sizeof(aBuf), "'%s' ClientID=%d is Frozen until you unfreeze him.", pServ->ClientName(Victim), Victim); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", aBuf); } }
void CGameControllerSoloFNG::DoHookers() { for(int i = 0; i < MAX_CLIENTS; i++) { CCharacter *pChr = CHAR(i); if (!pChr) continue; int Hooking = pChr->GetHookedPlayer(); if (Hooking >= 0) { CCharacter *pVic = CHAR(Hooking); if (!pVic || (/*pVic->GetPlayer()->GetTeam() != pChr->GetPlayer()->GetTeam() && */pChr->GetHookTick() < CFG(HookRegisterDelay))) Hooking = -1; } int HammeredBy = pChr->LastHammeredBy(); pChr->ClearLastHammeredBy(); if (Hooking >= 0) { CCharacter *pVic = CHAR(Hooking); if (pVic) { //bool SameTeam = pChr->GetPlayer()->GetTeam() == pVic->GetPlayer()->GetTeam(); m_aLastInteraction[Hooking] = /*SameTeam ? -1 : */ i; } } if (HammeredBy >= 0) { CCharacter *pHam = CHAR(HammeredBy); if (pHam) { //bool SameTeam = pChr->GetPlayer()->GetTeam() == pHam->GetPlayer()->GetTeam(); m_aLastInteraction[i] = /*SameTeam ? -1 : */ HammeredBy; if (/* !SameTeam &&*/ CFG(HammerFreeze) && pChr->GetFreezeTicks() <= 0) { pChr->Freeze(CFG(HammerFreeze) * TS, HammeredBy); m_aFrozenBy[i] = HammeredBy; //suppress kill event being generated } } else m_aLastInteraction[i] = -1; } } }
bool CPlasma::HitCharacter() { vec2 To2; CCharacter *Hit = GameServer()->m_World.IntersectCharacter(m_Pos, m_Pos + m_Core, 0.0f, To2); if (!Hit) return false; if (Hit->Team() != m_ResponsibleTeam) return false; m_Freeze ? Hit->Freeze() : Hit->UnFreeze(); if (m_Explosive) GameServer()->CreateExplosion(m_Pos, -1, WEAPON_GRENADE, true, m_ResponsibleTeam, Hit->Teams()->TeamMask(m_ResponsibleTeam)); GameServer()->m_World.DestroyEntity(this); return true; }
void CGameControllerOpenFNG::DoHookers() { for(int i = 0; i < MAX_CLIENTS; i++) { CCharacter *pChr = CHAR(i); if (!pChr) continue; int Hooking = pChr->GetHookedPlayer(); if (Hooking >= 0) { CCharacter *pVic = CHAR(Hooking); if (!pVic || (pVic->GetPlayer()->GetTeam() != pChr->GetPlayer()->GetTeam() && pChr->GetHookTick() < CFG(HookRegisterDelay))) Hooking = -1; } int HammeredBy = pChr->LastHammeredBy(); pChr->ClearLastHammeredBy(); if (Hooking >= 0) { CCharacter *pVic = CHAR(Hooking); if (pVic) { bool SameTeam = pChr->GetPlayer()->GetTeam() == pVic->GetPlayer()->GetTeam(); m_aLastInteraction[Hooking] = SameTeam ? -1 : i; } } /* CPlayer *pPlayer = TPLAYER(Hooking); if (pVic) { bool SameTeam = pChr->GetPlayer()->GetTeam() == pVic->GetPlayer()->GetTeam(); m_aLastInteraction[Hooking] = SameTeam ? -1 : i; if(pPlayer) { if (!SameTeam && CFG(HammerFreeze) && pVic->GetFreezeTicks() <= 0) { pVic->Freeze(CFG(HammerFreeze) * TS, i); m_aFrozenBy[Hooking] = i; //suppress kill event being generated } } } */ if (HammeredBy >= 0) { CCharacter *pHam = CHAR(HammeredBy); CPlayer *pPlayer = TPLAYER(HammeredBy); if (pHam) { bool SameTeam = pChr->GetPlayer()->GetTeam() == pHam->GetPlayer()->GetTeam(); m_aLastInteraction[i] = SameTeam ? -1 : HammeredBy; if(pPlayer) { if (!SameTeam && CFG(HammerFreeze) && pChr->GetFreezeTicks() <= 0 && pPlayer->m_HammerFreeze) { pChr->Freeze(CFG(HammerFreeze) * TS, HammeredBy); m_aFrozenBy[i] = HammeredBy; //suppress kill event being generated } } } else m_aLastInteraction[i] = -1; } } }
void CGameControllerOpenFNG::DoInteractions() { DoHookers(); for(int i = 0; i < MAX_CLIENTS; i++) { CCharacter *pChr = CHAR(i); if (!pChr) continue; int FrzTicks = pChr->GetFreezeTicks(); int Col = GameServer()->Collision()->GetCollisionAt(pChr->m_Pos.x, pChr->m_Pos.y); if (Col == TILE_SHRINE_ALL || Col == TILE_SHRINE_RED || Col == TILE_SHRINE_BLUE) { if (FrzTicks > 0 && m_aLastInteraction[i] < 0) pChr->Freeze(FrzTicks = 0); bool WasSacrificed = false; if (FrzTicks > 0) { int ShrineTeam = Col == TILE_SHRINE_RED ? TEAM_RED : Col == TILE_SHRINE_BLUE ? TEAM_BLUE : -1; HandleSacr(m_aLastInteraction[i], i, ShrineTeam); WasSacrificed = true; } pChr->Die(pChr->GetPlayer()->GetCID(), WEAPON_WORLD, WasSacrificed); } if (FrzTicks > 0) { if ((FrzTicks+1) % TS == 0) { int mask = -1; if (!CFG(MeltShowAll)) mask = (int)~m_aCltMask[1-(pChr->GetPlayer()->GetTeam()&1)]; GS->CreateDamageInd(pChr->m_Pos, 0, (FrzTicks+1) / TS, mask); if (CFG(ClickyMelt)) { mask = -1; if (CFG(ClickyMelt) == 1) mask = (int)m_aCltMask[1-(pChr->GetPlayer()->GetTeam()&1)]; GS->CreateSound(pChr->m_Pos, SOUND_WEAPON_NOAMMO, mask); } } if (FrzTicks == 1 && CFG(MeltSafeticks)) pChr->SetEmote(EMOTE_SURPRISE, TICK + CFG(MeltSafeticks) + 1); m_aMoltenBy[i] = -1; if (m_aFrozenBy[i] != -1) continue; int Killer = pChr->WasFrozenBy(); if (Killer < 0) //may happen then the gods are not pleased { m_aFrozenBy[i] = -1; continue; } m_aFrozenBy[i] = Killer; HandleFreeze(Killer, i); } else { m_aFrozenBy[i] = -1; int Melter = pChr->WasMoltenBy(); if (Melter < 0) m_aMoltenBy[i] = -1; if (Melter == m_aMoltenBy[i]) continue; m_aMoltenBy[i] = Melter; HandleMelt(Melter, i); } } }
void CPickup::Tick() { Move(); /*// wait for respawn if(m_SpawnTick > 0) { if(Server()->Tick() > m_SpawnTick) { // respawn m_SpawnTick = -1; if(m_Type == POWERUP_WEAPON) GameServer()->CreateSound(m_Pos, SOUND_WEAPON_SPAWN); } else return; }*/ // Check if a player intersected us CCharacter *apEnts[MAX_CLIENTS]; int Num = GameWorld()->FindEntities(m_Pos, 20.0f, (CEntity**)apEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER); for(int i = 0; i < Num; ++i) { CCharacter * pChr = apEnts[i]; if(pChr && pChr->IsAlive()) { if(m_Layer == LAYER_SWITCH && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[pChr->Team()]) continue; bool sound = false; // player picked us up, is someone was hooking us, let them go switch (m_Type) { case POWERUP_HEALTH: if(pChr->Freeze()) GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH, pChr->Teams()->TeamMask(pChr->Team())); break; case POWERUP_ARMOR: if(pChr->Team() == TEAM_SUPER) continue; for(int i = WEAPON_SHOTGUN; i < NUM_WEAPONS; i++) { if(pChr->GetWeaponGot(i)) { if(!(pChr->m_FreezeTime && i == WEAPON_NINJA)) { pChr->SetWeaponGot(i, false); pChr->SetWeaponAmmo(i, 0); sound = true; } } } pChr->SetNinjaActivationDir(vec2(0,0)); pChr->SetNinjaActivationTick(-500); pChr->SetNinjaCurrentMoveTime(0); if (sound) { pChr->SetLastWeapon(WEAPON_GUN); GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR, pChr->Teams()->TeamMask(pChr->Team())); } if(!pChr->m_FreezeTime && pChr->GetActiveWeapon() >= WEAPON_SHOTGUN) pChr->SetActiveWeapon(WEAPON_HAMMER); break; case POWERUP_WEAPON: if (m_Subtype >= 0 && m_Subtype < NUM_WEAPONS && (!pChr->GetWeaponGot(m_Subtype) || (pChr->GetWeaponAmmo(m_Subtype) != -1 && !pChr->m_FreezeTime))) { pChr->GiveWeapon(m_Subtype); //RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime; if (m_Subtype == WEAPON_GRENADE) GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE, pChr->Teams()->TeamMask(pChr->Team())); else if (m_Subtype == WEAPON_SHOTGUN) GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN, pChr->Teams()->TeamMask(pChr->Team())); else if (m_Subtype == WEAPON_RIFLE) GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN, pChr->Teams()->TeamMask(pChr->Team())); if (pChr->GetPlayer()) GameServer()->SendWeaponPickup(pChr->GetPlayer()->GetCID(), m_Subtype); } break; case POWERUP_NINJA: { // activate ninja on target player pChr->GiveNinja(); //RespawnTime = g_pData->m_aPickups[m_Type].m_Respawntime; /*// loop through all players, setting their emotes CCharacter *pC = static_cast<CCharacter *>(GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_CHARACTER)); for(; pC; pC = (CCharacter *)pC->TypeNext()) { if (pC != pChr) pC->SetEmote(EMOTE_SURPRISE, Server()->Tick() + Server()->TickSpeed()); }*/ break; } default: break; }; /*if(RespawnTime >= 0) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "pickup player='%d:%s' item=%d/%d", pChr->GetPlayer()->GetCID(), Server()->ClientName(pChr->GetPlayer()->GetCID()), m_Type, m_Subtype); GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); m_SpawnTick = Server()->Tick() + Server()->TickSpeed() * RespawnTime; }*/ } } }
void CProjectile::Tick() { float Pt = (Server()->Tick()-m_StartTick-1)/(float)Server()->TickSpeed(); float Ct = (Server()->Tick()-m_StartTick)/(float)Server()->TickSpeed(); vec2 PrevPos = GetPos(Pt); vec2 CurPos = GetPos(Ct); vec2 ColPos; vec2 NewPos; int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &ColPos, &NewPos, false); CCharacter *pOwnerChar = 0; if(m_Owner >= 0) pOwnerChar = GameServer()->GetPlayerChar(m_Owner); CCharacter *pTargetChr = GameServer()->m_World.IntersectCharacter(PrevPos, ColPos, m_Freeze ? 1.0f : 6.0f, ColPos, pOwnerChar); if(m_LifeSpan > -1) m_LifeSpan--; int TeamMask = -1; bool isWeaponCollide = false; if ( pOwnerChar && pTargetChr && pOwnerChar->IsAlive() && pTargetChr->IsAlive() && !pTargetChr->CanCollide(m_Owner) ) { isWeaponCollide = true; //TeamMask = OwnerChar->Teams()->TeamMask( OwnerChar->Team()); } if (pOwnerChar && pOwnerChar->IsAlive()) { TeamMask = pOwnerChar->Teams()->TeamMask(pOwnerChar->Team(), -1, m_Owner); } if( ((pTargetChr && (pOwnerChar ? !(pOwnerChar->m_Hit&CCharacter::DISABLE_HIT_GRENADE) : g_Config.m_SvHit || m_Owner == -1 || pTargetChr == pOwnerChar)) || Collide || GameLayerClipped(CurPos)) && !isWeaponCollide) { if(m_Explosive/*??*/ && (!pTargetChr || (pTargetChr && !m_Freeze))) { GameServer()->CreateExplosion(ColPos, m_Owner, m_Weapon, m_Owner == -1, (!pTargetChr ? -1 : pTargetChr->Team()), (m_Owner != -1)? TeamMask : -1); GameServer()->CreateSound(ColPos, m_SoundImpact, (m_Owner != -1)? TeamMask : -1); } else if(pTargetChr && m_Freeze && ((m_Layer == LAYER_SWITCH && GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[pTargetChr->Team()]) || m_Layer != LAYER_SWITCH)) pTargetChr->Freeze(); if(Collide && m_Bouncing != 0) { m_StartTick = Server()->Tick(); m_Pos = NewPos+(-(m_Direction*4)); if (m_Bouncing == 1) m_Direction.x = -m_Direction.x; else if(m_Bouncing == 2) m_Direction.y =- m_Direction.y; if (fabs(m_Direction.x) < 1e-6) m_Direction.x = 0; if (fabs(m_Direction.y) < 1e-6) m_Direction.y = 0; m_Pos += m_Direction; } else if (m_Weapon == WEAPON_GUN) { GameServer()->CreateDamageInd(CurPos, -atan2(m_Direction.x, m_Direction.y), 10, (m_Owner != -1)? TeamMask : -1); GameServer()->m_World.DestroyEntity(this); } else if (!m_Freeze) GameServer()->m_World.DestroyEntity(this); } if(m_LifeSpan == -1) { GameServer()->m_World.DestroyEntity(this); } }
void CCharacter::FireWeapon() { if(m_ReloadTimer != 0) return; DoWeaponSwitch(); vec2 Direction = normalize(vec2(m_LatestInput.m_TargetX, m_LatestInput.m_TargetY)); bool FullAuto = false; if(m_ActiveWeapon == WEAPON_GRENADE || m_ActiveWeapon == WEAPON_SHOTGUN || m_ActiveWeapon == WEAPON_RIFLE || (m_ActiveWeapon == WEAPON_HAMMER && g_Config.m_SvSuperHammer)) FullAuto = true; // check if we gonna fire bool WillFire = false; if(CountInput(m_LatestPrevInput.m_Fire, m_LatestInput.m_Fire).m_Presses) WillFire = true; if(FullAuto && (m_LatestInput.m_Fire&1) && m_aWeapons[m_ActiveWeapon].m_Ammo) WillFire = true; if (!g_Config.m_SvNinja && m_ActiveWeapon == WEAPON_NINJA) WillFire = false; if(!WillFire) return; // check for ammo if(!m_aWeapons[m_ActiveWeapon].m_Ammo) { // 125ms is a magical limit of how fast a human can click m_ReloadTimer = 125 * Server()->TickSpeed() / 1000; GameServer()->CreateSound(m_Pos, SOUND_WEAPON_NOAMMO); return; } vec2 ProjStartPos = m_Pos+Direction*m_ProximityRadius*0.75f; switch(m_ActiveWeapon) { case WEAPON_HAMMER: { // reset objects Hit m_NumObjectsHit = 0; GameServer()->CreateSound(m_Pos, SOUND_HAMMER_FIRE); CCharacter *apEnts[MAX_CLIENTS]; int Hits = 0; int Num = GameServer()->m_World.FindEntities(ProjStartPos, m_ProximityRadius*0.5f, (CEntity**)apEnts, MAX_CLIENTS, CGameWorld::ENTTYPE_CHARACTER); for (int i = 0; i < Num; ++i) { CCharacter *pTarget = apEnts[i]; if ((pTarget == this) || GameServer()->Collision()->IntersectLine(ProjStartPos, pTarget->m_Pos, NULL, NULL)) continue; // set his velocity to fast upward (for now) if(length(pTarget->m_Pos-ProjStartPos) > 0.0f) GameServer()->CreateHammerHit(pTarget->m_Pos-normalize(pTarget->m_Pos-ProjStartPos)*m_ProximityRadius*0.5f); else GameServer()->CreateHammerHit(ProjStartPos); vec2 Dir; if (length(pTarget->m_Pos - m_Pos) > 0.0f) Dir = normalize(pTarget->m_Pos - m_Pos); else Dir = vec2(0.f, -1.f); bool MeltHit = GameServer()->m_pController->IsTeamplay() && pTarget->GetPlayer()->GetTeam() == GetPlayer()->GetTeam() && pTarget->GetFreezeTicks() > 0; vec2 Force = (vec2(0.f, -1.f) + normalize(Dir + vec2(0.f, -1.1f)) * 10.0f); if (!MeltHit) { Force.x *= g_Config.m_SvHammerScaleX*0.01f; Force.y *= g_Config.m_SvHammerScaleY*0.01f; } else { Force.x *= g_Config.m_SvMeltHammerScaleX*0.01f; Force.y *= g_Config.m_SvMeltHammerScaleY*0.01f; } pTarget->TakeDamage(Force, g_pData->m_Weapons.m_Hammer.m_pBase->m_Damage, m_pPlayer->GetCID(), m_ActiveWeapon); Hits++; pTarget->m_HammeredBy = GetPlayer()->GetCID(); if (MeltHit) { pTarget->Freeze(pTarget->GetFreezeTicks() - g_Config.m_SvHammerMelt * Server()->TickSpeed()); if (pTarget->GetFreezeTicks() <= 0) { pTarget->m_MoltenBy = m_pPlayer->GetCID(); pTarget->m_MoltenAt = -1; // we don't want the unfreezability to take effect when being molten by hammer } } } // if we Hit anything, we have to wait for the reload if(Hits) m_ReloadTimer = Server()->TickSpeed()/3; } break; case WEAPON_GUN: { CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GUN, m_pPlayer->GetCID(), ProjStartPos, Direction, (int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GunLifetime), 1, 0, 0, -1, WEAPON_GUN); // pack the Projectile and send it to the client Directly CNetObj_Projectile p; pProj->FillInfo(&p); CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE); Msg.AddInt(1); for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++) Msg.AddInt(((int *)&p)[i]); Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID()); GameServer()->CreateSound(m_Pos, SOUND_GUN_FIRE); } break; case WEAPON_SHOTGUN: { int ShotSpread = 2; CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE); Msg.AddInt(ShotSpread*2+1); for(int i = -ShotSpread; i <= ShotSpread; ++i) { float Spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f}; float a = GetAngle(Direction); a += Spreading[i+2]; float v = 1-(absolute(i)/(float)ShotSpread); float Speed = mix((float)GameServer()->Tuning()->m_ShotgunSpeeddiff, 1.0f, v); CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_SHOTGUN, m_pPlayer->GetCID(), ProjStartPos, vec2(cosf(a), sinf(a))*Speed, (int)(Server()->TickSpeed()*GameServer()->Tuning()->m_ShotgunLifetime), 1, 0, 0, -1, WEAPON_SHOTGUN); // pack the Projectile and send it to the client Directly CNetObj_Projectile p; pProj->FillInfo(&p); for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++) Msg.AddInt(((int *)&p)[i]); } Server()->SendMsg(&Msg, 0,m_pPlayer->GetCID()); GameServer()->CreateSound(m_Pos, SOUND_SHOTGUN_FIRE); } break; case WEAPON_GRENADE: { CProjectile *pProj = new CProjectile(GameWorld(), WEAPON_GRENADE, m_pPlayer->GetCID(), ProjStartPos, Direction, (int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GrenadeLifetime), 1, true, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE); // pack the Projectile and send it to the client Directly CNetObj_Projectile p; pProj->FillInfo(&p); CMsgPacker Msg(NETMSGTYPE_SV_EXTRAPROJECTILE); Msg.AddInt(1); for(unsigned i = 0; i < sizeof(CNetObj_Projectile)/sizeof(int); i++) Msg.AddInt(((int *)&p)[i]); Server()->SendMsg(&Msg, 0, m_pPlayer->GetCID()); GameServer()->CreateSound(m_Pos, SOUND_GRENADE_FIRE); } break; case WEAPON_RIFLE: { new CLaser(GameWorld(), m_Pos, Direction, GameServer()->Tuning()->m_LaserReach, m_pPlayer->GetCID()); GameServer()->CreateSound(m_Pos, SOUND_RIFLE_FIRE); } break; case WEAPON_NINJA: { // reset Hit objects m_NumObjectsHit = 0; m_Ninja.m_ActivationDir = Direction; m_Ninja.m_CurrentMoveTime = g_pData->m_Weapons.m_Ninja.m_Movetime * Server()->TickSpeed() / 1000; m_Ninja.m_OldVelAmount = length(m_Core.m_Vel); GameServer()->CreateSound(m_Pos, SOUND_NINJA_FIRE); } break; } m_AttackTick = Server()->Tick(); if (!g_Config.m_SvUnlimitedAmmo && m_aWeapons[m_ActiveWeapon].m_Ammo > 0) m_aWeapons[m_ActiveWeapon].m_Ammo--; if(!m_ReloadTimer) m_ReloadTimer = g_pData->m_Weapons.m_aId[m_ActiveWeapon].m_Firedelay * Server()->TickSpeed() / 1000; }