// Called when the bot has a touch marker set static void BotTouchMarkerLogic() { TargetEnemyLogic(self); if (PAST(goal_refresh_time)) { UpdateGoal(self); } if (self->fb.path_state & BOTPATH_RJ_IN_PROGRESS) { if (self->s.v.velocity[2] <= 0) { self->fb.path_state &= ~BOTPATH_RJ_IN_PROGRESS; } } if (! (self->fb.path_state & BOTPATH_RJ_IN_PROGRESS)) { if (PAST (linked_marker_time)) { self->fb.old_linked_marker = NULL; } if (self->fb.old_linked_marker != self->fb.touch_marker) { ProcessNewLinkedMarker (self); } } if (FUTURE(arrow_time)) { if (self->isBot && self->fb.debug_path) { G_bprint(PRINT_HIGH, "%3.2f: arrow_time is %3.2f\n", g_globalvars.time, self->fb.arrow_time); } if (FUTURE(arrow_time2)) { if (g_random() < 0.5) { SetLinkedMarker (self, self->fb.touch_marker, "BotTouchMarkerLogic"); self->fb.old_linked_marker = self->fb.linked_marker; self->fb.path_state = 0; self->fb.linked_marker_time = g_globalvars.time + 0.3; } } } else if (self->fb.linked_marker) { vec3_t dir_move; BotMoveTowardsLinkedMarker(self, dir_move); BotOnGroundMovement(self, dir_move); SetDirectionMove (self, dir_move, ((int)self->s.v.flags & FL_ONGROUND) ? "OnGround" : "InAir"); } else { // The map is, imo, broken at this point, but some old fbca maps are missing links // and at this point would use 'world' // Deliberately don't move and hope that the fall gets us somewhere vec3_t dir_move = { 0, 0, 0 }; SetDirectionMove(self, dir_move, "NoLinkedMarker!"); } SelectWeapon(); }
/* Builds a 2D tree of n nodes in specified range with dir as primary axis (0 for x, 1 for y) */ Tree build_tree(int n,int dir,int lo,int num_proc,double min_x, double max_x,double min_y,double max_y) { double med; Tree t; #ifdef FUTURES future_cell_int fc; #endif if (n==0) return NULL; t = (Tree) ALLOC(lo,sizeof(*t)); if (dir) { dir = !dir; med = median(min_x,max_x,n); #ifndef FUTURES t->left=build_tree(n/2,dir,lo+num_proc/2,num_proc/2,min_x,med,min_y,max_y); t->right=build_tree(n/2,dir,lo,num_proc/2,med,max_x,min_y,max_y); #else FUTURE(n/2,dir,lo+num_proc/2,num_proc/2,min_x,med,min_y,max_y, build_tree,&fc); t->right=build_tree(n/2,dir,lo,num_proc/2,med,max_x,min_y,max_y); #endif t->x = med; t->y = uniform(min_y,max_y); } else { dir = !dir; med = median(min_y,max_y,n); #ifndef FUTURES t->left=build_tree(n/2,dir,lo+num_proc/2,num_proc/2,min_x,max_x,min_y,med); t->right=build_tree(n/2,dir,lo,num_proc/2,min_x,max_x,med,max_y); #else FUTURE(n/2,dir,lo+num_proc/2,num_proc/2,min_x,max_x,min_y,med, build_tree,&fc); t->right=build_tree(n/2,dir,lo,num_proc/2,min_x,max_x,med,max_y); #endif t->y = med; t->x = uniform(min_x,max_x); } t->sz = n; t->next = NULL; t->prev = NULL; #ifdef FUTURES TOUCH(&fc); t->left = (Tree) fc.value; #endif return t; }
/* Compute TSP for the tree t -- use conquer for problems <= sz */ Tree tsp(Tree t,int sz,int nproc) { Tree left,right; Tree leftval; #ifdef FUTURES future_cell_pointer fc; #endif Tree rightval; int nproc_2 = nproc/2; if (t->sz <= sz) return conquer(t); left = t->left; right = t->right; #ifndef FUTURES leftval = tsp(left,sz,nproc_2); #else FUTURE(left,sz,nproc_2,tsp,&fc); #endif rightval = tsp(right,sz,nproc_2); #ifdef FUTURES leftval = (Tree) TOUCH(&fc); leftval = (Tree) fc.value; return merge(leftval,rightval,t,nproc); #else return merge(leftval,rightval,t,nproc); #endif }
Graph MakeGraph(int numvert, int numproc) { int perproc = numvert/numproc; int i,j; int count1; Vertex v,tmp; Vertex block; Graph retval; #ifdef FUTURES future_cell_int fc[MAXPROC]; #endif retval = (Graph) ALLOC(0,sizeof(*retval)); for (i=0; i<MAXPROC; i++) { retval->vlist[i]=NULL; } chatting("Make phase 2\n"); for (j=numproc-1; j>=0; j--) { block = (Vertex) ALLOC(j,perproc*(sizeof(*tmp))); v = NULL; for (i=0; i<perproc; i++) { tmp = block+(perproc-i-1); HashRange = numvert/4; tmp->mindist = 9999999; tmp->edgehash = MakeHash(numvert/4,hashfunc); tmp->next = v; v=tmp; } retval->vlist[j] = v; } chatting("Make phase 3\n"); for (j=numproc-1; j>=0; j--) { count1 = j*perproc; #ifndef FUTURES AddEdges(count1, retval, numproc, perproc, numvert, j); #else FUTURE(count1,retval,numproc,perproc,numvert,j,AddEdges,&fc[j]); #endif } /* for j... */ chatting("Make phase 4\n"); #ifdef FUTURES for (j=0; j<numproc; j++) { TOUCH(&fc[j]); } #endif chatting("Make returning\n"); return retval; }
static void ApplyPhysics (gedict_t* self) { float drop = 0; vec3_t expected_velocity; float vel_length = 0; float hor_speed_squared; float movement_skill = bound (0, self->fb.skill.movement, 1.0); qbool onGround = (int)self->s.v.flags & FL_ONGROUND; // Just perform the move if we're backing away if (FUTURE (arrow_time2)) { return; } if (deathmatch >= 4 && isDuel() && !self->fb.skill.wiggle_run_dmm4) { return; } // Step 1: Apply friction VectorCopy (self->s.v.velocity, expected_velocity); vel_length = VectorLength (expected_velocity); if (vel_length < 1) return; if (self->s.v.waterlevel >= 2) { // Swimming... float waterfriction = cvar ("sv_waterfriction"); drop = vel_length * waterfriction * self->s.v.waterlevel * g_globalvars.frametime; } else if (onGround) { // FIXME: friction is doubled if player is about to drop off a ledge float stopspeed = cvar ("sv_stopspeed"); float friction = cvar ("sv_friction"); float control = vel_length < stopspeed ? stopspeed : vel_length; drop = control * friction * g_globalvars.frametime; } if (drop) { float new_vel = max (vel_length - drop, 0); VectorScale (expected_velocity, new_vel / vel_length, expected_velocity); vel_length = new_vel; } else { vel_length = VectorLength (expected_velocity); } // Step 2: change direction to maximise acceleration in desired direction if (self->s.v.waterlevel >= 2) { // Water movement } else { float min_numerator = onGround ? 319 : 29; float max_numerator = onGround ? 281.6 : -8.4; float used_numerator; float max_incr; vec3_t current_direction; vec3_t original_direction; // Gravity kicks in /* if (!onGround) expected_velocity[2] -= self->gravity * cvar ("sv_gravity") * g_globalvars.frametime; else expected_velocity[2] = 0; */ // Ground & air acceleration is the same hor_speed_squared = (expected_velocity[0] * expected_velocity[0] + expected_velocity[1] * expected_velocity[1]); if (onGround && hor_speed_squared < sv_maxspeed * sv_maxspeed * 0.8 * 0.8) { return; } self->fb.dir_move_[2] = 0; normalize(self->fb.dir_move_, original_direction); normalize(expected_velocity, current_direction); used_numerator = min_numerator + movement_skill * (max_numerator - min_numerator); max_incr = used_numerator * used_numerator; if (hor_speed_squared >= max_incr) { vec3_t perpendicular; vec3_t up_vector = { 0, 0, 1 }; float rotation = acos(max_incr / hor_speed_squared) * 180 / M_PI; // Find out if rotation should be positive or negative CrossProduct (current_direction, original_direction, perpendicular); if ((self->fb.path_state & BOTPATH_CURLJUMP_HINT) && !onGround) { // Once in the air, we rotate in opposite direction // FIXME: THIS IS UGLY HACK if (framecount % 3) { rotation = 0; } else if (self->fb.angle_hint > 0) { rotation = -rotation; } } else if (deathmatch == 4) { if (self->fb.wiggle_run_dir == 0) { self->fb.wiggle_increasing = perpendicular[2] > 0; self->fb.wiggle_run_dir = self->fb.wiggle_increasing ? 1 : -1; } else if (self->fb.wiggle_run_dir > self->fb.skill.wiggle_run_limit && perpendicular[2] < 0) { self->fb.wiggle_increasing = false; } else if (self->fb.wiggle_run_dir < -self->fb.skill.wiggle_run_limit && perpendicular[2] > 0) { self->fb.wiggle_increasing = 1; } else if (self->fb.wiggle_increasing) { ++self->fb.wiggle_run_dir; } else { --self->fb.wiggle_run_dir; } if (self->fb.wiggle_increasing) { rotation = -rotation; } } else if (perpendicular[2] < 0) { rotation = -rotation; } if (rotation) { vec3_t proposed_dir; vec3_t vel_after_rot; vec3_t vel_std; float dp_std, dp_rot; RotatePointAroundVector (proposed_dir, up_vector, current_direction, rotation); // Calculate what mvdsv will do (roughly) PM_Accelerate (expected_velocity, (int)self->s.v.flags & FL_ONGROUND, proposed_dir, vel_after_rot, false); PM_Accelerate (expected_velocity, (int)self->s.v.flags & FL_ONGROUND, current_direction, vel_std, false); // Only rotate if 'better' than moving normally dp_rot = DotProduct (vel_after_rot, original_direction); dp_std = DotProduct (vel_std, original_direction); if (dp_rot > dp_std || dp_rot >= 0.9) { VectorCopy (proposed_dir, self->fb.dir_move_); if (self->fb.debug_path) { PM_Accelerate(expected_velocity, (int)self->s.v.flags & FL_ONGROUND, proposed_dir, vel_after_rot, true); } } else if (self->fb.debug_path) { PM_Accelerate (expected_velocity, (int)self->s.v.flags & FL_ONGROUND, current_direction, vel_std, true); } } else { #ifdef DEBUG_MOVEMENT if (self->fb.debug_path && ! onGround) { G_bprint (PRINT_HIGH, "> AirControl rotation: <ignoring>\n"); } #endif } } } }
QuadTree MakeTree(int size, int center_x, int center_y, int lo_proc, int hi_proc, QuadTree parent, ChildType ct, int level) { int intersect=0; QuadTree retval; #ifdef FUTURES retval = (QuadTree) ALLOC(lo_proc,sizeof(*retval)); #else retval = (QuadTree) mymalloc(sizeof(*retval)); #endif retval->parent = parent; retval->childtype = ct; intersect = CheckIntersect(center_x,center_y,size); size = size/2; if ((intersect==0) && (size<512)) { retval->color = white; retval->nw = NULL; retval->ne = NULL; retval->sw = NULL; retval->se = NULL; } else if (intersect==2) { retval->color=black; retval->nw = NULL; retval->ne = NULL; retval->sw = NULL; retval->se = NULL; } else { if (!level) { retval->color = black; retval->nw = NULL; retval->ne = NULL; retval->sw = NULL; retval->se = NULL; } else { int mid1,mid2; #ifdef FUTURES future_cell_int fc_sw,fc_se,fc_ne; #endif mid1 = (lo_proc+hi_proc)/2; mid2 = (lo_proc+hi_proc+1)/2; #ifndef FUTURES retval->sw = MakeTree(size,center_x-size,center_y-size, (mid2+hi_proc+1)/2,hi_proc,retval, southwest,level-1); retval->se = MakeTree(size,center_x+size,center_y-size, mid2,(mid2+hi_proc)/2,retval, southeast,level-1); retval->ne = MakeTree(size,center_x+size,center_y+size, (lo_proc+mid1+1)/2,mid1,retval, northeast,level-1); retval->nw = MakeTree(size,center_x-size,center_y+size, lo_proc,(lo_proc+mid1)/2,retval, northwest,level-1); #else FUTURE(size,center_x-size,center_y-size, (mid2+hi_proc+1)/2,hi_proc,retval, southwest,level-1,MakeTree,&fc_sw); FUTURE(size,center_x+size,center_y-size, mid2,(mid2+hi_proc)/2,retval, southeast,level-1,MakeTree,&fc_se); FUTURE(size,center_x+size,center_y+size, (lo_proc+mid1+1)/2,mid1,retval, northeast,level-1,MakeTree,&fc_ne); retval->nw = MakeTree(size,center_x-size,center_y+size, lo_proc,(lo_proc+mid1)/2,retval, northwest,level-1); TOUCH(&fc_sw); retval->sw = (QuadTree) fc_sw.value; TOUCH(&fc_se); retval->se = (QuadTree) fc_se.value; TOUCH(&fc_ne); retval->ne = (QuadTree) fc_ne.value; #endif retval->color = grey; } } return retval; }