Пример #1
0
void AGENT::update_fight(GROUP* target_group)
{
	// get target
	AGENT * t = find_target(target_group); //group->is_single_unit() ? find_target(target_group) : find_target_random(target_group);
	if (!t) return; // didn't find one

	// fight
	move_mult(collision ? 3.0 : 1.0);
	set_dest(t->get_x(), t->get_y());
	if (dist_dest() > (t->getRadius() + getRadius()) * 2) { // move to target
		fight_timer--;
		if (!collision) move((int)get_dest_x(), (int)get_dest_y(), true); // move
		else collision_avoid(); // collision avoid
		state = AGENT::READY_FIGHT;
		setAnimation(is_stuckcounter() ? ANIMATION_DATA::STAND : ANIMATION_DATA::MOVE, true);
	} else { // at target
		move_stop();
		state = AGENT::FIGHTING;
		if (is_near_dest_angle(45)) { // deal damage
			set_dest(x, y);
			t->hurt_by(unitData->damage, this);
			setAnimation(ANIMATION_DATA::ATTACK, true);
		} else { // face target
			fight_timer--;
			rotate_towards((int)get_angle_dest());
			if (!is_near_dest_angle(90)) setAnimation(ANIMATION_DATA::STAND, true);
		}
	}

	// single units sync group position with their own
	if (group->is_single_unit()) group->sync_to(this);

	// update gemeric stuff
	update();
}
Пример #2
0
/* Random walking even when we've moved
 * To simulate zombie stumbling and ineffective movement
 * Note that this is sub-optimal; stumbling may INCREASE a zombie's speed.
 * Most of the time (out in the open) this effect is insignificant compared to
 * the negative effects, but in a hallway it's perfectly even
 */
void monster::stumble( bool moved )
{
    // don't stumble every turn. every 3rd turn, or 8th when walking.
    if( ( moved && !one_in( 8 ) ) || !one_in( 3 ) ) {
        return;
    }

    std::vector<tripoint> valid_stumbles;
    const bool avoid_water = has_flag( MF_NO_BREATHE ) && !has_flag( MF_SWIMS ) && !has_flag( MF_AQUATIC );
    for( int i = -1; i <= 1; i++ ) {
        for( int j = -1; j <= 1; j++ ) {
            tripoint dest( posx() + i, posy() + j, posz() );
            if( ( i || j ) && can_move_to( dest ) &&
                //Stop zombies and other non-breathing monsters wandering INTO water
                //(Unless they can swim/are aquatic)
                //But let them wander OUT of water if they are there.
                !( avoid_water &&
                   g->m.has_flag( "SWIMMABLE", dest ) &&
                   !g->m.has_flag( "SWIMMABLE", pos3() ) ) &&
                g->critter_at( dest ) == nullptr ) {
                valid_stumbles.push_back( dest );
            }
        }
    }

    if( g->m.has_zlevels() ) {
        tripoint below( posx(), posy(), posz() - 1 );
        tripoint above( posx(), posy(), posz() + 1 );
        if( g->m.valid_move( pos(), below, false, true ) && can_move_to( below ) ) {
            valid_stumbles.push_back( below );
        }
        // More restrictions for moving up
        // It should happen during "shambling around", but not as actual stumbling
        if( !moved && one_in( 5 ) && has_flag( MF_FLIES ) &&
            g->m.valid_move( pos(), above, false, true ) && can_move_to( above ) ) {
            valid_stumbles.push_back( above );
        }
    }

    if( valid_stumbles.empty() ) { //nowhere to stumble?
        return;
    }

    move_to( random_entry( valid_stumbles ), false );

    // Here we have to fix our plans[] list,
    // acquiring a new path to the previous target.
    // target == either end of current plan, or the player.
    int bresenham_slope, junk;
    if( !plans.empty() ) {
        if( g->m.sees( pos3(), plans.back(), -1, bresenham_slope, junk ) ) {
            set_dest( plans.back(), bresenham_slope );
        } else if( sees( g->u, bresenham_slope ) ) {
            set_dest( g->u.pos(), bresenham_slope );
        } else { //durr, i'm suddenly calm. what was i doing?
            plans.clear();
        }
    }
}
Пример #3
0
/* Random walking even when we've moved
 * To simulate zombie stumbling and ineffective movement
 * Note that this is sub-optimal; stumbling may INCREASE a zombie's speed.
 * Most of the time (out in the open) this effect is insignificant compared to
 * the negative effects, but in a hallway it's perfectly even
 */
void monster::stumble(bool moved)
{
// don't stumble every turn. every 3rd turn, or 8th when walking.
    if((moved && !one_in(8)) || !one_in(3))
    {
        return;
    }

    std::vector <point> valid_stumbles;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            const int nx = posx() + i;
            const int ny = posy() + j;
            if ((i || j) && can_move_to(nx, ny) &&
                    /* Don't ever stumble into impassable terrain, even if we normally could
                     * smash it, as this is uncoordinated movement (and is forced). */
                    g->m.move_cost(nx, ny) != 0 &&
                    //Stop zombies and other non-breathing monsters wandering INTO water
                    //(Unless they can swim/are aquatic)
                    //But let them wander OUT of water if they are there.
                    !(has_flag(MF_NO_BREATHE) && !has_flag(MF_SWIMS) && !has_flag(MF_AQUATIC)
                      && g->m.has_flag("SWIMMABLE", nx, ny)
                      && !g->m.has_flag("SWIMMABLE", posx(), posy())) &&
                    (g->u.posx != nx || g->u.posy != ny) &&
                    (g->mon_at(nx, ny) == -1)) {
                point tmp(nx, ny);
                valid_stumbles.push_back(tmp);
            }
        }
    }
    if (valid_stumbles.size() == 0) //nowhere to stumble?
    {
        return;
    }

    int choice = rng(0, valid_stumbles.size() - 1);
    int cx = valid_stumbles[choice].x;
    int cy = valid_stumbles[choice].y;

    moves -= calc_movecost(posx(), posy(), cx, cy);
    setpos(cx, cy);

// Here we have to fix our plans[] list,
// acquiring a new path to the previous target.
// target == either end of current plan, or the player.
    int tc;
    if (plans.size() > 0) {
        if (g->m.sees(posx(), posy(), plans.back().x, plans.back().y, -1, tc))
            set_dest(plans.back().x, plans.back().y, tc);
        else if (sees_player( tc ))
            set_dest(g->u.posx, g->u.posy, tc);
        else //durr, i'm suddenly calm. what was i doing?
            plans.clear();
    }
}
Пример #4
0
/* Random walking even when we've moved
 * To simulate zombie stumbling and ineffective movement
 * Note that this is sub-optimal; stumbling may INCREASE a zombie's speed.
 * Most of the time (out in the open) this effect is insignificant compared to
 * the negative effects, but in a hallway it's perfectly even
 */
