// This function Poisson samples the inverse Fourier transformed power and populates the volume // with galaxies. void Gendr(std::string file, double variance, fftw_real *deltar3d) { // Create Mersenne twister random number generators for the Poisson sampling, and // to distribute galaxies in a uniform random manner within the cells. std::mt19937_64 generator; // Seed the generator generator.seed(time(0)); std::ofstream fout; // Output filestream double n = nbar*dL*dL*dL; int count = 0; fout.open(file.c_str(),std::ios::out); // Open output file fout.precision(15); // Set the number of digits to output // Loop through all the grid points, assign galaxies uniform random positions within // each cell. for (int i = 0; i < N; ++i) { double xmin = i*dL; double xmax = (i+1)*dL; // Uniform random distribution for the x coordinate std::uniform_real_distribution<double> xpos(xmin, xmax); for (int j = 0; j < N; ++j) { double ymin = j*dL; double ymax = (j+1)*dL; // Uniform random distribution for the y coordinate std::uniform_real_distribution<double> ypos(ymin, ymax); for (int k = 0; k < N; ++k) { double zmin = k*dL; double zmax = (k+1)*dL; // Uniform random distribution for the z coordinate std::uniform_real_distribution<double> zpos(zmin, zmax); int index = k + N*(j+N*i); // Calculate grid index // Check that the matter density field is positive. Set to zero if not. //if (deltar3d[index] < 0.0) continue; // Initialize the Poisson distribution with the value of the matter field double density = n*exp(deltar3d[index]-variance/2); std::poisson_distribution<int> distribution(density); int numGal = distribution(generator); // Randomly Poisson sample count += numGal; // Randomly generate positions for numGal galaxies within the cell for (int gal = 0; gal < numGal; ++gal) { fout << xpos(generator) << " " << ypos(generator) << " " << zpos(generator) << "\n"; } } } } fout.close(); // Close file fout.open("GalaxyNum.dat",std::ios::app); fout << count << " " << file << "\n"; fout.close(); }
void fmingle::sweep_h2(double x0, double x1, int N){ //perform a sweep for h2 double dx = (x1-x0)/(N-1); vec xpos = zeros(N); vec enrg = zeros(N); vec3 corePos1 = {0,0,0}; vec3 corePos2 = {0,0,0}; for(int i = 0; i<N ; i++){ //wrapped = basisbank(); //BS = basis(); //basisbank wrapped (BS); cout << "Reset basisbank" << endl; //fminglebasisbank.bs = basis(); fminglebasisbank.bs.reset(); xpos(i) = x0 + dx*i; corePos1 = {0,0,0}; corePos2 = {0,0,xpos(i)}; fminglebasisbank.bs.add_nucleus(corePos1, 1); fminglebasisbank.bs.add_nucleus(corePos2, 1); fminglebasisbank.add_STO_6G_h(corePos1); //creating an electron positioned at core 1 using STO-6G basis set fminglebasisbank.add_STO_6G_h(corePos2); //creating an electron positioned at core 2 using STO-6G basis set initialize(); //myparty.rhf_solve(2); //e(i) = myparty.rhf_energy; } }
void toggle(void) { if(loc == HEX) { x = xpos() + AnzAdd + Anzahl3; loc = ASCII; } else { x = xpos() * 3 + AnzAdd; loc = HEX; } }
double PosInt::angle(const PosInt &from) const { double angl; int xdiff = xpos()-from.xpos(); angl = atan(static_cast<double>(ypos()-from.ypos())/xdiff); if (xdiff<0) angl += M_PI; return angl; }
void floating_label::draw(surface screen) { if(!visible_) { buf_.assign(nullptr); return; } if(screen == nullptr) { return; } create_surface(); if(surf_ == nullptr) { return; } if(buf_ == nullptr) { buf_.assign(create_compatible_surface(screen, surf_->w, surf_->h)); if(buf_ == nullptr) { return; } } SDL_Rect rect = sdl::create_rect(xpos(surf_->w), ypos_, surf_->w, surf_->h); const clip_rect_setter clip_setter(screen, &clip_rect_); sdl_copy_portion(screen,&rect,buf_,nullptr); sdl_blit(surf_,nullptr,screen,&rect); }
void Cube::initCubeTexture() { QImage xpos("./bin/textures/room/xpos.png"); QImage xneg("./bin/textures/room/xneg.png"); QImage ypos("./bin/textures/room/ypos.png"); QImage yneg("./bin/textures/room/yneg.png"); QImage zpos("./bin/textures/room/zpos.png"); QImage zneg("./bin/textures/room/zneg.png"); int width = xpos.width(); int height = xpos.height(); glGenTextures(1, &m_texture); glBindTexture(GL_TEXTURE_CUBE_MAP, m_texture); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, xpos.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, xneg.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, ypos.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, yneg.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, zpos.bits()); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, zneg.bits()); glBindTexture(GL_TEXTURE_CUBE_MAP, 0); }
void buildParticles(unsigned int particleCount, std::vector<particle*>& particles, sf::Font& font) { auto seed = std::chrono::system_clock::now().time_since_epoch().count(); std::default_random_engine generator(seed); std::uniform_int_distribution<int> xpos(100, 1820); std::uniform_int_distribution<int> ypos(100, 980); std::uniform_int_distribution<int> radius(8, 10); std::uniform_int_distribution<int> mass(10, 20); for (unsigned int i = 0; i < particleCount; i++) { particle* temp = new particle(radius(generator), mass(generator), xpos(generator), ypos(generator),font); particles.push_back(temp); } }
static void draw_pos_text_h(SkCanvas* canvas, const char* text, SkScalar y) { const size_t len = strlen(text); SkAutoTMalloc<SkScalar> xpos(len); for (size_t i = 0; i < len; i++) { xpos[i] = (SkScalar)i; } canvas->drawPosTextH(text, len, xpos, y, SkPaint()); }
/* * Drawing-related functions */ void Creature::draw(WINDOW *w, int player_x, int player_y, bool inverted) { int draw_x = getmaxx(w) / 2 + xpos() - player_x; int draw_y = getmaxy(w) / 2 + ypos() - player_y; if(inverted) { mvwputch_inv(w, draw_y, draw_x, basic_symbol_color(), symbol()); } else if(is_symbol_highlighted()) { mvwputch_hi(w, draw_y, draw_x, basic_symbol_color(), symbol()); } else { mvwputch(w, draw_y, draw_x, symbol_color(), symbol() ); } }
/* draw field */ void BoardWidget::drawBoard() { boardPM = QPixmap(width(), height()); boardPM.fill(*boardColor); QPainter p(&boardPM); p.setRenderHint(QPainter::Antialiasing); QPalette pal( *boardColor ); QPalette pal2 = QWidget::palette(); int boardSize = width() *10/12; if (boardSize > height()) boardSize = height(); QMatrix m; QPoint cp = rect().center(); m.translate(cp.x(), cp.y()); m.scale(boardSize/1100.0, boardSize/1000.0); m.rotate(0); p.setMatrix(m); p.setBrush(pal2.brush(QPalette::Mid)); QPolygon a; int dx=520 /2, dy=(520 *87)/100; a.setPoints(6, -dx,-dy, dx,-dy, 2*dx,0, dx,dy, -dx,dy, -2*dx,0 ); p.drawPolygon(a); drawShadedHexagon(&p, 0,0, 505, 1, pal, false); drawShadedHexagon(&p, 0,0, 512, 3, pal, true); drawShadedHexagon(&p, 0,0, 525, 5, pal2, true); #define xpos(i,j) (495*(2*(i)-(j))/9) #define ypos(j) (500*19*(j)/100) int i,j; for(j=-4;j<5;j++) for(i= ((j>0)?j-4:-4) ; i< ((j<0)?5+j:5) ;i++) { int x=xpos(i,j); int y=ypos(j); drawShadedHexagon(&p, x,y, 50, 2, pal, true); drawShadedHexagon(&p, x,y, 30, 1, pal, false); } }
void floating_label::undraw(surface screen) { if(screen == nullptr || buf_ == nullptr) { return; } SDL_Rect rect = sdl::create_rect(xpos(surf_->w), ypos_, surf_->w, surf_->h); const clip_rect_setter clip_setter(screen, &clip_rect_); sdl_blit(buf_,nullptr,screen,&rect); move(xmove_,ymove_); if(lifetime_ > 0) { --lifetime_; if(alpha_change_ != 0 && (xmove_ != 0.0 || ymove_ != 0.0) && surf_ != nullptr) { // fade out moving floating labels surf_.assign(adjust_surface_alpha_add(surf_,alpha_change_)); } } }
void fileinfo(char *fname) { off_t bytepos; char fstatus[MAXCMD]; char *string; if(fname) { string = malloc((size_t)strlen(fname) + MAXCMD); if(string == NULL) { emsg("Out of memory"); return; } sprintf(string, "\"%s\" ", fname); } else { string = malloc(MAXCMD); if(string == NULL) { emsg("Out of memory"); return; } strcpy(string, "No file "); } if(filemode != NEW && filemode != REGULAR) { strcat(string, "[Not edited] "); } if(P(P_RO)) { strcat(string, "[Read only] "); } if(edits) { strcat(string, "[Modified] "); } if(filesize) { bytepos = (pagepos + y * Anzahl + xpos()) - mem + 1L; sprintf(fstatus, "byte %llu of %llu --%llu%%--", (unsigned long long)bytepos, (unsigned long long)filesize, (unsigned long long)(bytepos * 100L / filesize)); strcat(string, fstatus); } else { strcat(string, " 0 bytes"); } msg(string); free(string); }
/* * xget_object() contains the logic for extracting an individual object from a * packed buffer, which it consumes using xread() and xseek() operations * provided by the caller. flags may be set to either EUP_ALLOC, in which case * new memory is allocated for the variable length items unpacked, or * EUP_NOALLOC, in which case item data pointer indicate locations within the * buffer, using the provided xpos() function. EUP_NOALLOC is generally not * useful for callers representing interaction with actual file streams, and * should not be specified thereby. */ static ea_object_type_t xget_object( ea_file_impl_t *f, ea_object_t *obj, size_t (*xread)(ea_file_impl_t *, void *, size_t), off_t (*xseek)(ea_file_impl_t *, off_t), void *(*xpos)(ea_file_impl_t *), int flags) { ea_size_t sz; uint32_t gp_backskip, scratch32; void *buf; size_t r; /* Read the catalog tag. */ if ((r = xread(f, &obj->eo_catalog, sizeof (ea_catalog_t))) == 0) { EXACCT_SET_ERR(EXR_EOF); return (EO_ERROR); } else if (r != sizeof (ea_catalog_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order32(&obj->eo_catalog); /* * If this is a record group, we treat it separately: only record * groups cause us to allocate new depth frames. */ if ((obj->eo_catalog & EXT_TYPE_MASK) == EXT_GROUP) { obj->eo_type = EO_GROUP; /* Read size field, and number of objects. */ if (xread(f, &sz, sizeof (ea_size_t)) != sizeof (ea_size_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order64(&sz); if (xread(f, &obj->eo_group.eg_nobjs, sizeof (uint32_t)) != sizeof (uint32_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order32(&obj->eo_group.eg_nobjs); /* Now read the group's small backskip. */ if (xread(f, &gp_backskip, sizeof (uint32_t)) != sizeof (uint32_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } /* Push a new depth stack frame. */ if (stack_new_group(f, obj->eo_group.eg_nobjs) != 0) { /* exacct_error set above */ return (EO_ERROR); } /* * If the group has no items, we now need to position to the * end of the group, because there will be no subsequent calls * to process the group, it being empty. */ if (obj->eo_group.eg_nobjs == 0) { if (stack_next_object(f, xread) == -1) { /* exacct_error set above. */ return (EO_ERROR); } } f->ef_advance = 0; EXACCT_SET_ERR(EXR_OK); return (obj->eo_type); } /* * Otherwise we are reading an item. */ obj->eo_type = EO_ITEM; switch (obj->eo_catalog & EXT_TYPE_MASK) { case EXT_STRING: case EXT_EXACCT_OBJECT: case EXT_RAW: if (xread(f, &sz, sizeof (ea_size_t)) != sizeof (ea_size_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order64(&sz); /* * Subtract backskip value from size. */ sz -= sizeof (uint32_t); if ((flags & EUP_ALLOC_MASK) == EUP_NOALLOC) { buf = xpos(f); if (xseek(f, sz) == -1) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } } else { if ((buf = ea_alloc(sz)) == NULL) /* exacct_error set above. */ return (EO_ERROR); if (xread(f, buf, sz) != sz) { ea_free(buf, sz); EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } } obj->eo_item.ei_string = buf; /* * Maintain our consistent convention that string lengths * include the terminating NULL character. */ obj->eo_item.ei_size = sz; break; case EXT_UINT8: if (xread(f, &obj->eo_item.ei_uint8, sizeof (uint8_t)) != sizeof (uint8_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } obj->eo_item.ei_size = sizeof (uint8_t); break; case EXT_UINT16: if (xread(f, &obj->eo_item.ei_uint16, sizeof (uint16_t)) != sizeof (uint16_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order16(&obj->eo_item.ei_uint16); obj->eo_item.ei_size = sizeof (uint16_t); break; case EXT_UINT32: if (xread(f, &obj->eo_item.ei_uint32, sizeof (uint32_t)) != sizeof (uint32_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order32(&obj->eo_item.ei_uint32); obj->eo_item.ei_size = sizeof (uint32_t); break; case EXT_UINT64: if (xread(f, &obj->eo_item.ei_uint64, sizeof (uint64_t)) != sizeof (uint64_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order64(&obj->eo_item.ei_uint64); obj->eo_item.ei_size = sizeof (uint64_t); break; case EXT_DOUBLE: if (xread(f, &obj->eo_item.ei_double, sizeof (double)) != sizeof (double)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order64((uint64_t *)&obj->eo_item.ei_double); obj->eo_item.ei_size = sizeof (double); break; default: /* * We've encountered an unknown type value. Flag the error and * exit. */ EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } /* * Advance over current large backskip value, * and position at the start of the next object. */ if (xread(f, &scratch32, sizeof (scratch32)) != sizeof (scratch32)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } if (stack_next_object(f, xread) == -1) { /* exacct_error set above. */ return (EO_ERROR); } f->ef_advance = 0; EXACCT_SET_ERR(EXR_OK); return (obj->eo_type); }
void BoardWidget::paintEvent(QPaintEvent *) { QPainter p(this); if (boardPM.isNull()) drawBoard(); p.drawPixmap(0, 0, boardPM); /* draw balls */ if (renderMode) { drawPieces(&p); return; } int i,j; p.setRenderHint(QPainter::Antialiasing); int boardSize = width() *10/12; if (boardSize > height()) boardSize = height(); QMatrix m; QPoint cp = rect().center(); m.translate(cp.x(), cp.y()); m.scale(boardSize/1100.0, boardSize/1000.0); m.rotate(0); p.setMatrix(m); p.setBrush(palette().color(QPalette::WindowText)); for(j=-4;j<5;j++) for(i= ((j>0)?j-4:-4) ; i< ((j<0)?5+j:5) ;i++) { int x=xpos(i,j); int y=ypos(j); int w=field[60+j*11+i]; if (w==Board::color1) drawColor(&p, x,y, 35, redColor ); else if (w==Board::color1bright) drawColor(&p, x,y, 35, redHColor ); else if (w==Board::color2) drawColor(&p, x,y, 35, yellowColor ); else if (w==Board::color2bright) drawColor(&p, x,y, 35, yellowHColor ); } if (color1Count >0) { /* the outer marks of color1 */ if (color1Count <12) { for(i=11; i>8 && i>color1Count ;i--) drawColor(&p, xpos(12-i,7-i)+55, ypos(7-i), 35, redColor ); } for(i=14; i>11 && i>color1Count ;i--) drawColor(&p, xpos(-6,10-i)+55, ypos(10-i), 35, redColor ); /* the outer marks of color2 */ if (color2Count <12) { for(i=11; i>8 && i>color2Count ;i--) drawColor(&p, xpos(i-12,i-7)-55, ypos(i-7), 35, yellowColor); } for(i=14; i>11 && i>color2Count ;i--) drawColor(&p, xpos(6,i-10)-55, ypos(i-10), 35, yellowColor); } }
/** * \brief Default constructor */ SpecificWorker::SpecificWorker(MapPrx& mprx) : GenericWorker(mprx) { connect(ci, SIGNAL(clicked()), this, SLOT(moverpataci())); connect(cd, SIGNAL(clicked()), this, SLOT(moverpatacd())); connect(Xpos, SIGNAL(clicked()), this, SLOT(xpos())); connect(Xneg, SIGNAL(clicked()), this, SLOT(xneg())); connect(Ypos, SIGNAL(clicked()), this, SLOT(ypos())); connect(Yneg, SIGNAL(clicked()), this, SLOT(yneg())); connect(Zpos, SIGNAL(clicked()), this, SLOT(zpos())); connect(Zneg, SIGNAL(clicked()), this, SLOT(zneg())); connect(Actualizar, SIGNAL(clicked()), this, SLOT(actualizar())); inner = new InnerModel("/home/ivan/robocomp/files/innermodel/hexapod1pata.xml"); Posini=inner->transform("base","axisA1T"); Posfin=Posini; QVec aux=inner->transform("arm1motor2","arm1motor3"); qDebug()<<aux; angle1=atan(aux.y()/aux.z()); Femur=aux.norm2(); aux=inner->transform("arm1motor3","axisA1T"); angle2=atan(aux.y()/aux.z()); Tibia=aux.norm2(); qDebug()<<aux; Coxa=52; qDebug()<<"-----------------------------"; qDebug()<<" Coxa = "<<Coxa; qDebug()<<" Femur = "<<Femur; qDebug()<<" Tibia = "<<Tibia; qDebug()<<" angle1 = "<<angle1; qDebug()<<" angle2 = "<<angle2; qDebug()<<"-----------------------------"; // Femur=sqrt(14.5*14.5+64.5*64.5); // Tibia=sqrt(123.714*123.714+ 23.6179 *23.6179); H=18.5; // Posini=QVec::zeros(3); // RoboCompJointMotor::MotorParamsList mp = jointmotor_proxy->getAllMotorParams(); // RoboCompJointMotor::MotorGoalPositionList mg; // for(auto m:mp){ // cout<<m.name<<endl; // RoboCompJointMotor::MotorGoalPosition p; // p.name=m.name; // p.maxSpeed=0.1; // p.position=0; // mg.push_back(p); // // mg.insert(p); // } // jointmotor_proxy->setSyncPosition(mg); m1="arm1motor1"; m2="arm1motor2"; m3="arm1motor3"; }
void LightPointNode::traverse(osg::NodeVisitor& nv) { if (_lightPointList.empty()) { // no light points so no op. return; } //#define USE_TIMER #ifdef USE_TIMER osg::Timer timer; osg::Timer_t t1=0,t2=0,t3=0,t4=0,t5=0,t6=0,t7=0,t8=0; #endif #ifdef USE_TIMER t1 = timer.tick(); #endif osgUtil::CullVisitor* cv = nv.asCullVisitor(); #ifdef USE_TIMER t2 = timer.tick(); #endif // should we disable small feature culling here? if (cv /*&& !cv->isCulled(_bbox)*/) { osg::Matrix matrix = *(cv->getModelViewMatrix()); osg::RefMatrix& projection = *(cv->getProjectionMatrix()); osgUtil::StateGraph* rg = cv->getCurrentStateGraph(); if (rg->leaves_empty()) { // this is first leaf to be added to StateGraph // and therefore should not already know current render bin, // so need to add it. cv->getCurrentRenderBin()->addStateGraph(rg); } #ifdef USE_TIMER t3 = timer.tick(); #endif LightPointDrawable* drawable = NULL; osg::Referenced* object = rg->getUserData(); if (object) { if (typeid(*object)==typeid(LightPointDrawable)) { // resuse the user data attached to the render graph. drawable = static_cast<LightPointDrawable*>(object); } else if (typeid(*object)==typeid(LightPointSpriteDrawable)) { drawable = static_cast<LightPointSpriteDrawable*>(object); } else { // will need to replace UserData. OSG_WARN << "Warning: Replacing osgUtil::StateGraph::_userData to support osgSim::LightPointNode, may have undefined results."<<std::endl; } } if (!drawable) { drawable = _pointSprites ? new LightPointSpriteDrawable : new LightPointDrawable; rg->setUserData(drawable); if (cv->getFrameStamp()) { drawable->setSimulationTime(cv->getFrameStamp()->getSimulationTime()); } } // search for a drawable in the RenderLeaf list equal to the attached the one attached to StateGraph user data // as this will be our special light point drawable. osgUtil::StateGraph::LeafList::iterator litr; for(litr = rg->_leaves.begin(); litr != rg->_leaves.end() && (*litr)->_drawable.get()!=drawable; ++litr) {} if (litr == rg->_leaves.end()) { // haven't found the drawable added in the RenderLeaf list, therefore this may be the // first time through LightPointNode in this frame, so need to add drawable into the StateGraph RenderLeaf list // and update its time signatures. drawable->reset(); rg->addLeaf(new osgUtil::RenderLeaf(drawable,&projection,NULL,FLT_MAX)); // need to update the drawable's frame count. if (cv->getFrameStamp()) { drawable->updateSimulationTime(cv->getFrameStamp()->getSimulationTime()); } } #ifdef USE_TIMER t4 = timer.tick(); #endif #ifdef USE_TIMER t7 = timer.tick(); #endif if (cv->getComputeNearFarMode() != osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR) cv->updateCalculatedNearFar(matrix,_bbox); const float minimumIntensity = 1.0f/256.0f; const osg::Vec3 eyePoint = cv->getEyeLocal(); double time=drawable->getSimulationTime(); double timeInterval=drawable->getSimulationTimeInterval(); const osg::Polytope clipvol(cv->getCurrentCullingSet().getFrustum()); const bool computeClipping = false;//(clipvol.getCurrentMask()!=0); //LightPointDrawable::ColorPosition cp; for(LightPointList::iterator itr=_lightPointList.begin(); itr!=_lightPointList.end(); ++itr) { const LightPoint& lp = *itr; if (!lp._on) continue; const osg::Vec3& position = lp._position; // skip light point if it is not contianed in the view frustum. if (computeClipping && !clipvol.contains(position)) continue; // delta vector between eyepoint and light point. osg::Vec3 dv(eyePoint-position); float intensity = (_lightSystem.valid()) ? _lightSystem->getIntensity() : lp._intensity; // slip light point if its intensity is 0.0 or negative. if (intensity<=minimumIntensity) continue; // (SIB) Clip on distance, if close to limit, add transparancy float distanceFactor = 1.0f; if (_maxVisibleDistance2!=FLT_MAX) { if (dv.length2()>_maxVisibleDistance2) continue; else if (_maxVisibleDistance2 > 0) distanceFactor = 1.0f - osg::square(dv.length2() / _maxVisibleDistance2); } osg::Vec4 color = lp._color; // check the sector. if (lp._sector.valid()) { intensity *= (*lp._sector)(dv); // skip light point if it is intensity is 0.0 or negative. if (intensity<=minimumIntensity) continue; } // temporary accounting of intensity. //color *= intensity; // check the blink sequence. bool doBlink = lp._blinkSequence.valid(); if (doBlink && _lightSystem.valid()) doBlink = (_lightSystem->getAnimationState() == LightPointSystem::ANIMATION_ON); if (doBlink) { osg::Vec4 bs = lp._blinkSequence->color(time,timeInterval); color[0] *= bs[0]; color[1] *= bs[1]; color[2] *= bs[2]; color[3] *= bs[3]; } // if alpha value is less than the min intentsity then skip if (color[3]<=minimumIntensity) continue; float pixelSize = cv->pixelSize(position,lp._radius); // cout << "pixelsize = "<<pixelSize<<endl; // adjust pixel size to account for intensity. if (intensity!=1.0) pixelSize *= sqrt(intensity); // adjust alpha to account for max range (Fade on distance) color[3] *= distanceFactor; // round up to the minimum pixel size if required. float orgPixelSize = pixelSize; if (pixelSize<_minPixelSize) pixelSize = _minPixelSize; osg::Vec3 xpos(position*matrix); if (lp._blendingMode==LightPoint::BLENDED) { if (pixelSize<1.0f) { // need to use alpha blending... color[3] *= pixelSize; // color[3] *= osg::square(pixelSize); if (color[3]<=minimumIntensity) continue; drawable->addBlendedLightPoint(0, xpos,color); } else if (pixelSize<_maxPixelSize) { unsigned int lowerBoundPixelSize = (unsigned int)pixelSize; float remainder = osg::square(pixelSize-(float)lowerBoundPixelSize); // (SIB) Add transparency if pixel is clamped to minpixelsize if (orgPixelSize<_minPixelSize) color[3] *= (2.0/3.0) + (1.0/3.0) * sqrt(orgPixelSize / pixelSize); drawable->addBlendedLightPoint(lowerBoundPixelSize-1, xpos,color); color[3] *= remainder; drawable->addBlendedLightPoint(lowerBoundPixelSize, xpos,color); } else // use a billboard geometry. { drawable->addBlendedLightPoint((unsigned int)(_maxPixelSize-1.0), xpos,color); } } else // ADDITIVE blending. { if (pixelSize<1.0f) { // need to use alpha blending... color[3] *= pixelSize; // color[3] *= osg::square(pixelSize); if (color[3]<=minimumIntensity) continue; drawable->addAdditiveLightPoint(0, xpos,color); } else if (pixelSize<_maxPixelSize) { unsigned int lowerBoundPixelSize = (unsigned int)pixelSize; float remainder = osg::square(pixelSize-(float)lowerBoundPixelSize); // (SIB) Add transparency if pixel is clamped to minpixelsize if (orgPixelSize<_minPixelSize) color[3] *= (2.0/3.0) + (1.0/3.0) * sqrt(orgPixelSize / pixelSize); float alpha = color[3]; color[3] = alpha*(1.0f-remainder); drawable->addAdditiveLightPoint(lowerBoundPixelSize-1, xpos,color); color[3] = alpha*remainder; drawable->addAdditiveLightPoint(lowerBoundPixelSize, xpos,color); } else // use a billboard geometry. { drawable->addAdditiveLightPoint((unsigned int)(_maxPixelSize-1.0), xpos,color); } } } #ifdef USE_TIMER t8 = timer.tick(); #endif } #ifdef USE_TIMER cout << "compute"<<endl; cout << " t2-t1="<<t2-t1<<endl; cout << " t4-t3="<<t4-t3<<endl; cout << " t6-t5="<<t6-t5<<endl; cout << " t8-t7="<<t8-t7<<endl; cout << "_lightPointList.size()="<<_lightPointList.size()<<endl; cout << " t8-t7/size = "<<(float)(t8-t7)/(float)_lightPointList.size()<<endl; #endif }
void Level::OnUpdate(sf::Time interval) { if (m_over && sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { m_game->SwitchScene(engine::Factory::create<Level>("assets/scripts/level.json", m_game)); } engine::util::RandomFloat xpos(0, m_size.x); engine::util::RandomFloat rotation(0, 360); engine::Scene::OnUpdate(interval); float delta = interval.asSeconds(); m_spawnTimer -= delta; m_rainbowTime -= delta; m_doubleTime -= delta; m_speedTime -= delta; m_healthTime -= delta; m_scoreAdd -= delta; m_zigzagTime -= delta; if (m_speedTime > 0 && !m_speed) { m_speed = true; m_world->SetGravity(b2Vec2(0.0, 6.0)); } else if (m_speed && m_speedTime < 0) { m_speed = false; m_world->SetGravity(b2Vec2(0.0, 3.0)); } if (m_spawnTimer < 0) { engine::util::RandomFloat chance(0.0, 1.0); if (m_rainbowTime > 0) { m_spawnTimer = 0.1; engine::Node *o = engine::Factory::CreateChildFromFile("assets/scripts/sheep_rainbow.json", m_objectNode); o->SetPosition(xpos(), -200); o->SetRotation(rotation()); } else if (m_zigzagTime > 0) { m_spawnTimer = 0.3; float c = chance(); // MEH engine::Node *o = nullptr; if (c < 0.3) o= engine::Factory::CreateChildFromFile("assets/scripts/cow.json", m_objectNode); else if (c < 0.6) o= engine::Factory::CreateChildFromFile("assets/scripts/pig.json", m_objectNode); else if (c < 0.75) o= engine::Factory::CreateChildFromFile("assets/scripts/sheep_white.json", m_objectNode); else if (c < 0.9) o= engine::Factory::CreateChildFromFile("assets/scripts/sheep_brown.json", m_objectNode); else o= engine::Factory::CreateChildFromFile("assets/scripts/sheep_black.json", m_objectNode); o->SetPosition(m_zig?362:662, -200); m_zig = !m_zig; o->SetRotation(rotation()); } else { m_spawnTimer = 0.5; if (m_speed) m_spawnTimer /= 4; if (m_doubleTime > 0) m_spawnTimer /= 2; for (auto &obj: m_objects) { float c = obj.chance; if (m_doubleTime > 0) c *= 2; if (chance() < c) { engine::Node *o = engine::Factory::CreateChildFromFile(obj.script, m_objectNode); o->SetPosition(xpos(), -200); o->SetRotation(rotation()); } } } } if (m_mouse) { if (!m_mouse->IsRender()) { m_mouse->GetBody()->SetGravityScale(1); m_game->GetWindow()->setMouseCursorVisible(false); m_mouse = nullptr; } else { auto pos = m_game->GetMousePosition(); if (pos.y > 576) pos.y = -10; m_mouse->SetPosition(pos.x, pos.y); } } if (m_healthTime > 0) { Player *player = static_cast<Player *>(GetChildByID("player")); if (player) { player->ChangeEnergy(1.5f); } } if (m_scoreAdd < 0 && !m_over) { AddScore(1); m_scoreAdd = 0.5; } }
void player::fire_gun(int tarx, int tary, bool burst) { item ammotmp; item* gunmod = weapon.active_gunmod(); it_ammo *curammo = NULL; item *used_weapon = NULL; if (weapon.has_flag("CHARGE")) { // It's a charger gun, so make up a type // Charges maxes out at 8. int charges = weapon.num_charges(); it_ammo *tmpammo = dynamic_cast<it_ammo*>(itypes["charge_shot"]); tmpammo->damage = charges * charges; tmpammo->pierce = (charges >= 4 ? (charges - 3) * 2.5 : 0); if (charges <= 4) tmpammo->dispersion = 14 - charges * 2; else // 5, 12, 21, 32 tmpammo->dispersion = charges * (charges - 4); tmpammo->recoil = tmpammo->dispersion * .8; tmpammo->ammo_effects.clear(); // Reset effects. if (charges == 8) { tmpammo->ammo_effects.insert("EXPLOSIVE_BIG"); } else if (charges >= 6) { tmpammo->ammo_effects.insert("EXPLOSIVE"); } if (charges >= 5){ tmpammo->ammo_effects.insert("FLAME"); } else if (charges >= 4) { tmpammo->ammo_effects.insert("INCENDIARY"); } if (gunmod != NULL) { // TODO: range calculation in case of active gunmod. used_weapon = gunmod; } else { used_weapon = &weapon; } curammo = tmpammo; used_weapon->curammo = tmpammo; } else if (gunmod != NULL) { used_weapon = gunmod; curammo = used_weapon->curammo; } else {// Just a normal gun. If we're here, we know curammo is valid. curammo = weapon.curammo; used_weapon = &weapon; } ammotmp = item(curammo, 0); ammotmp.charges = 1; if (!used_weapon->is_gun() && !used_weapon->is_gunmod()) { debugmsg("%s tried to fire a non-gun (%s).", name.c_str(), used_weapon->tname().c_str()); return; } projectile proj; // damage will be set later proj.aoe_size = 0; proj.ammo = curammo; proj.speed = 1000; std::set<std::string> *curammo_effects = &curammo->ammo_effects; if(gunmod == NULL){ std::set<std::string> *gun_effects = &dynamic_cast<it_gun*>(used_weapon->type)->ammo_effects; proj.proj_effects.insert(gun_effects->begin(),gun_effects->end()); } proj.proj_effects.insert(curammo_effects->begin(),curammo_effects->end()); proj.wide = (curammo->phase == LIQUID || proj.proj_effects.count("SHOT") || proj.proj_effects.count("BOUNCE")); proj.drops = (curammo->type == "bolt" || curammo->type == "arrow"); //int x = xpos(), y = ypos(); // Have to use the gun, gunmods don't have a type it_gun* firing = dynamic_cast<it_gun*>(weapon.type); if (has_trait("TRIGGERHAPPY") && one_in(30)) burst = true; if (burst && used_weapon->burst_size() < 2) burst = false; // Can't burst fire a semi-auto // Use different amounts of time depending on the type of gun and our skill if (!proj.proj_effects.count("BOUNCE")) { moves -= time_to_fire(*this, firing); } // Decide how many shots to fire int num_shots = 1; if (burst) num_shots = used_weapon->burst_size(); if (num_shots > used_weapon->num_charges() && !used_weapon->has_flag("CHARGE") && !used_weapon->has_flag("NO_AMMO")) num_shots = used_weapon->num_charges(); if (num_shots == 0) debugmsg("game::fire() - num_shots = 0!"); int ups_drain = 0; int adv_ups_drain = 0; if (weapon.has_flag("USE_UPS")) { ups_drain = 5; adv_ups_drain = 3; } else if (weapon.has_flag("USE_UPS_20")) { ups_drain = 20; adv_ups_drain = 12; } else if (weapon.has_flag("USE_UPS_40")) { ups_drain = 40; adv_ups_drain = 24; } // cap our maximum burst size by the amount of UPS power left if (ups_drain > 0 || adv_ups_drain > 0) while (!(has_charges("UPS_off", ups_drain*num_shots) || has_charges("UPS_on", ups_drain*num_shots) || has_charges("adv_UPS_off", adv_ups_drain*num_shots) || has_charges("adv_UPS_on", adv_ups_drain*num_shots))) { num_shots--; } const bool debug_retarget = false; // this will inevitably be needed //const bool wildly_spraying = false; // stub for now. later, rng based on stress/skill/etc at the start, int weaponrange = weapon.range(); // this is expensive, let's cache. todo: figure out if we need weapon.range(&p); for (int curshot = 0; curshot < num_shots; curshot++) { // Burst-fire weapons allow us to pick a new target after killing the first int zid = g->mon_at(tarx, tary); if ( curshot > 0 && (zid == -1 || g->zombie(zid).hp <= 0) ) { std::vector<point> new_targets; new_targets.clear(); if ( debug_retarget == true ) { mvprintz(curshot,5,c_red,"[%d] %s: retarget: mon_at(%d,%d)",curshot,name.c_str(),tarx,tary); if(zid == -1) { printz(c_red, " = -1"); } else { printz(c_red, ".hp=%d", g->zombie(zid).hp); } } for (unsigned long int i = 0; i < g->num_zombies(); i++) { monster &z = g->zombie(i); int dummy; // search for monsters in radius if (rl_dist(z.posx(), z.posy(), tarx, tary) <= std::min(2 + skillLevel("gun"), weaponrange) && rl_dist(xpos(),ypos(),z.xpos(),z.ypos()) <= weaponrange && sees(&z, dummy) ) { if (!z.is_dead_state()) new_targets.push_back(point(z.xpos(), z.ypos())); // oh you're not dead and I don't like you. Hello! } } if ( new_targets.empty() == false ) { /* new victim! or last victim moved */ int target_picked = rng(0, new_targets.size() - 1); /* 1 victim list unless wildly spraying */ tarx = new_targets[target_picked].x; tary = new_targets[target_picked].y; zid = g->mon_at(tarx, tary); /* debug */ if (debug_retarget) printz(c_ltgreen, " NEW:(%d:%d,%d) %d,%d (%s)[%d] hp: %d", target_picked, new_targets[target_picked].x, new_targets[target_picked].y, tarx, tary, g->zombie(zid).name().c_str(), zid, g->zombie(zid).hp); } else if ( ( !has_trait("TRIGGERHAPPY") || /* double ta TRIPLE TAP! wait, no... */ one_in(3) /* on second though...everyone double-taps at times. */ ) && ( skillLevel("gun") >= 7 || /* unless trained */ one_in(7 - skillLevel("gun")) /* ...sometimes */ ) ) { return; // No targets, so return } else if (debug_retarget) { printz(c_red, " new targets.empty()!"); } } else if (debug_retarget) { const int zid = g->mon_at(tarx, tary); mvprintz(curshot,5,c_red,"[%d] %s: target == mon_at(%d,%d)[%d] %s hp %d",curshot, name.c_str(), tarx ,tary, zid, g->zombie(zid).name().c_str(), g->zombie(zid).hp); } // Drop a shell casing if appropriate. itype_id casing_type = curammo->casing; if (casing_type != "NULL" && !casing_type.empty()) { item casing; casing.make(itypes[casing_type]); // Casing needs a charges of 1 to stack properly with other casings. casing.charges = 1; if( used_weapon->has_gunmod("brass_catcher") != -1 ) { i_add( casing ); } else { int x = 0; int y = 0; int count = 0; do { x = xpos() - 1 + rng(0, 2); y = ypos() - 1 + rng(0, 2); count++; // Try not to drop the casing on a wall if at all possible. } while( g->m.move_cost( x, y ) == 0 && count < 10 ); g->m.add_item_or_charges(x, y, casing); } } // Use up a round (or 100) if (used_weapon->has_flag("FIRE_100")) { used_weapon->charges -= 100; } else if (used_weapon->has_flag("FIRE_50")) { used_weapon->charges -= 50; } else if (used_weapon->has_flag("CHARGE")) { used_weapon->active = false; used_weapon->charges = 0; } else if (!used_weapon->has_flag("NO_AMMO")) { used_weapon->charges--; } // Drain UPS power if (has_charges("adv_UPS_off", adv_ups_drain)) { use_charges("adv_UPS_off", adv_ups_drain); } else if (has_charges("adv_UPS_on", adv_ups_drain)) { use_charges("adv_UPS_on", adv_ups_drain); } else if (has_charges("UPS_off", ups_drain)) { use_charges("UPS_off", ups_drain); } else if (has_charges("UPS_on", ups_drain)) { use_charges("UPS_on", ups_drain); } if (firing->skill_used != Skill::skill("archery") && firing->skill_used != Skill::skill("throw")) { // Current guns have a durability between 5 and 9. // Misfire chance is between 1/64 and 1/1024. if (is_underwater() && !weapon.has_flag("WATERPROOF_GUN") && one_in(firing->durability)) { g->add_msg_player_or_npc(this, _("Your weapon misfires with a wet click!"), _("<npcname>'s weapon misfires with a wet click!") ); return; } else if (one_in(2 << firing->durability)) { g->add_msg_player_or_npc(this, _("Your weapon misfires!"), _("<npcname>'s weapon misfires!") ); return; } } make_gun_sound_effect(*this, burst, used_weapon); double total_dispersion = get_weapon_dispersion(used_weapon); //debugmsg("%f",total_dispersion); int range = rl_dist(xpos(), ypos(), tarx, tary); // penalties for point-blank if (range < (firing->volume/3) && firing->ammo != "shot") total_dispersion *= double(firing->volume/3) / double(range); // rifle has less range penalty past LONG_RANGE if (firing->skill_used == Skill::skill("rifle") && range > LONG_RANGE) total_dispersion *= 1 - 0.4*double(range - LONG_RANGE) / double(range); if (curshot > 0) { if (recoil_add(*this) % 2 == 1) { recoil++; } recoil += recoil_add(*this) / 2; } else { recoil += recoil_add(*this); } int mtarx = tarx; int mtary = tary; int adjusted_damage = used_weapon->gun_damage(); proj.impact = damage_instance::physical(0,adjusted_damage,0); double missed_by = projectile_attack(proj, mtarx, mtary, total_dispersion); if (missed_by <= .1) { // TODO: check head existence for headshot practice(g->turn, firing->skill_used, 5); lifetime_stats()->headshots++; } else if (missed_by <= .2) { practice(g->turn, firing->skill_used, 3); } else if (missed_by <= .4) { practice(g->turn, firing->skill_used, 2); } else if (missed_by <= .6) { practice(g->turn, firing->skill_used, 1); } } if (used_weapon->num_charges() == 0) { used_weapon->curammo = NULL; } }
void MainWindow::openFile() { if( !scene->items().isEmpty() ) { QMessageBox::warning(this, tr("Warning"), tr("All unsaved data will be lost!")); } QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("XML Files (*.xml)")); if(fileName != "") { scene->clearAllItems(); projectName.clear(); commands.clear(); TiXmlDocument doc; if(!doc.LoadFile(fileName.toStdString())) { QMessageBox::critical(this, tr("Error"), tr("Could not open file")); } TiXmlElement * pProjectElement = doc.FirstChildElement("project"); TiXmlElement * pNodeElement; if( pProjectElement == NULL ) { QMessageBox::critical(this, tr("Error"), tr("Could not parse file: <project> not found")); return; } pNodeElement = pProjectElement->FirstChildElement("name"); if( pNodeElement != NULL ) { projectName = QString(pNodeElement->GetText()); ui->projectEdit->setText(projectName); } std::map<QString, HEESGraphicsItem*> nameIndex; // First pass: add components for( pNodeElement = pProjectElement->FirstChildElement("comp"); pNodeElement != NULL; pNodeElement = pNodeElement->NextSiblingElement("comp")) { HEESGraphicsItem * item; QString type(pNodeElement->Attribute("type")); if( type == QString("cti") ) { item = new HEESGraphicsItem(CTI); } else if( type == QString("bank")) { item = new HEESGraphicsItem(BANK); } else if( type == QString("load") ) { item = new HEESGraphicsItem(LOAD); } else if( type == QString("source") ) { item = new HEESGraphicsItem(SOURCE); } else if( type == QString("converter") ) { // will be added in the second pass continue; } else if( type == QString("manager") ) { item = new HEESGraphicsItem(MANAGER); } else { continue; } QString xpos(pNodeElement->Attribute("x_pos")); QString ypos(pNodeElement->Attribute("y_pos")); if( !xpos.isEmpty() && !ypos.isEmpty() ) { item->setPos( xpos.toDouble(), ypos.toDouble() ); } TiXmlElement * pNameElement = pNodeElement->FirstChildElement("name"); if( pNameElement != NULL ) { item->name = QString(pNameElement->GetText()); } TiXmlElement * pDerivedElement = pNodeElement->FirstChildElement("derived"); if( pDerivedElement == NULL ) { QMessageBox::critical(this, tr("Error"), tr("Could not parse file: <derived> not found for component:")+item->name); scene->clearAllItems(); projectName.clear(); commands.clear(); return; } if( type != QString("cti") ) { item->derivedType = QString(pDerivedElement->Attribute("type")); } TiXmlElement * pElement; for( pElement = pDerivedElement->FirstChildElement(); pElement != NULL; pElement = pElement->NextSiblingElement() ) { item->myAttributes()->insertBack( pElement->Value(), pElement->GetText() ); } nameIndex[item->name] = item; scene->addItem(item); } // Second pass: add converters for( pNodeElement = pProjectElement->FirstChildElement("comp"); pNodeElement != NULL; pNodeElement = pNodeElement->NextSiblingElement("comp")) { HEESGraphicsItem * item; QString type(pNodeElement->Attribute("type")); if( type == QString("converter") ) { // will be added in the second pass item = new HEESGraphicsItem(CONVERTER); } else { continue; } QString xpos(pNodeElement->Attribute("x_pos")); QString ypos(pNodeElement->Attribute("y_pos")); if( !xpos.isEmpty() && !ypos.isEmpty() ) { item->setPos( xpos.toDouble(), ypos.toDouble() ); } TiXmlElement * pNameElement = pNodeElement->FirstChildElement("name"); if( pNameElement != NULL ) { item->name = QString(pNameElement->GetText()); } TiXmlElement * pDerivedElement = pNodeElement->FirstChildElement("derived"); if( pDerivedElement == NULL ) { QMessageBox::critical(this, tr("Error"), tr("Could not parse file: <derived> not found for component:")+item->name); scene->clearAllItems(); projectName.clear(); commands.clear(); return; } item->derivedType = QString(pDerivedElement->Attribute("type")); TiXmlElement * pElement; for( pElement = pDerivedElement->FirstChildElement(); pElement != NULL; pElement = pElement->NextSiblingElement() ) { item->myAttributes()->insertBack( pElement->Value(), pElement->GetText() ); } TiXmlElement * pElementA = pNodeElement->FirstChildElement("port_a"); TiXmlElement * pElementB = pNodeElement->FirstChildElement("port_b"); std::map<QString, HEESGraphicsItem*>::iterator it; if( pElementA != NULL && (it = nameIndex.find(QString(pElementA->GetText()))) != nameIndex.end() ) { if( it->second->myType() != CONVERTER && it->second->myType() != MANAGER ) item->setLeftItem(it->second); } if( pElementB != NULL && (it = nameIndex.find(QString(pElementB->GetText()))) != nameIndex.end() ) { if( it->second->myType() != CONVERTER && it->second->myType() != MANAGER ) item->setRightItem(it->second); } nameIndex[item->name] = item; scene->addItem(item); } // Thrid pass: add sensors for( pNodeElement = pProjectElement->FirstChildElement("sensor"); pNodeElement != NULL; pNodeElement = pNodeElement->NextSiblingElement("sensor") ) { QString target(pNodeElement->Attribute("target")); QString prop(pNodeElement->Attribute("property")); if( nameIndex.find(target) != nameIndex.end() ) { nameIndex[target]->mySensors()->insertBack(prop); } } // Fourth pass: add commands for( pNodeElement = pProjectElement->FirstChildElement("cmd"); pNodeElement != NULL; pNodeElement = pNodeElement->NextSiblingElement("cmd") ) { QString type(pNodeElement->Attribute("type")); double time; pNodeElement->Attribute("time", &time); if( type == QString("set") || type == QString("get") ) { QString targetName(pNodeElement->Attribute("target")); for(TiXmlElement * pElement = pNodeElement->FirstChildElement(); pElement != NULL; pElement = pElement->NextSiblingElement() ) { Command command; command.type = type; command.time = time; command.targetName = targetName; command.propertyName = QString(pElement->Value()); command.propertyValue = QString(pElement->GetText()); commands.insertBack(command); } } else if( type == QString("finish") || type == QString("sim") ) { Command command; command.type = type; command.time = time; commands.insertBack(command); } } } }
double Creature::projectile_attack(const projectile &proj, int sourcex, int sourcey, int targetx, int targety, double shot_dispersion) { int range = rl_dist(sourcex,sourcey,targetx,targety); // .013 * trange is a computationally cheap version of finding the tangent. // (note that .00325 * 4 = .013; .00325 is used because deviation is a number // of quarter-degrees) // It's also generous; missed_by will be rather short. double missed_by = shot_dispersion * .00325 * range; // TODO: move to-hit roll back in here if (missed_by >= 1.) { // We missed D: // Shoot a random nearby space? targetx += rng(0 - int(sqrt(double(missed_by))), int(sqrt(double(missed_by)))); targety += rng(0 - int(sqrt(double(missed_by))), int(sqrt(double(missed_by)))); } std::vector<point> trajectory; int tart = 0; if (g->m.sees(sourcex, sourcey, targetx, targety, -1, tart)) { trajectory = line_to(sourcex,sourcey,targetx,targety,tart); } else { trajectory = line_to(sourcex,sourcey,targetx,targety,0); } // Set up a timespec for use in the nanosleep function below timespec ts; ts.tv_sec = 0; ts.tv_nsec = BULLET_SPEED; int dam = proj.impact.total_damage() + proj.payload.total_damage(); it_ammo *curammo = proj.ammo; // Trace the trajectory, doing damage in order int tx = trajectory[0].x; int ty = trajectory[0].y; int px = trajectory[0].x; int py = trajectory[0].y; for (int i = 0; i < trajectory.size() && (dam > 0 || (proj.proj_effects.count("FLAME"))); i++) { px = tx; py = ty; (void) px; (void) py; tx = trajectory[i].x; ty = trajectory[i].y; // Drawing the bullet uses player u, and not player p, because it's drawn // relative to YOUR position, which may not be the gunman's position. g->draw_bullet(g->u, tx, ty, i, trajectory, proj.proj_effects.count("FLAME")? '#':'*', ts); /* TODO: add running out of momentum back in if (dam <= 0 && !(proj.proj_effects.count("FLAME"))) { // Ran out of momentum. break; } */ int mondex = g->mon_at(tx, ty); // ignore non-point-blank digging targets (since they are underground) if (mondex != -1 && g->zombie(mondex).digging() && rl_dist(xpos(), ypos(), g->zombie(mondex).xpos(), g->zombie(mondex).ypos()) > 1) mondex = -1; // If we shot us a monster... // TODO: add size effects to accuracy // If there's a monster in the path of our bullet, and either our aim was true, // OR it's not the monster we were aiming at and we were lucky enough to hit it double cur_missed_by; if (i < trajectory.size() - 1) { // Unintentional hit cur_missed_by = std::max(rng_float(0,1.5)+(1-missed_by),0.2); } else { cur_missed_by = missed_by; } if (mondex != -1 && cur_missed_by <= 1.0) { monster &z = g->zombie(mondex); dealt_damage_instance dealt_dam; z.deal_projectile_attack(this, missed_by, proj, dealt_dam); std::vector<point> blood_traj = trajectory; blood_traj.insert(blood_traj.begin(), point(xpos(), ypos())); //splatter(this, blood_traj, dam, &z); TODO: add splatter effects //back in dam = 0; // TODO: general case this so it works for all npcs, instead of only // player } else if (g->u.xpos() == tx && g->u.ypos() == ty && cur_missed_by <= 1.0) { dealt_damage_instance dealt_dam; g->u.deal_projectile_attack(this, missed_by, proj, dealt_dam); std::vector<point> blood_traj = trajectory; blood_traj.insert(blood_traj.begin(), point(xpos(), ypos())); } else { g->m.shoot(tx, ty, dam, i == trajectory.size() - 1, proj.proj_effects); } } // Done with the trajectory! if (g->m.move_cost(tx, ty) == 0) { tx = px; ty = py; } // we can only drop something if curammo exists if (curammo != NULL && proj.drops && !(proj.proj_effects.count("IGNITE")) && !(proj.proj_effects.count("EXPLOSIVE")) && ((curammo->m1 == "wood" && !one_in(5)) || (curammo->m1 != "wood" && !one_in(15)) )) { item ammotmp = item(curammo, 0); ammotmp.charges = 1; g->m.add_item_or_charges(tx, ty, ammotmp); } ammo_effects(tx, ty, proj.proj_effects); if (proj.proj_effects.count("BOUNCE")) { for (unsigned long int i = 0; i < g->num_zombies(); i++) { monster &z = g->zombie(i); // search for monsters in radius 4 around impact site if (rl_dist(z.posx(), z.posy(), tx, ty) <= 4) { // don't hit targets that have already been hit if (!z.has_effect("bounced") && !z.dead) { g->add_msg(_("The attack bounced to %s!"), z.name().c_str()); projectile_attack(proj, tx, ty, z.posx(), z.posy(), shot_dispersion); break; } } } } return missed_by; }
double Creature::projectile_attack(const projectile &proj, int targetx, int targety, double shot_dispersion) { return projectile_attack(proj, xpos(), ypos(), targetx, targety, shot_dispersion); }