Exemple #1
0
void monster::knock_back_from(int x, int y)
{
 if (x == posx() && y == posy())
  return; // No effect
    if( is_hallucination() ) {
        die( nullptr );
        return;
    }
 point to(posx(), posy());
 if (x < posx())
  to.x++;
 if (x > posx())
  to.x--;
 if (y < posy())
  to.y++;
 if (y > posy())
  to.y--;

 bool u_see = g->u.sees( to );

// First, see if we hit another monster
 int mondex = g->mon_at(to.x, to.y);
    if( mondex != -1 && g->zombie( mondex ).is_hallucination() ) {
        // hallucinations should not affect real monsters. If they interfer, just remove them.
        g->zombie( mondex ).die( this );
        mondex = -1;
    }
 if (mondex != -1) {
  monster *z = &(g->zombie(mondex));
  apply_damage( z, bp_torso, z->type->size );
  add_effect("stunned", 1);
  if (type->size > 1 + z->type->size) {
   z->knock_back_from(posx(), posy()); // Chain reaction!
   z->apply_damage( this, bp_torso, type->size );
   z->add_effect("stunned", 1);
  } else if (type->size > z->type->size) {
   z->apply_damage( this, bp_torso, type->size );
   z->add_effect("stunned", 1);
  }
  z->check_dead_state();

  if (u_see)
   add_msg(_("The %s bounces off a %s!"), name().c_str(), z->name().c_str());

  return;
 }

 int npcdex = g->npc_at(to.x, to.y);
 if (npcdex != -1) {
  npc *p = g->active_npc[npcdex];
  apply_damage( p, bp_torso, 3 );
  add_effect("stunned", 1);
  p->deal_damage( this, bp_torso, damage_instance( DT_BASH, type->size ) );
  if (u_see)
   add_msg(_("The %s bounces off %s!"), name().c_str(), p->name.c_str());

  p->check_dead_state();
  return;
 }

// If we're still in the function at this point, we're actually moving a tile!
 if (g->m.ter_at(to.x, to.y).has_flag(TFLAG_DEEP_WATER)) {
  if (g->m.has_flag("LIQUID", to.x, to.y) && can_drown()) {
   die( nullptr );
   if (u_see) {
    add_msg(_("The %s drowns!"), name().c_str());
   }

  } else if (has_flag(MF_AQUATIC)) { // We swim but we're NOT in water
   die( nullptr );
   if (u_see) {
    add_msg(_("The %s flops around and dies!"), name().c_str());
   }
  }
 }

 if (g->m.move_cost(to.x, to.y) == 0) {

   // It's some kind of wall.
   apply_damage( nullptr, bp_torso, type->size );
   add_effect("stunned", 2);
   if (u_see) {
    add_msg(_("The %s bounces off a %s."), name().c_str(),
               g->m.tername(to.x, to.y).c_str());
   }

 } else { // It's no wall
  setpos(to);
 }
    check_dead_state();
}
Exemple #2
0
void monster::knock_back_from(int x, int y)
{
    if (x == posx() && y == posy())
        return; // No effect
    point to(posx(), posy());
    if (x < posx())
        to.x++;
    if (x > posx())
        to.x--;
    if (y < posy())
        to.y++;
    if (y > posy())
        to.y--;

    bool u_see = g->u_see(to.x, to.y);

// First, see if we hit another monster
    int mondex = g->mon_at(to.x, to.y);
    if (mondex != -1) {
        monster *z = &(g->zombie(mondex));
        hurt(z->type->size);
        add_effect("stunned", 1);
        if (type->size > 1 + z->type->size) {
            z->knock_back_from(posx(), posy()); // Chain reaction!
            z->hurt(type->size);
            z->add_effect("stunned", 1);
        } else if (type->size > z->type->size) {
            z->hurt(type->size);
            z->add_effect("stunned", 1);
        }

        if (u_see)
            g->add_msg(_("The %s bounces off a %s!"), name().c_str(), z->name().c_str());

        return;
    }

    int npcdex = g->npc_at(to.x, to.y);
    if (npcdex != -1) {
        npc *p = g->active_npc[npcdex];
        hurt(3);
        add_effect("stunned", 1);
        p->hit(this, bp_torso, -1, type->size, 0);
        if (u_see)
            g->add_msg(_("The %s bounces off %s!"), name().c_str(), p->name.c_str());

        return;
    }

// If we're still in the function at this point, we're actually moving a tile!
    if (g->m.ter_at(to.x, to.y).has_flag(TFLAG_DEEP_WATER)) {
        if (g->m.has_flag("LIQUID", to.x, to.y) && can_drown()) {
            hurt(9999);
            if (u_see) {
                g->add_msg(_("The %s drowns!"), name().c_str());
            }

        } else if (has_flag(MF_AQUATIC)) { // We swim but we're NOT in water
            hurt(9999);
            if (u_see) {
                g->add_msg(_("The %s flops around and dies!"), name().c_str());
            }
        }
    }

    if (g->m.move_cost(to.x, to.y) == 0) {

        // It's some kind of wall.
        hurt(type->size);
        add_effect("stunned", 2);
        if (u_see) {
            g->add_msg(_("The %s bounces off a %s."), name().c_str(),
                       g->m.tername(to.x, to.y).c_str());
        }

    } else { // It's no wall
        setpos(to);
    }
}
Exemple #3
0
void monster::knock_back_from( const tripoint &p )
{
    if( p == pos() ) {
        return; // No effect
    }
    if( is_hallucination() ) {
        die( nullptr );
        return;
    }
    tripoint to = pos();;
    if( p.x < posx() ) {
        to.x++;
    }
    if( p.x > posx() ) {
        to.x--;
    }
    if( p.y < posy() ) {
        to.y++;
    }
    if( p.y > posy() ) {
        to.y--;
    }

    bool u_see = g->u.sees( to );

    // First, see if we hit another monster
    if( monster *const z = g->critter_at<monster>( to ) ) {
        apply_damage( z, bp_torso, z->type->size );
        add_effect( effect_stunned, 1 );
        if( type->size > 1 + z->type->size ) {
            z->knock_back_from( pos() ); // Chain reaction!
            z->apply_damage( this, bp_torso, type->size );
            z->add_effect( effect_stunned, 1 );
        } else if( type->size > z->type->size ) {
            z->apply_damage( this, bp_torso, type->size );
            z->add_effect( effect_stunned, 1 );
        }
        z->check_dead_state();

        if( u_see ) {
            add_msg( _( "The %1$s bounces off a %2$s!" ), name().c_str(), z->name().c_str() );
        }

        return;
    }

    if( npc *const p = g->critter_at<npc>( to ) ) {
        apply_damage( p, bp_torso, 3 );
        add_effect( effect_stunned, 1 );
        p->deal_damage( this, bp_torso, damage_instance( DT_BASH, type->size ) );
        if( u_see ) {
            add_msg( _( "The %1$s bounces off %2$s!" ), name().c_str(), p->name.c_str() );
        }

        p->check_dead_state();
        return;
    }

    // If we're still in the function at this point, we're actually moving a tile!
    if( g->m.has_flag_ter( TFLAG_DEEP_WATER, to ) ) {
        if( g->m.has_flag( "LIQUID", to ) && can_drown() ) {
            die( nullptr );
            if( u_see ) {
                add_msg( _( "The %s drowns!" ), name().c_str() );
            }

        } else if( has_flag( MF_AQUATIC ) ) { // We swim but we're NOT in water
            die( nullptr );
            if( u_see ) {
                add_msg( _( "The %s flops around and dies!" ), name().c_str() );
            }
        }
    }

    if( g->m.impassable( to ) ) {

        // It's some kind of wall.
        apply_damage( nullptr, bp_torso, type->size );
        add_effect( effect_stunned, 2 );
        if( u_see ) {
            add_msg( _( "The %1$s bounces off a %2$s." ), name().c_str(),
                     g->m.obstacle_name( to ).c_str() );
        }

    } else { // It's no wall
        setpos( to );
    }
    check_dead_state();
}