static void update_enemy( Enemy * const enemy , const Map * const map , const double time ) { const int is_horizontal = enemy->flags & ENEMY_MOVING_HORIZONTAL; const int is_going_back = enemy->flags & ENEMY_GOING_BACK; /* update the target testination */ if ( is_moving( & enemy->entity ) == 0 ) { const int delta = is_going_back ? 1 : -1; if ( is_horizontal ) { enemy->entity.destination.x += delta; } else { enemy->entity.destination.y += delta; } } /* do the walking */ const TileType non_walkable = TILE_WALL | TILE_STRING | TILE_TRAP; update_entity( & enemy->entity, map, non_walkable, time ); /* handle wall hit */ if ( enemy->entity.flags & ENTITY_HAS_HIT_WALL ) { swap_enemy_direction( enemy ); enemy->entity.flags &= ~ENTITY_HAS_HIT_WALL; } }
bool BrainsComponent::plan_step_move(const Vec3i& dst, MovePrecision mp) { auto ent = get_parent()->as_entity(); if (not close_enough(ent->get_move_destination(), dst, mp)) { qDebug() << "move_to" << dst; if (not ent->move_to(dst, mp)) { // no route qDebug() << "no route" << ent->get_pos() << "to" << dst; finish_plan(PlanResult::MoveNoRoute); return true; } return false; } // Move finished auto close = close_enough(ent->get_pos(), dst, mp); if (close) { qDebug() << "plan: move finished"; finish_plan_step(); return false; } if (not ent->is_moving() && !close) { // not moving, but destination is correct - means can't move finish_plan(PlanResult::MoveStuck); return true; } return false; }
void DropletCustomOne::DropletMainLoop() { if ( !is_moving(NULL) ) { switch ( rand_byte() % 3 ) { case 0: { int8_t sign = rand_byte() % 2 ? 1 : -1; rotate_degrees ( 90 * sign ); set_rgb_led ( 50, 0, 0 ); } break; case 1: move_duration ( rand_byte() % 6, 3000 ); set_rgb_led ( 0, 50, 0 ); break; case 2: move_steps ( rand_byte() % 6, 100 ); set_rgb_led ( 0, 0, 50 ); break; default: break; } } }
void Movement::turn_around() { assert(is_moving() && !has_left_tile()); target_tile = thing.tile_pos; velocity = -velocity; steps = max_steps - steps; }
void Movement::head(Vector<int> dir) { assert(!is_moving()); target_tile = thing.tile_pos + dir; velocity.x = double(dir.x) * Arena::instance().tile_size / max_steps; velocity.y = double(dir.y) * Arena::instance().tile_size / max_steps; steps = 0; }
inline int LargeObject::delta( const OopDesc* p ) { GUARANTEE( is_moving( p ), "Not a large object to move" ); #if ENABLE_LIB_IMAGES const OopDesc* const* q = (const OopDesc* const*) interval_table_end; do { q -= 2; } while ( q[-1] > p ); return int( *q ); #else (void) p; return current_delta; #endif }
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 DropletCustomOne::random_walk ( void ) { if ( !is_moving(NULL) ) { // Either walk or rotate if ( rand_byte() % 3 == 0 ) { int8_t sign = rand_byte() % 2 ? 1 : -1; uint8_t degrees; while ( (degrees = rand_byte()) <= 90 ); rotate_degrees ( sign * degrees ); } else { last_move_dir = rand_byte() % 6; move_duration ( last_move_dir, rand_byte() * MOVE_DIST_SCALAR ); } } }
/** * Function used to decide whether the head is already in safe zone. If it is, stop the motor and store the current position. * If it is not, continue moving. */ void calibration_logic_axis(int axis, uint32_t input, int *was_in_safezone, int *safezone_enter, int *oldpos, int *not_moved, position_t pos) { int in_safezone = (axis == AXIS_X ? HEAD_IS_IN_SAFE_ZONE_LEFT(input) : HEAD_IS_IN_SAFE_ZONE_TOP(input)); int pwr = (axis == AXIS_X ? OUT_PWR_X : OUT_PWR_Y); int currval = (axis == AXIS_X ? pos.x : pos.y); if(in_safezone == 0) { i386_outport_byte(pwr, CALIBRATION_POWER); }else{ if (*was_in_safezone == 0) { *safezone_enter = currval; } i386_outport_byte(pwr, 0); is_moving(oldpos, currval, not_moved); *was_in_safezone = 1; } }
void Movement::update() { assert(is_moving()); if (is_halfway()) { if (Arena::instance().occupier(thing.tile_pos) == &thing) Arena::instance().occupy(thing.tile_pos, 0); thing.tile_pos = target_tile; Arena::instance().occupy(thing.tile_pos, &thing); } thing.get_graphic().move(velocity); ++steps; if (steps >= max_steps) { // make sure we sit tight thing.occupy_tile(thing.tile_pos); steps = not_moving; } }
extern State *process_free( State * const state , const int new_keys , const int old_keys ) { Entity * const player_entity = & state->player.entity; int moved = 0; if ( is_moving( player_entity ) == 0 ) { if (new_keys & KEY_UP) { player_entity->destination.y -= 1; moved = 1; } else if (new_keys & KEY_DOWN) { player_entity->destination.y += 1; moved = 1; } else if (new_keys & KEY_LEFT) { player_entity->destination.x -= 1; moved = 1; } else if (new_keys & KEY_RIGHT) { player_entity->destination.x += 1; moved = 1; } } if ( moved ) { const int destination = tile_at( & state->map , player_entity->destination ); const int current = tile_at( & state->map , player_entity->position ); const int antydest = antydestination_tile(state); if ( ( ! POINT_EQ( player_entity->destination , player_entity->previous_position ) ) && ( destination == TILE_STRING && antydest == TILE_STRING ) ) { cancel_move( player_entity ); } else { if (current == TILE_FLOOR && destination != TILE_STRING) { set_tile( & state->map, TILE_STRING, player_entity->position); } else if ( current == TILE_STRING && destination != TILE_FLOOR) { set_tile( & state->map, TILE_FLOOR, player_entity->position); } } Boulder * b = boulder_at( state, player_entity->destination ); if ( b != NULL ) { int i = player_entity->destination.x - player_entity->position.x; int j = player_entity->destination.y - player_entity->position.y; Point boulder_dest; boulder_dest.x = player_entity->destination.x + i; boulder_dest.y = player_entity->destination.y + j; TileType boulder_dest_tile = tile_at( & state->map, boulder_dest); if ( boulder_dest_tile == TILE_FLOOR ) { b->entity.destination = boulder_dest; } else { cancel_move( player_entity ); } } } return state; }
void LargeObject::update_pointer_in_instance_class( OopDesc** p ) { const OopDesc* const obj = *p; if( is_moving( obj ) && !obj->is_class_info() ) { *p = DERIVED( OopDesc*, obj, delta( obj ) ); }
void DropletCustomOne::DropletMainLoop() { switch ( state ) { case COLLABORATING: if ( get_32bit_time() - collab_time > COLLABORATE_DURATION ) { change_state ( LEAVING ); } break; case LEAVING: if ( !is_moving(NULL) ) { change_state ( SAFE ); } break; case SAFE: if ( check_safe () ) { change_state ( SEARCHING ); } // If you start in the red region then try to get out before you die else { random_walk (); } break; case SEARCHING: random_walk (); if ( !check_safe() ) { change_state ( WAITING ); } break; case START_DELAY: { uint32_t curr_time = get_32bit_time (); if ( curr_time - start_delay_time > START_DELAY_TIME ) change_state ( SAFE ); } break; case WAITING: if ( get_32bit_time() - heartbeat_time > HEART_RATE ) { heartbeat_time = get_32bit_time (); send_heartbeat (); } // Checks incoming messages and updates group size. // There is a chance the state can be changed to COLLABORATING in // this function if the droplet sees a GO message. update_group_size (); if ( get_32bit_time() - voting_time > HEART_RATE && state == WAITING ) { voting_time = get_32bit_time (); check_votes (); } break; default: break; } }
void DropletCustomFive::DropletMainLoop() { switch(state) { case WANDER: if(!wander_rgb) { set_rgb_led(255,0,255); wander_rgb = true; } if(!is_moving()) { move_steps((rand_byte() % 6) + 1, rand_byte() * 50); } if(!first_set) { uint8_t r, g, b; get_rgb_sensor(&r, &g, &b); if(r > 200) { first_set = true; char msg = 'R'; ir_broadcast(&msg, sizeof(msg)); cancel_move(); cancel_rotate(); guitar_id = 0; row_num = 0; num_in_row = 1; state = CALL; break; } } while(check_for_new_messages()) { char let = global_rx_buffer.buf[0]; uint8_t num; uint16_t idnum; switch(let) { case 'V': float dist, theta, phi; range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); num = global_rx_buffer.buf[1]; if(dist<20 && dist>10) { char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'C'; msg[1] = num; ir_broadcast(&msg[0], sizeof(msg)); } break; case 'S': memcpy(&idnum, &global_rx_buffer.buf[1], 2); if(idnum == get_droplet_id()) { target = global_rx_buffer.sender_ID; slot_num = (uint8_t)global_rx_buffer.buf[3]; guitar_id = (uint8_t)global_rx_buffer.buf[4]; cancel_move(); cancel_rotate(); state = DOCK; break; } break; case 'R': first_set = true; break; case 'D': range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); if(dist<30) { rotate_degrees(static_cast<int16_t>(theta+160)); move_steps(NORTH, 30); } break; default: break; } global_rx_buffer.read=true; } break; case DOCK: if(!dock_rgb) { set_rgb_led(150,150,150); dock_rgb = true; } if(!is_moving()) { float dist, theta, phi; if(!range_and_bearing(target, &dist, &theta, &phi)) { state = WANDER; set_rgb_led(0, 0, 0); move_steps((rand_byte() % 6) + 1, rand_byte()*50); break; } if(!is_rotating() && abs(theta) > 2.5f) { rotate_degrees(static_cast<int16_t>(theta)); } if(!is_rotating() && abs(theta) <= 2.5f) { move_steps(NORTH, static_cast<uint16_t>(dist)); } if(dist <= 20) { if(!clock_wise) // rotate around target counter clockwise { rotate_degrees(static_cast<int16_t>(theta-90)); move_steps(NORTH, 2); char msg = 'D'; ir_broadcast(&msg, 1); if(theta>85) { switch(slot_num) { case 0: if(phi < -75 && phi > -180) { cancel_move(); cancel_rotate(); rotate_degrees(static_cast<int16_t>(-180)); clock_wise = true; break; } if(phi<-59 && phi>-61) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 1: if(phi < -75 && phi > -180) { cancel_move(); cancel_rotate(); rotate_degrees(static_cast<int16_t>(-180)); clock_wise = true; break; } if(phi>-1 && phi<1) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 2: if(phi>59 && phi<61) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 3: if(phi<121 && phi>119) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 4: if((phi>179 && phi<181)||(phi>-181 && phi<-179)) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 5: if(phi>-121 && phi<-119) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; default: break; } } } else // rotate around target clockwise { rotate_degrees(static_cast<int16_t>(theta+90)); move_steps(NORTH, 2); char msg = 'D'; ir_broadcast(&msg, 1); if(theta<-85) { switch(slot_num) { case 0: if(phi < -30 && phi > -75) { cancel_move(); cancel_rotate(); rotate_degrees(static_cast<int16_t>(180)); clock_wise = false; break; } if(phi<121 && phi>119) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 1: if(phi < -50 && phi > -75) { cancel_move(); cancel_rotate(); rotate_degrees(static_cast<int16_t>(180)); clock_wise = false; break; } if((phi>177 && phi<181)||(phi<-177 && phi>-181)) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 2: if(phi>-121 && phi<-119) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 3: if(phi>-31 && phi<-29) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 4: if(phi>-1 && phi<1) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; case 5: if(phi>59 && phi<61) { cancel_move(); cancel_rotate(); state = ALIGN; break; } break; default: break; } } } } } if(check_for_new_messages()) { char let = (char)global_rx_buffer.buf[0]; uint8_t num = (uint8_t)global_rx_buffer.buf[1]; switch(let) { case 'A': if(num == guitar_id) { wander_rgb = false; state = WANDER; } case 'F': if(num == guitar_id) { wander_rgb = false; state = WANDER; } break; case 'T': float dist, theta, phi; range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); if(dist<5) { move_steps(SOUTH, 5); if(clock_wise) { cancel_move(); cancel_rotate(); clock_wise = false; rotate_degrees(static_cast<int16_t>(theta+165)); move_steps(NORTH, 20); break; } else { cancel_move(); cancel_rotate(); clock_wise = true; rotate_degrees(static_cast<int16_t>(theta+165)); move_steps(NORTH, 20); break; } } break; default: break; } global_rx_buffer.read = true; } break; case ALIGN: if(!align_rgb) { set_rgb_led(255,0,0); align_rgb = true; } float dist, theta, phi; range_and_bearing(target, &dist, &theta, &phi); rotate_degrees(static_cast<int16_t>(theta)); move_steps(NORTH, static_cast<uint16_t>(dist)); if(dist<5) { cancel_move(); rotate_degrees(static_cast<int16_t>(phi)); if(phi < 2 && phi >-2) { char msg[4]; msg[0] = 'F'; memcpy(&msg[1], &target, sizeof(uint16_t)); msg[3] = slot_num; ir_broadcast(&msg[0], sizeof(msg)); state = PRESET; break; } } while(check_for_new_messages()) { char let = (char)global_rx_buffer.buf[0]; uint8_t num = (uint8_t)global_rx_buffer.buf[1]; switch(let) { case 'A': if(num == guitar_id) { wander_rgb = false; state = WANDER; } case 'F': if(num == guitar_id) { wander_rgb = false; state = WANDER; } break; default: break; } global_rx_buffer.read = true; } break; case CALL: if(!call_rgb) { set_rgb_led(0,255,255); call_rgb = true; } if(!first_search) { find_empty_neighbors(guitar_id, row_num, num_in_row); first_search = true; set_timer(10000, 0); } if(check_timer(0)) { for(uint8_t i=0; i<6; i++) { if((neighbors[i]>0) && (neighbors[i]<200)) { /* this message calls needed droplets */ char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'V'; msg[1] = i; ir_broadcast(&msg[0], sizeof(msg)); } } } else { for(uint8_t i=0; i<6; i++) { if((neighbors[i]>0)) { /* timer hasn't gone off, we're list building and calling out all possible neighbors to see which ones are already there */ char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'N'; msg[1] = neighbors[i]; ir_broadcast(&msg[0], sizeof(msg)); } } } while(check_for_new_messages()) { char let = global_rx_buffer.buf[0]; uint8_t num; uint16_t send_id; switch(let) { case 'C': send_id = global_rx_buffer.sender_ID; num = (uint8_t)global_rx_buffer.buf[1]; if((neighbors[num]>0) && (neighbors[num]<200)) { char msg[5]; memset(&msg[0], 0, 3); msg[0] = 'S'; memcpy(&msg[1], &send_id, sizeof(uint16_t)); msg[3] = num; msg[4] = neighbors[num]; ir_broadcast(&msg[0], sizeof(msg)); neighbors[num] = 255; } break; case 'F': memcpy(&send_id, &global_rx_buffer.buf[1], sizeof(uint16_t)); num = (uint8_t)global_rx_buffer.buf[3]; if(send_id == get_droplet_id()) { set_rgb_led(255, 0, 0); call_rgb = false; neighbors[num] = 0; slots_set++; } break; case 'A': num = (uint8_t)global_rx_buffer.buf[1]; for(uint8_t i=0; i<6; i++) { if((neighbors[i] > 0) && (neighbors[i] == num)) { neighbors[i] = 0; slots_needed--; break; } } break; default: break; } global_rx_buffer.read = true; } if(slots_set == slots_needed) { char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'L'; msg[1] = (guitar_id + 1); ir_broadcast(&msg[0], sizeof(msg)); is_set_rgb = false; state = SET; break; } /*if((neighbors[1])==0 && (neighbors[2]==0) && (neighbors[3]==0) && (neighbors[4]==0) && (neighbors[5]==0)) { char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'L'; msg[1] = (guitar_id + 1); ir_broadcast(&msg[0], sizeof(msg)); is_set_rgb = false; state = SET; break; }*/ break; case PRESET: if(!preset_rgb) { set_rgb_led(0, 255, 0); preset_rgb = true; } set_rgb_led(0, 255, 0); while(check_for_new_messages()) { char let = (char)global_rx_buffer.buf[0]; uint8_t num = (uint8_t)global_rx_buffer.buf[1]; uint8_t num2; switch(let) { case 'S': num2 = (uint8_t)global_rx_buffer.buf[4]; if(num2 == guitar_id) { set_rgb_led(255, 0, 0); char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'A'; msg[1] = guitar_id; ir_broadcast(&msg[0], sizeof(msg)); } break; case 'L': if(num==guitar_id) { row_num = get_row_num(guitar_id); num_in_row = get_num_in_row(guitar_id); call_rgb = false; state = CALL; } break; case 'N': if(num==guitar_id) { set_rgb_led(255, 0, 0); char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'A'; msg[1] = guitar_id; ir_broadcast(&msg[0], sizeof(msg)); } break; case 'D': float dist, theta, phi; range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); if(dist<5) { char msg = 'T'; ir_broadcast(&msg, 1); } break; default: break; } global_rx_buffer.read = true; } break; case SET: if(!is_set_rgb) { set_rgb_led(0,0,255); is_set_rgb = true; } while(check_for_new_messages()) { char let = (char)global_rx_buffer.buf[0]; uint8_t num = (uint8_t)global_rx_buffer.buf[1]; switch(let) { case 'N': if(num==guitar_id) { set_rgb_led(255, 0 , 0); is_set_rgb = false; char msg[2]; memset(&msg[0], 0, 2); msg[0] = 'A'; msg[1] = guitar_id; ir_broadcast(&msg[0], sizeof(msg)); } break; case 'D': float dist, theta, phi; range_and_bearing(global_rx_buffer.sender_ID, &dist, &theta, &phi); if(dist<5) { char msg = 'T'; ir_broadcast(&msg, 1); } break; default: break; } global_rx_buffer.read = true; } break; } }