Advertisement
Guest User

Untitled

a guest
Dec 31st, 2016
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 110.17 KB | None | 0 0
  1. //LWeapons.zh Version 1.0.8
  2.  
  3. //
  4. //Library for doing custom LWeapon movement, death effects, sounds and lifespans. Without FFCS.
  5.  
  6. import "std.zh"
  7. import "string.zh"
  8. import "stdExtra.zh"
  9. import "ffcscript.zh"
  10. import "ghost.zh"
  11.  
  12. //import "LW_ZH/deprecated.z"
  13. //import "LW_ZH/global.z"
  14. //import "LW_ZH/genfunction.zh"
  15. //import "LW_ZH/common.z"
  16. //import "LW_ZH/update.z"
  17. //import "LW_ZH/movement.z"
  18. //import "LW_ZH/lweaponLife.z"
  19. //import "LW_ZH/other.z"
  20. //import "LW_ZH/scripts.z"
  21. //import "LW_ZH/caneofsomaria.z"
  22.  
  23. int LW_Vars[65536];//Array for extra LWeapon functions.
  24.  
  25. //Misc Constants
  26.  
  27. const int MAX_STUN_TIME = 180;//Maximum time to stun an enemy.
  28.  
  29. //Npc constants
  30.  
  31. const int NPC_ITEMSET = 180; // ID of a dummy enemy with type different from "none"
  32.  
  33. //Sound constants
  34.  
  35. const int SFX_POT_BREAK = 75;//Sound made by breaking pots.
  36. const int SFX_THROW = 61;//Sound of an object being thrown.
  37. const int SFX_HEFT = 0;//Sound of picking up an object.
  38.  
  39. //Item constants
  40.  
  41. const int I_CSOMARIA = 0;//Item id of Cane of Somaria.
  42.  
  43. // Sprite constants
  44. const int SPR_BUSH_CUT = 52;
  45. const int SPR_FLOWER_CUT = 53;
  46. const int SPR_GRASS_CUT = 54;
  47. const int SPR_POT_BREAK = 23;
  48. const int SPR_WAND_FIRE = 85;
  49. const int SPR_ICE_MAGIC = 83;
  50. const int SPR_SOMARIA_BLOCK = 90;
  51. const int SPR_SOMARIA_FIRE = 91;
  52. //const int SPR_ROCK = 0;
  53. const int SPR_BUSH = 44;
  54. const int SPR_NULL = 93;
  55. //const int SPR_POT = 0;
  56. //const int SPR_ICE_BLOCK = 0;
  57.  
  58. //Flags for category Screen->Flags[SF_SECRETS]
  59.  
  60. const int SF_BLOCK_SHUT = 0x01;//Blocks set shutters open.
  61. const int SF_NOT_PERM = 0x02;//Secrets are temporary
  62. const int SF_HIT_ALL_PERM = 0x04;//Hit all triggers to set permanent secrets.
  63. const int SF_HIT_ALL_16_31 = 0x08;//Hit all triggers to trigger flags 16-31.
  64.  
  65. //NPC Misc Indices
  66.  
  67. const int NPC_MISC_TARGET_NUMBER = 3;//Npc index to store the fact that it has been targeted.
  68.  
  69. //Lweapon Misc Indices
  70. //These must be unique numbers between 0 and 15.
  71.  
  72. const int LW_ZH_I_FLAGS = 15; // Every index but this one can be used by non-lweapons.zh Lweapons
  73. const int LW_ZH_I_WORK_3 = 1;//Used to calculate things, like MP drain.
  74. const int LW_ZH_I_FLAGS_2 = 2;//Index for more Lweapon flags. Most are used internally, not set by script.
  75. const int LW_ZH_I_FX = 3;//Misc index used to make lweapon sounds continuous.
  76. const int LW_ZH_I_WORK_2 = 4;// Only used by a few movement types
  77. const int LW_ZH_I_WORK = 5;//Uses for a variety of things by lweapons.zh.
  78. const int LW_ZH_I_MOVEMENT_ARG = 6;//First lweapon misc index for movement.
  79. const int LW_ZH_I_MOVEMENT_ARG2 = 7;//Second lweapon misc index for movement.
  80. const int LW_ZH_I_MOVEMENT = 8;//Lweapon index used to indicate how it moves.
  81. const int LW_ZH_I_XPOS = 9;//Lweapon index of it's X position.
  82. const int LW_ZH_I_YPOS = 10;//Lweapon index of it's Y position.
  83. const int LW_ZH_I_LIFESPAN = 11;//Lweapon index for lifespan
  84. const int LW_ZH_I_LIFESPAN_ARG = 12;//Lweapon index to tell how long lifespan is.
  85. const int LW_ZH_I_ON_DEATH = 13;//Lweapon index for death effects.
  86. const int LW_ZH_I_ON_DEATH_ARG = 14;//Lweapon index to determine what death effect does.
  87.  
  88. //Lweapon movement flags.
  89.  
  90. const int LWM_SINE_WAVE = 1;//Lweapon that moves in a sine wave.
  91. const int LWM_CIRCLE = 2;//LWeapon that moves in a circle around Link.
  92. const int LWM_HOMING = 3;//Lweapon that homes in on enemies.
  93. const int LWM_BRANG = 5;//LWeapon that acts like a boomerang.
  94. const int LWM_THROW = 15;//Lweapon that is thrown.
  95. const int LWM_FALL = 19;//Lweapon that falls from the air.
  96. const int LWM_CARRY = 8;//This lweapon remains at rest relative to link.
  97. const int LWM_HOOKSHOT = 4;//Lweapon that acts like a hookshot.
  98. const int LWM_DUAL_FX = 7;//This lweapon causes one of more types of flags to be hit.
  99. //const int LWM_MELEE = 6;//LWeapon that acts like a melee weapon.
  100.  
  101. // Flags used by certain Lweapon movement types
  102.  
  103. const int LWMF_DIE = 00000000001b;//This weapon dies when it stops moving.
  104. const int LWMF_REST= 00000000010b;//This weapon rests when it stops moving.
  105.  
  106. //Arguments used by certain lweapon types.
  107.  
  108. //const int LWM_R_GRENADE = 1;//This is a grenade.
  109. //const int LWM_R_SOMARIA = 2;//This is a cane of Somaria block.
  110. //const int LWM_R_MAGNET = 3;//This is a magnetic glove.
  111.  
  112. // Arguments to SetLWeaponLifespan()
  113.  
  114. const int LWL_TIMER = 1;//This lweapon runs on a timer.
  115. const int LWL_MP_COST = 4;//This lweapon continuously uses mp. If you don't have enough MP,it dies.
  116. const int LWL_EDGE = 15;//This weapon dies at the edge of the screen.
  117.  
  118. //LWeapon Flags, use with LW_ZH_I_FLAGS
  119.  
  120. const int LWF_ITEM_PICKUP = 00000000001b;//Can pickup items.
  121. const int LWF_PIERCES_ENEMIES = 00000000010b;//Pierces enemies.
  122. const int LWF_STUNS_ENEMIES = 00000000100b;//Stuns enemies.
  123. const int LWF_ZERO_G = 00000001000b;//Ignores gravity.
  124. const int LWF_POISON = 00000010000b;//Poisons enemies.
  125. const int LWF_INSTA_DELIVER = 00000100000b;//Used with item pickup. Insta-delivers item to Link.
  126. const int LWF_LINK_NO_COLL = 00001000000b;//Link can't be hurt while this lweapon is active.
  127. const int LWF_CAN_REFLECT = 00010000000b;//Reflected off of magic mirrors.
  128. //const int LWF_IS_MELEE = 00001000000b;//Used to tell that this is a melee item.
  129.  
  130. // Internal LWeapon flags
  131.  
  132. const int __LWFI_DEAD = 00100000000b;//This lweapon is dead.
  133. const int __LWFI_IS_LWZH_LWPN = 01000000000b;//A Lweapon.zh lweapon
  134. const int __LWFI_DEATH_EFFECT_DONE = 10000000000b;//The lweapon death effect is over.
  135.  
  136. //LWeapon Flags, use with LW_ZH_I_FLAGS_2
  137.  
  138. const int LWF_LEVEL_1 = 00000000001b;//Simulated level 1 of a particular weapon type.
  139. const int LWF_LEVEL_2 = 00000000011b;//Simulated level 2 of a particular weapon type..
  140. const int LWF_LEVEL_3 = 00000000111b;//Simulated level 3 of a particular weapon type.
  141. const int LWF_LEVEL_4 = 00000001111b;//Simulated level 4 of a particular weapon type.
  142. const int LWF_NO_COLLISION = 00001000000b;//This lweapon's collision is off.
  143. const int LWF_WAS_REFLECTED = 00010000000b;//This lweapon was just reflected.
  144. const int LWF_IS_REFLECTED = 00100000000b;//This is a reflected lweapon.
  145.  
  146. //Internal LWeapon Flags, use with LW_ZH_I_FLAGS_2
  147.  
  148. const int LWF_RETURN = 00000010000b;//This lweapon is returning to the user.
  149. const int LWF_HS_GRAB = 00000100000b;//A hookshot target has been grabbed.
  150. const int LWF_LINK_FROZEN = 01000000000b;//Link can't move while this lweapon is active.
  151.  
  152. // Arguments to SetLWeaponDeathEffect()
  153.  
  154. const int LWD_VANISH = 1;//This lweapon vanishes at death.
  155. const int LWD_AIM_AT_NPC = 2;//At death, this lweapon aims at an enemy on screen and head in that direction.
  156. const int LWD_EXPLODE = 3;//At death, this lweapon creates a bomb blast.
  157. const int LWD_SBOMB_EXPLODE = 4;//At death, this lweapon creates a super bomb blast.
  158. const int LWD_4_FIREBALLS_HV = 5;//At death, this lweapon makes 4 horizontal and vertical lweapons.
  159. const int LWD_4_FIREBALLS_DIAG = 6;//At death, this lweapon makes 4 diagonal lweapons.
  160. const int LWD_4_FIREBALLS_RANDOM = 7;//At death, this lweapon makes 4 random lweapons.
  161. const int LWD_8_FIREBALLS = 8;//At death, this lweapon makes 8 lweapons in all directions.
  162. const int LWD_FREEZE = 9;//At death, make an immobile ice block over the enemy.
  163.  
  164. //Ghost ZH compatiblilty stuff. Not needed, really.
  165.  
  166. const int LWD_4_FIRES_DIAG = 10;//At death, this lweapon makes 4 diagonal lweapons.
  167. const int LWD_4_FIRES_RANDOM = 11;//At death, this lweapon makes 4 random lweapons.
  168. const int LWD_8_FIRES = 12;//At death, this lweapon makes 8 lweapons in all directions.
  169. const int LWD_FIRE = 14;//At death, this lweapon makes another lweapon at its location.
  170.  
  171. //LWeapons Melee Item Duplication
  172.  
  173. //const int LW_IS_SWORD = 1;//This is a fake sword.
  174. //const int LW_IS_HAMMER = 2;//This is a fake hammer.
  175. //const int LW_IS_WAND = 3;//This is a fake wand.
  176.  
  177. //Internal Melee Item Flags
  178.  
  179. //const int LW_HAS_SLASH = 00000000001b;//This sword slashes.
  180. //const int LW_HAS_WHIM_RING = 00000000010b;//The weapon occassionally performs a critical attack.
  181. //const int LW_HAS_PERIL = 00000000100b;//This sword can shoot peril beams.
  182. //const int LW_HAS_BOOK = 00100000000b;//This wand has the magic book.
  183.  
  184. //Common LW_ZH functions
  185.  
  186. // Fire an lweapon
  187. lweapon FireLWeapon(int weaponID, int x, int y, float angle, int step, int damage, int sprite, int sound, int flags)
  188. {
  189.  
  190. lweapon wpn=Screen->CreateLWeapon(weaponID);
  191. wpn->X=x;
  192. wpn->Y=y;
  193. wpn->Step=step;
  194. wpn->Damage=damage;
  195. wpn->Angular=true;
  196. wpn->Angle=angle;
  197.  
  198. if(sprite>=0)
  199. wpn->UseSprite(sprite);
  200. wpn->Misc[LW_ZH_I_FLAGS]=flags|__LWFI_IS_LWZH_LWPN;
  201. //if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_CAN_REFLECT)!=0)wpn->Misc[LW_ZH_I_WORK]= sprite;
  202. SetLWeaponDir(wpn); // After flags so unblockability is detected
  203. Game->PlaySound(sound);
  204. return wpn;
  205. }
  206.  
  207.  
  208. // Fire an lweapon aimed based on an enemy's position
  209. lweapon FireAimedLWeapon(int weaponID, int x, int y, float angle, int step, int damage, int sprite, int sound, int flags)
  210. {
  211. lweapon wpn;
  212. float targetAngle;
  213. if(Screen->NumNPCs()>0){
  214. if(wpn->Misc[LW_ZH_I_WORK]==0)wpn->Misc[LW_ZH_I_WORK] = Rand(1,Screen->NumNPCs());
  215. npc target_enemy = Screen->LoadNPC(wpn->Misc[LW_ZH_I_WORK]);
  216. target_enemy->Misc[NPC_MISC_TARGET_NUMBER]=wpn->Misc[LW_ZH_I_WORK];
  217. if(target_enemy->HP<=0)wpn->Misc[LW_ZH_I_WORK]= 0;
  218. if(target_enemy->Misc[NPC_MISC_TARGET_NUMBER]==wpn->Misc[LW_ZH_I_WORK]){
  219. targetAngle=RadianAngle(wpn->X, wpn->Y, target_enemy->X, target_enemy->Y);
  220. if(targetAngle<0)
  221. targetAngle+=6.2832;
  222. }
  223. }
  224. return FireLWeapon(weaponID, x, y, targetAngle+angle, step, damage, sprite, sound, flags);
  225. }
  226.  
  227.  
  228. // Fire a non-angular lweapon
  229. lweapon FireNonAngularLWeapon(int weaponID, int x, int y, int dir, int step, int damage, int sprite, int sound, int flags)
  230. {
  231. lweapon wpn=Screen->CreateLWeapon(weaponID);
  232. wpn->X=x;
  233. wpn->Y=y;
  234. wpn->Step=step;
  235. wpn->Damage=damage;
  236. wpn->Angular=false;
  237. wpn->Dir=dir;
  238.  
  239. if(sprite>=0)
  240. wpn->UseSprite(sprite);
  241. wpn->Misc[LW_ZH_I_FLAGS]=flags|__LWFI_IS_LWZH_LWPN;
  242. //if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_CAN_REFLECT)!=0)wpn->Misc[LW_ZH_I_WORK]= sprite;
  243. Game->PlaySound(sound);
  244. return wpn;
  245. }
  246.  
  247.  
  248. // Fire an lweapon larger than 1x1
  249. lweapon FireBigLWeapon(int weaponID, int x, int y, float angle, int step, int damage, int sprite, int sound, int flags, int width, int height)
  250. {
  251. lweapon wpn= Screen->CreateLWeapon(weaponID);
  252. wpn->X=x;
  253. wpn->Y=y;
  254. wpn->Step=step;
  255. wpn->Damage=damage;
  256. wpn->Angular=true;
  257. wpn->Angle=angle;
  258.  
  259. if(sprite>=0)
  260. wpn->UseSprite(sprite);
  261. wpn->Misc[LW_ZH_I_FLAGS]=flags|__LWFI_IS_LWZH_LWPN;
  262. wpn->Extend=3;
  263. wpn->TileWidth=width;
  264. wpn->TileHeight=height;
  265. wpn->HitWidth=16*width;
  266. wpn->HitHeight=16*height;
  267. SetLWeaponDir(wpn);
  268. Game->PlaySound(sound);
  269. return wpn;
  270. }
  271.  
  272.  
  273. // Fire an lweapon larger than 1x1 aimed based on an enemy's position
  274. lweapon FireBigAimedLWeapon(int weaponID, int x, int y, float angle, int step, int damage, int sprite, int sound, int flags, int width, int height)
  275. {
  276. lweapon wpn=FireAimedLWeapon(weaponID, x, y, angle, step, damage, sprite, sound, flags);
  277. float targetAngle;
  278. if(Screen->NumNPCs()>0){
  279. if(wpn->Misc[LW_ZH_I_WORK]==0)wpn->Misc[LW_ZH_I_WORK] = Rand(1,Screen->NumNPCs());
  280. npc target_enemy = Screen->LoadNPC(wpn->Misc[LW_ZH_I_WORK]);
  281. target_enemy->Misc[NPC_MISC_TARGET_NUMBER]=wpn->Misc[LW_ZH_I_WORK];
  282. if(target_enemy->HP<=0)wpn->Misc[LW_ZH_I_WORK]= 0;
  283. if(target_enemy->Misc[NPC_MISC_TARGET_NUMBER]==wpn->Misc[LW_ZH_I_WORK]){
  284. targetAngle=RadianAngle(wpn->X, wpn->Y, target_enemy->X, target_enemy->Y);
  285. if(targetAngle<0)
  286. targetAngle+=6.2832;
  287. }
  288. }
  289. return FireBigLWeapon(weaponID, x, y, targetAngle+angle, step, damage, sprite, sound, flags,width,height);
  290. }
  291.  
  292.  
  293. // Fire a non-angular lweapon larger than 1x1
  294. lweapon FireBigNonAngularLweapon(int weaponID, int x, int y, int dir, int step, int damage, int sprite, int sound, int flags, int width, int height)
  295. {
  296. lweapon wpn=FireNonAngularLWeapon(weaponID, x, y, dir, step, damage, sprite, sound, flags);
  297. wpn->Extend=3;
  298. wpn->TileWidth=width;
  299. wpn->TileHeight=height;
  300. wpn->HitWidth=16*width;
  301. wpn->HitHeight=16*height;
  302. return wpn;
  303. }
  304.  
  305. //Included for compatiblilty with other scripts.
  306.  
  307. //Fires a scripted Lweapon.
  308.  
  309. //D0- Type of weapon
  310. //D1- X coords to fire at.
  311. //D2- Y coords to fire at.
  312. //D3- Sprite to use.
  313. //D4- Speed of Lweapon.
  314. //D5- Damage Lweapon does.
  315.  
  316. lweapon FireScriptedLWeapon(int type, int X, int Y,int Sprite, int Speed, int Damage,int flags){
  317. lweapon thing = Screen->CreateLWeapon(type);
  318. thing->X = X;
  319. thing->Y = Y;
  320. thing->Step = Speed;
  321. thing->Damage = Damage;
  322. thing->UseSprite(Sprite);
  323. thing->Dir= Link->Dir;
  324. if(thing->Dir == DIR_LEFTUP||thing->Dir == DIR_RIGHTUP
  325. ||thing->Dir == DIR_LEFTDOWN||thing->Dir == DIR_RIGHTDOWN){
  326. if(thing->NumFrames!=0)thing->Tile+=(thing->NumFrames*2);
  327. else thing->Tile+=2;
  328. if(thing->Dir==DIR_LEFTUP)
  329. thing->Flip = FLIP_H;
  330. else if(thing->Dir==DIR_RIGHTDOWN)
  331. thing->Flip = FLIP_V;
  332. else if(thing->Dir==DIR_LEFTDOWN)
  333. thing->Flip = FLIP_B;
  334. }
  335. else if(thing->Dir==DIR_LEFT||thing->Dir==DIR_RIGHT){
  336. if(thing->NumFrames!=0)thing->Tile+=thing->NumFrames;
  337. else thing->Tile+=1;
  338. if(thing->Dir ==DIR_LEFT)thing->Flip= FLIP_H;
  339. }
  340. else{
  341. if(thing->Dir == DIR_DOWN)
  342. thing->Flip = FLIP_V;
  343. }
  344. thing->Misc[LW_ZH_I_FLAGS]=flags|__LWFI_IS_LWZH_LWPN;
  345. return thing;
  346. }
  347.  
  348. lweapon FireIndependentLWeapon(int type, int X, int Y,int dir,int Sprite, int Speed, int Damage,int flags){
  349. lweapon thing = Screen->CreateLWeapon(type);
  350. thing->X = X;
  351. thing->Y = Y;
  352. thing->Step = Speed;
  353. thing->Damage = Damage;
  354. thing->UseSprite(Sprite);
  355. thing->Dir= dir;
  356. if(thing->Dir == DIR_LEFTUP||thing->Dir == DIR_RIGHTUP
  357. ||thing->Dir == DIR_LEFTDOWN||thing->Dir == DIR_RIGHTDOWN){
  358. if(thing->NumFrames!=0)thing->Tile+=(thing->NumFrames*2);
  359. else thing->Tile+=2;
  360. if(thing->Dir==DIR_LEFTUP)
  361. thing->Flip = FLIP_H;
  362. else if(thing->Dir==DIR_RIGHTDOWN)
  363. thing->Flip = FLIP_V;
  364. else if(thing->Dir==DIR_LEFTDOWN)
  365. thing->Flip = FLIP_B;
  366. }
  367. else if(thing->Dir==DIR_LEFT||thing->Dir==DIR_RIGHT){
  368. if(thing->NumFrames!=0)thing->Tile+=thing->NumFrames;
  369. else thing->Tile+=1;
  370. if(thing->Dir ==DIR_LEFT)thing->Flip= FLIP_H;
  371. }
  372. else{
  373. if(thing->Dir == DIR_DOWN)
  374. thing->Flip = FLIP_V;
  375. }
  376. thing->Misc[LW_ZH_I_FLAGS]=flags|__LWFI_IS_LWZH_LWPN;
  377. return thing;
  378. }
  379.  
  380. // Set the weapon's direction based on its angle;
  381.  
  382. void SetLWeaponDir(lweapon wpn){
  383. float angle=wpn->Angle%6.2832;
  384. int dir;
  385. int tile = wpn->OriginalTile;
  386. int flip= wpn->Flip;
  387.  
  388. if(angle<0)
  389. angle+=6.2832;
  390. if(angle<0.3927 || angle>5.8905){
  391. dir=DIR_RIGHT;
  392. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+wpn->NumFrames;
  393. else tile = wpn->OriginalTile+1;
  394. }
  395. else if(angle<1.1781){
  396. dir=DIR_RIGHTDOWN;
  397. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+(wpn->NumFrames*2);
  398. else tile = wpn->OriginalTile+2;
  399. flip = FLIP_V;
  400. }
  401. else if(angle<1.9635){
  402. dir=DIR_DOWN;
  403. if(wpn->TileWidth==1)
  404. flip = FLIP_V;
  405. }
  406. else if(angle<2.7489){
  407. dir=DIR_LEFTDOWN;
  408. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+(wpn->NumFrames*2);
  409. else tile = wpn->OriginalTile+2;
  410. flip = FLIP_B;
  411. }
  412. else if(angle<3.5343){
  413. dir=DIR_LEFT;
  414. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+wpn->NumFrames;
  415. else tile = wpn->OriginalTile+1;
  416. if(wpn->TileWidth==1)
  417. flip= FLIP_H;
  418. }
  419. else if(angle<4.3197){
  420. dir=DIR_LEFTUP;
  421. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+(wpn->NumFrames*2);
  422. else tile = wpn->OriginalTile+2;
  423. flip = FLIP_H;
  424. }
  425. else if(angle<5.1051)
  426. dir=DIR_UP;
  427. else{
  428. dir=DIR_RIGHTUP;
  429. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+(wpn->NumFrames*2);
  430. else tile = wpn->OriginalTile+2;
  431. }
  432. wpn->Dir=dir;
  433. wpn->Tile = tile;
  434. wpn->Flip = flip;
  435. }
  436.  
  437. // Flip the weapon's sprite to match its direction
  438. void SetLWeaponRotation(lweapon wpn, int dir){
  439. float angle=wpn->Angle%6.2832;
  440. if(angle<0)
  441. angle+=6.2832;
  442. int tile = wpn->OriginalTile;
  443. int flip= wpn->Flip;
  444. wpn->Angular = true;
  445. if(angle<0)
  446. angle+=6.2832;
  447. if(angle<0.3927 || angle>5.8905){
  448. dir=DIR_RIGHT;
  449. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+wpn->NumFrames;
  450. else tile = wpn->OriginalTile+1;
  451. }
  452. else if(angle<1.1781){
  453. dir=DIR_RIGHTDOWN;
  454. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+(wpn->NumFrames*2);
  455. else tile = wpn->OriginalTile+2;
  456. flip = FLIP_V;
  457. }
  458. else if(angle<1.9635){
  459. dir=DIR_DOWN;
  460. flip = FLIP_V;
  461. }
  462. else if(angle<2.7489){
  463. dir=DIR_LEFTDOWN;
  464. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+(wpn->NumFrames*2);
  465. else tile = wpn->OriginalTile+2;
  466. flip = FLIP_B;
  467. }
  468. else if(angle<3.5343){
  469. dir=DIR_LEFT;
  470. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+wpn->NumFrames;
  471. else tile = wpn->OriginalTile+1;
  472. flip= FLIP_H;
  473. }
  474. else if(angle<4.3197){
  475. dir=DIR_LEFTUP;
  476. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+(wpn->NumFrames*2);
  477. else tile = wpn->OriginalTile+2;
  478. flip = FLIP_H;
  479. }
  480. else if(angle<5.1051)
  481. dir=DIR_UP;
  482. else{
  483. dir=DIR_RIGHTUP;
  484. if(wpn->NumFrames!=0)tile = wpn->OriginalTile+(wpn->NumFrames*2);
  485. else tile = wpn->OriginalTile+2;
  486. }
  487. wpn->Dir=dir;
  488. wpn->Tile = tile;
  489. wpn->Flip = flip;
  490. }
  491.  
  492. // Kill an lweapon, triggering any death effects
  493. // Kill an lweapon, triggering any death effects
  494. void KillLWeapon(lweapon wpn){
  495. wpn->Misc[LW_ZH_I_FLAGS]|=__LWFI_DEAD;
  496. if(wpn->Misc[LW_ZH_I_ON_DEATH]==0){
  497. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_PIERCES_ENEMIES)!=0){
  498. wpn->Misc[LW_ZH_I_FLAGS]&= ~LWF_PIERCES_ENEMIES;
  499. wpn->DeadState = 0;
  500. Remove(wpn);
  501. }
  502. else
  503. Remove(wpn);
  504. }
  505. }
  506.  
  507.  
  508. //Removes a specific lweapon type.
  509.  
  510. void RemoveLWeaponType(int type){
  511. for(int i = 1;i<=Screen->NumLWeapons();i++){
  512. lweapon e = Screen->LoadLWeapon(i);
  513. if(e->ID==type)Remove(e);
  514. }
  515. }
  516.  
  517. //A function to adjust an lweapon's hitbox size.
  518. //D0- Lweapon to adjust
  519. //D1- HitWidth
  520. //D2- HitHeight
  521. //D3- HitXOffset
  522. //D4- HitYOffset
  523.  
  524. void SetLWeaponHitbox(lweapon wpn, int HitWidth, int HitHeight, int HitXOffset, int HitYOffset){
  525. wpn->HitHeight = HitHeight;
  526. wpn->HitWidth = HitWidth;
  527. wpn->HitXOffset = HitXOffset;
  528. wpn->HitYOffset = HitYOffset;
  529. }
  530.  
  531. //A function to quickly change the size of an lweapon.
  532. //D0- Lweapon to adjust.
  533. //D1- Tile Width
  534. //D2- Tile Height
  535.  
  536. void SetLWeaponSize(lweapon wpn, int TileWidth, int TileHeight){
  537. wpn->Extend = 3;
  538. wpn->TileHeight = TileHeight;
  539. wpn->TileWidth = TileWidth;
  540. }
  541.  
  542. //Find a previously saved lweapon.
  543.  
  544. lweapon FindMiscLWeapon(int Weapon_ID){
  545. lweapon wpn;
  546. for(int i= Screen->NumLWeapons();i>0;i--){
  547. wpn = Screen->LoadLWeapon(i);
  548. //This is the right lweapon.
  549. if(wpn->Misc[LW_ZH_I_WORK_3]==Weapon_ID)
  550. return wpn;
  551. }
  552. }
  553.  
  554. //Finds an lweapon of a certain type.
  555.  
  556. lweapon FindLWeaponType(int type){
  557. for(int i = 1;i<=Screen->NumLWeapons();i++){
  558. lweapon e = Screen->LoadLWeapon(i);
  559. if(e->ID==type)return e;
  560. }
  561. }
  562.  
  563. //Functions used by LWeapons.zh that may be included with other headers.
  564. //Preserved to allow internal functionality.
  565.  
  566. //Checks if one is true and the other is false.
  567.  
  568. bool Xor(bool A, bool B){
  569. if((A&&!B)||(B&&!A))
  570. return true;
  571. return false;
  572. }
  573.  
  574. // Returns true if FFC collides with a combo which has specific placed flag
  575. bool ComboFlagCollision (int loc, int flag, lweapon l){
  576. if (ComboFI(loc,flag)){
  577. if (ComboCollision(loc, l->X,l->Y,l->X+16,l->Y+16)) return true;
  578. }
  579. return false;
  580. }
  581.  
  582. // Returns true if FFC collides with a combo which has specific placed flag
  583. bool ComboFlagCollision (int loc, int flag, int type,lweapon l){
  584. if (ComboFIT(loc,flag,type)){
  585. if (ComboCollision(loc, l->X,l->Y,l->X+16,l->Y+16)) return true;
  586. }
  587. return false;
  588. }
  589.  
  590. // Returns TRUE if there is a collision between the combo and an arbitrary rectangle.
  591. // From stdWeapons.
  592. bool ComboCollision (int loc, int x1, int y1, int x2, int y2){
  593. return RectCollision( ComboX(loc), ComboY(loc), (ComboX(loc)+16), (ComboY(loc)+16), x1, y1, x2, y2);
  594. }
  595.  
  596. bool ComboCollision(int loc, lweapon wpn){
  597. int wpnX = wpn->X+wpn->HitXOffset;
  598. int wpnY = wpn->Y+wpn->HitYOffset;
  599. int wpnXWidth = wpnX+wpn->HitWidth;
  600. int wpnYHeight = wpnY+wpn->HitHeight;
  601. return ComboCollision (loc, wpnX, wpnY, wpnXWidth, wpnYHeight);
  602. }
  603.  
  604. bool ComboCollision(lweapon wpn, int loc){
  605. return ComboCollision(loc,wpn);
  606. }
  607.  
  608. //Check if you're using an item.
  609.  
  610. bool PressButtonItem(int itm){
  611. if(GetEquipmentA()==itm&&Link->PressA)return true;
  612. else if(GetEquipmentB()==itm&&Link->PressB)return true;
  613. return false;
  614. }
  615.  
  616. bool InputButtonItem(int itm){
  617. if(GetEquipmentA()==itm&&Link->InputA)return true;
  618. else if(GetEquipmentB()==itm&&Link->InputB)return true;
  619. return false;
  620. }
  621.  
  622. //Returns true if a weapon is on screen.
  623.  
  624. //Returns TRUE, if lweapon is inside screen boundaries.
  625. bool OnScreen (lweapon wpn){
  626. int lwx = wpn->X + wpn->HitXOffset;
  627. int lwy = wpn->Y + wpn->HitYOffset;
  628. if (lwx<0-wpn->HitWidth) return false;
  629. if (lwy<0-wpn->HitHeight) return false;
  630. if (lwx>256) return false;
  631. if (lwy>176) return false;
  632. return true;
  633. }
  634.  
  635. //Returns TRUE, if lweapon is inside screen boundaries.
  636. bool OnScreen (eweapon wpn){
  637. int lwx = wpn->X + wpn->HitXOffset;
  638. int lwy = wpn->Y + wpn->HitYOffset;
  639. if (lwx<0-wpn->HitWidth) return false;
  640. if (lwy<0-wpn->HitHeight) return false;
  641. if (lwx>256) return false;
  642. if (lwy>176) return false;
  643. return true;
  644. }
  645.  
  646. //Returns TRUE, if lweapon is inside screen boundaries.
  647. bool OnScreen (ffc wpn){
  648. int lwx = wpn->X;
  649. int lwy = wpn->Y;
  650. if (lwx<0-wpn->EffectWidth) return false;
  651. if (lwy<0-wpn->EffectHeight) return false;
  652. if (lwx>256) return false;
  653. if (lwy>176) return false;
  654. return true;
  655. }
  656.  
  657. //Returns TRUE, if lweapon is inside screen boundaries.
  658. bool OnScreen (npc wpn){
  659. int lwx = wpn->X + wpn->HitXOffset;
  660. int lwy = wpn->Y + wpn->HitYOffset;
  661. if (lwx<0-wpn->HitWidth) return false;
  662. if (lwy<0-wpn->HitHeight) return false;
  663. if (lwx>256) return false;
  664. if (lwy>176) return false;
  665. return true;
  666. }
  667.  
  668. //Returns TRUE, if lweapon is touching screen boundaries.
  669. bool OnScreenEdge(lweapon lw){
  670. int lwx = lw->X + lw->HitXOffset;
  671. int lwy = lw->Y + lw->HitYOffset;
  672. if ((lwx>=0-lw->HitWidth)&&(lwx<=0)){
  673. if (InsideScreen(lw)) return true;
  674. }
  675. if ((lwy>=0-lw->HitHeight)&&(lwy<=0)){
  676. if (InsideScreen(lw)) return true;
  677. }
  678. if ((lwx>=256-lw->HitWidth)&&(lwx<=256)){
  679. if (InsideScreen(lw)) return true;
  680. }
  681. if ((lwy>=176-lw->HitHeight)&&(lwy<=176)){
  682. if (InsideScreen(lw)) return true;
  683. }
  684. return false;
  685. }
  686.  
  687. //Returns TRUE, if lweapon is inside screen boundaries.
  688. bool InsideScreen (lweapon f){
  689. int lwx = f->X + f->HitXOffset;
  690. int lwy = f->Y + f->HitYOffset;
  691. if (lwx<0-f->HitWidth) return false;
  692. if (lwy<0-f->HitHeight) return false;
  693. if (lwx>256) return false;
  694. if (lwy>176) return false;
  695. return true;
  696. }
  697.  
  698. bool CanMove(npc e,int dir,int imprecision){
  699. int eX = e->X+e->HitXOffset;
  700. int eY = e->Y+e->HitYOffset;
  701. int eRtX = eX+e->HitWidth;
  702. int eBtY = eY+e->HitHeight;
  703. int eCentX = eX+(e->HitWidth/2);
  704. int eCentY = eY+(e->HitHeight/2);
  705. if(dir==DIR_UP){
  706. if(Screen->isSolid(eCentX,eY-imprecision))return false;
  707. if(ComboFI(ComboAt(eCentX,eY-imprecision),CF_NOENEMY))return false;
  708. if(Screen->ComboT[ComboAt(eCentX,eY-imprecision)]==CT_NOENEMY)return false;
  709. }
  710. else if(dir==DIR_DOWN){
  711. if(Screen->isSolid(eCentX,eBtY+imprecision))return false;
  712. if(ComboFI(ComboAt(eCentX,eBtY+imprecision),CF_NOENEMY))return false;
  713. if(Screen->ComboT[ComboAt(eCentX,eBtY+imprecision)]==CT_NOENEMY)return false;
  714. }
  715. else if(dir==DIR_LEFT){
  716. if(Screen->isSolid(eX-imprecision,eCentY))return false;
  717. if(ComboFI(ComboAt(eX-imprecision,eCentY),CF_NOENEMY))return false;
  718. if(Screen->ComboT[ComboAt(eX-imprecision,eCentY)]==CT_NOENEMY)return false;
  719. }
  720. else if(dir==DIR_RIGHT){
  721. if(Screen->isSolid(eRtX+imprecision,eCentY))return false;
  722. if(ComboFI(ComboAt(eRtX+imprecision,eCentY),CF_NOENEMY))return false;
  723. if(Screen->ComboT[ComboAt(eRtX+imprecision,eCentY)]==CT_NOENEMY)return false;
  724. }
  725. return true;
  726. }
  727.  
  728. bool CanMove(ffc e,int dir,int imprecision){
  729. int eX = e->X;
  730. int eY = e->Y;
  731. int eRtX = eX+e->EffectWidth;
  732. int eBtY = eY+e->EffectHeight;
  733. int eCentX = eX+(e->EffectWidth/2);
  734. int eCentY = eY+(e->EffectHeight/2);
  735. if(dir==DIR_UP){
  736. if(Screen->isSolid(eCentX,eY-imprecision))return false;
  737. }
  738. else if(dir==DIR_DOWN){
  739. if(Screen->isSolid(eCentX,eBtY+imprecision))return false;
  740. }
  741. else if(dir==DIR_LEFT){
  742. if(Screen->isSolid(eX-imprecision,eCentY))return false;
  743. }
  744. else if(dir==DIR_RIGHT){
  745. if(Screen->isSolid(eRtX+imprecision,eCentY))return false;
  746. }
  747. return true;
  748. }
  749.  
  750. bool CanMove(eweapon e,int dir,int imprecision){
  751. int eX = e->X+e->HitXOffset;
  752. int eY = e->Y+e->HitYOffset;
  753. int eRtX = eX+e->HitWidth;
  754. int eBtY = eY+e->HitHeight;
  755. int eCentX = eX+(e->HitWidth/2);
  756. int eCentY = eY+(e->HitHeight/2);
  757. if(dir==DIR_UP){
  758. if(Screen->isSolid(eCentX,eY-imprecision))return false;
  759. if(Screen->ComboT[ComboAt(eCentX,eY-imprecision)]==CT_BLOCKALL)return false;
  760. }
  761. else if(dir==DIR_DOWN){
  762. if(Screen->isSolid(eCentX,eBtY+imprecision))return false;
  763. if(Screen->ComboT[ComboAt(eCentX,eBtY+imprecision)]==CT_BLOCKALL)return false;
  764. }
  765. else if(dir==DIR_LEFT){
  766. if(Screen->isSolid(eX-imprecision,eCentY))return false;
  767. if(Screen->ComboT[ComboAt(eX-imprecision,eCentY)]==CT_BLOCKALL)return false;
  768. }
  769. else if(dir==DIR_RIGHT){
  770. if(Screen->isSolid(eRtX+imprecision,eCentY))return false;
  771. if(Screen->ComboT[ComboAt(eRtX+imprecision,eCentY)]==CT_BLOCKALL)return false;
  772. }
  773. return true;
  774. }
  775.  
  776. bool CanMove(lweapon e,int dir,int imprecision){
  777. int eX = e->X+e->HitXOffset;
  778. int eY = e->Y+e->HitYOffset;
  779. int eRtX = eX+e->HitWidth;
  780. int eBtY = eY+e->HitHeight;
  781. int eCentX = eX+(e->HitWidth/2);
  782. int eCentY = eY+(e->HitHeight/2);
  783. if(dir==DIR_UP){
  784. if(Screen->isSolid(eCentX,eY-imprecision))return false;
  785. if(Screen->ComboT[ComboAt(eCentX,eY-imprecision)]==CT_BLOCKALL)return false;
  786. }
  787. else if(dir==DIR_DOWN){
  788. if(Screen->isSolid(eCentX,eBtY+imprecision))return false;
  789. if(Screen->ComboT[ComboAt(eCentX,eBtY+imprecision)]==CT_BLOCKALL)return false;
  790. }
  791. else if(dir==DIR_LEFT){
  792. if(Screen->isSolid(eX-imprecision,eCentY))return false;
  793. if(Screen->ComboT[ComboAt(eX-imprecision,eCentY)]==CT_BLOCKALL)return false;
  794. }
  795. else if(dir==DIR_RIGHT){
  796. if(Screen->isSolid(eRtX+imprecision,eCentY))return false;
  797. if(Screen->ComboT[ComboAt(eRtX+imprecision,eCentY)]==CT_BLOCKALL)return false;
  798. }
  799. return true;
  800. }
  801.  
  802. bool DistX(lweapon a, int distance) {
  803. int dist;
  804. if ( a->X > Link->X ) dist = a->X - Link->X;
  805. else dist = Link->X - a->X;
  806. return ( dist <= distance );
  807. }
  808.  
  809. bool DistY(lweapon a, int distance) {
  810. int dist;
  811. if ( a->Y > Link->Y ) dist = a->Y - Link->Y;
  812. else dist = Link->Y - a->Y;
  813. return ( dist <= distance );
  814. }
  815.  
  816. //Returns the amount in radians for a direction.
  817.  
  818. float __DirtoRad(int dir){
  819. if(dir==DIR_UP)return DegtoRad(270);
  820. else if(dir==DIR_RIGHTUP)return DegtoRad(315);
  821. else if(dir==DIR_RIGHT)return DegtoRad(0);
  822. else if(dir==DIR_RIGHTDOWN)return DegtoRad(45);
  823. else if(dir==DIR_DOWN)return DegtoRad(90);
  824. else if(dir==DIR_LEFTDOWN)return DegtoRad(135);
  825. else if(dir==DIR_LEFT)return DegtoRad(180);
  826. else if(dir==DIR_LEFTUP)return DegtoRad(225);
  827. }
  828.  
  829. //Draws a screen specified by 'sourceMap and sourceScreen;, from layers specified by 'layerMin and layerMax',
  830. //at a desired opacity, to the layer specified by 'destLayer' of the current screen.
  831. void ScreenToLayer(int sourceMap, int sourceScreen, int layerMin, int layerMax, int drawOpacity, int destLayer){
  832. for (int i = layerMin; i < layerMax; i++){
  833. Screen->DrawLayer(destLayer, sourceMap, sourceScreen, i, 0, 0, 0, drawOpacity);
  834. }
  835. }
  836.  
  837. //Draws all layers of a screen specified by 'sourceMap and sourceScreen;,
  838. //at a desired opacity, to the layer specified by 'destLayer' of the current screen.
  839. void ScreenToLayer(int sourceMap, int sourceScreen, int drawOpacity, int destLayer){
  840. for (int i = 0; i < 6; i++){
  841. Screen->DrawLayer(destLayer, sourceMap, sourceScreen, i, 0, 0, 0, drawOpacity);
  842. }
  843. }
  844.  
  845. int ItemsToPickup[]={ I_ARROWAMMO1, I_ARROWAMMO5, I_ARROWAMMO10, I_ARROWAMMO30, //Stock arrow ammo.
  846. I_BOMBAMMO1, I_BOMBAMMO4, I_BOMBAMMO8, I_BOMBAMMO30, //Stock bomb ammo.
  847. I_FAIRY, I_FAIRYSTILL, I_HEART, I_MAGICJAR1, I_MAGICJAR2, //Stock refills.
  848. I_CLOCK, //Stock clock item.
  849. I_RUPEE1, I_RUPEE5, I_RUPEE10, I_RUPEE20, I_RUPEE50, I_RUPEE100, I_RUPEE200, //Stock Rupee Items
  850. I_KEY, I_LEVELKEY, //Stock keys.
  851. I_COMPASS, //Stock Dungeon Compass
  852. I_MAP, //Stock dungeon map.
  853. I_BOSSKEY, //Stock dungeon/level master key.
  854. I_HCPIECE};
  855.  
  856. //General Functions Zelda Header 1.1
  857.  
  858. //Extra Constants
  859.  
  860. //Misc Screen Flags
  861.  
  862. const int SF_MISC_SCRIPT1 = 0x0004; //General use 1 (Scripts)
  863. const int SF_MISC_SCRIPT2 = 0x0008; //General use 2 (Scripts)
  864. const int SF_MISC_SCRIPT3 = 0x0010; //General use 3 (Scripts)
  865. const int SF_MISC_SCRIPT4 = 0x0020; //General use 4 (Scripts)
  866. const int SF_MISC_SCRIPT5 = 0x0040; //General use 5 (Scripts)
  867.  
  868. //Scripted Lens Constants
  869.  
  870. const int INVISIBLE_MISC_INDEX = 0;//Used by scripted lens. Stores combo to draw.
  871. const int DRAWN_MISC_INDEX = 1;//Used by scripted lens. Tells whether or not to draw enemy.
  872. const int LENS_RADIUS = 60;//Width of scripted lens aperture.
  873.  
  874. //LW_ZH bools
  875.  
  876. //Test if one location is between two others.
  877. //D0- Location to test
  878. //D1- Lower bound
  879. //D2- Higher bound
  880.  
  881. bool Between(int loc,int greaterthan, int lessthan){
  882. if(loc>=greaterthan && loc<=lessthan)return true;
  883. return false;
  884. }
  885.  
  886. //Randomly set a bool's value to true or false.
  887.  
  888. bool ChooseBool() {
  889. if (Rand(0,1)==0) return true;
  890. else return false;
  891. }
  892.  
  893. //Checks for matching combo flag and type.
  894.  
  895. //D0- On scren location.
  896. //D1- Combo Flag to check.
  897. //D2- Combo Type to check.
  898.  
  899. bool ComboFIT(int loc,int flag,int type){
  900. if(ComboFI(loc,flag)&& Screen->ComboT[loc]==type)return true;
  901. return false;
  902. }
  903.  
  904. //Checks for matching combo flag and type.
  905.  
  906. //D0- On scren location.
  907. //D1- Combo Flag to check.
  908. //D2- Combo Type to check.
  909.  
  910. bool ComboFIT(int X, int Y,int flag,int type){
  911. int loc = ComboAt(X,Y);
  912. if(ComboFI(loc,flag)&& Screen->ComboT[loc]==type)return true;
  913. return false;
  914. }
  915.  
  916. //Checks if a screen flag has been toggled.
  917.  
  918. //D0- Category of flag
  919. //D1- Actual flag, in hex.
  920.  
  921. bool ScreenFlagTest(int category,int flag){
  922. return Screen->Flags[category]&flag;
  923. }
  924.  
  925. //Uses to make a boss using the Gen_Explode_Waitframe wait for a certain number of frames before doing something.
  926.  
  927. void Gen_Explode_Waitframes(ffc this, npc ghost,int frames){
  928. for(;frames>0;frames--){
  929. Gen_Explode_Waitframe(this,ghost);
  930. }
  931. }
  932.  
  933. //A general utility function to make a boss explode on death.
  934.  
  935. void Gen_Explode_Waitframe(ffc this, npc ghost){
  936. if(!Ghost_Waitframe(this, ghost, false, false)){
  937. Ghost_DeathAnimation(this, ghost, 2);
  938. Quit();
  939. }
  940. }
  941.  
  942. //General utility function for spawning another enemy when the main one dies.
  943. //Has same effects as Gen_Explode_Waitframe.
  944. //Set the original enemy's Misc 1 attribute to what enemy to spawn.
  945. //If no enemy is to be spawned, leave it at zero.
  946.  
  947. void Gen_Spawn_Waitframe(ffc this, npc ghost){
  948. if(!Ghost_Waitframe(this, ghost, false, false)){
  949. Ghost_DeathAnimation(this, ghost, 2);
  950. int EnemyToSpawn = Ghost_GetAttribute(ghost,0,0);
  951. if(EnemyToSpawn!=0){
  952. npc n = Screen->CreateNPC(EnemyToSpawn);
  953. n->X = ghost->X;
  954. n->Y = ghost->Y;
  955. }
  956. Quit();
  957. }
  958. }
  959.  
  960. void Gen_Spawn_Waitframes(ffc this, npc ghost, int frames){
  961. for(;frames>0;frames--)
  962. Gen_Spawn_Waitframe(this,ghost);
  963. }
  964.  
  965. //Kills all npcs on screen when this enemy dies.
  966.  
  967. void Gen_Leader_Waitframe(ffc this, npc ghost){
  968. if(!Ghost_Waitframe(this, ghost, false, false)){
  969. Ghost_DeathAnimation(this, ghost, 2);
  970. for(int i =Screen->NumNPCs();i>0;i--){
  971. npc n = Screen->LoadNPC(i);
  972. n->HP = 0;
  973. }
  974. Quit();
  975. }
  976. }
  977.  
  978. void Gen_Leader_Waitframes(ffc this, npc ghost, int frames){
  979. for(;frames>0;frames--)
  980. Gen_Leader_Waitframe(this,ghost);
  981. }
  982.  
  983. //A function to adjust an eweapon's hitbox size.
  984. //D0- Eweapon to adjust
  985. //D1- HitWidth
  986. //D2- HitHeight
  987. //D3- HitXOffset
  988. //D4- HitYOffset
  989.  
  990. void SetEWeaponHitbox(eweapon wpn, int HitWidth, int HitHeight, int HitXOffset, int HitYOffset){
  991. wpn->HitHeight = HitHeight;
  992. wpn->HitWidth = HitWidth;
  993. wpn->HitXOffset = HitXOffset;
  994. wpn->HitYOffset = HitYOffset;
  995. }
  996.  
  997. //A function to quickly change the size of an eweapon.
  998. //D0- EWeapon to adjust.
  999. //D1- Tile Width
  1000. //D2- Tile Height
  1001.  
  1002. void SetEWeaponSize(eweapon wpn, int TileWidth, int TileHeight){
  1003. wpn->Extend = 3;
  1004. wpn->TileHeight = TileHeight;
  1005. wpn->TileWidth = TileWidth;
  1006. }
  1007.  
  1008. //A function to change the current combo at a location.
  1009. //Changes id, cset and type.
  1010.  
  1011. //D0- Location to change.
  1012. //D1- Combo Id to change to.
  1013. //D2- Combo Cset to change to.
  1014. //D3- Combo Type to change to.
  1015.  
  1016. void ChangeCombo(int loc, int comboid, int cset, int type){
  1017. if(comboid>-1)Screen->ComboD[loc] = comboid;
  1018. if(cset>-1)Screen->ComboC[loc]= cset;
  1019. if(type>-1)Screen->ComboT[loc] = type;
  1020. }
  1021.  
  1022. //D0- Location to change.
  1023. //D1- Combo Id to change to.
  1024. //D2- Combo Cset to change to.
  1025. //D3- Combo Type to change to.
  1026. //D4- Placed flag to change to.
  1027.  
  1028. void ChangeCombo(int loc, int comboid,int cset,int type, int flag){
  1029. if(comboid>-1)Screen->ComboD[loc] = comboid;
  1030. if(cset>-1)Screen->ComboC[loc]= cset;
  1031. if(type>-1)Screen->ComboT[loc] = type;
  1032. if(flag>-1)Screen->ComboF[loc] = flag;
  1033. }
  1034.  
  1035. //D0- Location to change.
  1036. //D1- Combo Id to change to.
  1037. //D2- Combo Cset to change to.
  1038. //D3- Combo Type to change to.
  1039. //D4- Placed flag to change to.
  1040. //D5- Inherent flag to change to.
  1041.  
  1042. void ChangeCombo(int loc, int comboid,int cset,int type, int flag, int inh_flag){
  1043. if(comboid>-1)Screen->ComboD[loc] = comboid;
  1044. if(cset>-1)Screen->ComboC[loc]= cset;
  1045. if(type>-1)Screen->ComboT[loc] = type;
  1046. if(flag>-1)Screen->ComboF[loc] = flag;
  1047. if(inh_flag>-1)Screen->ComboI[loc] = inh_flag;
  1048. }
  1049.  
  1050. //A function to quickly change the size of an npc.
  1051. //D0- Npc to adjust.
  1052. //D1- Tile Width
  1053. //D2- Tile Height
  1054.  
  1055. void EnemyResize(npc enemy, int TileWidth, int TileHeight){
  1056. enemy->Extend = 3;
  1057. enemy->TileHeight = TileHeight;
  1058. enemy->TileWidth = TileWidth;
  1059. }
  1060.  
  1061. //A function to adjust an enemy's hitbox size.
  1062. //D0- Enemy to adjust
  1063. //D1- HitWidth
  1064. //D2- HitHeight
  1065. //D3- HitXOffset
  1066. //D4- HitYOffset
  1067.  
  1068. void SetEnemyHitbox(npc enemy, int HitWidth, int HitHeight, int HitXOffset, int HitYOffset){
  1069. enemy->HitHeight = HitHeight;
  1070. enemy->HitWidth = HitWidth;
  1071. enemy->HitXOffset = HitXOffset;
  1072. enemy->HitYOffset = HitYOffset;
  1073. }
  1074.  
  1075. //Combines enemy reaize and enemy set hitbox functions.
  1076.  
  1077. //D0- Enemy to set.
  1078. //D1- Tile width. Hit Width will be this times 16.
  1079. //D2- Tile Height. Hit height will be this times 16.
  1080.  
  1081. void Enemy_ExtendSimple(npc enemy,int TileWidth,int TileHeight){
  1082. EnemyResize(enemy,TileWidth,TileHeight);
  1083. SetEnemyHitbox(enemy,TileWidth*16,TileHeight*16,0,0);
  1084. }
  1085.  
  1086. //Draw an inverted circle (fill whole screen except circle)
  1087. //Also draws an enemy if it is invisible and ghosted.
  1088. void InvertedLensCircle(int bitmapID, int layer, int x, int y, int radius, int scale, int fillcolor,npc ghost){
  1089. Screen->SetRenderTarget(bitmapID); //Set the render target to the bitmap.
  1090. Screen->Rectangle(layer, 0, 0, 256, 176, fillcolor, 1, 0, 0, 0, true, 128); //Cover the screen
  1091. Screen->Circle(layer, x, y, radius, 0, scale, 0, 0, 0, true, 128); //Draw a transparent circle.
  1092. if(ghost->Dir==DIR_UP||ghost->Dir==DIR_LEFTUP)Screen->DrawCombo(layer, ghost->X, ghost->Y, ghost->Misc[INVISIBLE_MISC_INDEX], ghost->TileWidth, ghost->TileHeight, ghost->Attributes[8], -1, -1, 0, 0, 0, -1, 0, true, OP_OPAQUE);
  1093. else if(ghost->Dir==DIR_DOWN ||ghost->Dir== DIR_RIGHTDOWN)Screen->DrawCombo(layer, ghost->X, ghost->Y, ghost->Misc[INVISIBLE_MISC_INDEX]+1, ghost->TileWidth, ghost->TileHeight, ghost->Attributes[8], -1, -1, 0, 0, 0, -1, 0, true, OP_OPAQUE);
  1094. else if(ghost->Dir==DIR_LEFT||ghost->Dir== DIR_LEFTDOWN)Screen->DrawCombo(layer, ghost->X, ghost->Y, ghost->Misc[INVISIBLE_MISC_INDEX]+2, ghost->TileWidth, ghost->TileHeight, ghost->Attributes[8], -1, -1, 0, 0, 0, -1, 0, true, OP_OPAQUE);
  1095. else if(ghost->Dir==DIR_RIGHT||ghost->Dir== DIR_RIGHTUP)Screen->DrawCombo(layer, ghost->X, ghost->Y, ghost->Misc[INVISIBLE_MISC_INDEX]+3, ghost->TileWidth, ghost->TileHeight, ghost->Attributes[8], -1, -1, 0, 0, 0, -1, 0, true, OP_OPAQUE);
  1096. Screen->SetRenderTarget(RT_SCREEN); //Set the render target back to the screen.
  1097. Screen->DrawBitmap(layer, bitmapID, 0, 0, 256, 176, 0, 0, 256, 176, 0, true); //Draw the bitmap
  1098. }
  1099.  
  1100. //Draws scripted enemies with scripted lens.
  1101.  
  1102. void Drawn_Enemy_Waitframe(ffc this, npc ghost){
  1103. if(Ghost_Waitframe(this,ghost,false,false)){
  1104. if(ghost->Misc[DRAWN_MISC_INDEX]==1)InvertedLensCircle(4, 6, CenterLinkX(), CenterLinkY(), LENS_RADIUS, 1, 15,ghost);
  1105. }
  1106. else if(!Ghost_Waitframe(this, ghost, false, false)){
  1107. Ghost_DeathAnimation(this, ghost, 2);
  1108. Quit();
  1109. }
  1110. }
  1111.  
  1112. //Same as above, but multiple frames.
  1113.  
  1114. void Drawn_Enemy_Waitframes(ffc this,npc ghost,int frames){
  1115. for(;frames>0;frames--)
  1116. Drawn_Enemy_Waitframe(this,ghost);
  1117. }
  1118.  
  1119. //Removes a specific eweapon type.
  1120.  
  1121. void RemoveEWeaponType(int type){
  1122. for(int i = 1;i<=Screen->NumEWeapons();i++){
  1123. eweapon e = Screen->LoadEWeapon(i);
  1124. if(e->ID==type)Remove(e);
  1125. }
  1126. }
  1127.  
  1128. //Traces Current Dmap and Screen numbers.
  1129.  
  1130. void TraceDMapScreen(){
  1131. int DMAP[]= "The current DMap number is ";
  1132. int SCREEN[]= "The current screen number is ";
  1133. TraceS(DMAP);
  1134. Trace(Game->GetCurDMap());
  1135. TraceNL();
  1136. TraceS(SCREEN);
  1137. Trace(Game->GetCurDMapScreen());
  1138. }
  1139.  
  1140. //Calculates Average distance between two points, for a certain number of times.
  1141.  
  1142. //D0- First X or Y.
  1143. //D1- Second X or Y.
  1144. //D2- Number of times to divide.
  1145.  
  1146. int CalcXY(int XY1,int XY2, int NumberOfParts){
  1147. return (Abs(XY1-XY2))/NumberOfParts;
  1148. }
  1149.  
  1150. int CalcX(int X1,int X2, int NumberOfParts){
  1151. return (Abs(X1-X2))/NumberOfParts;
  1152. }
  1153.  
  1154. int CalcY(int Y1,int Y2, int NumberOfParts){
  1155. return (Abs(Y1-Y2))/NumberOfParts;
  1156. }
  1157.  
  1158. //Returns the correct offset to be 'dist' pixels away from the front of a sprite facing in the direction 'dir'
  1159.  
  1160. int FixedInFrontX(int dir, int dist) {
  1161. int x = 0;
  1162. if(dir == DIR_LEFT) x = -dist;
  1163. else if(dir == DIR_RIGHT) x = dist;
  1164. return x;
  1165. }
  1166.  
  1167. int FixedInFrontY(int dir, int dist){
  1168. int y = 0;
  1169. if(dir == DIR_UP) y = -dist;
  1170. else if(dir == DIR_DOWN) y = 16+dist;
  1171. return y;
  1172. }
  1173.  
  1174. int TrueFixedInFrontY(int dir, int dist){
  1175. int y = 0;
  1176. if(dir == DIR_UP) y = -dist;
  1177. else if(dir == DIR_DOWN) y = dist;
  1178. return y;
  1179. }
  1180.  
  1181. //Example LWeapons.zh global script
  1182.  
  1183. global script LW_Active{
  1184. void run(){
  1185. while(true){
  1186. //Various commands here.
  1187. //Call LWeapon handling, for before waitdraw stuff.
  1188. UpdateLWZH1();
  1189. Waitdraw();
  1190. //Call LWeapon Handling.
  1191. UpdateLWZH2();
  1192. //TraceLWeapons();
  1193. Waitframe();
  1194. }
  1195. }
  1196. }
  1197.  
  1198. void TraceLWeapons(){
  1199. for(int i= Screen->NumLWeapons();i>0;i--){
  1200. lweapon wpn = Screen->LoadLWeapon(i);
  1201. if((wpn->Misc[LW_ZH_I_FLAGS]&__LWFI_IS_LWZH_LWPN)==0)
  1202. continue;
  1203. int buffer []= "Flags are ";
  1204. TraceS(buffer);
  1205. Trace(wpn->Misc[LW_ZH_I_FLAGS]);
  1206. int buffer2 []= "Lifespan is ";
  1207. TraceS(buffer2);
  1208. Trace(wpn->Misc[LW_ZH_I_LIFESPAN_ARG]);
  1209. int buffer3 []= "Movement is ";
  1210. TraceS(buffer3);
  1211. Trace(wpn->Misc[LW_ZH_I_MOVEMENT]);
  1212. int buffer4[]= "Death effect is ";
  1213. TraceS(buffer4);
  1214. Trace(wpn->Misc[LW_ZH_I_ON_DEATH]);
  1215. }
  1216. }
  1217.  
  1218. //LW_ZH Life and Death Functions
  1219.  
  1220. // Set an lweapon's lifespan
  1221. void SetLWeaponLifespan(lweapon wpn, int type, int arg)
  1222. {
  1223. wpn->Misc[LW_ZH_I_LIFESPAN]=type;
  1224. wpn->Misc[LW_ZH_I_LIFESPAN_ARG]=arg;
  1225. //wpn->Misc[LW_ZH_I_FLAGS]|=__LWFI_IS_LWZH_LWPN;
  1226. }
  1227.  
  1228. // Set an lweapon to use a standard death effect
  1229. void SetLWeaponDeathEffect(lweapon wpn, int type, int arg)
  1230. {
  1231. wpn->Misc[LW_ZH_I_ON_DEATH]=type;
  1232. wpn->Misc[LW_ZH_I_ON_DEATH_ARG]=arg;
  1233. //wpn->Misc[LW_ZH_I_FLAGS]|=__LWFI_IS_LWZH_LWPN;
  1234. }
  1235.  
  1236. //LWeapon Death Effects
  1237.  
  1238. //This lweapon aims at an enemy.
  1239.  
  1240. void __DoLWeaponDeathAimAtNPC(lweapon wpn){
  1241. wpn->Step=0;
  1242. wpn->Misc[LW_ZH_I_WORK]=0;
  1243. wpn->Misc[LW_ZH_I_ON_DEATH_ARG]-=1;
  1244. float targetAngle;
  1245. npc target_enemy;
  1246. if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]<=0){
  1247. if(Screen->NumNPCs()>0){
  1248. wpn->Misc[LW_ZH_I_WORK] = Rand(1,Screen->NumNPCs());
  1249. for(int i=1;i<=Screen->NumNPCs();i++){
  1250. target_enemy = Screen->LoadNPC(i);
  1251. if(target_enemy->ID==wpn->Misc[LW_ZH_I_WORK] &&
  1252. target_enemy->Defense[LWDefense(wpn->ID)]!=NPCDT_BLOCK||
  1253. target_enemy->Defense[LWDefense(wpn->ID)]!=NPCDT_IGNORE)
  1254. target_enemy->Misc[NPC_MISC_TARGET_NUMBER]=wpn->Misc[LW_ZH_I_WORK];
  1255. }
  1256. if(target_enemy->HP<=0)wpn->Misc[LW_ZH_I_WORK]=0;
  1257. if(target_enemy->Misc[NPC_MISC_TARGET_NUMBER]==wpn->Misc[LW_ZH_I_WORK])
  1258. targetAngle=RadianAngle(wpn->X, wpn->Y, target_enemy->X, target_enemy->Y);
  1259. wpn->Angle=targetAngle;
  1260. SetLWeaponDir(wpn);
  1261. wpn->Step=300;
  1262. wpn->Misc[LW_ZH_I_ON_DEATH]=0;
  1263. }
  1264. else
  1265. wpn->DeadState = 0;
  1266. }
  1267. // Spin while waiting
  1268. wpn->Angle+=0.3;
  1269. return;
  1270. // Pick a direction based on the counter
  1271. int dir=wpn->Misc[LW_ZH_I_ON_DEATH_ARG]&110b;
  1272. if(dir==110b)
  1273. SetLWeaponRotation(wpn, DIR_UP);
  1274. else if(dir==100b)
  1275. SetLWeaponRotation(wpn, DIR_RIGHT);
  1276. else if(dir==010b)
  1277. SetLWeaponRotation(wpn, DIR_DOWN);
  1278. else
  1279. SetLWeaponRotation(wpn, DIR_LEFT);
  1280. }
  1281.  
  1282.  
  1283.  
  1284. // Some of these could probably be combined...
  1285.  
  1286. //This lweapon explodes in a bomb blast.
  1287.  
  1288. void __DoLWeaponDeathExplode(lweapon wpn)
  1289. {
  1290. FireNonAngularLWeapon(LW_BOMBBLAST, CenterX(wpn)-8, CenterY(wpn)-8, wpn->Dir, 0, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], -1, 0, LWF_PIERCES_ENEMIES);
  1291. wpn->DeadState=0;
  1292. }
  1293.  
  1294. //This lweapon explodes in a super bomb blast.
  1295.  
  1296. void __DoLWeaponDeathSBombExplode(lweapon wpn)
  1297. {
  1298. FireNonAngularLWeapon(LW_SBOMBBLAST, CenterX(wpn)-8, CenterY(wpn)-8, wpn->Dir, 0, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], -1, 0, LWF_PIERCES_ENEMIES);
  1299. wpn->DeadState=0;
  1300. }
  1301.  
  1302. //This lweapon produces 4 horizontal and vertical lweapons.
  1303.  
  1304. void __DoLWeaponDeath4FireballsHV(lweapon wpn)
  1305. {
  1306. for(int i=0; i<270; i+=90)
  1307. FireLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 200, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1308. wpn->DeadState=0;
  1309. }
  1310.  
  1311. //This lweapon produces 4 diagonal lweapons.
  1312.  
  1313. void __DoLWeaponDeath4FireballsDiag(lweapon wpn)
  1314. {
  1315. for(int i=45; i<315; i+=90)
  1316. FireLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 200, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1317. wpn->DeadState=0;
  1318. }
  1319.  
  1320. //This lweapon produces 4 random lweapons.
  1321.  
  1322. void __DoLWeaponDeath4FireballsRand(lweapon wpn)
  1323. {
  1324. if(Rand(2)==0)
  1325. {
  1326. for(int i=0; i<270; i+=90)
  1327. FireLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 200, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1328. }
  1329. else
  1330. {
  1331. for(int i=45; i<315; i+=90)
  1332. lweapon new = FireNonAngularLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 200, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1333. }
  1334. wpn->DeadState=0;
  1335. }
  1336.  
  1337. //This lweapon makes lweapons in all 8 directions.
  1338.  
  1339. void __DoLWeaponDeath8Fireballs(lweapon wpn)
  1340. {
  1341. for(int i=0; i<315; i+=45)
  1342. FireLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 200, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1343. wpn->DeadState=0;
  1344. }
  1345.  
  1346. //This lweapon creates an lweapon that freezes (stuns) enemies when it dies..
  1347.  
  1348. void __DoLWeaponDeathFreeze(lweapon wpn){
  1349. lweapon new = FireLWeapon(LW_SCRIPT1, wpn->X, wpn->Y, 0, 0, 0, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], SFX_ICE, LWF_STUNS_ENEMIES|LWF_PIERCES_ENEMIES);
  1350. SetLWeaponLifespan(new,LWL_TIMER,wpn->Misc[LW_ZH_I_LIFESPAN_ARG]);
  1351. wpn->DeadState=0;
  1352. }
  1353.  
  1354. //Handles lweapon that creates a projectile on death.
  1355.  
  1356. //void __DoLWeaponDeathLW(lweapon wpn){
  1357. //if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]!=LWDT_FIRE_ROD &&
  1358. //wpn->Misc[LW_ZH_I_ON_DEATH_ARG]!=LWDT_ICE_ROD &&
  1359. //wpn->Misc[LW_ZH_I_ON_DEATH_ARG]!=LWDT_POT &&
  1360. //wpn->Misc[LW_ZH_I_ON_DEATH_ARG]!=LWDT_BUSH &&
  1361. //wpn->Misc[LW_ZH_I_ON_DEATH_ARG]!=LWDT_ROCK &&
  1362. //wpn->Misc[LW_ZH_I_ON_DEATH_ARG]<=40)
  1363. //FireLWeapon(wpn->Misc[LW_ZH_I_ON_DEATH_ARG], wpn->X+InFrontX(wpn->Dir,2),
  1364. //wpn->Y+InFrontY(wpn->Dir,2), RadianAngleDir8(wpn->Dir), 200,
  1365. //wpn->Damage/2, wpn->Misc[LW_ZH_I_WORK], wpn->Misc[LW_ZH_I_FX], wpn->Misc[LW_ZH_I_FLAGS]);
  1366. //else{
  1367. //if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_FIRE_ROD){
  1368. //if(!Link->Item[I_BOOK])Link->Item[I_BOOK]= true;
  1369. //lweapon new = FireLWeapon(LW_MAGIC, wpn->X+InFrontX(wpn->Dir,2),
  1370. //wpn->Y+InFrontY(wpn->Dir,2), RadianAngleDir8(wpn->Dir), 200,
  1371. //wpn->Damage/2, wpn->Misc[LW_ZH_I_WORK], SFX_WAND, wpn->Misc[LW_ZH_I_FLAGS]);
  1372. //SetLWeaponLifespan(new,LWL_EDGE,I_BOOK);
  1373. //lweapon new1 = FireLWeapon(LW_SCRIPT1, wpn->X+InFrontX(wpn->Dir,2),
  1374. //wpn->Y+InFrontY(wpn->Dir,2), RadianAngleDir8(wpn->Dir), 200,
  1375. //wpn->Damage/2, wpn->Misc[LW_ZH_I_WORK], 0, wpn->Misc[LW_ZH_I_FLAGS]);
  1376. //SetLWeaponMovement(new1,LWM_FOLLOW,LW_MAGIC,0);
  1377. //SetLWeaponDeathEffect(new1,LWD_FIRE,SPR_WAND_FIRE);
  1378. //new1->Misc[LW_ZH_I_FLAGS_2]|=LWF_LEVEL_1|LWF_LEVEL_2|LWF_LEVEL_3;
  1379. //}
  1380. //else if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_ICE_ROD){
  1381. //lweapon new = FireLWeapon(LW_MAGIC, wpn->X+InFrontX(wpn->Dir,2),
  1382. //wpn->Y+InFrontY(wpn->Dir,2), RadianAngleDir8(wpn->Dir), 200,
  1383. //wpn->Damage/2, wpn->Misc[LW_ZH_I_WORK], SFX_WAND, wpn->Misc[LW_ZH_I_FLAGS]);
  1384. //SetLWeaponLifespan(new,LWL_EDGE,0);
  1385. //lweapon new1 = FireLWeapon(LW_SCRIPT1, wpn->X+InFrontX(wpn->Dir,2),
  1386. //wpn->Y+InFrontY(wpn->Dir,2), RadianAngleDir8(wpn->Dir), 200,
  1387. //wpn->Damage/2, wpn->Misc[LW_ZH_I_WORK], 0, wpn->Misc[LW_ZH_I_FLAGS]|LWF_FREEZE);
  1388. //SetLWeaponMovement(new1,LWM_FOLLOW,LW_MAGIC,0);
  1389. //SetLWeaponDeathEffect(new1,LWD_LW,LWDT_ICE_BLOCK);
  1390. //}
  1391. //else if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_POT
  1392. //||wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_BUSH
  1393. //||wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_ROCK
  1394. //||wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_THR_SOM
  1395. //||wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_GRENADE){
  1396. //lweapon new;
  1397. //if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_POT)
  1398. //new= FireLWeapon(LW_SCRIPT1,wpn->X,wpn->Y,RadianAngleDir8(Link->Dir),200,
  1399. //wpn->Damage/2,SPR_POT,SFX_THROW,wpn->Misc[LW_ZH_I_FLAGS]);
  1400. //else if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_BUSH)
  1401. //new = FireLWeapon(LW_SCRIPT1,wpn->X,wpn->Y,RadianAngleDir8(Link->Dir),200,
  1402. //wpn->Damage/2,SPR_BUSH,SFX_THROW,wpn->Misc[LW_ZH_I_FLAGS]);
  1403. //else if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_ROCK)
  1404. //new = FireLWeapon(LW_SCRIPT1,wpn->X,wpn->Y,RadianAngleDir8(Link->Dir),200,
  1405. //wpn->Damage/2,SPR_ROCK,SFX_THROW,wpn->Misc[LW_ZH_I_FLAGS]);
  1406. //else if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_THR_SOM){
  1407. //new = FireLWeapon(LW_SCRIPT1,wpn->X,wpn->Y,RadianAngleDir8(Link->Dir),200,
  1408. //wpn->Damage/2,SPR_SOMARIA_BLOCK,0,wpn->Misc[LW_ZH_I_FLAGS]);
  1409. //SetLWeaponLifespan(new,LWL_ITEM_PRESS,I_CSOMARIA);
  1410. //SetLWeaponMovement(new,LWM_THROW,0,LWMF_REST);
  1411. //SetLWeaponDeathEffect(new,LWD_4_FIREBALLS_DIAG,SPR_SOMARIA_FIRE);
  1412. //}
  1413. //else if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_GRENADE){
  1414. //new = FireLWeapon(LW_BOMB,wpn->X,wpn->Y,RadianAngleDir8(Link->Dir),200,
  1415. //wpn->Damage/2,SPR_SOMARIA_BLOCK,0,wpn->Misc[LW_ZH_I_FLAGS]);
  1416. //SetLWeaponDeathEffect(new,LWD_EXPLODE,new->Damage);
  1417. //}
  1418. //if(new->Misc[LW_ZH_I_MOVEMENT]==0)
  1419. //SetLWeaponMovement(new,LWM_THROW,0,LWMF_DIE);
  1420. //}
  1421. //else if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_SOMARIA){
  1422. //lweapon new = FireLWeapon(LW_SCRIPT10,wpn->X,wpn->Y,RadianAngleDir8(wpn->Dir),0,
  1423. //wpn->Damage/2,SPR_SOMARIA_BLOCK,0,wpn->Misc[LW_ZH_I_FLAGS]);
  1424. //SetLWeaponMovement(new,LWM_REST,LWM_R_SOMARIA,0);
  1425. //SetLWeaponDeathEffect(new,LWL_ITEM_PRESS,I_CSOMARIA);
  1426. //}
  1427. //else if(wpn->Misc[LW_ZH_I_ON_DEATH_ARG]==LWDT_ICE_BLOCK)
  1428. //lweapon new = FireLWeapon(LW_SCRIPT1,wpn->X,wpn->Y,RadianAngleDir8(wpn->Dir),0,
  1429. //wpn->Damage/2,SPR_ICE_BLOCK,0,wpn->Misc[LW_ZH_I_FLAGS]);
  1430. //}
  1431. //wpn->DeadState=0;
  1432. //}
  1433.  
  1434. //Handles lweapon that throws an object on death.
  1435.  
  1436. //void __DoLweaponDeathThrow(lweapon wpn){
  1437. //if((wpn->Misc[LW_ZH_I_ON_DEATH_ARG]&LW_THR_POT)!=0)
  1438.  
  1439. //if((wpn->Misc[LW_ZH_I_ON_DEATH_ARG]&LW_THR_BUSH)!=0)
  1440.  
  1441. //if((wpn->Misc[LW_ZH_I_ON_DEATH_ARG]&LW_THR_SOM)!=0)
  1442. //FireLWeapon(LW_SCRIPT1,wpn->X,wpn->Y,DegtoRad(270),200,
  1443. //wpn->Damage/2,SPR_SOMARIA,SFX_THROW,wpn->Misc{LW_ZH_I_FLAGS])
  1444. //if((wpn->Misc[LW_ZH_I_ON_DEATH_ARG]&LW_THR_BOMB)!=0)
  1445. //FireLWeapon(LW_BOMB,wpn->X,wpn->Y,DegtoRad(270),200,
  1446. //wpn->Damage/2,SPR_BOMB,SFX_THROW,wpn->Misc{LW_ZH_I_FLAGS])
  1447. //SetLWeaponMovement(FireLWeapon,LWM_THROW,0);
  1448. //wpn->DeadState=0;
  1449. //}
  1450.  
  1451. //Same as above... Redundant?
  1452.  
  1453. //void __DoLWeaponDeath4FiresHV(lweapon wpn)
  1454. //{
  1455. //for(int i=0; i<4; i++)
  1456. //FireNonAngularLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, i, 100, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1457. //Game->PlaySound(SFX_FIRE); // Only play sound once
  1458. //wpn->DeadState=0;
  1459. //}
  1460.  
  1461. void __DoLWeaponDeath4FiresDiag(lweapon wpn)
  1462. {
  1463. for(int i=45; i<315; i+=90)
  1464. FireLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 71, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1465. Game->PlaySound(SFX_FIRE);
  1466. wpn->DeadState=0;
  1467. }
  1468.  
  1469. void __DoLWeaponDeath4FiresRand(lweapon wpn)
  1470. {
  1471. if(Rand(2)==0)
  1472. {
  1473. for(int i=0; i<270; i+=90)
  1474. FireNonAngularLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 100, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1475. }
  1476. else
  1477. {
  1478. for(int i=45; i<315; i+=90)
  1479. FireLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 71, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1480. }
  1481. Game->PlaySound(SFX_FIRE);
  1482. wpn->DeadState=0;
  1483. }
  1484.  
  1485. void __DoLWeaponDeath8Fires(lweapon wpn)
  1486. {
  1487. for(int i=0; i<270; i+=90)
  1488. FireLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 100, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1489. for(int i=45; i<315; i+=90)
  1490. FireNonAngularLWeapon(LW_SCRIPT1, CenterX(wpn)-8, CenterY(wpn)-8, DegtoRad(i), 71, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1491. Game->PlaySound(SFX_FIRE);
  1492. wpn->DeadState=0;
  1493. }
  1494.  
  1495. void __DoLWeaponDeathSingleFire(lweapon wpn)
  1496. {
  1497. FireLWeapon(LW_FIRE, CenterX(wpn)-8, CenterY(wpn)-8, wpn->Dir, 0, wpn->Damage/2, wpn->Misc[LW_ZH_I_ON_DEATH_ARG], 0, 0);
  1498. Game->PlaySound(SFX_FIRE);
  1499. wpn->DeadState=0;
  1500. }
  1501.  
  1502. //Causes lweapon to home on given point. If "accel" boolean is set to TRUE, the function affects FFC`s
  1503. //acceleration, instead of velocity.
  1504. void __DoLWeaponDeathReturn(lweapon wpn){
  1505. //This is a boomerang.
  1506. if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_BRANG){
  1507. //Calculate the X and Y center of the weapon.
  1508. int fx = CenterX (wpn);
  1509. int fy = CenterY (wpn);
  1510. //Calculate angle from Link to Lweapon
  1511. int hdir = Angle(fx, fy, CenterLinkX(),CenterLinkY());
  1512. //Move weapon along that path towards Link.
  1513. wpn->Misc[LW_ZH_I_XPOS]= wpn->X+ ((wpn->Step/100)*Cos(hdir));
  1514. wpn->Misc[LW_ZH_I_YPOS]= wpn->Y+ ((wpn->Step/100)*Sin(hdir));
  1515. wpn->X=wpn->Misc[LW_ZH_I_XPOS];
  1516. wpn->Y=wpn->Misc[LW_ZH_I_YPOS];
  1517. //Set the weapon to pierce if it doesn't already.
  1518. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_PIERCES_ENEMIES)==0)
  1519. wpn->Misc[LW_ZH_I_FLAGS]|=LWF_PIERCES_ENEMIES;
  1520. //Set it not to collide with enemies.
  1521. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_NO_COLLISION;
  1522. //This lweapon has reached Link. Kill it.
  1523. if(LinkCollision(wpn))
  1524. wpn->DeadState = 0;
  1525. }
  1526. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_HOOKSHOT){
  1527. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_NO_COLLISION;
  1528. if(wpn->Dir==DIR_LEFT||wpn->Dir==DIR_RIGHT){
  1529. if(Abs(wpn->X-Link->X+8)>0){
  1530. if(wpn->Dir==DIR_LEFT)wpn->Misc[LW_ZH_I_XPOS]++;
  1531. else if(wpn->Dir==DIR_RIGHT)wpn->Misc[LW_ZH_I_XPOS]--;
  1532. for(int i =0;i<=wpn->Misc[LW_ZH_I_WORK];i++){
  1533. lweapon particle = FireScriptedLWeapon(LW_SCRIPT2, Calc(wpn->X,Link->X+8,wpn->Misc[LW_ZH_I_MOVEMENT_ARG]), wpn->Y, wpn->Misc[LW_ZH_I_MOVEMENT_ARG2], 0, 0,LWF_NO_COLLISION);
  1534. SetLWeaponLifespan(particle,LWL_TIMER,1);
  1535. SetLWeaponDeathEffect(particle,LWD_VANISH,0);
  1536. }
  1537. NoAction();
  1538. }
  1539. else{
  1540. KillLWeapon(wpn);
  1541. Link->CollDetection = true;
  1542. RemoveLWeaponType(LW_SCRIPT2);
  1543. }
  1544. }
  1545. else{
  1546. if(Abs(wpn->Y-Link->Y+8)>0){
  1547. if(wpn->Dir==DIR_UP)wpn->Misc[LW_ZH_I_YPOS]++;
  1548. else if(wpn->Dir==DIR_DOWN)wpn->Misc[LW_ZH_I_YPOS]--;
  1549. for(int i =0;i<=wpn->Misc[LW_ZH_I_MOVEMENT_ARG];i++){
  1550. lweapon particle = FireScriptedLWeapon(LW_SCRIPT2, wpn->X, Calc(wpn->Y,Link->Y+8,wpn->Misc[LW_ZH_I_MOVEMENT_ARG]), wpn->Misc[LW_ZH_I_MOVEMENT_ARG2], 0, 0,LWF_NO_COLLISION);
  1551. SetLWeaponLifespan(particle,LWL_TIMER,1);
  1552. SetLWeaponDeathEffect(particle,LWD_VANISH,0);
  1553. }
  1554. NoAction();
  1555. }
  1556. else{
  1557. KillLWeapon(wpn);
  1558. Link->CollDetection = true;
  1559. RemoveLWeaponType(LW_SCRIPT2);
  1560. }
  1561. }
  1562. }
  1563. SetLWeaponDir(wpn);
  1564. }
  1565.  
  1566. //LW_ZH Movement functions
  1567.  
  1568. //Set up an lweapon's movement.
  1569.  
  1570. //D0- Lweapon to alter.
  1571. //D1= Type of movement.
  1572. //D2- Movement argument one.
  1573. //D3- Movement argument two.
  1574.  
  1575. // Set an lweapon's movement type
  1576. void SetLWeaponMovement(lweapon wpn, int type, int arg, int arg2)
  1577. {
  1578. wpn->Misc[LW_ZH_I_XPOS]= wpn->X;
  1579. wpn->Misc[LW_ZH_I_YPOS]= wpn->Y;
  1580. wpn->Misc[LW_ZH_I_WORK]=0;
  1581. wpn->Misc[LW_ZH_I_MOVEMENT]=type;
  1582. wpn->Misc[LW_ZH_I_MOVEMENT_ARG]=arg;
  1583. wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]=arg2;
  1584. //wpn->Misc[LW_ZH_I_FLAGS]|=__LWFI_IS_LWZH_LWPN;
  1585. if(type!=LWM_FALL)wpn->Angular = true;
  1586. if(type==LWM_THROW){
  1587. wpn->Misc[LW_ZH_I_WORK_2]=wpn->Z;
  1588.  
  1589. // Necessary upward velocity to reach Link for thrown weapons
  1590. if(arg<=0){
  1591. if(Screen->NumNPCs()>0){
  1592. if(wpn->Misc[LW_ZH_I_WORK]==0)wpn->Misc[LW_ZH_I_WORK] = Rand(1,Screen->NumNPCs());
  1593. npc target_enemy = Screen->LoadNPC(wpn->Misc[LW_ZH_I_WORK]);
  1594. target_enemy->Misc[NPC_MISC_TARGET_NUMBER]=wpn->Misc[LW_ZH_I_WORK];
  1595. if(target_enemy->HP<=0)wpn->Misc[LW_ZH_I_WORK]=0;
  1596. if(target_enemy->Misc[NPC_MISC_TARGET_NUMBER]==wpn->Misc[LW_ZH_I_WORK]){
  1597. float time=Distance(wpn->X, wpn->Y, target_enemy->X,target_enemy->Y)/(wpn->Step/100);
  1598. wpn->Misc[LW_ZH_I_MOVEMENT_ARG]=GH_GRAVITY*time/2;
  1599. }
  1600. }
  1601. }
  1602. }
  1603. else if(type==LWM_FALL){
  1604. wpn->Z=arg;
  1605. wpn->Misc[LW_ZH_I_WORK_2]=arg;
  1606. wpn->Misc[LW_ZH_I_WORK]=GH_GRAVITY;
  1607. }
  1608. else if(type==LWM_CIRCLE)
  1609. wpn->Misc[LW_ZH_I_WORK]= RadtoDeg(wpn->Angle);
  1610. }
  1611.  
  1612. //Other Lweapons stuff
  1613.  
  1614. void SetLWeaponSFX(lweapon wpn, int type, int arg){
  1615. wpn->Misc[LW_ZH_I_FX]= type;
  1616. wpn->Misc[LW_ZH_I_WORK_2]= arg;
  1617. }
  1618.  
  1619. //Set up the lweapon and ffc to track one another.
  1620.  
  1621. void SetLWeaponScript(lweapon wpn, int script_num, int Misc_Num){
  1622. wpn->Misc[LW_ZH_I_WORK_3]= Misc_Num;//Save a specific number.
  1623. //Send that number to the ffc.
  1624. int Args[8]= {Misc_Num};
  1625. RunFFCScript(script_num,Args);
  1626. }
  1627.  
  1628. //Returns the right index in Npc->Defense for a lweapon type.
  1629.  
  1630. int LWDefense(int type){
  1631. if(type==LW_ARROW)return NPCD_ARROW;
  1632. else if(type == LW_BEAM)return NPCD_BEAM;
  1633. else if(type == LW_BRANG)return NPCD_BRANG;
  1634. else if(type == LW_BOMBBLAST)return NPCD_BOMB;
  1635. else if(type == LW_SBOMBBLAST)return NPCD_SBOMB;
  1636. else if(type == LW_FIRE)return NPCD_FIRE;
  1637. else if(type == LW_MAGIC)return NPCD_MAGIC;
  1638. else if(Between(type,LW_SCRIPT1,LW_SCRIPT10))return NPCD_SCRIPT;
  1639. }
  1640.  
  1641. //Calculate average distance.
  1642.  
  1643. //D0- First coordinate
  1644. //D1- Second coordinate
  1645. //D2- Divisor
  1646.  
  1647. int Calc(int x1, int x2, int numParts){
  1648. return (Abs(x1-x2))/numParts;
  1649. }
  1650.  
  1651. //Returns what combo types block this LWeapon
  1652.  
  1653. int LWBlockType(lweapon wpn){
  1654. if(wpn->ID==LW_MAGIC)return CT_BLOCKMAGIC;
  1655. else if(wpn->ID==LW_BEAM)return CT_BLOCKSWORDBEAM;
  1656. else if(wpn->ID==LW_ARROW){
  1657. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)return CT_BLOCKARROW1;
  1658. else if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)return CT_BLOCKARROW2;
  1659. else
  1660. return CT_BLOCKARROW3;
  1661. }
  1662. else if(wpn->ID==LW_BRANG){
  1663. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0) return CT_BLOCKBRANG1;
  1664. else if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)return CT_BLOCKBRANG2;
  1665. else
  1666. return CT_BLOCKBRANG3;
  1667. }
  1668. else
  1669. return CT_BLOCKALL;
  1670. }
  1671.  
  1672. //Returns the combo type that blocks an lweapon. Uses for dual lweapons.
  1673.  
  1674. int LWBlockType(int wpn_id,lweapon wpn){
  1675. if(wpn_id==LW_MAGIC)return CT_BLOCKMAGIC;
  1676. else if(wpn_id==LW_BEAM)return CT_BLOCKSWORDBEAM;
  1677. else if(wpn_id==LW_ARROW){
  1678. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)return CT_BLOCKARROW1;
  1679. else if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)return CT_BLOCKARROW2;
  1680. else
  1681. return CT_BLOCKARROW3;
  1682. }
  1683. else
  1684. return CT_BLOCKALL;
  1685. }
  1686.  
  1687. //Returns sprite for a combo type.
  1688.  
  1689. //int GetComboSprite(int type){
  1690. //if(type==CT_SLASH||type==CT_SLASHNEXT||type==CT_SLASHNEXTITEM)return SPR_POT_BREAK;
  1691. //else if(type== CT_FLOWERS)return SPR_FLOWER_CUT;
  1692. //else if(type==CT_BUSH||type==CT_BUSHNEXT)return SPR_BUSH_CUT;
  1693. //else if(type==CT_TALLGRASS||type==CT_TALLGRASSNEXT)return SPR_GRASS_CUT;
  1694. //}
  1695.  
  1696. //Returns sound made by slashed combo.
  1697.  
  1698. //int GetComboSound(int type){
  1699. //if(type==CT_SLASH||type==CT_SLASHNEXT||type==CT_SLASHNEXTITEM)return SFX_POT_BREAK;
  1700. //else
  1701. //return SFX_GRASSCUT;
  1702. //}
  1703.  
  1704. //Creates a sprite at a location.
  1705.  
  1706. //D0- Sprite to create.
  1707. //D1- X location
  1708. //D2- Y location
  1709.  
  1710. //int CreateGraphicAt(int sprite, int x, int y){
  1711. //eweapon e = Screen->CreateEWeapon(EW_SCRIPT1);
  1712. //e->HitXOffset = 500;
  1713. //e->UseSprite(sprite);
  1714. //e->DeadState = e->NumFrames*e->ASpeed;
  1715. //e->X = x;
  1716. //e->Y = y;
  1717. //return e->DeadState;
  1718. //}
  1719.  
  1720. //Find X center of a lweapon.
  1721.  
  1722. int CenterWpnX(lweapon wpn){
  1723. int x = wpn->X+wpn->HitXOffset;
  1724. if(wpn->HitWidth>16)
  1725. x+=(wpn->HitWidth/2);
  1726. else
  1727. x+=8;
  1728. return x;
  1729. }
  1730.  
  1731. //Find Y center of a lweapon.
  1732.  
  1733. int CenterWpnY(lweapon wpn){
  1734. int y = wpn->Y+wpn->HitYOffset;
  1735. if(wpn->HitWidth>16)
  1736. y+=(wpn->HitHeight/2);
  1737. else
  1738. y+=8;
  1739. return y;
  1740. }
  1741.  
  1742. //Returns combo type in front of Link.
  1743.  
  1744. int ComboLocInFront(){
  1745. if(Link->Dir==DIR_UP)
  1746. return ComboAt(Link->X,Link->Y-8);
  1747. else if(Link->Dir==DIR_DOWN)
  1748. return ComboAt(Link->X,Link->Y+16);
  1749. else if(Link->Dir==DIR_LEFT)
  1750. return ComboAt(Link->X-16,Link->Y+8);
  1751. else if(Link->Dir==DIR_RIGHT)
  1752. return ComboAt(Link->X+16,Link->Y+8);
  1753. }
  1754.  
  1755. //Returns combo type in front of Link.
  1756.  
  1757. int ComboTypeInFront(){
  1758. if(Link->Dir==DIR_UP)
  1759. return Screen->ComboT[ComboAt(Link->X,Link->Y-8)];
  1760. else if(Link->Dir==DIR_DOWN)
  1761. return Screen->ComboT[ComboAt(Link->X,Link->Y+16)];
  1762. else if(Link->Dir==DIR_LEFT)
  1763. return Screen->ComboT[ComboAt(Link->X-16,Link->Y+8)];
  1764. else if(Link->Dir==DIR_RIGHT)
  1765. return Screen->ComboT[ComboAt(Link->X+16,Link->Y+8)];
  1766. }
  1767.  
  1768. //Counts number of Lweapons with a certain flag set.
  1769.  
  1770. int NumMiscLWeapons(int index,int flag){
  1771. int ret;
  1772. for(int i = Screen->NumLWeapons();i>0;i--){
  1773. lweapon wpn = Screen->LoadLWeapon(i);
  1774. if((wpn->Misc[index]&flag)!=0)
  1775. ret++;
  1776. }
  1777. return ret;
  1778. }
  1779.  
  1780. int NumMoveLWeapons(int type){
  1781. int ret;
  1782. for(int i = Screen->NumLWeapons();i>0;i--){
  1783. lweapon wpn = Screen->LoadLWeapon(i);
  1784. if(wpn->Misc[LW_ZH_I_MOVEMENT]==type)
  1785. ret++;
  1786. }
  1787. return ret;
  1788. }
  1789.  
  1790. //Combo Type at weapon location.
  1791.  
  1792. int ComboTAtWpn(lweapon wpn){
  1793. return Screen->ComboT[ComboAt(CenterWpnX(wpn),CenterWpnY(wpn))];
  1794. }
  1795.  
  1796. //Returnss an lweapon with a particular movement type.
  1797.  
  1798. lweapon FindLWeaponMove(int type){
  1799. for(int i = Screen->NumLWeapons();i>0;i--){
  1800. lweapon wpn = Screen->LoadLWeapon(i);
  1801. if(wpn->Misc[LW_ZH_I_MOVEMENT]==type)
  1802. return wpn;
  1803. }
  1804. }
  1805.  
  1806. bool ComboFIAtWpn(lweapon wpn,int flag){
  1807. return (ComboFI(ComboAt(wpn->X + 3, wpn->Y + 3),flag)
  1808. || ComboFI(ComboAt(wpn->X + 8, wpn->Y + 3),flag)
  1809. || ComboFI(ComboAt(wpn->X + 13, wpn->Y + 3),flag)
  1810. || ComboFI(ComboAt(wpn->X + 3, wpn->Y + 8),flag)
  1811. || ComboFI(ComboAt(wpn->X + 8, wpn->Y + 8),flag)
  1812. || ComboFI(ComboAt(wpn->X + 13, wpn->Y + 8),flag)
  1813. || ComboFI(ComboAt(wpn->X + 3,wpn->Y + 13),flag)
  1814. || ComboFI(ComboAt(wpn->X + 8, wpn->Y + 13),flag)
  1815. || ComboFI(ComboAt(wpn->X + 13, wpn->Y + 13),flag));
  1816. }
  1817.  
  1818. bool ComboFITAtWpn(lweapon wpn,int flag,int type){
  1819. return (ComboFIT(ComboAt(wpn->X + 3, wpn->Y + 3),flag,type)
  1820. || ComboFIT(ComboAt(wpn->X + 8, wpn->Y + 3),flag,type)
  1821. || ComboFIT(ComboAt(wpn->X + 13, wpn->Y + 3),flag,type)
  1822. || ComboFIT(ComboAt(wpn->X + 3, wpn->Y + 8),flag,type)
  1823. || ComboFIT(ComboAt(wpn->X + 8, wpn->Y + 8),flag,type)
  1824. || ComboFIT(ComboAt(wpn->X + 13, wpn->Y + 8),flag,type)
  1825. || ComboFIT(ComboAt(wpn->X + 3,wpn->Y + 13),flag,type)
  1826. || ComboFIT(ComboAt(wpn->X + 8, wpn->Y + 13),flag,type)
  1827. || ComboFIT(ComboAt(wpn->X + 13, wpn->Y + 13),flag,type));
  1828. }
  1829.  
  1830. bool ComboTAtWpn(lweapon wpn,int type){
  1831. return ((Screen->ComboT[ComboAt(wpn->X + 3, wpn->Y + 3)]==type)
  1832. || (Screen->ComboT[ComboAt(wpn->X + 8, wpn->Y + 3)]==type)
  1833. || (Screen->ComboT[ComboAt(wpn->X + 13, wpn->Y + 3)]==type)
  1834. || (Screen->ComboT[ComboAt(wpn->X + 3, wpn->Y + 8)]==type)
  1835. || (Screen->ComboT[ComboAt(wpn->X + 8, wpn->Y + 8)]==type)
  1836. || (Screen->ComboT[ComboAt(wpn->X + 13, wpn->Y + 8)]==type)
  1837. || (Screen->ComboT[ComboAt(wpn->X + 3,wpn->Y + 13)]==type)
  1838. || (Screen->ComboT[ComboAt(wpn->X + 8, wpn->Y + 13)]==type)
  1839. || (Screen->ComboT[ComboAt(wpn->X + 13, wpn->Y + 13)]==type));
  1840. }
  1841.  
  1842. //Example Item Scripts.
  1843.  
  1844. item script Firebar{
  1845. void run(int dummy, int Damage, int sprite){
  1846. int i;
  1847. lweapon fireball;
  1848. for(i=1;i<=7;i++){
  1849. fireball= FireLWeapon(LW_SCRIPT1, Link->X + 8,
  1850. Link->Y+8, __DirtoRad(Link->Dir),
  1851. 100, Damage, sprite, SFX_SWORD, 0);
  1852. SetLWeaponLifespan(fireball,LWL_TIMER,180);
  1853. SetLWeaponMovement(fireball,LWM_CIRCLE,(16*i),10);
  1854. SetLWeaponDeathEffect(fireball,LWD_AIM_AT_NPC,10);
  1855. }
  1856. }
  1857. }
  1858.  
  1859. item script OmniByrna{
  1860. void run(int dummy, int Damage, int sprite){
  1861. lweapon fireball1;
  1862. lweapon fireball2;
  1863. lweapon fireball3;
  1864. lweapon fireball4;
  1865. if(NumLWeaponsOf(LW_SCRIPT1)==0){
  1866. fireball1= FireLWeapon(LW_SCRIPT1, Link->X + 8*Cos(0),
  1867. Link->Y+ 8*Sin(0), DegtoRad(0),
  1868. 100, Damage, sprite, SFX_SWORD, LWF_LINK_NO_COLL);
  1869. SetLWeaponLifespan(fireball1,LWL_MP_COST,5);
  1870. SetLWeaponMovement(fireball1,LWM_CIRCLE,32,10);
  1871. SetLWeaponDeathEffect(fireball1,LWD_VANISH,0);
  1872. fireball2= FireLWeapon(LW_SCRIPT1, Link->X + 8*Cos(90),
  1873. Link->Y+ 8*Sin(90), DegtoRad(90),
  1874. 100, Damage, sprite, SFX_SWORD, LWF_LINK_NO_COLL);
  1875. SetLWeaponLifespan(fireball2,LWL_MP_COST,-1);
  1876. SetLWeaponMovement(fireball2,LWM_CIRCLE,32,10);
  1877. SetLWeaponDeathEffect(fireball2,LWD_VANISH,0);
  1878. fireball3= FireLWeapon(LW_SCRIPT1, Link->X + 8*Cos(180),
  1879. Link->Y+ 8*Sin(180), DegtoRad(180),
  1880. 100, Damage, sprite, SFX_SWORD, LWF_LINK_NO_COLL);
  1881. SetLWeaponLifespan(fireball3,LWL_MP_COST,-1);
  1882. SetLWeaponMovement(fireball3,LWM_CIRCLE,32,10);
  1883. SetLWeaponDeathEffect(fireball3,LWD_VANISH,0);
  1884. fireball4= FireLWeapon(LW_SCRIPT1, Link->X + 8*Cos(270),
  1885. Link->Y+ 8*Sin(270), DegtoRad(270),
  1886. 100, Damage, sprite, SFX_SWORD, LWF_LINK_NO_COLL);
  1887. SetLWeaponLifespan(fireball4,LWL_MP_COST,-1);
  1888. SetLWeaponMovement(fireball4,LWM_CIRCLE,32,10);
  1889. SetLWeaponDeathEffect(fireball4,LWD_VANISH,0);
  1890. }
  1891. else{
  1892. if(fireball1->isValid())
  1893. KillLWeapon(fireball1);
  1894. if(fireball2->isValid())
  1895. KillLWeapon(fireball2);
  1896. if(fireball3->isValid())
  1897. KillLWeapon(fireball3);
  1898. if(fireball4->isValid())
  1899. KillLWeapon(fireball4);
  1900. }
  1901. }
  1902. }
  1903.  
  1904. item script Grenade{
  1905. void run(int dummy, int Damage, int sprite){
  1906. if(Game->Counter[CR_BOMBS]>0){
  1907. lweapon fireball;
  1908. fireball= FireLWeapon(LW_SCRIPT1, Link->X+8, Link->Y, __DirtoRad(Link->Dir),
  1909. 100, Damage, sprite, SFX_THROW, 0);
  1910. SetLWeaponMovement(fireball,LWM_THROW,3,LWMF_DIE);
  1911. SetLWeaponDeathEffect(fireball,LWD_EXPLODE,8);
  1912. Link->Action = LA_ATTACKING;
  1913. Game->Counter[CR_BOMBS]--;
  1914. }
  1915. }
  1916. }
  1917.  
  1918. item script Boulder{
  1919. void run(int dummy, int Damage, int sprite){
  1920. if(NumLWeaponsOf(LW_SCRIPT1)==0){
  1921. lweapon fireball;
  1922. fireball= FireBigLWeapon(LW_SCRIPT1, Link->X+8, Link->Y, __DirtoRad(Link->Dir),
  1923. 100, Damage, sprite, SFX_THROW, 0,2,2);
  1924. SetLWeaponMovement(fireball,LWM_THROW,3,LWMF_DIE);
  1925. SetLWeaponDeathEffect(fireball,LWD_4_FIREBALLS_RANDOM,99);
  1926. Link->Action = LA_ATTACKING;
  1927. }
  1928. }
  1929. }
  1930.  
  1931. item script Message{
  1932. void run(int message){
  1933. Screen->Message(message);
  1934. }
  1935. }
  1936.  
  1937. item script ScriptBoomerang{
  1938. void run(int dummy, int range,int level, int Damage, int sprite,int script_id){
  1939. lweapon brang;
  1940. if(NumLWeaponsOf(LW_SCRIPT1)==0){
  1941. brang = FireLWeapon(LW_SCRIPT1, Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  1942. __DirtoRad(Link->Dir), 100, Damage, sprite, SFX_BRANG, LWF_STUNS_ENEMIES|LWF_ITEM_PICKUP);
  1943. SetLWeaponMovement(brang,LWM_BRANG,range,15);
  1944. SetLWeaponSFX(brang,SFX_BRANG,30);
  1945. SetLWeaponDeathEffect(brang,LWD_VANISH,0);
  1946. brang->Misc[LW_ZH_I_FLAGS_2]|=level;
  1947. if(level==LWF_LEVEL_2)
  1948. SetLWeaponLifespan(brang,LWL_EDGE,SPR_MAGIC_SPARKLE);
  1949. else if(level==LWF_LEVEL_3)
  1950. SetLWeaponLifespan(brang,LWL_EDGE,SPR_FIRE_SPARKLE);
  1951. else
  1952. SetLWeaponLifespan(brang,LWL_EDGE,0);
  1953. }
  1954. }
  1955. }
  1956.  
  1957. const int SPR_MAGIC_SPARKLE = 31;
  1958. const int SPR_FIRE_SPARKLE = 32;
  1959.  
  1960. item script BombArrows{
  1961. void run(int dummy, int damage, int sprite){
  1962. if(Game->Counter[CR_ARROWS]!=0 && Game->Counter[CR_BOMBS]!=0){
  1963. lweapon bombarrow;
  1964. bombarrow = FireLWeapon(LW_SCRIPT1, Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  1965. __DirtoRad(Link->Dir), 200, damage, sprite, SFX_ARROW, 0);
  1966. SetLWeaponMovement(bombarrow,LWM_DUAL_FX,LW_ARROW,LW_BOMBBLAST);
  1967. SetLWeaponDeathEffect(bombarrow,LWD_EXPLODE,8);
  1968. bombarrow->Misc[LW_ZH_I_FLAGS_2]|=LWF_LEVEL_1;
  1969. Link->Action = LA_ATTACKING;
  1970. Game->Counter[CR_ARROWS]--;
  1971. Game->Counter[CR_BOMBS]--;
  1972. }
  1973. }
  1974. }
  1975.  
  1976. item script Fire_Rod{
  1977. void run(int dummy, int MPCost, int damage, int spritemagic, int spritewand){
  1978. if(Link->MP>=MPCost){
  1979. lweapon magic;
  1980. lweapon wand;
  1981. wand = FireLWeapon(LW_SCRIPT1,Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  1982. __DirtoRad(Link->Dir), 0, damage, spritewand, 0, 0);
  1983. SetLWeaponLifespan(wand,LWL_TIMER,10);
  1984. SetLWeaponDeathEffect(wand,LWD_VANISH,0);
  1985. magic = FireLWeapon(LW_MAGIC,Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  1986. __DirtoRad(Link->Dir), 200, damage, spritemagic, SFX_WAND, LWF_CAN_REFLECT);
  1987. SetLWeaponLifespan(magic,LWL_EDGE,spritemagic);
  1988. SetLWeaponDeathEffect(magic,LWD_FIRE,85);
  1989. magic->Misc[LW_ZH_I_FLAGS_2]|=LWF_LEVEL_3;
  1990. Link->Action = LA_CASTING;
  1991. Link->MP-=MPCost;
  1992. }
  1993. }
  1994. }
  1995.  
  1996. item script Ice_Rod{
  1997. void run(int dummy, int MPCost, int damage, int spritemagic, int spritewand){
  1998. if(Link->MP>=MPCost){
  1999. lweapon magic;
  2000. lweapon wand;
  2001. wand = FireLWeapon(LW_SCRIPT1,Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  2002. __DirtoRad(Link->Dir), 0, damage, spritewand, 0, 0);
  2003. SetLWeaponLifespan(wand,LWL_TIMER,10);
  2004. SetLWeaponDeathEffect(wand,LWD_VANISH,0);
  2005. magic = FireLWeapon(LW_SCRIPT1,Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  2006. __DirtoRad(Link->Dir), 200, 0,
  2007. spritemagic, SFX_WAND, LWF_STUNS_ENEMIES);
  2008. SetLWeaponLifespan(magic,LWL_EDGE,60);
  2009. SetLWeaponDeathEffect(magic,LWD_FREEZE,24);
  2010. Link->Action = LA_CASTING;
  2011. Link->MP-=MPCost;
  2012. }
  2013. }
  2014. }
  2015.  
  2016. const int SPR_WAVE_SHARDS = 57;
  2017.  
  2018. item script Wave_Sword_Beam{
  2019. void run(int dummy1, int dummy2, int Damage, int percent, int sprite){
  2020. Game->PlaySound(SFX_BEAM);
  2021. Link->Action = LA_ATTACKING;
  2022. lweapon beam;
  2023. lweapon fakesword;
  2024. beam = FireScriptedLWeapon(LW_BEAM, Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  2025. sprite, 200, Damage,LWF_ZERO_G);
  2026. beam->Misc[LW_ZH_I_FLAGS_2]|=LWF_LEVEL_3;
  2027. SetLWeaponLifespan(beam,LWL_EDGE,0);
  2028. if(beam->Dir==DIR_UP || beam->Dir==DIR_DOWN)SetLWeaponMovement(beam, LWM_SINE_WAVE, 6, 4);
  2029. else
  2030. SetLWeaponMovement(beam, EWM_SINE_WAVE, 4, 6);
  2031. if(Link->HP>=(Link->MaxHP * 0.01 * percent))
  2032. SetLWeaponDeathEffect(beam,LWD_4_FIREBALLS_DIAG,SPR_WAVE_SHARDS);
  2033. beam->Angle = __DirtoRad(Link->Dir);
  2034. }
  2035. }
  2036.  
  2037.  
  2038. const int SPR_ARROW_1 = 10;//Sprite for normal missile.
  2039. const int SPR_ARROW_2 = 11;//Sprite for ice missile.
  2040. const int SPR_ARROW_3 = 34;//Sprite for hyper missile.
  2041.  
  2042. item script Variable_Strength_Arrow{
  2043. void run(int dummy1, int dummy2, int level, int Damage){
  2044. //Create and position Lweapon.
  2045. lweapon beam;//Lweapon created by charge.
  2046. if(level==1){
  2047. beam = FireScriptedLWeapon(LW_ARROW, Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  2048. SPR_ARROW_1, 200, Damage,LWF_ZERO_G);
  2049. beam->Misc[LW_ZH_I_FLAGS_2]|=LWF_LEVEL_1;
  2050. SetLWeaponDeathEffect(beam,LWD_VANISH,0);
  2051. }
  2052. else if(level==2){
  2053. beam = FireScriptedLWeapon(LW_ARROW, Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  2054. SPR_ARROW_2, 200, Damage,LWF_ZERO_G);
  2055. beam->Misc[LW_ZH_I_FLAGS_2]|=LWF_LEVEL_2;
  2056. SetLWeaponLifespan(beam,LWL_TIMER,60);
  2057. SetLWeaponDeathEffect(beam,LWD_8_FIREBALLS,75);
  2058. }
  2059. else if(level ==3){
  2060. beam = FireScriptedLWeapon(LW_ARROW, Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  2061. SPR_ARROW_3, 200, Damage,LWF_ZERO_G);
  2062. beam->Misc[LW_ZH_I_FLAGS_2]|=LWF_LEVEL_3;
  2063. if(Screen->NumNPCs()>0){
  2064. beam->Angle = __DirtoRad(Link->Dir);
  2065. SetLWeaponMovement(beam, LWM_HOMING, 15, -1);
  2066. }
  2067. SetLWeaponDeathEffect(beam,LWD_VANISH,0);
  2068. }
  2069. Game->PlaySound(SFX_ARROW);
  2070. Link->Action = LA_ATTACKING;
  2071. Game->Counter[CR_ARROWS]--;
  2072. SetLWeaponLifespan(beam,LWL_EDGE,0);
  2073. }
  2074. }
  2075.  
  2076. item script Meteor{
  2077. void run(int dummy, int Damage, int sprite, int num){
  2078. int i;
  2079. lweapon fireball;
  2080. for(i=0;i<=num;i++){
  2081. fireball= FireLWeapon(LW_SCRIPT1, Rand(32,240),Rand(32,120),
  2082. DegtoRad(90), 0, Damage, sprite, SFX_FALL, 0);
  2083. SetLWeaponMovement(fireball,LWM_FALL,200,LWMF_DIE);
  2084. SetLWeaponDeathEffect(fireball,LWD_SBOMB_EXPLODE,8);
  2085. }
  2086. }
  2087. }
  2088.  
  2089.  
  2090.  
  2091. //D0- Weapon type that triggers this.
  2092. //D1- Level of weapon.
  2093. // Binary- 1= level one
  2094. // 2= level two
  2095. // 4= level three
  2096. // 8= level four
  2097. //D2- Screen->D register to store secrets in.
  2098.  
  2099. ffc script LWeapon_Index_Trigger{
  2100. void run(int type, int level, int perm){
  2101. lweapon thing;
  2102. int i;
  2103. bool triggered = false;
  2104. if(Screen->D[perm]!=0)triggered = true;
  2105. while(!triggered){
  2106. for(i = 1;i<=Screen->NumLWeapons();i++){
  2107. thing = Screen->LoadLWeapon(i);
  2108. if(thing->ID ==type && Collision(this,thing))
  2109. if(level!=0 && ((thing->Misc[LW_ZH_I_FLAGS_2]&level)!=0))
  2110. triggered = true;
  2111. else if(level==0)
  2112. triggered = true;
  2113. }
  2114. Waitframe();
  2115. }
  2116. Screen->TriggerSecrets();
  2117. Screen->State[ST_SECRET]= true;
  2118. Screen->D[perm] = 1;
  2119. }
  2120. }
  2121.  
  2122. const int LINK_HOLD_2_COMBO = 32380;
  2123.  
  2124. ffc script Large_Item{
  2125. void run(int item_to_give,int width, int height){
  2126. item anitem;
  2127. if(!Screen->State[ST_ITEM]){
  2128. anitem = Screen->CreateItem(item_to_give);
  2129. anitem->X = this->X;
  2130. anitem->Y = this->Y;
  2131. }
  2132. int timer;
  2133. int tile = anitem->OriginalTile;
  2134. int cset = anitem->CSet;
  2135. while(anitem->isValid()){
  2136. anitem->Extend = 3;
  2137. anitem->TileWidth = width;
  2138. anitem->TileHeight = height;
  2139. if(LinkCollision(anitem)){
  2140. anitem->X = Link->X;
  2141. anitem->Y = Link->Y;
  2142. Game->PlaySound(SFX_PICKUP);
  2143. while(timer<30){
  2144. Link->Invisible = true;
  2145. Screen->DrawTile(0, Link->X+8-((width*16)/2), Link->Y-(height*16),
  2146. tile, width, height, cset, -1, -1, 0, 0, 0, 0, true, 128);
  2147. Screen->DrawCombo(0, Link->X, Link->Y, LINK_HOLD_2_COMBO,
  2148. 1, 1, 6, -1, -1, 0, 0, 0, -1, 0, true, 128);
  2149. timer++;
  2150. WaitNoAction();
  2151. }
  2152. Link->Invisible = false;
  2153. Screen->State[ST_ITEM]= true;
  2154. }
  2155. Waitframe();
  2156. }
  2157. }
  2158. }
  2159.  
  2160.  
  2161.  
  2162. item script Bracelet{
  2163. void run(int dummy, int Strength, int damage, int this_id){
  2164. lweapon Carried;
  2165. lweapon Thrown;
  2166. int ComboType;
  2167. int Sprite;
  2168. if(Strength == 1){
  2169. if(NumLWeaponsOf(LW_SCRIPT1)==0){
  2170. if(ComboTypeInFront()== CT_BUSH ||
  2171. ComboTypeInFront()== CT_BUSHNEXT){
  2172. ComboType = Screen->ComboT[ComboLocInFront()];
  2173. Carried= FireLWeapon(LW_SCRIPT1, Link->X,Link->Y-16,
  2174. DegtoRad(270), 0, damage, SPR_BUSH, SFX_HEFT, LWF_PIERCES_ENEMIES);
  2175. SetLWeaponMovement(Carried,LWM_CARRY,ComboType,0);
  2176. if(ComboTypeInFront()==CT_BUSH)
  2177. Screen->ComboD[ComboLocInFront()]= Screen->UnderCombo;
  2178. else
  2179. Screen->ComboD[ComboLocInFront()]++;
  2180. Link->Action = LA_ATTACKING;
  2181. }
  2182. }
  2183. else if(NumLWeaponsOf(LW_SCRIPT2)==0){
  2184. Carried = FindLWeaponType(LW_SCRIPT1);
  2185. if(Carried->Misc[LW_ZH_I_MOVEMENT_ARG]== CT_BUSH ||
  2186. Carried->Misc[LW_ZH_I_MOVEMENT_ARG]== CT_BUSHNEXT)
  2187. Sprite = SPR_BUSH;
  2188. RemoveLWeaponType(LW_SCRIPT1);
  2189. Thrown = FireLWeapon(LW_SCRIPT2, Link->X,Link->Y-16, __DirtoRad(Link->Dir),
  2190. 100, damage*Strength, Sprite, SFX_THROW, 0);
  2191. SetLWeaponMovement(Thrown,LWM_THROW,3,LWMF_DIE);
  2192. Link->Action = LA_ATTACKING;
  2193. }
  2194. }
  2195. }
  2196. }
  2197.  
  2198. item script Hookshot{
  2199. void run(int dummy, int Damage, int sprite, int chain_sprite, int sfx){
  2200. int i;
  2201. lweapon hookshot;
  2202. hookshot= FireLWeapon(LW_SCRIPT1, Link->X+InFrontX(Link->Dir,2), Link->Y+InFrontY(Link->Dir,2),
  2203. __DirtoRad(Link->Dir), 100, Damage, sprite, sfx,
  2204. LWF_ITEM_PICKUP|LWF_STUNS_ENEMIES|LWF_LINK_NO_COLL);
  2205. SetLWeaponLifespan(hookshot,LWL_EDGE,0);
  2206. SetLWeaponMovement(hookshot,LWM_HOOKSHOT,32,chain_sprite);
  2207. SetLWeaponSFX(hookshot,sfx,30);
  2208. hookshot->Misc[LW_ZH_I_FLAGS_2]|=LWF_LINK_FROZEN;
  2209. }
  2210. }
  2211.  
  2212. //LW_ZH Update functions.
  2213.  
  2214. //Fixes Link's collision detection if it needs it.
  2215.  
  2216. void UpdateLWZH1(){
  2217. __CollDetectFix();
  2218. }
  2219.  
  2220. //Handle restoring Link's collision detection.
  2221.  
  2222. void __CollDetectFix(){
  2223. //Link's collision detection is off.
  2224. if(!Link->CollDetection){
  2225. //No Lweapons exist that turn it off.
  2226. if(NumMiscLWeapons(LW_ZH_I_FLAGS,LWF_LINK_NO_COLL)==0)
  2227. //Turn it on again.
  2228. Link->CollDetection = true;
  2229. }
  2230. }
  2231.  
  2232. // Calls UpdateLWeapon() on every eweapon on the screen
  2233.  
  2234. void UpdateLWZH2(){
  2235. lweapon wpn;
  2236.  
  2237. for(int i=Screen->NumLWeapons(); i>0; i--){
  2238. wpn=Screen->LoadLWeapon(i);
  2239.  
  2240. // If this is a dummy, or if it's not a ghost.zh weapon, don't do anything
  2241. if((wpn->Misc[LW_ZH_I_FLAGS]&__LWFI_IS_LWZH_LWPN)==0)
  2242. continue;
  2243.  
  2244. UpdateLWZH(wpn);
  2245. }
  2246. }
  2247.  
  2248.  
  2249. //Updates fancy lweapon movement stuff.
  2250.  
  2251. // Update a weapon's movement, lifespan, and death effects
  2252. void UpdateLWZH(lweapon wpn){
  2253.  
  2254. // Is the weapon still active?
  2255. if((wpn->Misc[LW_ZH_I_FLAGS]&__LWFI_DEAD )==0){
  2256. // Start movement updates
  2257. if(wpn->Misc[LW_ZH_I_MOVEMENT]!=0){
  2258. if(wpn->Misc[LW_ZH_I_MOVEMENT]!=0){
  2259. if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_SINE_WAVE)
  2260. __UpdateLWMSineWave(wpn);
  2261. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_HOMING)
  2262. __UpdateLWMHoming(wpn);
  2263. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_THROW)
  2264. __UpdateLWMThrow(wpn);
  2265. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_FALL)
  2266. __UpdateLWMFall(wpn);
  2267. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_CIRCLE)
  2268. __UpdateLWM_Circle(wpn);
  2269. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_HOOKSHOT
  2270. && (wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_RETURN)==0
  2271. && (wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_HS_GRAB)==0)
  2272. __UpdateLWM_Hookshot(wpn);
  2273. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_BRANG)
  2274. __UpdateLWM_BRang(wpn);
  2275. //else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_MELEE){
  2276. //__UpdateLWM_Melee(wpn);
  2277. //__UpdateLWE_Melee(wpn);
  2278. //}
  2279. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_CARRY)
  2280. __UpdateLWM_Carry(wpn);
  2281. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_DUAL_FX)
  2282. __UpdateLWM_Dual(wpn);
  2283. }
  2284. } // End movement updates
  2285.  
  2286. // Start lifespan updates
  2287. if(wpn->Misc[LW_ZH_I_LIFESPAN]!=0)
  2288. {
  2289. if(wpn->Misc[LW_ZH_I_LIFESPAN]==LWL_TIMER){
  2290. wpn->Misc[LW_ZH_I_LIFESPAN_ARG]-=1;
  2291. if(wpn->Misc[LW_ZH_I_LIFESPAN_ARG]<=0)
  2292. KillLWeapon(wpn);
  2293. }
  2294. else if(wpn->Misc[LW_ZH_I_LIFESPAN]==LWL_MP_COST){
  2295. if(wpn->Misc[LW_ZH_I_LIFESPAN_ARG]>0){
  2296. if(Game->Generic[GEN_MAGICDRAINRATE]==0)
  2297. wpn->Misc[LW_ZH_I_WORK_3]= (wpn->Misc[LW_ZH_I_WORK_3]+1)%wpn->Misc[LW_ZH_I_LIFESPAN_ARG];
  2298. else
  2299. wpn->Misc[LW_ZH_I_WORK_3]= (wpn->Misc[LW_ZH_I_WORK_3]+1)
  2300. %(wpn->Misc[LW_ZH_I_LIFESPAN_ARG]*2);
  2301. if(wpn->Misc[LW_ZH_I_WORK_3]==0 && Link->MP>0)
  2302. Link->MP--;
  2303. if(Link->MP<=0){
  2304. KillLWeapon(wpn);
  2305. Link->MP =0;
  2306. }
  2307. }
  2308. else{
  2309. if(Link->MP<=0){
  2310. KillLWeapon(wpn);
  2311. Link->MP =0;
  2312. }
  2313. }
  2314. }
  2315. else if(wpn->Misc[LW_ZH_I_LIFESPAN]==LWL_EDGE){
  2316. if(OnScreenEdge(wpn)){
  2317. if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_BRANG)
  2318. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  2319. }
  2320. }
  2321. } // End lifespan updates
  2322.  
  2323. if(wpn->Misc[LW_ZH_I_FX]>0)
  2324. __UpdateLWE_Sound(wpn);
  2325. __UpdateLWE_BlockFlags(wpn);
  2326. __NPCCollision(wpn);
  2327. __FlagTrigger(wpn);
  2328.  
  2329. //LWeapon flags, level 2
  2330.  
  2331. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_NO_COLLISION)!=0)
  2332. __UpdateLWF_Collision(wpn);
  2333. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_HS_GRAB)!=0)
  2334. __HookshotPull(wpn);
  2335. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_LINK_FROZEN)!=0)
  2336. __UpdateLWF_Link_FreezeOn();
  2337. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_LINK_NO_COLL)!=0)
  2338. __UpdateLWF_Link_CollOff();
  2339.  
  2340. }
  2341.  
  2342. // Start death effects
  2343. else if(wpn->Misc[LW_ZH_I_ON_DEATH]!=0 && (wpn->Misc[LW_ZH_I_FLAGS]&__LWFI_DEATH_EFFECT_DONE)==0)
  2344. {
  2345. //LWeapon flags, level 2
  2346.  
  2347. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_PIERCES_ENEMIES)!=0)
  2348. wpn->Misc[LW_ZH_I_FLAGS]&= ~LWF_PIERCES_ENEMIES;
  2349. if(wpn->Misc[LW_ZH_I_ON_DEATH]<8){
  2350. if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_VANISH)
  2351. wpn->DeadState=0;
  2352. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_AIM_AT_NPC)
  2353. __DoLWeaponDeathAimAtNPC(wpn);
  2354. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_EXPLODE)
  2355. __DoLWeaponDeathExplode(wpn);
  2356. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_SBOMB_EXPLODE)
  2357. __DoLWeaponDeathSBombExplode(wpn);
  2358. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_4_FIREBALLS_HV)
  2359. __DoLWeaponDeath4FireballsHV(wpn);
  2360. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_4_FIREBALLS_DIAG)
  2361. __DoLWeaponDeath4FireballsDiag(wpn);
  2362. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_4_FIREBALLS_RANDOM)
  2363. __DoLWeaponDeath4FireballsRand(wpn);
  2364. }
  2365. else // wpn->Misc[LW_ZH_I_ON_DEATH]>=8
  2366. {
  2367. if(wpn->Misc[LW_ZH_I_ON_DEATH]==EWD_8_FIREBALLS)
  2368. __DoLWeaponDeath8Fireballs(wpn);
  2369. //else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_4_FIRES_HV)
  2370. //__DoLWeaponDeath4FiresHV(wpn);
  2371. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_4_FIRES_DIAG)
  2372. __DoLWeaponDeath4FiresDiag(wpn);
  2373. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_4_FIRES_RANDOM)
  2374. __DoLWeaponDeath4FiresRand(wpn);
  2375. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_8_FIRES)
  2376. __DoLWeaponDeath8Fires(wpn);
  2377. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_FIRE)
  2378. __DoLWeaponDeathSingleFire(wpn);
  2379. else if(wpn->Misc[LW_ZH_I_ON_DEATH]==LWD_FREEZE)
  2380. __DoLWeaponDeathFreeze(wpn);
  2381. }
  2382.  
  2383. } // End death effects
  2384.  
  2385. //LWeapon flags, level 1
  2386.  
  2387. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_ITEM_PICKUP)!=0)
  2388. __UpdateLWF_Pickup(wpn);
  2389. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_PIERCES_ENEMIES)!=0)
  2390. __UpdateLWF_Pierce(wpn);
  2391. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_STUNS_ENEMIES)!=0)
  2392. __UpdateLWF_Stun(wpn);
  2393. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_CAN_REFLECT)!=0)
  2394. __UpdateLWF_Reflect(wpn);
  2395. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_ZERO_G)!=0)
  2396. __UpdateLWF_G_Force(wpn);
  2397. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_POISON)!=0)
  2398. __UpdateLWF_Poison(wpn);
  2399. }
  2400.  
  2401. //Handles LWeapons that continuously make sounds.
  2402.  
  2403. void __UpdateLWE_Sound(lweapon wpn){
  2404. if(wpn->Misc[LW_ZH_I_WORK_2]>0){
  2405. wpn->Misc[LW_ZH_I_WORK]=(wpn->Misc[LW_ZH_I_WORK]+1)%wpn->Misc[LW_ZH_I_WORK_2];
  2406. if(wpn->Misc[LW_ZH_I_WORK]==0)Game->PlaySound(wpn->Misc[LW_ZH_I_FX]);
  2407. }
  2408. }
  2409.  
  2410. //Handles lweapon that's blocked by a combo.
  2411.  
  2412. void __UpdateLWE_BlockFlags(lweapon wpn){
  2413. if(ComboTAtWpn(wpn)==LWBlockType(wpn)||(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_HOOKSHOT
  2414. && ComboTAtWpn(wpn)!=CT_HOOKSHOTONLY && ComboTAtWpn(wpn)!=CT_LADDERHOOKSHOT)){
  2415. if(wpn->Misc[LW_ZH_I_MOVEMENT]!=LWM_BRANG && wpn->Misc[LW_ZH_I_MOVEMENT]!=LWM_HOOKSHOT){
  2416. KillLWeapon(wpn);
  2417. Game->PlaySound(SFX_CLINK);
  2418. }
  2419. else{
  2420. if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_HOOKSHOT && ComboTAtWpn(wpn)==CT_HSGRAB)
  2421. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_HS_GRAB;
  2422. else
  2423. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  2424. }
  2425. }
  2426. }
  2427.  
  2428. void __UpdateLWM_Dual(lweapon wpn){
  2429. if(ComboTAtWpn(wpn)==LWBlockType(wpn->Misc[LW_ZH_I_MOVEMENT_ARG],wpn)
  2430. ||ComboTAtWpn(wpn)==LWBlockType(wpn->Misc[LW_ZH_I_MOVEMENT_ARG2],wpn)){
  2431. KillLWeapon(wpn);
  2432. Game->PlaySound(SFX_CLINK);
  2433. }
  2434. bool trigger = false;
  2435. if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_ARROW
  2436. ||wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]==LW_ARROW){
  2437. if(ComboFIAtWpn(wpn,CF_ARROW)){
  2438. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)trigger = true;
  2439. }
  2440. if(ComboFIAtWpn(wpn,CF_ARROW2)){
  2441. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)trigger = true;
  2442. }
  2443. if(ComboFIAtWpn(wpn,CF_ARROW3)){
  2444. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_3)!=0)trigger = true;
  2445. }
  2446. }
  2447. if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_BOMBBLAST
  2448. ||wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]==LW_BOMBBLAST){
  2449. if(ComboFIAtWpn(wpn,CF_BOMB))trigger = true;
  2450. }
  2451. if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_SBOMBBLAST
  2452. ||wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]==LW_SBOMBBLAST){
  2453. if(ComboFIAtWpn(wpn,CF_SBOMB))trigger = true;
  2454. }
  2455. if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_FIRE
  2456. ||wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]==LW_FIRE){
  2457. if(ComboFIAtWpn(wpn,CF_CANDLE1)){
  2458. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)trigger = true;
  2459. }
  2460. if(ComboFIAtWpn(wpn,CF_CANDLE2)){
  2461. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)trigger = true;
  2462. }
  2463. }
  2464. if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_MAGIC
  2465. ||wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]==LW_MAGIC)
  2466. && ComboFIAtWpn(wpn,CF_WANDMAGIC)
  2467. && (wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_IS_REFLECTED)==0)trigger = true;
  2468. if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_MAGIC
  2469. ||wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]==LW_MAGIC)
  2470. && ComboFIAtWpn(wpn,CF_REFMAGIC)
  2471. && (wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_IS_REFLECTED)!=0)trigger = true;
  2472. //else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_MELEE){
  2473. //if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_IS_SWORD){
  2474. //if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)return CF_SWORD1;
  2475. //else if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)return CF_SWORD2;
  2476. //else if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_3)!=0)return CF_SWORD3;
  2477. //else
  2478. //return CF_SWORD4;
  2479. //}
  2480. //else if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_IS_HAMMER)
  2481. //return CF_HAMMER;
  2482. //else if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_IS_WAND)
  2483. //return CF_WAND;
  2484. //}
  2485. if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_BEAM
  2486. ||wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]==LW_BEAM){
  2487. if(ComboFIAtWpn(wpn,CF_SWORD1BEAM)){
  2488. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)trigger = true;
  2489. }
  2490. if(ComboFIAtWpn(wpn,CF_SWORD2BEAM)){
  2491. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)trigger = true;
  2492. }
  2493. if(ComboFIAtWpn(wpn,CF_SWORD3BEAM)){
  2494. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_3)!=0)trigger = true;
  2495. }
  2496. if(ComboFIAtWpn(wpn,CF_SWORD4BEAM)){
  2497. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_4)!=0)trigger = true;
  2498. }
  2499. }
  2500. //else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_HOOKSHOT)
  2501. //return CF_HOOKSHOT;
  2502. if(trigger){
  2503. KillLWeapon(wpn);
  2504. Screen->TriggerSecrets();
  2505. Screen->State[ST_SECRET] = true;
  2506. Game->PlaySound(SFX_SECRET);
  2507. }
  2508. }
  2509.  
  2510. //Handles melee weapon behavior.
  2511.  
  2512. //void __UpdateLWE_Melee(lweapon wpn){
  2513. //for(int i=0; i<176; i++){
  2514. //if(wpn->Misc[LW_ZH_I_MOVEMENT]==LW_IS_SWORD){
  2515. //if((Screen->ComboT[i]==CT_SLASH||Screen->ComboT[i]==CT_BUSH
  2516. //||Screen->ComboT[i]==CT_FLOWERS||Screen->ComboT[i]==CT_TALLGRASS
  2517. //||Screen->ComboT[i]==CT_SLASHITEM||Screen->ComboT[i]==CT_SLASHNEXT)
  2518. //&& ComboCollision(i,wpn->X,wpn->Y,wpn->X+wpn->HitWidth,wpn->Y+wpn->HitHeight)){
  2519. //if(Screen->ComboT[i]!=CT_SLASH && Screen->ComboT[i]==CT_SLASHNEXT){
  2520. //CreateGraphicAt(GetComboSprite(Screen->ComboT[i]),ComboX(i),ComboY(i));
  2521. //ItemSetAt(IS_COMBOS,i);
  2522. //Game->PlaySound(GetComboSound(Screen->ComboT[i]));
  2523. //}
  2524. //if(Screen->ComboT[i]==CT_SLASHNEXT){
  2525. //Game->PlaySound(GetComboSound(Screen->ComboT[i]));
  2526. //Screen->ComboD[i]++;
  2527. //}
  2528. //else{
  2529. //Game->PlaySound(GetComboSound(Screen->ComboT[i]));
  2530. //Screen->ComboD[i]= Screen->UnderCombo;
  2531. //}
  2532. //}
  2533. //else if(Screen->ComboT[i]==CT_BUSHNEXT
  2534. //||Screen->ComboT[i]==CT_TALLGRASSNEXT
  2535. //||Screen->ComboT[i]==CT_SLASHNEXTITEM){
  2536. //CreateGraphicAt(GetComboSprite(Screen->ComboT[i]),ComboX(i),ComboY(i));
  2537. //ItemSetAt(IS_COMBOS,i);
  2538. //Game->PlaySound(GetComboSound(Screen->ComboT[i]));
  2539. //Screen->ComboD[i]++;
  2540. //}
  2541. //}
  2542. //else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LW_IS_HAMMER){
  2543. //if(Screen->ComboT[i]==CT_POUND
  2544. //&& ComboCollision(i,wpn->X,wpn->Y,wpn->X+wpn->HitWidth,wpn->Y+wpn->HitHeight)){
  2545. //Screen->ComboD[i]++;
  2546. //Game->PlaySound(SFX_HAMMER);
  2547. //}
  2548. //}
  2549. //}
  2550. //if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]&LW_HAS_SLASH)!=0)
  2551. //__UpdateLWM_Slash(wpn);
  2552. //if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]&LW_HAS_PERIL_SCR)!=0)
  2553. //__UpdateLWE_Peril(wpn);
  2554. //if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]&LW_HAS_WHIM_RING)!=0)
  2555. //__UpdateLWE_Whim(wpn);
  2556. //if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]&LW_HAS_BOOK)!=0)
  2557. //__UpdateLWE_Book(wpn);
  2558. //}
  2559.  
  2560. //Handles sword beam slash effects.
  2561.  
  2562. //void __UpdateLWM_Slash(lweapon wpn){
  2563.  
  2564. //}
  2565.  
  2566. //This weapon has the peril beam.
  2567.  
  2568. //void __UpdateLWE_Peril(lweapon wpn){
  2569.  
  2570. //}
  2571.  
  2572. //This weapon has the whimsical ring.
  2573.  
  2574. //void __UpdateLWE_Whim(lweapon wpn){
  2575.  
  2576. //}
  2577.  
  2578. //This wand has the magic book.
  2579.  
  2580. //void __UpdateLWE_Book(lweapon weapon){
  2581.  
  2582. //}
  2583.  
  2584. //Handles interaction with combos and Somaria blocks.
  2585.  
  2586. //void __UpdateLWE_Somaria(lweapon wpn){
  2587. //for(int i=0; i<176; i++){
  2588. //if(ComboFI(i,CF_BLOCKTRIGGER)
  2589. //&& ComboCollision(i,wpn->X,wpn->Y,wpn->X+wpn->HitWidth,wpn->Y+wpn->HitHeight)){
  2590. //if(!ScreenFlagTest(SF_SECRETS,SF_HIT_ALL_16_31) &&
  2591. //!ScreenFlagTest(SF_SECRETS,SF_HIT_ALL_PERM))
  2592. //Screen->TriggerSecrets();
  2593. //if(!ScreenFlagTest(SF_SECRETS,SF_NOT_PERM))
  2594. //Screen->State[ST_SECRET]= true;
  2595. //wpn->Misc[LW_ZH_I_WORK]=Screen->ComboD[i];
  2596. //wpn->Misc[LW_ZH_I_WORK_2]=i;
  2597. //if(wpn->DeadState==0){
  2598. //Screen->ComboD[i]=wpn->Misc[LW_ZH_I_WORK];
  2599. //Screen->State[ST_SECRET]= false;
  2600. //}
  2601. //Screen->ComboD[i]++;
  2602. //}
  2603. //if((Screen->ComboT[i]== CT_STEP||Screen->ComboT[i]==CT_STEPALL
  2604. //||Screen->ComboT[i]== CT_STEPSAME)
  2605. //&& ComboCollision(i,wpn->X,wpn->Y,wpn->X+wpn->HitWidth,wpn->Y+wpn->HitHeight)){
  2606. //wpn->Misc[LW_ZH_I_WORK]=Screen->ComboD[i];
  2607. //Screen->ComboD[i]++;
  2608. //if(wpn->DeadState==0)Screen->ComboD[i]=wpn->Misc[LW_ZH_I_WORK];
  2609. //}
  2610. //}
  2611. //if(wpn->Misc[LW_ZH_I_WORK]!=0){
  2612. //for(int i=0; i<176; i++){
  2613. //if(wpn->Misc[LW_ZH_I_WORK]==CT_STEPALL && Screen->ComboT[i]==CT_STEPCOPY){
  2614. //wpn->Misc[LW_ZH_I_WORK_2]=Screen->ComboD[i];
  2615. //Screen->ComboD[i]++;
  2616. //if(wpn->DeadState==0)Screen->ComboD[i]=wpn->Misc[LW_ZH_I_WORK_2];
  2617. //}
  2618. //else if(wpn->Misc[LW_ZH_I_WORK]==CT_STEPSAME && Screen->ComboT[i]== CT_STEPSAME)
  2619. //Screen->ComboD[i]++;
  2620. //else{
  2621. //if(!ComboCollision(i,wpn->X,wpn->Y,wpn->X+wpn->HitWidth,wpn->Y+wpn->HitHeight)
  2622. //&& Screen->ComboD[i]!=wpn->Misc[LW_ZH_I_WORK])
  2623. //Screen->ComboD[i]=wpn->Misc[LW_ZH_I_WORK];
  2624. //if(wpn->DeadState==0)
  2625. //Screen->ComboD[wpn->Misc[LW_ZH_I_WORK_2]]=wpn->Misc[LW_ZH_I_WORK];
  2626. //}
  2627. //}
  2628. //}
  2629. //}
  2630.  
  2631. //Handles magnetic glove interaction.
  2632.  
  2633. //void __UpdateLWE_Magnet(lweapon wpn){
  2634.  
  2635. //}
  2636.  
  2637. //Handles lweapons that move in a sine wave.
  2638.  
  2639. void __UpdateLWMSineWave(lweapon wpn){
  2640. float offset;
  2641. wpn->Misc[LW_ZH_I_WORK]+=wpn->Misc[LW_ZH_I_MOVEMENT_ARG2];
  2642.  
  2643. // Adjust the weapon's position at an angle
  2644. // perpendicular to that of its forward movement.
  2645. offset=wpn->Misc[LW_ZH_I_MOVEMENT_ARG]*Sin(wpn->Misc[LW_ZH_I_WORK]);
  2646. wpn->Misc[LW_ZH_I_XPOS]+=(wpn->Step/100)*RadianCos(wpn->Angle);
  2647. wpn->Misc[LW_ZH_I_YPOS]+=(wpn->Step/100)*RadianSin(wpn->Angle);
  2648. wpn->X=wpn->Misc[LW_ZH_I_XPOS]+offset*RadianCos(wpn->Angle+1.5708);
  2649. wpn->Y=wpn->Misc[LW_ZH_I_YPOS]+offset*RadianSin(wpn->Angle+1.5708);
  2650. }
  2651.  
  2652. //Handles homing lweapons.
  2653.  
  2654. void __UpdateLWMHoming(lweapon wpn){
  2655. // Wrap angle to 0..2*PI
  2656. float currentAngle=wpn->Angle%6.2832;
  2657.  
  2658. if(currentAngle<0)
  2659. currentAngle+=6.2832;
  2660. npc target_enemy;
  2661. int target_number;
  2662. // Find angle to Link and wrap it
  2663. if(Screen->NumNPCs()>0){
  2664. if(wpn->Misc[LW_ZH_I_WORK]==0)wpn->Misc[LW_ZH_I_WORK] = Rand(1,Screen->NumNPCs());
  2665. for(int i=Screen->NumNPCs();i>0;i--){
  2666. target_enemy = Screen->LoadNPC(i);
  2667. if(target_enemy->ID==wpn->Misc[LW_ZH_I_WORK] &&
  2668. target_enemy->Defense[LWDefense(wpn->ID)]!=NPCDT_BLOCK||
  2669. target_enemy->Defense[LWDefense(wpn->ID)]!=NPCDT_IGNORE)
  2670. target_enemy->Misc[NPC_MISC_TARGET_NUMBER]=wpn->Misc[LW_ZH_I_WORK];
  2671. }
  2672. if(target_enemy->HP<=0)wpn->Misc[LW_ZH_I_WORK]=0;
  2673. if(target_enemy->Misc[NPC_MISC_TARGET_NUMBER]==wpn->Misc[LW_ZH_I_WORK]){
  2674. float targetAngle=RadianAngle(wpn->X, wpn->Y, target_enemy->X, target_enemy->Y);
  2675. if(targetAngle<0)
  2676. targetAngle+=6.2832;
  2677.  
  2678. float diff=Abs(currentAngle-targetAngle);
  2679.  
  2680. // Turn toward Link
  2681. if(diff<wpn->Misc[LW_ZH_I_MOVEMENT_ARG] || diff>6.2832-wpn->Misc[LW_ZH_I_MOVEMENT_ARG])
  2682. wpn->Angle=targetAngle;
  2683.  
  2684. // Can't turn enough to point directly at him...
  2685. else if(Sign(currentAngle-targetAngle)==Sign(diff-PI)) // current>target and diff>pi or
  2686. wpn->Angle+=wpn->Misc[LW_ZH_I_MOVEMENT_ARG]; // current<target and diff<pi
  2687. else // - Turn CW or CCW?
  2688. wpn->Angle-=wpn->Misc[LW_ZH_I_MOVEMENT_ARG];
  2689.  
  2690. SetLWeaponDir(wpn);
  2691.  
  2692. // Decrement timer, unless it was negative to begin with
  2693. if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]>0){
  2694. wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]--;
  2695. if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]<=0)
  2696. Remove(wpn);
  2697. }
  2698. }
  2699. }
  2700.  
  2701. }
  2702.  
  2703. //Handles Lweapons thrown in an arc.
  2704.  
  2705. void __UpdateLWMThrow(lweapon wpn)
  2706. {
  2707. // LW_ZH_I_WORK: Current jump
  2708. // LW_ZH_I_WORK_2: Current Z position
  2709. // LW_ZH_I_MOVEMENT_ARG: Initial jump
  2710.  
  2711. wpn->Jump=0; // Override engine handling of Z movement
  2712.  
  2713. // Just thrown
  2714. if(wpn->Misc[LW_ZH_I_WORK]==0 && wpn->Misc[LW_ZH_I_MOVEMENT_ARG]!=0)
  2715. {
  2716. wpn->Misc[LW_ZH_I_WORK]=wpn->Misc[LW_ZH_I_MOVEMENT_ARG];
  2717. wpn->Misc[LW_ZH_I_MOVEMENT_ARG]=0;
  2718. }
  2719.  
  2720. // Fall
  2721. wpn->Misc[LW_ZH_I_WORK_2]=Max(wpn->Misc[LW_ZH_I_WORK_2]+wpn->Misc[LW_ZH_I_WORK], 0);
  2722. wpn->Z=wpn->Misc[LW_ZH_I_WORK_2];
  2723.  
  2724. // Hit the ground
  2725. // Still in the air; adjust velocity
  2726. if(wpn->Misc[LW_ZH_I_WORK_2]>0) // Z>0
  2727. wpn->Misc[LW_ZH_I_WORK]=Max(wpn->Misc[LW_ZH_I_WORK]-GH_GRAVITY, -GH_TERMINAL_VELOCITY);
  2728.  
  2729. // Hit the ground
  2730. else{
  2731. if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]&LWMF_DIE)!=0)
  2732. KillLWeapon(wpn);
  2733. //if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]&LWMF_REST)!=0){
  2734. //lweapon new = FireLWeapon(LW_SCRIPT1,wpn->X,wpn->Y,DegtoRad(0),0,
  2735. //wpn->Damage/2,SPR_SOMARIA_BLOCK,0,wpn->Misc[LW_ZH_I_FLAGS]);
  2736. //SetLWeaponLifespan(new,LWL_ITEM_PRESS,I_CSOMARIA);
  2737. //SetLWeaponMovement(new,LWM_REST,LWM_R_SOMARIA,0);
  2738. //SetLWeaponDeathEffect(new,LWD_4_FIREBALLS_DIAG,SPR_SOMARIA_FIRE);
  2739. //KillLWeapon(wpn);
  2740. //}
  2741. }
  2742.  
  2743. }
  2744.  
  2745. //Handles Lweapons that fall from the sky.
  2746.  
  2747. void __UpdateLWMFall(lweapon wpn)
  2748. {
  2749. wpn->Jump=0; // Override engine handling of Z movement
  2750. wpn->Misc[LW_ZH_I_WORK_2]-=wpn->Misc[LW_ZH_I_WORK];
  2751. wpn->Z=wpn->Misc[LW_ZH_I_WORK_2];
  2752. wpn->Misc[LW_ZH_I_WORK]=Min(wpn->Misc[LW_ZH_I_WORK]+GH_GRAVITY, GH_TERMINAL_VELOCITY);
  2753. // Hit the ground?
  2754. if(wpn->Misc[LW_ZH_I_WORK_2]<=0){
  2755. if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]&LWMF_DIE)!=0)
  2756. KillLWeapon(wpn);
  2757. //if((wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]&LWMF_REST)!=0){
  2758. //lweapon new = FireLWeapon(LW_SCRIPT1,wpn->X,wpn->Y,DegtoRad(0),0,
  2759. //wpn->Damage/2,SPR_SOMARIA_BLOCK,0,wpn->Misc[LW_ZH_I_FLAGS]);
  2760. //SetLWeaponLifespan(new,LWL_ITEM_PRESS,I_CSOMARIA);
  2761. //SetLWeaponMovement(new,LWM_REST,LWM_R_SOMARIA,0);
  2762. //SetLWeaponDeathEffect(new,LWD_4_FIREBALLS_DIAG,SPR_SOMARIA_FIRE);
  2763. //KillLWeapon(wpn);
  2764. //}
  2765. }
  2766. }
  2767.  
  2768. //Handles Lweapons that circle Link.
  2769.  
  2770. void __UpdateLWM_Circle(lweapon wpn){
  2771. wpn->Misc[LW_ZH_I_WORK]= (wpn->Misc[LW_ZH_I_WORK]
  2772. +((wpn->Step/100)*wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]))%360;
  2773. wpn->Misc[LW_ZH_I_XPOS]= Link->X+wpn->Misc[LW_ZH_I_MOVEMENT_ARG]*Sin(wpn->Misc[LW_ZH_I_WORK]);
  2774. wpn->Misc[LW_ZH_I_YPOS]= Link->Y+wpn->Misc[LW_ZH_I_MOVEMENT_ARG]*Cos(wpn->Misc[LW_ZH_I_WORK]);
  2775. wpn->Angle = DegtoRad(wpn->Misc[LW_ZH_I_WORK]);
  2776. SetLWeaponDir(wpn);
  2777. wpn->X=wpn->Misc[LW_ZH_I_XPOS];
  2778. wpn->Y=wpn->Misc[LW_ZH_I_YPOS];
  2779. }
  2780.  
  2781. //Handles Lweapons that act like the hookshot.
  2782.  
  2783. void __UpdateLWM_Hookshot(lweapon wpn){
  2784. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_RETURN)==0
  2785. &&(wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_HS_GRAB)==0){
  2786. if(wpn->Dir==DIR_LEFT||wpn->Dir==DIR_RIGHT){
  2787. if(Abs(wpn->X-Link->X+8)<=(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]*16)){
  2788. if(wpn->Dir==DIR_LEFT)wpn->Misc[LW_ZH_I_XPOS]--;
  2789. else if(wpn->Dir==DIR_RIGHT)wpn->Misc[LW_ZH_I_XPOS]++;
  2790. for(int i =0;i<=wpn->Misc[LW_ZH_I_MOVEMENT_ARG];i++){
  2791. lweapon particle = FireScriptedLWeapon(LW_SCRIPT1, Calc(wpn->X,Link->X+8,wpn->Misc[LW_ZH_I_MOVEMENT_ARG]),
  2792. wpn->Y, wpn->Misc[LW_ZH_I_MOVEMENT_ARG2], 0, 0,LWF_NO_COLLISION);
  2793. SetLWeaponLifespan(particle,LWL_TIMER,1);
  2794. SetLWeaponDeathEffect(particle,LWD_VANISH,0);
  2795. }
  2796. }
  2797. else
  2798. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  2799. }
  2800. else{
  2801. if(Abs(wpn->Y-Link->Y+8)<=(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]*16)){
  2802. if(wpn->Dir==DIR_UP)wpn->Misc[LW_ZH_I_YPOS]--;
  2803. else if(wpn->Dir==DIR_DOWN)wpn->Misc[LW_ZH_I_YPOS]++;
  2804. for(int i =0;i<=wpn->Misc[LW_ZH_I_MOVEMENT_ARG];i++){
  2805. lweapon particle = FireScriptedLWeapon(LW_SCRIPT1, wpn->X, Calc(wpn->Y,Link->Y+8,wpn->Misc[LW_ZH_I_MOVEMENT_ARG]),
  2806. wpn->Misc[LW_ZH_I_MOVEMENT_ARG2], 0, 0,LWF_NO_COLLISION);
  2807. SetLWeaponLifespan(particle,LWL_TIMER,1);
  2808. SetLWeaponDeathEffect(particle,LWD_VANISH,0);
  2809. }
  2810. }
  2811. else
  2812. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  2813. }
  2814. if(!OnScreen(wpn))
  2815. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  2816. Link->CollDetection = false;
  2817. NoAction();
  2818. }
  2819. SetLWeaponDir(wpn);
  2820. wpn->X= wpn->Misc[LW_ZH_I_XPOS];
  2821. wpn->Y= wpn->Misc[LW_ZH_I_YPOS];
  2822. }
  2823.  
  2824. void __HookshotPull(lweapon wpn){
  2825. wpn->Step = 0;
  2826. if(Link->X!=wpn->X && Link->Y!=wpn->Y){
  2827. if(Link->X<wpn->X)Link->X++;
  2828. else
  2829. Link->X--;
  2830. if(Link->Y<wpn->Y)Link->Y++;
  2831. else
  2832. Link->Y--;
  2833. Link->CollDetection = false;
  2834. NoAction();
  2835. }
  2836. else{
  2837. Link->CollDetection = true;
  2838. KillLWeapon(wpn);
  2839. }
  2840. }
  2841.  
  2842. void __NPCCollision(lweapon wpn){
  2843. for(int i=Screen->NumNPCs();i>0;i--){
  2844. npc n = Screen->LoadNPC(i);
  2845. if(Collision(wpn,n)){
  2846. if(n->Defense[LWDefense(wpn->ID)]==NPCDT_BLOCK||
  2847. n->Defense[LWDefense(wpn->ID)]==NPCDT_IGNORE){
  2848. Game->PlaySound(SFX_CLINK);
  2849. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_PIERCES_ENEMIES)!=0)
  2850. KillLWeapon(wpn);
  2851. }
  2852. if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_BRANG ||
  2853. wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_HOOKSHOT)
  2854. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  2855. else{
  2856. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_PIERCES_ENEMIES)==0)
  2857. KillLWeapon(wpn);
  2858. }
  2859. }
  2860. }
  2861. }
  2862.  
  2863. //Handles Lweapon that moves like a boomerang.
  2864.  
  2865. void __UpdateLWM_BRang(lweapon wpn){
  2866. float currentAngle=wpn->Angle%6.2832;
  2867. int RandX;
  2868. int RandY;
  2869. int PartX;
  2870. int PartY;
  2871. if(currentAngle<0)
  2872. currentAngle+=6.2832;
  2873. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_RETURN)==0){
  2874. if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]>0){
  2875. //This boomerang isn't farther from Link than it's range.
  2876. if(Abs(wpn->X-wpn->Misc[LW_ZH_I_XPOS])>wpn->Misc[LW_ZH_I_MOVEMENT_ARG]
  2877. ||Abs(wpn->Y-wpn->Misc[LW_ZH_I_YPOS])>wpn->Misc[LW_ZH_I_MOVEMENT_ARG])
  2878. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  2879. }
  2880. if(OnScreenEdge(wpn))
  2881. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  2882. }
  2883. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_RETURN)!=0){
  2884. //Set it not to collide with enemies.
  2885. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_NO_COLLISION;
  2886. float targetAngle=RadianAngle(wpn->X, wpn->Y, CenterLinkX(), CenterLinkY());
  2887. if(targetAngle<0)
  2888. targetAngle+=6.2832;
  2889.  
  2890. float diff=Abs(currentAngle-targetAngle);
  2891.  
  2892. //Turn toward Link
  2893. if(diff<wpn->Misc[LW_ZH_I_MOVEMENT_ARG2] || diff>6.2832-wpn->Misc[LW_ZH_I_MOVEMENT_ARG2])
  2894. wpn->Angle=targetAngle;
  2895.  
  2896. // Can't turn enough to point directly at him...
  2897. else if(Sign(currentAngle-targetAngle)==Sign(diff-PI)) // current>target and diff>pi or
  2898. wpn->Angle+=wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]; // current<target and diff<pi
  2899. else // - Turn CW or CCW?
  2900. wpn->Angle-=wpn->Misc[LW_ZH_I_MOVEMENT_ARG2];
  2901.  
  2902. SetLWeaponDir(wpn);
  2903.  
  2904. if(LinkCollision(wpn))
  2905. KillLWeapon(wpn);
  2906. }
  2907. //This boomerang makes sparkles.
  2908. if(wpn->Misc[LW_ZH_I_LIFESPAN_ARG]>0){
  2909. //Every 30 frames, create a sparkle.
  2910. //This sparkle dies in 30 frames.
  2911. wpn->Misc[LW_ZH_I_WORK_3]= (wpn->Misc[LW_ZH_I_WORK_3]+1)%5;
  2912. if(wpn->Misc[LW_ZH_I_WORK_3]==0){
  2913. if(wpn->Dir ==DIR_LEFT||wpn->Dir==DIR_RIGHT){
  2914. RandY = Rand(-4,4);
  2915. PartY = wpn->Y;
  2916. PartX = CenterWpnX(wpn);
  2917. }
  2918. else{
  2919. RandX = Rand(-4,4);
  2920. PartX = wpn->X;
  2921. PartY = CenterWpnY(wpn);
  2922. }
  2923. lweapon particle = FireLWeapon(LW_SCRIPT1,PartX+RandX,PartY+RandY,
  2924. DegtoRad(0), 0, wpn->Damage, wpn->Misc[LW_ZH_I_LIFESPAN_ARG], 0, 0);
  2925. SetLWeaponLifespan(particle,LWL_TIMER,60);
  2926. SetLWeaponDeathEffect(particle,LWD_VANISH,0);
  2927. }
  2928. }
  2929. }
  2930.  
  2931. //Handles Lweapon that has melee movement.
  2932.  
  2933. //void __UpdateLWM_Melee(lweapon wpn){
  2934.  
  2935. //}
  2936.  
  2937. //Handles lweapon that is carried.
  2938.  
  2939. void __UpdateLWM_Carry(lweapon wpn){
  2940. wpn->Misc[LW_ZH_I_XPOS]= Link->X;
  2941. wpn->Misc[LW_ZH_I_YPOS]= Link->Y-16;
  2942. wpn->X = wpn->Misc[LW_ZH_I_XPOS];
  2943. wpn->Y = wpn->Misc[LW_ZH_I_YPOS];
  2944. //else if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]== LWM_CARRY_SOM){
  2945. //if((Link->X+16)==wpn->X && Between(Link->Y+8,wpn->Y,wpn->Y+wpn->HitHeight)
  2946. //&& (Link->PressRight ||Link->InputRight)
  2947. //&& !Screen->isSolid(wpn->X+wpn->HitWidth,wpn->Y)
  2948. //&& !Screen->isSolid(wpn->X+wpn->HitWidth,wpn->Y+wpn->HitHeight)){
  2949. //wpn->Misc[LW_ZH_I_XPOS]++;
  2950. //}
  2951. //else if((Link->X+16)==wpn->X && Between(Link->Y+8,wpn->Y,wpn->Y+wpn->HitHeight)
  2952. //&& (Link->PressRight ||Link->InputRight)
  2953. //&& Screen->isSolid(wpn->X+wpn->HitWidth,wpn->Y)
  2954. //&& Screen->isSolid(wpn->X+wpn->HitWidth,wpn->Y+wpn->HitHeight)){
  2955. //Link->PressRight = false;
  2956. //Link->InputRight = false;
  2957. //}
  2958. //else if((Link->Y+16)==wpn->Y && Between(Link->X+8,wpn->X,wpn->X+wpn->HitWidth)
  2959. //&& (Link->PressDown ||Link->InputDown)
  2960. //&& !Screen->isSolid(wpn->X,wpn->Y+wpn->HitHeight)
  2961. //&& !Screen->isSolid(wpn->X+wpn->HitWidth,wpn->Y+wpn->HitHeight)){
  2962. //wpn->Misc[LW_ZH_I_YPOS]++;
  2963. //}
  2964. //else if((Link->Y+16)==wpn->Y && Between(Link->X+8,wpn->X,wpn->X+wpn->HitWidth)
  2965. //&& (Link->PressDown ||Link->InputDown)
  2966. //&& Screen->isSolid(wpn->X,wpn->Y+wpn->HitHeight)
  2967. //&& Screen->isSolid(wpn->X+wpn->HitHeight,wpn->Y+wpn->HitHeight)){
  2968. //Link->PressDown = false;
  2969. //Link->InputDown = false;
  2970. //}
  2971. //else if(Link->X==(wpn->X+wpn->HitWidth) && Between(Link->Y+8,wpn->Y,wpn->Y+wpn->HitHeight)
  2972. //&& (Link->PressLeft ||Link->InputLeft)
  2973. //&& !Screen->isSolid(wpn->X-1,wpn->Y)
  2974. //&& !Screen->isSolid(wpn->X-1,wpn->Y+wpn->HitHeight)){
  2975. //wpn->Misc[LW_ZH_I_XPOS]--;
  2976. //}
  2977. //else if(Link->X==(wpn->X+wpn->HitWidth) && Between(Link->Y+8,wpn->Y,wpn->Y+wpn->HitHeight)
  2978. //&& (Link->PressLeft ||Link->InputLeft)
  2979. //&& Screen->isSolid(wpn->X-1,wpn->Y)
  2980. //&& Screen->isSolid(wpn->X-1,wpn->Y+wpn->HitHeight)){
  2981. //Link->PressLeft = false;
  2982. //Link->InputLeft = false;
  2983. //}
  2984. //else if(Link->Y==(wpn->Y+wpn->HitHeight) && Between(Link->X+8,wpn->X,wpn->Y+wpn->HitWidth)
  2985. //&& (Link->PressUp ||Link->InputUp)
  2986. //&& !Screen->isSolid(wpn->X,wpn->Y-1)
  2987. //&& !Screen->isSolid(wpn->X+wpn->HitHeight,wpn->Y-1)){
  2988. //wpn->Misc[LW_ZH_I_YPOS]--;
  2989. //}
  2990. //else if(Link->Y==(wpn->Y+wpn->HitHeight) && Between(Link->X+8,wpn->X,wpn->Y+wpn->HitWidth)
  2991. //&& (Link->PressUp ||Link->InputUp)
  2992. //&& Screen->isSolid(wpn->X,wpn->Y-1)
  2993. //&& Screen->isSolid(wpn->X+wpn->HitHeight,wpn->Y-1)){
  2994. //Link->PressUp = false;
  2995. //Link->InputUp = false;
  2996. //}
  2997. //wpn->X = wpn->Misc[LW_ZH_I_XPOS];
  2998. //wpn->Y = wpn->Misc[LW_ZH_I_YPOS];
  2999. //__UpdateLWE_Somaria(wpn);
  3000. //}
  3001. //else if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]== LWM_R_MAGNET){
  3002. //if(Link->PressLeft||Link->InputLeft)
  3003. //wpn->Misc[LW_ZH_I_XPOS]--;
  3004. //else if(Link->PressRight||Link->InputRight)
  3005. //wpn->Misc[LW_ZH_I_XPOS]++;
  3006. //if(Link->PressUp||Link->InputUp)
  3007. //wpn->Misc[LW_ZH_I_YPOS]--;
  3008. //else if(Link->PressDown||Link->InputDown)
  3009. //wpn->Misc[LW_ZH_I_YPOS]++;
  3010. //Link->Dir= wpn->Dir;
  3011. //wpn->X = wpn->Misc[LW_ZH_I_XPOS];
  3012. //wpn->Y = wpn->Misc[LW_ZH_I_YPOS];
  3013. //__UpdateLWE_Magnet(wpn);
  3014. //}
  3015. }
  3016.  
  3017. //Handles Lweapons that pickup items.
  3018.  
  3019. void __UpdateLWF_Pickup(lweapon wpn){
  3020. if(Screen->NumItems()>0){
  3021. for(int i=1;i<=Screen->NumItems();i++){
  3022. item anitem = Screen->LoadItem(i);
  3023. for ( int r = 0; r < SizeOfArray(ItemsToPickup); r++ ) {
  3024. if(anitem->isValid()){
  3025. if ( anitem->ID == ItemsToPickup[r]) {
  3026. if (Collision(wpn,anitem)) {
  3027. if((wpn->Misc[LW_ZH_I_FLAGS]&LWF_INSTA_DELIVER)!=0){
  3028. anitem->X = Link->X;
  3029. anitem->Y = Link->Y;
  3030. }
  3031. else{
  3032. if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_BRANG)
  3033. wpn->Misc[LW_ZH_I_FLAGS_2]|= LWF_RETURN;
  3034. anitem->X = wpn->X;
  3035. anitem->Y = wpn->Y;
  3036. if(LinkCollision(wpn)){
  3037. anitem->X = Link->X;
  3038. anitem->Y = Link->Y;
  3039. }
  3040. }
  3041. }
  3042.  
  3043. }
  3044. }
  3045. else
  3046. continue;
  3047. }
  3048. }
  3049. }
  3050. }
  3051.  
  3052. //Handles Lweapons that pierce enemies.
  3053.  
  3054. void __UpdateLWF_Pierce(lweapon wpn){
  3055. wpn->DeadState = WDS_ALIVE;
  3056. }
  3057.  
  3058. //Handles Lweapons that stun enemies.
  3059.  
  3060. void __UpdateLWF_Stun(lweapon wpn){
  3061. if(Screen->NumNPCs()>0){
  3062. for(int i=Screen->NumNPCs();i>0;i--){
  3063. npc thing = Screen->LoadNPC(i);
  3064. if(thing->HP<=0)break;
  3065. if(Collision(thing,wpn) && (thing->Defense[LWDefense(wpn->ID)]==NPCDT_STUN
  3066. || thing->Defense[LWDefense(wpn->ID)]==NPCDT_STUNORBLOCK
  3067. || thing->Defense[LWDefense(wpn->ID)]==NPCDT_STUNORIGNORE)){
  3068. if(thing->Defense[LWDefense(wpn->ID)]!=NPCDT_STUN){
  3069. int StunChance = Rand(0,100);
  3070. if(StunChance>50)thing->Stun= Rand(0,MAX_STUN_TIME);
  3071. }
  3072. else
  3073. thing->Stun = Rand(0,MAX_STUN_TIME);
  3074. KillLWeapon(wpn);
  3075. }
  3076. }
  3077. }
  3078. }
  3079.  
  3080. //Handles lweapons that are reflected off of magic mirrors.
  3081.  
  3082. void __UpdateLWF_Reflect(lweapon wpn){
  3083. float angle;
  3084. lweapon new;
  3085. int XOffset = wpn->X % 16;
  3086. int YOffset = wpn->Y % 16;
  3087. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_WAS_REFLECTED)==0){
  3088. if(ComboTAtWpn(wpn,CT_MIRROR)||
  3089. ComboTAtWpn(wpn,CT_MIRRORBACKSLASH)||
  3090. ComboTAtWpn(wpn,CT_MIRRORSLASH)){
  3091. if(ComboTAtWpn(wpn)==CT_MIRRORSLASH){
  3092. if(wpn->Dir==DIR_UP){
  3093. angle = DegtoRad(0);
  3094. wpn->X+=XOffset;
  3095. wpn->Y-=YOffset;
  3096. }
  3097. else if(wpn->Dir==DIR_DOWN){
  3098. angle = DegtoRad(180);
  3099. wpn->X-=XOffset;
  3100. wpn->Y+=YOffset;
  3101. }
  3102. else if(wpn->Dir==DIR_LEFT){
  3103. angle = DegtoRad(270);
  3104. wpn->X+=XOffset;
  3105. wpn->Y-=YOffset;
  3106. }
  3107. else if(wpn->Dir==DIR_RIGHT){
  3108. angle = DegtoRad(90);
  3109. wpn->X-=XOffset;
  3110. wpn->Y+=YOffset;
  3111. }
  3112. }
  3113. else if(ComboTAtWpn(wpn)==CT_MIRRORBACKSLASH){
  3114. if(wpn->Dir==DIR_UP){
  3115. angle = DegtoRad(180);
  3116. wpn->X-=XOffset;
  3117. wpn->Y-=YOffset;
  3118. }
  3119. else if(wpn->Dir==DIR_DOWN){
  3120. angle = DegtoRad(0);
  3121. wpn->X+=XOffset;
  3122. wpn->Y+=YOffset;
  3123. }
  3124. else if(wpn->Dir==DIR_LEFT){
  3125. angle = DegtoRad(90);
  3126. wpn->X-=XOffset;
  3127. wpn->Y+=YOffset;
  3128. }
  3129. else if(wpn->Dir==DIR_RIGHT){
  3130. angle = DegtoRad(270);
  3131. wpn->X+=XOffset;
  3132. wpn->Y-=YOffset;
  3133. }
  3134. }
  3135. if(wpn->TileHeight==0 && wpn->TileWidth==0)
  3136. new = FireLWeapon(wpn->ID, wpn->X, wpn->Y, angle, wpn->Step, wpn->Damage, wpn->Misc[LW_ZH_I_LIFESPAN_ARG], wpn->Misc[LW_ZH_I_FX], wpn->Misc[LW_ZH_I_FLAGS]);
  3137. else
  3138. new = FireBigLWeapon(wpn->ID, wpn->X, wpn->Y, angle, wpn->Step, wpn->Damage, wpn->Misc[LW_ZH_I_LIFESPAN_ARG], wpn->Misc[LW_ZH_I_FX], wpn->Misc[LW_ZH_I_FLAGS],wpn->TileHeight,wpn->TileWidth);
  3139. SetLWeaponLifespan(new, wpn->Misc[LW_ZH_I_LIFESPAN], wpn->Misc[LW_ZH_I_LIFESPAN_ARG]);
  3140. SetLWeaponMovement(new,wpn->Misc[LW_ZH_I_MOVEMENT],wpn->Misc[LW_ZH_I_MOVEMENT_ARG],wpn->Misc[LW_ZH_I_MOVEMENT_ARG2]);
  3141. if(wpn->Misc[LW_ZH_I_FX]>0)
  3142. SetLWeaponSFX(new, wpn->Misc[LW_ZH_I_FX], wpn->Misc[LW_ZH_I_WORK_2]);
  3143. SetLWeaponDeathEffect(new, wpn->Misc[LW_ZH_I_ON_DEATH], wpn->Misc[LW_ZH_I_ON_DEATH_ARG]);
  3144. new->Misc[LW_ZH_I_FLAGS_2]|=wpn->Misc[LW_ZH_I_FLAGS_2]|LWF_WAS_REFLECTED;
  3145. Remove(wpn);
  3146. }
  3147. }
  3148. else if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_WAS_REFLECTED)!=0){
  3149. if(!ComboTAtWpn(wpn,CT_MIRROR)&&
  3150. !ComboTAtWpn(wpn,CT_MIRRORBACKSLASH)&&
  3151. !ComboTAtWpn(wpn,CT_MIRRORSLASH)){
  3152. wpn->Misc[LW_ZH_I_FLAGS_2]&=~LWF_WAS_REFLECTED;
  3153. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_IS_REFLECTED)==0)
  3154. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_IS_REFLECTED;
  3155. }
  3156. }
  3157. }
  3158.  
  3159. //Makes lweapon ignore gravity
  3160.  
  3161. void __UpdateLWF_G_Force(lweapon wpn){
  3162. wpn->Jump = 0;
  3163. }
  3164.  
  3165. //Turns an lweapons collision detection off.
  3166.  
  3167. void __UpdateLWF_Collision(lweapon wpn){
  3168. wpn->CollDetection= false;
  3169. }
  3170.  
  3171. void __UpdateLWF_Poison(lweapon wpn){
  3172. if(Screen->NumNPCs()>0){
  3173. for(int i=Screen->NumNPCs();i>0;i--){
  3174. npc thing = Screen->LoadNPC(i);
  3175. if(wpn->Misc[LW_ZH_I_WORK]==0){
  3176. if(Collision(thing,wpn) && (thing->Defense[LWDefense(wpn->ID)]==NPCDT_STUN
  3177. || thing->Defense[LWDefense(wpn->ID)]==NPCDT_STUNORBLOCK
  3178. || thing->Defense[LWDefense(wpn->ID)]==NPCDT_STUNORIGNORE)){
  3179. if(thing->Defense[LWDefense(wpn->ID)]!=NPCDT_STUN){
  3180. int PoisonChance = Rand(0,100);
  3181. if(PoisonChance>50){
  3182. if(thing->HP<=0)wpn->Misc[LW_ZH_I_WORK]=0;
  3183. thing->Misc[NPC_MISC_TARGET_NUMBER] = Rand(0,255);
  3184. wpn->Misc[LW_ZH_I_WORK]= thing->Misc[NPC_MISC_TARGET_NUMBER];
  3185. }
  3186. }
  3187. else{
  3188. if(thing->HP<=0)wpn->Misc[LW_ZH_I_WORK]=0;
  3189. thing->Misc[NPC_MISC_TARGET_NUMBER] = Rand(0,255);
  3190. wpn->Misc[LW_ZH_I_WORK]= thing->Misc[NPC_MISC_TARGET_NUMBER];
  3191. }
  3192. }
  3193. }
  3194. else{
  3195. thing = Screen->LoadNPC(wpn->Misc[LW_ZH_I_WORK]);
  3196. if(thing->HP<=0)wpn->Misc[LW_ZH_I_WORK]=0;
  3197. else{
  3198. if(wpn->Misc[LW_ZH_I_WORK_3]<300){
  3199. wpn->Misc[LW_ZH_I_WORK_2]= (wpn->Misc[LW_ZH_I_WORK_2]+1)%30;
  3200. if(wpn->Misc[LW_ZH_I_WORK_2]==0)thing->HP--;
  3201. wpn->Misc[LW_ZH_I_WORK_3]++;
  3202. wpn->X = thing->X;
  3203. wpn->Y = thing->Y;
  3204. wpn->UseSprite(POISON_SPRITE);
  3205. Game->PlaySound(SFX_POISON);
  3206. }
  3207. }
  3208. }
  3209. }
  3210. }
  3211. }
  3212.  
  3213. const int POISON_SPRITE = 0;
  3214. const int SFX_POISON = 0;
  3215.  
  3216. //Makes Link invincible while this is active.
  3217.  
  3218. void __UpdateLWF_Link_CollOff(){
  3219. Link->CollDetection= false;
  3220. }
  3221.  
  3222. //Makes it where Link can't move while this lweapon is active.
  3223.  
  3224. void __UpdateLWF_Link_FreezeOn(){
  3225. NoAction();
  3226. }
  3227.  
  3228. void __FlagTrigger(lweapon wpn){
  3229. bool trigger = false;
  3230. if(wpn->ID==LW_ARROW){
  3231. if(ComboFIAtWpn(wpn,CF_ARROW)){
  3232. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)trigger = true;
  3233. }
  3234. if(ComboFIAtWpn(wpn,CF_ARROW2)){
  3235. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)trigger = true;
  3236. }
  3237. if(ComboFIAtWpn(wpn,CF_ARROW3)){
  3238. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_3)!=0)trigger = true;
  3239. }
  3240. }
  3241. else if(wpn->ID==LW_FIRE){
  3242. if(ComboFIAtWpn(wpn,CF_CANDLE1)){
  3243. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)trigger = true;
  3244. }
  3245. if(ComboFIAtWpn(wpn,CF_CANDLE2)){
  3246. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)trigger = true;
  3247. }
  3248. }
  3249. else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_BRANG){
  3250. if(ComboFIAtWpn(wpn,CF_BRANG1)){
  3251. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)trigger = true;
  3252. }
  3253. if(ComboFIAtWpn(wpn,CF_BRANG2)){
  3254. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)trigger = true;
  3255. }
  3256. if(ComboFIAtWpn(wpn,CF_BRANG3)){
  3257. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_3)!=0)trigger = true;
  3258. }
  3259. }
  3260. else if(wpn->ID==LW_MAGIC && ComboFIAtWpn(wpn,CF_WANDMAGIC))trigger = true;
  3261. else if(wpn->ID==LW_MAGIC && ComboFIAtWpn(wpn,CF_WANDFIRE)
  3262. && (wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_3)!=0)trigger = true;
  3263. else if(wpn->ID==LW_MAGIC && ComboFIAtWpn(wpn,CF_REFMAGIC)
  3264. && (wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_IS_REFLECTED)!=0)trigger = true;
  3265. //else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_MELEE){
  3266. //if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_IS_SWORD){
  3267. //if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)return CF_SWORD1;
  3268. //else if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)return CF_SWORD2;
  3269. //else if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_3)!=0)return CF_SWORD3;
  3270. //else
  3271. //return CF_SWORD4;
  3272. //}
  3273. //else if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_IS_HAMMER)
  3274. //return CF_HAMMER;
  3275. //else if(wpn->Misc[LW_ZH_I_MOVEMENT_ARG]==LW_IS_WAND)
  3276. //return CF_WAND;
  3277. //}
  3278. else if(wpn->ID==LW_BEAM){
  3279. if(ComboFIAtWpn(wpn,CF_SWORD1BEAM)){
  3280. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_1)!=0)trigger = true;
  3281. }
  3282. if(ComboFIAtWpn(wpn,CF_SWORD2BEAM)){
  3283. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_2)!=0)trigger = true;
  3284. }
  3285. if(ComboFIAtWpn(wpn,CF_SWORD3BEAM)){
  3286. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_3)!=0)trigger = true;
  3287. }
  3288. if(ComboFIAtWpn(wpn,CF_SWORD4BEAM)){
  3289. if((wpn->Misc[LW_ZH_I_FLAGS_2]&LWF_LEVEL_4)!=0)trigger = true;
  3290. }
  3291. }
  3292. //else if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_HOOKSHOT)
  3293. //return CF_HOOKSHOT;
  3294. if(trigger){
  3295. if(wpn->Misc[LW_ZH_I_MOVEMENT]==LWM_BRANG)
  3296. wpn->Misc[LW_ZH_I_FLAGS_2]|=LWF_RETURN;
  3297. else
  3298. KillLWeapon(wpn);
  3299. Screen->TriggerSecrets();
  3300. Screen->State[ST_SECRET] = true;
  3301. Game->PlaySound(SFX_SECRET);
  3302. }
  3303. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement