Beispiel #1
0
void StrongCharacter::OnKeyDown(SDL_KeyboardEvent *evt)
{
    if (fixed_) return;

    switch (evt->keysym.sym) {
        case SDLK_LEFT:
            state_ |= kMoveLeft;
            break;
        case SDLK_RIGHT:
            state_ |= kMoveRight;
            break;
        case SDLK_SPACE:
            if (IsGrounded()) {
                state_ |= kJump;
                body_->ApplyLinearImpulse(b2Vec2(0, jump_speed_), body_->GetWorldCenter());
            }
            break;
        case SDLK_a:
            if (IsGrounded()) {
                state_ |= kAction;
                Character *overlap = GetOverlapping();
                if (overlap) {
                    grab_ = true;
                    grabbed_character_ = overlap;
                    grabbed_character_->Freeze();
                    CreateGrabJoint(grabbed_character_->body());
                }
            }
        default:
            break;
    }
}
Beispiel #2
0
void StrongCharacter::Step(double time)
{
    animation_->Step(time);

    if (!grab_ && !(state_ & kAction)) {
        DoWalk(time);
    } else {
        double dir = direction_ == kLeft ? -1 : 1; 
        if (state_ & kMoveLeft) {
            launch_angle_ += dir * time / 2 * 90;
        } else if (state_ & kMoveRight) {
            launch_angle_ -= dir * time / 2 * 90;
        }

        if (launch_angle_ < 0) {
            launch_angle_ = 0;
        } else if (launch_angle_ > 80) {
            launch_angle_ = 80;
        }
    }

    if (state_ & kAction) {
        animation_->SetState("grab");
    } else if (IsGrounded() && !(state_ & (kMoveLeft | kMoveRight))) {
        animation_->SetState("stand");
    }

}
Beispiel #3
0
bool CComputer::IsOff() {

	m_lock.lock();
	bool bStat = false;
	do
	{
	if(IsNetCutDefender())
		break;

	if (IsSpeedLimit()||IsGrounded())
		bStat = true;

	}while(false);

	m_lock.unlock();
	return bStat;

}
void CCharacter::Tick()
{
	if(m_pPlayer->m_ForceBalanced)
	{
		char Buf[128];
		str_format(Buf, sizeof(Buf), "You were moved to %s due to team balancing", GameServer()->m_pController->GetTeamName(m_pPlayer->GetTeam()));
		GameServer()->SendBroadcast(Buf, m_pPlayer->GetCID());

		m_pPlayer->m_ForceBalanced = false;
	}

	m_Core.m_Input = m_Input;
	m_Core.Tick(true);

	// handle death-tiles and leaving gamelayer
	if(GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
		GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
		GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y-m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
		GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/3.f, m_Pos.y+m_ProximityRadius/3.f)&CCollision::COLFLAG_DEATH ||
		GameLayerClipped(m_Pos))
	{
		Die(m_pPlayer->GetCID(), WEAPON_WORLD);
	}

	// handle Weapons
	HandleWeapons();

/* INFECTION MODIFICATION START ***************************************/
	if(GetClass() == PLAYERCLASS_HUNTER)
	{
		if(IsGrounded()) m_AirJumpCounter = 0;
		if(m_Core.m_TriggeredEvents&COREEVENT_AIR_JUMP && m_AirJumpCounter < 1)
		{
			m_Core.m_Jumped &= ~2;
			m_AirJumpCounter++;
		}
	}
	
	if(m_pClassChooser)
	{
		if(GetClass() != PLAYERCLASS_NONE)
		{
			GameServer()->m_World.DestroyEntity(m_pClassChooser);
			m_pClassChooser = 0;
		}
		else
		{
			m_pClassChooser->m_Pos = m_Pos;
			m_pClassChooser->SetCursor(vec2(m_Input.m_TargetX, m_Input.m_TargetY));
			
			if(m_Input.m_Fire&1)
			{
				int ccRes = m_pClassChooser->SelectClass();
				if(ccRes)
				{				
					GameServer()->m_World.DestroyEntity(m_pClassChooser);
					m_pClassChooser = 0;
					
					m_pPlayer->SetClass(ccRes);
				}
			}
		}
	}
