Add Give Equipment node for giving a specific PC an item,
possibly with modifiers (like equipping it)
This commit is contained in:
@@ -91,7 +91,7 @@ name
|
||||
level
|
||||
morale
|
||||
soul-crystal
|
||||
|
||||
give-item
|
||||
monst-target
|
||||
monst-attack
|
||||
monst-statistic
|
||||
|
||||
@@ -222,20 +222,20 @@ Unused
|
||||
Unused
|
||||
Special to Jump To
|
||||
--------------------
|
||||
Unused Node
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
Unused
|
||||
Give Equipment
|
||||
Unused
|
||||
Unused
|
||||
First part of message
|
||||
Second part of message
|
||||
Unused
|
||||
Special to call if inventory full
|
||||
Unused
|
||||
Which item
|
||||
Which enchantment (if weapon)
|
||||
Number of charges (-1 = default)
|
||||
ID? (-1 - normal, 0 - no, 1 - yes, 2 - full)
|
||||
Cursed? (-1 - default, 0 - no, 1 - yes)
|
||||
Equip? (-1 - no, 0 - soft, 1 - try, 2 - force)
|
||||
Special to Jump To
|
||||
--------------------
|
||||
Affect Monster Target
|
||||
|
||||
@@ -3254,6 +3254,31 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
// TODO: Verify this actually works! It's possible the monster ignores this and just recalculates its target each turn.
|
||||
dynamic_cast<cCreature*>(pc)->target = spec.ex1a;
|
||||
break;
|
||||
case eSpecType::GIVE_ITEM:
|
||||
if(pc_num >= 100) break;
|
||||
if(spec.ex1a >= 0 && spec.ex1a < univ.scenario.scen_items.size()) {
|
||||
cItem to_give = univ.scenario.scen_items[spec.ex1a];
|
||||
if(spec.ex1b >= 0 && spec.ex1b <= 6) {
|
||||
// TODO: This array and accompanying calculation is now duplicated here, in start_town_mode(), and in place_buy_button()
|
||||
const short aug_cost[10] = {4,7,10,8, 15,15,10, 0,0,0};
|
||||
int val = max(aug_cost[spec.ex1b] * 100, to_give.value * (5 + aug_cost[spec.ex1b]));
|
||||
to_give.enchant_weapon(eEnchant(spec.ex1b), val);
|
||||
}
|
||||
if(to_give.charges > 0 && spec.ex1c >= 0)
|
||||
to_give.charges = spec.ex1c;
|
||||
if(spec.ex2a == 1) to_give.ident = true;
|
||||
else if(spec.ex2a == 0) to_give.ident = false;
|
||||
if(spec.ex2b == 1) to_give.cursed = to_give.unsellable = true;
|
||||
else if(spec.ex2b == 0) to_give.cursed = to_give.unsellable = false;
|
||||
int equip_type = 0;
|
||||
if(spec.ex2c == 0) equip_type = GIVE_EQUIP_SOFT;
|
||||
else if(spec.ex2c == 1) equip_type = GIVE_EQUIP_TRY;
|
||||
else if(spec.ex2c >= 2) equip_type = GIVE_EQUIP_FORCE;
|
||||
for(i = 0; i < 6; i++)
|
||||
if(pc_num == 6 || pc_num == i)
|
||||
univ.party[i].give_item(to_give, equip_type | GIVE_ALLOW_OVERLOAD);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!");
|
||||
break;
|
||||
|
||||
@@ -445,9 +445,9 @@ int cParty::calc_day() const {
|
||||
return (age / 3700) + 1;
|
||||
}
|
||||
|
||||
bool cParty::give_item(cItem item,bool do_print) {
|
||||
bool cParty::give_item(cItem item,int flags) {
|
||||
for(int i = 0; i < 6; i++) {
|
||||
if(adven[i]->give_item(item,do_print))
|
||||
if(adven[i]->give_item(item,flags))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
void writeTo(std::ostream& file) const;
|
||||
void readFrom(std::istream& file);
|
||||
|
||||
bool give_item(cItem item,bool do_print);
|
||||
bool give_item(cItem item,int flags);
|
||||
bool forced_give(item_num_t item_num,eItemAbil abil,short dat = -1);
|
||||
bool has_abil(eItemAbil abil, short dat = -1);
|
||||
bool take_abil(eItemAbil abil, short dat = -1);
|
||||
|
||||
@@ -419,8 +419,14 @@ void cPlayer::sort_items() {
|
||||
}
|
||||
}
|
||||
|
||||
bool cPlayer::give_item(cItem item, bool do_print, bool allow_overload) {
|
||||
bool cPlayer::give_item(cItem item, int flags) {
|
||||
if(main_status != eMainStatus::ALIVE)
|
||||
return false;
|
||||
|
||||
short free_space;
|
||||
bool do_print = flags & GIVE_DO_PRINT;
|
||||
bool allow_overload = flags & GIVE_ALLOW_OVERLOAD;
|
||||
int equip_type = flags & GIVE_EQUIP_FORCE;
|
||||
|
||||
if(item.variety == eItemType::NO_ITEM)
|
||||
return true;
|
||||
@@ -476,6 +482,59 @@ bool cPlayer::give_item(cItem item, bool do_print, bool allow_overload) {
|
||||
print_result(announce.str());
|
||||
}
|
||||
|
||||
if(equip_type != 0 && equippable.count(item.variety)) {
|
||||
if(!equip_item(free_space, false) && equip_type != GIVE_EQUIP_SOFT) {
|
||||
int exclude = 0;
|
||||
if(num_hands_to_use.count(item.variety))
|
||||
exclude = 100;
|
||||
else exclude = excluding_types[item.variety];
|
||||
int rem1 = 24, rem2 = 24;
|
||||
for(int i = 0; i < 24; i++) {
|
||||
if(i == free_space) continue;
|
||||
if(!equip[i]) continue;
|
||||
int check_exclude = 0;
|
||||
if(num_hands_to_use.count(items[i].variety))
|
||||
check_exclude = 100;
|
||||
else check_exclude = excluding_types[items[i].variety];
|
||||
if(exclude != check_exclude) continue;
|
||||
if(exclude == 0 && item.variety != items[i].variety)
|
||||
continue;
|
||||
if(exclude == 100) {
|
||||
if(rem1 == 24) {
|
||||
if(item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED || rem2 < 24)
|
||||
rem1 = i;
|
||||
if(rem1 < 24) continue;
|
||||
}
|
||||
if(rem2 == 24) {
|
||||
if(item.variety == eItemType::SHIELD || item.variety == eItemType::SHIELD_2 || rem1 < 24)
|
||||
rem2 = i;
|
||||
}
|
||||
} else if(rem1 < 24)
|
||||
rem1 = i;
|
||||
}
|
||||
bool can_rem1 = rem1 < 24 && (!items[rem1].cursed || equip_type == GIVE_EQUIP_FORCE);
|
||||
bool can_rem2 = rem2 < 24 && (!items[rem2].cursed || equip_type == GIVE_EQUIP_FORCE);
|
||||
if(exclude == 100) {
|
||||
if(item.variety == eItemType::TWO_HANDED) {
|
||||
if(can_rem1) equip[rem1] = false;
|
||||
if(can_rem2) equip[rem2] = false;
|
||||
} else if(item.variety == eItemType::ONE_HANDED) {
|
||||
if(can_rem1) equip[rem1] = false;
|
||||
else if(can_rem2) equip[rem2] = false;
|
||||
} else { // It's a shield
|
||||
if(can_rem2 && items[rem2].variety != item.variety)
|
||||
equip[rem2] = false;
|
||||
else if(can_rem1 && items[rem1].variety != item.variety)
|
||||
equip[rem1] = false;
|
||||
}
|
||||
if((rem1 == weap_poisoned && !equip[rem1]) || (rem2 == weap_poisoned && !equip[rem2]))
|
||||
status[eStatus::POISONED_WEAPON] = 0;
|
||||
} else if(can_rem1)
|
||||
equip[rem1] = false;
|
||||
equip_item(free_space, false);
|
||||
}
|
||||
}
|
||||
|
||||
combine_things();
|
||||
sort_items();
|
||||
return true;
|
||||
|
||||
@@ -23,6 +23,15 @@ namespace legacy { struct pc_record_type; };
|
||||
|
||||
enum class eBuyStatus {OK, NO_SPACE, NEED_GOLD, TOO_HEAVY, HAVE_LOTS};
|
||||
|
||||
enum {
|
||||
GIVE_DO_PRINT = 1,
|
||||
GIVE_ALLOW_OVERLOAD = 2,
|
||||
// These three are mutually exclusive:
|
||||
GIVE_EQUIP_SOFT = 4,
|
||||
GIVE_EQUIP_TRY = 8,
|
||||
GIVE_EQUIP_FORCE = 12,
|
||||
};
|
||||
|
||||
class cParty;
|
||||
|
||||
class cPlayer : public iLiving {
|
||||
@@ -85,7 +94,7 @@ public:
|
||||
|
||||
void combine_things();
|
||||
void sort_items();
|
||||
bool give_item(cItem item, bool do_print, bool allow_overload = false);
|
||||
bool give_item(cItem item, int flags);
|
||||
bool equip_item(int which_item, bool do_print);
|
||||
bool unequip_item(int which_item, bool do_print);
|
||||
void take_item(int which_item);
|
||||
|
||||
@@ -644,7 +644,7 @@ enum class eSpecType {
|
||||
AFFECT_LEVEL = 91,
|
||||
AFFECT_MORALE = 92,
|
||||
AFFECT_SOUL_CRYSTAL = 93,
|
||||
UNUSED2 = 94,
|
||||
GIVE_ITEM = 94,
|
||||
AFFECT_MONST_TARG = 95,
|
||||
AFFECT_MONST_ATT = 96,
|
||||
AFFECT_MONST_STAT = 97,
|
||||
|
||||
@@ -383,6 +383,7 @@ void cSpecial::append(legacy::special_node_type& old){
|
||||
// j - Choose button to select a quest
|
||||
// J - Choose button to select a quest status
|
||||
// < - Choose button to select a cardinal direction
|
||||
// ~ - Choose button to select a weapon enchantment
|
||||
// 0..9 - Choose button to select a specific type of picture
|
||||
// (terrain, monster, dialog, talk, item, pc, field, boom, missile, status)
|
||||
static const char*const button_dict[7][11] = {
|
||||
@@ -411,13 +412,13 @@ static const char*const button_dict[7][11] = {
|
||||
"s s s S", // ex2b
|
||||
" ", // ex2c
|
||||
}, { // affect pc nodes
|
||||
"mmmmmmmmmmmmm mmmmmmmmmmmmm", // msg1
|
||||
"mmmmmmmmmmmmmmmmmmmmmmmmmmmm", // msg1
|
||||
" ", // msg2
|
||||
" M M ", // msg3
|
||||
" 5 ", // pic
|
||||
" s 5 ", // pic
|
||||
" s ", // pictype
|
||||
" w q AP a ", // ex1a
|
||||
" s", // ex1b
|
||||
" w q i AP a ", // ex1a
|
||||
" ~ s", // ex1b
|
||||
" e Q ", // ex1c
|
||||
" CK E ", // ex2a
|
||||
" D ", // ex2b
|
||||
|
||||
@@ -874,6 +874,7 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
|
||||
case '&': strt = STRT_SHOP; title = "Which shop?"; break;
|
||||
case '%': strt = STRT_COST_ADJ; title = "What cost adjust?"; break;
|
||||
case '*': strt = STRT_CONTEXT; title = "What context?"; break;
|
||||
case '~': strt = STRT_ENCHANT; title = "Which enchantment?"; break;
|
||||
case '^': strt = STRT_POS_MODE; title = "Select positioning mode:"; break;
|
||||
case ':': strt = STRT_STAIR_MODE; title = "Select trigger limitations:"; break;
|
||||
case 'w': strt = STRT_STATUS; title = "Select status:"; str_adj = 1; break;
|
||||
|
||||
Reference in New Issue
Block a user