Basically, remove as many as possible of the dependencies of the source files in the tools and classes folders on source files not in those folders. (With the exception that files in the classes folder may depend on files in the tools folder.) In this commit, several changes were made. - Project file modified, may need further modification. - Many files renamed to match the Mac version. - #include statements for system headers changed to use <> instead of "" (some already did, but many didn't). - xxx.h headers replaced with cxxx headers where appropriate. - Most sound-related variables moved from globvars.cpp to soundvars.cpp. - The files originally named graphutil and gutils have been merged. - Changed TRUE/FALSE to true/false. - Changed exlsound to soundtool and mostly removed dependencies on the main game files; the exception is that it still uses mainPtr (which probably can't be helped) and print_nums (which should probably be incorporated into the MessageBox string). - Possibly other things that were forgotten. For some reason this commit also includes changes recently committed into the branch for osx. git-svn-id: http://openexile.googlecode.com/svn/trunk@121 4ebdad44-0ea0-11de-aab3-ff745001d230
984 lines
25 KiB
C++
984 lines
25 KiB
C++
#include "pc.h" // party_record_type
|
|
#include "location.h" // location
|
|
//#include "boe.text.h" // add_string_to_buf
|
|
//#include "boe.main.h" // globals
|
|
#include "tools/soundtool.h" // play_sound
|
|
//#include "boe.combat.h" // hit_chance
|
|
//#include "boe.items.h" // place_item
|
|
//#include "boe.fields.h" // make_sfx
|
|
#include "tools/mathutil.h" // get_ran
|
|
//#include "boe.infodlg.h" // give_help
|
|
//#include "boe.party.h" // adjust_spell_menu
|
|
//#include "boe.itemdata.h" // return_dummy_item
|
|
//#include "boe.locutils.h" // is_container
|
|
//#include "globvar.h"
|
|
|
|
void pc_record_type::kill(short type)
|
|
{
|
|
short i = 24;
|
|
bool dummy, no_save = false;
|
|
location item_loc;
|
|
|
|
if (type >= 10)
|
|
{
|
|
type -= 10;
|
|
no_save = true;
|
|
}
|
|
|
|
if (type != 4)
|
|
i = hasAbilEquip(48); //check if has life saving items
|
|
else
|
|
i = hasAbilEquip(49); //check if has protection vs petrification items
|
|
|
|
short which_pc = getNum();
|
|
|
|
if ((no_save == false) && (type != 0) && (skills[SKILL_LUCK] > 0) &&
|
|
(get_ran(1,0,100) < hit_chance[skills[SKILL_LUCK]])) {
|
|
add_string_to_buf(" But you luck out! ");
|
|
cur_health = 0;
|
|
}
|
|
else if ((i == 24) || (type == 0)) {
|
|
if (combat_active_pc == which_pc)
|
|
combat_active_pc = 6;
|
|
|
|
for (i = 0; i < 24; i++)
|
|
equip[i] = false;
|
|
|
|
item_loc = (overall_mode >= MODE_COMBAT) ? pc_pos[which_pc] : c_town.p_loc;
|
|
|
|
if (type == 2)
|
|
make_sfx(item_loc.x,item_loc.y,3);
|
|
else if (type == 3)
|
|
make_sfx(item_loc.x,item_loc.y,6);
|
|
|
|
if (overall_mode != 0)
|
|
for (i = 0; i < 24; i++)
|
|
if (items[i].variety != 0) {
|
|
dummy = place_item(items[i],item_loc,true);
|
|
items[i].variety = 0;
|
|
}
|
|
if ((type == 2) || (type == 3))
|
|
play_sound(21);
|
|
if(type == 4){
|
|
play_sound(43);
|
|
sprintf ((char *) create_line, " %s is turned to stone. ",(char *) name);
|
|
add_string_to_buf((char *) create_line);
|
|
}
|
|
main_status = type;
|
|
pc_moves[which_pc] = 0;
|
|
}
|
|
else {
|
|
if (type == 4) {
|
|
sprintf ((char *) create_line, " %s is immune to petrification. ",(char *) name);
|
|
add_string_to_buf((char*) create_line); //inform of what has happened
|
|
}
|
|
else{
|
|
add_string_to_buf(" Life saved! ");
|
|
takeItem(i);
|
|
heal(200);
|
|
}
|
|
}
|
|
|
|
current_pc = first_active_pc();
|
|
|
|
if (current_pc > 5) {
|
|
for (i = 0; i < NUM_OF_PCS; i++)
|
|
if (adven[i].status > 0)
|
|
current_pc = i;
|
|
}
|
|
|
|
put_pc_screen();
|
|
set_stat_window(current_pc);
|
|
}
|
|
|
|
bool pc_record_type::runTrap(short trap_type, short trap_level, short diff)
|
|
{
|
|
short r1,skill,i,num_hits = 1,i_level;
|
|
short trap_odds[30] = {5,30,35,42,48, 55,63,69,75,77,
|
|
78,80,82,84,86, 88,90,92,94,96,98,99,99,99,99,99,99,99,99,99};
|
|
|
|
num_hits += trap_level;
|
|
|
|
if (trap_type == TRAP_RANDOM)
|
|
trap_type = get_ran(1,1,4);
|
|
|
|
/// ??? => no trap after all ;)
|
|
if (trap_type == 6)
|
|
return true;
|
|
|
|
i = statAdj(1);
|
|
|
|
if ((i_level = getProtLevel(42)) > 0)
|
|
i += i_level / 2;
|
|
|
|
skill = minmax(0, 20, skills[14] + skills[SKILL_LUCK] / 2 + 1 - c_town.difficulty + 2 * i);
|
|
|
|
r1 = get_ran(1,0,100) + diff;
|
|
// Nimble?
|
|
if (traits[TRAIT_NIMBLE] == true) r1 -= 6;
|
|
|
|
if (r1 < trap_odds[skill])
|
|
{
|
|
add_string_to_buf(" Trap disarmed. ");
|
|
return true;
|
|
}
|
|
else add_string_to_buf(" Disarm failed. ");
|
|
|
|
switch (trap_type)
|
|
{
|
|
case TRAP_BLADE:
|
|
for (i = 0; i < num_hits; i++)
|
|
{
|
|
add_string_to_buf(" A knife flies out! ");
|
|
damage(get_ran(2 + c_town.difficulty / 14,1,10),DAMAGE_WEAPON,-1);
|
|
}
|
|
break;
|
|
|
|
case TRAP_DART:
|
|
add_string_to_buf(" A dart flies out. ");
|
|
poison((3 + c_town.difficulty / 14) + (trap_level * 2));
|
|
break;
|
|
|
|
case TRAP_GAS:
|
|
add_string_to_buf(" Poison gas pours out. ");
|
|
adven.poison((2 + c_town.difficulty / 14) + trap_level * 2);
|
|
break;
|
|
|
|
case TRAP_EXPLOSION:
|
|
for (i = 0; i < num_hits; i++)
|
|
{
|
|
add_string_to_buf(" There is an explosion. ");
|
|
adven.damage(get_ran(3 + c_town.difficulty / 13,1,8), DAMAGE_FIRE);
|
|
}
|
|
break;
|
|
|
|
case TRAP_SLEEP_RAY:
|
|
add_string_to_buf(" A purple ray flies out. ");
|
|
sleep((200 + c_town.difficulty * 100) + (trap_level * 400),12,50);
|
|
break;
|
|
|
|
case TRAP_DRAIN_XP:
|
|
add_string_to_buf(" You feel weak. ");
|
|
experience = max(0, experience - (40 + trap_level * 30));
|
|
break;
|
|
|
|
case TRAP_ALERT:
|
|
add_string_to_buf(" An alarm goes off!!! ");
|
|
set_town_status(0);
|
|
break;
|
|
|
|
case TRAP_FLAMES:
|
|
add_string_to_buf(" Flames shoot from the walls. ");
|
|
adven.damage(get_ran(10 + trap_level * 5,1,8),DAMAGE_FIRE);
|
|
break;
|
|
|
|
case TRAP_DUMBFOUND:
|
|
add_string_to_buf(" You feel disoriented. ");
|
|
adven.dumbfound(2 + trap_level * 2);
|
|
break;
|
|
|
|
case TRAP_DISEASE:
|
|
add_string_to_buf(" You prick your finger. ");
|
|
disease((3 + c_town.difficulty / 14) + (trap_level * 2));
|
|
break;
|
|
|
|
case TRAP_DISEASE_ALL:
|
|
add_string_to_buf(" A foul substance sprays out.");
|
|
adven.disease((2 + c_town.difficulty / 14) + (trap_level * 2));
|
|
break;
|
|
|
|
default:
|
|
add_string_to_buf(" (ERROR: Unknown type of trap!)");
|
|
break;
|
|
}
|
|
|
|
put_pc_screen();
|
|
put_item_screen(stat_window,0);
|
|
return true;
|
|
}
|
|
|
|
short pc_record_type::statAdj(short which)
|
|
{
|
|
short tr;
|
|
|
|
tr = skill_bonus[skills[which]];
|
|
|
|
if (which == 2) {
|
|
if (traits[1] == true) tr++;
|
|
if (hasAbilEquip(40) < 24) tr++;
|
|
}
|
|
|
|
if (which == 0)
|
|
if (traits[8] == true) tr++;
|
|
if (hasAbilEquip(38) < 24)
|
|
tr++;
|
|
|
|
if (which == 1) {
|
|
if (hasAbilEquip(39) < 24)
|
|
tr++;
|
|
}
|
|
|
|
return tr;
|
|
}
|
|
|
|
void pc_record_type::giveXP(short amt)
|
|
{
|
|
short adjust,add_hp;
|
|
short xp_percent[30] = {150,120,100,90,80,70,60,50,50,50,
|
|
45,40,40,40,40,35,30,25,23,20,
|
|
15,15,15,15,15,15,15,15,15,15};
|
|
|
|
if (!isAlive()) return;
|
|
|
|
if (level > 49)
|
|
{
|
|
level = 50;
|
|
return;
|
|
}
|
|
|
|
if (amt > 200) { // debug
|
|
MessageBeep(MB_OK);
|
|
ASB("Oops! Too much xp!");
|
|
ASB("Report this!");
|
|
return;
|
|
}
|
|
|
|
if (amt < 0) { // debug
|
|
MessageBeep(MB_OK);
|
|
ASB("Oops! Negative xp!");
|
|
ASB("Report this!");
|
|
return;
|
|
}
|
|
|
|
if (level >= 40) adjust = 15;
|
|
else adjust = xp_percent[level / 2];
|
|
|
|
if ((amt > 0) && (level > 7))
|
|
{
|
|
if (get_ran(1,0,100) < xp_percent[level / 2]) amt--;
|
|
}
|
|
|
|
if (amt <= 0) return;
|
|
|
|
experience += (max(((amt * adjust) / 100), 0) * 100) / 100;
|
|
|
|
party.total_xp_gained += (max(((amt * adjust) / 100), 0) * 100) / 100;
|
|
|
|
if (experience < 0) {
|
|
MessageBeep(MB_OK);
|
|
ASB("Oops! Xp became negative somehow!");
|
|
ASB("Report this!");
|
|
experience = level * (get_tnl(this)) - 1;
|
|
return;
|
|
}
|
|
|
|
if (experience > 15000)
|
|
{
|
|
experience = 15000;
|
|
return;
|
|
}
|
|
|
|
while (experience >= (level * (get_tnl(this))))
|
|
{
|
|
play_sound(7);
|
|
level++;
|
|
|
|
sprintf ((char *) c_line, " %s is level %d! ",(char *) name, level);
|
|
add_string_to_buf((char *) c_line);
|
|
skill_pts += (level < 20) ? 5 : 4;
|
|
add_hp = (level < 26) ? get_ran(1,2,6) + skill_bonus[skills[0]]
|
|
: max (skill_bonus[skills[0]],0);
|
|
|
|
if (add_hp < 0) add_hp = 0;
|
|
max_health += add_hp;
|
|
|
|
if (max_health > 250) max_health = 250;
|
|
cur_health += add_hp;
|
|
|
|
if (cur_health > 250) cur_health = 250;
|
|
|
|
put_pc_screen();
|
|
}
|
|
}
|
|
|
|
void pc_record_type::drainXP(short how_much)
|
|
{
|
|
if (!isAlive()) return;
|
|
|
|
experience = max(experience - how_much, 0);
|
|
sprintf ((char *) c_line, " %s drained.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
}
|
|
|
|
void pc_record_type::restoreSP(short amt)
|
|
{
|
|
if (!isAlive()) return;
|
|
if (cur_sp > max_sp) return;
|
|
cur_sp += amt;
|
|
if (cur_sp > max_sp) cur_sp = max_sp;
|
|
}
|
|
|
|
void pc_record_type::cure(short amt)
|
|
{
|
|
if (!isAlive()) return;
|
|
|
|
if (status[STATUS_POISON] <= amt)
|
|
status[STATUS_POISON] = 0;
|
|
else
|
|
status[STATUS_POISON] -= amt;
|
|
|
|
one_sound(51);
|
|
}
|
|
|
|
void pc_record_type::curse(short how_much)
|
|
{
|
|
if (!isAlive()) return;
|
|
|
|
status[STATUS_BLESS] = max(status[STATUS_BLESS] - how_much, -8);
|
|
sprintf ((char *) c_line, " %s cursed.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
|
|
put_pc_screen();
|
|
give_help(59,0,0);
|
|
}
|
|
|
|
void pc_record_type::dumbfound(short how_much)
|
|
{
|
|
short r1;
|
|
|
|
if (!isAlive()) return;
|
|
|
|
r1 = get_ran(1,0,90);
|
|
|
|
if (hasAbilEquip(53) < 24) {
|
|
add_string_to_buf(" Ring of Will glows.");
|
|
r1 -= 10;
|
|
}
|
|
|
|
if (r1 < level)
|
|
how_much -= 2;
|
|
|
|
if (how_much <= 0) {
|
|
sprintf ((char *) c_line, " %s saved.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
return;
|
|
}
|
|
|
|
status[STATUS_DUMB] = min(status[STATUS_DUMB] + how_much, 8);
|
|
sprintf ((char *) c_line, " %s dumbfounded.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
|
|
one_sound(67);
|
|
put_pc_screen();
|
|
adjust_spell_menus();
|
|
give_help(28,0,0);
|
|
}
|
|
|
|
void pc_record_type::disease(short how_much)
|
|
{
|
|
short r1, tlevel;
|
|
|
|
if (!isAlive()) return;
|
|
|
|
r1 = get_ran(1,0,100);
|
|
|
|
if (r1 < level * 2)
|
|
how_much -= 2;
|
|
|
|
if (how_much <= 0)
|
|
{
|
|
sprintf ((char *) c_line, " %s saved.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
return;
|
|
}
|
|
|
|
if ((tlevel = getProtLevel(62)) > 0)
|
|
how_much -= tlevel / 2;
|
|
|
|
if ((traits[12] == true) && (how_much > 1)) how_much++;
|
|
if ((traits[12] == true) && (how_much == 1) && (get_ran(1,0,1) == 0)) how_much++;
|
|
|
|
status[STATUS_DISEASE] = min(status[STATUS_DISEASE] + how_much,8);
|
|
sprintf ((char *) c_line, " %s diseased.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
|
|
one_sound(66);
|
|
put_pc_screen();
|
|
give_help(29,0,0);
|
|
}
|
|
|
|
|
|
void pc_record_type::sleep(short how_much,short what_type,short adjust)
|
|
// higher adjust, less chance of saving
|
|
{
|
|
short r1, tlevel;
|
|
if (!isAlive()) return;
|
|
|
|
if (how_much == 0)
|
|
return;
|
|
|
|
if ((what_type == STATUS_ASLEEP) || (what_type == STATUS_PARALYZED)) { ////
|
|
if ((tlevel = getProtLevel(53)) > 0)
|
|
how_much -= tlevel / 2;
|
|
if ((tlevel = getProtLevel(54)) > 0)
|
|
how_much -= (what_type == STATUS_ASLEEP) ? tlevel : tlevel * 300;
|
|
|
|
}
|
|
|
|
r1 = get_ran(1,0,100) + adjust;
|
|
if (r1 < 30 + level * 2)
|
|
how_much = -1;
|
|
if ((what_type == STATUS_ASLEEP) && ((traits[7] > 0) || (status[STATUS_ASLEEP] < 0)))
|
|
how_much = -1;
|
|
if (how_much <= 0) {
|
|
sprintf ((char *) c_line, " %s resisted.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
return;
|
|
}
|
|
if (isAlive()) {
|
|
status[what_type] = how_much;
|
|
if (what_type == STATUS_ASLEEP)
|
|
sprintf ((char *) c_line, " %s falls asleep.",(char *) name);
|
|
else sprintf ((char *) c_line, " %s paralyzed.",(char *) name);
|
|
if (what_type == STATUS_ASLEEP)
|
|
play_sound(96);
|
|
else play_sound(90);
|
|
add_string_to_buf((char *) c_line);
|
|
pc_moves[getNum()] = 0;
|
|
}
|
|
put_pc_screen();
|
|
if (what_type == STATUS_ASLEEP)
|
|
give_help(30,0,0);
|
|
else give_help(32,0,0);
|
|
}
|
|
|
|
void pc_record_type::slow(short how_much)
|
|
{
|
|
if (!isAlive()) return;
|
|
|
|
status[STATUS_HASTE] = minmax(-8,8,status[STATUS_HASTE] - how_much);
|
|
if (how_much < 0)
|
|
sprintf ((char *) c_line, " %s hasted.",(char *) name);
|
|
else sprintf ((char *) c_line, " %s slowed.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
|
|
put_pc_screen();
|
|
if (how_much < 0)
|
|
give_help(35,0,0);
|
|
}
|
|
|
|
void pc_record_type::web(short how_much)
|
|
{
|
|
if (!isAlive()) return;
|
|
|
|
status[STATUS_WEBS] = min(status[STATUS_WEBS] + how_much,8);
|
|
sprintf ((char *) c_line, " %s webbed.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
one_sound(17);
|
|
|
|
put_pc_screen();
|
|
give_help(31,0,0);
|
|
}
|
|
|
|
void pc_record_type::acid(short how_much)
|
|
{
|
|
if (!isAlive()) return;
|
|
|
|
if (hasAbilEquip(36) < 24) {
|
|
sprintf ((char *) c_line, " %s resists acid.",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
return;
|
|
}
|
|
|
|
status[STATUS_ACID] += how_much;
|
|
sprintf ((char *) c_line, " %s covered with acid!",(char *) name);
|
|
add_string_to_buf((char *) c_line);
|
|
one_sound(42);
|
|
|
|
put_pc_screen();
|
|
}
|
|
|
|
void pc_record_type::heal(short amt)
|
|
{
|
|
if (!isAlive()) return;
|
|
if (cur_health > max_health) return;
|
|
|
|
cur_health += amt;
|
|
|
|
if (cur_health > max_health)
|
|
cur_health = max_health;
|
|
}
|
|
|
|
void pc_record_type::sortItems()
|
|
{
|
|
item_record_type store_item;
|
|
short item_priority[26] = {20,8,8,20,9, 9,3,2,1,0, 7,20,10,10,10, 10,10,10,5,6, 4,11,12,9,9, 9};
|
|
bool no_swaps = false, store_equip;
|
|
int i;
|
|
|
|
while (no_swaps == false) {
|
|
no_swaps = true;
|
|
for (i = 0; i < 23; i++)
|
|
if (item_priority[items[i + 1].variety] <
|
|
item_priority[items[i].variety]) {
|
|
no_swaps = false;
|
|
store_item = items[i + 1];
|
|
items[i + 1] = items[i];
|
|
items[i] = store_item;
|
|
store_equip = equip[i + 1];
|
|
equip[i + 1] = equip[i];
|
|
equip[i] = store_equip;
|
|
if (weap_poisoned == i + 1)
|
|
weap_poisoned--;
|
|
else if (weap_poisoned == i)
|
|
weap_poisoned++;
|
|
}
|
|
}
|
|
}
|
|
|
|
short pc_record_type::getNum()
|
|
{
|
|
short i;
|
|
|
|
for (i = 0; i < NUM_OF_PCS; i++)
|
|
{
|
|
if (&adven[i] == this) break;;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
bool pc_record_type::giveToPC(item_record_type item, bool print_result)
|
|
{
|
|
short free_space;
|
|
char announce_string[60];
|
|
|
|
if (item.variety == 0)
|
|
return true;
|
|
|
|
if (item.variety == 3) {
|
|
party.gold += item.item_level;
|
|
ASB("You get some gold.");
|
|
return true;
|
|
}
|
|
if (item.variety == 11) {
|
|
party.food += item.item_level;
|
|
ASB("You get some food.");
|
|
return true;
|
|
}
|
|
if (item_weight(item) > amountCanCarry() - amountCarried()) {
|
|
if (print_result == true) {
|
|
MessageBeep(MB_OK);
|
|
ASB("Item too heavy to carry.");
|
|
}
|
|
return false;
|
|
}
|
|
if (((free_space = hasSpace()) == 24) || (!isAlive()))
|
|
return false;
|
|
else {
|
|
item.item_properties = item.item_properties & 253; // not property
|
|
item.item_properties = item.item_properties & 247; // not contained
|
|
items[free_space] = item;
|
|
|
|
|
|
if (print_result == 1) {
|
|
if (stat_window == getNum())
|
|
put_item_screen(stat_window,0);
|
|
}
|
|
if (in_startup_mode == false) {
|
|
if (item.isIdent() == false)
|
|
sprintf((char *) announce_string," %s gets %s.",name,item.name);
|
|
else sprintf((char *) announce_string," %s gets %s.",name,item.full_name);
|
|
if (print_result)
|
|
add_string_to_buf((char *)announce_string);
|
|
}
|
|
|
|
combineThings();
|
|
sortItems();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// returnes equipped protection level of specified abil, or -1 if no such abil is equipped
|
|
short pc_record_type::getProtLevel(short abil)
|
|
{
|
|
for (int i = 0; i < 24; i++)
|
|
if ((items[i].variety != 0) && (items[i].ability == abil) && (equip[i] == true))
|
|
return items[i].ability_strength;
|
|
return (-1);
|
|
}
|
|
|
|
short pc_record_type::hasAbilEquip(short abil)
|
|
{
|
|
short i = 0;
|
|
|
|
while (((items[i].variety == 0) || (items[i].ability != abil)
|
|
|| (equip[i] == false)) && (i < 24))
|
|
i++;
|
|
return i;
|
|
}
|
|
|
|
short pc_record_type::hasAbil(short abil)
|
|
{
|
|
short i = 0;
|
|
|
|
while (((items[i].variety == 0) || (items[i].ability != abil)) && (i < 24)) i++;
|
|
return i;
|
|
}
|
|
|
|
short pc_record_type::amountCanCarry()
|
|
{
|
|
return 100 + (15 * min(skills[0],20)) + ((traits[8] == 0) ? 0 : 30)
|
|
+ ((traits[14] == 0) ? 0 : -50);
|
|
}
|
|
|
|
short pc_record_type::amountCarried()
|
|
{
|
|
short i, storage = 0;
|
|
bool airy = false, heavy = false;
|
|
|
|
for (i = 0; i < 24; i++)
|
|
if (items[i].variety > 0)
|
|
{
|
|
storage += item_weight(items[i]);
|
|
if (items[i].ability == 44) airy = true;
|
|
if (items[i].ability == 45) heavy = true;
|
|
}
|
|
|
|
if (airy) storage -= 30;
|
|
if (heavy) storage += 30;
|
|
if (storage < 0) storage = 0;
|
|
|
|
return storage;
|
|
}
|
|
|
|
short pc_record_type::hasSpace()
|
|
{
|
|
int i = 0;
|
|
|
|
while (i < 24)
|
|
{
|
|
if (items[i].variety == 0)
|
|
return i;
|
|
i++;
|
|
}
|
|
|
|
return 24;
|
|
}
|
|
|
|
// returns 1 if OK, 2 if no room, 3 if not enough cash, 4 if too heavy, 5 if too many of item
|
|
short pc_record_type::okToBuy(short cost, item_record_type item)
|
|
{
|
|
int i;
|
|
|
|
if ((item.variety != 3) && (item.variety != 11)) {
|
|
for (i = 0; i < 24; i++)
|
|
if ((items[i].variety > 0) && (items[i].type_flag == item.type_flag)
|
|
&& (items[i].charges > 123))
|
|
return 5;
|
|
|
|
if (hasSpace() == 24) return 2;
|
|
if (item_weight(item) > amountCanCarry() - amountCarried()) return 4;
|
|
}
|
|
|
|
if (party.takeGold(cost, false) == false)
|
|
return 3;
|
|
return 1;
|
|
}
|
|
|
|
void pc_record_type::takeItem(short which_item)
|
|
//short pc_num,which_item; // if which_item > 30, don't update stat win, item is which_item - 30
|
|
{
|
|
int i;
|
|
bool do_print = true;
|
|
|
|
if (which_item >= 30) {
|
|
do_print = false;
|
|
which_item -= 30;
|
|
}
|
|
|
|
if ((weap_poisoned == which_item) && (status[0] > 0)) {
|
|
add_string_to_buf(" Poison lost. ");
|
|
status[0] = 0;
|
|
}
|
|
|
|
if ((weap_poisoned > which_item) && (status[0] > 0))
|
|
weap_poisoned--;
|
|
|
|
for (i = which_item; i < 23; i++) {
|
|
items[i] = items[i + 1];
|
|
equip[i] = equip[i + 1];
|
|
}
|
|
items[23] = return_dummy_item();
|
|
equip[23] = false;
|
|
|
|
if ((stat_window == getNum()) && (do_print))
|
|
put_item_screen(stat_window,1);
|
|
}
|
|
|
|
void pc_record_type::removeCharge(short which_item)
|
|
{
|
|
if (items[which_item].charges > 0)
|
|
{
|
|
items[which_item].charges--;
|
|
if (items[which_item].charges == 0) takeItem(which_item);
|
|
}
|
|
|
|
if (stat_window == getNum())
|
|
put_item_screen(stat_window,1);
|
|
|
|
}
|
|
|
|
void pc_record_type::enchantWeapon(short item_hit, short enchant_type, short new_val)
|
|
{
|
|
char store_name[60];
|
|
|
|
if ((items[item_hit].isMagic()) || (items[item_hit].ability != 0)) return;
|
|
|
|
items[item_hit].item_properties |= 4;
|
|
|
|
switch (enchant_type) {
|
|
case 0:
|
|
sprintf((char *)store_name,"%s (+1)", items[item_hit].full_name);
|
|
items[item_hit].bonus++;
|
|
items[item_hit].value = new_val;
|
|
break;
|
|
case 1:
|
|
sprintf((char *)store_name,"%s (+2)", items[item_hit].full_name);
|
|
items[item_hit].bonus += 2;
|
|
items[item_hit].value = new_val;
|
|
break;
|
|
case 2:
|
|
sprintf((char *)store_name,"%s (+3)", items[item_hit].full_name);
|
|
items[item_hit].bonus += 3;
|
|
items[item_hit].value = new_val;
|
|
break;
|
|
case 3:
|
|
sprintf((char *)store_name,"%s (F)", items[item_hit].full_name);
|
|
items[item_hit].ability = 110;
|
|
items[item_hit].ability_strength = 5;
|
|
items[item_hit].charges = 8;
|
|
break;
|
|
case 4:
|
|
sprintf((char *)store_name,"%s (F!)", items[item_hit].full_name);
|
|
items[item_hit].value = new_val;
|
|
items[item_hit].ability = 1;
|
|
items[item_hit].ability_strength = 5;
|
|
break;
|
|
case 5:
|
|
sprintf((char *)store_name,"%s (+5)", items[item_hit].full_name);
|
|
items[item_hit].value = new_val;
|
|
items[item_hit].bonus += 5;
|
|
break;
|
|
case 6:
|
|
sprintf((char *)store_name,"%s (B)", items[item_hit].full_name);
|
|
items[item_hit].bonus++;
|
|
items[item_hit].ability = 71;
|
|
items[item_hit].ability_strength = 5;
|
|
items[item_hit].magic_use_type = 0;
|
|
items[item_hit].charges = 8;
|
|
break;
|
|
default:
|
|
strcpy(store_name, items[item_hit].full_name);
|
|
break;
|
|
}
|
|
if (items[item_hit].value > 15000)
|
|
items[item_hit].value = 15000;
|
|
if (items[item_hit].value < 0)
|
|
items[item_hit].value = 15000;
|
|
strcpy(items[item_hit].full_name,store_name);
|
|
}
|
|
|
|
void pc_record_type::equipItem(short item_num)
|
|
{
|
|
short num_equipped_of_this_type = 0;
|
|
short num_hands_occupied = 0;
|
|
short i;
|
|
short equip_item_type = 0;
|
|
|
|
if ((overall_mode == MODE_COMBAT) && (items[item_num].variety == 11))
|
|
add_string_to_buf("Equip: Not in combat");
|
|
else {
|
|
// unequip
|
|
if (equip[item_num] == true) {
|
|
if ((equip[item_num] == true) &&
|
|
(items[item_num].isCursed()))
|
|
add_string_to_buf("Equip: Item is cursed. ");
|
|
else {
|
|
equip[item_num] = false;
|
|
add_string_to_buf("Equip: Unequipped");
|
|
if ((weap_poisoned == item_num) && (status[0] > 0)) {
|
|
add_string_to_buf(" Poison lost. ");
|
|
status[0] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
else { // equip
|
|
if (equippable[items[item_num].variety] == false)
|
|
add_string_to_buf("Equip: Can't equip this item.");
|
|
else {
|
|
for (i = 0; i < 24; i++)
|
|
if (equip[i] == true) {
|
|
if (items[i].variety == items[item_num].variety)
|
|
num_equipped_of_this_type++;
|
|
num_hands_occupied = num_hands_occupied + num_hands_to_use[items[i].variety];
|
|
}
|
|
|
|
|
|
equip_item_type = excluding_types[items[item_num].variety];
|
|
// Now if missile is already equipped, no more missiles
|
|
if (equip_item_type > 0) {
|
|
for (i = 0; i < 24; i++)
|
|
if ((equip[i] == true) && (excluding_types[items[i].variety] == equip_item_type)) {
|
|
add_string_to_buf("Equip: You have something of");
|
|
add_string_to_buf(" this type equipped.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
if ((is_combat()) && (items[item_num].variety == 13))
|
|
add_string_to_buf("Equip: Not armor in combat");
|
|
else if ((2 - num_hands_occupied) < num_hands_to_use[items[item_num].variety])
|
|
add_string_to_buf("Equip: Not enough free hands");
|
|
else if (num_that_can_equip[items[item_num].variety] <= num_equipped_of_this_type)
|
|
add_string_to_buf("Equip: Can't equip another");
|
|
else {
|
|
equip[item_num] = true;
|
|
add_string_to_buf("Equip: OK");
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
if (stat_window == getNum())
|
|
put_item_screen(stat_window,1);
|
|
}
|
|
|
|
|
|
void pc_record_type::dropItem(short item_num, location where_drop)
|
|
{
|
|
short choice, how_many = 0;
|
|
item_record_type item_store;
|
|
bool take_given_item = true;
|
|
location loc;
|
|
|
|
item_store = items[item_num];
|
|
|
|
if ((equip[item_num] == true) && (items[item_num].isCursed()))
|
|
add_string_to_buf("Drop: Item is cursed. ");
|
|
else switch (overall_mode) {
|
|
case 0:
|
|
choice = fancy_choice_dialog(1093,0);
|
|
if (choice == 1)
|
|
return;
|
|
add_string_to_buf("Drop: OK");
|
|
if ((item_store.type_flag > 0) && (item_store.charges > 1)) {
|
|
how_many = get_num_of_items(item_store.charges);
|
|
if (how_many == item_store.charges)
|
|
takeItem(item_num);
|
|
else items[item_num].charges -= how_many;
|
|
}
|
|
else takeItem(item_num);
|
|
break;
|
|
|
|
case 5: case 15:
|
|
loc = where_drop;
|
|
if ((item_store.type_flag > 0) && (item_store.charges > 1)) {
|
|
how_many = get_num_of_items(item_store.charges);
|
|
if (how_many <= 0)
|
|
return;
|
|
if (how_many < item_store.charges)
|
|
take_given_item = false;
|
|
item_store.charges = how_many;
|
|
}
|
|
if (is_container(loc) == true)
|
|
item_store.item_properties = item_store.item_properties | 8;
|
|
if (place_item(item_store,loc,false) == false) {
|
|
add_string_to_buf("Drop: Too many items on ground");
|
|
item_store.item_properties = item_store.item_properties & 247; // not contained
|
|
}
|
|
else {
|
|
if (item_store.isContained())
|
|
add_string_to_buf("Drop: Item put away");
|
|
else add_string_to_buf("Drop: OK");
|
|
items[item_num].charges -= how_many;
|
|
if (take_given_item) takeItem(item_num);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void pc_record_type::giveThing(short item_num)
|
|
{
|
|
short who_to,how_many = 0;
|
|
item_record_type item_store;
|
|
bool take_given_item = true;
|
|
short pc_num = getNum();
|
|
|
|
if ((equip[item_num] == true) && (items[item_num].isCursed()))
|
|
add_string_to_buf("Give: Item is cursed. ");
|
|
else {
|
|
item_store = items[item_num];
|
|
who_to = char_select_pc(1,1,"Give item to who?");
|
|
if ((overall_mode == MODE_COMBAT) && (adjacent(pc_pos[pc_num],pc_pos[who_to]) == false)) {
|
|
add_string_to_buf("Give: Must be adjacent.");
|
|
who_to = 6;
|
|
}
|
|
|
|
if ((who_to < 6) && (who_to != pc_num)
|
|
&& ((overall_mode != MODE_COMBAT) || (adjacent(pc_pos[pc_num],pc_pos[who_to]) == true))) {
|
|
if ((item_store.type_flag > 0) && (item_store.charges > 1)) {
|
|
how_many = get_num_of_items(item_store.charges);
|
|
if (how_many == 0)
|
|
return;
|
|
if (how_many < item_store.charges)
|
|
take_given_item = false;
|
|
items[item_num].charges -= how_many;
|
|
item_store.charges = how_many;
|
|
}
|
|
if (adven[who_to].giveToPC(item_store,0) == true) {
|
|
if (take_given_item) takeItem(item_num);
|
|
}
|
|
else {
|
|
if (adven[who_to].hasSpace() == 24)
|
|
ASB("Can't give: PC has max. # of items.");
|
|
else ASB("Can't give: PC carrying too much.");
|
|
if (how_many > 0)
|
|
items[item_num].charges += how_many;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void pc_record_type::combineThings()
|
|
{
|
|
int i,j,test;
|
|
|
|
for (i = 0; i < 24; i++) {
|
|
if ((items[i].variety > 0) && (items[i].type_flag > 0) && (items[i].isIdent()))
|
|
{
|
|
for (j = i + 1; j < 24; j++)
|
|
if ((items[j].variety > 0) && (items[j].type_flag == items[i].type_flag) && (items[j].isIdent()))
|
|
{
|
|
add_string_to_buf("(items combined)");
|
|
test = items[i].charges + items[j].charges;
|
|
if (test > 125) {
|
|
items[i].charges = 125;
|
|
ASB("(Can have at most 125 of any item.");
|
|
}
|
|
else items[i].charges += items[j].charges;
|
|
if (equip[j] == true) {
|
|
equip[i] = true;
|
|
equip[j] = false;
|
|
}
|
|
takeItem(30 + j);
|
|
}
|
|
}
|
|
if ((items[i].variety > 0) && (items[i].charges < 0))
|
|
items[i].charges = 1;
|
|
}
|
|
}
|