135 lines
5.3 KiB
C
135 lines
5.3 KiB
C
/*
|
|
CrossFire, A Multiplayer game for X-windows
|
|
|
|
Copyright (C) 2007 Mark Wedel & Crossfire Development Team
|
|
Copyright (C) 1992 Frank Tore Johansen
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
The authors can be reached via e-mail at crossfire-devel@real-time.com
|
|
*/
|
|
/** @file book.c
|
|
* The implementation of the Book class of objects.
|
|
*/
|
|
#include <global.h>
|
|
#include <ob_methods.h>
|
|
#include <ob_types.h>
|
|
#include <sounds.h>
|
|
#include <sproto.h>
|
|
|
|
static method_ret book_type_apply(ob_methods *context, object *op,
|
|
object *applier, int aflags);
|
|
|
|
/**
|
|
* Initializer for the BOOK object type.
|
|
*/
|
|
void init_type_book(void) {
|
|
register_apply(BOOK, book_type_apply);
|
|
}
|
|
|
|
/**
|
|
* Handles reading a regular (ie not containing a spell) book.
|
|
* @param context The method context
|
|
* @param op The Book to apply
|
|
* @param applier The object attempting to apply the Book
|
|
* @param aflags Special flags (always apply/unapply)
|
|
* @retval METHOD_UNHANDLED If the Book wasn't read by a player
|
|
* @retval METHOD_OK If applier was a player
|
|
*/
|
|
static method_ret book_type_apply(ob_methods *context, object *op, object *applier, int aflags) {
|
|
int lev_diff;
|
|
object *skill_ob;
|
|
|
|
if (applier->type != PLAYER)
|
|
return METHOD_UNHANDLED;
|
|
|
|
if (QUERY_FLAG(applier, FLAG_BLIND)&&!QUERY_FLAG(applier, FLAG_WIZ)) {
|
|
draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_ERROR,
|
|
"You are unable to read while blind.", NULL);
|
|
return METHOD_OK;
|
|
}
|
|
if (op->msg == NULL) {
|
|
draw_ext_info_format(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
|
|
"You open the %s and find it empty.",
|
|
"You open the %s and find it empty.",
|
|
op->name);
|
|
return METHOD_OK;
|
|
}
|
|
|
|
/* need a literacy skill to read stuff! */
|
|
skill_ob = find_skill_by_name(applier, op->skill);
|
|
if (!skill_ob) {
|
|
draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
|
|
"You are unable to decipher the strange symbols.", NULL);
|
|
return METHOD_OK;
|
|
}
|
|
lev_diff = op->level-(skill_ob->level+5);
|
|
if (!QUERY_FLAG(applier, FLAG_WIZ) && lev_diff > 0) {
|
|
if (lev_diff < 2)
|
|
draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
|
|
"This book is just barely beyond your comprehension.", NULL);
|
|
else if (lev_diff < 3)
|
|
draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
|
|
"This book is slightly beyond your comprehension.", NULL);
|
|
else if (lev_diff < 5)
|
|
draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
|
|
"This book is beyond your comprehension.", NULL);
|
|
else if (lev_diff < 8)
|
|
draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
|
|
"This book is quite a bit beyond your comprehension.", NULL);
|
|
else if (lev_diff < 15)
|
|
draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
|
|
"This book is way beyond your comprehension.", NULL);
|
|
else
|
|
draw_ext_info(NDI_UNIQUE, 0, applier, MSG_TYPE_APPLY, MSG_TYPE_APPLY_FAILURE,
|
|
"This book is totally beyond your comprehension.", NULL);
|
|
return METHOD_OK;
|
|
}
|
|
|
|
/* Lauwenmark: Handle for plugin book event */
|
|
/*printf("Book apply: %s\n", tmp->name);
|
|
execute_event(tmp, EVENT_APPLY, op, NULL, SCRIPT_FIX_ALL);
|
|
printf("Book applied: %s\n", tmp->name);*/
|
|
{
|
|
char desc[MAX_BUF];
|
|
const readable_message_type *msgType = get_readable_message_type(op);
|
|
|
|
draw_ext_info_format(NDI_UNIQUE|NDI_NAVY, 0, applier, msgType->message_type, msgType->message_subtype,
|
|
"You open the %s and start reading.\n%s",
|
|
"You open the %s and start reading.\n%s",
|
|
ob_describe(op, applier, desc, sizeof(desc)), op->msg);
|
|
}
|
|
|
|
/* gain xp from reading */
|
|
if (!QUERY_FLAG(op, FLAG_NO_SKILL_IDENT)) {
|
|
/* only if not read before */
|
|
int exp_gain = calc_skill_exp(applier, op, skill_ob);
|
|
|
|
if (!QUERY_FLAG(op, FLAG_IDENTIFIED)) {
|
|
/*exp_gain *= 2; because they just identified it too */
|
|
SET_FLAG(op, FLAG_IDENTIFIED);
|
|
/* If in a container, update how it looks */
|
|
if (op->env)
|
|
esrv_update_item(UPD_FLAGS|UPD_NAME, applier, op);
|
|
else
|
|
applier->contr->socket.update_look = 1;
|
|
}
|
|
change_exp(applier, exp_gain, skill_ob->skill, 0);
|
|
/* so no more xp gained from this book */
|
|
SET_FLAG(op, FLAG_NO_SKILL_IDENT);
|
|
}
|
|
return METHOD_OK;
|
|
}
|