void ccp_seen(int cn,int co) { struct ccp_mem *mem=get_ccp_mem(cn); if (ch[co].attack_cn==cn) { // he's attacking us if (ch[co].points_tot>ch[cn].points_tot) ccp_sector_score(cn,-10000); } if (co==mem->fighting) return; if (ch[cn].a_hp<ch[cn].hp[5]*800) return; if (ch[cn].a_mana<ch[cn].hp[5]*800) return; if (ch[co].flags&CF_PLAYER) return; if (ch[co].alignment>0) return; if (IS_COMPANION(co)) return; if (!do_char_can_see(cn,co)) return; if (!can_go(ch[cn].x,ch[cn].y,ch[co].x,ch[co].y)) return; if (ch[co].points_tot>(ch[cn].points_tot*3)/2) return; // too strong if (ch[co].points_tot<ch[cn].points_tot/3) { // too weak if (ch[co].points_tot>ch[cn].points_tot) ccp_sector_score(cn,-3000); return; } ccp_set_enemy(cn,co); ccp_sector_score(cn,1000); }
void ccp_driver(int cn) { #ifdef REAL_CCP struct ccp_mem *mem=get_ccp_mem(cn); int co; if (ch[cn].a_hp<ch[cn].hp[5]*500 && !ccp_at_recall_point(cn) && npc_try_spell(cn,cn,SK_RECALL)) return; if (ch[cn].a_mana>1000*30) { // always keep 15 mana for recall if (ch[cn].a_hp<ch[cn].hp[5]*750 && npc_try_spell(cn,cn,SK_HEAL)) return; if (npc_try_spell(cn,cn,SK_PROTECT)) return; if (npc_try_spell(cn,cn,SK_ENHANCE)) return; if (npc_try_spell(cn,cn,SK_BLESS)) return; if (npc_try_spell(cn,cn,SK_MSHIELD)) return; } // dont fight enemy if no longer visible if (mem->fighting && !do_char_can_see(cn,mem->fighting)) mem->fighting=0; if ((co=mem->fighting)) { ch[cn].attack_cn=co; ch[cn].goto_x=ch[cn].goto_y=0; if (ch[cn].a_mana>1000*30) { // always keep 15 mana for recall if (mem->enemy_strength>1) { if (npc_try_spell(cn,co,SK_CURSE)) return; // keep him cursed if (npc_try_spell(cn,co,SK_STUN)) return; // and stunned all the time if (mem->enemy_strength>2) { if (npc_try_spell(cn,co,SK_BLAST)) return; // then blast } } } } if (ch[cn].attack_cn || ch[cn].goto_x || ch[cn].misc_action) return; // we're busy if (ch[cn].skill[SK_MEDIT][0] && ch[cn].a_mana<ch[cn].mana[5]*900) return; // wait for mana regeneration if (ch[cn].a_hp<ch[cn].hp[5]*900) return; // wait for hp regeneration ccp_sector_score(cn,-1); // we get bored easily... ccp_goto_sector(cn); #endif }
int char_give_char(int cn, int co) { int ax, ay, x, y, err, tox, toy; if (ch[cn].cerrno==ERR_FAILED) { ch[cn].cerrno = ERR_NONE; return( -1); } if (ch[co].used!=USE_ACTIVE || do_char_can_see(cn, co)==0 || cn==co) { return(-1); } if (!ch[cn].citem) { return( 1); } x = ch[co].x; tox = ch[co].tox; y = ch[co].y; toy = ch[co].toy; ax = ch[cn].x; ay = ch[cn].y; if ((x==ax + 1 && (y==ay + 1 || y==ay - 1)) || (x==ax - 1 && (y==ay + 1 || y==ay - 1))) { err = char_moveto(cn, x, y, 2, tox, toy); if (err==-1) { return( -1); } else { return( 0); } } // give if possible if ((ax==x - 1 && ay==y) || (ax==tox - 1 && ay==toy)) { if (ch[cn].dir!=DX_RIGHT) { act_turn_right(cn); return( 0); } act_give(cn); return(0); } if ((ax==x + 1 && ay==y) || (ax==tox + 1 && ay==toy)) { if (ch[cn].dir!=DX_LEFT) { act_turn_left(cn); return( 0); } act_give(cn); return(0); } if ((ax==x && ay==y - 1) || (ax==tox && ay==toy - 1)) { if (ch[cn].dir!=DX_DOWN) { act_turn_down(cn); return( 0); } act_give(cn); return(0); } if ((ax==x && ay==y + 1) || (ax==tox && ay==toy + 1)) { if (ch[cn].dir!=DX_UP) { act_turn_up(cn); return( 0); } act_give(cn); return(0); } err = char_moveto(cn, x, y, 2, tox, toy); if (err==-1) { return( -1); } else { return( 0); } }
int char_attack_char(int cn, int co) { int ax, ay, x, y, err, tox, toy, dist1, dist2, diff; if (ch[cn].cerrno==ERR_FAILED) { ch[cn].cerrno = ERR_NONE; return( -1); } if (ch[co].used!=USE_ACTIVE || do_char_can_see(cn, co)==0 || cn==co || (ch[co].flags & CF_BODY) || (ch[co].flags & CF_STONED)) { return( -1); } x = ch[co].x; tox = ch[co].tox; y = ch[co].y; toy = ch[co].toy; ax = ch[cn].x; ay = ch[cn].y; if ((x==ax + 1 && (y==ay + 1 || y==ay - 1)) || (x==ax - 1 && (y==ay + 1 || y==ay - 1))) { err = char_moveto(cn, x, y, 2, tox, toy); if (err==-1) { return( -1); } else { return( 0); } } // attack if possible if ((ax==x - 1 && ay==y) || (ax==tox - 1 && ay==toy)) { if (ch[cn].dir!=DX_RIGHT) { act_turn_right(cn); return( 0); } act_attack(cn); return(1); } if ((ax==x + 1 && ay==y) || (ax==tox + 1 && ay==toy)) { if (ch[cn].dir!=DX_LEFT) { act_turn_left(cn); return( 0); } act_attack(cn); return(1); } if ((ax==x && ay==y - 1) || (ax==tox && ay==toy - 1)) { if (ch[cn].dir!=DX_DOWN) { act_turn_down(cn); return( 0); } act_attack(cn); return(1); } if ((ax==x && ay==y + 1) || (ax==tox && ay==toy + 1)) { if (ch[cn].dir!=DX_UP) { act_turn_up(cn); return( 0); } act_attack(cn); return(1); } dist1 = abs(ax - x) + abs(ay - y); dist2 = abs(ax - tox) + abs(ay - toy); diff = dist1 - dist2; if (dist1>20 && diff<5) { x = tox = tox + (tox - x) * 8; y = toy = toy + (toy - y) * 8; } else if (dist1>10 && diff<4) { x = tox = tox + (tox - x) * 5; y = toy = toy + (toy - y) * 5; } else if (dist1>5 && diff<3) { x = tox = tox + (tox - x) * 3; y = toy = toy + (toy - y) * 3; } else if (dist1>3 && diff<2) { x = tox = tox + (tox - x) * 2; y = toy = toy + (toy - y) * 2; } else if (dist1>2 && diff<1) { x = tox = tox + (tox - x); y = toy = toy + (toy - y); } err = char_moveto(cn, x, y, 2, tox, toy); if (err==-1) { return( -1); } else { return( 0); } }
/* Called by do_say() to check for a spoken riddle answer. This does not fit in very well with npc_hear(). */ int lab9_guesser_says(int cn, char *text) { int m; char word[40]; int riddler, ar, idx, found; struct riddle *riddle; // is the speaker a player? if (!IS_PLAYER(cn)) return 0; // does the riddler exist? riddler = ch[cn].data[CHD_RIDDLER]; if (!IS_SANENPC(riddler)) { ch[cn].data[CHD_RIDDLER] = 0; return 0; } // is the riddler a certified riddler? ar = ch[riddler].data[72]; // area of knowledge if ((ar < RIDDLE_MIN_AREA) || (ar > RIDDLE_MAX_AREA)) { ch[cn].data[CHD_RIDDLER] = 0; return 0; } // does the riddler remember the guesser? idx = ar - RIDDLE_MIN_AREA; if (guesser[idx] != cn) { ch[cn].data[CHD_RIDDLER] = 0; return 0; } // does the player see the riddler? if (!do_char_can_see(cn, riddler)) { return 0; } riddle = &riddles[idx][riddleno[idx]-1]; found = 0; // break his saying into words (copied from do_say()) while (1) { m=0; while (isalnum(*text) && m<40) word[m++]=*text++; word[m]=0; // check if the word matches any solution text if (!strcasecmp(word, riddle->answer1) || (riddle->answer2 && !strcasecmp(word, riddle->answer2)) || (riddle->answer3 && !strcasecmp(word, riddle->answer3))) { found = 1; break; } while (*text && !isalnum(*text)) text++; if (!*text) break; } if (found) { do_sayx(riddler, "That's absolutely correct, %s! " "For solving my riddle, I will advance you in your quest. " "Close your eyes and...\n", ch[cn].name); if (god_transfer_char(cn, destinations[idx].x, destinations[idx].y)) { guesser[idx] = 0; ch[cn].data[CHD_RIDDLER] = 0; } else { do_sayx(riddler, "Oops! Something went wrong. Please try again a bit later.\n"); } return 1; } else { riddleattempts[idx]--; if (riddleattempts[idx] > 0) { do_sayx(riddler, "Sorry, that's not right. You have %d more attempt%s!", riddleattempts[idx], (riddleattempts[idx] == 1) ? "" : "s"); } else { do_sayx(riddler, "Sorry, that's not right. Now you'll have to bring me the book again to start over!\n"); guesser[idx] = 0; ch[cn].data[CHD_RIDDLER] = 0; } return 0; } }