void lab4_gnalb_driver_init(int cn, struct lab4_gnalb_driver_data *dat) { int p; if (dat->type==1) { int dist,mindist=10000; for (p=1; p<max_gnalb_path; p++) { if ((dist=map_dist(ch[cn].x,ch[cn].y,gnalb_path[p].x,gnalb_path[p].y))<mindist) { mindist=dist; dat->path=p; } } } if (dat->type==1) { // guard dat->aggressive=1; dat->helper=1; fight_driver_set_dist(cn,0,10,20); } else if (dat->type==2) { xlog("CANTBETRUE in %s %d",__FILE__,__LINE__); } else { // crazy dat->aggressive=0; dat->helper=0; fight_driver_set_dist(cn,0,10,0); } }
void keyhold_fight_driver(int cn,int ret,int lastact) { struct gate_fight_driver_data *dat; struct msg *msg,*next; dat=set_data(cn,DRD_GATE_FIGHT,sizeof(struct gate_fight_driver_data)); if (!dat) return; // oops... // loop through our messages for (msg=ch[cn].msg; msg; msg=next) { next=msg->next; if (msg->type==NT_CREATE) { dat->creation_time=ticker; fight_driver_set_dist(cn,10,0,20); } 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. // self destruct eventually if (ticker-dat->creation_time>TICKS*60*5) { say(cn,"Thats all folks!"); remove_destroy_char(cn); return; } fight_driver_update(cn); if (fight_driver_attack_visible(cn,0)) return; if (fight_driver_follow_invisible(cn)) return; if (secure_move_driver(cn,ch[cn].tmpx,ch[cn].tmpy,DX_DOWN,ret,lastact)) return; if (regenerate_driver(cn)) return; if (spell_self_driver(cn)) return; do_idle(cn,TICKS); }
void monk_gatama_driver(int cn, int ret, int lastact) { static struct talk_data talkbuf; // we only have one, so there is no need to use the memory system (?) struct talk_data *talkdat=&talkbuf; struct saltmine_ppd *ppd; struct msg *msg,*next; int co; int talkdir=0,didsay=0,noturn=0; char *str; // loop through our messages for (msg=ch[cn].msg; msg; msg=next) { next=msg->next; if (msg->type==NT_CREATE) { fight_driver_set_dist(cn,20,0,30); } if (msg->type==NT_GIVE) { if (!ch[cn].citem) { remove_message(cn,msg); continue; } // ??? i saw something like this at DBs source co=msg->dat1; // destroy everything we get destroy_item(ch[cn].citem); ch[cn].citem=0; } if (msg->type==NT_CHAR) { co=msg->dat1; // dont talk if (!(ch[co].flags&CF_PLAYER)) { remove_message(cn,msg); continue; } // dont talk to other NPCs if (ch[co].driver==CDR_LOSTCON) { remove_message(cn,msg); continue; } // dont talk to players without connection if (ticker<talkdat->lasttalk+5*TICKS) { remove_message(cn,msg); continue; } // only talk when the old sentence is read if (!char_see_char(cn,co) || cn==co) { remove_message(cn,msg); continue; } // dont talk to someone we cant see, and dont talk to ourself // get ppd if (!(ppd=get_saltmine_ppd(co))) { remove_message(cn,msg); continue; } if (char_dist(cn,co)>7) { ppd->gatamastate=0; remove_message(cn,msg); continue; } // dont talk to someone far away // remove cv if (talkdat->cv_co) { if (!ch[talkdat->cv_co].flags || ch[talkdat->cv_co].serial!=talkdat->cv_serial || char_dist(cn,talkdat->cv_co)>7 || !char_see_char(cn,talkdat->cv_co)) { talkdat->cv_co=0; } } // only talk to cv if (talkdat->cv_co && talkdat->cv_co!=co) { remove_message(cn,msg); continue; } // set new cv if (!talkdat->cv_co) { talkdat->cv_co=co; talkdat->cv_serial=ch[co].serial; } switch(ppd->gatamastate) { case 0: if (ppd->salt) ppd->gatamastate=50; else ppd->gatamastate=10; break; // Intro case 10: say(cn,"Welcome %s. The Monastery of Kir Laka needs thine help. We live from the salt we get from the saltmine thou can find to the west. But now many golems appeared in the mine and we had to run for our lives, and all the salt we had already mined is lost there.",ch[co].name); didsay=1; ppd->gatamastate++; break; case 11: say(cn,"Thou might want to know more °c4details°c0 of what thee can do for the monastery. After this, thou might °c4begin°c0 helping us, or not."); didsay=1; ppd->gatamastate++; break; case 12: talkdat->cv_co=0; break; // Details case 20: say(cn,"Thou will have to lead group of monks safely to certain ladders in the saltmine. Once reached, thou \"use\" the ladder, and one of the monks will get the salt out of that place. Every ladder can be used only once every 12 astonian days, and every monk can only carry one bag of salt."); didsay=1; ppd->gatamastate++; break; case 21: say(cn,"The monks will follow thee, and help thee against the golems. Once left, thou canst return to the monastery any time you like, the monks will then deposit their salt, if they have any, and will rest then. Thou can give some commands to the monks by simply speaking to them. Those commands are:"); say(cn,"wait - and they will wait a short while."); say(cn,"come - and they will come to thee."); say(cn,"salt - and they will show thee if they carry salt, or not."); didsay=1; ppd->gatamastate++; break; case 22: say(cn,"Hopefully thou now decide to °c4begin°c0 helping us."); didsay=1; ppd->gatamastate++; break; case 23: talkdat->cv_co=0; break; // Begin (check) case 30: if (monksout(co,ppd)) ppd->gatamastate=40; else ppd->gatamastate++; break; case 31: say(cn,"Come here, Monks. The mighty %s offers %s help. I want to see and hear quick feet now!",ch[co].name,hisname(co)); didsay=1; ppd->gatamastate++; create_worker(co,ppd); create_worker(co,ppd); create_worker(co,ppd); break; case 32: say(cn,"Lead them wise and carfully, %s. Mayest thou all return safe.",ch[co].name); didsay=1; ppd->gatamastate++; case 33: talkdat->cv_co=0; break; // ... case 40: say(cn,"Let us wait until all thine Monks are resting. Either in the rest room, or in peace."); didsay=1; ppd->gatamastate++; case 41: talkdat->cv_co=0; break; // Reward case 50: say(cn,"Thanks thee %s for thine help. Thou canst use the saltbag in the store room, to take thee thine reward. I trust thee, that thou wilt take the right amount.",ch[co].name); ppd->gatamastate++; case 51: talkdat->cv_co=0; break; } if (didsay) { talkdat->lasttalk=ticker; talkdir=offset2dx(ch[cn].x,ch[cn].y,ch[co].x,ch[co].y); } } if (msg->type==NT_TEXT) { co=msg->dat3; str=(char *)msg->dat2; tabunga(cn,co,(char*)msg->dat2); if (co==cn) { remove_message(cn,msg); continue; } if (!(ch[co].flags&CF_PLAYER)) { remove_message(cn,msg); continue; } if (!char_see_char(cn,co)) { remove_message(cn,msg); continue; } if (char_dist(cn,co)>7) { remove_message(cn,msg); continue; } // get ppd if (!(ppd=get_saltmine_ppd(co))) { remove_message(cn,msg); continue; } if (strcasestr(str,"REPEAT")) { say(cn,"I will repeat, %s",ch[co].name); ppd->gatamastate=0; } else if (strcasestr(str,"DETAILS")) { ppd->gatamastate=20; } else if (strcasestr(str,"BEGIN")) { ppd->gatamastate=30; } } standard_message_driver(cn,msg,1,1); remove_message(cn,msg); } if (talkdir) turn(cn,talkdir); // fighting fight_driver_update(cn); if (fight_driver_attack_visible(cn,0)) return; if (regenerate_driver(cn)) return; if (spell_self_driver(cn)) return; if (talkdat->lasttalk+TICKS*30<ticker || noturn) { if (secure_move_driver(cn,ch[cn].tmpx,ch[cn].tmpy,DX_LEFT,ret,lastact)) return; if (!noturn && (ticker/TICKS)%5==0) whisper(cn,"Auaaauuuuuuummmmmmmmmmm"); } do_idle(cn,TICKS); }
void monk_worker_driver(int cn, int ret, int lastact) { struct saltmine_worker_data *workerdat; struct saltmine_ppd *ppd; struct msg *msg,*next; int co,dir; char *str; // get data if (!(workerdat=set_data(cn,DRD_SALTMINE_WORKER,sizeof(struct saltmine_worker_data)))) return; if (!(ppd=get_saltmine_ppd(workerdat->follow_cn))) return; // kill monk if ((!ch[workerdat->follow_cn].flags) || (ch[workerdat->follow_cn].serial!=workerdat->follow_serial)) { remove_destroy_char(cn); return; } if (char_dist(cn,workerdat->follow_cn)>90) { log_char(workerdat->follow_cn,LOG_SYSTEM,0,"°c3One of thine monks vanished!°c0"); remove_destroy_char(cn); return; } // loop through our messages for (msg=ch[cn].msg; msg; msg=next) { next=msg->next; if (msg->type==NT_CREATE) { fight_driver_set_dist(cn,0,20,0); } if (msg->type==NT_GIVE) { if (!ch[cn].citem) { remove_message(cn,msg); continue; } // ??? i saw something like this at DBs source co=msg->dat1; // destroy everything we get destroy_item(ch[cn].citem); ch[cn].citem=0; } if (msg->type==NT_TEXT) { co=msg->dat3; str=(char *)msg->dat2; tabunga(cn,co,(char*)msg->dat2); if (co==cn) { remove_message(cn,msg); continue; } if (!(ch[co].flags&CF_PLAYER)) { remove_message(cn,msg); continue; } // if (!char_see_char(cn,co)) { remove_message(cn,msg); continue; } if (co==workerdat->follow_cn) { if (strcasestr(str,"COME")) { workerdat->waituntil=0; } else if (strcasestr(str,"WAIT")) { workerdat->waituntil=ticker+20*TICKS; } else if (strcasestr(str,"SALT")) { log_area(ch[cn].x,ch[cn].y,LOG_SYSTEM,0,10,"%s %s his head.",ch[cn].name,workerdat->hassalt?"nods":"shakes"); } } } if (msg->type==NT_CHAR) { co=msg->dat1; if (co==workerdat->follow_cn && !(ch[cn].flags&CF_INVISIBLE)) { if (ch[co].x<216) { ch[cn].tmpx=ch[co].x; ch[cn].tmpy=ch[co].y; } else workerdat->useitem=map[door_itemx+door_itemy*MAXMAP].it; } } if (msg->type==NT_NPC && msg->dat1==NTID_SALTMINE_USEITEM) { if (msg->dat2==workerdat->follow_cn && !workerdat->hassalt && !workerdat->useitem && ppd->useitemflag) { workerdat->useitem=msg->dat3; ppd->useitemflag=0; } } standard_message_driver(cn,msg,1,1); remove_message(cn,msg); } // monastery action of worker if (workerdat->leftmonastery && workerdat->leftmonastery+10*TICKS<ticker) { if (in_monastery(ch[cn].x,ch[cn].y)) { if (workerdat->hassalt && !workerdat->useitem) workerdat->useitem=map[saltbag_itemx+saltbag_itemy*MAXMAP].it; if (!workerdat->hassalt && !workerdat->useitem) workerdat->useitem=map[door_itemx+door_itemy*MAXMAP].it; } } else { if (!workerdat->leftmonastery && !in_monastery(ch[cn].x,ch[cn].y)) workerdat->leftmonastery=ticker; } if (workerdat->hassalt && ch[cn].speed_mode!=SM_STEALTH) ch[cn].speed_mode=SM_STEALTH; if (!workerdat->hassalt && ch[cn].speed_mode!=SM_NORMAL) ch[cn].speed_mode=SM_NORMAL; if (workerdat->hassalt && ch[cn].hp<ch[cn].value[1][V_HP]*POWERSCALE && ch[cn].speed_mode!=SM_NORMAL) ch[cn].speed_mode=SM_NORMAL; // fighting fight_driver_update(cn); if (ch[cn].hp>20*POWERSCALE) { if (fight_driver_attack_visible(cn,0)) return; } else { if (fight_driver_flee(cn)) return; } if (regenerate_driver(cn)) return; if (spell_self_driver(cn)) return; if ((ch[cn].flags&CF_INVISIBLE)) { if (ticker>workerdat->turnvisible) { ch[cn].flags&=~CF_INVISIBLE; } else if (move_driver(cn,ch[cn].tmpx,ch[cn].tmpy,0)) return; } else if (workerdat->useitem) { if (use_driver(cn,workerdat->useitem,0)) return; } else if (ticker>workerdat->waituntil) { if (move_driver(cn,ch[cn].tmpx,ch[cn].tmpy,3)) return; } // turn to owner dir=offset2dx(ch[cn].x,ch[cn].y,ch[workerdat->follow_cn].x,ch[workerdat->follow_cn].y); if (ch[cn].dir!=dir) turn(cn,dir); do_idle(cn,TICKS/8); // they need to be fast, otherwise they act a bit stupid (easy solution. swap driver cause some deadlocks) }
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); }