void monster::stumble(bool moved)
{
 // don't stumble every turn. every 3rd turn, or 8th when walking.
 if((moved && !one_in(8)) || !one_in(3))
 {
     return;
 }

 std::vector <point> valid_stumbles;
 for (int i = -1; i <= 1; i++) {
  for (int j = -1; j <= 1; j++) {
   const int nx = posx() + i;
   const int ny = posy() + j;
   if ((i || j) && can_move_to(nx, ny) &&
       //Stop zombies and other non-breathing monsters wandering INTO water
       //(Unless they can swim/are aquatic)
       //But let them wander OUT of water if they are there.
       !(has_flag(MF_NO_BREATHE) && !has_flag(MF_SWIMS) && !has_flag(MF_AQUATIC)
           && g->m.has_flag("SWIMMABLE", nx, ny)
           && !g->m.has_flag("SWIMMABLE", posx(), posy())) &&
       (g->u.posx() != nx || g->u.posy() != ny) &&
       (g->mon_at(nx, ny) == -1) &&
       (g->npc_at(nx, ny) == -1) ) {
    point tmp(nx, ny);
    valid_stumbles.push_back(tmp);
   }
  }
 }
 if (valid_stumbles.empty()) //nowhere to stumble?
 {
     return;
 }

 int choice = rng(0, valid_stumbles.size() - 1);
 int cx = valid_stumbles[choice].x;
 int cy = valid_stumbles[choice].y;

 move_to( cx, cy, false );

 // Here we have to fix our plans[] list,
 // acquiring a new path to the previous target.
 // target == either end of current plan, or the player.
 int bresenham_slope;
 if (!plans.empty()) {
  if (g->m.sees( pos(), plans.back(), -1, bresenham_slope))
   set_dest(plans.back().x, plans.back().y, bresenham_slope);
  else if (sees( g->u, bresenham_slope ))
   set_dest(g->u.posx(), g->u.posy(), bresenham_slope);
  else //durr, i'm suddenly calm. what was i doing?
   plans.clear();
 }
}
Пример #5
0
void renumber_registers(IRCode* code, bool width_aware) {
  auto chains = calculate_ud_chains(code);

  Rank rank;
  Parent parent;
  DefSets def_sets((RankPMap(rank)), (ParentPMap(parent)));
  for (const auto& mie : InstructionIterable(code)) {
    if (mie.insn->dests_size()) {
      def_sets.make_set(mie.insn);
    }
  }
  unify_defs(chains, &def_sets);
  SymRegMapper sym_reg_mapper(width_aware);
  for (auto& mie : InstructionIterable(code)) {
    auto insn = mie.insn;
    if (insn->dests_size()) {
      auto sym_reg = sym_reg_mapper.make(def_sets.find_set(insn));
      insn->set_dest(sym_reg);
    }
  }
  for (auto& mie : InstructionIterable(code)) {
    auto insn = mie.insn;
    for (size_t i = 0; i < insn->srcs_size(); ++i) {
      auto& defs = chains.at(Use{insn, insn->src(i)});
      insn->set_src(i, sym_reg_mapper.at(def_sets.find_set(*defs.begin())));
    }
  }
  code->set_registers_size(sym_reg_mapper.regs_size());
}
Пример #6
0
void DexInstruction::verify_encoding() const {
  auto test = m_count ? new DexInstruction(opcode()) : new DexInstruction(opcode(), 0);
  if (dests_size()) {
    test->set_dest(dest());
  }
  for (unsigned i = 0; i < srcs_size(); i++) {
    test->set_src(i, src(i));
  }
  if (has_range_base()) test->set_range_base(range_base());
  if (has_range_size()) test->set_range_size(range_size());
  if (has_arg_word_count()) test->set_arg_word_count(arg_word_count());
  if (has_literal()) test->set_literal(literal());
  if (has_offset()) test->set_offset(offset());

  assert_log(m_opcode == test->m_opcode, "%x %x\n", m_opcode, test->m_opcode);
  for (unsigned i = 0; i < m_count; i++) {
    assert_log(m_arg[i] == test->m_arg[i],
               "(%x %x) (%x %x)",
               m_opcode,
               m_arg[i],
               test->m_opcode,
               test->m_arg[i]);
  }

  delete test;
}
Пример #7
0
void create_runtime_exception_block(
    DexString* except_str, std::vector<IRInstruction*>& block) {
  // new-instance v0, Ljava/lang/RuntimeException; // type@3852
  // const-string v1, "Exception String e.g. Too many args" // string@7a6d
  // invoke-direct {v0, v1}, Ljava/lang/RuntimeException;.<init>:(Ljava/lang/String;)V
  // throw v0
  auto new_inst =
      (new IRInstruction(OPCODE_NEW_INSTANCE))
          ->set_type(DexType::make_type("Ljava/lang/RuntimeException;"));
  new_inst->set_dest(0);
  IRInstruction* const_inst =
      (new IRInstruction(OPCODE_CONST_STRING))->set_string(except_str);
  const_inst->set_dest(1);
  auto ret = DexType::make_type("V");
  auto arg = DexType::make_type("Ljava/lang/String;");
  auto args = DexTypeList::make_type_list({arg});
  auto proto = DexProto::make_proto(ret, args);
  auto meth = DexMethod::make_method(
    DexType::make_type("Ljava/lang/RuntimeException;"),
    DexString::make_string("<init>"), proto);
  auto invk = new IRInstruction(OPCODE_INVOKE_DIRECT);
  invk->set_method(meth);
  invk->set_arg_word_count(2);
  invk->set_src(0, 0); invk->set_src(1, 1);
  IRInstruction* throwinst = new IRInstruction(OPCODE_THROW);
  block.emplace_back(new_inst);
  block.emplace_back(const_inst);
  block.emplace_back(invk);
  block.emplace_back(throwinst);
}
Пример #8
0
void AGENT::update_rangedfight(GROUP* target_group)
{
	// get target
	AGENT * t = find_target_random(target_group);
	if (!t) return; // didn't find one

	// fight
	move_mult(collision ? 3.0 : 1.0);
	set_dest(t->get_x(), t->get_y());
	if (dist_dest() > unitData->range - group->get_radius()/2) { // move to target
		fight_timer--;
		if (!collision) move((int)get_dest_x(), (int)get_dest_y(), true); // move
		else collision_avoid(); // collision avoid
		state = AGENT::READY_FIGHT;
		setAnimation(is_stuckcounter() ? ANIMATION_DATA::STAND : ANIMATION_DATA::MOVE, true);
	} else { // close enough to target
		move_stop();
		state = AGENT::FIGHTING;
		double angle = rotation * M_PI / 180.;
		double angle_target = angle_to(t->get_x() - unitData->r_horiz_offset*cos(angle + M_PI/2), t->get_y() - unitData->r_horiz_offset*sin(angle + M_PI/2));
		if (is_near_angle(angle_target, 15) || group->is_building()) { // deal damage
			// create projectile
			if (frame_num() == unitData->rattack_frame) {
			    if (is_first_frame_display()) {
			        double t_angle = angle_target*M_PI/180;
			        int plife = (int)(dist_to(t->get_x(), t->get_y()) - getRadius() - 2*t->getRadius());
                    part_sys.add(attack_type->particle, x + getRadius()*cos(t_angle) + unitData->r_horiz_offset*cos(t_angle + M_PI/2), y + getRadius()*sin(t_angle) + unitData->r_horiz_offset*sin(t_angle + M_PI/2), angle_target, (plife > 0) ? plife : t->getRadius(), attack_type, t->getGroup(), t->get_id(), group->get_id());
			    }
			}
            // unit stuff
            set_dest(x, y);
			setAnimation(ANIMATION_DATA::RANGED, true);
		} else { // face target
			fight_timer--;
			rotate_towards((int)angle_target);
			if (!is_near_angle(angle_target, 20)) setAnimation(ANIMATION_DATA::STAND, true);
		}
	}

	// single units sync group position with their own
	if (group->is_single_unit()) group->sync_to(this);

	// update gemeric stuff
	update();
}
Пример #9
0
/* Random walking even when we've moved
 * To simulate zombie stumbling and ineffective movement
 * Note that this is sub-optimal; stumbling may INCREASE a zombie's speed.
 * Most of the time (out in the open) this effect is insignificant compared to
 * the negative effects, but in a hallway it's perfectly even
 */
void monster::stumble(game *g, bool moved)
{
 // don't stumble every turn. every 3rd turn, or 8th when walking.
 if((moved && !one_in(8)) || !one_in(3))
 {
     return;
 }

 std::vector <point> valid_stumbles;
 for (int i = -1; i <= 1; i++) {
  for (int j = -1; j <= 1; j++) {
   if (can_move_to(g, posx + i, posy + j) &&
       (g->u.posx != posx + i || g->u.posy != posy + j) &&
       (g->mon_at(posx + i, posy + j) == -1 || (i == 0 && j == 0))) {
    point tmp(posx + i, posy + j);
    valid_stumbles.push_back(tmp);
   }
  }
 }
 if (valid_stumbles.size() == 0) //nowhere to stumble?
 {
     return;
 }

 int choice = rng(0, valid_stumbles.size() - 1);
 int cx = valid_stumbles[choice].x;
 int cy = valid_stumbles[choice].y;

 moves -= calc_movecost(g, posx, posy, cx, cy);
 posx = cx;
 posy = cy;

 // Here we have to fix our plans[] list,
 // acquiring a new path to the previous target.
 // target == either end of current plan, or the player.
 int tc;
 if (plans.size() > 0) {
  if (g->m.sees(posx, posy, plans.back().x, plans.back().y, -1, tc))
   set_dest(plans.back().x, plans.back().y, tc);
  else if (g->sees_u(posx, posy, tc))
   set_dest(g->u.posx, g->u.posy, tc);
  else //durr, i'm suddenly calm. what was i doing?
   plans.clear();
 }
}
Пример #10
0
    int string_convert(dst_string &dst,const src_string &src) {
        dst.resize(std::max(dst.size(),((src.length()+4u)*4u)+2u)); // maximum 4 bytes/char expansion UTF-8 or bigger if caller resized already
        set_dest(dst); /* will apply new size to dst/fence pointers */

        int err = string_convert_src(src);

        dst.resize(get_dest_last_written());

        finish();
        return err;
    }
Пример #11
0
    int string_convert_dest(dst_string &dst) {
        size_t srcl = (size_t)((uintptr_t)src_ptr_fence - (uintptr_t)src_ptr);

        dst.resize(std::max(dst.size(),((srcl+4u)*4u)+2u));
        set_dest(dst);

        int err = string_convert();

        finish();
        return err;
    }
