bool Bullet::handleTimer() { setYpos(ypos() - dy); if (ypos()<0) { h = true; return true; } if (ypos() > (1.0-height())) { setYpos(1.0-height()); h = true; return true; } return false; }
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 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); } }
/* * 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 CEntity::RenderAuras() { if( !(m_bounds && m_visible && !m_auras.empty()) ) return; const SPlayerColour& playerCol = m_player->GetColour(); glPushMatrix(); glTranslatef(m_graphics_position.X, m_graphics_position.Y, m_graphics_position.Z); size_t i=0; for ( AuraTable::iterator it=m_auras.begin(); it!=m_auras.end(); ++it, ++i ) { CVector4D color = it->second->m_color; glColor4f(color.m_X, color.m_Y, color.m_Z, color.m_W); #ifdef SELECTION_TERRAIN_CONFORMANCE //This starts to break when the radius is bigger if ( it->second->m_radius < 15.0f ) { glBegin(GL_TRIANGLE_FAN); glVertex3f(0.0f, GetAnchorLevel(m_graphics_position.X, m_graphics_position.Z)-m_graphics_position.Y+.5f, 0.0f); for ( int j=0; j<AURA_CIRCLE_POINTS; ++j ) { CVector2D ypos( m_unsnappedPoints[i][j].x+m_graphics_position.X, m_unsnappedPoints[i][j].y+m_graphics_position.Z ); CVector3D pos( m_unsnappedPoints[i][j].x, GetAnchorLevel(ypos.x, ypos.y)- m_graphics_position.Y+.5f, m_unsnappedPoints[i][j].y ); glVertex3f(pos.X, pos.Y, pos.Z); } //Loop around CVector3D pos( m_unsnappedPoints[i][0].x, GetAnchorLevel(m_unsnappedPoints[i][0].x+m_graphics_position.X, m_unsnappedPoints[i][0].y+m_graphics_position.Z)- m_graphics_position.Y+.5f, m_unsnappedPoints[i][0].y ); glVertex3f(pos.X, pos.Y, pos.Z); glEnd(); // GL_TRIANGLE_FAN } //Draw edges glEnable(GL_LINE_SMOOTH); glLineWidth(1.0f); glBegin(GL_LINE_LOOP); glColor3f( playerCol.r, playerCol.g, playerCol.b ); for ( int j=0; j<AURA_CIRCLE_POINTS; ++j ) { CVector2D ypos( m_unsnappedPoints[i][j].x+m_graphics_position.X, m_unsnappedPoints[i][j].y+m_graphics_position.Z ); CVector3D pos( m_unsnappedPoints[i][j].x, GetAnchorLevel(ypos.x, ypos.y)- m_graphics_position.Y+.5f, m_unsnappedPoints[i][j].y ); glVertex3f(pos.X, pos.Y, pos.Z); } glEnd(); glDisable(GL_LINE_SMOOTH); #else if ( it->second->m_radius < 15.0f ) { for ( int j=0; j<SELECTION_CIRLCE_POINTS; ++j ) glVertex3f(m_unsnappedPoints[i][j].x, .25f, m_unsnappedPoints[i][j].y); glVertex3f(m_unsnappedPoints[i][0].x, .25f, m_unsnappedPoints[i][0].y); } glEnd(); //Draw edges glBegin(GL_LINE_LOOP); glColor3f( col.r, col.g, col.b ); for ( int j=0; j<SELECTION_CIRLCE_POINTS; ++j ) glVertex3f(unsnappedPoints[i][j].x, .25f, m_unsnappedPoints[i][j].y); glEnd(); #endif } glPopMatrix(); }
/** * \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"; }
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); }
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 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); } }
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); } } } }