// respawn character tmp at tmpx,tmpy // if that place is occupied, try again in one second static void respawn_callback(int tmp,int tmpx,int tmpy,int tmpa,int dum) { int cn; cn=create_char_nr(tmp,tmpa); ch[cn].tmpx=tmpx; ch[cn].tmpy=tmpy; if (char_driver(ch[cn].driver,CDT_RESPAWN,cn,0,0)==1 && set_char(cn,tmpx,tmpy,0)) { update_char(cn); ch[cn].hp=ch[cn].value[0][V_HP]*POWERSCALE; ch[cn].endurance=ch[cn].value[0][V_ENDURANCE]*POWERSCALE; ch[cn].mana=ch[cn].value[0][V_MANA]*POWERSCALE; if (ch[cn].lifeshield<0) { elog("respawn_callback(): lifeshield=%d (%X) for char %d (%s). fixed.",ch[cn].lifeshield,ch[cn].lifeshield,cn,ch[cn].name); ch[cn].lifeshield=0; } ch[cn].dir=DX_RIGHTDOWN; register_respawn_respawn(cn); //charlog(cn,"created by respawn"); return; } destroy_char(cn); set_timer(ticker+TICKS*10,respawn_callback,tmp,tmpx,tmpy,tmpa,0); }
void create_worker(int follow_cn, struct saltmine_ppd *ppd) { int cn; struct saltmine_worker_data *workerdat; // create cn=create_char("monk_worker",0); if (!cn) { xlog("create_char() failed in %s %d",__FILE__,__LINE__); return; } snprintf(ch[cn].name,sizeof(ch[cn].name)-1,"%s's Monk",ch[follow_cn].name); ch[cn].name[sizeof(ch[cn].name)-1]=0; ch[cn].dir=DX_DOWN; update_char(cn); ch[cn].hp=ch[cn].value[0][V_HP]*POWERSCALE; ch[cn].endurance=ch[cn].value[0][V_ENDURANCE]*POWERSCALE; ch[cn].mana=ch[cn].value[0][V_MANA]*POWERSCALE; // set initital values if ((workerdat=set_data(cn,DRD_SALTMINE_WORKER,sizeof(struct saltmine_worker_data)))) { workerdat->follow_cn=follow_cn; workerdat->follow_serial=ch[follow_cn].serial; } else { destroy_char(cn); xlog("set_data() failed in %s %d",__FILE__,__LINE__); return; } // drop him to map if (!drop_char(cn,179,19,0) && !drop_char(cn,182,19,0)) { destroy_char(cn); xlog("drop_char() failed (%s,%d)",__FILE__,__LINE__); return; } // set first coords ch[cn].tmpx=ch[follow_cn].x; ch[cn].tmpy=ch[follow_cn].y; }
int improve_prof(int cn,int co,int nr) { int cnt,step; if (!ch[co].prof[nr]) { say(cn,"But thou knowest not the ways of the %s. Thou must learn them first.",prof[nr].name); return 0; } if (ch[co].prof[nr]>=prof[nr].max) { say(cn,"Thou hast reached mastery in the art of the %s already.",prof[nr].name); return 0; } cnt=free_prof_points(co); step=min(prof[nr].step,prof[nr].max-ch[co].prof[nr]); if (!(ch[co].flags&CF_PAID) && ch[co].prof[nr]+step>=20) { say(cn,"Only paying players may raise this profession higher than %d.",ch[co].prof[nr]); return 0; } if (cnt<step) { say(cn,"Thou needst have at least %d unused profession points.",prof[nr].step); return 0; } ch[co].prof[nr]+=step; ch[co].flags|=CF_PROF; update_char(co); say(cn,"Thy profession %s was improved to %d.",prof[nr].name,ch[co].prof[nr]); return 1; }
int learn_prof(int cn,int co,int nr) { int cnt; if (ch[co].prof[nr]) { say(cn,"But thou knowest the ways of the %s already!",prof[nr].name); return 0; } if (!(ch[co].flags&CF_PAID) && count_prof(co)>0) { say(cn,"Only paying players may learn more than one profession."); return 0; } if (nr==P_LIGHT && ch[co].prof[P_DARK]) { say(cn,"Thou hast learned Master of Dark already, thou mayest not learn Master of Light."); return 0; } if (nr==P_DARK && ch[co].prof[P_LIGHT]) { say(cn,"Thou hast learned Master of Light already, thou mayest not learn Master of Dark."); return 0; } cnt=free_prof_points(co); if (cnt<prof[nr].base) { say(cn,"Thou have not the required profession points. Thou needst %d, but thou hast only %d.",prof[nr].base,cnt); return 0; } ch[co].prof[nr]=prof[nr].base; ch[co].flags|=CF_PROF; update_char(co); say(cn,"Thou hast learnt the art of %s.",prof[nr].name); return 1; }
// swap citem with inventory pos int swap(int cn,int pos) { int in,price; if (cn<1 || cn>=MAXCHARS) { error=ERR_ILLEGAL_CHARNO; return 0; } if (ch[cn].flags&(CF_DEAD)) { error=ERR_DEAD; return 0; } // no switching equipment while in teufel PK arena if (areaID==34 && (map[ch[cn].x+ch[cn].y*MAXMAP].flags&MF_ARENA) && pos!=WN_LHAND && pos<12) { error=ERR_ILLEGAL_ATTACK; return 0; } if ((in=ch[cn].citem)) { if (pos<0) { // <0, illegal error=ERR_ILLEGAL_INVPOS; return 0; } else if (pos<12) { // wear position if (!can_wear(cn,in,pos)) { error=ERR_REQUIREMENTS; return 0; } } else if (pos<30) { // spell position error=ERR_ILLEGAL_INVPOS; return 0; } else if (pos<INVENTORYSIZE) { // backpack ; } else { // >=INVENTORYSIZE, illegal error=ERR_ILLEGAL_INVPOS; return 0; } } else { if (pos<0 || (pos>=12 && pos<30) || pos>=INVENTORYSIZE) { error=ERR_ILLEGAL_INVPOS; return 0; } } // swap items ch[cn].citem=ch[cn].item[pos]; if (it[in].flags&IF_MONEY) { if (ch[cn].flags&CF_PLAYER) dlog(cn,in,"dropped into goldbag"); price=destroy_money_item(in); ch[cn].gold+=price; stats_update(cn,0,price); ch[cn].item[pos]=0; } else ch[cn].item[pos]=in; ch[cn].flags|=CF_ITEMS; if (pos<12) update_char(cn); return 1; }
void keyholder_door(int in,int cn) { int x,y,n,in2,flag,co,nr; char buf[80]; if (!cn) return; nr=it[in].drdata[0]; for (n=0; n<9; n++) { flag=0; for (x=2+(n%3)*8; x<9+(n%3)*8; x++) { for (y=231+(n/3)*8; y<238+(n/3)*8; y++) { if ((in2=map[x+y*MAXMAP].it) && (it[in2].flags&IF_TAKE)) { flag=1; break; } if (map[x+y*MAXMAP].ch) { flag=1; break; } } } if (!flag) break; } if (flag) { log_char(cn,LOG_SYSTEM,0,"You hear fighting noises from behind the door. It won't open while the fight lasts."); return; } if (!(in2=ch[cn].citem) || it[in2].driver!=IDR_ENHANCE || it[in2].drdata[0]!=2 || *(unsigned int*)(it[in2].drdata+1)!=2000) { log_char(cn,LOG_SYSTEM,0,"You'll need to use 2000 gold units as a key to open the door."); return; } if (!teleport_char_driver(cn,2+(n%3)*8+1,231+(n/3)*8+3)) { log_char(cn,LOG_SYSTEM,0,"You hear fighting noises from behind the door. It won't open while the fight lasts."); return; } destroy_item(in2); ch[cn].citem=0; ch[cn].flags|=CF_ITEMS; sprintf(buf,"keyholder_golem%d",nr); co=create_char(buf,0); if (co) { update_char(co); ch[co].hp=ch[co].value[0][V_HP]*POWERSCALE; ch[co].endurance=ch[co].value[0][V_ENDURANCE]*POWERSCALE; ch[co].mana=ch[co].value[0][V_MANA]*POWERSCALE; ch[co].dir=DX_LEFTUP; ch[co].tmpx=2+(n%3)*8+5; ch[co].tmpy=231+(n/3)*8+3; drop_char(co,2+(n%3)*8+5,231+(n/3)*8+3,1); } }
void warmfire(int in,int cn) { int in2,fn,n; if (!cn) return; if (ch[cn].citem) { log_char(cn,LOG_SYSTEM,0,"Please empty your 'hand' (mouse cursor) first."); return; } if (!it[in].drdata[0]) { in2=create_item("ice_scroll"); if (in2) { if (ch[cn].flags&CF_PLAYER) dlog(cn,in2,"took from warmfire"); ch[cn].citem=in2; it[in2].carried=cn; ch[cn].flags|=CF_ITEMS; it[in2].drdata[0]=ch[cn].x; it[in2].drdata[1]=ch[cn].y; log_char(cn,LOG_SYSTEM,0,"Next to the fire, you find an ancient scroll. It seems to be a scroll of teleport which will take you back here."); } } for (n=12; n<30; n++) { if ((in2=ch[cn].item[n]) && it[in2].driver==IDR_CURSE) { destroy_item(in2); ch[cn].item[n]=0; break; } } if (n==30) { log_char(cn,LOG_SYSTEM,0,"You warm your hands on the fire."); return; } for (n=0; n<4; n++) { if ((fn=ch[cn].ef[n]) && ef[fn].type==EF_CURSE) { remove_effect_char(fn); free_effect(fn); } } update_char(cn); log_char(cn,LOG_SYSTEM,0,"You move close to the heat of the fire, and you feel the demon's cold leave you."); }
// remove item from char. checks for errors and does light. // will also update the character values if needed. int remove_item_char(int in) { int cn,n; if (in<1 || in>=MAXITEM) { elog("remove_item_char(): illegal item number %d",in); return 0; } if (!(cn=it[in].carried)) { elog("remove_item_char(): item %s (%d) is not carried",it[in].name,in); btrace("remove_item_char"); return 0; } if (cn<1 || cn>=MAXCHARS) { elog("remove_item_char(): Item %s (%d) thinks it is carried by character %d, but that number is out of bounds.",it[in].name,in,cn); it[in].carried=0; return 1; // we return success anyway. we did remove it, sort of... } if (ch[cn].citem==in) { ch[cn].citem=0; ch[cn].flags|=CF_ITEMS; it[in].carried=0; return 1; } else { for (n=0; n<INVENTORYSIZE; n++) if (ch[cn].item[n]==in) break; if (n==INVENTORYSIZE) { elog("remove_item(): Item %s (%d) thinks it is carried by character %s (%d), but it is not.",it[in].name,in,ch[cn].name,cn); // we're going to return success anyway: the character does NOT carry the item anymore } else ch[cn].item[n]=0; ch[cn].flags|=CF_ITEMS; it[in].carried=0; if (n<30) update_char(cn); // worn item or spell return 1; } }
// raise value v of cn by 1 and give exp for it, does error checking int raise_value_exp(int cn,int v) { int cost,seyan; int hardcore=0; if (v<0 || v>V_MAX) return 0; if (!skill[v].cost) return 0; if (!ch[cn].value[1][v]) return 0; if (!(ch[cn].flags&CF_ARCH) && ch[cn].value[1][v]>49) return 0; if ((ch[cn].flags&(CF_WARRIOR|CF_MAGE))==(CF_WARRIOR|CF_MAGE)) seyan=1; else seyan=0; if (ch[cn].flags&CF_HARDCORE) hardcore=7; /*{ if (seyan) hardcore=5; else hardcore=7; }*/ if (seyan && ch[cn].value[1][v]>99+hardcore) return 0; if (ch[cn].value[1][v]>114+hardcore) return 0; if (v==V_PROFESSION && ch[cn].value[1][v]>99) return 0; cost=raise_cost(v,ch[cn].value[1][v],seyan); ch[cn].exp_used+=cost; ch[cn].exp+=cost; check_levelup(cn); ch[cn].value[1][v]++; update_char(cn); dlog(cn,0,"raised %s to %d",skill[v].name,ch[cn].value[1][v]); return 1; }
void ritual_create_char(char *name, int x, int y, int dir, int attackstart) { int cn; struct lab5_daemon_data *dat; // create cn=create_char(name,0); if (!cn) return; ch[cn].dir=dir; ch[cn].flags&=~CF_RESPAWN; update_char(cn); ch[cn].hp=ch[cn].value[0][V_HP]*POWERSCALE; ch[cn].endurance=ch[cn].value[0][V_ENDURANCE]*POWERSCALE; ch[cn].mana=ch[cn].value[0][V_MANA]*POWERSCALE; // drop him to map if (!drop_char(cn,x,y,0)) { destroy_char(cn); /*destroy_items(cn); free_char(cn);*/ xlog("drop_char failed (%s,%d)",__FILE__,__LINE__); return; } // set values of the secure move driver ch[cn].tmpx=ch[cn].x; ch[cn].tmpy=ch[cn].y; // set direction of deamon driver dat=set_data(cn,DRD_LAB5_DAEMON,sizeof(struct lab5_daemon_data)); if (dat) { dat->dir=dir; dat->attackstart=attackstart*TICKS; } }
// lower value v of cn by 1, does error checking int lower_value(int cn,int v) { int cost,seyan; if (v<0 || v>V_MAX) return 0; if (!skill[v].cost) return 0; if (ch[cn].value[1][v]<=skill[v].start) return 0; if ((ch[cn].flags&(CF_WARRIOR|CF_MAGE))==(CF_WARRIOR|CF_MAGE)) seyan=1; else seyan=0; ch[cn].value[1][v]--; cost=raise_cost(v,ch[cn].value[1][v],seyan); ch[cn].exp_used-=cost; update_char(cn); dlog(cn,0,"lowered %s to %d",skill[v].name,ch[cn].value[1][v]); return 1; }
void edit( int ch ) { struct viewporttype tmp; char key, *buff; take_char( ( char ) ch ); backup_char( ); getviewsettings( &tmp ); setviewport( 400, 30, getmaxx( ), getmaxy( ), 1 ); buff = ( char* ) malloc( imagesize( 0 + align, 0, X*( 2 + WIDTH_X ) + align, Y*( 2 + WIDTH_Y ) ) ); getimage( 0 + align, 0, X*( 2 + WIDTH_X ) + align, Y*( 2 + WIDTH_Y ), buff ); draw_char( ); start_clock( EDIT_FONT ); while ( ( key = get_pos( &pos_x, &pos_y, X - 1, Y - 1, 1, 1 ) ) != 3 ) { switch ( tolower( key ) ) { case 1: xor_dot( pos_x, pos_y ); continue; case '8': pan_up( ); draw_char( ); break; case '2': pan_down( ); draw_char( ); break; case '4': pan_left( ); draw_char( ); break; case '6': pan_right( ); draw_char( ); break; case 'r': insert_row( pos_y ); draw_char( ); break; case 'c': insert_col( pos_x ); draw_char( ); break; case 'e': del_row( pos_y ); draw_char( ); break; case 'd': del_col( pos_x ); draw_char( ); break; case 'i': invert( ); draw_char( ); break; case 'm': mirror( ); draw_char( ); break; case '.': ++draw_mode; switch ( draw_mode ) { case 0: break; case 1: put_dot( pos_x, pos_y ); edit_font[pos_x][pos_y] = ~0; break; case 2: square( pos_x, pos_y ); edit_font[pos_x][pos_y] = 0; break; case 3: draw_mode = 0; } continue; case 'u': undo( ); draw_char( ); goto exit; case '?': help( ); break; default: if ( draw_mode == 1 ) { put_dot( pos_x, pos_y ); edit_font[pos_x][pos_y] = ~0; } if ( draw_mode == 2 ) { square( pos_x, pos_y ); edit_font[pos_x][pos_y] = 0; } } } update_char( ( char ) ch ); exit: putimage( 0 + align, 0, buff, COPY_PUT ); free( buff ); stop_clock( ); dispblank( 50, 16, strlen( "Move mode" ), 0 ); setviewport( tmp.left, tmp.top, tmp.right, tmp.bottom, tmp.clip ); print_table( which_page( ch ) ); }
void edemongate_driver(int in,int cn) { int n,co,ser,nr; char name[80]; if (cn) return; nr=it[in].drdata[0]; if (nr==0) { static int pos[14]={ 62,157, 62,164, 62,174, 62,184, 62,191, 56,174, 67,174}; for (n=0; n<7; n++) { co=*(unsigned short*)(it[in].drdata+4+n*4); ser=*(unsigned short*)(it[in].drdata+6+n*4); if (!co || !ch[co].flags || (unsigned short)ch[co].serial!=(unsigned short)ser) { sprintf(name,"edemon2s"); co=create_char(name,0); if (!co) break; if (item_drop_char(in,co)) { ch[co].tmpx=pos[n*2]; ch[co].tmpy=pos[n*2+1]; update_char(co); ch[co].hp=ch[co].value[0][V_HP]*POWERSCALE; ch[co].endurance=ch[co].value[0][V_ENDURANCE]*POWERSCALE; ch[co].mana=ch[co].value[0][V_MANA]*POWERSCALE; ch[co].dir=DX_RIGHTDOWN; *(unsigned short*)(it[in].drdata+4+n*4)=co; *(unsigned short*)(it[in].drdata+6+n*4)=ch[co].serial; break; // only one spawn per call } else { destroy_char(co); break; } } } call_item(it[in].driver,in,0,ticker+TICKS*10); } else if (nr==1) { static int pos[100]={0},co_nr[100],serial[100],maxpos=0; if (!maxpos) { for (n=1; n<MAXITEM; n++) { if (!it[n].flags) continue; if (it[n].driver!=IDR_EDEMONLIGHT) continue; if (it[n].drdata[0]!=4) continue; pos[maxpos++]=it[n].x+it[n].y*MAXMAP; } } for (n=0; n<maxpos; n++) { if (!(co=co_nr[n]) || !ch[co].flags || ch[co].serial!=serial[n]) { co=create_char("edemon6s",0); if (!co) break; if (item_drop_char(in,co)) { ch[co].tmpx=pos[n]%MAXMAP; ch[co].tmpy=pos[n]/MAXMAP; update_char(co); ch[co].hp=ch[co].value[0][V_HP]*POWERSCALE; ch[co].endurance=ch[co].value[0][V_ENDURANCE]*POWERSCALE; ch[co].mana=ch[co].value[0][V_MANA]*POWERSCALE; ch[co].dir=DX_RIGHTDOWN; co_nr[n]=co; serial[n]=ch[co].serial; break; // only one spawn per call } else { destroy_char(co); break; } } } call_item(it[in].driver,in,0,ticker+TICKS*20); } }
void minewall(int in,int cn) { int in2,amount,co; char buf[80]; if (!cn) { if (!it[in].drdata[4]) { it[in].drdata[4]=1; switch((it[in].x+it[in].y)%3) { case 0: it[in].sprite=15070; break; case 1: it[in].sprite=15078; break; case 2: it[in].sprite=15086; break; } } if (it[in].drdata[3]==8) { if ((map[it[in].x+it[in].y*MAXMAP].flags&MF_TMOVEBLOCK) || map[it[in].x+it[in].y*MAXMAP].it) { call_item(it[in].driver,in,0,ticker+TICKS); return; } it[in].sprite-=8; it[in].drdata[3]=0; it[in].flags|=IF_USE; it[in].flags&=~IF_VOID; remove_lights(it[in].x,it[in].y); map[it[in].x+it[in].y*MAXMAP].it=in; map[it[in].x+it[in].y*MAXMAP].flags|=MF_TSIGHTBLOCK|MF_TMOVEBLOCK; it[in].flags|=IF_SIGHTBLOCK; reset_los(it[in].x,it[in].y); add_lights(it[in].x,it[in].y); set_sector(it[in].x,it[in].y); } return; } if (ch[cn].citem) { log_char(cn,LOG_SYSTEM,0,"Please empty your hand (mouse cursor) first."); player_driver_dig_off(cn); return; } if (it[in].drdata[3]<9) { if (ch[cn].endurance<POWERSCALE) { log_char(cn,LOG_SYSTEM,0,"You're too exhausted to continue digging."); player_driver_dig_off(cn); return; } ch[cn].endurance-=POWERSCALE/4-(ch[cn].prof[P_MINER]*POWERSCALE/(4*25)); it[in].drdata[3]++; it[in].drdata[5]=0; it[in].sprite++; if (it[in].drdata[3]==8) { map[it[in].x+it[in].y*MAXMAP].it=0; map[it[in].x+it[in].y*MAXMAP].flags&=~MF_TMOVEBLOCK; it[in].flags&=~IF_USE; it[in].flags|=IF_VOID; call_item(it[in].driver,in,0,ticker+TICKS*60*5+RANDOM(TICKS*60*25)); if (!RANDOM(15)) { in2=create_item("silver"); if (!in2) elog("silver not found"); amount=RANDOM(it[in].drdata[0]*2+1)+it[in].drdata[0]; //xlog("amount=%d",amount); if (ch[cn].prof[P_MINER]) amount+=amount*ch[cn].prof[P_MINER]/10; //xlog("amount=%d",amount); if (!amount && in2) { destroy_item(in2); } } else if (!RANDOM(50)) { in2=create_item("gold"); if (!in2) elog("gold not found"); amount=RANDOM(it[in].drdata[1]*2+1)+it[in].drdata[1]; if (ch[cn].prof[P_MINER]) amount+=amount*ch[cn].prof[P_MINER]/10; if (!amount && in2) { destroy_item(in2); } } else amount=in2=0; if (amount && in2) { it[in2].value*=amount; *(unsigned int*)(it[in2].drdata+1)=amount; sprintf(it[in2].description,"%d units of %s.",*(unsigned int*)(it[in2].drdata+1),it[in2].name); if (ch[cn].flags&CF_PLAYER) dlog(cn,in2,"took from minewall"); ch[cn].citem=in2; it[in2].carried=cn; ch[cn].flags|=CF_ITEMS; log_char(cn,LOG_SYSTEM,0,"You found %d units of %s.",amount,it[in2].name); if (it[in2].drdata[0]==1) check_military_silver(cn,amount); } if (!RANDOM(10)) { sprintf(buf,"miner%d",it[in].drdata[2]); co=create_char(buf,0); if (!co) elog("%s not found",buf); if (co) { if (drop_char(co,it[in].x,it[in].y,0)) { ch[co].tmpx=ch[co].x; ch[co].tmpy=ch[co].y; update_char(co); ch[co].hp=ch[co].value[0][V_HP]*POWERSCALE; ch[co].endurance=ch[co].value[0][V_ENDURANCE]*POWERSCALE; ch[co].mana=ch[co].value[0][V_MANA]*POWERSCALE; ch[co].dir=DX_RIGHTDOWN; } else { destroy_char(co); } } } } set_sector(it[in].x,it[in].y); if (it[in].drdata[3]==3) { remove_lights(it[in].x,it[in].y); map[it[in].x+it[in].y*MAXMAP].flags&=~MF_TSIGHTBLOCK; it[in].flags&=~IF_SIGHTBLOCK; reset_los(it[in].x,it[in].y); add_lights(it[in].x,it[in].y); } } if (it[in].drdata[3]<8) player_driver_dig_on(cn); else player_driver_dig_off(cn); }
void warpfighter(int cn,int ret,int lastact) { struct warpfighter_data *dat; struct msg *msg,*next; int co,in,fre; dat=set_data(cn,DRD_WARPFIGHTER,sizeof(struct warpfighter_data)); if (!dat) return; // oops... // loop through our messages for (msg=ch[cn].msg; msg; msg=next) { next=msg->next; switch(msg->type) { case NT_CREATE: fight_driver_set_dist(cn,40,0,40); dat->creation_time=ticker; break; case NT_TEXT: co=msg->dat3; tabunga(cn,co,(char*)msg->dat2); break; } standard_message_driver(cn,msg,1,0); remove_message(cn,msg); } // do something. whenever possible, call do_idle with as high a tick count // as reasonable when doing nothing. co=dat->co; if (!ch[co].flags || ch[co].serial!=dat->cser || ch[co].x<dat->xs || ch[co].y<dat->ys || ch[co].x>dat->xe || ch[co].y>dat->ye) { remove_char(cn); destroy_char(cn); //xlog("self-destruct %d %d %d %d %d %d (%d)",!ch[co].flags,ch[co].serial!=dat->cser,ch[co].x<dat->xs,ch[co].y<dat->ys,ch[co].x>dat->xe,ch[co].y>dat->ye,dat->co); return; } if (dat->pot_done<1 && ticker>dat->creation_time+TICKS*2) { dat->pot_done++; if (ch[cn].level>60 && !RANDOM(6)) { if (RANDOM(2)) { emote(cn,"drinks a potion of freeze"); ch[cn].value[1][V_FREEZE]=ch[cn].value[1][V_ATTACK]+ch[cn].value[1][V_ATTACK]/4; ch[cn].value[1][V_MANA]=10; update_char(cn); ch[cn].mana=POWERSCALE*10; } else { if ((fre=may_add_spell(cn,IDR_FREEZE)) && (in=create_item("freeze_spell"))) { emote(cn,"drinks a spoiled potion of freeze"); it[in].mod_value[0]=-ch[cn].value[0][V_SPEED]-100; it[in].driver=IDR_FREEZE; it[in].carried=cn; ch[cn].item[fre]=in; *(signed long*)(it[in].drdata)=ticker+TICKS*60; *(signed long*)(it[in].drdata+4)=ticker; create_spell_timer(cn,in,fre); update_char(cn); } } } } if (ch[cn].lifeshield<POWERSCALE*5 && ch[cn].endurance<ch[cn].value[0][V_WARCRY]*POWERSCALE/3 && dat->pot_done<3) { dat->pot_done++; if (ch[cn].level>50 && !RANDOM(4)) { emote(cn,"drinks an endurance potion"); ch[cn].endurance=min(ch[cn].value[0][V_ENDURANCE]*POWERSCALE,ch[cn].endurance+32*POWERSCALE); } } if (ch[cn].hp<ch[cn].value[0][V_ENDURANCE]*POWERSCALE/2 && dat->pot_done<5) { dat->pot_done++; if (ch[cn].level>40 && !RANDOM(4)) { emote(cn,"drinks a healing potion"); ch[cn].hp=min(ch[cn].value[0][V_HP]*POWERSCALE,ch[cn].hp+32*POWERSCALE); } } fight_driver_update(cn); if (fight_driver_attack_visible(cn,0)) return; if (fight_driver_follow_invisible(cn)) return; if (regenerate_driver(cn)) return; if (spell_self_driver(cn)) return; if (secure_move_driver(cn,ch[cn].tmpx,ch[cn].tmpy,DX_DOWN,ret,lastact)) return; do_idle(cn,TICKS); }
int warptrialdoor_driver(int in,int cn) { int xs,ys,xe,ye,x,y,m,in2,dx,dy,dir,co; struct warpfighter_data *dat; struct warped_ppd *ppd; ppd=set_data(cn,DRD_WARP_PPD,sizeof(struct warped_ppd)); if (!ppd) return 2; // oops... if (!ppd->base) ppd->base=40; if (!it[in].drdata[2]) { xs=xe=ys=ye=in2=0; for (x=it[in].x+1,y=it[in].y; x<it[in].x+15; x++) { if (map[x+y*MAXMAP].it && it[map[x+y*MAXMAP].it].driver==IDR_WARPTRIALDOOR) { in2=map[x+y*MAXMAP].it; xs=it[in].x; xe=it[in2].x; for (x=it[in].x+1,y=it[in].y; y<it[in].y+15; y++) { if (map[x+y*MAXMAP].flags&MF_MOVEBLOCK) { ye=y; break; } } for (x=it[in].x+1,y=it[in].y; y>it[in].y-15; y--) { if (map[x+y*MAXMAP].flags&MF_MOVEBLOCK) { ys=y; break; } } break; } if (map[x+y*MAXMAP].flags&(MF_MOVEBLOCK|MF_TMOVEBLOCK)) break; } if (!in2) { for (x=it[in].x-1,y=it[in].y; x>it[in].x-15; x--) { if (map[x+y*MAXMAP].it && it[map[x+y*MAXMAP].it].driver==IDR_WARPTRIALDOOR) { in2=map[x+y*MAXMAP].it; xe=it[in].x; xs=it[in2].x; for (x=it[in].x-1,y=it[in].y; y<it[in].y+15; y++) { if (map[x+y*MAXMAP].flags&MF_MOVEBLOCK) { ye=y; break; } } for (x=it[in].x-1,y=it[in].y; y>it[in].y-15; y--) { if (map[x+y*MAXMAP].flags&MF_MOVEBLOCK) { ys=y; break; } } break; } if (map[x+y*MAXMAP].flags&(MF_MOVEBLOCK|MF_TMOVEBLOCK)) break; } } if (!in2) { for (x=it[in].x,y=it[in].y+1; y<it[in].y+15; y++) { if (map[x+y*MAXMAP].it && it[map[x+y*MAXMAP].it].driver==IDR_WARPTRIALDOOR) { in2=map[x+y*MAXMAP].it; ys=it[in].y; ye=it[in2].y; for (x=it[in].x,y=it[in].y+1; x<it[in].x+15; x++) { if (map[x+y*MAXMAP].flags&MF_MOVEBLOCK) { xe=x; break; } } for (x=it[in].x,y=it[in].y+1; x>it[in].x-15; x--) { if (map[x+y*MAXMAP].flags&MF_MOVEBLOCK) { xs=x; break; } } break; } if (map[x+y*MAXMAP].flags&(MF_MOVEBLOCK|MF_TMOVEBLOCK)) break; } } if (!in2) { for (x=it[in].x,y=it[in].y-1; y>it[in].y-15; y--) { if (map[x+y*MAXMAP].it && it[map[x+y*MAXMAP].it].driver==IDR_WARPTRIALDOOR) { in2=map[x+y*MAXMAP].it; ye=it[in].y; ys=it[in2].y; for (x=it[in].x,y=it[in].y-1; x<it[in].x+15; x++) { if (map[x+y*MAXMAP].flags&MF_MOVEBLOCK) { xe=x; break; } } for (x=it[in].x,y=it[in].y-1; x>it[in].x-15; x--) { if (map[x+y*MAXMAP].flags&MF_MOVEBLOCK) { xs=x; break; } } break; } if (map[x+y*MAXMAP].flags&(MF_MOVEBLOCK|MF_TMOVEBLOCK)) break; } } //xlog("xs=%d, ys=%d, xe=%d, ye=%d, in=%d, in2=%d",xs,ys,xe,ye,in,in2); it[in].drdata[2]=xs; it[in].drdata[3]=ys; it[in].drdata[4]=xe; it[in].drdata[5]=ye; *(unsigned short*)(it[in].drdata+6)=in2; } if (!cn) return 2; xs=it[in].drdata[2]; ys=it[in].drdata[3]; xe=it[in].drdata[4]; ye=it[in].drdata[5]; in2=*(unsigned short*)(it[in].drdata+6); if (ch[cn].x>=xs && ch[cn].x<=xe && ch[cn].y>=ys && ch[cn].y<=ye) { log_char(cn,LOG_SYSTEM,0,"You cannot open the door from this side."); return 2; } for (y=ys+1; y<ye; y++) { for (x=xs+1,m=x+y*MAXMAP; x<xe; x++,m++) { if ((co=map[m].ch) && ch[co].driver!=CDR_SIMPLEBADDY) { log_char(cn,LOG_SYSTEM,0,"You hear fighting noises and the door won't open."); return 2; } } } co=create_char("warped_fighter",0); if (!co) { log_char(cn,LOG_SYSTEM,0,"Bug #319i, sorry."); return 2; } if (!drop_char(co,(xs+xe)/2,(ys+ye)/2,0)) { log_char(cn,LOG_SYSTEM,0,"Bug #319j, sorry."); destroy_char(co); return 2; } ch[co].tmpx=ch[co].x; ch[co].tmpy=ch[co].y; warped_raise(co,ppd->base); update_char(co); ch[co].hp=ch[co].value[0][V_HP]*POWERSCALE; ch[co].endurance=ch[co].value[0][V_ENDURANCE]*POWERSCALE; ch[co].mana=ch[co].value[0][V_MANA]*POWERSCALE; ch[co].lifeshield=ch[co].value[0][V_MAGICSHIELD]*POWERSCALE; ch[co].dir=DX_RIGHTDOWN; dat=set_data(co,DRD_WARPFIGHTER,sizeof(struct warpfighter_data)); if (!dat) { log_char(cn,LOG_SYSTEM,0,"Bug #319k, sorry."); remove_char(co); destroy_char(co); return 2; } dir=offset2dx(it[in].x,it[in].y,it[in2].x,it[in2].y); if (!dir) { log_char(cn,LOG_SYSTEM,0,"Bug #319l, sorry."); remove_char(co); destroy_char(co); return 2; } dx2offset(dir,&dx,&dy,NULL); dat->co=cn; dat->cser=ch[cn].serial; dat->tx=it[in2].x+dx; dat->ty=it[in2].y+dy; dat->xs=xs; dat->xe=xe; dat->ys=ys; dat->ye=ye; teleport_char_driver(cn,it[in].x+dx,it[in].y+dy); return 1; }