Пример #12
0
void MethodBlock::sfield_op(DexOpcode opcode,
                            DexField* field,
                            Location& src_or_dst) {
  always_assert(is_sfield_op(opcode));
  if (is_sget(opcode)) {
    auto sget = new DexOpcodeField(opcode, field);
    sget->set_dest(reg_num(src_or_dst));
    src_or_dst.type = field->get_class();
    push_instruction(sget);
  } else {
    auto sput = new DexOpcodeField(opcode, field);
    sput->set_src(0, reg_num(src_or_dst));
    push_instruction(sput);
  }
}
Пример #13
0
void AGENT::update_normal(void)
{
	int tx, ty;

	state = AGENT::NORMAL;

	// Logic
	if (!is_dest() && !at_unreachable_dest()) {
		// move faster if out of position
		if (within_dist_dest(unitData->radius * 2)) move_mult(1.0);
		else if (within_dist_dest(unitData->radius * 4)) move_mult(1.1);
		else move_mult(1.8);
		// animation
		setAnimation(ANIMATION_DATA::MOVE, true);
	} else {
		// clear last swap memory
		last_swap = -1;
		// don't move
		if (!is_dest_angle() && group->task_type() == TASK::MOVE) rotate_towards((int)group->get_angle_dest()); // rotate towards target
		else if (rotate_to_group) {
			if (!is_angle(group->get_rotation())) rotate_towards((int)group->get_rotation()); // rotate to group direction
			else end_rotate_to_group();
		}
		move_stop();
		if (!is_moving()) setAnimation(ANIMATION_DATA::STAND, true);
	}

	// Movement
	if (group->is_single_unit()) sync_to(group);
	else {
		swap_count--;
		if (!collision) move((int)get_dest_x(), (int)get_dest_y(), !group->is_moving()); // no collision
		else if (!is_dest() && (!agent_collided || agent_collided->getGroup() != getGroup()) && dist_dest() < group->get_radius()) {
		    if (agent_collided) shorten_dest(2 * getRadius());
		    else {
		        set_dest(group->get_x(), group->get_y());
		        shorten_dest(100);
		    }
		} else if (agent_collided && !is_dest() && group->is_dest_angle() && agent_collided->is_near_dest_angle(35) && agent_collided->is_near_dest() && is_near_angle(agent_collided->get_rotation(), 35) && agent_collided->getGroup() == getGroup() && ((!is_last_swap(agent_collided->get_sort_id()) && !agent_collided->is_last_swap(sort_id)) || swap_count < 0)) { // swap group positions
			swap_positions(agent_collided); // in same group, do it
		}
		else collision_avoid(); // collision
	}

	// generic update
	update();
}
Пример #14
0
void MethodBlock::ifield_op(DexCodeItemOpcode opcode,
                            DexField* field,
                            Location obj,
                            Location& src_or_dst) {
  always_assert(is_ifield_op(opcode));
  if (is_iget(opcode)) {
    auto iget = new DexOpcodeField(opcode, field);
    iget->set_dest(reg_num(src_or_dst));
    src_or_dst.type = field->get_class();
    iget->set_src(0, reg_num(obj));
    push_opcode(iget);
  } else {
    auto iput = new DexOpcodeField(opcode, field);
    iput->set_src(0, reg_num(src_or_dst));
    iput->set_src(1, reg_num(obj));
    push_opcode(iput);
  }
}
Пример #15
0
/* Random walking even when we've moved
 * To simulate zombie stumbling and ineffective movement
 * Note that this is sub-optimal; stumbling may INCREASE a zombie's speed.
 * Most of the time (out in the open) this effect is insignificant compared to
 * the negative effects, but in a hallway it's perfectly even
 */
