void obj_BL_init_tb(obj *o,evt *e,lnk *l) { obj *co; evt *me,*de; lnk *nl; me=get_evt(); evt_func_set[E_bl_dummy](me,o,NULL,NULL,3.0); ins_evt(o,me); // ход пустого субъекта (защита от мгновенных ходов) me=get_evt(); evt_func_set[E_bl_eturn](me,o,NULL,NULL,40.0); ins_evt(o,me); // переход хода по таймауту de=get_evt(); evt_func_set[E_bl_eturnd](de,o,NULL,NULL,0.0); me->e=de; de->e=me; nl=evt_lnk_ins(lnks_tags[E_bl_dummy],o,de,NULL); de->l=nl; nl->l=nl; o->turn=0; // первый ход co=o->bo; o->nact=1; while(co!=NULL) { o->nact++; // if(co->bitf&GOF_ISNIF!=0 && co->s.me!=NULL) // объект управляемый и движется, остановить надобно // evt_func_act[E_mvf_user](co,co->s.me,NULL); co->turn=0; // первый ход // для встроенных ботов создаем событие планирования хода и вставляем в очередь if(co->bitf&GOF_ISNIF==0) { me=get_evt(); evt_func_set[E_bt_obj](me,co,NULL,NULL,3.0*rand()/RAND_MAX); ins_evt(co,me); } co=co->next; } o->rt=GTIME; // время окончания предыдущего хода, совпадает со временем начала текущего cmd_send_bl_begin(o); // оповестим участников о начале боя }
void spark_matka_act(obj *o) { evt *me; obj *co; int i; if(o->mem->tt==0.0) o->mem->tt=GTIME; if(GTIME-o->mem->tt<18.0) // слишком рано принимать решения { me=get_evt(); evt_spark_set(me,o,NULL,NULL,36.0); ins_evt(o,me); return; } if(o->pl->mem->d[1]!=0) // идет война { if(o->pl->mem->d[2]<o->pl->mem->d[3]) obj_create_SP(o,4); else obj_create_SP(o,2); drop_UL_stat(o); me=get_evt(); evt_spark_set(me,o,NULL,NULL,36.0); ins_evt(o,me); return; } co=get_UL_eda(o->pl); for(i=0;i<6 && o->pl->mem->pid[i]!=0;i++); if((o->pl->mem->d[2]==0 || co->dev.cm/o->pl->mem->d[2]>20.0) && i>1) { if(o->pl->mem->d[2]*2<o->pl->mem->d[3]) obj_create_SP(o,2); else obj_create_SP(o,2); drop_UL_stat(o); me=get_evt(); evt_spark_set(me,o,NULL,NULL,36.0); ins_evt(o,me); return; } else if(1.0*rand()/RAND_MAX>0.8) { obj_create_SP(o,3); drop_UL_stat(o); me=get_evt(); evt_spark_set(me,o,NULL,NULL,36.0); ins_evt(o,me); return; } me=get_evt(); evt_spark_set(me,o,NULL,NULL,36.0); ins_evt(o,me); }
void evt_init_obj_act(obj *o,evt *e,lnk *l) { obj *co,*no; obj_func_init[o->tag](o,NULL,NULL); del_evt(o,e); free_evt(o,e); no=o->next; if(no!=NULL) { e=get_evt(); evt_init_obj_set(e,no,NULL,NULL,0.0); ins_evt(no,e); } if(o->tag==T_SHAB) return; // контейнер шаблонов, шаблоны не инициализируем. co=o->bo; if(co!=NULL) { e=get_evt(); evt_init_obj_set(e,co,NULL,NULL,0.0); ins_evt(co,e); } }
// событие начала движения объекта в бою в режиме реального времени void evt_bmv_act(obj *o,evt *e,lnk *l) { double dr,t=0.0,tx=l->tx,ty=l->ty; int mode=l->n; if(o->pl->bmode==1) { evt_bm_act(o,e,l); return; } // пошаговый режим free_lnk(NULL,l); e->l=NULL; del_evt(o,e); free_evt(o,e); o->s.me=NULL; dr=(GTIME-o->s.ct)*o->s.v; o->s.cx+=o->s.tx*dr; o->s.cy+=o->s.ty*dr; o->s.v=o->dev.pwr[1]/(1.0*o->dev.cm); if(mode!=0 && (tx!=0.0 || ty!=0.0)) // движение в указанную точку { tx-=o->s.cx; ty-=o->s.cy; dr=sqrt(tx*tx+ty*ty); t=dr/o->s.v; dr=1.0/dr; tx*=dr; ty*=dr; l=get_lnk(); l->tx=0.0; l->ty=0.0; l->n=0; e=get_evt(); evt_bmv_set(e,o,NULL,l,t); ins_evt(o,e); o->s.me=e; } else { dr=tx*tx+ty*ty; if(dr>1.001) { dr=1.0/sqrt(dr); tx*=dr; ty*=dr; } } o->s.tx=tx; o->s.ty=ty; if(tx!=0.0 || ty!=0.0) o->s.ct=GTIME; locs_send_mv(o); }
// нужно подсчитать время необходимое для копания и дать приказ // еще не реализована void spark_set_ASkopanie(obj *o) { obj *co=o->bo; double dt; evt *me; int i,pid; // printf("spark_set_ASkopanie\n"); while(co!=NULL && co->tag!=T_CRGO) co=co->next; if(co==NULL) { printf("У спарка нету CRGO\n"); exit(0); } if(spark_act_AStest(o,o->pl)!=0) { // выходим из AS и стираем о нем инфу spark_set_ASexit(o); pid=o->mem->pid[0]; memcpy(o->mem->p[0],o->mem->p[1],sizeof(float)*5*3); memcpy(&o->mem->pid[0],&o->mem->pid[1],sizeof(int)*5); o->mem->p[5][0]=0.0; o->mem->p[5][1]=0.0; o->mem->pid[5]=pid; o->mem->ct=2; o->mem->tt=GTIME; return; } o->mem->ct=2; o->mem->tt=GTIME; dt=(co->dev.pwr[1]-co->dev.cm)/co->dev.pwr[2]+1.0; me=get_evt(); evt_spark_set(me,o,NULL,NULL,dt); ins_evt(o,me); }
void buse_FLD_rt(obj *o,evt *e,lnk *l) { double dp,dt; obj *bo=o->pl->pl; evt *me; if(l!=NULL) free_lnk(NULL,l); e->l=NULL; del_evt(o,e); free_evt(o,e); o->s.me=NULL; dp=o->dev.pwr[0]-o->dev.pwr[1]; if(dp>0.0) { dt=GTIME-o->s.ct; o->dev.pwr[1]+=dt*o->dev.pwr[2]; if(o->dev.pwr[1]>o->dev.pwr[0]) o->dev.pwr[1]=o->dev.pwr[0]; dp=o->dev.pwr[0]-o->dev.pwr[1]; } if(GTIME==o->s.ct) // было повреждение поля, нужно сообщить клиентам состояние { } o->s.ct=GTIME; // посчитаем не нужно ли вставить еще одно событие if(dp<=0.0) return; if(o->dev.pwr[2]<=0.0) return; dt=dp/o->dev.pwr[2]; me=get_evt(); evt_buse_set(me,o,NULL,NULL,dt); ins_evt(o,me); o->s.me=me; }
// вызывается вдали от UL, приказ спарку лететь к UL void spark_set_ULgo(obj *o) { obj *wo=o->pl; lnk *l=o->locl; lnk *nlo; obj *ulo=NULL; double dr,dx,dy,dt; evt *me; int golod,massa; // printf("spark_set_ULgo\n"); if(o->mem->hname[0]==0) // родного улья нету, вызываю либо ASsearch, либо ASgo { golod=get_spark_golod(o); massa=get_spark_massa(o); if(golod>1 && massa>0) { spark_set_Wpitanie(o); return; } // кушаем if(golod<2) { spark_set_ASsearch(o); return; } // в поиске if(golod==2) { spark_set_ASgo(o); return; } // возвращаемся на ближайший AS } dt=1.0/o->s.v; // обратная скорость спарка dx=o->mem->hx-o->s.cx; dy=o->mem->hy-o->s.cy; dr=sqrt(dx*dx+dy*dy); o->s.ct=GTIME; dt*=dr; o->s.tx=dx/dr; o->s.ty=dy/dr; me=get_evt(); evt_spark_set(me,o,NULL,NULL,dt); ins_evt(o,me); o->mem->tt=GTIME; o->mem->ct=3; }
void show_args_for_debug() { int i, max_pnl; if(ttm.set_pnl_num) max_pnl = ttm.pnl_num; else max_pnl = PNL_NUM; for(i=0;i<max_pnl;i++) { printf("ap %d (on pnl %d), ",get_ap(i), i); printf("ap_read_evt: %d, ",get_evt(i)); printf("ap_display_fb: %d, ",get_fb(i)); printf("pnl_%d_read_evt: %d\n",i, get_pnl_evt(i)); } printf("master panel : %d\n",ttm.pnl_arg); printf("calibrate : %s\n",(ttm.calibrate)?"yes":"no"); printf("split mode : %s\n",(ttm.split)?"yes":"no"); if(ttm.arg.bind.set) { int j; for (i = 0; i < ttm.bind_data.pnl_num; i++) { printf("bind panel %d : ", i); for (j = 0; j < ttm.bind_data.pnl[i].ap_num; j++) { printf("%d ",ttm.bind_data.pnl[i].group[j]); } printf("\n"); } } }
void evt_init_newobj(obj *o) { obj *co; evt *e; obj_func_init[o->tag](o,NULL,NULL); co=o->bo; if(co!=NULL) { e=get_evt(); evt_init_obj_set(e,co,NULL,NULL,0.0); ins_evt(co,e); } }
void obj_SP_init(obj *o,evt *e,lnk *l) { evt *me; lnk *ml; double dr; if(o->pl->tag==T_WORLD) // если спарк внутри другого объекта, то он никуда не летит { dr=(GTIME-o->s.ct)*o->s.v; o->s.cx+=o->s.tx*dr; o->s.cy+=o->s.ty*dr; o->s.tx=0; o->s.ty=0; o->s.ct=GTIME; obj_FF_init(o,e,l); } o->dev.cm=0; o->dev.pwr[0]=o->dev.pwr[1]=o->dev.pwr[2]=0; if(o->pl->tag!=T_SP) // если спарк не находтся в животе у мамы, то он должен думать { me=get_evt(); evt_func_set[E_spark](me,o,NULL,NULL,1.0+(49.0*rand()/RAND_MAX)); ins_evt(o,me); // поскольку спарки могут летать в космосе, то нужно зарегистрировать реакцию // на коррекцию или уничтожение события пересечения с границей локации // в результате после первого вызова E_spark, будет вызвано E_cold_loc, // которое при необходимости создаст E_col_loc и вставит его в очередь. me=get_evt(); evt_func_set[E_cold_loc](me,o,NULL,NULL,0.0); ml=evt_lnk_ins(lnks_tags[E_spark],o,me,NULL); ml->l=ml; me->l=ml; } }
// событие смерти объекта в бою // объект выкидывается из боя // если объект управляемый, то еще телепортируется в портал // если не управляемый, то уничтожается void bkill_PERS_rt(obj *o,evt *e,lnk *l) { double x,y,dr; obj *po; lnk *ml; evt *me; // останавливаю корабль if(o->s.me!=NULL) // событие уже есть { me=o->s.me; me->t=GTIME; me->l->tx=0.0; me->l->ty=0.0; me->l->n=0; move_evt(o,me); } else // события нет, создаю { ml=get_lnk(); ml->tx=0.0; ml->ty=0.0; ml->n=0; me=get_evt(); evt_func_set[E_bmv](me,o,NULL,ml,0.0); ins_evt(o,me); o->s.me=me; } // loc_obj_unreg(o); // убираю корабль с карты po=o->port; ml=get_lnk(); ml->o=po; me=get_evt(); evt_func_set[E_prich_user](me,o,NULL,ml,0.1); ins_evt(o,me); /* dr=(GTIME-po->s.ct)*po->s.v; x=po->s.cx+po->s.tx*dr; y=po->s.cy+po->s.ty*dr; if(1.0*rand()/RAND_MAX>0.5) dr=-1.0; else dr=1.0; o->s.cx=x+po->s.xs*dr*(0.55+0.45*rand()/RAND_MAX); if(1.0*rand()/RAND_MAX>0.5) dr=-1.0; else dr=1.0; o->s.cy=y+po->s.ys*dr*(0.55+0.45*rand()/RAND_MAX); o->s.ct=GTIME; o->s.tx=0.0; o->s.ty=0.0; o->s.v=0.0; loc_obj_reg(o,0); // cmd_send_iam(o); // отправляю список объектов видимых локаций locs_send_obj(o); */ }
void spark_set_Wpitanie(obj *o) { // посмотрим что есть в пузе obj *co=o->bo,*ro,*mo=NULL; obj *ftn_o=NULL; obj *crgo_o=NULL; float *rm,m=0.0; int i; evt *me; // printf("spark_set_Wpitanie\n"); while(co!=NULL) { if(co->tag==T_FTN) ftn_o=co; if(co->tag==T_CRGO) crgo_o=co; co=co->next; } if(ftn_o==NULL || crgo_o==NULL) { printf("У спарка отсутствует FTN или CRGO\n"); exit(0); } ro=crgo_o->bo; while(ro!=NULL) { if(ro->tag==T_RES) { if(ro->s.img!=6 && ro->dev.cm>0.0) // выбрасываю рес { // выбрасываю рес if(mo==NULL) mo=obj_create_MUSOR(o->pl,o); obj_create_RES(mo,ro->s.img,ro->dev.cm); // уменьшаю массу спарка ro->pl->dev.cm-=ro->dev.cm; ro->pl->pl->dev.cm-=ro->dev.cm; ro->dev.cm=0; } else // найдена еда, перегоняю рес в здоровье 1 к 1 { m=ro->dev.cm; if(ftn_o->dev.pwr[0]-ftn_o->dev.pwr[1]<m) m=ftn_o->dev.pwr[0]-ftn_o->dev.pwr[1]; ro->pl->dev.cm-=m; ro->pl->pl->dev.cm-=m; ro->dev.cm-=m; } ro=ro->next; } else // это не рес, тоже выбрасываю { if(mo==NULL) mo=obj_create_MUSOR(o->pl,o); co=ro->next; obj_ch_parent(ro,mo); ro=co; } } ftn_o->dev.pwr[1]+=m; me=get_evt(); evt_spark_set(me,o,NULL,NULL,1.0); ins_evt(o,me); }
// вызывается вдали от AS, приказ спарку лететь к AS void spark_set_ASgo(obj *o) { double dr,dx,dy,dt; evt *me; // printf("spark_set_ASgo\n"); if(o->mem->p[0][0]==0.0 && o->mem->p[0][1]==0.0) { spark_set_ASsearch(o); return; } dt=(1.0*o->dev.cm)/o->dev.pwr[1]; // обратная скорость спарка dx=o->mem->p[0][0]-o->s.cx; dy=o->mem->p[0][1]-o->s.cy; dr=sqrt(dx*dx+dy*dy); o->s.ct=GTIME; dt*=dr; o->s.tx=dx/dr; o->s.ty=dy/dr; me=get_evt(); evt_spark_set(me,o,NULL,NULL,dt); ins_evt(o,me); o->mem->tt=GTIME; o->mem->ct=1; }
void BL_init_rt(obj *o) { obj *co; evt *me; co=o->bo; while(co!=NULL) { // для встроенных ботов создаем событие планирования хода и вставляем в очередь if(co->tag!=T_PERS) { me=get_evt(); evt_func_set[E_bobj](me,co,NULL,NULL,3.0*rand()/RAND_MAX); ins_evt(co,me); } co=co->next; } cmd_send_bl_begin(o); // оповестим участников о начале боя }
void buse_FLD_tb(obj *o,evt *e,lnk *l) { double dp,dt; obj *bo=o->pl->pl; evt *me; if(l!=NULL) free_lnk(NULL,l); e->l=NULL; del_evt(o,e); free_evt(o,e); o->s.me=NULL; dp=o->dev.pwr[0]-o->dev.pwr[1]; dt=bo->rt-o->rt; if(dt>=0.0) // первый вызов за ход { if(dp>0.0) { o->dev.pwr[1]+=dt*o->dev.pwr[2]; if(o->dev.pwr[1]>o->dev.pwr[0]) o->dev.pwr[1]=o->dev.pwr[0]; dp=o->dev.pwr[0]-o->dev.pwr[1]; } o->rt=bo->s.ct; } // вызов в течении хода, посчитаем как идет восстановление if(dp>0.0) { dt=GTIME-o->rt; o->dev.pwr[1]+=dt*o->dev.pwr[2]; if(o->dev.pwr[1]>o->dev.pwr[0]) o->dev.pwr[1]=o->dev.pwr[0]; dp=o->dev.pwr[0]-o->dev.pwr[1]; } if(GTIME==o->rt) // было повреждение поля, нужно сообщить клиентам состояние { } o->rt=GTIME; // посчитаем не нужно ли вставить еще одно событие if(dp<=0.0) return; if(o->dev.pwr[2]<=0.0) return; dt=dp/o->dev.pwr[2]*RBTURN_TIME; if(GTIME-bo->s.ct+dt>1.0) return; // за ход не укладываемся me=get_evt(); evt_buse_set(me,o,NULL,NULL,dt); ins_evt(o,me); }
// нужно определить время питания и дать приказ void spark_set_ULpitanie(obj *o) { obj *co,*ftn_o=NULL,*eng_o=NULL; evt *me; float dt; // printf("spark_set_ULpitanie\n"); co=o->bo; while(co!=NULL) { if(co->tag==T_FTN) ftn_o=co; else if(co->tag==T_ENG) eng_o=co; co=co->next; } if(ftn_o==NULL || eng_o==NULL) { printf("У спарка нету FTN или ENG\n"); exit(0); } dt=(ftn_o->dev.pwr[0]-ftn_o->dev.pwr[1])/ftn_o->dev.pwr[2]+1.0; me=get_evt(); evt_spark_set(me,o,NULL,NULL,dt); ins_evt(o,me); o->mem->ct=0; o->mem->tt=GTIME; }
void spark_set_ASexit(obj *o) { double dr,cx,cy; evt *me; // printf("spark_set_ASexit\n"); dr=(GTIME-o->pl->s.ct)*o->pl->s.v; cx=o->pl->s.cx+o->pl->s.tx*dr; cy=o->pl->s.cy+o->pl->s.ty*dr; o->mem->p[0][0]=cx; o->mem->p[0][1]=cy; o->mem->pid[0]=(int)o->pl; if(o->mem->hname[0]==0) // дома нет, буду временно домом считать AS { o->mem->hx=cx; o->mem->hy=cy; } obj_ch_parent(o,o->pl->pl); // выхожу из AS o->s.cx=cx; o->s.cy=cy; // присваиваю координаты от родительского объекта o->s.tx=o->s.ty=0.0; o->s.v=0; o->s.ct=GTIME; loc_obj_reg(o,1); // регистрирую спарка в локациях me=get_evt(); evt_spark_set(me,o,NULL,NULL,1.0); ins_evt(o,me); o->mem->ct=3; // спарк летит в улей }
void spark_set_ULexit(obj *o) { double dr,cx,cy; evt *me; // проверим не пора ли умереть if(o->mem->te<GTIME) { spark_selfkill(o); return; } // больше события не вызываются // printf("spark_set_ULexit\n"); dr=(GTIME-o->pl->s.ct)*o->pl->s.v; o->mem->hx=o->pl->s.cx+o->pl->s.tx*dr; o->mem->hy=o->pl->s.cy+o->pl->s.ty*dr; strcpy(o->mem->hname,o->pl->dn); o->mem->d[0]=o->pl->mem->d[0]; obj_ch_parent(o,o->pl->pl); // выхожу из UL o->s.cx=o->mem->hx; o->s.cy=o->mem->hy; // присваиваю координаты от родительского объекта o->s.tx=o->s.ty=0.0; o->s.v=0; o->s.ct=GTIME; loc_obj_reg(o,1); // регистрирую спарка в локациях me=get_evt(); evt_spark_set(me,o,NULL,NULL,1.0); ins_evt(o,me); o->mem->ct=1; // спарк летит к астероиду }
void spark_act_btl(obj *o,evt *e,lnk *l) { obj *bo=o->pl; obj *co,*eo=NULL; obj *wo1=NULL,*wo2=NULL; evt *me; double minr=0,dr,dx,dy,cx,cy,r; double wt1,wt2; // текущее время подготовки оружия к выстрелу double dt,ct; int n; char *b; lnk *nl; // del_evt(o,e); free_evt(o,e); dr=(GTIME-o->s.ct)*o->s.v; o->s.cx+=o->s.tx*dr; o->s.cy+=o->s.ty*dr; o->s.ct=GTIME; o->s.tx=0.0; o->s.ty=0.0; cx=o->s.cx; cy=o->s.cy; co=bo->bo; while(co!=NULL) { if(co->bside!=0 && co->bside!=o->bside) // противник найден { dr=(GTIME-co->s.ct)*co->s.v; dx=co->s.cx+co->s.tx*dr-cx; dy=co->s.cy+co->s.ty*dr-cy; dr=1.0/(dx*dx+dy*dy); if(dr>minr) { minr=dr; eo=co; } } co=co->next; } if(eo==NULL) // врагов нету, выхожу из боя { obj_ch_parent(o,o->pl->pl); me=get_evt(); evt_spark_set(me,o,NULL,NULL,1.0); ins_evt(o,me); return; } dr=(GTIME-eo->s.ct)*eo->s.v; minr=sqrt(minr); dx=eo->s.cx+eo->s.tx*dr-cx; dy=eo->s.cy+eo->s.ty*dr-cy; r=1.0/minr; dx*=minr; dy*=minr; // найдем параметры оружия co=o->bo; while(co!=NULL) { if(co->tag==T_WPN) if(co->s.img==1) wo1=co; else wo2=co; co=co->next; } wt1=GTIME-wo1->s.ct; wt2=GTIME-wo2->s.ct; if(wt1>=wo1->dev.pwr[2] && wo1->s.me==NULL) { // формирую команду выстрела по цели nl=get_lnk(); nl->st[0]=0; nl->o=eo; nl->tx=0.0; nl->ty=0.0; me=get_evt(); evt_buse_set(me,wo1,NULL,nl,0.0); ins_evt(wo1,me); wt1=0.0; } wt1=wo1->dev.pwr[2]-wt1; // время до следующего выстрела if(r<=wo2->dev.pwr[0] && wt2>=wo2->dev.pwr[2] && wo2->s.me==NULL) { // формирую команду выстрела по цели nl=get_lnk(); nl->st[0]=0; nl->o=eo; nl->tx=0.0; nl->ty=0.0; me=get_evt(); evt_buse_set(me,wo2,NULL,nl,0.0); ins_evt(wo2,me); dt=wo2->dev.pwr[2]; } else dt=wo2->dev.pwr[2]-wt2; if(r>wo2->dev.pwr[0]) // подсчитаем время подлета { dt=(r-wo2->dev.pwr[0])/o->s.v; // формирую команду подлета к цели o->s.ct=GTIME; o->s.tx=dx; o->s.ty=dy; } if(dt>wt1) dt=wt1; me=get_evt(); evt_spark_set(me,o,NULL,NULL,dt+1.0); ins_evt(o,me); }
void obj_AS_init(obj *o,evt *e,lnk *l) { evt *me; me=get_evt(); evt_func_set[E_orb](me,o,NULL,NULL,0.0); ins_evt(o,me); }
void spark_set_ASsearch(obj *o) { obj *wo=o->pl; lnk *l=o->locl; lnk *nlo; evt *me; int i,locn; obj *aso=NULL; double dr,fi,cx,cy,tx,ty; // printf("spark_set_ASsearch\n"); o->mem->ct=1; o->mem->tt=GTIME; // осмотрим видимые локации на предмет наличия полезных астероидов while(l!=NULL) { nlo=wo->locs[l->ln].ol; while(nlo!=NULL) // пройдемся по списку объектов в данной локации { if(nlo->o->tag==T_AS && spark_act_AStest(o,nlo->o)==0) // опа, астероид, посмотрим не посещали ли мы его { for(i=1;i<6 && o->mem->pid[i]!=(int)nlo->o;i++); if(i==6) // еще не копали, ура, оценим полезность и примем решение лететь ли к { fi=(GTIME-nlo->o->s.ct)*nlo->o->s.v; cx=nlo->o->s.cx+nlo->o->s.tx*fi-o->s.cx; cy=nlo->o->s.cy+nlo->o->s.ty*fi-o->s.cy; if(aso==NULL || dr>cx*cx+cy*cy) { dr=cx*cx+cy*cy; aso=nlo->o; } } } if(nlo->o->tag==T_UL && o->mem->hname[0]==0) // опа, нашел новый дом, живем { fi=(GTIME-nlo->o->s.ct)*nlo->o->s.v; o->mem->hx=nlo->o->s.cx+nlo->o->s.tx*fi; o->mem->hy=nlo->o->s.cy+nlo->o->s.ty*fi; strcpy(o->mem->hname,nlo->o->dn); } nlo=nlo->next; } l=l->next; } if(aso!=NULL) // вперед к цели { // заявим астероид в качестве цели fi=(GTIME-aso->s.ct)*aso->s.v; dr=sqrt(dr); o->mem->p[0][0]=aso->s.cx+aso->s.tx*fi; o->mem->p[0][1]=aso->s.cy+aso->s.ty*fi; o->mem->pid[0]=(int)aso; cx=o->mem->p[0][0]-o->s.cx; cy=o->mem->p[0][1]-o->s.cy; o->s.tx=cx/dr; o->s.ty=cy/dr; // параметры движения определены, устанавливаем событие me=get_evt(); evt_spark_set(me,o,NULL,NULL,dr/o->s.v); ins_evt(o,me); return; } // летим до новой локации if(o->s.cx==o->mem->hx && o->s.cy==o->mem->hy) { fi=(2.0*M_PI*rand())/RAND_MAX; o->s.tx=cos(fi); o->s.ty=sin(fi); } else { tx=o->s.cx-o->mem->hx; ty=o->s.cy-o->mem->hy; fi=1.0/sqrt(tx*tx+ty*ty); tx*=fi; ty*=fi; fi=(M_PI*rand())/RAND_MAX-0.5*M_PI; o->s.tx=tx*cos(fi)-ty*sin(fi); o->s.ty=tx*sin(fi)+ty*cos(fi); } // параметры движения определены, устанавливаем событие dr=get_loc_col_time(o)+1.0; // тут нужно прикинуть как далеко спарк залетит и хватит ли ему сил на возвращение // похоже тут нужно решать квадратное уравнение, а лень // поэтому пусть дохнет me=get_evt(); evt_spark_set(me,o,NULL,NULL,dr); ins_evt(o,me); }
void obj_ARS_init(obj *o,evt *e,lnk *l) { obj_CRGO_init(o,e,l); e=get_evt(); evt_func_set[E_buse](e,o,NULL,NULL,0.0); ins_evt(o,e); o->s.me=e; }
// событие использования оружия в бою void buse_WPN_rt(obj *o,evt *e,lnk *l) { obj *eo=l->o,*co; obj *bo; obj *mo; double dr,r,rmin,d,ex=l->tx,ey=l->ty; double fi,rt,mx,my,tx,ty,fx,fy; float dmg[8][2],dmgsum=0.0; int i,n; char *b; lnk *ml,*nl; evt *me; e->l=NULL; del_evt(o,e); free_evt(o,e); mo=o->pl; bo=mo->pl; if(bo->tag!=T_BL) { free_lnk(NULL,l); o->s.me=NULL; return; } // бой закончился // проверяю готовность устройства rt=GTIME-o->s.ct; if(rt<o->dev.pwr[2]) // объект не готов к использованию, сдвигаю событие { printf("Подозрительное место, делаю задержку с повторным вызовом\n"); me=get_evt(); evt_buse_set(me,o,NULL,l,o->dev.pwr[2]-rt+0.001); ins_evt(o,me); o->s.me=me; return; } if(l->st[0]==0) { free_lnk(NULL,l); o->s.me=NULL; } // одиночный выстрел else if(l->st[0]==1) { if(eo==NULL || eo->pl==bo) { me=get_evt(); evt_buse_set(me,o,NULL,l,o->dev.pwr[2]); ins_evt(o,me); o->s.me=me; } // продолжаю очередь else { free_lnk(NULL,l); o->s.me=NULL; return; } // уже мертв, обрываю очередь } dr=(GTIME-mo->s.ct)*mo->s.v; mx=mo->s.cx+mo->s.tx*dr; my=mo->s.cy+mo->s.ty*dr; if(eo!=NULL) { dr=(GTIME-eo->s.ct)*eo->s.v; ex=eo->s.cx+eo->s.tx*dr; ey=eo->s.cy+eo->s.ty*dr; } // нужно стрельнуть и посмотреть куда попали // найдем направление выстрела tx=ex-mx; ty=ey-my; fi=(1.0-o->dev.pwr[1])/(0.636619772367581343+o->dev.pwr[1])*(1.0-2.0*rand()/RAND_MAX); fx=tx*cos(fi)-ty*sin(fi); fy=tx*sin(fi)+ty*cos(fi); // направление выстрела dr=fx*fx+fy*fy; dr=1.0/sqrt(dr); fx*=dr; fy*=dr; rmin=o->dev.pwr[0]*2.0; // дальность на которой повреждения 0 co=bo->bo; eo=NULL; while(co!=NULL) // пройдемся по объектам и найдем в кого попали { dr=(GTIME-co->s.ct)*co->s.v; ex=co->s.cx+co->s.tx*dr-mx; ey=co->s.cy+co->s.ty*dr-my; r=fx*ex+fy*ey; if(r>0.0 && r<rmin && co!=mo) // не очень правильно, ну да пусть будет так { r=fabs(fx*ey-fy*ex); if(r<co->s.r1) { eo=co; rmin=r; } } co=co->next; } o->s.ct=GTIME; if(eo==NULL) //никуда не попали, создадим сообщение и закончим на этом { n=snprintf(NULL,0,"<BUSE t=\"%f\" id=\"%x\" obj=\"%x\" trg=\"%f,%f\" res=\"0\" />",GTIME,mo,o,fx,fy)+1; b=mymalloc(n); snprintf(b,n,"<BUSE t=\"%f\" id=\"%x\" obj=\"%x\" trg=\"%f,%f\" res=\"0\" />",GTIME,mo,o,fx,fy); cmd_send_buse(bo, b, n); myfree(b); return; } // подсчитаем повреждения for(i=0;i<7;i++) { dmg[i][0]=o->dev.atkp[i][0]+(o->dev.atkp[i][1]-o->dev.atkp[i][0])*rand()/RAND_MAX; } // найдем все генераторы поля dmg[7][0]=dmg[7][1]=0; ml=eo->dev.dvsl; while(ml!=NULL) { ml=get_slot_bytype(ml,'F'); if(ml!=NULL) { co=ml->o; for(i=0;i<7;i++) { dmg[i][1]=co->dev.defp[i][0]+(co->dev.defp[i][1]-co->dev.defp[i][0])*rand()/RAND_MAX; if(dmg[i][1]>dmg[i][0]) dmg[i][1]=dmg[i][0]; dmg[i][0]-=dmg[i][1]; dmg[7][0]+=dmg[i][1]; } dmg[7][1]=upd_FLD_rt(co); // состояние поля на текущий момент if(dmg[7][0]>dmg[7][1]) // заряда поля не достаточно, часть повреждений нужно вернуть { dr=(dmg[7][0]-dmg[7][1])/dmg[7][0]; for(i=0;i<7;i++) dmg[i][0]+=dmg[i][1]*dr; dmg[7][0]=dmg[7][1]; } dmgsum+=dmg[7][0]; co->dev.pwr[1]-=dmg[7][0]; if(dmg[7][0]>0.0) { n=snprintf(NULL,0,"<BFLD t=\"%f\" id=\"%x\" obj=\"%x\" dmg=\"%f\" />",GTIME-bo->s.ct,eo,co,dmg[7][0])+1; b=mymalloc(n); snprintf(b,n,"<BFLD t=\"%f\" id=\"%x\" obj=\"%x\" dmg=\"%f\" />",GTIME-bo->s.ct,eo,co,dmg[7][0]); cmd_send_buse(bo, b, n); myfree(b); me=get_evt(); evt_buse_set(me,co,NULL,NULL,0.0); ins_evt(co,me); // ревизия состояния поля } ml=ml->next; } } // найдем все слои брони, в отличие от поля, броня поглощает часть повреждений, // а остальная часть идет на ее разрушение. Если состояние брони 0 то она // пропускает повреждения дальше dmg[7][0]=dmg[7][1]=0; ml=eo->dev.dvsl; while(ml!=NULL) { ml=get_slot_bytype(ml,'H'); if(ml!=NULL && ml->o->dev.chull>0.0) { co=ml->o; for(i=0;i<7;i++) { dmg[i][1]=co->dev.defp[i][0]+(co->dev.defp[i][1]-co->dev.defp[i][0])*rand()/RAND_MAX; if(dmg[i][1]>dmg[i][0]) dmg[i][1]=dmg[i][0]; dmg[i][0]-=dmg[i][1]; dmg[7][0]+=dmg[i][0]; } dmg[7][1]=co->dev.chull; // состояние брони на текущий момент if(dmg[7][0]>dmg[7][1]) { dr=(dmg[7][0]-dmg[7][1])/dmg[7][0]; for(i=0;i<7;i++) dmg[i][0]*=dr; dmg[7][0]=dmg[7][1]; } dmgsum+=dmg[7][0]; co->dev.chull-=dmg[7][0]; if(dmg[7][0]>0.0) { n=snprintf(NULL,0,"<BDMG t=\"%f\" id=\"%x\" obj=\"%x\" dmg=\"%f\" />",GTIME-bo->s.ct,eo,co,dmg[7][0])+1; b=mymalloc(n); snprintf(b,n,"<BDMG t=\"%f\" id=\"%x\" obj=\"%x\" dmg=\"%f\" />",GTIME-bo->s.ct,eo,co,dmg[7][0]); cmd_send_buse(bo, b, n); myfree(b); } } if(ml!=NULL) ml=ml->next; } // найдем корпус корабля if(eo->dev.mysl==NULL) // у него даже корпуса нет, сразу умирает { for(i=0;i<7;i++) dmgsum+=dmg[i][0]; n=snprintf(NULL,0,"<BUSE t=\"%f\" id=\"%x\" obj=\"%x\" trg=\"%f,%f\" res=\"%f\" tid=\"%x\" />",GTIME,mo,o,fx,fy,dmgsum,eo)+1; b=mymalloc(n); snprintf(b,n,"<BUSE t=\"%f\" id=\"%x\" obj=\"%x\" trg=\"%f,%f\" res=\"%f\" tid=\"%x\" />",GTIME,mo,o,fx,fy,dmgsum,eo); cmd_send_buse(bo, b, n); myfree(b); me=get_evt(); evt_bkill_set(me,eo,NULL,NULL,0.0); ins_evt(eo,me); return; // убиваю объект } dmg[7][0]=dmg[7][1]=0; co=eo->dev.mysl->o; if(co->dev.chull>0.0) { for(i=0;i<7;i++) { dmg[i][1]=co->dev.defp[i][0]+(co->dev.defp[i][1]-co->dev.defp[i][0])*rand()/RAND_MAX; if(dmg[i][1]>dmg[i][0]) dmg[i][1]=dmg[i][0]; dmg[i][0]-=dmg[i][1]; dmg[7][0]+=dmg[i][0]; } dmg[7][1]=co->dev.chull; // состояние брони на текущий момент if(dmg[7][0]>dmg[7][1]) { dr=(dmg[7][0]-dmg[7][1])/dmg[7][0]; for(i=0;i<7;i++) dmg[i][0]*=dr; dmg[7][0]=dmg[7][1]; } dmgsum+=dmg[7][0]; co->dev.chull-=dmg[7][0]; if(dmg[7][0]>0.0) { n=snprintf(NULL,0,"<BDMG t=\"%f\" id=\"%x\" obj=\"%x\" dmg=\"%f\" />",GTIME-bo->s.ct,eo,co,dmg[7][0])+1; b=mymalloc(n); snprintf(b,n,"<BDMG t=\"%f\" id=\"%x\" obj=\"%x\" dmg=\"%f\" />",GTIME-bo->s.ct,eo,co,dmg[7][0]); cmd_send_buse(bo, b, n); myfree(b); } } for(i=0;i<7;i++) dmgsum+=dmg[i][0]; n=snprintf(NULL,0,"<BUSE t=\"%f\" id=\"%x\" obj=\"%x\" trg=\"%f,%f\" res=\"%f\" tid=\"%x\" />",GTIME,mo,o,fx,fy,dmgsum,eo)+1; b=mymalloc(n); snprintf(b,n,"<BUSE t=\"%f\" id=\"%x\" obj=\"%x\" trg=\"%f,%f\" res=\"%f\" tid=\"%x\" />",GTIME,mo,o,fx,fy,dmgsum,eo); cmd_send_buse(bo, b, n); myfree(b); // пока считаем что при состоянии корпуса корабля 0 объект умирает if(co->dev.chull<=0.0) { me=get_evt(); evt_bkill_set(me,eo,NULL,NULL,0.0); ins_evt(eo,me); // убиваю объект } }