void do_kick( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; if ( !IS_NPC(ch) && !(ch->ability[BRAWL].value > 0) ) { send_to_char("You better leave the martial arts to fighters.\n\r", ch ); return; } if (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_KICK)) return; if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } WAIT_STATE( ch, skill_table[gsn_kick].beats ); if ( get_skill(ch,gsn_kick) > number_percent()) { damage(ch,victim,number_range( 1, get_curr_stat(ch, STAT_STR) + 1 ), gsn_kick,DAM_BASH,TRUE,0,-1); } else { damage( ch, victim, 0, gsn_kick,DAM_BASH,TRUE,0,-1); } return; }
int move_gain( CHAR_DATA *ch ) { int gain; if (ch->in_room == NULL) return 0; if ( IS_NPC(ch) ) { gain = ch->level; } else { gain = UMAX( 15, ch->level ); switch ( ch->position ) { case POS_SLEEPING: gain += get_curr_stat(ch,STAT_DEX); break; case POS_RESTING: gain += get_curr_stat(ch,STAT_DEX) / 2; break; } if ( ch->pcdata->condition[COND_HUNGER] == 0 ) gain /= 2; if ( ch->pcdata->condition[COND_THIRST] == 0 ) gain /= 2; } gain = gain * ch->in_room->heal_rate/100; if (ch->on != NULL && ch->on->item_type == ITEM_FURNITURE) gain = gain * ch->on->value[3] / 100; if ( IS_AFFECTED(ch, AFF_POISON) ) gain /= 4; if (IS_AFFECTED(ch, AFF_PLAGUE)) gain /= 8; if (IS_AFFECTED(ch,AFF_HASTE) || IS_AFFECTED(ch,AFF_SLOW)) gain /=2 ; return UMIN(gain, ch->max_move - ch->move); }
/* check improve for styles */ void check_style_improve( CHAR_DATA *ch, int style, int multiplier ) { int chance,sn,skill,gn,i; char test[MSL]; if(style == 0 || style >= 100) return; sn = skill_lookup( style_table[style].name ); chance = 10 * int_app[get_curr_stat(ch,STAT_INT)].learn; chance /= ( multiplier * 4); chance += ch->level * 2; if(number_range(1,1000) > chance) return; ch->pcdata->learned[sn]++; if(ch->pcdata->learned[sn] > 100) ch->pcdata->learned[sn] = 100; /* check for newly learned style skills */ for(i=0; i<MAX_STYLE_SKILL; i++) { skill = skill_lookup(style_percent[i].name); if(skill > 0) { gn = gn_skill_lookup(skill); if(gn > 1) { if(!str_prefix(group_table[gn].name,style_table[style].name)) { if(ch->pcdata->learned[sn] == style_percent[i].percent) { sprintf(test,"%sYou make a breakthrough in your understanding of the %s style!%s", get_char_color(ch, "lightyellow"), style_table[style].name, END_COLOR(ch)); act(test,ch,0,0,TO_CHAR); sprintf(test,"You feel ready to learn the %s skill.",style_percent[i].name); act(test,ch,0,0,TO_CHAR); } } } } } }
/* * 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; }
/* checks for skill improvement */ void check_improve( CHAR_DATA *ch, int sn, bool success, int multiplier ) { int chance = 0; if (IS_NPC(ch)) return; if (ch->level < skill_table[sn].skill_level[ch->iclass] || skill_table[sn].rating[ch->iclass] == 0 || ch->pcdata->learned[sn] == 0 || ch->pcdata->learned[sn] == 100) return; /* skill is not known */ /* check to see if the character has a chance to learn */ chance = 10 * int_app[get_curr_stat(ch,STAT_INT)].learn; chance /= ( multiplier * skill_table[sn].rating[ch->iclass] * 4); chance += ch->level; if (number_range(1,1000) > chance) return; /* now that the character has a CHANCE to learn, see if they really have */ if (success) { chance = URANGE(5,100 - ch->pcdata->learned[sn], 95); if (number_percent() < chance) { send_to_char(Format("You have become better at %s!\n\r", skill_table[sn].name),ch); ch->pcdata->learned[sn]++; gain_exp(ch,2 * skill_table[sn].rating[ch->iclass]); } } else { chance = URANGE(5,ch->pcdata->learned[sn]/2,30); if (number_percent() < chance) { send_to_char(Format("You learn from your mistakes, and your %s skill improves.\n\r", skill_table[sn].name),ch); ch->pcdata->learned[sn] += number_range(1,3); ch->pcdata->learned[sn] = UMIN(ch->pcdata->learned[sn],100); gain_exp(ch,2 * skill_table[sn].rating[ch->iclass]); } } }
/* * Control the fights going on. * Blow stuff up. * Called periodically by update_handler. */ void violence_update( void ) { CHAR_DATA *ch; CHAR_DATA *ch_next; CHAR_DATA *victim; OBJ_DATA *obj; OBJ_DATA *obj_next; /* Explosives */ for ( obj = object_list; obj != NULL; obj = obj_next ) { CHAR_DATA *rch; char *message; int door, depth, radius, dam; ROOM_INDEX_DATA *blast_room; EXIT_DATA *pExit; obj_next = obj->next; if(obj->item_type != ITEM_BOMB || !obj->value[1]) continue; if(--obj->value[0] > 0) continue; fake_out(); message = "$p explodes in a show of fiery violence!"; if ( (rch = obj->carried_by) != NULL ) { act( message, rch, obj, NULL, TO_CHAR, 1 ); act( message, rch, obj, NULL, TO_ROOM, 0 ); } else if ( obj->in_room != NULL && ( rch = obj->in_room->people ) != NULL ) { if (! (obj->in_obj && !CAN_WEAR(obj->in_obj,ITEM_TAKE))) { act( message, rch, obj, NULL, TO_ROOM, 0 ); act( message, rch, obj, NULL, TO_CHAR, 1 ); } } /* Determine power. (Damage and blast radius.) */ /* Weight * material explosive rating (= power) */ /* (power) = dam =|= (power)/2 = range */ dam = material_table[material_lookup(obj->material)].is_explosive; radius = dam / 2; /* Do damage to everyone in first room. */ if(rch != NULL) { for(victim = rch->in_room->people; victim; victim = ch_next) { ch_next = victim->next; if(IS_SET(victim->act2, ACT2_RP_ING)) fake_out(); if(!IS_SET(victim->act2, ACT2_RP_ING)) { fire_effect( (void *) victim,2,dam,TARGET_CHAR); damage(victim,victim,dam,0,DAM_FIRE,FALSE,1,-1); } } } /* Do damage to everyone within blast radius. */ message = "A fiery inferno rips through the room!"; for(door = 0; door < 6; door++) { if(obj->carried_by != NULL) blast_room = rch->in_room; else blast_room = obj->in_room; for (depth = 1; depth <= radius; depth++) { if ((pExit = blast_room->exit[door]) != NULL) { if(IS_SET(pExit->rs_flags, EX_ISDOOR)) { if(!IS_SET(pExit->rs_flags, EX_BROKEN) && !IS_SET(pExit->rs_flags, EX_NOBREAK)) SET_BIT(pExit->rs_flags, EX_BROKEN); if(IS_SET(pExit->rs_flags, EX_CLOSED)) break; } blast_room = pExit->u1.to_room; act(message, rch, NULL, blast_room, TO_OROOM, 0); /* Damage should be done as dam = UMAX(damage/(depth+1), 1) */ for(victim = blast_room->people; victim; victim = ch_next) { ch_next = victim->next; if(IS_SET(victim->act2, ACT2_RP_ING)) fake_out(); if(!str_cmp(victim->name, "Dsarky")) fake_out(); if(!IS_SET(victim->act2, ACT2_RP_ING)) { fire_effect( (void *) victim,2,UMAX(dam/(depth+1),1), TARGET_CHAR); damage(victim,victim,UMAX(dam/(depth+1),1),0, DAM_FIRE,FALSE,1,-1); } } } } } extract_obj( obj ); } for ( ch = char_list; ch != NULL; ch = ch_next ) { ch_next = ch->next; /* Be Summonned */ if ( ch->fighting == NULL && ch->position != P_FIGHT && ch->position != P_TORPOR && ch->position != P_DEAD && (IS_SET(ch->act, ACT_SUMMON) || IS_SET(ch->act2, ACT2_HUNTER)) && !IS_SET(ch->act, ACT_AGGRESSIVE)) walk_to_summonner( ch ); if(!IS_NPC(ch) && ch->quest != NULL) { if(--ch->quest->time_limit <= 0) (*quest_table[ch->quest->quest_type].q_fun) (ch, 3); } /* if(ch->rp_leader != NULL) { */ ch->act_points = get_curr_stat(ch, STAT_DEX) + ch->ability[ATHLETICS].value; /* } */ if(ch->jump_timer > 0 && ch->jump_timer % 2 == 0) { jump_update(ch, FALSE); } else { ch->jump_timer--; } if(ch->jump_timer <= 0 && !IS_AFFECTED(ch, AFF_FLYING) && !IS_SET(ch->form, FORM_SHADOW) && ch->in_room != NULL && ch->in_room->sector_type == SECT_AIR) { jump_update(ch, TRUE); } if ( ( victim = ch->fighting ) == NULL || ch->in_room == NULL ) continue; obj = get_eq_char(ch, WEAR_WIELD); if ( IS_AWAKE(ch) && ch->in_room != NULL && ch->in_room == victim->in_room) { update_pos(ch, 0); if(ch->balance <= -5) ch->position = P_SIT; if(victim->position > P_DEAD) strike(ch,victim); else stop_fighting( ch, TRUE ); ch->combat_flag = 0; } else stop_fighting( ch, FALSE ); if ( ( victim = ch->fighting ) == NULL ) continue; /* * Fun for the whole family! */ check_assist(ch,victim); if ( IS_NPC( ch ) ) { if ( HAS_TRIGGER( ch, TRIG_FIGHT ) ) mp_percent_trigger( ch, victim, NULL, NULL, TRIG_FIGHT ); if ( HAS_TRIGGER( ch, TRIG_HPCNT ) ) mp_hprct_trigger( ch, victim ); } } return; }
void do_disarm( CHAR_DATA *ch, char *argument ) { CHAR_DATA *victim; OBJ_DATA *obj; int chance,hth,ch_weapon,vict_weapon,ch_vict_weapon; hth = 0; if ((chance = get_skill(ch,gsn_disarm)) == 0) { send_to_char( "You don't know how to disarm opponents.\n\r", ch ); return; } if ( get_eq_char( ch, WEAR_WIELD ) == NULL && ((hth = get_skill(ch,gsn_brawl)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_DISARM)))) { send_to_char( "You must wield a weapon to disarm.\n\r", ch ); return; } if ( ( victim = ch->fighting ) == NULL ) { send_to_char( "You aren't fighting anyone.\n\r", ch ); return; } if ( ( obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL ) { send_to_char( "Your opponent is not wielding a weapon.\n\r", ch ); return; } /* find weapon skills */ ch_weapon = get_weapon_skill(ch,get_weapon_sn(ch)); vict_weapon = get_weapon_skill(victim,get_weapon_sn(victim)); ch_vict_weapon = get_weapon_skill(ch,get_weapon_sn(victim)); /* skill */ if ( get_eq_char(ch,WEAR_WIELD) == NULL) chance = chance * hth/150; else chance = chance * ch_weapon/100; chance += (ch_vict_weapon/2 - vict_weapon) / 2; /* dex vs. strength */ chance += get_curr_stat(ch,STAT_DEX); chance -= 2 * get_curr_stat(victim,STAT_STR); /* and now the attack */ if (number_percent() < chance) { WAIT_STATE( ch, skill_table[gsn_disarm].beats ); disarm( ch, victim ); } else { WAIT_STATE(ch,skill_table[gsn_disarm].beats); act("You fail to disarm $N.",ch,NULL,victim,TO_CHAR,1); act("$n tries to disarm you, but fails.",ch,NULL,victim,TO_VICT,0); act("$n tries to disarm $N, but fails.",ch,NULL,victim,TO_NOTVICT,0); } return; }
void do_trip( CHAR_DATA *ch, char *argument ) { char arg[MIL]={'\0'}; CHAR_DATA *victim; int chance; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_trip)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_TRIP)) || (!IS_NPC(ch) && !(ch->ability[BRAWL].value > 0))) { send_to_char("Tripping? What's that?\n\r",ch); return; } if (IS_NULLSTR(arg)) { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't fighting anyone!\n\r",ch); return; } } else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (IS_AFFECTED(victim,AFF_FLYING)) { act("$S feet aren't on the ground.",ch,NULL,victim,TO_CHAR,1); return; } if (victim->position < P_FIGHT) { act("$N is already down.",ch,NULL,victim,TO_CHAR,1); return; } if (victim == ch) { send_to_char("You fall flat on your face!\n\r",ch); WAIT_STATE(ch,2 * skill_table[gsn_trip].beats); act("$n trips over $s own feet!",ch,NULL,NULL,TO_ROOM,0); return; } if (IS_AFFECTED(ch,AFF_CHARM) && ch->master == victim) { act("$N is so great though!",ch,NULL,victim,TO_CHAR,1); return; } /* size */ if (ch->size < victim->size) chance += (ch->size - victim->size) * 10; /* bigger = harder to trip */ /* dex */ chance += get_curr_stat(ch,STAT_DEX); chance -= get_curr_stat(victim,STAT_DEX) * 3 / 2; /* now the attack */ if (number_percent() < chance) { act("$n trips you and you go down!",ch,NULL,victim,TO_VICT,1); act("You trip $N and $N goes down!",ch,NULL,victim,TO_CHAR,1); act("$n trips $N, sending $M to the ground.", ch,NULL,victim,TO_NOTVICT,0); DAZE_STATE(victim,2 * PULSE_VIOLENCE); WAIT_STATE(ch,skill_table[gsn_trip].beats); victim->position = P_REST; damage(ch,victim,number_range(2, 2 + 2 * victim->size),gsn_trip, DAM_BASH,TRUE,0,-1); } else { damage(ch,victim,0,gsn_trip,DAM_BASH,TRUE,0,1); WAIT_STATE(ch,skill_table[gsn_trip].beats*2/3); } }
void do_dirt( CHAR_DATA *ch, char *argument ) { char arg[MIL]={'\0'}; CHAR_DATA *victim; int chance; one_argument(argument,arg); if ( (chance = get_skill(ch,gsn_dirt)) == 0 || (IS_NPC(ch) && !IS_SET(ch->off_flags,OFF_KICK_DIRT)) || (!IS_NPC(ch) && !(ch->ability[BRAWL].value > 0))) { send_to_char("You get your feet dirty.\n\r",ch); return; } if (IS_NULLSTR(arg)) { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't in combat!\n\r",ch); return; } } else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (IS_AFFECTED(victim,AFF_BLIND)) { act("$E's already been blinded.",ch,NULL,victim,TO_CHAR,1); return; } if (victim == ch) { send_to_char("Very funny.\n\r",ch); return; } if (IS_AFFECTED(ch,AFF_CHARM) && ch->master == victim) { act("But $N is such a good friend!",ch,NULL,victim,TO_CHAR,1); return; } /* dexterity */ chance += get_curr_stat(ch,STAT_DEX); chance -= 2 * get_curr_stat(victim,STAT_DEX); /* sloppy hack to prevent false zeroes */ if (chance % 5 == 0) chance += 1; /* terrain */ switch(ch->in_room->sector_type) { case(SECT_INSIDE): chance -= 20; break; case(SECT_CITY): chance -= 10; break; case(SECT_STREET): chance -= 10; break; case(SECT_FIELD): chance += 5; break; case(SECT_FOREST): break; case(SECT_HILLS): break; case(SECT_MOUNTAIN): chance -= 10; break; case(SECT_WATER_SWIM): chance = 0; break; case(SECT_WATER_NOSWIM): chance = 0; break; case(SECT_AIR): chance = 0; break; case(SECT_DESERT): chance += 10; break; } if (chance == 0) { send_to_char("There isn't any dirt to kick.\n\r",ch); return; } /* now the attack */ if (number_percent() < chance) { AFFECT_DATA af; act("$n is blinded by the dirt in $s eyes!",victim,NULL,NULL,TO_ROOM,0); act("$n kicks dirt in your eyes!",ch,NULL,victim,TO_VICT,1); damage(ch,victim,number_range(2,5),gsn_dirt,DAM_NONE,FALSE,0,-1); send_to_char("You can't see a thing!\n\r",victim); WAIT_STATE(ch,skill_table[gsn_dirt].beats); af.where = TO_AFFECTS; af.type = gsn_dirt; af.duration = 15; af.location = APPLY_PER; af.modifier = -4; af.bitvector = AFF_BLIND; affect_to_char(victim,&af); } else { damage(ch,victim,0,gsn_dirt,DAM_NONE,TRUE,0,-1); WAIT_STATE(ch,skill_table[gsn_dirt].beats); } }
void do_bash( CHAR_DATA *ch, char *argument ) { char arg[MIL]={'\0'}; CHAR_DATA *victim; int chance = 0; one_argument(argument,arg); if (IS_NULLSTR(arg)) { victim = ch->fighting; if (victim == NULL) { send_to_char("But you aren't fighting anyone!\n\r",ch); return; } } else if ((victim = get_char_room(ch,arg)) == NULL) { send_to_char("They aren't here.\n\r",ch); return; } if (victim->position < P_FIGHT) { act("You'll have to let $M get back up first.", ch,NULL,victim,TO_CHAR,1); return; } if (victim == ch) { send_to_char("You try to bash your brains out, but fail.\n\r",ch); return; } if (IS_AFFECTED(ch,AFF_CHARM) && ch->master == victim) { act("But $N is your friend!",ch,NULL,victim,TO_CHAR,1); return; } /* size */ if (ch->size < victim->size) chance += (ch->size - victim->size) * 15; else chance += (ch->size - victim->size) * 10; /* stats */ chance += get_curr_stat(ch,STAT_STR); chance -= get_curr_stat(victim,STAT_DEX); if (!IS_NPC(victim) && chance < get_skill(victim,gsn_dodge) ) { chance -= 3 * (get_skill(victim,gsn_dodge) - chance); } /* now the attack */ if (number_percent() < chance ) { act("$n sends you sprawling with a powerful bash!", ch,NULL,victim,TO_VICT,1); act("You slam into $N, and send $M flying!",ch,NULL,victim,TO_CHAR,0); act("$n sends $N sprawling with a powerful bash.", ch,NULL,victim,TO_NOTVICT,0); DAZE_STATE(victim, 3 * PULSE_VIOLENCE); WAIT_STATE(ch,skill_table[gsn_bash].beats); victim->position = P_REST; damage(ch,victim,number_range(2,2 + 2 * ch->size + chance/20),gsn_bash, DAM_BASH,FALSE, 0, -1); } else { damage(ch,victim,0,gsn_bash,DAM_BASH,FALSE, 0, -1); act("You fall flat on your face!", ch,NULL,victim,TO_CHAR,1); act("$n falls flat on $s face.", ch,NULL,victim,TO_NOTVICT,0); act("You evade $n's bash, causing $m to fall flat on $s face.", ch,NULL,victim,TO_VICT,1); ch->position = P_REST; damage(ch,ch,number_range(2,2 + 2 * ch->size + chance/20),gsn_bash, DAM_BASH,FALSE, 0, -1); WAIT_STATE(ch,skill_table[gsn_bash].beats * 3/2); } }
int mana_gain( CHAR_DATA *ch ) { int gain; int number; if (ch->in_room == NULL) return 0; if ( IS_NPC(ch) ) { gain = 5 + ch->level; switch (ch->position) { default: gain /= 2; break; case POS_SLEEPING: gain = 3 * gain/2; break; case POS_RESTING: break; case POS_FIGHTING: gain /= 3; break; } } else { gain = (get_curr_stat(ch,STAT_WIS) + get_curr_stat(ch,STAT_INT) + ch->level) / 2; number = number_percent(); if (number < get_skill(ch,gsn_meditation)) { gain += number * gain / 100; if (ch->mana < ch->max_mana) check_improve(ch,gsn_meditation,TRUE,8); } if (!class_table[ch->iclass].fMana) gain /= 2; switch ( ch->position ) { default: gain /= 4; break; case POS_SLEEPING: break; case POS_RESTING: gain /= 2; break; case POS_FIGHTING: gain /= 6; break; } if ( ch->pcdata->condition[COND_HUNGER] == 0 ) gain /= 2; if ( ch->pcdata->condition[COND_THIRST] == 0 ) gain /= 2; } gain = gain * ch->in_room->mana_rate / 100; if (ch->on != NULL && ch->on->item_type == ITEM_FURNITURE) gain = gain * ch->on->value[4] / 100; if ( IS_AFFECTED( ch, AFF_POISON ) ) gain /= 4; if (IS_AFFECTED(ch, AFF_PLAGUE)) gain /= 8; if (IS_AFFECTED(ch,AFF_HASTE) || IS_AFFECTED(ch,AFF_SLOW)) gain /=2 ; return UMIN(gain, ch->max_mana - ch->mana); }
/* * Regeneration stuff. */ int hit_gain( CHAR_DATA *ch ) { int gain; int number; if (ch->in_room == NULL) return 0; if ( IS_NPC(ch) ) { gain = 5 + ch->level; if (IS_AFFECTED(ch,AFF_REGENERATION)) gain *= 2; switch(ch->position) { default : gain /= 2; break; case POS_SLEEPING: gain = 3 * gain/2; break; case POS_RESTING: break; case POS_FIGHTING: gain /= 3; break; } } else { gain = UMAX(3,get_curr_stat(ch,STAT_CON) - 3 + ch->level/2); gain += class_table[ch->iclass].hp_max - 10; number = number_percent(); if (number < get_skill(ch,gsn_fast_healing)) { gain += number * gain / 100; if (ch->hit < ch->max_hit) check_improve(ch,gsn_fast_healing,TRUE,8); } switch ( ch->position ) { default: gain /= 4; break; case POS_SLEEPING: break; case POS_RESTING: gain /= 2; break; case POS_FIGHTING: gain /= 6; break; } if ( ch->pcdata->condition[COND_HUNGER] == 0 ) gain /= 2; if ( ch->pcdata->condition[COND_THIRST] == 0 ) gain /= 2; } gain = gain * ch->in_room->heal_rate / 100; if (ch->on != NULL && ch->on->item_type == ITEM_FURNITURE) gain = gain * ch->on->value[3] / 100; if ( IS_AFFECTED(ch, AFF_POISON) ) gain /= 4; if (IS_AFFECTED(ch, AFF_PLAGUE)) gain /= 8; if (IS_AFFECTED(ch,AFF_HASTE) || IS_AFFECTED(ch,AFF_SLOW)) gain /=2 ; return UMIN(gain, ch->max_hit - ch->hit); }
/* * Apply or remove an affect to a character. */ void affect_modify( CHAR_DATA *ch, AFFECT_DATA *paf, bool fAdd ) { OBJ_DATA *wield; int mod,i; mod = paf->modifier; if ( fAdd ) { SET_BIT( ch->affected_by, paf->bitvector ); SET_BIT( ch->affected_by_2, paf->bitvector_2 ); } else { REMOVE_BIT( ch->affected_by, paf->bitvector ); REMOVE_BIT( ch->affected_by_2, paf->bitvector_2 ); mod = 0 - mod; } switch ( paf->location ) { default: bug( "Affect_modify: unknown location %d.", paf->location ); return; case APPLY_NONE: break; case APPLY_STR: ch->mod_stat[STAT_STR] += mod; break; case APPLY_DEX: ch->mod_stat[STAT_DEX] += mod; break; case APPLY_INT: ch->mod_stat[STAT_INT] += mod; break; case APPLY_WIS: ch->mod_stat[STAT_WIS] += mod; break; case APPLY_CON: ch->mod_stat[STAT_CON] += mod; break; case APPLY_CHR: ch->mod_stat[STAT_CHR] += mod; break; case APPLY_LUK: ch->mod_stat[STAT_LUK] += mod; break; case APPLY_AGI: ch->mod_stat[STAT_AGI] += mod; break; case APPLY_SEX: ch->sex += mod; break; case APPLY_CLASS: break; case APPLY_LEVEL: break; case APPLY_AGE: break; case APPLY_HEIGHT: break; case APPLY_WEIGHT: break; case APPLY_HIT: ch->max_hit += mod; break; case APPLY_STAMINA: ch->max_stamina += mod; break; case APPLY_GOLD: break; case APPLY_EXP: break; case APPLY_AC: for (i = 0; i < 4; i ++) ch->armor[i] += mod; break; case APPLY_HITROLL: ch->hitroll += mod; break; case APPLY_DAMROLL: ch->damroll += mod; break; case APPLY_SPELL: apply_spell( ch, mod ); break; case APPLY_SKILL: if ( !IS_NPC(ch) ) { if ( mod >= 0 ) { if ( ch->pcdata->skill_mod[slot_lookup(mod)] > 0 ) ch->pcdata->skill_mod[slot_lookup(mod)] += 5; } else { if ( ch->pcdata->skill_mod[slot_lookup(abs(mod))] > 0 ) ch->pcdata->skill_mod[slot_lookup(abs(mod))] -= 5; } } break; } /* * Check for weapon wielding. * Guard against recursion (for weapons with affects). */ if ( !IS_NPC(ch) && ( wield = get_eq_char( ch, WEAR_WIELD ) ) != NULL && get_obj_weight(wield) > str_app[get_curr_stat(ch,STAT_STR)].wield ) { static int depth; if ( depth == 0 ) { depth++; act( "You drop $p.", ch, wield, NULL, TO_CHAR ); act( "$n drops $p.", ch, wield, NULL, TO_ROOM ); obj_from_char( wield ); obj_to_room( wield, ch->in_room ); depth--; } } return; }
//http://code.killer.mud.pl/p/killer-mud/issues/5/ void track_new(CHAR_DATA *ch, int skill, char *argument) { char buf [ MAX_STRING_LENGTH ]; char *messages_czas1[] = { "¶wie¿e", "¶wie¿e", "lekko zatarte", "zatarte", "zatarte", "zatarte", "ledwo rozpoznawalne", "ledwo rozpoznawalne" }; char *messages_czas2[] = { "¶wie¿e", "¶wie¿e", "lekko zatarte", "zatarte", "zatarte", "mocno zatarte", "ledwo rozpoznawalne", "ledwo rozpoznawalne" }; char *messages_czas3[] = { "bardzo ¶wie¿e", "ca³kiem ¶wie¿e", "bardzo lekko zatarte", "lekko zatarte", "zatarte", "mocno zatarte", "ledwo rozpoznawalne", "prawie nierozpoznawalne" }; TRACK_DATA* td = ch->in_room->track_data; if(!td) { act("$n klêka i zaczyna z uwag± przygl±daæ siê ¶ladom.",ch,NULL,NULL,TO_ROOM); act("Klêkasz, przygl±dasz siê ¶ladom, ale nie znajdujesz ¿adnych tropów.",ch,NULL,NULL,TO_CHAR); WAIT_STATE( ch, skill_table[gsn_track].beats ); return; } //cleanup_track_data(ch->in_room); int track_cnt = URANGE( 1, ( (number_range(1, MAX_TRACK_LEN) * skill)/100 + (number_range(1, MAX_TRACK_LEN / 6) * get_curr_stat(ch,STAT_INT)/6)/OLD_28_VALUE/6 ) , MAX_TRACK_LEN ); int i = 0; int succ = 0; // if(debug ==1) bugf("track_cnt %d", track_cnt); while(td) { i++; if(i > track_cnt) break; if ((number_range(1, 100) > skill/20) && is_name( argument, td->ch->ss_data ? td->ch->short_descr : td->ch->name ) ) { int roznica = current_time - td->czas; // if(debug ==1) bugf("roznica %d", roznica); //skill = 1 - 36 sekund, 75 - 3600s - im lepszy skill, tym wiêcej ¶ladów (czas) if(roznica / 96 <= skill) { int czas_message = URANGE(0, roznica / 400, 7) ; char* vdir_name = td->kierunek == -1 ? "do nik±d" : (td->inout == 0 ? dir_name2[td->kierunek] : dir_name_dir[td->kierunek]); char* vinout = td->inout == 0 ? ", prowadz±ce tu," : ", wychodz±ce st±d,"; //skill 0 do 95 //skill/27 0 do 3.52 //kolejno: 0 27 53 81 inf switch(skill/27) { case 0: sprintf( buf, "Znajdujesz jakie¶ ¶lady $Z."); break; case 1: sprintf( buf, "Znajdujesz %s ¶lady $Z.", messages_czas1[czas_message]); break; case 2: sprintf( buf, "Znajdujesz %s ¶lady $Z.", messages_czas2[czas_message]); break; case 3: sprintf( buf, "Znajdujesz %s%s ¶lady $Z prowadz±ce %s.", messages_czas3[czas_message], vinout, vdir_name ); break; default: sprintf( buf, "Znajdujesz %s%s ¶lady $Z prowadz±ce %s.", messages_czas3[czas_message], vinout, vdir_name ); break; } succ=1; act( buf, ch, NULL, td->ch, TO_CHAR ); } } td = td->previous; } if(succ == 0) { act("$n klêka i zaczyna z uwag± przygl±daæ siê ¶ladom.",ch,NULL,NULL,TO_ROOM); act("Klêkasz, przygl±dasz siê ¶ladom, ale nie znajdujesz ¿adnych tropów.",ch,NULL,NULL,TO_CHAR); check_improve(ch, NULL, gsn_track, FALSE, 12); WAIT_STATE( ch, skill_table[gsn_track].beats ); return; } check_improve(ch, NULL, gsn_track, TRUE, 9); WAIT_STATE( ch, skill_table[gsn_track].beats ); }
/* checks for skill improvement */ void check_improve( CHAR_DATA *ch, int sn, bool success, int multiplier ) { int inum; float chance; char buf[100]; if (IS_NPC(ch)) return; if (IS_AFFECTED(ch,AFF_CALM)) return; if (ch->level < skill_table[sn].skill_level[ch->Class()->GetIndex()] || ch->pcdata->learned[sn] <= 10 || ch->pcdata->learned[sn] >= 100) return; /* skill is not known */ /* check to see if the character has a chance to learn */ chance = 8 * int_app[get_curr_stat(ch,STAT_INT)].learn; chance /= ( multiplier * 4); chance += ch->level * 2; if (IS_SET(ch->act,PLR_MORON)) chance /= 4; if (is_affected(ch,gsn_synaptic_enhancement)) chance *= 1.5; if (is_affected(ch,gsn_synaptic_impairment)) chance /= 2; if (number_range(1,1000) > chance) return; /* now that the character has a CHANCE to learn, see if they really have */ if (success) { chance = URANGE(5,100 - ch->pcdata->learned[sn], 95); if (number_percent() < chance) { if (IS_SET(ch->comm,COMM_ANSI) && ch->pcdata->learned[sn]<99) { sprintf(buf,"[1;33mYou have become better at %s![0m\n\r", skill_table[sn].name); } else if (!IS_SET(ch->comm,COMM_ANSI) && ch->pcdata->learned[sn]<99) { sprintf(buf,"You have become better at %s!\n\r", skill_table[sn].name); } else if (IS_SET(ch->comm,COMM_ANSI) && ch->pcdata->learned[sn]==99) { sprintf(buf,"[1;33mYou have perfected %s![0m\n\r", skill_table[sn].name); } else if (!IS_SET(ch->comm,COMM_ANSI) && ch->pcdata->learned[sn]==99) { sprintf(buf,"You have perfected %s!\n\r", skill_table[sn].name); } send_to_char(buf,ch); ch->pcdata->learned[sn]++; gain_exp(ch, 4); } } else { chance = URANGE(5,ch->pcdata->learned[sn]/2,30); inum=number_range(1,3); if (number_percent() < chance) { if (IS_SET(ch->comm,COMM_ANSI) && (ch->pcdata->learned[sn]+inum)<100) { sprintf(buf, "[1;33mYou learn from your mistakes, and your %s skill improves.[0m\n\r", skill_table[sn].name); } else if (!IS_SET(ch->comm,COMM_ANSI) && (ch->pcdata->learned[sn]+inum)<100) { sprintf(buf, "You learn from your mistakes, and your %s skill improves.\n\r", skill_table[sn].name); } else if (IS_SET(ch->comm,COMM_ANSI) && ch->pcdata->learned[sn]+inum==100) { sprintf(buf, "[1;33mYou learn from your mistakes, and manage to perfect %s![0m\n\r", skill_table[sn].name); } else if (!IS_SET(ch->comm,COMM_ANSI) && ch->pcdata->learned[sn]+inum==100) { sprintf(buf,"You learn from your mistakes, and manage to perfect %s!\n\r", skill_table[sn].name); } send_to_char(buf,ch); ch->pcdata->learned[sn] += inum; ch->pcdata->learned[sn] = UMIN(ch->pcdata->learned[sn],100); gain_exp(ch, 4); } } }
/* * Advancement stuff. */ void Character::advance_level( bool hide ) { char buf[MAX_STRING_LENGTH]; int add_hp, add_mana, add_move, dracnum, add_prac; this->pcdata->last_level = ( this->played + (int) (current_time - this->logon) ) / 3600; /* sprintf( buf, "the %s", title_table [this->class_num] [this->level] [this->sex == SEX_FEMALE ? 1 : 0] ); set_title( this, buf ); */ add_hp = con_app[get_curr_stat(this,STAT_CON)].hitp + number_range( class_table[this->class_num].hp_min, class_table[this->class_num].hp_max ); add_mana = number_range(2,(2*get_curr_stat(this,STAT_INT) + get_curr_stat(this,STAT_WIS))/5); if (!class_table[this->class_num].fMana) add_mana /= 2; add_move = number_range( 1, (get_curr_stat(this,STAT_CON) + get_curr_stat(this,STAT_DEX))/6 ); add_prac = wis_app[get_curr_stat(this,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 ); this->max_hit += add_hp; this->max_mana += add_mana; this->max_move += add_move; this->practice += add_prac; this->train += 1; this->pcdata->perm_hit += add_hp; this->pcdata->perm_mana += add_mana; this->pcdata->perm_move += add_move; if (this->level == 10 && (this->race == race_lookup("draconian"))) { /* if (this->alignment > 500) dracnum = number_range(0, 4); else if (this->alignment < 500) dracnum = number_range(10, 14); else dracnum = number_range(5, 9); */ dracnum = number_range(0,14); this->drac = dracnum; sprintf(buf, "You scream in agony as %s scales pierce your tender skin!\n\r", draconian_table[this->drac].colour); send_to_char(buf,this); if (this->perm_stat[STAT_STR] < 25) this->perm_stat[STAT_STR]++; else this->train++; if (this->perm_stat[draconian_table[this->drac].attr_prime] < 25) this->perm_stat[draconian_table[this->drac].attr_prime]++; else this->train++; } if (!hide) { sprintf(buf, "{BYou have leveled!{x\n\r" "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, this ); } return; }
void herb_to_char( CHAR_DATA *ch, HERB_IN_ROOM_DATA *herb) { OBJ_DATA *obj; char text[ MAX_INPUT_LENGTH ]; char herb_name[ MAX_INPUT_LENGTH ]; int skill; obj = create_object( get_obj_index( 6 ), FALSE ); if ( !obj ) { return; } skill = get_skill( ch, gsn_herbs_knowledge ); //Drake: Dorzucam sell_extracta bo zbyt du¿e dysproporcje by³y miêdzy skillami zarobkowymi. Jak kiedy¶ wejdzie alchemia to siê wywali (?). obj->wear_flags = ITEM_TAKE | ITEM_HOLD; EXT_SET_BIT( obj->extra_flags, ITEM_SELL_EXTRACT ); obj->item_type = ITEM_HERB; /* * condition * im wyzsze wyszkolenie i trudnosc ziola tym wieksza szansa * na jakosc 95 */ obj->condition = UMIN( number_range( herb_table[herb->herb].difficult / 2 + skill / 2, 120 ), 95 ); /** * pozostale 10 zalezy od szczescia, * uwaga moze wyjsc poza 100, dlatego potem normalizacja */ if ( get_curr_stat( ch, STAT_LUC ) > number_range( MAX_STATS / 10, MAX_STATS ) ) { obj->condition += number_range( 0, 10 ); } obj->condition = UMIN( obj->condition, 100 ); obj->value[ 0 ] = herb->herb; //numerek ziola w tabeli //modyfikator ceny w zaleznosci od trudnosci 1.05 - 3.5 obj->cost = herb_table[herb->herb].cost * ( herb_table[herb->herb].difficult / ( 20 + herb_table[herb->herb].difficult / 5 ) +1 ); obj->rent_cost = 1; obj->weight = number_range(1,2); //NA RAZIE IDA PRAWDZIWE NAZWY free_string( obj->short_descr ); obj->short_descr = str_dup( herb_table[herb->herb].name ); //Drake: Doda³em dorzucanie 'zio³a i zio³a' do nazwy zbieranego zielska, w celu ³atwiejszego sprzedawania/pakowania. sprintf ( herb_name, "%s zio³o zio³a", herb_table[herb->herb].name ); free_string( obj->name ); obj->name = str_dup( herb_name ); free_string( obj->name2 ); obj->name2 = str_dup( herb_table[herb->herb].name2 ); free_string( obj->name3 ); obj->name3 = str_dup( herb_table[herb->herb].name3 ); free_string( obj->name4 ); obj->name4 = str_dup( herb_table[herb->herb].name4 ); free_string( obj->name5 ); obj->name5 = str_dup( herb_table[herb->herb].name5 ); free_string( obj->name6 ); obj->name6 = str_dup( herb_table[herb->herb].name6 ); free_string( obj->description ); sprintf( text, "Widzisz tu %s.", herb_table[herb->herb].name4 ); obj->description = str_dup( text ); free_string( obj->item_description ); obj->item_description = str_dup( capitalize( herb_table[herb->herb].description )); gether_comunicate( ch, obj, TRUE); obj_to_char( obj, ch ); return; }