void monster::stumble(game *g, bool moved)
{
 std::vector <point> valid_stumbles;
 for (int i = -1; i <= 1; i++) {
  for (int j = -1; j <= 1; j++) {
   if (can_move_to(g->m, posx + i, posy + j) &&
       (g->u.posx != posx + i || g->u.posy != posy + j) && 
       (g->mon_at(posx + i, posy + j) == -1 || (i == 0 && j == 0))) {
    point tmp(posx + i, posy + j);
    valid_stumbles.push_back(tmp);
   }
  }
 }
 if (valid_stumbles.size() > 0 && (one_in(8) || (!moved && one_in(3)))) {
  int choice = rng(0, valid_stumbles.size() - 1);
  posx = valid_stumbles[choice].x;
  posy = valid_stumbles[choice].y;
  if (!has_flag(MF_DIGS) || !has_flag(MF_FLIES))
   moves -= (g->m.move_cost(posx, posy) - 2) * 50;
// Here we have to fix our plans[] list, trying to get back to the last point
// Otherwise the stumble will basically have no effect!
  if (plans.size() > 0) {
   int tc;
   if (g->m.sees(posx, posy, plans[0].x, plans[0].y, -1, tc)) {
// Copy out old plans...
    std::vector <point> plans2;
    for (int i = 0; i < plans.size(); i++)
     plans2.push_back(plans[i]);
// Set plans to a route between where we are now, and where we were
    set_dest(plans[0].x, plans[0].y, tc);
// Append old plans to the new plans
    for (int index = 0; index < plans2.size(); index++)
     plans.push_back(plans2[index]);
   } else
    plans.clear();
  }
 }
}
Пример #16
0
int
main(int argc, char **argv)
{
    int32_t arg_id;
    int     fd, clonefd = -1;
    int     i, j, eoff, off, ret;
    FILE*   onf;
    char    msg[MAX_SEND];
    int     c;
    int     mlen          = 0;
    int     udp           = 0;
    int     det           = 0;
    char    fname[MAX_FILENAME] = "";
    char    raddr[MAX_IP] = "127.0.0.1";
    int     rport         = 12345;

    kfs_event_arg_t *kea;
    struct           fsevent_clone_args fca;
    char             buffer[FSEVENT_BUFSIZ];
    struct passwd   *p;
    struct group    *g;
    mode_t           va_mode;
    u_int32_t        va_type;
    u_int32_t        is_fse_arg_vnode = 0;
    char             fileModeString[11 + 1];
    int8_t           event_list[] = { // action to take for each event
                         FSE_REPORT,  // FSE_CREATE_FILE,
                         FSE_REPORT,  // FSE_DELETE,
                         FSE_REPORT,  // FSE_STAT_CHANGED,
                         FSE_REPORT,  // FSE_RENAME,
                         FSE_REPORT,  // FSE_CONTENT_MODIFIED,
                         FSE_REPORT,  // FSE_EXCHANGE,
                         FSE_REPORT,  // FSE_FINDER_INFO_CHANGED,
                         FSE_REPORT,  // FSE_CREATE_DIR,
                         FSE_REPORT,  // FSE_CHOWN,
                         FSE_REPORT,  // FSE_XATTR_MODIFIED,
                         FSE_REPORT,  // FSE_XATTR_REMOVED,
                     };

    // Print usage if not root
    if (geteuid() != 0){
        usage();
        exit(1);
    }

    onf = stdout;
    opterr = 0;
    while ((c = getopt (argc, argv, "huf:s:p:")) != -1)
        switch (c){
            case 'f':
                strncpy(fname,optarg,MAX_FILENAME - 1);
                    
                onf = fopen(fname,"w");
                if (onf == NULL){
                    fprintf(stderr, "Cannot open output file %s.\n\n",optarg);
                    usage();
                    exit(1);
                }
                break;
            case 'u':
                udp = 1;
                break;
            case 's':
                strncpy(raddr,optarg,MAX_IP);
                break;
            case 'p':
                rport = atoi( optarg );
                break;
            case 'h':
            case '?':
                if (optopt == 'f'){
                    fprintf(stderr, "Output filename required.\n");
                    usage();
                    exit(1);
                }
                usage();
                exit(1);
        }

    setbuf(onf, NULL);

    //Set UDP Socket
    set_dest(raddr, rport);
    set_sock();

    if ((fd = open(DEV_FSEVENTS, O_RDONLY)) < 0) {
        perror("open");
        exit(1);
    }

    fca.event_list = (int8_t *)event_list;
    fca.num_events = sizeof(event_list)/sizeof(int8_t);
    fca.event_queue_depth = EVENT_QUEUE_SIZE;
    fca.fd = &clonefd; 
    if ((ret = ioctl(fd, FSEVENTS_CLONE, (char *)&fca)) < 0) {
        perror("ioctl");
        close(fd);
        exit(1);
    }

    close(fd);

    //YAML comments lines start with '#'. Use this for debug and status statements
    snprintf(msg, MAX_DATA,"#fsevents device cloned (fd %d)\n#fslogger ready\n",clonefd);
    if (udp){
        send_packet(msg, strlen(msg));
    } else {
        fprintf(onf,"%s",msg);
        // Since we use setbuf this might not be necessary. Let's do it anyway.
        fflush(onf);
    }

    if ((ret = ioctl(clonefd, FSEVENTS_WANT_EXTENDED_INFO, NULL)) < 0) {
        perror("ioctl");
        close(clonefd);
        exit(1);
    }

    while (1) { // event processing loop

        if ((ret = read(clonefd, buffer, FSEVENT_BUFSIZ)) > 0){
            snprintf(msg, MAX_DATA, "# => received %d bytes\n", ret);
            if (udp){
                send_packet(msg, strlen(msg));
            } else {
                fprintf(onf,"%s", msg);
                fflush(onf);
            }
        }

        off = 0;

        while (off < ret) { // process one or more events received
        
            // Start message over
            mlen = 0;

            struct kfs_event *kfse = (struct kfs_event *)((char *)buffer + off);

            off += sizeof(int32_t) + sizeof(pid_t); // type + pid

            //Use snprintf for formatting to permit concantenting the message together
            mlen += snprintf(msg + mlen, MAX_DATA, "---\n");

            if (kfse->type == FSE_EVENTS_DROPPED) { // special event
                mlen += snprintf(msg + mlen, MAX_DATA, "Event:\n");
                mlen += snprintf(msg + mlen, MAX_DATA, " %s: %s\n", "type", "EVENTS_DROPPED");
                mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "pid", kfse->pid);
                // Special event with continue. So send data then restart loop
                if (udp){
                    send_packet(msg, strlen(msg));
                } else {
                    fprintf(onf,"%s", msg);
                    fflush(onf);
                }

                off += sizeof(u_int16_t); // FSE_ARG_DONE: sizeof(type)
                continue;
            }

            int32_t atype = kfse->type & FSE_TYPE_MASK;
            uint32_t aflags = FSE_GET_FLAGS(kfse->type);

            if ((atype < FSE_MAX_EVENTS) && (atype >= -1)) {
                mlen += snprintf(msg + mlen, MAX_DATA, "Event:\n");
                mlen += snprintf(msg + mlen, MAX_DATA, " %s: %s", "type", kfseNames[atype]);
                if (aflags & FSE_COMBINED_EVENTS) {
                    mlen += snprintf(msg + mlen, MAX_DATA,"%s", ", combined events");
                }
                if (aflags & FSE_CONTAINS_DROPPED_EVENTS) {
                    mlen += snprintf(msg + mlen, MAX_DATA, "%s", ", contains dropped events");
                }
                mlen += snprintf(msg + mlen,MAX_DATA, "%s","\n");


            } else { // should never happen
                mlen += snprintf(msg + mlen, MAX_DATA, "# This may be a program bug (type = %d).\n", atype);
                // Special event with exit. So send data
                if (udp){
                    send_packet(msg, strlen(msg));
                } else {
                    fprintf(onf,"%s", msg);
                    fflush(onf);
                }
                exit(1);
            }

            mlen += snprintf(msg + mlen, MAX_DATA, " %s: %d\n", "pid", kfse->pid);
            mlen += snprintf(msg + mlen, MAX_DATA, " %s: %s\n", "pname", get_proc_name(kfse->pid));

            mlen += snprintf(msg + mlen, MAX_DATA, "%s", "Details:\n");

            kea = kfse->args; 
            i = 0;

            //while ((off < ret) && (i <= FSE_MAX_ARGS)) { // process arguments
            while (off < ret) {

                i++;

                if (kea->type == FSE_ARG_DONE) { // no more arguments
                    mlen += snprintf(msg + mlen, MAX_DATA, " %s:\n", "FSE_ARG_DONE");
                    // Added Length for FSE_ARG_DONE to be consistent with other values
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %d\n", "len", 0);
                    // Added Type for FSE_ARG_DONE to be consistent with other values
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %d\n", "type", kea->type);

                    //This should be the only time to send data for a YAML doc which is a full FSEVENT
                    if (udp){
                        send_packet(msg, strlen(msg));
                    } else {
                        fprintf(onf,"%s", msg);
                        fflush(onf);
                    }
                    det = 0;
                    off += sizeof(u_int16_t);
                    break;
                }

                eoff = sizeof(kea->type) + sizeof(kea->len) + kea->len;
                off += eoff;

                arg_id = (kea->type > FSE_MAX_ARGS) ? 0 : kea->type;
                // Do no put detail marker on timestamp
                if (arg_id == 5){
                    mlen += snprintf(msg + mlen, MAX_DATA, " %s:\n", kfseArgNames[arg_id]);
                } else {
                    mlen += snprintf(msg + mlen, MAX_DATA, " %s_%d:\n", kfseArgNames[arg_id],det);
                }
                mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %d\n", "len", kea->len);

                switch (kea->type) { // handle based on argument type

                case FSE_ARG_VNODE:  // a vnode (string) pointer
                    is_fse_arg_vnode = 1;
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %s\n", "path", (char *)&(kea->data.vp));
                    break;

                case FSE_ARG_STRING: // a string pointer
                    // Added double quotes to protect strings with ":"s 
                    // Actually, to handle "\" it needs to be a single quote
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: \'%s\'\n", "string", (char *)&(kea->data.str)-4);
                    break;

                case FSE_ARG_INT32:
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %d\n", "int32", kea->data.int32);
                    break;

                case FSE_ARG_RAW: // a void pointer
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: ", "ptr");
                    for (j = 0; j < kea->len; j++)
                        mlen += snprintf(msg + mlen, MAX_DATA, "%02x ", ((char *)kea->data.ptr)[j]);
                    mlen += snprintf(msg + mlen, MAX_DATA, "%s", "\n");
                    break;

                case FSE_ARG_INO: // an inode number
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %d\n", "ino", (int)kea->data.ino);
                    break;

                case FSE_ARG_UID: // a user ID
                    p = getpwuid(kea->data.uid);
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %d (%s)\n", "uid", kea->data.uid, (p) ? p->pw_name : "?");
                    break;

                case FSE_ARG_DEV: // a file system ID or a device number
                    if (is_fse_arg_vnode) {
                        mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %#08x\n", "fsid", kea->data.dev);
                        is_fse_arg_vnode = 0;
                    } else {
                        mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %#08x (major %u, minor %u)\n", "dev", kea->data.dev, major(kea->data.dev), minor(kea->data.dev));
                    }
                    break;

                case FSE_ARG_MODE: // a combination of file mode and file type
                    va_mode = (kea->data.mode & 0x0000ffff);
                    va_type = (kea->data.mode & 0xfffff000);
                    strmode(va_mode, fileModeString);
                    va_type = iftovt_tab[(va_type & S_IFMT) >> 12];
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %s (%#08x, vnode type %s)", "mode", fileModeString, kea->data.mode, (va_type < VTYPE_MAX) ?  vtypeNames[va_type] : "?");
                    if (kea->data.mode & FSE_MODE_HLINK) {
                        mlen += snprintf(msg + mlen, MAX_DATA, "%s", ", hard link");
                    }
                    if (kea->data.mode & FSE_MODE_LAST_HLINK) {
                        mlen += snprintf(msg + mlen, MAX_DATA, "%s", ", link count zero now");
                    }
                    mlen += snprintf(msg + mlen, MAX_DATA, "%s", "\n");
                    break;

                case FSE_ARG_GID: // a group ID
                    g = getgrgid(kea->data.gid);
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %d (%s)\n", "gid", kea->data.gid, (g) ? g->gr_name : "?");
                    // This is usually the last value before everything repeats. Inc det
                    det += 1;
                    break;

                case FSE_ARG_INT64: // timestamp
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s: %llu\n", "tstamp", kea->data.timestamp);
                    break;

                default:
                    mlen += snprintf(msg + mlen, MAX_DATA, "   %s = ?\n", "unknown");
                    break;
                }

                kea = (kfs_event_arg_t *)((char *)kea + eoff); // next
            } // for each argument
        } // for each event
    } // forever

    close(clonefd);

    // Only close output file if it is not stdout
    if (argc == 2) {
        fclose(onf);
    }

    exit(0);
}
Пример #17
0
void monster::plan(const mfactions &factions)
{
    // Bots are more intelligent than most living stuff
    bool electronic = has_flag( MF_ELECTRONIC );
    Creature *target = nullptr;
    // 8.6f is rating for tank drone 60 tiles away, moose 16 or boomer 33
    float dist = !electronic ? 1000 : 8.6f;
    int bresenham_slope = 0;
    int selected_slope = 0;
    bool fleeing = false;
    bool docile = has_flag( MF_VERMIN ) || ( friendly != 0 && has_effect( "docile" ) );
    bool angers_hostile_weak = type->anger.find( MTRIG_HOSTILE_WEAK ) != type->anger.end();
    int angers_hostile_near = ( type->anger.find( MTRIG_HOSTILE_CLOSE ) != type->anger.end() ) ? 5 : 0;
    int fears_hostile_near = ( type->fear.find( MTRIG_HOSTILE_CLOSE ) != type->fear.end() ) ? 5 : 0;
    bool group_morale = has_flag( MF_GROUP_MORALE ) && morale < type->morale;
    bool swarms = has_flag( MF_SWARMS );
    auto mood = attitude();

    // If we can see the player, move toward them or flee.
    if( friendly == 0 && sees( g->u, bresenham_slope ) ) {
        dist = rate_target( g->u, bresenham_slope, dist, electronic );
        fleeing = fleeing || is_fleeing( g->u );
        target = &g->u;
        selected_slope = bresenham_slope;
        if( dist <= 5 ) {
            anger += angers_hostile_near;
            morale -= fears_hostile_near;
        }
    } else if( friendly != 0 && !docile ) {
        // Target unfriendly monsters, only if we aren't interacting with the player.
        for( int i = 0, numz = g->num_zombies(); i < numz; i++ ) {
            monster &tmp = g->zombie( i );
            if( tmp.friendly == 0 ) {
                float rating = rate_target( tmp, bresenham_slope, dist, electronic );
                if( rating < dist ) {
                    target = &tmp;
                    dist = rating;
                    selected_slope = bresenham_slope;
                }
            }
        }
    }

    if( !docile ) {
        for( size_t i = 0; i < g->active_npc.size(); i++ ) {
            npc *me = g->active_npc[i];
            float rating = rate_target( *me, bresenham_slope, dist, electronic );
            bool fleeing_from = is_fleeing( *me );
            // Switch targets if closer and hostile or scarier than current target
            if( ( rating < dist && fleeing ) ||
                ( rating < dist && attitude( me ) == MATT_ATTACK ) ||
                ( !fleeing && fleeing_from ) ) {
                    target = me;
                    dist = rating;
                    selected_slope = bresenham_slope;
            }
            fleeing = fleeing || fleeing_from;
            if( rating <= 5 ) {
                anger += angers_hostile_near;
                morale -= fears_hostile_near;
            }
        }
    }

    fleeing = fleeing || ( mood == MATT_FLEE );
    if( friendly == 0 && !docile ) {
        for( const auto &fac : factions ) {
            auto faction_att = faction->attitude( fac.first );
            if( faction_att == MFA_NEUTRAL || faction_att == MFA_FRIENDLY ) {
                continue;
            }

            for( int i : fac.second ) { // mon indices
                monster &mon = g->zombie( i );
                float rating = rate_target( mon, bresenham_slope, dist, electronic );
                if( rating < dist ) {
                    target = &mon;
                    dist = rating;
                    selected_slope = bresenham_slope;
                }
                if( rating <= 5 ) {
                    anger += angers_hostile_near;
                    morale -= fears_hostile_near;
                }
            }
        }
    }

    // Friendly monsters here
    // Avoid for hordes of same-faction stuff or it could get expensive
    const monfaction *actual_faction = friendly == 0 ? faction : GetMFact( "player" );
    auto const &myfaction_iter = factions.find( actual_faction );
    if( myfaction_iter == factions.end() ) {
        DebugLog( D_ERROR, D_GAME ) << disp_name() << " tried to find faction " << 
            ( friendly == 0 ? faction->name : "player" ) << " which wasn't loaded in game::monmove";
        swarms = false;
        group_morale = false;
    }
    swarms = swarms && target == nullptr; // Only swarm if we have no target
    if( group_morale || swarms ) {
        auto const &myfaction = myfaction_iter->second;
        for( int i : myfaction ) {
            monster &mon = g->zombie( i );
            float rating = rate_target( mon, bresenham_slope, dist, electronic );
            if( group_morale && rating <= 10 ) {
                morale += 10 - rating;
            }
            if( swarms ) {
                if( rating < 5 ) { // Too crowded here
                    wandx = posx() * rng( 1, 3 ) - mon.posx();
                    wandy = posy() * rng( 1, 3 ) - mon.posy();
                    wandf = 2;
                    target = nullptr;
                    // Swarm to the furthest ally you can see
                } else if( rating < INT_MAX && rating > dist && wandf <= 0 ) {
                    target = &mon;
                    dist = rating;
                    selected_slope = bresenham_slope;
                }
            }
        }
    }

    if( target != nullptr ) {
        if( one_in( 2 ) ) { // Random for the diversity of the trajectory
            ++selected_slope;
        } else {
            --selected_slope;
        }

        point dest = target->pos();
        auto att_to_target = attitude_to( *target );
        if( att_to_target == Attitude::A_HOSTILE && !fleeing ) {
            set_dest( dest.x, dest.y, selected_slope );
        } else if( fleeing ) {
            set_dest( posx() * 2 - dest.x, posy() * 2 - dest.y, selected_slope );
        }
        if( angers_hostile_weak && att_to_target != Attitude::A_FRIENDLY ) {
            int hp_per = target->hp_percentage();
            if( hp_per <= 70 ) {
                anger += 10 - int( hp_per / 10 );
            }
        }
    } else if( friendly > 0 && one_in(3)) {
            // Grow restless with no targets
            friendly--;
    } else if( friendly < 0 && sees( g->u, bresenham_slope ) ) {
        if( rl_dist( pos(), g->u.pos() ) > 2 ) {
            set_dest(g->u.posx(), g->u.posy(), bresenham_slope);
        } else {
            plans.clear();
        }
    }
    // If we're not adjacent to the start of our plan path, don't act on it.
    // This is to catch when we had pre-existing invalid plans and
    // made it through the function without changing them.
    if( !plans.empty() && square_dist(pos().x, pos().y,
                                      plans.front().x, plans.front().y ) > 1 ) {
        plans.clear();
    }
}
Пример #18
0
int
copy(void)
{
	ARCHD *arcn;
	int res;
	int fddest;
	char *dest_pt;
	int dlen;
	int drem;
	int fdsrc = -1;
	struct stat sb;
	char dirbuf[PAXPATHLEN+1];

	arcn = &archd;
	/*
	 * set up the destination dir path and make sure it is a directory. We
	 * make sure we have a trailing / on the destination
	 */
	dlen = strlcpy(dirbuf, dirptr, sizeof(dirbuf));
	if (dlen >= sizeof(dirbuf) ||
	    (dlen == sizeof(dirbuf) - 1 && dirbuf[dlen - 1] != '/')) {
		tty_warn(1, "directory name is too long %s", dirptr);
		return 1;
	}
	dest_pt = dirbuf + dlen;
	if (*(dest_pt-1) != '/') {
		*dest_pt++ = '/';
		++dlen;
	}
	*dest_pt = '\0';
	drem = PAXPATHLEN - dlen;

	if (stat(dirptr, &sb) < 0) {
		syswarn(1, errno, "Cannot access destination directory %s",
			dirptr);
		return 1;
	}
	if (!S_ISDIR(sb.st_mode)) {
		tty_warn(1, "Destination is not a directory %s", dirptr);
		return 1;
	}

	/*
	 * start up the hard link table; file traversal routines and the
	 * modification time and access mode database
	 */
	if ((lnk_start() < 0) || (ftree_start() < 0) || (dir_start() < 0))
		return 1;

	/*
	 * When we are doing interactive rename, we store the mapping of names
	 * so we can fix up hard links files later in the archive.
	 */
	if (iflag && (name_start() < 0))
		return 1;

	/*
	 * set up to cp file trees
	 */
	cp_start();

	/*
	 * while there are files to archive, process them
	 */
	while (next_file(arcn) == 0) {
		fdsrc = -1;

		/*
		 * check if this file meets user specified options
		 */
		if (sel_chk(arcn) != 0)
			continue;

		/*
		 * if there is already a file in the destination directory with
		 * the same name and it is newer, skip the one stored on the
		 * archive.
		 * NOTE: this test is done BEFORE name modifications as
		 * specified by pax. this can be confusing to the user who
		 * might expect the test to be done on an existing file AFTER
		 * the name mod. In honesty the pax spec is probably flawed in
		 * this respect
		 */
		if (uflag || Dflag) {
			/*
			 * create the destination name
			 */
			if (strlcpy(dest_pt, arcn->name + (*arcn->name == '/'),
			    drem + 1) > drem) {
				tty_warn(1, "Destination pathname too long %s",
					arcn->name);
				continue;
			}

			/*
			 * if existing file is same age or newer skip
			 */
			res = lstat(dirbuf, &sb);
			*dest_pt = '\0';

			if (res == 0) {
				if (uflag && Dflag) {
					if ((arcn->sb.st_mtime<=sb.st_mtime) &&
					    (arcn->sb.st_ctime<=sb.st_ctime))
						continue;
				} else if (Dflag) {
					if (arcn->sb.st_ctime <= sb.st_ctime)
						continue;
				} else if (arcn->sb.st_mtime <= sb.st_mtime)
					continue;
			}
		}

		/*
		 * this file is considered selected. See if this is a hard link
		 * to a previous file; modify the name as requested by the
		 * user; set the final destination.
		 */
		ftree_sel(arcn);
		if ((chk_lnk(arcn) < 0) || ((res = mod_name(arcn, RENM)) < 0))
			break;
		if ((res > 0) || (set_dest(arcn, dirbuf, dlen) < 0)) {
			/*
			 * skip file, purge from link table
			 */
			purg_lnk(arcn);
			continue;
		}

		/*
		 * Non standard -Y and -Z flag. When the exisiting file is
		 * same age or newer skip
		 */
		if ((Yflag || Zflag) && ((lstat(arcn->name, &sb) == 0))) {
			if (Yflag && Zflag) {
				if ((arcn->sb.st_mtime <= sb.st_mtime) &&
				    (arcn->sb.st_ctime <= sb.st_ctime))
					continue;
			} else if (Yflag) {
				if (arcn->sb.st_ctime <= sb.st_ctime)
					continue;
			} else if (arcn->sb.st_mtime <= sb.st_mtime)
				continue;
		}

		if (vflag) {
			(void)safe_print(arcn->name, listf);
			vfpart = 1;
		}
		++flcnt;

		/*
		 * try to create a hard link to the src file if requested
		 * but make sure we are not trying to overwrite ourselves.
		 */
		if (lflag)
			res = cross_lnk(arcn);
		else
			res = chk_same(arcn);
		if (res <= 0) {
			if (vflag && vfpart) {
				(void)putc('\n', listf);
				vfpart = 0;
			}
			continue;
		}

		/*
		 * have to create a new file
		 */
		if ((arcn->type != PAX_REG) && (arcn->type != PAX_CTG)) {
			/*
			 * create a link or special file
			 */
			if ((arcn->type == PAX_HLK) ||
			    (arcn->type == PAX_HRG)) {
				int payload;

				res = lnk_creat(arcn, &payload);
			} else {
				res = node_creat(arcn);
			}
			if (res < 0)
				purg_lnk(arcn);
			if (vflag && vfpart) {
				(void)putc('\n', listf);
				vfpart = 0;
			}
			continue;
		}

		/*
		 * have to copy a regular file to the destination directory.
		 * first open source file and then create the destination file
		 */
		if ((fdsrc = open(arcn->org_name, O_RDONLY, 0)) < 0) {
			syswarn(1, errno, "Unable to open %s to read",
			    arcn->org_name);
			purg_lnk(arcn);
			continue;
		}
		if ((fddest = file_creat(arcn, 0)) < 0) {
			rdfile_close(arcn, &fdsrc);
			purg_lnk(arcn);
			continue;
		}

		/*
		 * copy source file data to the destination file
		 */
		cp_file(arcn, fdsrc, fddest);
		file_close(arcn, fddest);
		rdfile_close(arcn, &fdsrc);

		if (vflag && vfpart) {
			(void)putc('\n', listf);
			vfpart = 0;
		}
	}

	/*
	 * restore directory modes and times as required; make sure all
	 * patterns were selected block off signals to avoid chance for
	 * multiple entry into the cleanup code.
	 */
	(void)sigprocmask(SIG_BLOCK, &s_mask, (sigset_t *)NULL);
	ar_close();
	proc_dir();
	ftree_chk();

	return 0;
}
Пример #19
0
void monster::plan( const mfactions &factions )
{
    // Bots are more intelligent than most living stuff
    bool smart_planning = has_flag( MF_PRIORITIZE_TARGETS );
    Creature *target = nullptr;
    // 8.6f is rating for tank drone 60 tiles away, moose 16 or boomer 33
    float dist = !smart_planning ? 1000 : 8.6f;
    bool fleeing = false;
    bool docile = friendly != 0 && has_effect( effect_docile );
    bool angers_hostile_weak = type->anger.find( MTRIG_HOSTILE_WEAK ) != type->anger.end();
    int angers_hostile_near =
        ( type->anger.find( MTRIG_HOSTILE_CLOSE ) != type->anger.end() ) ? 5 : 0;
    int fears_hostile_near = ( type->fear.find( MTRIG_HOSTILE_CLOSE ) != type->fear.end() ) ? 5 : 0;
    bool group_morale = has_flag( MF_GROUP_MORALE ) && morale < type->morale;
    bool swarms = has_flag( MF_SWARMS );
    auto mood = attitude();

    // If we can see the player, move toward them or flee.
    if( friendly == 0 && sees( g->u ) ) {
        dist = rate_target( g->u, dist, smart_planning );
        fleeing = fleeing || is_fleeing( g->u );
        target = &g->u;
        if( dist <= 5 ) {
            anger += angers_hostile_near;
            morale -= fears_hostile_near;
        }
    } else if( friendly != 0 && !docile ) {
        // Target unfriendly monsters, only if we aren't interacting with the player.
        for( int i = 0, numz = g->num_zombies(); i < numz; i++ ) {
            monster &tmp = g->zombie( i );
            if( tmp.friendly == 0 ) {
                float rating = rate_target( tmp, dist, smart_planning );
                if( rating < dist ) {
                    target = &tmp;
                    dist = rating;
                }
            }
        }
    }

    if( docile ) {
        if( friendly != 0 && target != nullptr ) {
            set_dest( target->pos() );
        }

        return;
    }

    for( size_t i = 0; i < g->active_npc.size(); i++ ) {
        npc &who = *g->active_npc[i];
        auto faction_att = faction.obj().attitude( who.get_monster_faction() );
        if( faction_att == MFA_NEUTRAL || faction_att == MFA_FRIENDLY ) {
            continue;
        }

        float rating = rate_target( who, dist, smart_planning );
        bool fleeing_from = is_fleeing( who );
        // Switch targets if closer and hostile or scarier than current target
        if( ( rating < dist && fleeing ) ||
            ( rating < dist && attitude( &who ) == MATT_ATTACK ) ||
            ( !fleeing && fleeing_from ) ) {
            target = &who;
            dist = rating;
        }
        fleeing = fleeing || fleeing_from;
        if( rating <= 5 ) {
            anger += angers_hostile_near;
            morale -= fears_hostile_near;
        }
    }

    fleeing = fleeing || ( mood == MATT_FLEE );
    if( friendly == 0 ) {
        for( const auto &fac : factions ) {
            auto faction_att = faction.obj().attitude( fac.first );
            if( faction_att == MFA_NEUTRAL || faction_att == MFA_FRIENDLY ) {
                continue;
            }

            for( int i : fac.second ) { // mon indices
                monster &mon = g->zombie( i );
                float rating = rate_target( mon, dist, smart_planning );
                if( rating < dist ) {
                    target = &mon;
                    dist = rating;
                }
                if( rating <= 5 ) {
                    anger += angers_hostile_near;
                    morale -= fears_hostile_near;
                }
            }
        }
    }

    // Friendly monsters here
    // Avoid for hordes of same-faction stuff or it could get expensive
    const auto actual_faction = friendly == 0 ? faction : mfaction_str_id( "player" );
    auto const &myfaction_iter = factions.find( actual_faction );
    if( myfaction_iter == factions.end() ) {
        DebugLog( D_ERROR, D_GAME ) << disp_name() << " tried to find faction "
                                    << actual_faction.id().str()
                                    << " which wasn't loaded in game::monmove";
        swarms = false;
        group_morale = false;
    }
    swarms = swarms && target == nullptr; // Only swarm if we have no target
    if( group_morale || swarms ) {
        for( const int i : myfaction_iter->second ) {
            monster &mon = g->zombie( i );
            float rating = rate_target( mon, dist, smart_planning );
            if( group_morale && rating <= 10 ) {
                morale += 10 - rating;
            }
            if( swarms ) {
                if( rating < 5 ) { // Too crowded here
                    wander_pos.x = posx() * rng( 1, 3 ) - mon.posx();
                    wander_pos.y = posy() * rng( 1, 3 ) - mon.posy();
                    wandf = 2;
                    target = nullptr;
                    // Swarm to the furthest ally you can see
                } else if( rating < INT_MAX && rating > dist && wandf <= 0 ) {
                    target = &mon;
                    dist = rating;
                }
            }
        }
    }

    if( target != nullptr ) {

        tripoint dest = target->pos();
        auto att_to_target = attitude_to( *target );
        if( att_to_target == Attitude::A_HOSTILE && !fleeing ) {
            set_dest( dest );
        } else if( fleeing ) {
            set_dest( tripoint( posx() * 2 - dest.x, posy() * 2 - dest.y, posz() ) );
        }
        if( angers_hostile_weak && att_to_target != Attitude::A_FRIENDLY ) {
            int hp_per = target->hp_percentage();
            if( hp_per <= 70 ) {
                anger += 10 - int( hp_per / 10 );
            }
        }
    } else if( friendly > 0 && one_in( 3 ) ) {
        // Grow restless with no targets
        friendly--;
    } else if( friendly < 0 && sees( g->u ) ) {
        if( rl_dist( pos(), g->u.pos() ) > 2 ) {
            set_dest( g->u.pos() );
        } else {
            unset_dest();
        }
    }
}
Пример #20
0
 void set_dest(dstT * const dst,const size_t len/*in units of sizeof(dstT)*/) {
     set_dest(dst,dst+len);
 }
