Пример #1
0
void PhysicalObj::UpdatePosition()
{
  // No ghost allowed here !
  if (IsGhost()) {
    return;
  }

  if (m_collides_with_ground) {
    // object is not moving
    if (!IsMoving()) {
      // and has no reason to move
      if (!FootsInVacuum()) {
        if (!IsInWater()) {
          return;
        }
      } else {
        // it should fall !
        StartMoving();
      }
    }
  }

  // Compute new position.
  RunPhysicalEngine();

  if (IsGhost()) {
    return;
  }

  // Classical object sometimes sinks in water and sometimes goes out of water!
  if (m_collides_with_ground) {
    if (IsInWater() && m_alive!=DROWNED && m_alive!=DEAD) Drown();
    else if (!IsInWater() && m_alive==DROWNED) GoOutOfWater();
  }
}
Пример #2
0
void PhysicalObj::SetEnergyDelta(int delta, Character* /*dealer*/)
{
  if (m_energy == -1)
    return;
  m_energy += delta;

  if (m_energy <= 0 && !IsGhost()) {
    Ghost();
    m_energy = -1;
  }
}
Пример #3
0
// called when a monster die [give exp/give extra drop]
bool CMonster::OnDie( )
{
    CMap* map = GServer->MapList.Index[Position->Map];
    if(map->ghost!=0)
    {
     if((map->IsNight( ) || map->ghost==2) && !IsGhost( ) && !IsGhostSeed( ) && !IsSummon( ))
       {
        UINT gs = GServer->RandNumber( 0, 100 );
        if(gs<30) // 30% / 70%
            {   // spawn a ghost seed [for now will be 701 [level 1 ghost seed] ]
                map->AddMonster( 701, Position->current, 0, NULL, NULL, Position->respawn, true );
            }
        }
    }
    
    //LMA begin
    //CF mode 1
    //20070621-211100
    UINT special_exp=0;
    UINT special_lvl=0;
    
    if (map->is_cf==1)
    {
       //what monster is dead?
       if(this->montype==map->id_def_mon)
       {
           //oh my god, they killed a j&b !! (or the monster with exp)
           special_exp=(UINT) map->mon_lvl;
           special_lvl= (UINT) map->mon_exp;
       }
       else
       {
           if (this->montype!=map->id_temp_mon)
           {
                UINT gs = GServer->RandNumber( 0, 100 );
                if(gs<map->percent)
                {
                  //we use the temporary monster as a decoy.
                  fPoint position_cf = GServer->RandInCircle( Position->current, 50 );
                  CMonster* monster2 = map->AddMonster( map->id_temp_mon, position_cf, 0, NULL, NULL, 0, true );           
                }
                
           }

       }
       
    }
    
    GServer->GiveExp( this , special_lvl, special_exp );
    //LMA End
    

    return true; 
}
Пример #4
0
// called when we create a new monster [attack players?]
bool CMonster::OnSpawn( bool Attack )
{
     lastSighCheck = clock();
    if(IsGhost( ) && Attack )
    {
        CPlayer* player = GetNearPlayer( );
        if(player==NULL) // no players or too far
            return true;
        StartAction( (CCharacter*)player, NORMAL_ATTACK, 0 );
    }

    return true;
}
Пример #5
0
// Move to a point with collision test
collision_t PhysicalObj::NotifyMove(Point2d oldPos, Point2d newPos)
{
  if (IsGhost())
    return NO_COLLISION;

  Point2d contactPos;
  Double contactAngle;
  Point2d pos, offset;
  PhysicalObj* collided_obj = NULL;

  collision_t collision = NO_COLLISION;

  // Convert meters to pixels.
  oldPos *= PIXEL_PER_METER;
  newPos *= PIXEL_PER_METER;

  // Compute distance between old and new position.
  Double lg = oldPos.SquareDistance(newPos);

  MSG_DEBUG("physic.move", "%s moves (%s, %s) -> (%s, %s), square distance: %s",
            GetName().c_str(),
            Double2str(oldPos.x).c_str(), Double2str(oldPos.y).c_str(),
            Double2str(newPos.x).c_str(), Double2str(newPos.y).c_str(),
            Double2str(lg).c_str());

  if (!lg.IsNotZero())
    return NO_COLLISION;

  // Compute increments to move the object step by step from the old
  // to the new position.
  lg = sqrt(lg);
  offset = (newPos - oldPos) / lg;

  // First iteration position.
  pos = oldPos + offset;

  if (!m_collides_with_ground || IsInWater()) {
    MSG_DEBUG("physic.move", "%s moves (%s, %s) -> (%s, %s), collides ground:%d, water:%d",
              GetName().c_str(),
              Double2str(oldPos.x).c_str(), Double2str(oldPos.y).c_str(),
              Double2str(newPos.x).c_str(), Double2str(newPos.y).c_str(),
              m_collides_with_ground, IsInWater());

    SetXY(newPos);
    return NO_COLLISION;
  }

  do {
    Point2i tmpPos(uround(pos.x), uround(pos.y));

    // Check if we exit the GetWorld(). If so, we stop moving and return.
    if (IsOutsideWorldXY(tmpPos)) {

      if (!GetWorld().IsOpen()) {
        tmpPos.x = InRange_Long(tmpPos.x, 0, GetWorld().GetWidth() - GetWidth() - 1);
        tmpPos.y = InRange_Long(tmpPos.y, 0, GetWorld().GetHeight() - GetHeight() - 1);
        MSG_DEBUG("physic.state", "%s - DeplaceTestCollision touche un bord : %d, %d",
                  GetName().c_str(), tmpPos.x, tmpPos.y);
        collision = COLLISION_ON_GROUND;
        break;
      }

      SetXY(pos);

      MSG_DEBUG("physic.move", "%s moves (%f, %f) -> (%f, %f) : OUTSIDE WORLD",
                GetName().c_str(), oldPos.x.tofloat(), oldPos.y.tofloat(),
                newPos.x.tofloat(), newPos.y.tofloat());
      return NO_COLLISION;
    }

    // Test if we collide...
    collided_obj = CollidedObjectXY(tmpPos);
    if (collided_obj) {
      if (!m_go_through_objects || m_last_collided_object != collided_obj) {
        MSG_DEBUG("physic.state", "%s collide on %s", GetName().c_str(), collided_obj->GetName().c_str());

        if (m_go_through_objects) {
          SignalObjectCollision(GetSpeed(), collided_obj, collided_obj->GetSpeed());
          collision = NO_COLLISION;
        } else {
          collision = COLLISION_ON_OBJECT;
        }
        m_last_collided_object = collided_obj;
      } else {
        collided_obj = NULL;
        collision = NO_COLLISION;
      }
    } else if (!IsInVacuumXY(tmpPos, false)) {
      collision = COLLISION_ON_GROUND;
      m_last_collided_object = NULL;
    }

    if (collision != NO_COLLISION) {
      // Nothing more to do!
      MSG_DEBUG("physic.state", "%s - Collision at %d,%d : on %s",
                GetName().c_str(), tmpPos.x, tmpPos.y,
                collision == COLLISION_ON_GROUND ? "ground" : "an object");

      // Set the object position to the current position.
      SetXY(Point2d(pos.x - offset.x, pos.y - offset.y));
      break;
    }

    // Next motion step
    pos += offset;
    lg -= ONE;
  } while (ZERO < lg);

  Point2d speed_before_collision = GetSpeed();
  Point2d speed_collided_obj;
  if (collided_obj) {
    speed_collided_obj = collided_obj->GetSpeed();
  }

  ContactPointAngleOnGround(pos, contactPos, contactAngle);

  Collide(collision, collided_obj, pos);

  // ===================================
  // it's time to signal object(s) about collision!
  // WARNING: the following calls can send Action(s) over the network (cf bug #11232)
  // Be sure to keep it isolated here
  // ===================================
  ActiveTeam().AccessWeapon().NotifyMove(!!collision);
  switch (collision) {
  case NO_COLLISION:
    // Nothing more to do!
    break;
  case COLLISION_ON_GROUND:
    SignalGroundCollision(speed_before_collision, contactAngle);
    break;
  case COLLISION_ON_OBJECT:
    SignalObjectCollision(speed_before_collision, collided_obj, speed_collided_obj);
    collided_obj->SignalObjectCollision(speed_collided_obj, this, speed_before_collision);
    break;
  }
  // ===================================

  return collision;
}
Пример #6
0
void Plane::Draw()
{
  if (IsGhost())
    return;
  image->Draw(GetPosition());
}