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
|
level
|
||||||
morale
|
morale
|
||||||
soul-crystal
|
soul-crystal
|
||||||
|
give-item
|
||||||
monst-target
|
monst-target
|
||||||
monst-attack
|
monst-attack
|
||||||
monst-statistic
|
monst-statistic
|
||||||
|
|||||||
@@ -222,20 +222,20 @@ Unused
|
|||||||
Unused
|
Unused
|
||||||
Special to Jump To
|
Special to Jump To
|
||||||
--------------------
|
--------------------
|
||||||
Unused Node
|
Give Equipment
|
||||||
Unused
|
|
||||||
Unused
|
|
||||||
Unused
|
|
||||||
Unused
|
|
||||||
Unused
|
|
||||||
Unused
|
|
||||||
Unused
|
|
||||||
Unused
|
|
||||||
Unused
|
|
||||||
Unused
|
Unused
|
||||||
Unused
|
Unused
|
||||||
|
First part of message
|
||||||
|
Second part of message
|
||||||
Unused
|
Unused
|
||||||
|
Special to call if inventory full
|
||||||
Unused
|
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
|
Special to Jump To
|
||||||
--------------------
|
--------------------
|
||||||
Affect Monster Target
|
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.
|
// 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;
|
dynamic_cast<cCreature*>(pc)->target = spec.ex1a;
|
||||||
break;
|
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:
|
default:
|
||||||
giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!");
|
giveError("Special node type \"" + (*cur_node.type).name() + "\" is either miscategorized or unimplemented!");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -445,9 +445,9 @@ int cParty::calc_day() const {
|
|||||||
return (age / 3700) + 1;
|
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++) {
|
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 true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ public:
|
|||||||
void writeTo(std::ostream& file) const;
|
void writeTo(std::ostream& file) const;
|
||||||
void readFrom(std::istream& file);
|
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 forced_give(item_num_t item_num,eItemAbil abil,short dat = -1);
|
||||||
bool has_abil(eItemAbil abil, short dat = -1);
|
bool has_abil(eItemAbil abil, short dat = -1);
|
||||||
bool take_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;
|
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)
|
if(item.variety == eItemType::NO_ITEM)
|
||||||
return true;
|
return true;
|
||||||
@@ -476,6 +482,59 @@ bool cPlayer::give_item(cItem item, bool do_print, bool allow_overload) {
|
|||||||
print_result(announce.str());
|
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();
|
combine_things();
|
||||||
sort_items();
|
sort_items();
|
||||||
return true;
|
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 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 cParty;
|
||||||
|
|
||||||
class cPlayer : public iLiving {
|
class cPlayer : public iLiving {
|
||||||
@@ -85,7 +94,7 @@ public:
|
|||||||
|
|
||||||
void combine_things();
|
void combine_things();
|
||||||
void sort_items();
|
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 equip_item(int which_item, bool do_print);
|
||||||
bool unequip_item(int which_item, bool do_print);
|
bool unequip_item(int which_item, bool do_print);
|
||||||
void take_item(int which_item);
|
void take_item(int which_item);
|
||||||
|
|||||||
@@ -644,7 +644,7 @@ enum class eSpecType {
|
|||||||
AFFECT_LEVEL = 91,
|
AFFECT_LEVEL = 91,
|
||||||
AFFECT_MORALE = 92,
|
AFFECT_MORALE = 92,
|
||||||
AFFECT_SOUL_CRYSTAL = 93,
|
AFFECT_SOUL_CRYSTAL = 93,
|
||||||
UNUSED2 = 94,
|
GIVE_ITEM = 94,
|
||||||
AFFECT_MONST_TARG = 95,
|
AFFECT_MONST_TARG = 95,
|
||||||
AFFECT_MONST_ATT = 96,
|
AFFECT_MONST_ATT = 96,
|
||||||
AFFECT_MONST_STAT = 97,
|
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
|
||||||
// J - Choose button to select a quest status
|
// J - Choose button to select a quest status
|
||||||
// < - Choose button to select a cardinal direction
|
// < - 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
|
// 0..9 - Choose button to select a specific type of picture
|
||||||
// (terrain, monster, dialog, talk, item, pc, field, boom, missile, status)
|
// (terrain, monster, dialog, talk, item, pc, field, boom, missile, status)
|
||||||
static const char*const button_dict[7][11] = {
|
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
|
"s s s S", // ex2b
|
||||||
" ", // ex2c
|
" ", // ex2c
|
||||||
}, { // affect pc nodes
|
}, { // affect pc nodes
|
||||||
"mmmmmmmmmmmmm mmmmmmmmmmmmm", // msg1
|
"mmmmmmmmmmmmmmmmmmmmmmmmmmmm", // msg1
|
||||||
" ", // msg2
|
" ", // msg2
|
||||||
" M M ", // msg3
|
" M M ", // msg3
|
||||||
" 5 ", // pic
|
" s 5 ", // pic
|
||||||
" s ", // pictype
|
" s ", // pictype
|
||||||
" w q AP a ", // ex1a
|
" w q i AP a ", // ex1a
|
||||||
" s", // ex1b
|
" ~ s", // ex1b
|
||||||
" e Q ", // ex1c
|
" e Q ", // ex1c
|
||||||
" CK E ", // ex2a
|
" CK E ", // ex2a
|
||||||
" D ", // ex2b
|
" 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_SHOP; title = "Which shop?"; break;
|
||||||
case '%': strt = STRT_COST_ADJ; title = "What cost adjust?"; break;
|
case '%': strt = STRT_COST_ADJ; title = "What cost adjust?"; break;
|
||||||
case '*': strt = STRT_CONTEXT; title = "What context?"; 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_POS_MODE; title = "Select positioning mode:"; break;
|
||||||
case ':': strt = STRT_STAIR_MODE; title = "Select trigger limitations:"; break;
|
case ':': strt = STRT_STAIR_MODE; title = "Select trigger limitations:"; break;
|
||||||
case 'w': strt = STRT_STATUS; title = "Select status:"; str_adj = 1; break;
|
case 'w': strt = STRT_STATUS; title = "Select status:"; str_adj = 1; break;
|
||||||
|
|||||||
Reference in New Issue
Block a user