/* share out experience among guild memberships */ void gain_experience(int amount) { int i,count=0,share; Player.xp += (long) amount; gain_level(); /* actually, check to see if should gain level */ for(i=0; i<NUMRANKS; i++) if (Player.guildxp[i] > 0) count++; share = amount/(max(count,1)); for(i=0; i<NUMRANKS; i++) if (Player.guildxp[i] > 0) Player.guildxp[i]+=share; }
/* i have condensed this function to just three states: MOB_FIGHTING, * MOB_RESTING/ MOB_SLEEPING, and MOB_STANDING. each of these three states * will call it's appropriate function. */ void int_group_handler( NPC_GROUP_DATA * ngroup ) { CHAR_DATA *follower = NULL; CHAR_DATA *leader = ngroup->leader; DL_LIST *follower_ptr; // short followers_want = GRP_STATE_NO_CHANGE; short leader_wants = GRP_STATE_NO_CHANGE; short group_count = 1; // start with leader char monbuf[MSL]; if ( leader == NULL ) { monitor_chan( "No Leader in NPC_GROUP", MONITOR_MOB ); return; } // check for followers needs for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next ) { // check for needing healing, levelling follower = (CHAR_DATA *)follower_ptr->this_one; group_count++; continue; } // check for leader's needs if ( leader->hit < leader->max_hit * 25 / 100 ) { leader_wants = GRP_STATE_CRIT_HEAL; } else if ( leader->mana < leader->max_mana * 25 / 100 ) { leader_wants = GRP_STATE_CRIT_MANA; } else if ( leader->hit < leader->max_hit * 60 / 100 ) { leader_wants = GRP_STATE_NORM_HEAL; } else if ( leader->mana < leader->max_mana * 50 / 100 ) { leader_wants = GRP_STATE_NORM_MANA; } else if ( able_to_level( leader ) ) { leader_wants = GRP_STATE_LEVELING; } snprintf( monbuf, MSL, "NPC Group Handler, Leader is %s, state is %s", ngroup->leader->name.c_str(), group_state_table[ngroup->state] ); monitor_chan( monbuf, MONITOR_MOB ); switch ( ngroup->state ) { case GRP_STATE_CRIT_HEAL: case GRP_STATE_CRIT_MANA: case GRP_STATE_NORM_HEAL: case GRP_STATE_NORM_MANA: { bool everyone_ready = TRUE; bool room_ready = FALSE; // ready_heal_room( leader ); if ( ( leader->mana < leader->max_mana * 85 / 100 ) || ( leader->hit < leader->max_hit * 85 / 100 ) ) { everyone_ready = FALSE; if ( ( ( room_ready = ready_heal_room( leader ) ) == TRUE ) || ( leader->mana < leader->max_mana * 20 / 100 ) ) { do_sleep( leader, "" ); } } else { do_stand( leader, "" ); } for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next ) { follower = (CHAR_DATA *)follower_ptr->this_one; if ( ( follower->mana < follower->max_mana * 75 / 100 ) || ( follower->hit < follower->max_hit * 75 / 100 ) ) { everyone_ready = FALSE; do_sleep( follower, "" ); } else { do_stand( follower, "" ); } } if ( everyone_ready == TRUE ) { ngroup->state = GRP_STATE_IDLE; } break; } case GRP_STATE_FIGHT: { // violence_update will handle if ( ( leader_wants < GRP_STATE_HUNTING ) || ( leader->fighting == NULL ) ) { bool someone_still_fighting = FALSE; ngroup->state = GRP_STATE_FLEE; for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next ) { follower = (CHAR_DATA *)follower_ptr->this_one; if ( follower->fighting != NULL ) { do_flee( follower, "" ); someone_still_fighting = TRUE; } } if ( someone_still_fighting == FALSE ) { ngroup->state = GRP_STATE_REFORM; } if ( leader->fighting != NULL ) { do_flee( leader, "" ); } } break; } case GRP_STATE_FLEE: { bool someone_still_fighting = FALSE; for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next ) { follower = (CHAR_DATA *)follower_ptr->this_one; if ( follower->fighting != NULL ) { do_flee( follower, "" ); someone_still_fighting = TRUE; } } if ( leader->fighting != NULL ) { do_flee( leader, "" ); someone_still_fighting = TRUE; } if ( someone_still_fighting == FALSE ) { ngroup->state = GRP_STATE_REFORM; } break; } case GRP_STATE_IDLE: { // check_re_equip( leader ); // check_rewield( leader ); if ( leader_wants < GRP_STATE_NO_CHANGE ) { ngroup->state = leader_wants; break; } else if ( number_percent( ) < 40 ) { select_target( ngroup->leader ); ngroup->state = GRP_STATE_HUNTING; break; } } case GRP_STATE_HUNTING: { // poll followers later short move_dir; if ( leader->fighting != NULL ) { ngroup->state = GRP_STATE_FIGHT; break; } if ( leader->hunting == NULL ) { // snprintf( monbuf, MSL, "Leader %s not hunting anything in GRP_STATE_HUNTING", // leader->name ); // monitor_chan( monbuf, MONITOR_MOB ); select_target( ngroup->leader ); break; } if ( leader->in_room == leader->hunting->in_room ) { ngroup->state = GRP_STATE_FIGHT; one_hit( leader, leader->hunting, TYPE_UNDEFINED ); break; } move_dir = h_find_dir( leader->in_room, leader->hunting->in_room, HUNT_WORLD | HUNT_OPENDOOR | HUNT_UNLOCKDOOR | HUNT_PICKDOOR ); if ( move_dir < 0 ) // can't get there from here { ngroup->state = GRP_STATE_LOST; break; } hunt_move( leader, move_dir ); break; } case GRP_STATE_LEVELING: { char_from_room( leader ); char_to_room( leader, get_room_index( 3758 ) ); if ( able_to_level( leader ) ) { gain_level( leader ); } for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next ) { follower = (CHAR_DATA *)follower_ptr->this_one; if ( able_to_level( follower ) ) { gain_level( follower ); } } ngroup->state = GRP_STATE_IDLE; break; } case GRP_STATE_REFORM: { bool all_are_here = TRUE; for ( follower_ptr = ngroup->first_follower; follower_ptr; follower_ptr = follower_ptr->next ) { follower = (CHAR_DATA *)follower_ptr->this_one; if ( follower->in_room != leader->in_room ) { short move_dir; all_are_here = FALSE; move_dir = h_find_dir( follower->in_room, leader->in_room, HUNT_WORLD | HUNT_OPENDOOR | HUNT_UNLOCKDOOR | HUNT_PICKDOOR ); if ( move_dir < 0 ) // can't get there from here { ngroup->state = GRP_STATE_LOST; break; } hunt_move( follower, move_dir ); } } if ( all_are_here == TRUE ) { ngroup->state = GRP_STATE_IDLE; } break; } } }
void mob_is_standing( CHAR_DATA * ch ) { short dir; CHAR_DATA *vch; CHAR_DATA *tch; list<CHAR_DATA *>::iterator li; bool ready = TRUE; bool prey_still_exist = FALSE; int number_got_up = 0; int number_of_group = 1; int number_of_other_group = 1; /* * get a light source */ if ( ch->in_room->light <= 0 ) { if ( ch->mana >= mana_cost( ch, skill_lookup( "continual light" ) ) ) { do_cast( ch, "'continual light'" ); do_get( ch, "all" ); do_wear( ch, "all" ); return; } } if ( ( IS_AFFECTED( ch, AFF_POISON ) ) || ( IS_AFFECTED( ch, AFF_BLIND ) ) ) { if ( IS_AFFECTED( ch, AFF_POISON ) ) if ( ch->mana >= mana_cost( ch, skill_lookup( "cure poison" ) ) ) do_cast( ch, "'cure poison'" ); if ( IS_AFFECTED( ch, AFF_BLIND ) ) if ( ch->mana >= mana_cost( ch, skill_lookup( "cure blindness" ) ) ) do_cast( ch, "'cure blindness'" ); return; } /* * is anyone in group being attacked? if so, assist! */ /* * -leaders will be forced to rescue in the 'mob_is_fighting' function * * already so no need to check for it here */ for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room ) { if ( ( is_same_group( ch, vch ) ) && ( vch->fighting != NULL ) && ( vch != ch ) ) { do_assist( ch, "" ); return; } } if ( ch->leader == NULL ) { for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room ) { if ( is_same_group( ch, vch ) && ( ch != vch ) ) { number_of_group = number_of_group + 1; } } if ( number_of_group < 4 ) { for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room ) { if ( vch->leader != NULL ) continue; if ( ( vch != ch ) && ( IS_NPC( vch ) ) && ( AI_MOB(vch) ) && ( !is_same_group( ch, vch ) ) && ( vch->position == POS_STANDING ) && ( ( vch->get_level("psuedo") - ch->get_level("psuedo") <= 20 && vch->get_level("psuedo") - ch->get_level("psuedo") >= -20 ) || ( ch->get_level("psuedo") - vch->get_level("psuedo") <= 20 && ch->get_level("psuedo") - vch->get_level("psuedo") >= -20 ) ) && ( can_see( vch, ch ) ) && ( can_see( ch, vch ) ) ) { if ( vch->leader == NULL ) { for ( tch = vch->in_room->first_person; tch != NULL; tch = tch->next_in_room ) { if ( is_same_group( tch, vch ) && ( tch != vch ) ) { number_of_other_group = number_of_other_group + 1; } } } if ( number_of_group + number_of_other_group <= 4 ) { get_mob_group( ch, vch ); return; } } } } } /* * do you need to heal? */ if ( ch->hit < ch->max_hit * 85 / 100 ) { if ( ( ch->mana >= mana_cost( ch, skill_lookup( "heal" ) ) ) || ( ch->mana >= mana_cost( ch, skill_lookup( "cure critical" ) ) ) || ( ch->mana >= mana_cost( ch, skill_lookup( "cure serious" ) ) ) ) mob_regen_check( ch, NULL, FALSE ); /* * if leader is ready to move, just keep standing */ if ( ( ch->leader != NULL ) && ( ch->leader->in_room == ch->in_room ) && ( ch->leader->position == POS_STANDING ) && ( ch->leader->mana >= ch->leader->max_mana * 85 / 100 ) && ( ch->leader->hit >= ch->leader->max_hit * 85 / 100 ) ) return; else { if ( ch->mana >= ch->max_mana * 75 / 100 ) ready = ready_heal_room( ch ); if ( ready == TRUE ) do_sleep( ch, "" ); return; } } if ( ch->mana < ch->max_mana * 85 / 100 ) { do_sleep( ch, "" ); return; } /* * do you need to level? if you have a group leader, have the leader * * find a the trainer. if you are the leader just go and find the * * trainer */ // ZEN FIX Have them recall then hunt the room if ( able_to_level( ch ) ) { char_from_room( ch ); char_to_room( ch, get_room_index( 3758 ) ); gain_level( ch ); return; /* dir = h_find_dir ( get_room_index(ch->in_room->vnum), get_room_index(ROOM_VNUM_INT_HEAL), ch->hunt_flags ); if ( dir == -1 ) gain_level ( ch ); else { if ( ( ch->leader != NULL ) && ( ch->leader->in_room == ch->in_room ) ) { hunt_move ( ch->leader, dir ); end_hunt ( ch->leader ); return; } else { hunt_move ( ch, dir ); return; } } */ } /* * if you're leader and you don't need to gain level, does anyone else * * in the group? */ /* * actually, the above function will force the leader to find a trainer * * already. but since i don't want the leader to select a new target * * until the group gains the needed level, i'll put this check here */ for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room ) { if ( ( is_same_group( vch, ch ) ) && ( vch->in_room == ch->in_room ) && ( vch->leader == ch ) && ( able_to_level( vch ) ) ) { dir = h_find_dir( get_room_index( ch->in_room->vnum ), get_room_index( ROOM_VNUM_INT_HEAL ), ch->hunt_flags ); hunt_move( ch, dir ); return; } } /* * if noone needs to heal or gain level, then let's hunt! */ /* * by the way, only leaders will hunt. followers will just follow and * * assist when needed */ if ( ( ch->leader != NULL ) && ( ch->leader->in_room == ch->in_room ) && ( ch->hunting != NULL ) ) { end_hunt( ch ); } else if ( ( ch->leader != NULL ) && ( ch->leader->in_room == ch->in_room ) && ( ch->hunting == NULL ) ) { return; } else if ( is_group_leader( ch ) ) { for ( vch = ch->in_room->first_person; vch != NULL; vch = vch->next_in_room ) { if ( ( vch != ch ) && ( is_same_group( vch, ch ) ) && ( vch->position != POS_STANDING ) ) { get_up( vch, vch->position ); number_got_up = number_got_up + 1; } } if ( number_got_up != 0 ) return; } else { if ( ch->hunting != NULL ) { for ( li = char_list.begin(); li != char_list.end(); li++ ) { vch = *li; if ( vch == ch->hunting ) { prey_still_exist = TRUE; return; } } if ( prey_still_exist == FALSE ) { ch->hunting = NULL; } } if ( ch->hunting == NULL && ch->leader == NULL ) { select_target( ch ); return; } } /* * power_up_mob ( ch ); */ /* * if ( ch->leader != NULL * && ch->in_room != ch->leader->in_room ) * { * do_follow( ch, ch->name ); * } */ return; }
void game_loop() { int regen_timer = 0; _draw(); while (io::window_is_open() && _game_running) { if (!io::window_is_open()) break; bool do_update_action_list = false; int state = statestack_top(); if (get_action_list_size() == 0) { append_action_list(&player); for (size_t i = 0; i < current_dungeon->creatures.size(); i++) { append_action_list(current_dungeon->creatures.at(i)); } _regenerate_creatures(regen_timer); // Tick effects every turn. tick_effects(); // Update gas clouds and gas machines. update_gas_machines(current_dungeon); // Update stealth check_stealth(); // Respawn creatures if few enough. if (_count_enemies_in_current_dungeon() <= 3 && one_in(25)) { spawn_monsters(current_branch->name, current_dungeon, current_dungeon->level, random(0, 3), true); } // Increase turn count. turn_count++; } if (current_actor()->identity == IDENT_PLAYER) { int old_player_ap = player.ap; // Do this before taking action -> // Draws everything from the previous turn and also // shows all the previous turns messages. _draw(); if (state == STATE_READ_COMMAND) { _read_command(); } else if (state == STATE_EXAMINE || state == STATE_CAST_SPELL || state == STATE_ZAP_WAND) { _move_targeting_cursor(); } else if (state == STATE_CLOSE_DOOR || state == STATE_CHAT) { _select_direction(); } else if (state == STATE_TRAVEL) { _travel(); } do_update_action_list = old_player_ap != player.ap; if (do_update_action_list) { check_cloud_collisions(current_dungeon); // Check if player has gained a level. if (can_gain_level()) { gain_level(); } } } else { creature_t* actor = current_actor(); actor->update(); do_update_action_list = true; } if (do_update_action_list) { if (current_actor() && current_actor()->ap <= 0) { if (current_actor()->identity == IDENT_PLAYER) { tick_food_clock(); } // TODO: Regenerate creature here. current_actor()->ap += 100; remove_from_action_list(current_actor()); } sort_action_list(); } } }