/* INFECTION MODIFICATION END *****************************************/

	// Previnput
	m_PrevInput = m_Input;
	return;
}
Beispiel #5
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();
}
Beispiel #6
0
void CBuilding::Tick()
{
	// handle death-tiles and leaving gamelayer
	if(GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/2.f, m_Pos.y-m_ProximityRadius/2.f)&CCollision::COLFLAG_DEATH ||
		GameServer()->Collision()->GetCollisionAt(m_Pos.x+m_ProximityRadius/2.f, m_Pos.y+m_ProximityRadius/2.f)&CCollision::COLFLAG_DEATH ||
		GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/2.f, m_Pos.y-m_ProximityRadius/2.f)&CCollision::COLFLAG_DEATH ||
		GameServer()->Collision()->GetCollisionAt(m_Pos.x-m_ProximityRadius/2.f, m_Pos.y+m_ProximityRadius/2.f)&CCollision::COLFLAG_DEATH ||
		GameLayerClipped(m_Pos))
	{
		Die(-1, WEAPON_WORLD);
		return;
	}
	
	if(!IsGrounded()) {
		Die(-1, WEAPON_WORLD);
		return;
	}
	
	
	
	if(Server()->Tick() % 5 == 0 && m_Decon) {
		if( ((CGameControllerNODES*)GameServer()->m_pController)->Spawns[m_Team] <= 0)
		{
			m_Decon = false;
		} else {
			TakeDamage(vec2(0,0), 1, -1, WEAPON_SELF);
		}
	}
		
	if(m_Decay > 0)
		m_Decay--;
		
	if(m_AnimDecay > 0)
		m_AnimDecay--;
		
	if(m_SpawnanimDecay > 0)
		m_SpawnanimDecay--;

	m_Power = Powered();

	if(!m_Power && (m_Type == B_REPEATER || m_Type == B_TELEPORT))
		m_Anim = 0;
	
	if(!m_Power)
		m_Hit = 0;
		
	
		
	if(!m_Power && m_Type == B_TELEPORT)
		m_Anim = 0;

	if(!m_Alive || (!m_Power && m_Type != B_SHIELD))
		return;

	if(Server()->Tick() % 100 == 0 && m_Health < m_Maxhealth/4) {
		GameServer()->CreateExplosion(pos, -1, -1, true);
		
	}	
	
	switch(m_Type) {
		case B_REACTOR: {
			if(m_AnimDecay == 0) {
				m_Anim++;
				if(m_Anim > 3) {
					m_Anim = 0;
					m_AnimDecay = 100;
				} else
					m_AnimDecay = 10;
			}
		} break;
		
		case B_REPEATER: {
			if(!m_Power) {
				m_Anim = 0;
			} else {
				if(m_AnimDecay == 0) {
					m_Anim++;
					if(m_Anim > 1) {
						m_Anim = 0;
						m_AnimDecay = 100;
					} else
						m_AnimDecay = 10;
				}
			}
		} break;
		
		case B_SPAWN: {
			m_Anim = m_Anim & 0xF;
			if(m_AnimDecay == 0) {
				m_Anim++;
				if(m_Anim > 6)
					m_Anim = 0;
				m_AnimDecay = 35;
			}
			if(m_Spawnanim > 0 && m_SpawnanimDecay == 0) {
				m_Spawnanim--;
				m_SpawnanimDecay = 4;
			}
			m_Anim = (m_Spawnanim << 4) | m_Anim;
		} break;
		case B_AMMO1: case B_AMMO2: case B_AMMO3: {
			CCharacter *c = GetNearest(ms_PhysSize, m_Team);
			if(c) {
				if(m_Anim < 3 && m_AnimDecay == 0) {
					m_Anim++;
					m_AnimDecay = 4;
				}
				if(m_Decay == 0 && m_Anim == 3) {
					m_Decay = 50;
					int weapon = -1;
					if(m_Type == B_AMMO1)
						weapon = WEAPON_SHOTGUN;
					else if(m_Type == B_AMMO2) 
						weapon = WEAPON_GRENADE;
					else if(m_Type == B_AMMO3)
						weapon = WEAPON_RIFLE;
					if(!c->m_Weapons[weapon].m_Got) {
						c->m_Weapons[weapon].m_Got = 1;	
						c->m_ActiveWeapon = weapon;
						GameServer()->CreateSound(m_Pos, SOUND_PICKUP_SHOTGUN);
					} else {
						GameServer()->CreateSound(m_Pos, SOUND_PICKUP_GRENADE);
					}
					c->m_Weapons[weapon].m_Ammo = 10;
				}
			}
			else {
				if(m_Anim > 0 && m_AnimDecay == 0) {
					m_Anim--;
					m_AnimDecay = 4;
				}
			}
		} break;
		
		case B_TURRET1: {
			vec2 realpos = vec2(m_Pos.x, m_Pos.y-74);
			vec2 tmppos = m_Pos;
			m_Pos = realpos;
			CCharacter *c = GetNearest(700, m_Team^1);
			m_Pos = tmppos;
			if(c) {
				m_Angle = GetAngle(normalize(c->m_Pos - realpos));
				if(m_Decay == 0) {
					m_Decay = 12;
						float a = m_Angle;
						a+=frandom()*0.20f -0.10f;
						CProjectile *pProj = new CProjectile(WEAPON_GUN,
							-1,
							realpos,
							vec2(cosf(a), sinf(a)),
							(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_GunLifetime),
							1, 0, 0, -1, WEAPON_GUN, false);
					GameServer()->CreateSound(realpos, SOUND_GUN_FIRE);
				}
			}
		} break;
		
		case B_TURRET2: {
			vec2 realpos = vec2(m_Pos.x, m_Pos.y-66);
			vec2 tmppos = m_Pos;
			m_Pos = realpos;
			CCharacter *c = GetNearest(500, m_Team^1);
			m_Pos = tmppos;
			if(c) {
				m_Angle = GetAngle(normalize(c->m_Pos-realpos));
				if(m_Decay == 0) {
					m_Decay = 30;
					int shotspread = 2;
					
					for(int i = -shotspread; i <= shotspread; i++)
					{
						float spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
						float a = m_Angle;
						a += spreading[i+2];
						float v = 1-(abs(i)/(float)shotspread);
						float speed = mix((float)tuning.shotgun_speeddiff, 1.0f, v);
						CProjectile *pProj = new CProjectile(WEAPON_SHOTGUN,
							-2, 
							realpos,
							vec2(cosf(a), sinf(a))*speed,
							(int)(Server()->TickSpeed()*GameServer()->Tuning()->m_ShotgunLifetime),
							1, 0, 0, -1, WEAPON_SHOTGUN, false);
					}
					game.create_sound(realpos, SOUND_SHOTGUN_FIRE);
				}
			}
		} break;
		
		case B_HEALTH: case B_ARMOR: {
			CCharacter *c = GetNearest(ms_PhysSize, m_Team);
			if(c) {
				if(m_Decay == 0) { //wait for open first
					if(m_AnimDecay == 0 && m_Decay == 0 && m_Anim < 4) {
						m_AnimDecay = 3;
						m_Anim++;
					}
					else if(m_AnimDecay == 0) {
						if(m_Type == B_HEALTH && c->m_Health < 10) {
							m_Decay = 150;
							c->IncreaseHealth(3);
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_HEALTH);
							c->m_Ill = false;
						} else if(m_Type == B_HEALTH) {
							c->m_Ill = false;
						} else if(m_Type == B_ARMOR && c->m_Armor < 10) {
							m_Decay = 150;
							c->IncreaseArmor(3);
							GameServer()->CreateSound(m_Pos, SOUND_PICKUP_ARMOR);
						}
					}
				}
			}
			else { 
				if(m_AnimDecay == 0 && m_Decay == 0 && m_Anim > 0) {
					m_AnimDecay = 3;
					m_Anim--;
				}
			}
		} break;
		
		case B_SHIELD: {
			if(Server()->Tick() % 50 == 0 && m_Power) {
				if(m_Armor < 30)
					m_Armor++;				
				//game.create_damageind(pos, 3.141592, armor > 0 ? (int)(10.0f*armor/30) : 0);
			}
			
			if(Server()->Tick() % 5 == 0) {
				if(m_Hit > 0)
					m_Hit--;
				if(m_Power && m_Armor > 0) {
					CProjectile *pProj[128];
					int num = GameServer()->m_World.FindEntities(m_Pos, 250.0f, (CEntity**)pProj, 128, CGameWorld::ENTTYPE_PROJECTILE);
					for(int i = 0; i < num && m_Armor > 0; i++) {
						if(pProj[i]->m_Bounce)
							continue;
						if((pProj[i]->m_Owner >= 0) && GameServer()->m_apPlayers[pProj[i]->m_Owner] && GameServer()->m_apPlayers[pProj[i]->m_Owner]->m_Team == m_Team)
							continue;
						if(pProj[i]->m_Owner < 0)
							continue;
						
						pProj[i]->m_Initpos = pProj[i]->m_Pos;
						pProj[i]->m_StartTick = Server()->Tick();
						pProj[i]->m_Direction = normalize(pProj[i]->m_Pos-m_Pos);
						pProj[i]->m_Bounce = 1;
						m_Hit = 3;
						
						//game.create_shieldhit(m_Pos, 0);
						
						m_Armor = clamp(m_Armor-(pProj[i]->m_Weapon == WEAPON_GRENADE ? 4 : 2), 0, 30);
						if(m_Armor == 0) {
							m_Armor = -4;
						}
					}
				}
			}
			m_Anim = (m_Armor > 0 ? (int)(9.0f*m_Armor/30.0f) : 0) | (m_Hit << 4);
		} break;
		
		//NODESTODO: COUNTINUE!
		case B_TELEPORT: {
			if(m_Decay == 0) {
				//find other teleport... D=
				CBuilding *other = 0;
				for(int i = 0; i < ((CGameControllerNODES*)GameServer()->m_pController)->BuildingsCount[m_Team]; i++) {
					CBuilding *b = ((CGameControllerNODES*)GameServer()->m_pController)->Buildings[m_Team][i];
					if( b != this && b->m_Type == B_TELEPORT && b->m_Alive && b->m_Power) {
						other = b;
					}
				}
				if(other) {
					bool is_enemy = false;
					CCharacter *c = GetNearest(ms_PhysSize-4.0f, m_Team); 
					if(!c && m_Anim == 8) {//once opened, port enemies as well
						c = GetNearest(ms_PhysSize-4.0f, m_Team^1);
						is_enemy = true;
					}
					if(c) {
						if(m_Anim < 8 && m_AnimDecay == 0 && !is_enemy) {
							m_Anim++;
							m_AnimDecay = 2;
							other->m_Anim = m_Anim;
							other->m_AnimDecay = m_AnimDecay+1;
							other->m_Decay =m_AnimDecay+1;
						}
						else if(anim == 8 && m_AnimDecay == 0) {
							if(!c->m_pPlayer->m_Ported) {
								//dbg_msg("nodes", "yay");
								float ill_prob = min((distance(other->m_Pos, m_Pos))/8000.0f * 0.2f, 0.2f);
								for(int i = 0; i < MAX_CLIENTS; i++) {
									if(game.players[i] && game.players[i]->get_character() && (game.players[i]->get_character()->core.hooked_player == c->player->client_id || c->core.hooked_player == game.players[i]->client_id)) {
										CCharacter *hc = game.players[i]->get_character();
										hc->m_Pos = vec2(other->m_Pos.x, other->m_Pos.y-1);
										hc->core.m_Pos = vec2(other->m_Pos.x, other->m_Pos.y-1);
										hc->player->ported = true;
										hc->core.hook_state = -1;
										hc->core.hooked_player = -1;
										if(frandom() <= ill_prob) {
											if(!hc->ill) {
												hc->ill = true;
												hc->infecter = -1;
											}
										}
									}
								}
								//dbg_msg("nodes", "porting %d from (%d,%d) to (%d,%d)", c->player->client_id, (int)pos.x, (int)pos.y, (int)other->pos.x, (int)other->pos.y);
								c->pos = vec2(other->pos.x, other->pos.y-1);
								c->core.pos = vec2(other->pos.x, other->pos.y-1);
								c->player->ported = true;
								c->core.hook_state = -1;
								c->core.hooked_player = -1;
								if(frandom() <= ill_prob) {
									if(!c->ill) {
										c->ill = true;
										c->infecter = -1;
									}
								}
								decay = 50;
								other->decay = 50;
								anim = 1;
								other->anim = 1;
								game.create_playerspawn(other->pos);
								game.create_sound(pos, SOUND_TELEPORT);
								game.create_death(pos, c->player->client_id);
								game.create_sound(other->pos, SOUND_TELEPORT);
							} else {
								anim = 0;
							}
						}
					}
					else {
						if(anim > 0 && anim_decay == 0) {
							anim++;
							if(anim == 9)
								anim = 0;
							anim_decay = 2;
							other->anim = anim;
							other->anim_decay = anim_decay+1;
							other->decay =anim_decay+1;
						}
					}
				}
			} else {
				if(anim_decay == 0 && anim > 0) {
					anim_decay = 2;
					anim++;
					if(anim == 9)
						anim = 0;
				}
			}
		} break;
	}

	return;
}
Beispiel #7
0
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;
}