void update_read(CHAR_DATA *ch, long stamp, int type) { if (IS_NPC(ch)) return; switch (type) { default: return; case NOTE_NOTE: ch->pcdata->last_note = UMAX(ch->pcdata->last_note,stamp); break; case NOTE_IDEA: ch->pcdata->last_idea = UMAX(ch->pcdata->last_idea,stamp); break; case NOTE_PENALTY: ch->pcdata->last_penalty = UMAX(ch->pcdata->last_penalty,stamp); break; case NOTE_NEWS: ch->pcdata->last_news = UMAX(ch->pcdata->last_news,stamp); break; case NOTE_CHANGES: ch->pcdata->last_changes = UMAX(ch->pcdata->last_changes,stamp); break; } }
/* * Do one group of attacks. */ void multi_hit( CHAR_DATA *ch, CHAR_DATA *victim, int dt ) { /* decrement the wait */ if (ch->desc == NULL) ch->wait = UMAX(0,ch->wait - PULSE_VIOLENCE); if (ch->desc == NULL) ch->daze = UMAX(0,ch->daze - PULSE_VIOLENCE); /* no attacks for stunnies -- just a check */ if (ch->position < P_REST) return; if (IS_NPC(ch)) { mob_hit(ch,victim,dt); return; } one_hit( ch, victim, dt ); if (ch->fighting != victim) return; if ( ch->fighting != victim || dt == gsn_backstab ) return; return; }
void get_money_from_rent( CHAR_DATA* ch, OBJ_DATA* obj ) { int cost, period_h, period_d, period_m; int copper = money_count_copper( ch ); int bank = ch->bank; //odjac kase za przedmiot*dni cost = obj->rent_cost; if ( cost < 0 ) { cost = 0; } period_d = ( current_time - ch->pcdata->last_logoff ) / ( 24 * 60 * 60 ); period_h = ( current_time - ch->pcdata->last_logoff ) / ( 60 * 60 ); period_m = ( current_time - ch->pcdata->last_logoff ) / 60; if ( period_d >= 1 ) cost = UMAX( 0, cost * period_d ); else if ( period_h >= 1 ) cost = UMAX( 0, ( cost * period_h ) / 24 ); else if ( period_m >= 1 ) cost = UMAX( 0, ( cost * period_m ) / ( 24 * 60 ) ); else cost = 1; cost = UMAX( 1, ( cost * get_rent_rate( ch ) / 100 ) ); if ( copper + ch->bank < cost ) { money_reset_character_money( ch ); ch->bank = 0; } else { if ( copper < cost ) { ch->bank += copper; money_reset_character_money ( ch ); ch->bank -= cost; } else { money_reduce( ch, cost ); } } if ( cost ) { append_file_format_daily ( ch, MONEY_LOG_FILE, "-> S: %d %d (%d), B: %d %d (%d) - oplata za rent przetrzymanego artefaktu (lub takiego ktoremu skonczyla sie zywotnosc) (przy jego zabieraniu)", copper, money_count_copper( ch ), money_count_copper( ch ) - copper, bank, ch->bank, ch->bank - bank ); } return; }
void update_read(CHAR_DATA *ch, NOTE_DATA *pnote) { time_t stamp; if (IS_NPC(ch)) return; stamp = pnote->date_stamp; switch (pnote->type) { default: return; case NOTE_NOTE: ch->pcdata->last_note = UMAX(ch->pcdata->last_note,stamp); break; case NOTE_IDEA: ch->pcdata->last_idea = UMAX(ch->pcdata->last_idea,stamp); break; case NOTE_PENALTY: ch->pcdata->last_penalty = UMAX(ch->pcdata->last_penalty,stamp); break; case NOTE_NEWS: ch->pcdata->last_news = UMAX(ch->pcdata->last_news,stamp); break; case NOTE_CHANGES: ch->pcdata->last_changes = UMAX(ch->pcdata->last_changes,stamp); break; } }
/** * przenoszenie pieniêdzy z objektu na character, * wykorzystywane przy podnoszeniu ITEM_MONEY */ void money_gain_from_obj ( CHAR_DATA *ch, OBJ_DATA *obj, OBJ_DATA *container ) { if ( obj->item_type == ITEM_MONEY ) { long int copper = money_count_copper( ch ); ch->copper += UMAX ( 0, obj->value[ 0 ] ); ch->silver += UMAX ( 0, obj->value[ 1 ] ); ch->gold += UMAX ( 0, obj->value[ 2 ] ); ch->mithril += UMAX ( 0, obj->value[ 3 ] ); if ( container ) { append_file_format_daily ( ch, MONEY_LOG_FILE, "-> S: %ld %ld (%ld) - /%d/%d/%d/%d/- wzi±³ kasê z kontenera [%5d] w lokacji [%5d]", copper, money_count_copper( ch ), money_count_copper( ch ) - copper, obj->value[ 0 ], obj->value[ 1 ], obj->value[ 2 ], obj->value[ 3 ], container->pIndexData ? container->pIndexData->vnum : 0, container->in_room ? container->in_room->vnum : 0 ); if ( container->item_type == ITEM_CORPSE_NPC || ( container->item_type == ITEM_CORPSE_PC && str_cmp( container->hidden_description, ch->name2 ) ) ) { money_split_auto( ch, obj ); } } else { append_file_format_daily ( ch, MONEY_LOG_FILE, "-> S: %ld %ld (%ld) - /%d/%d/%d/%d/ - podniós³ kasê w lokacji [%5d]", copper, money_count_copper( ch ), money_count_copper( ch ) - copper, obj->value[ 0 ], obj->value[ 1 ], obj->value[ 2 ], obj->value[ 3 ], ch->in_room ? ch->in_room->vnum : 0 ); } extract_obj( obj ); } }
/** * dodawanie pieniedzy, wykorzystywac tylko w handlu z mobami * oraz w operacjach bankowych */ void money_gain ( CHAR_DATA *ch, long int copper ) { long int money = 0; if ( copper > 0 && ! copper < RATTING_MITHRIL ) { money = copper; money /= RATTING_MITHRIL; ch->mithril += UMAX( 0, money ); copper -= money * RATTING_MITHRIL; } if ( copper > 0 && ! copper < RATTING_GOLD ) { money = copper; money /= RATTING_GOLD; ch->gold += UMAX( 0, money ); copper -= money * RATTING_GOLD; } if ( copper > 0 && ! copper < RATTING_SILVER ) { money = copper; money /= RATTING_SILVER; ch->silver += UMAX( 0, money ); copper -= money * RATTING_SILVER; } if ( copper > 0 ) { ch->copper += UMAX( 0, copper ); } }
// if both 'other' == -1 return ( max( highest ), -1 ) // if both 'other' != -1 return ( max( highest ), max( other ) ) // else if c1.other == -1 // if c1.highest >= c2.highest return ( c1.highest, -1 ) // else return ( c2.highest, max( c1.highest, c2.other ) ) // else if c2.other == -1 // if c2.highest >= c1.highest return ( c2.highest, -1 ) // else return ( c1.highest, max( c2.highest, c1.other ) ) casting_rule_type compose_casting_rule( const casting_rule_type c1, const casting_rule_type c2 ) { casting_rule_type c3; if ( c1.other == -1 && c2.other == -1 ) { c3.highest = UMAX( c1.highest, c2.highest ); c3.other = -1; return c3; } if ( c1.other != -1 && c2.other != -1 ) { c3.highest = UMAX( c1.highest, c2.highest ); c3.other = UMAX( c1.other, c2.other ); return c3; } if ( c1.other == -1 ) { //c3.highest = max( c1.highest, c2.highest ); if ( c1.highest >= c2.highest ) { c3.highest = c1.highest; c3.other = -1; } else { c3.highest = c2.highest; c3.other = UMAX( c1.highest, c2.other ); } return c3; } // we are sure following test is true: if ( c2.other == -1 ) { if ( c2.highest >= c1.highest ) { c3.highest = c2.highest; c3.other = -1; } else { c3.highest = c1.highest; c3.other = UMAX( c2.highest, c1.other ); } return c3; }
int get_maxskill( CHAR_DATA *ch, int sn, bool availabletochar ) { int sklvl1 = skill_table[sn]->skill_level[ch->Class]; int sklvl2 = skill_table[sn]->skill_level[ch->secondclass]; int sklvl3 = skill_table[sn]->skill_level[ch->thirdclass]; int result = 0; bool one = FALSE, two = FALSE, three = FALSE; if ( sklvl1 == 0 ) sklvl1 = 101; if ( sklvl2 == 0 ) sklvl2 = 101; if ( sklvl3 == 0 ) sklvl3 = 101; /* Means players have access to said sn */ if ( availabletochar ) { if ( sklvl3 <= ch->thirdlevel ) three = TRUE; if ( sklvl2 <= ch->secondlevel ) two = TRUE; if ( IS_SECONDCLASS( ch ) ) { if ( sklvl1 <= ch->firstlevel ) one = TRUE; } else { if ( sklvl1 <= ch->Class ) one = TRUE; } } else { three = TRUE; two = TRUE; one = TRUE; } if ( three ) { if ( two ) { if ( one ) { /* * All three are valid!! */ result = sklvl3 > sklvl2 ? UMAX( sklvl3, sklvl1 ) : UMAX( sklvl2, sklvl1 ); } else /* Only three and two! */ result = UMAX( sklvl3, sklvl2 ); } if ( one ) /* Might still be three and one */ result = UMAX( sklvl3, sklvl1 ); } else if ( two ) result = UMAX( sklvl2, sklvl1 ); else result = sklvl1; return result; }
/* Read next note in current group. If no more notes, go to next board */ static void do_nread (CHAR_DATA *ch, char *argument) { NOTE_DATA *p; int count = 0, number; time_t *last_note = &ch->pcdata->last_note[board_number(ch->pcdata->board)]; if (!str_cmp(argument, "again")) { /* read last note again */ } else if (is_number (argument)) { number = atoi(argument); for (p = ch->pcdata->board->note_first; p; p = p->next) if (++count == number) break; if (!p || !is_note_to(ch, p)) send_to_char ("No such note.\n\r",ch); else { show_note_to_char (ch,p,count); *last_note = UMAX (*last_note, p->date_stamp); } } else /* just next one */ { char buf[200]; count = 1; if (ch->pcdata->board == NULL) { send_to_char("You are not on a board.\n\r", ch ); return;} if (ch->pcdata->board->note_first == NULL) { send_to_char("There are no notes.\n\r", ch ); return;} for (p = ch->pcdata->board->note_first; p ; p = p->next, count++) if ((p->date_stamp > *last_note) && is_note_to(ch,p)) { show_note_to_char (ch,p,count); /* Advance if new note is newer than the currently newest for that char */ *last_note = UMAX (*last_note, p->date_stamp); return; } send_to_char ("No new notes in this board.\n\r",ch); if (next_board (ch)) xprintf (buf, "Changed to next board, %s.\n\r", ch->pcdata->board->short_name); else xprintf (buf, "There are no more boards.\n\r"); send_to_char (buf,ch); } }
/** * funkcja pomocnicza, tylko do autosplita */ void money_split_auto ( CHAR_DATA *ch, OBJ_DATA *obj ) { if ( !IS_NPC( ch ) && EXT_IS_SET( ch->act, PLR_AUTOSPLIT ) ) { money_split( ch, UMAX( 0, obj->value[ 0 ] ), NOMINATION_COPPER, FALSE, FALSE, TRUE ); money_split( ch, UMAX( 0, obj->value[ 1 ] ), NOMINATION_SILVER, FALSE, FALSE, TRUE ); money_split( ch, UMAX( 0, obj->value[ 2 ] ), NOMINATION_GOLD, FALSE, FALSE, TRUE ); money_split( ch, UMAX( 0, obj->value[ 3 ] ), NOMINATION_MITHRIL, FALSE, FALSE, TRUE ); } }
/* * Advancement stuff. */ void advance_level( CHAR_DATA *ch, bool hide ) { char buf[MAX_STRING_LENGTH]; int add_hp; int add_mana; int add_move; int add_prac; ch->pcdata->last_level = ( ch->played + (int) (current_time - ch->logon) ) / 3600; sprintf( buf, "the %s", title_table [ch->iclass] [ch->level] [ch->sex == SEX_FEMALE ? 1 : 0] ); set_title( ch, buf ); add_hp = con_app[get_curr_stat(ch,STAT_CON)].hitp + number_range( class_table[ch->iclass].hp_min, class_table[ch->iclass].hp_max ); add_mana = number_range(2,(2*get_curr_stat(ch,STAT_INT) + get_curr_stat(ch,STAT_WIS))/5); if (!class_table[ch->iclass].fMana) add_mana /= 2; add_move = number_range( 1, (get_curr_stat(ch,STAT_CON) + get_curr_stat(ch,STAT_DEX))/6 ); add_prac = wis_app[get_curr_stat(ch,STAT_WIS)].practice; add_hp = add_hp * 9/10; add_mana = add_mana * 9/10; add_move = add_move * 9/10; add_hp = UMAX( 2, add_hp ); add_mana = UMAX( 2, add_mana ); add_move = UMAX( 6, add_move ); ch->max_hit += add_hp; ch->max_mana += add_mana; ch->max_move += add_move; ch->practice += add_prac; ch->train += 1; ch->pcdata->perm_hit += add_hp; ch->pcdata->perm_mana += add_mana; ch->pcdata->perm_move += add_move; if (!hide) { sprintf(buf, "You gain %d hit point%s, %d mana, %d move, and %d practice%s.\n\r", add_hp, add_hp == 1 ? "" : "s", add_mana, add_move, add_prac, add_prac == 1 ? "" : "s"); send_to_char( buf, ch ); } return; }
void write_node(struct session *ses, int list, struct listnode *node, FILE *file) { char result[STRING_SIZE], buffer[BUFFER_SIZE]; int llen = UMAX(20, strlen(node->left)); int rlen = UMAX(25, strlen(node->right)); push_call("write_node(%d,%p,%p)",list,node,file); switch (list) { case LIST_EVENT: case LIST_FUNCTION: case LIST_MACRO: sprintf(result, "%c%s {%s}\n{\n%s\n}\n\n", gtd->command_char, list_table[list].name, node->left, script_writer(ses, node->right)); break; case LIST_ACTION: case LIST_ALIAS: sprintf(result, "%c%s {%s}\n{\n%s\n}\n{%s}\n\n", gtd->command_char, list_table[list].name, node->left, script_writer(ses, node->right), node->pr); break; case LIST_VARIABLE: show_nest_node(node, buffer, 1); sprintf(result, "%c%-16s {%s} %*s {%s}\n", gtd->command_char, list_table[list].name, node->left, 20 - llen, "", buffer); break; default: switch (list_table[list].args) { case 0: result[0] = 0; break; case 1: sprintf(result, "%c%-16s {%s}\n", gtd->command_char, list_table[list].name, node->left); break; case 2: sprintf(result, "%c%-16s {%s} %*s {%s}\n", gtd->command_char, list_table[list].name, node->left, 20 - llen, "", node->right); break; case 3: sprintf(result, "%c%-16s {%s} %*s {%s} %*s {%s}\n", gtd->command_char, list_table[list].name, node->left, 20 - llen, "", node->right, 25 - rlen, "", node->pr); break; } break; } fputs(result, file); pop_call(); return; }
void func_rnew_mail(USER_DATA *usr) { MAIL_DATA *pMail; char buf[STRING]; BUFFER *buffer; int vnum = 1; buffer = new_buf(); for (pMail = usr->pMailFirst; pMail; pMail = pMail->next) { if (pMail->stamp_time <= pMail->read_time) break; } if (pMail) { time_t *last_read = &pMail->read_time; *last_read = UMAX(*last_read, pMail->stamp_time); sprintf(buf, "Reading new message %d.\n\rDate: %s\n\rFrom: %s\n\r" "Subject: %s\n\r\n\r", vnum, time_str(pMail->stamp_time), pMail->from, pMail->subject); add_buf(buffer, buf); add_buf(buffer, pMail->message); add_buf(buffer, "#x\n\r"); page_to_user(buf_string(buffer), usr); free_buf(buffer); save_mail(usr); return; } send_to_user("No new messages.\n\r", usr); return; }
bool check_word_kill(CHAR_DATA *ch, CHAR_DATA *victim, int type, int spell) { if( (!IS_NPC(victim) && IS_IMMORTAL(victim)) || 100*victim->hit/UMAX(get_max_hp(victim), 1) > 24 ) return TRUE; return FALSE; }
bool check_word_blind(CHAR_DATA *ch, CHAR_DATA *victim, int type, int spell) { if( IS_AFFECTED(victim, AFF_BLIND) || 100*victim->hit/UMAX(get_max_hp(victim), 1) > 39 ) return TRUE; return FALSE; }
int spell_sonic_blast( int sn, int level, CHAR_DATA *ch, void *vo ) { CHAR_DATA *victim = (CHAR_DATA *) vo; static const int dam_each [ ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260 }; int dam; level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 ); level = UMAX( 0, level ); dam = number_range( dam_each[level], dam_each[level] * 6 ); if ( saves_spell( level, victim ) ) dam /= 2; //damage( ch, victim, dam, sn ); return dam; }
bool check_word_stun(CHAR_DATA *ch, CHAR_DATA *victim, int type, int spell) { if( 100*victim->hit/UMAX(get_max_hp(victim), 1) > 39 ) return TRUE; return FALSE; }
/** * wylicz wagê noszonych przez postaæ monet */ int money_weight ( long int copper, long int silver, long int gold, long int mithril ) { if ( copper > 0 || silver > 0 || gold > 0 || mithril > 0 ) { return UMAX( 1, copper/40 + silver/20 + gold/10 + mithril/5 ); } return 0; }
int exp_to_level_adept( CHAR_DATA * ch ) { int exp; exp = ( 30000 + ( ch->adept_level * 5000 ) ); exp = UMAX( exp, exp * ch->adept_level/2 ); return exp; }
bool check_vnums( CHAR_DATA * ch, AREA_DATA * tarea, RENUMBER_AREA * r_area ) { int high, low; AREA_DATA *area; bool proto; if( !r_area ) { bug( "%s: NULL r_area!", __func__ ); return TRUE; } /* * this function assumes all the lows are allways gonna be * lower or equal to all the highs .. */ high = UMAX( r_area->hi_room, UMAX( r_area->hi_obj, r_area->hi_mob ) ); low = UMIN( r_area->low_room, UMIN( r_area->low_obj, r_area->low_mob ) ); /* * in do_check_vnums they use first_bsort, first_asort but.. i dunno.. */ area = first_area; proto = FALSE; while( area ) { if( tarea == area ) ; else if( !( high < area->low_r_vnum || low > area->hi_r_vnum ) || !( high < area->low_o_vnum || low > area->hi_o_vnum ) || !( high < area->low_m_vnum || low > area->hi_m_vnum ) ) { ch_printf( ch, "This operation would overwrite area %s! Use checkvnums first.\r\n", area->filename ); return TRUE; } area = area->next; if( area == NULL && !proto ) { area = first_build; proto = TRUE; } } return FALSE; }
int class_hpmin(long c) { int res = 0; long i = 0; for (i=0;i<MAX_CLASS;i++) if ((1<<i) & c) res = UMAX(res,class_table[i].hp_min); return res; }
/* * Stick a little fuzz on a number. */ int number_fuzzy( int number ) { switch ( number_bits( 2 ) ) { case 0: number -= 1; break; case 3: number += 1; break; } return UMAX( 1, number ); }
void update_soil( ROOM_INDEX_DATA *room ) { int interval = environment_interval - room->water_update; room->water = UMAX( room->water_min, room->water - ( interval * room->water_degrade ) ); room->water_update = environment_interval; return; }
int class_abilityadept(long c) { int res = 0; int i = 0; for (i=0;i<MAX_CLASS;i++) { if ((1<<i) & c) { res = UMAX(res,class_table[i].ability_adept); } } return res; }
char *sub_arg_in_braces(struct session *ses, char *string, char *result, int flag, int sub) { char *buffer = str_alloc(UMAX(strlen(string), BUFFER_SIZE)); string = get_arg_in_braces(ses, string, buffer, flag); substitute(ses, buffer, result, sub); str_free(buffer); return string; }
void Weave::GenerateLeyLines(ROOM_INDEX_DATA & room) { // Choose a random direction s_changedRooms.insert(&room); std::vector<Direction::Value> validDirections(Direction::ValidDirectionsFrom(room)); Direction::Value direction(PopNextDirection(room, validDirections)); if (direction == Direction::Max) return; // Proceed down that direction unsigned int leyLength((AverageLeyLength * number_range(50, 150)) / 100); ContinueLeyLine(room, direction, &room, 0, UMAX(leyLength, MinLeyLength), room.ley_group->FountOrderPower(), room.ley_group->FountPositivePower()); }
int main() { unsigned char c = ~0; unsigned short s = ~0; unsigned int i = ~0; unsigned long l = ~0; printf("char min: %d, max: %d, unsigned max: %u\n", CHAR_MIN, CHAR_MAX, UCHAR_MAX); printf("short min: %d, max: %d, unsigned max: %u\n", SHRT_MIN, SHRT_MAX, USHRT_MAX); printf("int min: %d, max: %d, unsigned max: %u\n", INT_MIN, INT_MAX, UINT_MAX); printf("long min: %ld, max: %ld, unsigned max: %lu\n", LONG_MIN, LONG_MAX, ULONG_MAX); #define MIN(x) (-(x >> 1) - 1) #define MAX(x) (x >> 1) #define UMAX(x) x printf("char min: %d, max: %d, unsigned max: %u\n", MIN(c), MAX(c), UMAX(c)); printf("short min: %d, max: %d, unsigned max: %u\n", MIN(s), MAX(s), UMAX(s)); printf("int min: %d, max: %d, unsigned max: %u\n", MIN(i), MAX(i), UMAX(i)); printf("long min: %ld, max: %ld, unsigned max: %lu\n", MIN(l), MAX(l), UMAX(l)); return 0; }
int class_abilityrating(CHAR_DATA *ch,int sn, int lvl ) { int res = 0; int i = 0; long c = ch->cstat(classes); for (i=0;i<MAX_CLASS;i++) { // Modified by SinaC 2003, added abs if ( ((1<<i) & c) && (abs(ability_table[sn].rating[i]) > 0)) { res = res ? UMIN(res,abs(ability_table[sn].rating[i])) : abs(ability_table[sn].rating[i]); } } // Added by SinaC 2001, if the spell has been learned at a level <> 0 // we return that level, only if the previous result was 0 (class can't learn that ability) if ( !IS_NPC(ch) && ch->pcdata->ability_info[sn].level > 0 && res == 0 ) { //res = ch->pcdata->ability_info[sn].level; // 1 before modified by SinaC 2003 res = 10; // difficulty for learned spell is 10, SinaC 2003 } // Modified by SinaC 2001 for ability level, level but no prereq if ( ability_table[sn].nb_casting_level > 0 && ability_table[sn].prereqs == NULL ) { return UMAX( res, DEFAULT_PREREQ_COST(lvl) ); } // Modified by SinaC 2000 for ability level, level and prereq if ( ability_table[sn].nb_casting_level > 0 && ability_table[sn].prereqs != NULL && res > 0 ){ //if ( ability_table[sn].prereqs[lvl] != NULL ) return UMAX(ability_table[sn].prereqs[lvl].cost, res ); // for ( int j = 0; j < ability_table[sn].nb_casting_level; j++ ){ // if ( skill_table[sn].prereqs[j].casting_level == lvl ) // return UMAX(ability_table[sn].prereqs[j].cost, res ); //} } return res; }
void auth_maxdesc(int *md, fd_set *ins, fd_set *outs, fd_set *excs) { AUTH_DATA *a; for (a = first_auth; a; a = a->next) if (a->state != AS_TOOPEN) { *md = UMAX(*md, a->afd); FD_SET(a->afd, ins); FD_SET(a->afd, outs); FD_SET(a->afd, excs); } return; }
bool spell_causticblast(int sn, int level, CHAR_DATA * ch, void * vo, int target) { CHAR_DATA *victim = (CHAR_DATA *) vo; int dam(dice(level, 4)); // Blast them act("$n unleashes a blast of hissing acid upon $N!", ch, NULL, victim, TO_NOTVICT); act("You unleash a blast of hissing acid upon $N!", ch, NULL, victim, TO_CHAR); act("$n unleashes a blast of hissing acid upon you!", ch, NULL, victim, TO_VICT); if (saves_spell(level, ch, victim, DAM_ACID)) { damage_old(ch, victim, dam / 2, sn, DAM_ACID, true); return true; } damage_old(ch, victim, dam, sn, DAM_ACID, true); if (!IS_VALID(victim) || victim->in_room != ch->in_room) return true; act("The acid eats away at you, leaving painful, ugly scars!", victim, NULL, NULL, TO_CHAR); act("The acid eats away at $m, leaving painful, ugly scars!", victim, NULL, NULL, TO_ROOM); // Apply -charisma AFFECT_DATA af = {0}; af.where = TO_AFFECTS; af.type = sn; af.level = level; af.duration = level / 2; af.location = APPLY_CHR; af.modifier = -1; affect_to_char(victim, &af); // Apply burning for (AFFECT_DATA * paf(get_affect(victim, sn)); paf != NULL; paf = get_affect(victim, sn, paf)) { if (paf->location == APPLY_NONE) { paf->duration = UMAX(2, paf->duration); paf->modifier = UMIN(100, paf->modifier + 1); return true; } } af.duration = 2; af.location = APPLY_NONE; af.modifier = 1; affect_to_char(victim, &af); return true; }