--- deliantra/server/server/player.C 2008/04/30 06:40:28 1.192 +++ deliantra/server/server/player.C 2008/09/07 21:31:23 1.203 @@ -124,7 +124,10 @@ if (*buf == '%') { /* send one news */ if (size > 0) - draw_ext_info_format (NDI_UNIQUE | NDI_GREEN, 0, op, MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, "INFORMATION: %s\n%s", (char *)"%s\n%s", subject, news); /*send previously read news */ + draw_ext_info_format (NDI_UNIQUE | NDI_GREEN, 0, op, + MSG_TYPE_ADMIN, MSG_TYPE_ADMIN_NEWS, + "INFORMATION: %s\n%s", (char *)"%s\n%s", + subject, news); /*send previously read news */ strcpy (subject, buf + 1); strip_endline (subject); @@ -323,7 +326,7 @@ } ob->change_weapon (combat_ob ? combat_ob : ranged_ob); - ob->deactivate (); // change_Weapon activates, fix this better + ob->deactivate (); // change_weapon activates, fix this better } void @@ -347,7 +350,6 @@ gen_sp_armour = 10; bowtype = bow_normal; petmode = pet_normal; - listening = 10; usekeys = containers; peaceful = 1; /* default peaceful */ do_los = 1; @@ -867,15 +869,6 @@ if (ob->msg) ob->msg = 0; - /* We create this now because some of the unique maps will need it - * to save here. - */ - { - char buf[MAX_BUF]; - sprintf (buf, "%s/%s/%s", settings.localdir, settings.playerdir, &ob->name); - make_path_to_file (buf); - } - start_info (ob); CLEAR_FLAG (ob, FLAG_WIZ); give_initial_items (ob, ob->randomitems); @@ -887,20 +880,7 @@ * is one for this race */ if (*first_map_ext_path) - { - object *tmp; - char mapname[MAX_BUF]; - - snprintf (mapname, MAX_BUF - 1, "%s/%s", &first_map_ext_path, &ob->arch->archname); - tmp = object::create (); - EXIT_PATH (tmp) = mapname; - EXIT_X (tmp) = ob->x; - EXIT_Y (tmp) = ob->y; - ob->enter_exit (tmp); /* we don't really care if it succeeded; - * if the map isn't there, then stay on the - * default initial map */ - tmp->destroy (); - } + ob->player_goto (format ("%s/%s", &first_map_ext_path, &ob->arch->archname), ob->x, ob->y); else LOG (llevDebug, "first_map_ext_path not set\n"); } @@ -1329,9 +1309,9 @@ /* use value density to decide what else to grab */ /* >=7 was >= op->contr->mode */ /* >=7 is the old standard setting. Now we take the last 4 bits - * and multiply them by 5, giving 0..15*5== 5..75 */ - wvratio = (op->contr->mode & PU_RATIO) * 5; - if ((query_cost (tmp, op, F_TRUE) * 100 / (tmp->weight * MAX (tmp->nrof, 1))) >= (unsigned int) wvratio) + */ + wvratio = op->contr->mode & PU_RATIO; + if (1000 * query_cost (tmp, op, F_TRUE) / tmp->total_weight () >= wvratio * 100) { CHK_PICK_PICKUP; #if 0 @@ -1445,6 +1425,7 @@ } } } + if (tmp == NULL && arrow == NULL) return find_arrow (op, type); @@ -2333,8 +2314,8 @@ { static dynbuf_text buf; - buf << "---- R.I.P. ----\n\n"; - op->name; + buf << "---- R.I.P. ----\n\n" + << op->name; if (op->type == PLAYER) buf << " the " << op->contr->title; @@ -2546,40 +2527,55 @@ if (op->stats.food < 0 && op->stats.hp >= 0) { - object *tmp, *flesh = 0; + object *flesh = 0; - for (tmp = op->inv; tmp; tmp = tmp->below) + for_inv_removable (op, tmp) { - if (!QUERY_FLAG (tmp, FLAG_UNPAID)) + if (QUERY_FLAG (tmp, FLAG_UNPAID)) + continue; + + if (tmp->type == FOOD || tmp->type == DRINK || tmp->type == POISON) { - if (tmp->type == FOOD || tmp->type == DRINK || tmp->type == POISON) - { - new_draw_info (NDI_UNIQUE, 0, op, "You blindly grab for a bite of food."); - manual_apply (op, tmp, 0); - if (op->stats.food >= 0 || op->stats.hp < 0) - break; - } - else if (tmp->type == FLESH) - flesh = tmp; - } /* End if paid for object */ - } /* end of for loop */ + op->statusmsg ("You blindly grab for a bite of food. " + "H"); + manual_apply (op, tmp, 0); + + if (op->stats.food >= 0 || op->stats.hp < 0) + break; + } + else if (tmp->type == FLESH) + flesh = tmp; + } /* If player is still starving, it means they don't have any food, so * eat flesh instead. */ if (op->stats.food < 0 && op->stats.hp >= 0 && flesh) { - new_draw_info (NDI_UNIQUE, 0, op, "You blindly grab for a bite of food."); + op->statusmsg ("You blindly grab for a bite of food. " + "H"); manual_apply (op, flesh, 0); } + + // If player is still starving, alert him! + if (op->stats.food < 0) + op->failmsg ("You are starving! " + "H"); } if (op->stats.food < 0) { - op->stats.hp += op->stats.food; + op->stats.hp += op->stats.food; op->stats.food = 0; + + if (op->stats.hp < 0) + { + op->contr->killer = archetype::get ("killer_starvation"); + op->contr->killer->destroy (); + } } + /* killer should be set here already */ if (op->stats.hp < 0 && !QUERY_FLAG (op, FLAG_WIZ)) kill_player (op); } @@ -2658,12 +2654,6 @@ command_kill_pets (op, 0); - if (op->stats.food < 0) - { - op->contr->killer = archetype::get ("killer_starvation"); - op->contr->killer->destroy (); - } - op->contr->play_sound (sound_find ("player_dies")); /* save the map location for corpse, gravestone */ @@ -2781,6 +2771,7 @@ } } } + /* If no stat lost, tell the player. */ if (!lost_a_stat) { @@ -2794,19 +2785,16 @@ new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you feel a holy presence protecting you."); } #else - new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you" " feel a holy presence protecting you from losing yourself completely."); + new_draw_info (NDI_UNIQUE, 0, op, "For a brief moment you feel a holy presence protecting you from losing yourself completely."); #endif /* Put a gravestone up where the character 'almost' died. List the * exp loss on the stone. */ tmp = arch_to_object (archetype::find ("gravestone")); - sprintf (buf, "%s's gravestone", &op->name); - tmp->name = buf; - sprintf (buf, "%s's gravestones", &op->name); - tmp->name_pl = buf; - sprintf (buf, "RIP\nHere rests the hero %s the %s,\n" "who was killed\n" "by %s.\n", &op->name, op->contr->title, op->contr->killer_name ()); - tmp->msg = buf; + tmp->name = format ("%s's gravestone", &op->name); + tmp->name_pl = format ("%s's gravestones", &op->name); + tmp->msg = format ("RIP\nHere rests the hero %s the %s,\nwho was killed\nby %s.\n", &op->name, op->contr->title, op->contr->killer_name ()); tmp->x = op->x, tmp->y = op->y; insert_ob_in_map (tmp, op->map, NULL, 0); @@ -2839,10 +2827,24 @@ cure_disease (op, 0, 0); /* remove any disease */ + // remove all spell effects that are active + // to avoid long-term effects such as word-of-recall + for (object *item = op->inv; item; ) + { + object *next = item->below; + + if (item->type == SPELL_EFFECT && item->active) + item->destroy (); + + item = next; + } + /*add_exp(op, (op->stats.exp * -0.20)); */ apply_death_exp_penalty (op); + if (op->stats.food < 100) op->stats.food = 900; + op->stats.hp = op->stats.maxhp; op->stats.sp = MAX (op->stats.sp, op->stats.maxsp); op->stats.grace = MAX (op->stats.grace, op->stats.maxgrace); @@ -3073,13 +3075,13 @@ void do_hidden_move (object *op) { - int hide = 0, num = random_roll (0, 19, op, PREFER_LOW); - object *skop; + int hide = 0; if (!op || !op->map) return; - skop = find_obj_by_type_subtype (op, SKILL, SK_HIDING); + object *skop = find_obj_by_type_subtype (op, SKILL, SK_HIDING); + int num = random_roll (0, 19, op, PREFER_LOW); /* its *extremely* hard to run and sneak/hide at the same time! */ if (op->type == PLAYER && op->contr->run_on) @@ -3099,6 +3101,7 @@ if ((op->type == PLAYER && hide < -10) || ((op->invisible -= num) <= 0)) { make_visible (op); + if (op->type == PLAYER) new_draw_info (NDI_UNIQUE, 0, op, "You moved out of hiding! You are visible!"); }