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(); }
/* 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(); } } }
/* 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(); } }
/* 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(); } }
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()); }
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; }
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); }
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(); }
/* 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(); } }
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; }
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; }
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); } }
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(); }
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); } }
/* 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(); } } }
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); }
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(); } }
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; }
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(); } } }
void set_dest(dstT * const dst,const size_t len/*in units of sizeof(dstT)*/) { set_dest(dst,dst+len); }
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); } }
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"); } } } } }
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); } }
void set_dest(dst_string &dst) { /* PRIVATE: External use can easily cause use-after-free bugs */ set_dest(&dst[0],dst.size()); }
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); } }
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(); } }