Skip to content

Commit b084548

Browse files
committed
add 'Lift Flags' - allow disabling shield/items while lifting
1 parent da42a87 commit b084548

File tree

12 files changed

+108
-26
lines changed

12 files changed

+108
-26
lines changed

resources/include/std_zh/std_constants.zh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3914,4 +3914,11 @@ enum
39143914
SPLAYER_DARKROOM_OVER //Over dark room darkness
39153915
};
39163916

3917+
enum //for Hero->LiftFlags[]
3918+
{
3919+
LIFTFL_DISABLE_SHIELD,
3920+
LIFTFL_DISABLE_ITEMS,
3921+
LIFTFL_MAX
3922+
};
3923+
39173924

src/base/zdefs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,6 +2228,10 @@ struct guydata
22282228
#define FLAG_USE_NEW_MOVEMENT 0x00004000
22292229
#define FLAG_NOT_PUSHABLE 0x00008000
22302230

2231+
#define LIFTFL_DIS_SHIELD 0x00000001
2232+
#define LIFTFL_DIS_ITEMS 0x00000002
2233+
#define NUM_LIFTFL 2
2234+
22312235
#define MAX_PC dword(-1)
22322236
class refInfo
22332237
{

src/dialog/itemeditor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ void loadinfo(ItemNameInfo * inf, itemdata const& ref)
342342
_SET(actionsnd[1], "Throw Sound", "SFX to play when an object is thrown");
343343
_SET(flag[0], "Fake Z Throw", "Throws weapons in the fakez axis instead of the z axis");
344344
_SET(flag[1], "Lift In Water", "Allows lifting while swimming");
345+
_SET(flag[2], "Disable Shield", "Makes the shield not protect from projectiles, in the same way as when the player is attacking");
346+
_SET(flag[3], "Disable Item Use", "Stop the use of items unrelated to lifting while an object is lifted");
345347
break;
346348
}
347349
case itype_magicring:

src/parser/ByteCode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1985,7 +1985,7 @@ string ZScript::VarToString(int32_t ID)
19851985
case HEROLIFTMAXTIMER: return "HEROLIFTMAXTIMER";
19861986
case HEROLIFTHEIGHT: return "HEROLIFTHEIGHT";
19871987
case HEROHAMMERSTATE: return "HEROHAMMERSTATE";
1988-
case RESRVD_VAR_EMILY19: return "RESRVD_VAR_EMILY19";
1988+
case HEROLIFTFLAGS: return "HEROLIFTFLAGS";
19891989
case RESRVD_VAR_EMILY20: return "RESRVD_VAR_EMILY20";
19901990
case RESRVD_VAR_EMILY21: return "RESRVD_VAR_EMILY21";
19911991
case RESRVD_VAR_EMILY22: return "RESRVD_VAR_EMILY22";

src/parser/ByteCode.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,7 @@
14571457
#define HEROLIFTMAXTIMER 1373
14581458
#define HEROLIFTHEIGHT 1374
14591459
#define HEROHAMMERSTATE 1375
1460-
#define RESRVD_VAR_EMILY19 1376
1460+
#define HEROLIFTFLAGS 1376
14611461
#define RESRVD_VAR_EMILY20 1377
14621462
#define RESRVD_VAR_EMILY21 1378
14631463
#define RESRVD_VAR_EMILY22 1379

src/parser/symbols/HeroSymbols.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ static AccessorTable HeroSTable[] =
179179
{ "setLiftHeight", 0, ZTID_VOID, HEROLIFTHEIGHT, 0, { ZTID_PLAYER, ZTID_FLOAT },{} },
180180
{ "getHammerState", 0, ZTID_FLOAT, HEROHAMMERSTATE, 0, { ZTID_PLAYER },{} },
181181
{ "setHammerState", 0, ZTID_VOID, HEROHAMMERSTATE, 0, { ZTID_PLAYER, ZTID_FLOAT },{} },
182+
{ "getLiftFlags[]", 0, ZTID_BOOL, HEROLIFTFLAGS, 0, { ZTID_PLAYER, ZTID_FLOAT },{} },
183+
{ "setLiftFlags[]", 0, ZTID_VOID, HEROLIFTFLAGS, 0, { ZTID_PLAYER, ZTID_FLOAT, ZTID_BOOL },{} },
182184

183185

184186
//Intentionally undocumented

