static void move( void ) { int taildir; /*this actually sets the dir variable.*/ get_direction(); /*draw head*/ switch (dir) { case (NORTH): board[headx][heady]=NORTH; heady--; break; case (EAST): board[headx][heady]=EAST; headx++; break; case (SOUTH): board[headx][heady]=SOUTH; heady++; break; case (WEST): board[headx][heady]=WEST; headx--; break; } if(headx == WIDTH) headx = 0; else if(headx < 0) headx = WIDTH-1; if(heady == HEIGHT) heady = 0; else if(heady < 0) heady = HEIGHT-1; draw_head_bit(headx, heady); /*clear tail*/ if(applecountdown <= 0) { rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID); draw_head_bit(tailx, taily); rb->lcd_set_drawmode(DRMODE_SOLID); taildir = board[tailx][taily]; board[tailx][taily] = 0; switch (taildir) { case(NORTH): taily--; break; case(EAST): tailx++; break; case(SOUTH): taily++; break; case(WEST): tailx--; break; } if(tailx == WIDTH) tailx = 0; else if(tailx < 0) tailx = WIDTH-1; if(taily == HEIGHT) taily = 0; else if(taily < 0) taily = HEIGHT-1; } else applecountdown--; }
/** * \brief Returns whether the hero is correctly placed to * start jumping with this jumper. * \param hero The hero. * \param candidate_position The candidate bounding box. * \param extended_region Whether you want to consider the extended jumper * beyond its bounding box, or to keep it restricted to its bounding box. * \return \c true if the hero is correctly placed to start a jump. */ bool Jumper::is_in_jump_position( const Hero& hero, const Rectangle& candidate_position, bool extended_region) const { if (overlaps_jumping_region(candidate_position, extended_region)) { // Overlapping the active region: cannot start a jump from there. return false; } const int direction8 = get_direction(); const int expected_hero_direction4 = direction8 / 2; if (is_jump_diagonal()) { // Diagonal case: The sensor's shape is a diagonal bar. // The player should move toward one of both directions. if (!hero.is_moving_towards(expected_hero_direction4) && !hero.is_moving_towards((expected_hero_direction4 + 1) % 4)) { return false; } // Test if the appropriate corner of the hero crosses the diagonal. Point corner = { candidate_position.get_x() - 1, candidate_position.get_y() - 1 }; if (direction8 == 1 || direction8 == 7) { // Right-up or right-down. corner.x += candidate_position.get_width() + 1; } if (direction8 == 5 || direction8 == 7) { // Left-down or right-down. corner.y += candidate_position.get_height() + 1; } return extended_region ? is_point_in_extended_diagonal(corner) : is_point_in_diagonal(corner); } // Non-diagonal case: the sensor has one of the four main directions. // Its shape is exactly its rectangle. // The player should move toward the jumper's direction. if (!hero.is_moving_towards(expected_hero_direction4)) { return false; } Point facing_point; switch (expected_hero_direction4) { // right case 0: facing_point = { candidate_position.get_x() + 16, candidate_position.get_y() + 8 }; break; // up case 1: facing_point = { candidate_position.get_x() + 8, candidate_position.get_y() - 1 }; break; // left case 2: facing_point = { candidate_position.get_x() - 1, candidate_position.get_y() + 8 }; break; // down case 3: facing_point = { candidate_position.get_x() + 8, candidate_position.get_y() + 16 }; break; default: Debug::die("Invalid direction"); } if (is_jump_horizontal()) { if (extended_region) { // Are we inside the extended strip? return facing_point.x >= get_top_left_x() && facing_point.x < get_top_left_x() + get_width(); } else { // Are we inside the strip and the bounding box? return overlaps(facing_point.x, facing_point.y - 8) && overlaps(facing_point.x, facing_point.y + 7); } } else { // Same thing for a vertical jump. if (extended_region) { // Are we inside the extended strip? return facing_point.y >= get_top_left_y() && facing_point.y < get_top_left_y() + get_height(); } else { return overlaps(facing_point.x - 8, facing_point.y) && overlaps(facing_point.x + 7, facing_point.y); } } }
void game::compare(int iCompareX, int iCompareY) { int examx, examy; int ch = (int)'.'; if (iCompareX != -999 && iCompareX != -999) { examx = iCompareX; examy = iCompareY; } else { mvwprintw(w_terrain, 0, 0, "Compare where? (Direction button)"); wrefresh(w_terrain); ch = input(); last_action += ch; if (ch == KEY_ESCAPE || ch == 'q') return; if (ch == '\n' || ch == 'I') ch = '.'; get_direction(this, examx, examy, ch); if (examx == -2 || examy == -2) { add_msg("Invalid direction."); return; } } examx += u.posx; examy += u.posy; std::vector <item> here = m.i_at(examx, examy); std::vector <item> grounditems; //Filter out items with the same name (keep only one of them) std::map <std::string, bool> dups; for (int i = 0; i < here.size(); i++) { if (!dups[here[i].tname(this).c_str()]) { grounditems.push_back(here[i]); dups[here[i].tname(this).c_str()] = true; } } //Only the first 10 Items due to numbering 0-9 const int groundsize = (grounditems.size() > 10 ? 10 : grounditems.size()); u.inv.sort(); u.inv.restack(&u); invslice stacks = u.inv.slice(0, u.inv.size()); WINDOW* w_inv = newwin(TERMY-VIEW_OFFSET_Y*2, TERMX-VIEW_OFFSET_X*2, VIEW_OFFSET_Y, VIEW_OFFSET_X); int maxitems = TERMY-5-VIEW_OFFSET_Y*2; // Number of items to show at one time. std::vector<int> compare; // Count of how many we'll drop from each stack bool bFirst = false; // First Item selected bool bShowCompare = false; char cLastCh; compare.resize(u.inv.size() + groundsize, 0); std::vector<char> weapon_and_armor; // Always single, not counted print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); // Gun, ammo, weapon, armor, food, tool, book, other std::vector<int> first = find_firsts(stacks); std::vector<int> firsts; if (groundsize > 0) { firsts.push_back(0); } for (int i = 0; i < first.size(); i++) { firsts.push_back((first[i] >= 0) ? first[i]+groundsize : -1); } ch = '.'; int start = 0, cur_it; do { if (( ch == '<' || ch == KEY_PPAGE ) && start > 0) { for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); start -= maxitems; if (start < 0) start = 0; mvwprintw(w_inv, maxitems + 4, 0, " "); } if (( ch == '>' || ch == KEY_NPAGE ) && cur_it < u.inv.size() + groundsize) { start = cur_it; mvwprintw(w_inv, maxitems + 4, 12, " "); for (int i = 1; i < maxitems+4; i++) mvwprintz(w_inv, i, 0, c_black, " "); } int cur_line = 2; int iHeaderOffset = (groundsize > 0) ? 0 : 1; for (cur_it = start; cur_it < start + maxitems && cur_line < maxitems+3; cur_it++) { // Clear the current line; mvwprintw(w_inv, cur_line, 0, " "); // Print category header for (int i = iHeaderOffset; i < iCategorieNum; i++) { if (cur_it == firsts[i-iHeaderOffset]) { mvwprintz(w_inv, cur_line, 0, c_magenta, CATEGORIES[i].c_str()); cur_line++; } } if (cur_it < u.inv.size() + groundsize) { char icon = '-'; if (compare[cur_it] == 1) icon = '+'; if (cur_it < groundsize) { mvwputch (w_inv, cur_line, 0, c_white, '1'+((cur_it<9) ? cur_it: -1)); nc_color col = (compare[cur_it] == 0 ? c_ltgray : c_white); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, grounditems[cur_it].tname(this).c_str()); } else { item& it = stacks[cur_it-groundsize]->front(); mvwputch (w_inv, cur_line, 0, c_white, it.invlet); nc_color col = (compare[cur_it] == 0 ? c_ltgray : c_white); mvwprintz(w_inv, cur_line, 1, col, " %c %s", icon, it.tname(this).c_str()); if (stacks[cur_it-groundsize]->size() > 1) wprintz(w_inv, col, " [%d]", stacks[cur_it-groundsize]->size()); if (it.charges > 0) wprintz(w_inv, col, " (%d)", it.charges); else if (it.contents.size() == 1 && it.contents[0].charges > 0) wprintw(w_inv, " (%d)", it.contents[0].charges); } } cur_line++; } if (start > 0) mvwprintw(w_inv, maxitems + 4, 0, "< Go Back"); if (cur_it < u.inv.size() + groundsize) mvwprintw(w_inv, maxitems + 4, 12, "> More items"); wrefresh(w_inv); ch = getch(); if (u.has_item(ch)) { item& it = u.inv.item_by_letter(ch); if (it.is_null()) { // Not from inventory bool found = false; for (int i = 0; i < weapon_and_armor.size() && !found; i++) { if (weapon_and_armor[i] == ch) { weapon_and_armor.erase(weapon_and_armor.begin() + i); found = true; bFirst = false; print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); } } if (!found) { if ( ch == u.weapon.invlet && std::find(unreal_itype_ids.begin(), unreal_itype_ids.end(), u.weapon.type->id) != unreal_itype_ids.end()) { //Do Bionic stuff here?! } else { if (!bFirst) { weapon_and_armor.push_back(ch); print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } } else { int index = -1; for (int i = 0; i < stacks.size(); ++i) { if (stacks[i]->front().invlet == it.invlet) { index = i; break; } } if (index == -1) { debugmsg("Inventory got out of sync with inventory slice?"); } if (compare[index+groundsize] == 1) { compare[index+groundsize] = 0; bFirst = false; } else { if (!bFirst) { compare[index+groundsize] = 1; bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } } else if ((ch >= '1' && ch <= '9' && ch-'1' < groundsize) || (ch == '0' && groundsize == 10)) { //Ground Items int iZero = 0; if (ch == '0') { iZero = 10; } if (compare[ch-'1'+iZero] == 1) { compare[ch-'1'+iZero] = 0; bFirst = false; } else { if (!bFirst) { compare[ch-'1'+iZero] = 1; bFirst = true; cLastCh = ch; } else { bShowCompare = true; } } } if (bShowCompare) { std::vector<iteminfo> vItemLastCh, vItemCh; std::string sItemLastCh, sItemCh; if (cLastCh >= '0' && cLastCh <= '9') { int iZero = 0; if (cLastCh == '0') { iZero = 10; } grounditems[cLastCh-'1'+iZero].info(true, &vItemLastCh); sItemLastCh = grounditems[cLastCh-'1'+iZero].tname(this); } else { u.i_at(cLastCh).info(true, &vItemLastCh); sItemLastCh = u.i_at(cLastCh).tname(this); } if (ch >= '0' && ch <= '9') { int iZero = 0; if (ch == '0') { iZero = 10; } grounditems[ch-'1'+iZero].info(true, &vItemCh); sItemCh = grounditems[ch-'1'+iZero].tname(this); } else { u.i_at(ch).info(true, &vItemCh); sItemCh = u.i_at(ch).tname(this); } compare_split_screen_popup(0, (TERMX-VIEW_OFFSET_X*2)/2, TERMY-VIEW_OFFSET_Y*2, sItemLastCh, vItemLastCh, vItemCh); compare_split_screen_popup((TERMX-VIEW_OFFSET_X*2)/2, (TERMX-VIEW_OFFSET_X*2)/2, TERMY-VIEW_OFFSET_Y*2, sItemCh, vItemCh, vItemLastCh); wclear(w_inv); print_inv_statics(this, w_inv, "Compare:", weapon_and_armor); bShowCompare = false; } } while (ch != '\n' && ch != KEY_ESCAPE && ch != ' '); werase(w_inv); delwin(w_inv); erase(); refresh_all(); }
/** * \brief Returns whether this jumper makes vertical jumps. * \return \c true if this jumper makes vertical jumps. */ bool Jumper::is_jump_vertical() const { return get_direction() == 2 || get_direction() == 6; }
/** * \brief Returns whether the direction of this jumper is diagonal. * \return \c true if this jumper is a diagonal one. */ bool Jumper::is_jump_diagonal() const { return get_direction() % 2 != 0; }
char * parse_function_definition(Functions *functions, char cell_str[2], char *f_ptr, char *f_end, Cell *cell) { u32 function_index = get_function_index(cell_str); char *start_f_ptr = f_ptr; consume_whitespace(f_ptr, f_end); if (str_eq(f_ptr, "->", 2)) { // Function Definition log(L_Parser, "Parsing function definition,"); f_ptr += 2; Function *function = functions->hash_table + function_index; if (function->type != FUNCTION_NULL) { log(L_Parser, "Function already defined, ignore this definition."); } else { function->name[0] = cell_str[0]; function->name[1] = cell_str[1]; consume_whitespace(f_ptr, f_end); if (*f_ptr == '=') { log(L_Parser, " Type: Assignment,"); ++f_ptr; consume_whitespace(f_ptr, f_end); u32 assignment_value; char *end_num_f_ptr = get_num(f_ptr, f_end, &assignment_value); if (end_num_f_ptr == f_ptr) { function->type = FUNCTION_NULL; log(L_Parser, " Function invalid: Assignment value missing."); } else { log(L_Parser, " Value: %d", assignment_value); f_ptr = end_num_f_ptr; function->value = assignment_value; function->type = FUNCTION_ASSIGNMENT; } } else if ((f_ptr[0] == '+' || f_ptr[0] == '-' || f_ptr[0] == '*' || f_ptr[0] == '/') && f_ptr[1] == '=') { log(L_Parser, " Type: Operator,"); char sign = f_ptr[0]; f_ptr += 2; consume_whitespace(f_ptr, f_end); u32 assignment_value; char *end_num_f_ptr = get_num(f_ptr, f_end, &assignment_value); if (end_num_f_ptr == f_ptr) { function->type = FUNCTION_NULL; log(L_Parser, " Invalid function: Operator value missing."); } else { log(L_Parser, " Value: %d", assignment_value); f_ptr = end_num_f_ptr; function->value = assignment_value; switch (sign) { case '+': { function->type = FUNCTION_INCREMENT; } break; case '-': { function->type = FUNCTION_DECREMENT; } break; case '*': { function->type = FUNCTION_MULTIPLY; } break; case '/': { function->type = FUNCTION_DIVIDE; } break; } } } else if (str_eq(f_ptr, "IF", 2) || str_eq(f_ptr, "if", 2)) { log(L_Parser, " Type: Conditional,"); f_ptr += 2; consume_whitespace(f_ptr, f_end); FunctionType conditional_func_type; b32 valid_condition = true; if (str_eq(f_ptr, "<=", 2)) { f_ptr += 2; conditional_func_type = FUNCTION_LESS_EQUAL; } else if (*f_ptr == '<') { f_ptr += 1; conditional_func_type = FUNCTION_LESS; } else if (str_eq(f_ptr, ">=", 2)) { f_ptr += 2; conditional_func_type = FUNCTION_GREATER_EQUAL; } else if (*f_ptr == '>') { f_ptr += 1; conditional_func_type = FUNCTION_GREATER; } else if (str_eq(f_ptr, "==", 2)) { f_ptr += 2; conditional_func_type = FUNCTION_EQUAL; } else if (str_eq(f_ptr, "!=", 2)) { f_ptr += 2; conditional_func_type = FUNCTION_NOT_EQUAL; } else { log(L_Parser, " Invalid function: Conditional operator missing."); function->type = FUNCTION_NULL; valid_condition = false; } if (valid_condition) { consume_whitespace(f_ptr, f_end); u32 condition_value; char *end_num_f_ptr = get_num(f_ptr, f_end, &condition_value); if (end_num_f_ptr == f_ptr) { log(L_Parser, " Invalid function: Missing condition value."); function->type = FUNCTION_NULL; } else { log(L_Parser, " Condition value: %d", condition_value); f_ptr = end_num_f_ptr; consume_whitespace(f_ptr, f_end); if (!(str_eq(f_ptr, "THEN", 4) || str_eq(f_ptr, "then", 4))) { log(L_Parser, " Invalid function: Missing 'THEN' keyword."); function->type = FUNCTION_NULL; } else { f_ptr += 4; consume_whitespace(f_ptr, f_end); V2 true_direction; char *end_true_direction_f_ptr = get_direction(f_ptr, &true_direction); if (end_true_direction_f_ptr == f_ptr) { log(L_Parser, " Invalid function: Missing 'THEN' direction."); function->type = FUNCTION_NULL; } else { log(L_Parser, " THEN direction: (%f, %f)", true_direction.x, true_direction.y); f_ptr = end_true_direction_f_ptr; consume_whitespace(f_ptr, f_end); b32 valid_conditional_function = true; b32 else_exists = false; V2 false_direction; // ELSE is optional if (str_eq(f_ptr, "ELSE", 4) || str_eq(f_ptr, "else", 4)) { else_exists = true; f_ptr += 4; consume_whitespace(f_ptr, f_end); char *end_false_direction_f_ptr = get_direction(f_ptr, &false_direction); if (end_false_direction_f_ptr == f_ptr) { log(L_Parser, "Invalid function: Missing 'ELSE' direction."); valid_conditional_function = false; function->type = FUNCTION_NULL; } else { log(L_Parser, " ELSE direction: (%f, %f)", false_direction.x, false_direction.y); f_ptr = end_false_direction_f_ptr; valid_conditional_function = true; } } if (valid_conditional_function) { function->type = conditional_func_type; function->conditional.value = condition_value; function->conditional.true_direction = true_direction; function->conditional.else_exists = else_exists; if (else_exists) { function->conditional.false_direction = false_direction; } } } } } } } } if (function->type != FUNCTION_NULL) { ++functions->n_functions; } consume_until_newline(f_ptr, f_end); } else { f_ptr = start_f_ptr; } return f_ptr; }
/** * \brief Returns whether this jumper makes horizontal jumps. * \return \c true if this jumper makes horizontal jumps. */ bool Jumper::is_jump_horizontal() const { return get_direction() == 0 || get_direction() == 4; }
void veh_interact::do_tirechange(int reason) { werase( w_msg ); switch( reason ) { case 1: mvwprintz(w_msg, 0, 1, c_ltred, "There is no wheel to change here."); wrefresh (w_msg); return; case 2: mvwprintz(w_msg, 1, 1, c_ltgray, "To change a wheel you need a "); wprintz(w_msg, has_wrench? c_ltgreen : c_red, "wrench"); wprintz(w_msg, c_ltgray, " and a "); wprintz(w_msg, has_jack? c_ltgreen : c_red, "jack"); return; default:; } mvwprintz(w_mode, 0, 1, c_ltgray, "Choose wheel to use as replacement: "); wrefresh (w_mode); int pos = 0; while (true) { bool is_wheel = false; sel_part = can_mount[pos]; switch(sel_part) { case vp_wheel: case vp_wheel_wide: case vp_wheel_bicycle: case vp_wheel_motorbike: case vp_wheel_small: is_wheel = true; break; default: break; } display_list (pos); itype_id itm = vpart_list[sel_part].item; bool has_comps = crafting_inv.has_amount(itm, 1); bool has_tools = has_jack && has_wrench; werase (w_msg); wrefresh (w_msg); char ch = input(); // See keypress.h int dx, dy; get_direction (g, dx, dy, ch); if ((ch == '\n' || ch == ' ') && has_comps && has_tools && is_wheel) { sel_cmd = 'c'; return; } else { if (ch == KEY_ESCAPE || ch == 'q' ) { werase (w_list); wrefresh (w_list); werase (w_msg); break; } } if (dy == -1 || dy == 1) { pos += dy; if (pos < 0) { pos = can_mount.size()-1; } else if (pos >= can_mount.size()) { pos = 0; } } } }
static int critbit_insert_inplace(critbit_root *root, const char *key, int keylen, const void* value) { const uint8_t *bytes = (void *)key; uint8_t *p = root->head; if(!p) { p = alloc_string(key, keylen, value); if(!p) return 1; root->head = p; return 0; } p = find_nearest(root->head, bytes, keylen); uint32_t newbyte; uint8_t newotherbits; for(newbyte = 0; newbyte < keylen; ++newbyte) { if(p[newbyte] != bytes[newbyte]) { newotherbits = p[newbyte] ^ bytes[newbyte]; goto found; } } if(p[newbyte]) { newotherbits = p[newbyte]; goto found; } return 1; found: while(newotherbits & (newotherbits - 1)) { newotherbits &= newotherbits - 1; } newotherbits ^= 0xFF; uint8_t c = p[newbyte]; int newdirection = (1 + (newotherbits | c)) >> 8; struct critbit_node *node = alloc_aligned(sizeof(struct critbit_node)); if(!node) return 1; char *x = alloc_string(key, keylen, value); if(!x) { free(node); return 1; } node->byte = newbyte; node->otherbits = newotherbits; node->child[1 - newdirection] = x; void **wherep = &root->head; for(;;) { uint8_t *p = *wherep; if(!IS_INTERNAL(p)) break; struct critbit_node *q = TO_NODE(p); if(q->byte > newbyte) break; if(q->byte == newbyte && q->otherbits > newotherbits) break; wherep = q->child + get_direction(q, bytes, keylen); } node->child[newdirection] = *wherep; __sync_synchronize(); *wherep = FROM_NODE(node); __sync_synchronize(); return 0; }
void veh_interact::do_repair(int reason) { werase (w_msg); if (g->u.morale_level() < MIN_MORALE_CRAFT) { // See morale.h mvwprintz(w_msg, 0, 1, c_ltred, "Your morale is too low to construct..."); wrefresh (w_msg); return; } switch (reason) { case 1: mvwprintz(w_msg, 0, 1, c_ltred, "There are no damaged parts here."); wrefresh (w_msg); return; case 2: mvwprintz(w_msg, 0, 1, c_ltgray, "You need a powered welder to repair."); mvwprintz(w_msg, 0, 12, has_welder? c_ltgreen : c_red, "powered welder"); wrefresh (w_msg); return; default:; } mvwprintz(w_mode, 0, 1, c_ltgray, "Choose a part here to repair:"); wrefresh (w_mode); int pos = 0; while (true) { sel_part = parts_here[need_repair[pos]]; werase (w_parts); veh->print_part_desc (w_parts, 0, winw2, cpart, need_repair[pos]); wrefresh (w_parts); werase (w_msg); bool has_comps = true; int dif = veh->part_info(sel_part).difficulty + (veh->parts[sel_part].hp <= 0? 0 : 2); bool has_skill = g->u.skillLevel("mechanics") >= dif; mvwprintz(w_msg, 0, 1, c_ltgray, "You need level %d skill in mechanics.", dif); mvwprintz(w_msg, 0, 16, has_skill? c_ltgreen : c_red, "%d", dif); if (veh->parts[sel_part].hp <= 0) { itype_id itm = veh->part_info(sel_part).item; has_comps = crafting_inv.has_amount(itm, 1); mvwprintz(w_msg, 1, 1, c_ltgray, "You also need a wrench and %s to replace broken one.", g->itypes[itm]->name.c_str()); mvwprintz(w_msg, 1, 17, has_wrench? c_ltgreen : c_red, "wrench"); mvwprintz(w_msg, 1, 28, has_comps? c_ltgreen : c_red, g->itypes[itm]->name.c_str()); } wrefresh (w_msg); char ch = input(); // See keypress.h int dx, dy; get_direction (g, dx, dy, ch); if ((ch == '\n' || ch == ' ') && has_comps && (veh->parts[sel_part].hp > 0 || has_wrench) && has_skill) { sel_cmd = 'r'; return; } else if (ch == KEY_ESCAPE || ch == 'q' ) { werase (w_parts); veh->print_part_desc (w_parts, 0, winw2, cpart, -1); wrefresh (w_parts); werase (w_msg); break; } if (dy == -1 || dy == 1) { pos += dy; if(pos >= need_repair.size()) pos = 0; else if(pos < 0) pos = need_repair.size() - 1; } } }
void veh_interact::do_remove(int reason) { werase (w_msg); if (g->u.morale_level() < MIN_MORALE_CRAFT) { // See morale.h mvwprintz(w_msg, 0, 1, c_ltred, "Your morale is too low to construct..."); wrefresh (w_msg); return; } switch (reason) { case 1: mvwprintz(w_msg, 0, 1, c_ltred, "No parts here."); wrefresh (w_msg); return; case 2: mvwprintz(w_msg, 0, 1, c_ltgray, "You need a "); wprintz(w_msg, has_wrench? c_ltgreen : c_red, "wrench"); wprintz(w_msg, c_ltgray, " and a "); wprintz(w_msg, has_hacksaw? c_ltgreen : c_red, "hacksaw"); wprintz(w_msg, c_ltgray, " to remove parts."); if(wheel) { mvwprintz(w_msg, 1, 1, c_ltgray, "To change a wheel you need a "); wprintz(w_msg, has_wrench? c_ltgreen : c_red, "wrench"); wprintz(w_msg, c_ltgray, " and a "); wprintz(w_msg, has_jack? c_ltgreen : c_red, "jack"); } wrefresh (w_msg); return; case 3: mvwprintz(w_msg, 0, 1, c_ltred, "You cannot remove mount point while something is attached to it."); wrefresh (w_msg); return; case 4: mvwprintz(w_msg, 0, 1, c_ltred, "You need level 2 mechanics skill to remove parts."); wrefresh (w_msg); return; default:; } mvwprintz(w_mode, 0, 1, c_ltgray, "Choose a part here to remove:"); wrefresh (w_mode); int first = parts_here.size() > 1? 1 : 0; int pos = first; while (true) { sel_part = parts_here[pos]; werase (w_parts); veh->print_part_desc (w_parts, 0, winw2, cpart, pos); wrefresh (w_parts); char ch = input(); // See keypress.h int dx, dy; get_direction (g, dx, dy, ch); if (ch == '\n' || ch == ' ') { sel_cmd = 'o'; return; } else if (ch == KEY_ESCAPE || ch == 'q' ) { werase (w_parts); veh->print_part_desc (w_parts, 0, winw2, cpart, -1); wrefresh (w_parts); werase (w_msg); break; } if (dy == -1 || dy == 1) { pos += dy; if (pos < first) pos = parts_here.size()-1; else if (pos >= parts_here.size()) pos = first; } } }
void veh_interact::do_install(int reason) { werase (w_msg); if (g->u.morale_level() < MIN_MORALE_CRAFT) { // See morale.h mvwprintz(w_msg, 0, 1, c_ltred, "Your morale is too low to construct..."); wrefresh (w_msg); return; } switch (reason) { case 1: mvwprintz(w_msg, 0, 1, c_ltred, "Cannot install any part here."); wrefresh (w_msg); return; case 2: mvwprintz(w_msg, 0, 1, c_ltgray, "You need a "); wprintz(w_msg, has_wrench? c_ltgreen : c_red, "wrench"); wprintz(w_msg, c_ltgray, " and a "); wprintz(w_msg, has_welder? c_ltgreen : c_red, "powered welder"); wprintz(w_msg, c_ltgray, " to install parts."); wrefresh (w_msg); return; default:; } mvwprintz(w_mode, 0, 1, c_ltgray, "Choose new part to install here: "); wrefresh (w_mode); int pos = 0; int engines = 0; int dif_eng = 0; for (int p = 0; p < veh->parts.size(); p++) { if (veh->part_flag (p, vpf_engine)) { engines++; dif_eng = dif_eng / 2 + 12; } } while (true) { sel_part = can_mount[pos]; display_list (pos); itype_id itm = vpart_list[sel_part].item; bool has_comps = crafting_inv.has_amount(itm, 1); bool has_skill = g->u.skillLevel("mechanics") >= vpart_list[sel_part].difficulty; bool has_tools = has_welder && has_wrench; werase (w_msg); mvwprintz(w_msg, 0, 1, c_ltgray, "Needs "); wprintz(w_msg, has_comps? c_ltgreen : c_red, g->itypes[itm]->name.c_str()); wprintz(w_msg, c_ltgray, ", a "); wprintz(w_msg, has_wrench? c_ltgreen : c_red, "wrench"); wprintz(w_msg, c_ltgray, ", a "); wprintz(w_msg, has_welder? c_ltgreen : c_red, "powered welder"); wprintz(w_msg, c_ltgray, ", and level "); wprintz(w_msg, has_skill? c_ltgreen : c_red, "%d", vpart_list[sel_part].difficulty); wprintz(w_msg, c_ltgray, " skill in mechanics."); bool eng = vpart_list[sel_part].flags & mfb (vpf_engine); bool has_skill2 = !eng || (g->u.skillLevel("mechanics") >= dif_eng); if (engines && eng) // already has engine { wprintz(w_msg, c_ltgray, " You also need level "); wprintz(w_msg, has_skill2? c_ltgreen : c_red, "%d", dif_eng); wprintz(w_msg, c_ltgray, " skill in mechanics to install additional engine."); } wrefresh (w_msg); char ch = input(); // See keypress.h int dx, dy; get_direction (g, dx, dy, ch); if ((ch == '\n' || ch == ' ') && has_comps && has_tools && has_skill && has_skill2) { //if(itm.is_var_veh_part() && crafting_inv.has_amount(itm, 2); sel_cmd = 'i'; return; } else { if (ch == KEY_ESCAPE || ch == 'q' ) { werase (w_list); wrefresh (w_list); werase (w_msg); break; } } if (dy == -1 || dy == 1) { pos += dy; if (pos < 0) { pos = can_mount.size()-1; } else if (pos >= can_mount.size()) { pos = 0; } } } }
void veh_interact::exec (game *gm, vehicle *v, int x, int y) { g = gm; veh = v; ex = x; ey = y; // x1 x2 // y1 ----+------+-- // | | // y2 ----+------+ // | // | winw1 = 12; winw2 = 35; winh1 = 3; winh2 = 12; winw12 = winw1 + winw2 + 1; winw3 = FULL_SCREEN_WIDTH - winw1 - winw2 - 2; winh3 = FULL_SCREEN_HEIGHT - winh1 - winh2 - 2; winh23 = winh2 + winh3 + 1; winx1 = winw1; winx2 = winw1 + winw2 + 1; winy1 = winh1; winy2 = winh1 + winh2 + 1; // changed FALSE value to 1, to keep w_border from starting at a negative x,y const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX-FULL_SCREEN_WIDTH)/2 : 1; const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY-FULL_SCREEN_HEIGHT)/2 : 1; page_size = winh23; // h w y x WINDOW *w_border= newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, -1 + iOffsetY, -1 + iOffsetX); w_grid = newwin(FULL_SCREEN_HEIGHT -2, FULL_SCREEN_WIDTH-2, iOffsetY, iOffsetX); w_mode = newwin(1, FULL_SCREEN_WIDTH-2, iOffsetY, iOffsetX); w_msg = newwin(winh1 - 1, FULL_SCREEN_WIDTH-2, 1 + iOffsetY, iOffsetX); w_disp = newwin(winh2-1, winw1, winy1 + 1 + iOffsetY, iOffsetX); w_parts = newwin(winh2-1, winw2, winy1 + 1 + iOffsetY, winx1 + 1 + iOffsetX); w_stats = newwin(winh3-1, winw12, winy2 + iOffsetY, iOffsetX); w_list = newwin(winh23, winw3, winy1 + 1 + iOffsetY, winx2 + 1 + iOffsetX); wborder(w_border, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX ); mvwputch(w_border, 16, 0, c_ltgray, LINE_XXXO); // |- mvwputch(w_border, 4, 0, c_ltgray, LINE_XXXO); // |- mvwputch(w_border, 4, FULL_SCREEN_WIDTH-1, c_ltgray, LINE_XOXX); // -| mvwputch(w_border, 24, 49, c_ltgray, LINE_XXOX); wrefresh(w_border); for (int i = 0; i < FULL_SCREEN_HEIGHT; i++) { mvwputch(w_grid, i, winx2, c_ltgray, i == winy1 || i == winy2-1? LINE_XOXX : LINE_XOXO); if (i >= winy1 && i < winy2) mvwputch(w_grid, i, winx1, c_ltgray, LINE_XOXO); } for (int i = 0; i < FULL_SCREEN_WIDTH; i++) { mvwputch(w_grid, winy1, i, c_ltgray, i == winx1? LINE_OXXX : (i == winx2? LINE_OXXX : LINE_OXOX)); if (i < winx2) mvwputch(w_grid, winy2-1, i, c_ltgray, i == winx1? LINE_XXOX : LINE_OXOX); } wrefresh(w_grid); crafting_inv = gm->crafting_inventory(&gm->u); int charges = ((it_tool *) g->itypes["welder"])->charges_per_use; has_wrench = crafting_inv.has_amount("wrench", 1) || crafting_inv.has_amount("toolset", 1); has_hacksaw = crafting_inv.has_amount("hacksaw", 1) || crafting_inv.has_amount("toolset", 1); has_welder = (crafting_inv.has_amount("welder", 1) && crafting_inv.has_charges("welder", charges)) || (crafting_inv.has_amount("toolset", 1) && crafting_inv.has_charges("toolset", charges/20)); has_jack = crafting_inv.has_amount("jack", 1); has_siphon = crafting_inv.has_amount("hose", 1); has_wheel = 0; has_wheel |= crafting_inv.has_amount( "wheel", 1 ); has_wheel |= crafting_inv.has_amount( "wheel_wide", 1 ); has_wheel |= crafting_inv.has_amount( "wheel_bicycle", 1 ); has_wheel |= crafting_inv.has_amount( "wheel_motorbike", 1 ); has_wheel |= crafting_inv.has_amount( "wheel_small", 1 ); display_stats (); display_veh (); move_cursor (0, 0); bool finish = false; while (!finish) { char ch = input(); // See keypress.h int dx, dy; get_direction (gm, dx, dy, ch); if (ch == KEY_ESCAPE || ch == 'q' ) finish = true; else if (dx != -2 && (dx || dy) && cx + dx >= -6 && cx + dx < 6 && cy + dy >= -6 && cy + dy < 6) move_cursor(dx, dy); else { int mval = cant_do(ch); display_mode (ch); switch (ch) { case 'i': do_install(mval); break; case 'r': do_repair(mval); break; case 'f': do_refill(mval); break; case 'o': do_remove(mval); break; case 'e': do_rename(mval); break; case 's': do_siphon(mval); break; case 'c': do_tirechange(mval); break; default:; } if (sel_cmd != ' ') finish = true; display_mode (' '); } } werase(w_grid); werase(w_mode); werase(w_msg); werase(w_disp); werase(w_parts); werase(w_stats); werase(w_list); delwin(w_grid); delwin(w_mode); delwin(w_msg); delwin(w_disp); delwin(w_parts); delwin(w_stats); delwin(w_list); erase(); }
/** * ==================================================================== * routine fn: * Configures poll(), sets up infinite loop to run on new thread * in jvm and then uses poll() to determine if a change has * taken place on a gpio pin. If it has, it calls get_direction * to determine which way the encoder was turned. * ==================================================================== * authors(s): Stephan Greto-McGrath * ==================================================================== */ void *routine(){ /* get a new environment and attach this new thread to jvm */ JNIEnv* newEnv; JavaVMAttachArgs args; args.version = JNI_VERSION_1_6; /* JNI version */ args.name = NULL; /* thread name */ args.group = NULL; /* thread group */ (*jvm)->AttachCurrentThread(jvm,&newEnv,&args); /* get method ID to call back to Java */ jmethodID mid = (*newEnv)->GetMethodID(newEnv, cls, "handleStateChange", "(I)V"); jmethodID construct = (*newEnv)->GetMethodID(newEnv,cls,"<init>","()V"); jobject obj = (*newEnv)->NewObject(newEnv, cls, construct); /* initialization of vars */ struct pollfd pfd[2]; int fd1, fd2; char str1[256], str2[256]; char buf1[8], buf2[8]; sprintf(str1, "/sys/class/gpio/gpio%d/value", gpio1); sprintf(str2, "/sys/class/gpio/gpio%d/value", gpio2); /* open file descriptors */ if ((fd1 = open(str1, O_RDONLY)) < 0) { LOGD("failed on 1st open"); exit(1); } if ((fd2 = open(str2, O_RDONLY)) < 0) { LOGD("failed on 2nd open"); exit(1); } //TODO change POLLIN to POLLPRI if device has functional sysfs gpio interface /* configure poll struct */ pfd[0].fd = fd1; pfd[1].fd = fd2; pfd[0].events = POLLIN; pfd[1].events = POLLIN; lseek(fd1, 0, SEEK_SET); /* consume any prior interrupt on ch1*/ read(fd1, buf1, sizeof buf1); lseek(fd2, 0, SEEK_SET); /* consume any prior interrupt on ch2*/ read(fd2, buf2, sizeof buf2); for (;;) { /* wait for interrupt */ poll(pfd, 2, 1); // TODO if POLLPRI change to poll(pfd, 2, -1) if ((pfd[0].revents & POLLIN) | (pfd[1].revents & POLLIN)) { /*interrupt received */ /* consume interrupts & read values */ if (lseek(fd1, 0, SEEK_SET) == -1) break; if (read(fd1, buf1, sizeof buf1) == -1) break; if (lseek(fd2, 0, SEEK_SET) == -1) break; if (read(fd2, buf2, sizeof buf2) == -1) break; get_direction(buf1,buf2,newEnv,obj,mid); } } /* shutdown */ LOGD("Reading Terminated"); close(fd1); close(fd2); (*jvm)->DetachCurrentThread(jvm); pthread_exit(NULL); }
// Why put this in a Big Switch? Why not let bionics have pointers to // functions, much like monsters and items? // // Well, because like diseases, which are also in a Big Switch, bionics don't // share functions.... void player::activate_bionic(int b, game *g) { bionic bio = my_bionics[b]; int power_cost = bionics[bio.id].power_cost; if (weapon.type->id == itm_bio_claws && bio.id == bio_claws) power_cost = 0; if (power_level < power_cost) { if (my_bionics[b].powered) { g->add_msg("Your %s powers down.", bionics[bio.id].name.c_str()); my_bionics[b].powered = false; } else g->add_msg("You cannot power your %s", bionics[bio.id].name.c_str()); return; } if (my_bionics[b].powered && my_bionics[b].charge > 0) { // Already-on units just lose a bit of charge my_bionics[b].charge--; } else { // Not-on units, or those with zero charge, have to pay the power cost if (bionics[bio.id].charge_time > 0) { my_bionics[b].powered = true; my_bionics[b].charge = bionics[bio.id].charge_time; } power_level -= power_cost; } std::string junk; std::vector<point> traj; std::vector<std::string> good; std::vector<std::string> bad; WINDOW* w; int dirx, diry, t, index; InputEvent input; unsigned int l; item tmp_item; switch (bio.id) { case bio_painkiller: pkill += 6; pain -= 2; if (pkill > pain) pkill = pain; break; case bio_nanobots: healall(4); break; case bio_resonator: g->sound(posx, posy, 30, "VRRRRMP!"); for (int i = posx - 1; i <= posx + 1; i++) { for (int j = posy - 1; j <= posy + 1; j++) { g->m.bash(i, j, 40, junk); g->m.bash(i, j, 40, junk); // Multibash effect, so that doors &c will fall g->m.bash(i, j, 40, junk); if (g->m.is_destructable(i, j) && rng(1, 10) >= 4) g->m.ter(i, j) = t_rubble; } } break; case bio_time_freeze: moves += 100 * power_level; power_level = 0; g->add_msg("Your speed suddenly increases!"); if (one_in(3)) { g->add_msg("Your muscles tear with the strain."); hurt(g, bp_arms, 0, rng(5, 10)); hurt(g, bp_arms, 1, rng(5, 10)); hurt(g, bp_legs, 0, rng(7, 12)); hurt(g, bp_legs, 1, rng(7, 12)); hurt(g, bp_torso, 0, rng(5, 15)); } if (one_in(5)) add_disease(DI_TELEGLOW, rng(50, 400), g); break; case bio_teleport: g->teleport(); add_disease(DI_TELEGLOW, 300, g); break; // TODO: More stuff here (and bio_blood_filter) case bio_blood_anal: w = newwin(20, 40, 3, 10); wborder(w, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX ); if (has_disease(DI_FUNGUS)) bad.push_back("Fungal Parasite"); if (has_disease(DI_DERMATIK)) bad.push_back("Insect Parasite"); if (has_disease(DI_POISON)) bad.push_back("Poison"); if (radiation > 0) bad.push_back("Irradiated"); if (has_disease(DI_PKILL1)) good.push_back("Minor Painkiller"); if (has_disease(DI_PKILL2)) good.push_back("Moderate Painkiller"); if (has_disease(DI_PKILL3)) good.push_back("Heavy Painkiller"); if (has_disease(DI_PKILL_L)) good.push_back("Slow-Release Painkiller"); if (has_disease(DI_DRUNK)) good.push_back("Alcohol"); if (has_disease(DI_CIG)) good.push_back("Nicotine"); if (has_disease(DI_HIGH)) good.push_back("Intoxicant: Other"); if (has_disease(DI_TOOK_PROZAC)) good.push_back("Prozac"); if (has_disease(DI_TOOK_FLUMED)) good.push_back("Antihistamines"); if (has_disease(DI_ADRENALINE)) good.push_back("Adrenaline Spike"); if (good.size() == 0 && bad.size() == 0) mvwprintz(w, 1, 1, c_white, "No effects."); else { for (int line = 1; line < 39 && line <= good.size() + bad.size(); line++) { if (line <= bad.size()) mvwprintz(w, line, 1, c_red, bad[line - 1].c_str()); else mvwprintz(w, line, 1, c_green, good[line - 1 - bad.size()].c_str()); } } wrefresh(w); refresh(); getch(); delwin(w); break; case bio_blood_filter: rem_disease(DI_FUNGUS); rem_disease(DI_POISON); rem_disease(DI_PKILL1); rem_disease(DI_PKILL2); rem_disease(DI_PKILL3); rem_disease(DI_PKILL_L); rem_disease(DI_DRUNK); rem_disease(DI_CIG); rem_disease(DI_HIGH); rem_disease(DI_TOOK_PROZAC); rem_disease(DI_TOOK_FLUMED); rem_disease(DI_ADRENALINE); break; case bio_evap: if (query_yn("Drink directly? Otherwise you will need a container.")) { tmp_item = item(g->itypes[itm_water], 0); thirst -= 50; if (has_trait(PF_GOURMAND) && thirst < -60) { g->add_msg("You can't finish it all!"); thirst = -60; } else if (!has_trait(PF_GOURMAND) && thirst < -20) { g->add_msg("You can't finish it all!"); thirst = -20; } } else { t = g->inv("Choose a container:"); if (i_at(t).type == 0) { g->add_msg("You don't have that item!"); power_level += bionics[bio_evap].power_cost; } else if (!i_at(t).is_container()) { g->add_msg("That %s isn't a container!", i_at(t).tname().c_str()); power_level += bionics[bio_evap].power_cost; } else { it_container *cont = dynamic_cast<it_container*>(i_at(t).type); if (i_at(t).volume_contained() + 1 > cont->contains) { g->add_msg("There's no space left in your %s.", i_at(t).tname().c_str()); power_level += bionics[bio_evap].power_cost; } else if (!(cont->flags & con_wtight)) { g->add_msg("Your %s isn't watertight!", i_at(t).tname().c_str()); power_level += bionics[bio_evap].power_cost; } else { g->add_msg("You pour water into your %s.", i_at(t).tname().c_str()); i_at(t).put_in(item(g->itypes[itm_water], 0)); } } } break; case bio_lighter: g->draw(); mvprintw(0, 0, "Torch in which direction?"); input = get_input(); get_direction(dirx, diry, input); if (dirx == -2) { g->add_msg("Invalid direction."); power_level += bionics[bio_lighter].power_cost; return; } dirx += posx; diry += posy; if (!g->m.add_field(g, dirx, diry, fd_fire, 1)) // Unsuccessful. g->add_msg("You can't light a fire there."); break; case bio_claws: if (weapon.type->id == itm_bio_claws) { g->add_msg("You withdraw your claws."); weapon = ret_null; } else if (weapon.type->id != 0) { g->add_msg("Your claws extend, forcing you to drop your %s.", weapon.tname().c_str()); g->m.add_item(posx, posy, weapon); weapon = item(g->itypes[itm_bio_claws], 0); weapon.invlet = '#'; } else { g->add_msg("Your claws extend!"); weapon = item(g->itypes[itm_bio_claws], 0); weapon.invlet = '#'; } break; case bio_blaster: tmp_item = weapon; weapon = item(g->itypes[itm_bio_blaster], 0); weapon.curammo = dynamic_cast<it_ammo*>(g->itypes[itm_bio_fusion]); weapon.charges = 1; g->refresh_all(); g->plfire(false); weapon = tmp_item; break; case bio_laser: tmp_item = weapon; weapon = item(g->itypes[itm_v29], 0); weapon.curammo = dynamic_cast<it_ammo*>(g->itypes[itm_laser_pack]); weapon.charges = 1; g->refresh_all(); g->plfire(false); weapon = tmp_item; break; case bio_emp: g->draw(); mvprintw(0, 0, "Fire EMP in which direction?"); input = get_input(); get_direction(dirx, diry, input); if (dirx == -2) { g->add_msg("Invalid direction."); power_level += bionics[bio_emp].power_cost; return; } dirx += posx; diry += posy; g->emp_blast(dirx, diry); break; case bio_hydraulics: g->add_msg("Your muscles hiss as hydraulic strength fills them!"); break; case bio_water_extractor: for (int i = 0; i < g->m.i_at(posx, posy).size(); i++) { item tmp = g->m.i_at(posx, posy)[i]; if (tmp.type->id == itm_corpse && query_yn("Extract water from the %s", tmp.tname().c_str())) { i = g->m.i_at(posx, posy).size() + 1; // Loop is finished t = g->inv("Choose a container:"); if (i_at(t).type == 0) { g->add_msg("You don't have that item!"); power_level += bionics[bio_water_extractor].power_cost; } else if (!i_at(t).is_container()) { g->add_msg("That %s isn't a container!", i_at(t).tname().c_str()); power_level += bionics[bio_water_extractor].power_cost; } else { it_container *cont = dynamic_cast<it_container*>(i_at(t).type); if (i_at(t).volume_contained() + 1 > cont->contains) { g->add_msg("There's no space left in your %s.", i_at(t).tname().c_str()); power_level += bionics[bio_water_extractor].power_cost; } else { g->add_msg("You pour water into your %s.", i_at(t).tname().c_str()); i_at(t).put_in(item(g->itypes[itm_water], 0)); } } } if (i == g->m.i_at(posx, posy).size() - 1) // We never chose a corpse power_level += bionics[bio_water_extractor].power_cost; } break; case bio_magnet: for (int i = posx - 10; i <= posx + 10; i++) { for (int j = posy - 10; j <= posy + 10; j++) { if (g->m.i_at(i, j).size() > 0) { if (g->m.sees(i, j, posx, posy, -1, t)) traj = line_to(i, j, posx, posy, t); else traj = line_to(i, j, posx, posy, 0); } traj.insert(traj.begin(), point(i, j)); for (int k = 0; k < g->m.i_at(i, j).size(); k++) { if (g->m.i_at(i, j)[k].made_of(IRON) || g->m.i_at(i, j)[k].made_of(STEEL)){ tmp_item = g->m.i_at(i, j)[k]; g->m.i_rem(i, j, k); for (l = 0; l < traj.size(); l++) { index = g->mon_at(traj[l].x, traj[l].y); if (index != -1) { if (g->z[index].hurt(tmp_item.weight() * 2)) g->kill_mon(index, true); g->m.add_item(traj[l].x, traj[l].y, tmp_item); l = traj.size() + 1; } else if (l > 0 && g->m.move_cost(traj[l].x, traj[l].y) == 0) { g->m.bash(traj[l].x, traj[l].y, tmp_item.weight() * 2, junk); g->sound(traj[l].x, traj[l].y, 12, junk); if (g->m.move_cost(traj[l].x, traj[l].y) == 0) { g->m.add_item(traj[l - 1].x, traj[l - 1].y, tmp_item); l = traj.size() + 1; } } } if (l == traj.size()) g->m.add_item(posx, posy, tmp_item); } } } } break; case bio_lockpick: g->draw(); mvprintw(0, 0, "Unlock in which direction?"); input = get_input(); get_direction(dirx, diry, input); if (dirx == -2) { g->add_msg("Invalid direction."); power_level += bionics[bio_lockpick].power_cost; return; } dirx += posx; diry += posy; if (g->m.ter(dirx, diry) == t_door_locked) { moves -= 40; g->add_msg("You unlock the door."); g->m.ter(dirx, diry) = t_door_c; } else g->add_msg("You can't unlock that %s.", g->m.tername(dirx, diry).c_str()); break; // Unused enums added for completeness. default: break; } }
void game::place_construction(constructable *con) { refresh_all(); inventory total_inv; total_inv.form_from_map(this, point(u.posx, u.posy), PICKUP_RANGE); total_inv.add_stack(u.inv_dump()); std::vector<point> valid; for (int x = u.posx - 1; x <= u.posx + 1; x++) { for (int y = u.posy - 1; y <= u.posy + 1; y++) { if (x == u.posx && y == u.posy) y++; construct test; bool place_okay = (test.*(con->able))(this, point(x, y)); for (int i = 0; i < con->stages.size() && !place_okay; i++) { if (m.ter(x, y) == con->stages[i].terrain) place_okay = true; } if (place_okay) { // Make sure we're not trying to continue a construction that we can't finish int starting_stage = 0, max_stage = 0; for (int i = 0; i < con->stages.size(); i++) { if (m.ter(x, y) == con->stages[i].terrain) starting_stage = i + 1; if (player_can_build(u, total_inv, con, i, true)) max_stage = i; } if (max_stage >= starting_stage) { valid.push_back(point(x, y)); m.drawsq(w_terrain, u, x, y, true, false); wrefresh(w_terrain); } } } } mvprintz(0, 0, c_red, "Pick a direction in which to construct:"); int dirx, diry; get_direction(this, dirx, diry, input()); if (dirx == -2) { add_msg("Invalid direction."); return; } dirx += u.posx; diry += u.posy; bool point_is_okay = false; for (int i = 0; i < valid.size() && !point_is_okay; i++) { if (valid[i].x == dirx && valid[i].y == diry) point_is_okay = true; } if (!point_is_okay) { add_msg("You cannot build there!"); return; } // Figure out what stage to start at, and what stage is the maximum int starting_stage = 0, max_stage = 0; for (int i = 0; i < con->stages.size(); i++) { if (m.ter(dirx, diry) == con->stages[i].terrain) starting_stage = i + 1; if (player_can_build(u, total_inv, con, i, true)) max_stage = i; } u.assign_activity(ACT_BUILD, con->stages[starting_stage].time * 1000, con->id); u.moves = 0; std::vector<int> stages; for (int i = starting_stage; i <= max_stage; i++) stages.push_back(i); u.activity.values = stages; u.activity.placement = point(dirx, diry); }
static bool get_segments(const SkPath& path, const SkMatrix& m, SegmentArray* segments, SkPoint* fanPt, int* vCount, int* iCount, SkRect* devBounds) { SkPath::Iter iter(path, true); // This renderer over-emphasizes very thin path regions. We use the distance // to the path from the sample to compute coverage. Every pixel intersected // by the path will be hit and the maximum distance is sqrt(2)/2. We don't // notice that the sample may be close to a very thin area of the path and // thus should be very light. This is particularly egregious for degenerate // line paths. We detect paths that are very close to a line (zero area) and // draw nothing. DegenerateTestData degenerateData; SkPath::Direction dir; // get_direction can fail for some degenerate paths. if (!get_direction(path, m, &dir)) { return false; } for (;;) { GrPoint pts[4]; SkPath::Verb verb = iter.next(pts); switch (verb) { case SkPath::kMove_Verb: m.mapPoints(pts, 1); update_degenerate_test(°enerateData, pts[0]); devBounds->set(pts->fX, pts->fY, pts->fX, pts->fY); break; case SkPath::kLine_Verb: { m.mapPoints(&pts[1], 1); update_degenerate_test(°enerateData, pts[1]); add_line_to_segment(pts[1], segments, devBounds); break; } case SkPath::kQuad_Verb: m.mapPoints(pts, 3); update_degenerate_test(°enerateData, pts[1]); update_degenerate_test(°enerateData, pts[2]); add_quad_segment(pts, segments, devBounds); break; case SkPath::kCubic_Verb: { m.mapPoints(pts, 4); update_degenerate_test(°enerateData, pts[1]); update_degenerate_test(°enerateData, pts[2]); update_degenerate_test(°enerateData, pts[3]); add_cubic_segments(pts, dir, segments, devBounds); break; }; case SkPath::kDone_Verb: if (degenerateData.isDegenerate()) { return false; } else { compute_vectors(segments, fanPt, dir, vCount, iCount); return true; } default: break; } } }
int main(int argc, char *argv[]) { /* select部份 */ int opt = TRUE; int master_socket, addrlen, new_socket, client_socket[MAXCLIENTS], max_clients = MAXCLIENTS, activity, i, valread, sd; user_content_t *my_contents[MAXCLIENTS + 1]; int max_sd; struct timeval tv; /* select超时 */ //set of socket descriptors fd_set readfds; /* IP部份 */ struct addrinfo hints, *res; /* 连接到target的用到的 */ struct sockaddr_in address; /* 每个客户端的缓冲区和索引 */ char buffer[MAXCLIENTS][MAXLEN]; char *buffer_p[MAXCLIENTS]; //data buffer of 1K int buffer_data_size[MAXCLIENTS]; char itoa_buffer[8]; /* ip地址从网络顺序转成char数组 */ char *header = NULL; /* 将转换好的ip地址:封包成header */ /* 串口部份 固定变量 */ static char com_devicename[] = "/dev/ttyUSB0"; /* 固定的linux串口设备文件 */ user_content_t *my_com_conf = my_malloc(sizeof(user_content_t));/* 串口配置 */ /* 串口部份 动态变量 */ #ifdef MODULE_SERIAL char buffer_com[MAXLEN]; /* 串口缓冲区 */ char *buffer_com_p=buffer_com; int buffer_com_data_size=0; #endif /* 蓝牙部份 */ #ifdef MODULE_BLUETOOTH struct sockaddr_rc blue_rem_addr = {0}; char blue_buffer[MAXLEN],blue_sender_MAC[18]; int blue_fd,blue_fd_client,blue_bytes_read; socklen_t blue_opt=sizeof(blue_rem_addr); user_content_t *blue_user_content; #endif /* args参数 */ char *PORT; if (argc != 2) { fprintf(stderr, "usage: %s listen-port\n", argv[0]); return 1; } PORT = argv[1]; #ifdef MODULE_SERIAL /* 打开串口,须root权限 */ if(NULL==(my_com_conf=open_com(com_devicename))) { printf("error open com!\n"); return 1; } #endif #ifdef MODULE_BLUETOOTH /* 打开蓝牙 */ blue_fd=create_bluetooth_socket(); if(blue_fd<0) { printf("error bluetooth fd is -1\n"); return -1; } listen(blue_fd, 1); #endif //initialise all client_socket[] to 0 so not checked for (i = 0; i < max_clients; i++) { client_socket[i] = 0; } if ((master_socket = create_server_socket("0.0.0.0", PORT)) < 0) { printf("error create socket fd\n"); return 1; } //set master socket to allow multiple connections , this is just a good habit, it will work without this if (setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt)) < 0) { perror("setsockopt"); exit(EXIT_FAILURE); } //try to specify maximum of 3 pending connections for the master socket if (listen(master_socket, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } printf("Listening on port %s \n", PORT); //accept the incoming connection addrlen = sizeof(address); puts("Waiting for connections ..."); while (TRUE) { //clear the socket set FD_ZERO(&readfds); //add master socket to set FD_SET(master_socket, &readfds); max_sd = master_socket; #ifdef MODULE_SERIAL FD_SET(my_com_conf->fd,&readfds); max_sd = max_sd>my_com_conf->fd?max_sd:my_com_conf->fd; #endif #ifdef MODULE_BLUETOOTH FD_SET(blue_fd,&readfds); max_sd = max_sd>blue_fd?max_sd:blue_fd; #endif //add child sockets to set for (i = 0; i < max_clients; i++) { //socket descriptor sd = client_socket[i]; //if valid socket descriptor then add to read list if (sd > 0) FD_SET(sd, &readfds); //highest file descriptor number, need it for the select function if (sd > max_sd) max_sd = sd; } //wait for an activity on one of the sockets , timeout is NULL , so wait indefinitely activity = select(max_sd + 1, &readfds, NULL, NULL, NULL); if ((activity < 0) && (errno != EINTR)) { printf("select error"); } //If something happened on the master socket , then its an incoming connection if (FD_ISSET(master_socket, &readfds)) { if ((new_socket = accept(master_socket, (struct sockaddr *) &address, (socklen_t*) &addrlen)) < 0) { perror("accept"); exit(EXIT_FAILURE); } //add new socket to array of sockets for (i = 0; i < max_clients; i++) { //if position is empty, create new one if (client_socket[i] == 0) { client_socket[i] = new_socket; // 初始化buffer buffer_p[i] = buffer[i]; memset(buffer_p[i], 0, MAXLEN); buffer_data_size[i] = 0; printf("accepted #%d client\n", i); break; } } } #ifdef MODULE_SERIAL // 串口读 if (FD_ISSET(my_com_conf->fd, &readfds)) { /* 非阻塞读取 */ valread=sp_nonblocking_read(my_com_conf->com_port,buffer_com_p+buffer_com_data_size,MAXLEN); if(valread<0) { printf("read data from com error: %d\n",valread); return 1; buffer_com_data_size=0; buffer_com_p=buffer_com; } else { buffer_com_data_size+=valread; /* 读完所有数据,串口数据包必须以\r\n结尾 */ if(buffer_com[buffer_com_data_size-2]==13 && buffer_com[buffer_com_data_size-1]==10) { printf("- - - - - - - - - -\nread from COM ok\n"); buffer_com_p[buffer_com_data_size]=0; my_contents[MAXCLIENTS]=new_user_content_from_str(buffer_com,com_devicename,get_direction(buffer_com)); if(!my_contents[MAXCLIENTS]) { printf("invalid packet!\n"); } else { printf(" %s",com_devicename); redirect_from_user_content(my_contents[MAXCLIENTS]); } my_free(my_contents[MAXCLIENTS]); /* reset buffer offset */ buffer_com_data_size=0; buffer_com_p=buffer_com; } } } #endif #ifdef MODULE_BLUETOOTH // 蓝牙读 if(FD_ISSET(blue_fd,&readfds)) { // accept one connection blue_fd_client = accept(blue_fd, (struct sockaddr *)&blue_rem_addr, &blue_opt); ba2str( &blue_rem_addr.rc_bdaddr, blue_sender_MAC ); // read data from the client blue_bytes_read = read(blue_fd_client, blue_buffer, sizeof(blue_buffer)); if( blue_bytes_read > 0 ) { printf("- - - - - - - - - -\nread from bluetooth ok\n"); blue_buffer[blue_bytes_read]=0; blue_user_content=new_user_content_from_str(blue_buffer,blue_sender_MAC,get_direction(blue_buffer)); if(!blue_user_content) { printf("invalid packet!\n"); } else { printf(" %s",blue_sender_MAC); redirect_from_user_content(blue_user_content); } my_free(blue_user_content); } else { printf("bluetooth recv data error!\n"); } // close connection close(blue_fd_client); } #endif // 局域网ip读 for (i = 0; i < max_clients; i++) { sd = client_socket[i]; if (FD_ISSET(sd, &readfds)) { //Check if it was for closing , and also read the incoming message if ((valread = read(sd, buffer_p[i] + buffer_data_size[i], MAXLEN)) == 0) { //Somebody disconnected , get his details and print buffer[i][buffer_data_size[i]] = 0; getpeername(sd, (struct sockaddr*) &address, (socklen_t*) &addrlen); printf( "- - - - - - - - - -\nread %d bytes from LAN client\n", buffer_data_size[i]); //Close the socket and mark as 0 in list for reuse close(sd); client_socket[i] = 0; /* convert port(interger) to char* */ sprintf(itoa_buffer, "%d", ntohs(address.sin_port)); header = get_header_ipv4(inet_ntoa(address.sin_addr), itoa_buffer); /* create relay struct: from LAN ip, to serial */ my_contents[i] = new_user_content_from_str(buffer[i], header, get_direction(buffer[i])); if (!my_contents[i]) { printf("invalid packet!\n"); } else { printf(" %s", header); redirect_from_user_content(my_contents[i]); } my_free(header); my_free(my_contents[i]); } else { /* 累加数据 */ buffer_data_size[i] += valread; } } } } #ifdef MODULE_SERIAL sp_close(my_com_conf->com_port); sp_free_port(my_com_conf->com_port); sp_free_config(my_com_conf->com_conf); my_free(my_com_conf); #endif #ifdef MODULE_BLUETOOTH close(blue_fd); #endif close(master_socket); printf("exit..\n"); return 0; }