Пример #21
0
void monster::plan(game *g)
{
 int sightrange = g->light_level();
 int closest = -1;
 int dist = 1000;
 int tc, stc;
 if (friendly != 0) {	// Target monsters, not the player!
  for (int i = 0; i < g->z.size(); i++) {
   monster *tmp = &(g->z[i]);
   if (tmp->friendly == 0 && rl_dist(posx, posy, tmp->posx, tmp->posy) < dist &&
       g->m.sees(posx, posy, tmp->posx, tmp->posy, sightrange, tc)) {
    closest = i;
    dist = rl_dist(posx, posy, tmp->posx, tmp->posy);
    stc = tc;
   }
  }
  if (closest >= 0)
   set_dest(g->z[closest].posx, g->z[closest].posy, stc);
  else if (friendly > 0 && one_in(3))	// Grow restless with no targets
   friendly--;
  else if (friendly < 0 && g->sees_u(posx, posy, tc)) {
   if (rl_dist(posx, posy, g->u.posx, g->u.posy) > 2)
    set_dest(g->u.posx, g->u.posy, tc);
   else
    plans.clear();
  }
  return;
 }
 if (is_fleeing(g->u) && can_see() && g->sees_u(posx, posy, tc) &&
     (!g->u.has_trait(PF_ANIMALEMPATH) || !has_flag(MF_ANIMAL))) {
  wandx = posx * 2 - g->u.posx;
  wandy = posy * 2 - g->u.posy;
  wandf = 40;
 }
// If we can see, and we can see a character, start moving towards them
 if (!is_fleeing(g->u) && can_see()) {
  if (g->sees_u(posx, posy, tc)) {
   dist = rl_dist(posx, posy, g->u.posx, g->u.posy);
   closest = -2;
   stc = tc;
  }
  for (int i = 0; i < g->active_npc.size(); i++) {
   npc *me = &(g->active_npc[i]);
   if (rl_dist(posx, posy, me->posx, me->posy) < dist &&
       g->m.sees(posx, posy, me->posx, me->posy, sightrange, tc)) {
    dist = rl_dist(posx, posy, me->posx, me->posy);
    closest = i;
    stc = tc;
   }
  }
  for (int i = 0; i < g->z.size(); i++) {
   monster *mon = &(g->z[i]);
   if (mon->friendly != 0 && rl_dist(posx, posy, mon->posx, mon->posy) < dist &&
       g->m.sees(posx, posy, mon->posx, mon->posy, sightrange, tc)) {
    dist = rl_dist(posx, posy, mon->posx, mon->posy);
    closest = -3 - i;
    stc = tc;
   }
  }
  if (closest == -2)
   set_dest(g->u.posx, g->u.posy, stc);
  else if (closest <= -3)
   set_dest(g->z[-3 - closest].posx, g->z[-3 - closest].posy, stc);
  else if (closest >= 0)
   set_dest(g->active_npc[closest].posx, g->active_npc[closest].posy, stc);
 }
}
Пример #22
0
int main (int argc, char **argv)
{
    int			c;
    unsigned short	port = 0;
    binding_t		*source = 0;
    binding_t		*dest = 0;

    binding_t		*s, *d;

    char		packet[8192];
    int			n;
    int			i;
    int			nsource;
    int			soopts;
    int			verbose = 0;
    int			source_set = 0;
    int			dest_set = 0;
    struct pollfd	*fds;

    while ((c = getopt (argc, argv, "vp:s:d:")) >= 0)
    {
        switch (c) {
        case 'p':
            port = atoi (optarg);
            if (port <= 0)
                usage (argv[0]);
            break;
        case 's':
            s = make_binding (optarg);
            s->next = source;
            source = s;
            break;
        case 'd':
            d = make_binding (optarg);
            d->next = dest;
            dest = d;
            break;
        case 'v':
            verbose++;
            break;
        default:
            usage (argv[0]);
            break;
        }
    }
    if (!port || !source || !dest)
        usage (argv[0]);

    nsource = 0;
    for (s = source; s; s = s->next)
    {
        set_source (s, port);
        if (verbose)
            dump_addr (s->fd, "source", 0);
        nsource++;
    }

    if (nsource > 1)
    {
        fds = malloc (nsource * sizeof (struct pollfd));
        if (!fds)
            losing (argv[0], "malloc fds");

        i = 0;
        for (s = source; s; s = s->next)
        {
            fds[i].fd = s->fd;
            fds[i].events = POLLIN;
            fds[i].revents = 0;
        }
    }
    else
        fds = 0;

    for (d = dest; d; d = d->next)
    {
        set_dest (d, port);
        if (verbose)
            dump_addr (d->fd, "dest", 1);
    }

    /* spend a while shipping packets around */
    for (;;)
    {
        if (fds)
        {
            i = poll (fds, nsource, -1);
            if (i < 0)
                break;
        }

        i = 0;
        for (s = source, i = 0; s; s = s->next, i++)
        {
            if (!fds || fds[i].revents & POLLIN)
            {
                n = read (s->fd, packet, sizeof (packet));
                if (n < 0)
                    losing (argv[0], "read");
                if (verbose)
                    fprintf (stderr, "%d\n", n );
                for (d = dest; d; d = d->next)
                {
                    if (write (d->fd, packet, n) < n)
                        losing (argv[0], "write");
                }
            }
        }
    }
}
Пример #23
0
void monster::plan(game *g)
{
 int sightrange = g->light_level();
 int closest = -1;
 int dist = 1000;
 int tc, stc;
 bool fleeing = false;
 if (friendly != 0) {	// Target monsters, not the player!
  for (int i = 0; i < g->z.size(); i++) {
   monster *tmp = &(g->z[i]);
   if (tmp->friendly == 0 && rl_dist(posx, posy, tmp->posx, tmp->posy) < dist &&
       g->m.sees(posx, posy, tmp->posx, tmp->posy, sightrange, tc)) {
    closest = i;
    dist = rl_dist(posx, posy, tmp->posx, tmp->posy);
    stc = tc;
   }
  }
  if (has_effect(ME_DOCILE))
   closest = -1;
  if (closest >= 0)
   set_dest(g->z[closest].posx, g->z[closest].posy, stc);
  else if (friendly > 0 && one_in(3))	// Grow restless with no targets
   friendly--;
  else if (friendly < 0 && g->sees_u(posx, posy, tc)) {
   if (rl_dist(posx, posy, g->u.posx, g->u.posy) > 2)
    set_dest(g->u.posx, g->u.posy, tc);
   else
    plans.clear();
  }
  return;
 }
 if (is_fleeing(g->u) && can_see() && g->sees_u(posx, posy, tc)) {
  fleeing = true;
  wandx = posx * 2 - g->u.posx;
  wandy = posy * 2 - g->u.posy;
  wandf = 40;
  dist = rl_dist(posx, posy, g->u.posx, g->u.posy);
 }
// If we can see, and we can see a character, start moving towards them
 if (!is_fleeing(g->u) && can_see() && g->sees_u(posx, posy, tc)) {
  dist = rl_dist(posx, posy, g->u.posx, g->u.posy);
  closest = -2;
  stc = tc;
 }
 for (int i = 0; i < g->active_npc.size(); i++) {
  npc *me = (g->active_npc[i]);
  int medist = rl_dist(posx, posy, me->posx, me->posy);
  if ((medist < dist || (!fleeing && is_fleeing(*me))) &&
      (can_see() &&
       g->m.sees(posx, posy, me->posx, me->posy, sightrange, tc))) {
   if (is_fleeing(*me)) {
    fleeing = true;
    wandx = posx * 2 - me->posx;
    wandy = posy * 2 - me->posy;
    wandf = 40;
    dist = medist;
   } else if (can_see() &&
              g->m.sees(posx, posy, me->posx, me->posy, sightrange, tc)) {
    dist = rl_dist(posx, posy, me->posx, me->posy);
    closest = i;
    stc = tc;
   }
  }
 }
 if (!fleeing) {
  fleeing = attitude() == MATT_FLEE;
  for (int i = 0; i < g->z.size(); i++) {
   monster *mon = &(g->z[i]);
   int mondist = rl_dist(posx, posy, mon->posx, mon->posy);
   if (mon->friendly != 0 && mondist < dist && can_see() &&
       g->m.sees(posx, posy, mon->posx, mon->posy, sightrange, tc)) {
    dist = mondist;
    if (fleeing) {
     wandx = posx * 2 - mon->posx;
     wandy = posy * 2 - mon->posy;
     wandf = 40;
    } else {
     closest = -3 - i;
     stc = tc;
    }
   }
  }
 }
 if (!fleeing) {
  if (closest == -2)
   set_dest(g->u.posx, g->u.posy, stc);
  else if (closest <= -3)
   set_dest(g->z[-3 - closest].posx, g->z[-3 - closest].posy, stc);
  else if (closest >= 0)
   set_dest(g->active_npc[closest]->posx, g->active_npc[closest]->posy, stc);
 }
}
Пример #24
0
 void set_dest(dst_string &dst) { /* PRIVATE: External use can easily cause use-after-free bugs */
     set_dest(&dst[0],dst.size());
 }