src/zc/ffscript.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3856,6 +3856,17 @@ int32_t get_register(const int32_t arg)
38563856
}
38573857
break;
38583858
}
3859+
case HEROLIFTFLAGS:
3860+
{
3861+
int32_t indx = ri->d[rINDEX]/10000;
3862+
if(BC::checkBounds(indx, 0, NUM_LIFTFL-1, "Hero->LiftFlags[]") != SH::_NoError)
3863+
ret = 0; //false
3864+
else
3865+
{
3866+
ret = (Hero.liftflags & (1<<indx)) ? 10000 : 0;
3867+
}
3868+
break;
3869+
}
38593870

38603871
case HEROISWARPING:
38613872
ret = Hero.is_warping ? 10000L : 0L;
@@ -13974,6 +13985,19 @@ void set_register(int32_t arg, int32_t value)
1397413985
}
1397513986
break;
1397613987
}
13988+
case HEROLIFTFLAGS:
13989+
{
13990+
int32_t indx = ri->d[rINDEX]/10000;
13991+
if(BC::checkBounds(indx, 0, NUM_LIFTFL-1, "Hero->LiftFlags[]") == SH::_NoError)
13992+
{
13993+
int32_t bit = 1<<indx;
13994+
if(value)
13995+
Hero.liftflags |= bit;
13996+
else
13997+
Hero.liftflags &= ~bit;
13998+
}
13999+
break;
14000+
}
1397714001

1397814002
case CLOCKACTIVE:
1397914003
{
@@ -41778,7 +41802,7 @@ script_variable ZASMVars[]=
4177841802
{ "HEROLIFTMAXTIMER", HEROLIFTMAXTIMER, 0, 0 },
4177941803
{ "HEROLIFTHEIGHT", HEROLIFTHEIGHT, 0, 0 },
4178041804
{ "HEROHAMMERSTATE", HEROHAMMERSTATE, 0, 0 },
41781-
{ "RESRVD_VAR_EMILY19", RESRVD_VAR_EMILY19, 0, 0 },
41805+
{ "HEROLIFTFLAGS", HEROLIFTFLAGS, 0, 0 },
4178241806
{ "RESRVD_VAR_EMILY20", RESRVD_VAR_EMILY20, 0, 0 },
4178341807
{ "RESRVD_VAR_EMILY21", RESRVD_VAR_EMILY21, 0, 0 },
4178441808
{ "RESRVD_VAR_EMILY22", RESRVD_VAR_EMILY22, 0, 0 },

src/zc/ffscript.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4784,7 +4784,7 @@ enum ASM_DEFINE
47844784
#define HEROLIFTMAXTIMER 0x1493
47854785
#define HEROLIFTHEIGHT 0x1494
47864786
#define HEROHAMMERSTATE 0x1495
4787-
#define RESRVD_VAR_EMILY19 0x1496
4787+
#define HEROLIFTFLAGS 0x1496
47884788
#define RESRVD_VAR_EMILY20 0x1497
47894789
#define RESRVD_VAR_EMILY21 0x1498
47904790
#define RESRVD_VAR_EMILY22 0x1499

src/zc/hero.cpp

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ bool usingActiveShield(int32_t itmid)
155155
break;
156156
default: return false;
157157
}
158+
if(Hero.lift_wpn && (Hero.liftflags&LIFTFL_DIS_SHIELD)) return false;
158159
if(itmid < 0)
159160
itmid = (Hero.active_shield_id < 0
160161
? current_item_id(itype_shield,true,true) : Hero.active_shield_id);
@@ -284,6 +285,14 @@ bool HeroClass::isLifting()
284285
if(lift_wpn) return true;
285286
return false;
286287
}
288+
void HeroClass::set_liftflags(int liftid)
289+
{
290+
if(unsigned(liftid) >= MAXITEMS)
291+
return;
292+
itemdata const& itm = itemsbuf[liftid];
293+
SETFLAG(liftflags, LIFTFL_DIS_SHIELD, itm.flags & ITEM_FLAG3);
294+
SETFLAG(liftflags, LIFTFL_DIS_ITEMS, itm.flags & ITEM_FLAG4);
295+
}
287296

