inline bool from_script( const char* _v ) { if ( _v ) { allStatesStr_ = ""; itemStatesStr_ = ""; std::size_t vLen( ::strlen( _v ) ); /// NOTE: there is a memory leak and crash here when using QString /// on Windows, a hand-made loop to copy the states seems /// could avoid crashing. std::size_t idx( 0 ); while ( idx < vLen ) { if ( _v[ idx ] == ',' ) { ++idx; break; } if ( _v[ idx ] == '0' || _v[ idx ] == '1' ) { allStatesStr_.push_back( _v[ idx ] ); } ++idx; } while ( idx < vLen ) { if ( _v[ idx ] == ']' ) { ++idx; break; } if ( _v[ idx ] == '0' || _v[ idx ] == '1' ) { itemStatesStr_.push_back( _v[ idx ] ); } ++idx; } return true; } return false; }
/*********************************************************************** * BasicAI * update ***********************************************************************/ void fired::BasicAI::update() { if (target) if (target->dead) target = NULL; selectTarget(); if (!target) return; owner->character->setAiming(atan2(target->phys.center.y - owner->character->phys.center.y, target->phys.center.x - owner->character->phys.center.x)); owner->character->phys.jumpdown = false; if (target->phys.center.x < owner->character->phys.center.x) owner->character->moveLeft(); else owner->character->moveRight(); if (target->phys.center.y < owner->character->phys.center.y - 32) owner->character->jump(); else if (target->phys.center.y > owner->character->phys.center.y + 32) owner->character->jumpdown(); if (vLen(owner->character->phys.center - target->phys.center) < owner->character->phys.size.x / 2 + owner->character->getRange()) { owner->character->shot(); owner->character->unshot(); } }
/*********************************************************************** * BasicAI * selectTarget ***********************************************************************/ void fired::BasicAI::selectTarget() { float minDist, dist; minDist = -1; for (unsigned int i = 0; i < world->chars.size(); i++) { if (world->chars[i]->dead) continue; if (owner->character->isEnemy(world->chars[i]->fraction)) { dist = vLen(owner->character->phys.center - world->chars[i]->phys.center); if (dist > owner->character->stats.aimrange) continue; if (target && dist > owner->character->stats.aimrange * 0.66f) continue; if (minDist == -1) { minDist = dist; target = world->chars[i]; } else if (dist < minDist) { minDist = dist; target = world->chars[i]; } } } }
/*********************************************************************** * vNorm ***********************************************************************/ sf::Vector2f vNorm(sf::Vector2f v) { return v / vLen(v); }
/*********************************************************************** Fast Ray-Box Intersection by Andrew Woo from "Graphics Gems", Academic Press, 1990 ***********************************************************************/ bool lineBoxCollision(sf::FloatRect box, sf::FloatRect ray, sf::Vector2f *coord, sf::Vector2f *normal, float *dist) { bool inside = true; sf::Vector2i quadrant; int whichPlane; sf::Vector2f maxT; sf::Vector2f candidatePlane; if(ray.left < box.left) { quadrant.x = LEFT; candidatePlane.x = box.left; inside = false; } else if (ray.left > box.left + box.width) { quadrant.x = RIGHT; candidatePlane.x = box.left + box.width; inside = false; } else { quadrant.x = MIDDLE; } if(ray.top < box.top) { quadrant.y = LEFT; candidatePlane.y = box.top; inside = false; } else if (ray.top > box.top + box.height) { quadrant.y = RIGHT; candidatePlane.y = box.top + box.height; inside = false; } else { quadrant.y = MIDDLE; } if(inside) { *coord = sf::Vector2f(ray.left, ray.top); return true; } if (quadrant.x != MIDDLE && ray.width !=0.) maxT.x = (candidatePlane.x - ray.left) / ray.width; else maxT.x = -1.; if (quadrant.y != MIDDLE && ray.height !=0.) maxT.y = (candidatePlane.y - ray.top) / ray.height; else maxT.y = -1.; whichPlane = 0; if (maxT.x < maxT.y) whichPlane = 1; if (whichPlane == 0) { if (maxT.x < 0.) return false; } else { if (maxT.y < 0.) return false; } if (whichPlane == 0) { coord->x = candidatePlane.x; coord->y = ray.top + maxT.x * ray.height; normal->x = quadrant.x; normal->y = 0; if (coord->y < box.top || coord->y > (box.top + box.height)) return false; } else { coord->x = ray.left + maxT.y * ray.width; coord->y = candidatePlane.y; normal->x = 0; normal->y = quadrant.y; if (coord->x < box.left || coord->x > (box.left + box.width)) return false; } if (dist) { *dist = vLen(sf::Vector2f(coord->x - ray.left, coord->y - ray.top)); if (*dist > vLen(sf::Vector2f(ray.width, ray.height))) return false; } return true; }
/* * Normalize vector <v_in> (scale it so its length becomes 1) and put the result * into <v_out>. */ void vNorm(Vector *v_out, Vector *v_in) { double len = vLen(v_in); vScale(v_out, v_in, 1 / len); }