Пример #25
0
void monster::plan(const std::vector<int> &friendlies)
{
    int sightrange = g->light_level();
    int closest = -1;
    int dist = 1000;
    int tc = 0;
    int stc = 0;
    bool fleeing = false;
    if (friendly != 0) { // Target monsters, not the player!
        for (int i = 0, numz = g->num_zombies(); i < numz; i++) {
            monster *tmp = &(g->zombie(i));
            if (tmp->friendly == 0) {
                int d = rl_dist(posx(), posy(), tmp->posx(), tmp->posy());
                if (d < dist && g->m.sees(posx(), posy(), tmp->posx(), tmp->posy(), sightrange, tc)) {
                    closest = i;
                    dist = d;
                    stc = tc;
                }
            }
        }

        if (has_effect("docile")) {
            closest = -1;
        }

        if (closest >= 0) {
            set_dest(g->zombie(closest).posx(), g->zombie(closest).posy(), stc);
        } else if (friendly > 0 && one_in(3)) {
            // Grow restless with no targets
            friendly--;
        } else if (friendly < 0 &&  sees_player( tc ) ) {
            if (rl_dist(posx(), posy(), g->u.posx, g->u.posy) > 2) {
                set_dest(g->u.posx, g->u.posy, tc);
            } else {
                plans.clear();
            }
        }
        return;
    }

    // If we can see, and we can see a character, move toward them or flee.
    if (can_see() && sees_player( tc ) ) {
        dist = rl_dist(posx(), posy(), g->u.posx, g->u.posy);
        if (is_fleeing(g->u)) {
            // Wander away.
            fleeing = true;
            set_dest(posx() * 2 - g->u.posx, posy() * 2 - g->u.posy, tc);
        } else {
            // Chase the player.
            closest = -2;
            stc = tc;
        }
    }

    for (int i = 0; i < g->active_npc.size(); i++) {
        npc *me = (g->active_npc[i]);
        int medist = rl_dist(posx(), posy(), me->posx, me->posy);
        if ((medist < dist || (!fleeing && is_fleeing(*me))) &&
                (can_see() &&
                 g->m.sees(posx(), posy(), me->posx, me->posy, sightrange, tc))) {
            if (is_fleeing(*me)) {
                fleeing = true;
                set_dest(posx() * 2 - me->posx, posy() * 2 - me->posy, tc);
                \
            } else {
                closest = i;
                stc = tc;
            }
            dist = medist;
        }
    }

    if (!fleeing) {
        fleeing = attitude() == MATT_FLEE;
        if (can_see()) {
            for (int f = 0, numf = friendlies.size(); f < numf; f++) {
                const int i = friendlies[f];
                monster *mon = &(g->zombie(i));
                int mondist = rl_dist(posx(), posy(), mon->posx(), mon->posy());
                if (mondist < dist &&
                        g->m.sees(posx(), posy(), mon->posx(), mon->posy(), sightrange, tc)) {
                    dist = mondist;
                    if (fleeing) {
                        wandx = posx() * 2 - mon->posx();
                        wandy = posy() * 2 - mon->posy();
                        wandf = 40;
                    } else {
                        closest = -3 - i;
                        stc = tc;
                    }
                }
            }
        }

        if (closest == -2) {
            if (one_in(2)) {//random for the diversity of the trajectory
                ++stc;
            } else {
                --stc;
            }
            set_dest(g->u.posx, g->u.posy, stc);
        }
        else if (closest <= -3)
            set_dest(g->zombie(-3 - closest).posx(), g->zombie(-3 - closest).posy(), stc);
        else if (closest >= 0)
            set_dest(g->active_npc[closest]->posx, g->active_npc[closest]->posy, stc);
    }
}
Пример #26
0
void monster::plan(const std::vector<int> &friendlies)
{
    int sightrange = g->light_level();
    int closest = -1;
    int dist = 1000;
    int tc = 0;
    int stc = 0;
    bool fleeing = false;

    if (friendly != 0) { // Target monsters, not the player!
        for (int i = 0, numz = g->num_zombies(); i < numz; i++) {
            monster *tmp = &(g->zombie(i));
            if (tmp->friendly == 0) {
                int d = rl_dist(posx(), posy(), tmp->posx(), tmp->posy());
                if (d < dist && g->m.sees(posx(), posy(), tmp->posx(), tmp->posy(), sightrange, tc)) {
                    closest = i;
                    dist = d;
                    stc = tc;
                }
            }
        }

        if (has_effect("docile")) {
            closest = -1;
        }

        if (closest >= 0) {
            set_dest(g->zombie(closest).posx(), g->zombie(closest).posy(), stc);
        } else if (friendly > 0 && one_in(3)) {
            // Grow restless with no targets
            friendly--;
        } else if (friendly < 0 &&  sees_player( tc ) ) {
            if (rl_dist(posx(), posy(), g->u.posx, g->u.posy) > 2) {
                set_dest(g->u.posx, g->u.posy, tc);
            } else {
                plans.clear();
            }
        }
        return;
    }

    // If we can see, and we can see a character, move toward them or flee.
    if (can_see() && sees_player( tc ) ) {
        dist = rl_dist(posx(), posy(), g->u.posx, g->u.posy);
        if (is_fleeing(g->u)) {
            // Wander away.
            fleeing = true;
            set_dest(posx() * 2 - g->u.posx, posy() * 2 - g->u.posy, tc);
        } else {
            // Chase the player.
            closest = -2;
            stc = tc;
        }
    }

    for (size_t i = 0; i < g->active_npc.size(); i++) {
        npc *me = (g->active_npc[i]);
        int medist = rl_dist(posx(), posy(), me->posx, me->posy);
        if ((medist < dist || (!fleeing && is_fleeing(*me))) &&
                (can_see() &&
                g->m.sees(posx(), posy(), me->posx, me->posy, sightrange, tc))) {
            if (is_fleeing(*me)) {
                fleeing = true;
                set_dest(posx() * 2 - me->posx, posy() * 2 - me->posy, tc);\
            } else {
                closest = i;
                stc = tc;
            }
            dist = medist;
        }
    }

    if (!fleeing) {
        fleeing = attitude() == MATT_FLEE;
        if (can_see()) {
            for( auto &friendlie : friendlies ) {
                const int i = friendlie;
                monster *mon = &(g->zombie(i));
                int mondist = rl_dist(posx(), posy(), mon->posx(), mon->posy());
                if (mondist < dist &&
                        g->m.sees(posx(), posy(), mon->posx(), mon->posy(), sightrange, tc)) {
                    dist = mondist;
                    if (fleeing) {
                        wandx = posx() * 2 - mon->posx();
                        wandy = posy() * 2 - mon->posy();
                        wandf = 40;
                    } else {
                        closest = -3 - i;
                        stc = tc;
                    }
                }
            }
        }

        if (closest == -2) {
            if (one_in(2)) {//random for the diversity of the trajectory
                ++stc;
            } else {
                --stc;
            }
            set_dest(g->u.posx, g->u.posy, stc);
        } else if (closest <= -3) {
            set_dest(g->zombie(-3 - closest).posx(), g->zombie(-3 - closest).posy(), stc);
        } else if (closest >= 0) {
            set_dest(g->active_npc[closest]->posx, g->active_npc[closest]->posy, stc);
        }
    }
    // If we're not adjacent to the start of our plan path, don't act on it.
    // This is to catch when we had pre-existing invalid plans and
    // made it through the function without changing them.
    if( !plans.empty() && square_dist(pos().x, pos().y,
                                      plans.front().x, plans.front().y ) > 1 ) {
        plans.clear();
    }
}