Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!decwrl!decvax!tektronix!tekgen!tekred!games-request From: games-request@tekred.TEK.COM Newsgroups: comp.sources.games Subject: v03i058: omega - rogue like dungeon exploration, Part11/15 Message-ID: <2082@tekred.TEK.COM> Date: 20 Jan 88 16:05:27 GMT Sender: billr@tekred.TEK.COM Lines: 1705 Approved: billr@tekred.TEK.COM Submitted by: "Laurence R. Brothers" Comp.sources.games: Volume 3, Issue 58 Archive-name: omega/Part11 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh oaux2.c <<'END_OF_oaux2.c' X/* omega copyright (C) by Laurence Raphael Brothers, 1987 */ X X/* oaux2.c */ X X/* some functions called by ocom.c, also see oaux2.c */ X/* This is a real grab bag file. It contains functions used by X oaux1 and o.c, as well as elsewhere. It is mainly here so oaux1.c X is not huge */ X X#include X#include "oglob.h" X X/* from ospell */ Xextern char *spellid(); X X/* from oeffect 1 or 2 */ Xextern void manastorm(); X X/* from oitemf */ Xextern void weapon_normal_hit(),weapon_demonblade(),weapon_lightsabre(); Xextern void weapon_mace_disrupt(),weapon_bare_hands(); Xextern void weapon_vorpal(),weapon_desecrate(),weapon_firestar(); Xextern void weapon_defend(),weapon_victrix(),weapon_tangle(); Xextern void weapon_arrow(),weapon_bolt(); X X/* from oitem */ Xextern void item_use(),damage_item(); X X/* from oinv */ Xextern void pickup_at(),drop_at(),givemonster(),conform_lost_objects(); Xextern void conform_unused_object(),add_item_to_pack(); Xextern char *itemid(); Xextern int getitem(),badobject(),cursed(); X X/* from outil */ Xextern int random_range(); Xextern int inbounds(),confirmation(); Xextern char inversedir(); Xextern char *getarticle(); Xextern int unblocked(),bitp(); Xextern void bitset(),bitreset(); X X/* from oscr */ Xextern void showcursor(),refreshmsg(),drawspot(),describe_player(); Xextern void mprint(),endgraf(),showflags(),dataprint(),menuaddch(); Xextern void show_screen(),xredraw(),phaseprint(); Xextern void drawvision(),display_death(),morewait(),menumorewait(); Xextern void menuclear(),menuprint(),display_win(),mnumprint(); Xextern char mgetc(),lgetc(),ynq(); Xextern void screencheck(); X X X/* from ocom */ Xvoid p_process(),wwp(); X X/* from omon */ Xextern void m_damage(),m_status_set(),m_status_reset(),m_death(),m_pickup(); Xextern void tacmonster(); Xextern int m_statusp(); X X/* from oaux1 */ Xextern void p_damage(),calc_melee(),p_death(); X X/* oaux2 functions */ Xchar *actionlocstr(); Xvoid break_weapon(),drop_weapon(),moon_check(),toggle_item_use(); Xvoid p_fumble(),p_win(),p_hit(),p_miss(),addring(),torch_check(); Xvoid top_level(),printactions(),movecursor(),p_drown(); Xvoid tacexecute(),weapon_use(),move_status_check(),hour_status_check(); Xint expval(),player_hit(),statmod(),item_value(),true_item_value(); X X X X X /* Player stats like str, agi, etc give modifications to various abilities X chances to do things, etc. Positive is good, negative bad. */ X int statmod(stat) X int stat; X { X return((stat-10)/2); X } X X X/* effects of hitting */ Xvoid p_hit (m,dmg,dtype) Xstruct monster *m; Xint dmg; Xint dtype; X{ X int dmult; X X /* chance for critical hit..., 3/10 */ X switch (random_range(10)) { X case 0: X if (random_range(100) < Player.level) { X strcpy(Str3,"You annihilate the "); X dmult = 1000; X } X else { X strcpy(Str3,"You blast "); X dmult=5; X } X break; X case 1: X case 2: strcpy(Str3,"You smash "); dmult=2; break; X default: strcpy(Str3,"You hit "); dmult=1; break; X } X if (Lunarity == 1) dmult = dmult * 2; X else if (Lunarity == -1) dmult = dmult / 2; X if (m->uniqueness == COMMON) strcat(Str3,"the "); X strcat(Str3,m->monstring); X strcat(Str3,". "); X if (Tacmode) { X menuprint(Str3); X menuprint("\n"); X } X else mprint(Str3); X m_damage(m,dmult * random_range(dmg),dtype); X} X X/* and effects of missing */ Xvoid p_miss(m,dtype) Xstruct monster *m; Xint dtype; X{ X if (random_range(30)==1) /* fumble 1 in 30 */ X p_fumble(dtype); X else { X strcpy(Str3,"You miss "); X if (m->uniqueness == COMMON) strcat(Str3,"the "); X strcat(Str3,m->monstring); X strcat(Str3,". "); X if (Tacmode) { X menuprint(Str3); X menuprint("\n"); X } X else mprint(Str3); X } X} X X/* oh nooooo, a fumble.... */ Xvoid p_fumble(dtype) Xint dtype; X{ X mprint("Ooops! You fumbled...."); X switch(random_range(10)) { X case 0: X case 1: X case 2: X case 3: X case 4: X case 5: drop_weapon(); break; X case 6: X case 7: X case 8: break_weapon(); break; X case 9: mprint("Oh No! You hit yourself!"); X p_damage(Player.dmg,dtype,"stupidity"); X break; X } X} X X/* try to drop a weapon (from fumbling) */ Xvoid drop_weapon() X{ X int i; X if (Player.primary != NULL) { X strcpy(Str1,"You dropped your "); X strcat(Str1,Player.primary->objstr); X mprint(Str1); X morewait(); X p_drop_at(Player.x,Player.y,1,Player.primary); X conform_lost_objects(1,Player.primary); X } X else mprint("You feel fortunate."); X} X X X/* try to break a weapon (from fumbling) */ Xvoid break_weapon() X{ X if (Player.primary != NULL) { X strcpy(Str1,"Your "); X strcat(Str1,itemid(Player.primary)); X strcat(Str1,"vibrates in your hand...."); X mprint(Str1); X damage_item(Player.primary); X morewait(); X } X} X X X/* hooray */ Xvoid p_win() X{ X mprint("You won!"); X morewait(); X display_win(); X endgraf(); X exit(0); X} X X X/* handle a h,j,k,l, etc., to change x and y by dx and dy */ Xvoid movecursor(x,y,dx,dy) Xint *x,*y; Xint dx,dy; X{ X if (inbounds(*x+dx,*y+dy)) { X *x += dx; X *y += dy; X screencheck(*y); X } X showcursor(*x,*y); X} X X X/* is Player immune to damage type dtype */ Xint p_immune(dtype) Xint dtype; X{ X return(Player.immunity[dtype]); X} X X X X X X X/* deal with each possible stati -- values are per move */ X/* this function is executed every move */ X/* A value over 1000 indicates a permanent effect */ Xvoid move_status_check() X{ X int i; X X if (Player.status[HASTED]>0) { X if (Player.status[HASTED] < 1000) { X Player.status[HASTED]--; X if (Player.status[HASTED]==0) { X mprint("The world speeds up."); X calc_melee(); X } X } X } X X X if (Player.status[POISONED]>0) { X Player.status[POISONED]--; X p_damage(3,POISON,"poison"); X if (Player.status[POISONED] == 0) { X showflags(); X mprint("You feel better now."); X } X } X X X if (Player.immunity[UNSTOPPABLE]>0) { X for(i=0;i0) { X Player.status[IMMOBILE]--; X if (Player.status[IMMOBILE] == 0) X mprint("You can move again."); X } X X X if (Player.status[SLEPT]>0) { X Player.status[SLEPT]--; X Skipplayer = TRUE; X if (Player.status[SLEPT] == 0) { X mprint("You woke up."); X Skipplayer = FALSE; X } X } X X if (Player.status[REGENERATING]>0) { X if (Player.hp < Player.maxhp) Player.hp++; X if (Player.status[REGENERATING] < 1000) { X Player.status[REGENERATING]--; X if (Player.status[REGENERATING] == 0) { X mprint("You feel less homeostatic."); X } X } X } X X if (Player.status[SLOWED]>0) { X if (Player.status[SLOWED] < 1000) { X Player.status[SLOWED]--; X if (Player.status[SLOWED] == 0) { X mprint("You feel quicker now."); X calc_melee(); X } X } X } X X if (Player.status[RETURNING]>0) { X Player.status[RETURNING]--; X if (Player.status[RETURNING] == 150) X mprint("Your spell slowly hums towards activation..."); X else if (Player.status[RETURNING] == 100) X mprint("There is an electric tension in the air!"); X else if (Player.status[RETURNING] == 50) X mprint("A vortex of mana begins to form around you!"); X else if (Player.status[RETURNING] == 10) X mprint("Your surroundings start to warp and fade!"); X if (Player.status[RETURNING] == 0) { X mprint("The vortex of mana carries you off!"); X level_return(); X } X } X X if (Player.status[AFRAID]>0) { X if (Player.status[AFRAID] < 1000) { X Player.status[AFRAID]--; X if (Player.status[AFRAID] == 0) { X mprint("You feel bolder now."); X } X } X } X X} X X X X/* effect of gamma ray radiation... */ Xvoid moon_check() X{ X /* 24 day lunar cycle */ X Phase = (Phase+1)%24; X phaseprint(); X Lunarity = 0; X if (((Player.patron == DRUID) && ((Phase/2 == 3) || (Phase/2 == 9))) || X ((Player.alignment > 10) && (Phase/2 == 6)) || X ((Player.alignment < -10) && (Phase/2 == 0))) { X mprint("As the moon rises you feel unusually vital!"); X Lunarity = 1; X } X else X if (((Player.patron == DRUID) && ((Phase/2 == 0) || (Phase/2 == 6))) || X ((Player.alignment > 10) && (Phase/2 == 0)) || X ((Player.alignment < -10) && (Phase/2 == 6))) { X mprint("The rise of the moon tokens a strange enervation!"); X Lunarity = -1; X } X X} X X Xvoid torch_check() X{ X int i; X for(i=0;iid == THINGID+8) && /*torch */ X (Player.possessions[i]->used) && X (Player.possessions[i]->aux > 0)) { X Player.possessions[i]->aux--; X if (Player.possessions[i]->aux==0) { X mprint("Your torch goes out!!!"); X conform_unused_object(Player.possessions[i]); X if (Player.possessions[i]->number > 1) { X Player.possessions[i]->number--; X Player.possessions[i]->aux = 6; X } X else { X Player.possessions[i]->usef = I_NO_OP; X strcpy(Player.possessions[i]->objstr,"burnt-out torch"); X strcpy(Player.possessions[i]->truename,"burnt-out torch"); X strcpy(Player.possessions[i]->cursestr,"burnt-out torch"); X } X } X } X} X X/* these values are in hours */ X/* this function is checked hourly */ X/* values over 1000 indicate a permanent effect */ Xvoid hour_status_check() X{ X if (hour()==0) { /* midnight, a new day */ X moon_check(); X Date++; X } X torch_check(); X if ((Player.status[SHADOWFORM]>0) && (Player.status[SHADOWFORM]<1000)) { X Player.status[SHADOWFORM]--; X if (Player.status[SHADOWFORM] == 0) { X Player.immunity[NORMAL_DAMAGE]--; X Player.immunity[ACID]--; X Player.immunity[THEFT]--; X Player.immunity[INFECTION]--; X mprint("You feel less shadowy now."); X } X } X X if ((Player.status[VULNERABLE]>0) && (Player.status[VULNERABLE]<1000)){ X Player.status[VULNERABLE]--; X if (Player.status[VULNERABLE] == 0) X mprint("You feel less endangered."); X } X X if ((Player.status[ACCURATE]>0) && (Player.status[ACCURACY]<1000)){ X Player.status[ACCURATE]--; X if (Player.status[ACCURATE] == 0) { X calc_melee(); X mprint("The bulls' eyes go away."); X } X } X if ((Player.status[HERO]>0) && (Player.status[HERO]<1000)){ X Player.status[HERO]--; X if (Player.status[HERO] == 0) { X calc_melee(); X mprint("You feel less than super."); X } X } X X if ((Player.status[LEVITATING]>0) && (Player.status[LEVITATING]<1000)){ X Player.status[LEVITATING]--; X if (Player.status[LEVITATING] == 0) X mprint("You're no longer walking on air."); X } X X if (Player.status[DISEASED]>0) { X Player.status[DISEASED]--; X if (Player.status[DISEASED] == 0) { X showflags(); X mprint("You feel better now."); X } X } X X X if ((Player.status[INVISIBLE] > 0) && (Player.status[INVISIBLE]<1000)){ X Player.status[INVISIBLE]--; X if (Player.status[INVISIBLE] == 0) X mprint("You feel more opaque now."); X } X X if ((Player.status[BLINDED]>0) && (Player.status[BLINDED]<1000)) { X Player.status[BLINDED]--; X if (Player.status[BLINDED] == 0) X mprint("You can see again."); X } X X if ((Player.status[TRUESIGHT]>0) && (Player.status[TRUESIGHT]<1000)) { X Player.status[TRUESIGHT]--; X if (Player.status[TRUESIGHT] == 0) X mprint("You feel less keen now."); X } X X if ((Player.status[BERSERK]>0) && (Player.status[BERSERK]<1000)) { X Player.status[BERSERK]--; X if (Player.status[BERSERK] == 0) X mprint("You stop foaming at the mouth."); X } X X if ((Player.status[ALERT]>0) && (Player.status[ALERT] < 1000)) { X Player.status[ALERT]--; X if (Player.status[ALERT] == 0) X mprint("You feel less alert now."); X } X X if ((Player.status[BREATHING]>0) && (Player.status[BREATHING] < 1000)) { X Player.status[BREATHING]--; X if (Player.status[BREATHING] == 0) X mprint("You feel somewhat congested."); X } X X if ((Player.status[DISPLACED]>0) && (Player.status[DISPLACED] < 1000)) { X Player.status[DISPLACED]--; X if (Player.status[DISPLACED]==0) X mprint("You feel a sense of position."); X } X timeprint(); X} X X X X/* Increase in level at appropriate experience gain */ Xvoid gain_level() X{ X if (expval(Player.level+1) <= Player.xp) { X Player.level++; X mprint("You have attained a new level of experience!"); X Player.maxhp += random_range(Player.con)+1; X Player.mana = Player.maxmana = calcmana(); X gain_level(); X } X calc_melee(); X} X X/* experience requirements */ Xint expval(plevel) Xint plevel; X{ X switch(plevel) { X case 0:return(0);break; X case 1:return(20);break; X case 2:return(40);break; X case 3:return(80);break; X case 4:return(160);break; X case 5:return(320);break; X case 6:return(640);break; X case 7:return(1280);break; X case 8:return(2560);break; X case 9:return(5120);break; X case 10:return(10240);break; X default:return((plevel-9) * 10240); break; X } X} X X/* If an item is unidentified, it isn't worth much to those who would buy it */ Xint item_value(item) Xpob item; X{ X if (item->known == 0) { X if (item->objchar == THING) return(1); X else return(true_item_value(item) / 10); X } X else if (item->known == 1) { X if (item->objchar == THING) return(item->basevalue); X else return(item->basevalue / 2); X } X else return(true_item_value(item)); X} X X X/* figures value based on item base-value, charge, plus, and blessing */ Xint true_item_value(item) Xpob item; X{ X float value = item->basevalue; X X if (item->objchar == THING) return(item->basevalue); X else { X if (item->objchar == STICK) value *= (1.0 + (item->charge/20.0)); X if (item->plus > -1.0) value *= (1.0 + (item->plus/4.0)); X else value *= (1.0/abs(item->plus)); X if (item->blessing > 0) value *= 2.0; X return((int) value); X } X} X X/* kill of player if he isn't got the "breathing" status */ Xvoid p_drown() X{ X if (Player.status[BREATHING] > 0) X mprint("Your breathing is unaffected!"); X else { X mprint("You try to hold your breath...."); X mprint("You choke...."); X mprint("Your lungs fill..."); X p_death("drowning"); X } X} X X X/* the effect of some weapon on monster m, with dmgmod a bonus to damage */ Xvoid weapon_use(dmgmod,weapon,m) Xint dmgmod; Xpob weapon; Xstruct monster *m; X{ X int aux = (weapon==NULL ? -2 : weapon->aux); /* bare hands */ X switch(aux) { X case -2: weapon_bare_hands(dmgmod,m); break; X case I_NO_OP: weapon_normal_hit(dmgmod,weapon,m); break; X case I_TANGLE: weapon_tangle(dmgmod,weapon,m); break; X case I_ARROW: weapon_arrow(dmgmod,weapon,m); break; X case I_BOLT: weapon_bolt(dmgmod,weapon,m); break; X case I_DEMONBLADE: weapon_demonblade(dmgmod,weapon,m); break; X case I_LIGHTSABRE: weapon_lightsabre(dmgmod,weapon,m); break; X case I_MACE_DISRUPT: weapon_mace_disrupt(dmgmod,weapon,m); break; X case I_VORPAL: weapon_vorpal(dmgmod,weapon,m); break; X case I_DESECRATE: weapon_desecrate(dmgmod,weapon,m); break; X case I_FIRESTAR: weapon_firestar(dmgmod,weapon,m); break; X case I_DEFEND: weapon_defend(dmgmod,weapon,m); break; X case I_VICTRIX: weapon_victrix(dmgmod,weapon,m); break; X } X} X X/* auxiliary for tacmode: block, attack, lunge, riposte actions */ Xint getlocation() X{ X char response; X menuprint(" low, center, or high [lch]: "); X do X response = mgetc(); X while((response!='l')&&(response!='c')&&(response!='h')); X if (response == 'l') return(LOW); X else return(response=='c' ? CENTER : HIGH); X} X Xvoid printactions(pnumactions,p_actions) Xint pnumactions,p_actions[10]; X{ X int i; X menuprint("\nActions:\n"); X for(i=0;ihp > 0) { X menuprint("\n"); X switch(p_actions[i]-(p_actions[i]%10)){ X case DISENGAGE: X menuprint("\nYou try to disengage..."); X if (Player.agi+Player.level + random_range(20) > X m->level*2+m->speed*5+random_range(20)) { X menuprint("\nYou get away!"); X Tacmode = FALSE; X Skipmonsters = TRUE; X } X else menuprint("\nYou don't get away!"); X break; X case THRUST: X if (Player.primary == NULL) strcpy(Str1,"You jab"); X else if (Player.primary->type == MISSILE) strcpy(Str1,"You shoot"); X else strcpy(Str1,"You thrust"); X strcat(Str1,actionlocstr(p_actions[i] % 10)); X menuprint(Str1); X hitmod = 0; X for (j=0;jtype == CUTTING) strcpy(Str1,"You cut"); X else if (Player.primary->type == STRIKING) strcpy(Str1,"You strike"); X strcat(Str1,actionlocstr(p_actions[i] % 10)); X menuprint(Str1); X hitmod = 0; X for (j=0;jhp > 0) { X menuprint("\n"); X switch(m_actions[i]-(m_actions[i]%10)){ X case DISENGAGE: X menuprint("\nYour opponent tries to run away..."); X if (Player.agi+Player.level + random_range(20) < X m->level*2+m->speed*5+random_range(20)) { X menuprint("\n...and succeeds!"); X m->movef = M_MOVE_SCAREDY; X movemonster(m); X movemonster(m); X Tacmode = FALSE; X } X else menuprint("\n...and fails!"); X break; X case CUT: X hitmod = 0; X for (j=0;jhit += hitmod; X monster_melee(m); X m->hit -= hitmod; X break; X } X } X } X morewait(); X monster_special(m); X} X X X X X/* checks to see if player hits with hitmod vs.monster m at location hitloc */ Xint player_hit(hitmod,hitloc,mnumactions,m_actions,m) Xint hitmod,hitloc,mnumactions,m_actions[10]; Xstruct monster *m; X{ X int i,b,blocks=FALSE,goodblocks=0,hit; X if (m->hp < 1) { X mprint("Unfortunately, your opponent is already dead!"); X return(FALSE); X } X else { X for(i=0;iac+goodblocks*10); X if ((! hit) && (goodblocks > 0)) { X if (m->uniqueness == COMMON) { X strcpy(Str1,"The "); X strcat(Str1,m->monstring); X } X else strcpy(Str1,m->monstring); X strcat(Str1," blocks it!"); X menuprint("\n"); X menuprint(Str1); X } X return(hit); X } X} X X X X/* This function is used to undo all items temporarily, should Xalways be used in pairs with on being TRUE and FALSE, and may cause Xanomalous stats and item-usage if used indiscriminately */ X X Xvoid toggle_item_use(on) Xint on; X{ X static int used[MAXITEMS]; X int i; X SuppressPrinting = TRUE; X if (on) X for(i=0;iused) { X Player.possessions[i]->used = FALSE; X item_use(Player.possessions[i]); X } X } X } X else { X for(i=0;iused = TRUE; X item_use(Player.possessions[i]); X } X calc_melee(); X showflags(); X dataprint(); X timeprint(); X } X SuppressPrinting = FALSE; X} END_OF_oaux2.c if test 22148 -ne `wc -c oinititem1.c <<'END_OF_oinititem1.c' X/* omega copyright (C) 1987 by Laurence Raphael Brothers */ X/* oinititem1.c */ X X#include X#include "oglob.h" X X/* from oitem */ Xextern void potionname(),scrollname(),ringname(),stickname(),cloakname(); Xextern void bootname(); X X Xvoid inititem1(); X X/* initialize the item lists.... */ X/* also RESET *name functions */ Xvoid inititem1() X{ X int i; X potionname(TRUE,Str1); X scrollname(TRUE,Str1); X ringname(TRUE,Str1); X stickname(TRUE,Str1); X cloakname(TRUE,Str1); X bootname(TRUE,Str1); X X for(i=0;i