void check_waterwheel_charging(OBJ_DATA & obj) { static const int DurationStep(20); // Verify that the object is a crystal and the waterwheel is in a room if (obj.contains == NULL || obj.contains->material != material_lookup("crystal") || obj.contains->item_type != ITEM_GEM) return; // Verify that the waterwheel is in a room ROOM_INDEX_DATA * room(get_room_for_obj(obj)); if (room == NULL) return; // Check for existing effect AFFECT_DATA * paf(get_obj_affect(obj.contains, gsn_constructwaterwheel)); if (paf == NULL) { // First time, add the effect AFFECT_DATA af = {0}; af.where = TO_OBJECT; af.type = gsn_constructwaterwheel; af.level = obj.level; af.duration = DurationStep; af.bitvector = ITEM_HUM; affect_to_obj(obj.contains, &af); if (room != NULL) act("Inside the waterwheel, $p begins to emit a faint humming sound.", room->people, obj.contains, NULL, TO_ALL); return; } // Increase the duration int maxCharge(obj.level * 5); if (paf->duration + DurationStep < maxCharge) { paf->duration += DurationStep; act("$p's hum intensifies slightly as it absorbs the river's energy.", room->people, obj.contains, NULL, TO_ALL); return; } paf->duration = maxCharge; if (number_bits(1) == 0) act("From inside the waterwheel, $p hums steadily, unable to absorb any more power.", room->people, obj.contains, NULL, TO_ALL); }
/* * 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 death_cry( CHAR_DATA *ch ) { ROOM_INDEX_DATA *was_in_room; char *msg; int door; int vnum; vnum = 0; msg = NULL; while(msg == NULL) switch ( number_bits(4)) { case 0: msg = "$n hits the ground ... DEAD."; break; case 1: if (ch->material == 0) { msg = "$n splatters blood on your clothes."; break; } case 2: if (IS_SET(ch->parts,PART_GUTS)) { msg = "$n spills $s guts all over the floor."; vnum = OBJ_VNUM_GUTS; } break; case 3: if (IS_SET(ch->parts,PART_HEAD)) { msg = "$n's severed head plops on the ground."; vnum = OBJ_VNUM_SEVERED_HEAD; } break; case 4: if (IS_SET(ch->parts,PART_HEART)) { msg = "$n's heart is torn from $s chest."; vnum = OBJ_VNUM_TORN_HEART; } break; case 5: if (IS_SET(ch->parts,PART_ARMS)) { msg = "$n's arm is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_ARM; } break; case 6: if (IS_SET(ch->parts,PART_LEGS)) { msg = "$n's leg is sliced from $s dead body."; vnum = OBJ_VNUM_SLICED_LEG; } break; case 7: if (IS_SET(ch->parts,PART_BRAINS)) { msg = "$n's head is shattered, and $s brains splash all over you."; vnum = OBJ_VNUM_BRAINS; } } act( msg, ch, NULL, NULL, TO_ROOM, 0 ); if ( vnum != 0 ) { char buf[MSL]={'\0'}; OBJ_DATA *obj; char *name; name = IS_NPC(ch) ? ch->short_descr : ch->name; obj = create_object( get_obj_index( vnum ) ); obj->timer = number_range( 4, 7 ); snprintf( buf, sizeof(buf), obj->short_descr, name ); PURGE_DATA( obj->short_descr ); obj->short_descr = str_dup( buf ); snprintf( buf, sizeof(buf), obj->description, name ); PURGE_DATA( obj->description ); obj->description = str_dup( buf ); if (obj->item_type == ITEM_FOOD) { if (IS_SET(ch->form,FORM_POISON)) obj->value[3] = 1; else if (!IS_SET(ch->form,FORM_EDIBLE)) obj->item_type = ITEM_TRASH; } if(!str_cmp(ch->material, "flesh") && !str_cmp(ch->material, "none") && (material_lookup(ch->material) != material_lookup("unknown"))) { PURGE_DATA( obj->material ); obj->material = str_dup(ch->material); } if(IS_SET(ch->act, ACT_UMBRA)) obj_to_plane(obj, 1); if(IS_SET(ch->act, ACT_DREAMING)) obj_to_plane(obj, 2); obj_to_room( obj, ch->in_room ); } was_in_room = ch->in_room; for ( door = 0; door <= 5; door++ ) { EXIT_DATA *pexit; if ( ( pexit = was_in_room->exit[door] ) != NULL && pexit->u1.to_room != NULL && pexit->u1.to_room != was_in_room ) { ch->in_room = pexit->u1.to_room; act( msg, ch, NULL, NULL, TO_ROOM, 0 ); } } ch->in_room = was_in_room; return; }
/* * Make a corpse out of a character. */ void make_corpse( CHAR_DATA *ch ) { char buf[MSL]={'\0'}; OBJ_DATA *corpse; OBJ_DATA *obj; OBJ_DATA *obj_next; char *name; if ( IS_NPC(ch) ) { name = ch->short_descr; corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_NPC)); corpse->timer = number_range( 3, 6 ); if ( ch->dollars > 0 ) { obj_to_obj( create_money( ch->dollars, ch->cents ), corpse ); ch->cents = 0; ch->dollars = 0; } corpse->cost = 0; } else { name = ch->name; corpse = create_object(get_obj_index(OBJ_VNUM_CORPSE_PC)); corpse->timer = number_range( 25, 40 ); corpse->owner = NULL; if (ch->dollars > 1 || ch->cents > 1) { obj_to_obj(create_money(ch->dollars / 2, ch->cents/2), corpse); ch->cents = 0; ch->dollars = 0; } corpse->cost = 0; } snprintf( buf, sizeof(buf), corpse->short_descr, name ); PURGE_DATA( corpse->short_descr ); corpse->short_descr = str_dup( buf ); snprintf( buf, sizeof(buf), corpse->description, name ); PURGE_DATA( corpse->description ); corpse->description = str_dup( buf ); PURGE_DATA( corpse->full_desc ); corpse->full_desc = str_dup( Format("The corpse of someone who in life looked like:\n\r%s", ch->description) ); if(!str_cmp(ch->material, "flesh") && !str_cmp(ch->material, "none") && (material_lookup(ch->material) != material_lookup("unknown"))) { PURGE_DATA( corpse->material ); corpse->material = str_dup(ch->material); } for ( obj = ch->carrying; obj != NULL; obj = obj_next ) { obj_next = obj->next_content; obj_from_char( obj ); if (obj->item_type == ITEM_POTION) obj->timer = number_range(500,1000); if (obj->item_type == ITEM_SCROLL) obj->timer = number_range(1000,2500); if (IS_SET(obj->extra_flags,ITEM_ROT_DEATH)) { obj->timer = number_range(1,3); REMOVE_BIT(obj->extra_flags,ITEM_ROT_DEATH); } REMOVE_BIT(obj->extra_flags,ITEM_VIS_DEATH); if(obj != NULL) { if(IS_SET(ch->act, ACT_UMBRA)) obj_to_plane(obj, 1); if(IS_SET(ch->act, ACT_DREAMING)) obj_to_plane(obj, 2); } obj_to_obj( obj, corpse ); } if(IS_SET(ch->act, ACT_UMBRA)) obj_to_plane(corpse, 1); if(IS_SET(ch->act, ACT_DREAMING)) obj_to_plane(corpse, 2); obj_to_room( corpse, ch->in_room ); return; }