288297
void HeroClass::set_respawn_point(bool setwarp)
289298
{
@@ -1455,6 +1464,7 @@ void HeroClass::init()
14551464
liftclk = 0;
14561465
tliftclk = 0;
14571466
liftheight = 0;
1467+
liftflags = 0;
14581468
if ( dontdraw != 2 ) { dontdraw = 0; } //scripted dontdraw == 2, normal == 1, draw hero == 0
14591469
hookshot_used=false;
14601470
justmoved = 0;
@@ -5967,16 +5977,18 @@ int32_t HeroClass::EwpnHit()
59675977
}
59685978

59695979
int32_t itemid = getCurrentShield(false);
5970-
if(itemid<0 || !(checkbunny(itemid) && checkmagiccost(itemid))) return i;
5980+
if(itemid<0 || !(checkbunny(itemid) && checkmagiccost(itemid)))
5981+
return i;
59715982
itemdata const& shield = itemsbuf[itemid];
5983+
bool allow_inactive = (shield.flags & ITEM_FLAG9);
59725984
auto cmpdir = compareDir(ew->dir);
59735985
bool hitshield = compareShield(cmpdir, shield);
59745986

5987+
if(!allow_inactive && ((lift_wpn && (liftflags & LIFTFL_DIS_SHIELD)) || (action==attacking||action==sideswimattacking) || action==swimming || action == sideswimming || action == sideswimattacking || charging > 0 || spins > 0 || hopclk==0xFF))
5988+
return i;
59755989

5976-
if(!hitshield || (action==attacking||action==sideswimattacking) || action==swimming || action == sideswimming || action == sideswimattacking || charging > 0 || spins > 0 || hopclk==0xFF)
5977-
{
5990+
if(!hitshield)
59785991
return i;
5979-
}
59805992

59815993
paymagiccost(itemid);
59825994

@@ -6097,7 +6109,8 @@ int32_t HeroClass::LwpnHit() //only here to c
60976109

60986110
if (!(lw->id == wRefFireball || lw->id == wRefMagic || lw->id == wRefBeam || lw->id == wRefRock)) return -1;
60996111
int32_t itemid = getCurrentShield(false);
6100-
if(itemid<0 || !(checkbunny(itemid) && checkmagiccost(itemid))) return i;
6112+
if(itemid<0 || !(checkbunny(itemid) && checkmagiccost(itemid)))
6113+
return i;
61016114
itemdata const& shield = itemsbuf[itemid];
61026115
auto cmpdir = compareDir(lw->dir);
61036116
bool hitshield = compareShield(cmpdir, shield);
@@ -6152,7 +6165,11 @@ int32_t HeroClass::LwpnHit() //only here to c
61526165
return -1;
61536166
}
61546167

6155-
if(!hitshield || (action==attacking||action==sideswimattacking) || action==swimming || action == sideswimming || action == sideswimattacking || hopclk==0xFF)
6168+
bool allow_inactive = (shield.flags & ITEM_FLAG9);
6169+
if(!allow_inactive && ((lift_wpn && (liftflags & LIFTFL_DIS_SHIELD)) || (action==attacking||action==sideswimattacking) || action==swimming || action == sideswimming || action == sideswimattacking || charging > 0 || spins > 0 || hopclk==0xFF))
6170+
return i;
6171+
6172+
if(!hitshield)
61566173
return i;
61576174

