void Entity::updateTransform(const Camera &camera) { qreal angleToCamera = QLineF(to2d(m_pos), to2d(camera.pos())).angle(); qreal angle = QLineF(QPointF(), to2d(m_dir)).angle(); int cameraAngleIndex = mod(qRound(angleToCamera + 22.5), 360) / 45; m_angleIndex = mod(qRound(cameraAngleIndex * 45 - angle + 22.5), 360) / 45; QVector3D delta = to3d(QLineF::fromPolar(0.18 * m_scale, 270.1 + 45 * cameraAngleIndex).p2()); m_a = m_pos - delta; m_b = m_pos + delta; }
int tickAttackTower(gnode* grid,tower* t){ tower_type *type; if (t->type==BASE) return 0; type=typesTowerGet(t->type); if (type==0){ t->health=-1; return 0; } if (t->target==0){ //find near npc int x=idtox(t->position); int y=idtoy(t->position); int i,j,k; int yid,xid; npc* tmp; for (i=0;i<type->distanse;i++) for(j=0;j<config.area_size[i];j++) if (((xid=x+config.area_array[i][j].x)>=0 && x+config.area_array[i][j].x<config.gridsize) && ((yid=y+config.area_array[i][j].y)>=0 && y+config.area_array[i][j].y<config.gridsize)) for (k=0;k<MAX_GROUPS;k++) if (k!=config.players[t->owner].group) for(tmp=grid[to2d(xid,yid)].npcs[k]; tmp!=0;tmp=tmp->next) if (canSee(grid,&(vec){x+0.5,y+0.5},&tmp->position)>0) if(sqr(x+0.5-(tmp->position.x))+sqr(y+0.5-(tmp->position.y))<=sqr(type->distanse)){ t->target=tmp; setMask(t,TOWER_TARGET); if (rand()%100<60) return 0; } }else{ if (t->target->id==0) return 0; if(rand()%100<8){ t->target=0; return 0; } if (sqr(t->target->position.x-getGridx(t->position))+ sqr(t->target->position.y-getGridy(t->position))> sqr(type->distanse)){ t->target=0; return 0; } // printDebug("\t|%d %d\n",t->attack_count,type->attack_speed); if (t->attack_count>=type->attack_speed){ t->attack_count=0; bullet* b;//set params of bullet if ((b=newBullet())==0){ perror("newBullet tickAttackBullet"); return -1; } vec position={getGridx(t->position),getGridy(t->position)}; // getTargetPos(vec *pos, vec *dir, float v, vec * $pos, float $v){ // vec* target=getTargetPos(&t->target->position, // &t->target->direction, // config.npc_types[t->target->type].move_speed, // &position, // config.bullet_types[type->bullet_type].speed // ); memcpy(&b->position,&position,sizeof(vec)); memcpy(&b->source,&position,sizeof(vec)); //memcpy(&b->destination,target,sizeof(vec)); // printDebug("aaaa = %g|%g {%g|%g}\n",target->x,target->y,t->target->position.x,t->target->position.y); b->ntarget=t->target; b->destination.x=t->target->position.x; b->destination.y=t->target->position.y; b->max_dist=type->distanse; b->type=type->bullet_type; b->damage=type->damage; b->support=type->support; b->group=config.players[t->owner].group; b->owner=t->owner; setMask(b,BULLET_CREATE); // b->target=NPC; getDir(&b->position,&b->destination,&b->direction); // memcpy(&b->effects,&config.npc_types[n->type].effects,sizeof(effects)); } } /**/ return 0; }
int tickProcessBullet(gnode * grid,bullet * b){ if (b->detonate==0){ bullet_type * type=typesBulletGet(b->type); if (type==0){ b->detonate=1; return 0; } //vec dir={0,0}; // printDebug("!!%g %g\n",b->position.x,b->position.y); //float length=getDir(&b->position,&b->destination,&dir); float delta=1; if (type->move_type!=SHOT){ b->position.x+=b->direction.x*type->speed; b->position.y+=b->direction.y*type->speed; delta=type->speed; if (delta<0.2) delta=0.2; }else{ b->position.x=b->destination.x; b->position.y=b->destination.y; } setMask(b,BULLET_POSITION); if (eqInD(b->position.x,b->destination.x,delta)&& eqInD(b->position.y,b->destination.y,delta)){ int i,j,k; int multiple=0; int x=(int)b->position.x; int y=(int)b->position.y; int xid,yid; int _id=to2d(x,y); if ( x<0 || y<0 || x>=config.gridsize || y>=config.gridsize) goto out; //tower search { tower * tmp; if (_id<sqr(config.gridsize)) if ((tmp=grid[_id].tower)>0) if(config.players[tmp->owner].group!=b->group){ damageTower(tmp,b); multiple++; } } if (type->attack_type==SINGLE && multiple>0) goto out; //npc search { npc* tmp; if (_id<sqr(config.gridsize)) for(j=0;j<MAX_GROUPS;j++) for(tmp=grid[_id].npcs[j]; tmp!=0;tmp=tmp->next) if (config.players[tmp->owner].group!=b->group) if (eqInD(tmp->position.x,b->position.x,delta)&& eqInD(tmp->position.y,b->position.y,delta)) //attack npc near the destination { damageNpc(tmp,b); multiple++; if (type->attack_type==SINGLE) goto out; if (type->attack_type==MULTIPLE && multiple>type->area) goto out; } //if npc not in node, see nodes near i=0; for(j=0;j<config.area_size[i];j++) if (((xid=x+config.area_array[i][j].x)>=0 && x+config.area_array[i][j].x<config.gridsize) && ((yid=y+config.area_array[i][j].y)>=0 && y+config.area_array[i][j].y<config.gridsize)) for(k=0;k<MAX_GROUPS;k++) for(tmp=grid[to2d(xid,yid)].npcs[k]; tmp!=0;tmp=tmp->next) if (config.players[tmp->owner].group!=b->group) if (eqInD(tmp->position.x,b->position.x,delta)&& eqInD(tmp->position.y,b->position.y,delta)) //attack first npc in gnode, need to correct { damageNpc(tmp,b); multiple++; if (type->attack_type==SINGLE) goto out; if (type->attack_type==MULTIPLE && multiple>type->area) goto out; } } //add area damage to Npc //add area damage to towers if (type->attack_type==AREA || type->attack_type==AREA_FF){ //add area gamage npc* tmp; for (i=0;i<type->area;i++) for(j=0;j<config.area_size[i];j++) if (((xid=x+config.area_array[i][j].x)>=0 && x+config.area_array[i][j].x<config.gridsize) && ((yid=y+config.area_array[i][j].y)>=0 && y+config.area_array[i][j].y<config.gridsize)){ //tower if (grid[to2d(xid,yid)].tower!=0) if (canSee(grid,&b->position,&(vec){xid+0.5,yid+0.5})>0) if(type->attack_type==AREA? config.players[grid[to2d(xid,yid)].tower->owner].group!=b->group :1){ damageTower(grid[to2d(xid,yid)].tower,b); } //npc for (k=0;k<MAX_GROUPS;k++) if (type->attack_type==AREA?k!=b->group:1) for(tmp=grid[to2d(xid,yid)].npcs[k]; tmp!=0;tmp=tmp->next) if (canSee(grid,&b->position,&tmp->position)>0) damageNpc(tmp,b); } } out: b->detonate++; setMask(b,BULLET_DETONATE); }else{ if (b->ntarget!=0){ if (glength(&b->ntarget->position,&b->source)>b->max_dist){ b->ntarget=0; }else{ //TODO: add folow attr memcpy(&b->destination,&b->ntarget->position,sizeof(b->destination)); getDir(&b->position,&b->destination,&b->direction); } } } } return 0; }