61586175
if(itemid<0 || !(checkbunny(itemid) && checkmagiccost(itemid))) return i;
@@ -10568,6 +10585,7 @@ void HeroClass::do_liftglove(int32_t liftid, bool passive)
1056810585
paidmagic = true;
1056910586
paymagiccost(liftid);
1057010587
}
10588+
set_liftflags(liftid);
1057110589
if(passive)
1057210590
getIntBtnInput(intbtn, true, true, false, false, false); //eat buttons
1057310591
return;
@@ -10883,7 +10901,25 @@ bool HeroClass::startwpn(int32_t itemid)
1088310901
if(((dir==up && y<24) || (dir==down && y>128) ||
1088410902
(dir==left && x<32) || (dir==right && x>208)) && !(get_bit(quest_rules,qr_ITEMSONEDGES) || inlikelike))
1088510903
return false;
10886-
10904+
10905+
bool liftonly = lift_wpn && (liftflags & LIFTFL_DIS_ITEMS);
10906+
if(liftonly)
10907+
{
10908+
dowpn = -1;
10909+
switch(itm.family)
10910+
{
10911+
case itype_bomb:
10912+
case itype_sbomb:
10913+
if(itm.flags & ITEM_FLAG4)
10914+
do_liftglove(-1,false);
10915+
break;
10916+
case itype_liftglove:
10917+
do_liftglove(-1,false);
10918+
break;
10919+
}
10920+
return false;
10921+
}
10922+
1088710923
int32_t wx=x;
1088810924
int32_t wy=y-fakez;
1088910925
int32_t wz=z;
@@ -11242,6 +11278,7 @@ bool HeroClass::startwpn(int32_t itemid)
1124211278
if(liftid > -1 && (!itm.misc4 || itm.misc4 <= glove.fam_type))
1124311279
{
1124411280
lift(wpn,itm.misc5,itm.misc6);
11281+
set_liftflags(liftid);
1124511282
lifted = true;
1124611283
}
1124711284
}
@@ -11296,6 +11333,7 @@ bool HeroClass::startwpn(int32_t itemid)
1129611333
if(liftid > -1 && (!itm.misc4 || itm.misc4 <= glove.fam_type))
1129711334
{
1129811335
lift(wpn,itm.misc5,itm.misc6);
11336+
set_liftflags(liftid);
1129911337
lifted = true;
1130011338
}
1130111339
}
@@ -12065,6 +12103,8 @@ bool HeroClass::startwpn(int32_t itemid)
1206512103

1206612104
bool HeroClass::doattack()
1206712105
{
12106+
if(lift_wpn && (liftflags & LIFTFL_DIS_ITEMS))
12107+
return false;
1206812108
//int32_t s = BSZ ? 0 : 11;
1206912109
int32_t s = (zinit.heroAnimationStyle==las_bszelda) ? 0 : 11;
1207012110

@@ -13782,7 +13822,8 @@ void HeroClass::moveheroOld()
1378213822
if(can_attack() && btnwpn>itype_sword && charging==0 && btnwpn!=itype_rupee) // This depends on item 0 being a rupee...
1378313823
{
1378413824
bool paidmagic = false;
13785-
if(btnwpn==itype_wand && (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_wand : false) : current_item(itype_wand)))
13825+
bool liftonly = lift_wpn && (liftflags & LIFTFL_DIS_ITEMS);
13826+
if(!liftonly && btnwpn==itype_wand && (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_wand : false) : current_item(itype_wand)))
1378613827
{
1378713828
attackid=directWpn>-1 ? directWpn : current_item_id(itype_wand);
1378813829
no_jinx = checkitem_jinx(attackid);
@@ -13801,7 +13842,7 @@ void HeroClass::moveheroOld()
1380113842
item_error();
1380213843
}
1380313844
}
13804-
else if((btnwpn==itype_hammer)&&!((action==attacking||action==sideswimattacking) && attack==wHammer)
13845+
else if(!liftonly && (btnwpn==itype_hammer)&&!((action==attacking||action==sideswimattacking) && attack==wHammer)
1380513846
&& (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_hammer : false) : current_item(itype_hammer)))
1380613847
{
1380713848
no_jinx = checkitem_jinx(dowpn);
@@ -13819,7 +13860,7 @@ void HeroClass::moveheroOld()
1381913860
attackclk=0;
1382013861
}
1382113862
}
13822-
else if((btnwpn==itype_candle)&&!((action==attacking||action==sideswimattacking) && attack==wFire)
13863+
else if(!liftonly && (btnwpn==itype_candle)&&!((action==attacking||action==sideswimattacking) && attack==wFire)
1382313864
&& (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_candle : false) : current_item(itype_candle)))
1382413865
{
1382513866
//checkbunny handled where magic cost is paid
@@ -13832,7 +13873,7 @@ void HeroClass::moveheroOld()
1383213873
attackclk=0;
1383313874
}
1383413875
}
13835-
else if((btnwpn==itype_cbyrna)&&!((action==attacking||action==sideswimattacking) && attack==wCByrna)
13876+
else if(!liftonly && (btnwpn==itype_cbyrna)&&!((action==attacking||action==sideswimattacking) && attack==wCByrna)
1383613877
&& (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_cbyrna : false) : current_item(itype_cbyrna)))
1383713878
{
1383813879
attackid=directWpn>-1 ? directWpn : current_item_id(itype_cbyrna);
@@ -13852,7 +13893,7 @@ void HeroClass::moveheroOld()
1385213893
item_error();
1385313894
}
1385413895
}
13855-
else if((btnwpn==itype_bugnet)&&!((action==attacking||action==sideswimattacking) && attack==wBugNet)
13896+
else if(!liftonly && (btnwpn==itype_bugnet)&&!((action==attacking||action==sideswimattacking) && attack==wBugNet)
1385613897
&& (directWpn>-1 ? (!item_disabled(directWpn) && itemsbuf[directWpn].family==itype_bugnet) : current_item(itype_bugnet)))
1385713898
{
1385813899
attackid = directWpn>-1 ? directWpn : current_item_id(itype_bugnet);
@@ -17726,7 +17767,8 @@ bool HeroClass::premove()
1772617767
if(can_attack() && btnwpn>itype_sword && charging==0 && btnwpn!=itype_rupee) // This depends on item 0 being a rupee...
1772717768
{
1772817769
bool paidmagic = false;
17729-
if(btnwpn==itype_wand && (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_wand : false) : current_item(itype_wand)))
17770+
bool liftonly = lift_wpn && (liftflags & LIFTFL_DIS_ITEMS);
17771+
if(!liftonly && btnwpn==itype_wand && (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_wand : false) : current_item(itype_wand)))
1773017772
{
1773117773
attackid=directWpn>-1 ? directWpn : current_item_id(itype_wand);
1773217774
no_jinx = checkitem_jinx(attackid);
@@ -17745,7 +17787,7 @@ bool HeroClass::premove()
1774517787
item_error();
1774617788
}
1774717789
}
17748-
else if((btnwpn==itype_hammer)&&!((action==attacking||action==sideswimattacking) && attack==wHammer)
17790+
else if(!liftonly && (btnwpn==itype_hammer)&&!((action==attacking||action==sideswimattacking) && attack==wHammer)
1774917791
&& (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_hammer : false) : current_item(itype_hammer)))
1775017792
{
1775117793
no_jinx = checkitem_jinx(dowpn);
@@ -17763,7 +17805,7 @@ bool HeroClass::premove()
1776317805
attackclk=0;
1776417806
}
1776517807
}
17766-
else if((btnwpn==itype_candle)&&!((action==attacking||action==sideswimattacking) && attack==wFire)
17808+
else if(!liftonly && (btnwpn==itype_candle)&&!((action==attacking||action==sideswimattacking) && attack==wFire)
1776717809
&& (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_candle : false) : current_item(itype_candle)))
1776817810
{
1776917811
//checkbunny handled where magic cost is paid
@@ -17776,7 +17818,7 @@ bool HeroClass::premove()
1777617818
attackclk=0;
1777717819
}
1777817820
}
17779-
else if((btnwpn==itype_cbyrna)&&!((action==attacking||action==sideswimattacking) && attack==wCByrna)
17821+
else if(!liftonly && (btnwpn==itype_cbyrna)&&!((action==attacking||action==sideswimattacking) && attack==wCByrna)
1778017822
&& (directWpn>-1 ? (!item_disabled(directWpn) ? itemsbuf[directWpn].family==itype_cbyrna : false) : current_item(itype_cbyrna)))
1778117823
{
1778217824
attackid=directWpn>-1 ? directWpn : current_item_id(itype_cbyrna);
@@ -17796,7 +17838,7 @@ bool HeroClass::premove()
1779617838
item_error();
1779717839
}
1779817840
}
17799-
else if((btnwpn==itype_bugnet)&&!((action==attacking||action==sideswimattacking) && attack==wBugNet)
17841+
else if(!liftonly && (btnwpn==itype_bugnet)&&!((action==attacking||action==sideswimattacking) && attack==wBugNet)
1780017842
&& (directWpn>-1 ? (!item_disabled(directWpn) && itemsbuf[directWpn].family==itype_bugnet) : current_item(itype_bugnet)))
1780117843
{
1780217844
attackid = directWpn>-1 ? directWpn : current_item_id(itype_bugnet);

src/zc/hero.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,11 @@ class HeroClass : public sprite
333333
byte liftclk;
334334
byte tliftclk;
335335
zfix liftheight;
336-
336+
uint32_t liftflags;
337337

338338
// Methods below here.
339339
bool isLifting();
340+
void set_liftflags(int liftid);
340341
void doSwitchHook(byte style);
341342
bool isStanding(bool forJump = false);
342343
void explode(int32_t type);

0 commit comments

Comments
 (0)