ZoriaRPG

NES Zelda Drops v0.3 for 2.55

Feb 17th, 2019
201
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Zelda 1 Style Random drops
  2. //v0.3
  3. //For 2.55
  4. //By: ZoriaRPG
  5. //17th February, 2019
  6.  
  7. script typedef ffc class;
  8.  
  9. class script Z1enemydrop
  10. {
  11.     void run(){}
  12.     int killcount[2];
  13.     const int KILL_NORMAL;
  14.     const int KILL_CONSEC;
  15.    
  16.     const int DROPSET_A = 0;
  17.     const int DROPSET_B = 1;
  18.     const int DROPSET_C = 2;
  19.     const int DROPSET_D = 3;
  20.     const int DROPSET_X = 4;
  21.     const int DROPSET_M = 5; MAGIC, 100%
  22.     const int DROPSET_V = 6; //Vire splits increase the count, but do not drop items.
  23.     const int DROP_X_OFS = 0;
  24.     const int DROP_Y_OFS = 0;
  25.    
  26.     int chances[] = {31,41,59,41, 0, 100};
  27.     int lists[4*10]=
  28.     {
  29.         I_RUPEE, I_HEART, I_RUPEE, I_FAIRY, I_RUPEE, I_HEART, I_HEART, I_RUPEE, I_HEART, I_HEART,
  30.         I_BOMB, I_RUPEE, I_CLOCK, I_RUPEE, I_HEART, I_BOMB, I_RUPEE, I_BOMB, I_HEART, I_HEART,
  31.         I_RUPEE, I_HEART, I_RUPEE, I_RUPEE5, I_HEART, I_CLOCK, I_RUPEE, I_RUPEE, I_RUPEE, I_RUPEE5,
  32.         I_HEART, I_FAIRY. I_RUPEE, I_HEART, I_FAIRY, I_HEART, I_HEART, I_HEART, I_RUPEE, I_HEART,
  33.         -1, -1, -1, -1, -1, -1,  -1,  -1,  -1,  -1 //Vires when they only split, will increment counts, bu never drop items
  34.     };
  35.     //The dropset that a given enemy uses; SPLITTERS NEED SPECIAL HANDLING?
  36.     //This could instead be an enemy editor attribute fied of some sort. rather than an array,
  37.     //so that the questmaker can customise it.
  38.     int enemydropsets[]=
  39.     {
  40.         //guys
  41.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  42.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  43.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  44.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  45.        
  46.         //enemies start here
  47.         DROPSET_A, DROPSET_B, DROPSET_A, DROPSET_B, DROPSET_A,
  48.         DROPSET_C, DROPSET_C, DROPSET_A, DROPSET_A, DROPSET_B,
  49.         DROPSET_D, DROPSET_C, DROPSET_D, DROPSET_D, DROPSET_X,
  50.                //GHINI2 ?PHANTOM
  51.         DROPSET_C, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  52.         DROPSET_X, DROPSET_C, DROPSET_X, DROPSET_C, DROPSET_C,
  53.         DROPSET_B, DROPSET_D, DROPSET_X, DROPSET_C, DROPSET_B,
  54.         DROPSET_D, DROPSET_X, DROPSET_B, DROPSET_X, DROPSET_B,
  55.         DROPSET_C, DROPSET_B, DROPSET_A, DROPSET_D, DROPSET_D,MOLDORM
  56.         DROPSET_D, DROPSET_D, DROPSET_D, DROPSET_D, DROPSET_D,
  57.         DROPSET_D, DROPSET_X, DROPSET_X, DROPSET_D, DROPSET_D,
  58.         DROPSET_D, DROPSET_D, DROPSET_D, DROPSET_D, DROPSET_D, //LANMOLA
  59.         DROPSET_C, DROPSET_D, DROPSET_D, DROPSET_X, DROPSET_C,
  60.         DROPSET_C, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  61.         DROPSET_X, DROPSET_B, DROPSET_D, DROPSET_X, DROPSET_X,
  62.         DROPSET_X, DROPSET_B, DROPSET_D, DROPSET_D, DROPSET_D,
  63.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_B,
  64.         DROPSET_A, DROPSET_C, DROPSET_C, DROPSET_D, DROPSET_D,
  65.         DROPSET_D, DROPSET_M, DROPSET_A, DROPSET_A, DROPSET_D,
  66.         DROPSET_D, DROPSET_D, DROPSET_D, DROPSET_A, DROPSET_D,
  67.         DROPSET_D, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  68.         DROPSET_C, DROPSET_D, DROPSET_D, DROPSET_X, DROPSET_X,
  69.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  70.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  71.         DROPSET_X, DROPSET_D, DROPSET_A, DROPSET_B, DROPSET_B,
  72.         DROPSET_B, DROPSET_B, DROPSET_X, DROPSET_X, DROPSET_X,
  73.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  74.         DROPSET_X, DROPSET_X, DROPSET_B, DROPSET_A, DROPSET_X,
  75.         DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X, DROPSET_X,
  76.         DROPSET_X, DROPSET_X, DROPSET_C, DROPSET_X, DROPSET_C,
  77.         DROPSET_A, DROPSET_X, DROPSET_X, DROPSET_D, DROPSET_D,
  78.         DROPSET_M, DROPSET_C, DROPSET_D, DROPSET_D, DROPSET_M,
  79.         DROPSET_X, DROPSET_X, DROPSET_X
  80.    
  81.     };
  82.     int getChance(int enemyid)
  83.     {
  84.         return chances[enemydropsets[enemyid]];
  85.     }
  86.     bool canDrop(int enemy_id)
  87.     {
  88.         return ( Rand(1,100) <= getChance(enemy_id) );
  89.     }
  90.     void doDrop(npc n)
  91.     {
  92.         if ( n->HP > 0 ) return; //wait until dead
  93.         bool ignore = false;
  94.         switch(n->Family)
  95.         {
  96.             case NPCT_MOLDORM:
  97.             case NPCT_MANHANDLA:
  98.             case NPCT_GLEEOK:
  99.             case NPCT_LANMOLA:
  100.             case NPCT_PATRA:
  101.             {
  102.                 if ( !n->isCore ) ignore = true; break;
  103.             }
  104.             case NPCT_DODONGO: ignore = true; break; //These never drop items, AFAIK.
  105.             default: break;
  106.        
  107.         }
  108.         if ( !ignore )
  109.         {
  110.             if ( canDrop(n->ID) )
  111.             {
  112.                 int drp_itm_id = lists[enemydropsets[n->ID]+killcount[KILL_NORMAL]];
  113.                 switch(killcount[KILL_CONSEC])
  114.                 {
  115.                     begin insane Z1 consecutive drop rules.
  116.                     case 10: drp_itm_id = I_BOMBAMMO1; break;
  117.                     case 16: drp_itm_id = I_FAIRY; break;
  118.                     default: break;
  119.                    
  120.                     /*
  121.                     TO IMPLEMENT
  122.                     Advanced strategies: If a forced bomb/rupee or forced fairy drops,
  123.                     the consecutive counter for bombs/rupees is reset, but not the counter
  124.                     for fairies. So no matter how many hits you get on Manhandla with one
  125.                     well-placed bomb, the 10 count is reset after defeating him.
  126.                     The same is true of Dodongo. Likewise with a "Hippo Fairy"
  127.                     (going into a Patra with 7 on the consecutive counters, so that the
  128.                     Patra's center will be kill #16 and get a fairy), the bomb/rupee count
  129.                     resets to 0. Credit to Khananaphone for this discovery.
  130.                     This means that if you get a forced fairy drop, the next
  131.                     consecutive bomb/rupee kill will not be at 20. It will be at 26.
  132.                     So bomb/rupee drops work in one of two methods:
  133.  
  134.                         10, (Fairy at 16), 26, 36, 46...
  135.                         10, (Skip fairy at 16 by killing non-dropping enemy), 20, 30, 40...            
  136.                     */
  137.                 }
  138.                 item drp = Screen->CreateItem(drp_itm_id);
  139.                 drp->X = n->X + DROP_X_OFS; drp->Y = n->Y + DROP_Y_OFS;
  140.                 drp->Pickup = IP_TIMEOUT;
  141.                 ( killcount[KILL_NORMAL] < 9 ) ? ++killcount[KILL_NORMAL] : killcount[KILL_NORMAL] = 0;
  142.                 ++killcount[KILL_CONSEC]; //when does this roll over on the NES?
  143.             }
  144.         }
  145.     }
  146.     void resetKillcount()
  147.     {  
  148.         if ( Link->InvFrames ) killcount[KILL_CONSEC] = 0;
  149.     }
  150.    
  151. }
  152.  
  153. link script LinkZ1
  154. {
  155.     void run()
  156.     {
  157.         while(1)
  158.         {
  159.             Z1enemydrop.resetKillcount();
  160.             for ( int q = Screen->NumNPCs(); q > 0; --q )
  161.             {
  162.                 npc n = Screen->LoadNPC(q);
  163.                 Z1enemydrop.doDrop(n);
  164.             }
  165.    
  166.    
  167.     }
  168. }
  169.  
  170. /*
  171. Forced drops
  172.  
  173. Some item drops can be forced and take priority over the standard drop system.
  174. Forced drops are handled by two consecutive kill counters and a bomb flag.
  175. The first counter, the ten count ($50), controls whether a forced 5 rupee is dropped.
  176. The bomb flag ($51) controls whether the ten count drop should be a bomb, instead.
  177. The second counter, the fairy count ($0627), controls whether fairies are dropped.
  178. All of these variables are cleared when Link collides with an enemy (including bubbles and
  179. even the recorder whirlwind).
  180.  
  181. When Link kills an enemy (that is, the enemy makes a dying sound), both counters are incremented.
  182. This occurs at kill time, before the dying animation.
  183. Item drops occur later, after the dying animation completes. When the drop is calculated,
  184. the game checks the counters to decide what to drop. If the fairy count is 16, then a fairy is
  185. dropped and the ten count and bomb flag are cleared. Otherwise, if the ten count is 10,
  186. either a 5 rupee is dropped if the bomb flag is clear or a bomb is dropped if the flag is set,
  187. and the ten count and bomb flag are then cleared. So, in the case of any forced drop,
  188. the ten count and bomb flag are cleared, but the fairy count is not.
  189.  
  190. Some enemies cannot drop items. Because they don't run the drop code, they also can't
  191. drop forced items, and thus won't consume the counters. These enemies are those in the
  192. no-drop group, as well as stalfos, gibdos, and like likes in slot 1
  193. (because these enemies may be carrying the room treasure, and it would be undesirable
  194. if they dropped both the treasure and an item). We'll call these no-drop enemies.
  195.  
  196. If the ten count transitions from 9 to 10 due to a bomb kill, the bomb flag is set.
  197. The ten count cannot exceed 10 and will hold at that value even if additional
  198. kills occur before the forced item can be dropped, such as by killing a group of
  199. enemies at once or killing no-drop enemies.
  200. Once any forced drop occurs, the counter is reset to 0.
  201.  
  202. The fairy counter, however, has no hard limit.
  203. It will continue to increase with each kill.
  204. Because of this, the fairy drop can be skipped.
  205. Any drop occurring when the fairy counter is 16 will be a fairy, so killing a
  206. group of enemies to bring the count above 16 at drop time will skip the fairy.
  207. Alternatively, because no-drop enemies can't drop forced items,
  208. they can die with the counter at 16 without performing the drop.
  209. Skipping the fairy will avoid resetting the ten count and bomb flag.
  210.  
  211. Because the fairy counter isn't cleared when the drop occurs, multiple
  212. fairies can be dropped from the same count. For example, if the counter is
  213. 12 and 4 enemies are quickly killed before any of them can calculate a drop,
  214. the counter will be 16 when the drops are handled, so all 4 drops will be fairies.
  215.  
  216. Note that while the fairy counter has no hard limit, it is an 8-bit value and will
  217. overflow to 0 at 256 kills, allowing it to force more fairies at the next 16.
  218.  
  219. There are some notable special cases and edge cases with counters. These include:
  220.  
  221. Dodongos: Killing a dodongo does not increment either counter, whether killed with
  222. bombs or the sword. If the dodongo is killed with a sword, however,
  223. the ten count is set to 10 and the bomb flag is set, forcing a bomb at drop time.
  224. This method of forcing the bomb can result in unexpected behavior.
  225. If Link takes a hit after killing the dodongo, but before the drop, the forced bomb
  226. will be lost. Furthermore, if the fairy count is 16 when the drop occurs, the fairy
  227. will be dropped instead of the bomb and the ten count and bomb flag will be cleared.
  228. Finally, if Link kills a second dodongo with a sword before the first one has dropped
  229. its bomb, the second will not drop a bomb because the forced drop system has no way of
  230. queuing up multiple forced bombs.
  231.  
  232. Vulnerable unkillable enemies: Enemies such as the manhandla core and flying
  233. gleeok heads are invincible, but actually handle weapon collision and will
  234. clear their iframes and unkill themselves each frame. This means they count as a
  235. kill every frame that a weapon is touching them. Bombing these enemies is a good
  236. way to force a bomb because it will quickly max out the ten count and set
  237. the bomb flag, but it will also be adding to the fairy counter, which could override
  238. the bomb drop when killing the boss. The old man in the dungeon also behaves this way,
  239. but because he doesn't clear his iframes, he'll only count as one kill per attack.
  240.  
  241. Multi-part enemies: Manhandla's hands, gleeok's attached heads, and moldorm's
  242. and lanmola's segments each increment the consecutive counters when killed,
  243. but the death of the whole enemy does not grant an additional consecutive kill;
  244. that is, killing the last part will only add 1 to the counters, not 2.
  245. A perfect bomb on manhandla will increase the counters by 5 instead of 4,
  246. though, because the core is also hit and counts as a kill.
  247.  
  248. Leader enemies: When a ringleader (such as the level 2 goriya leader) is killed,
  249. the other enemies in the room die by being directly transitioned to the dying state
  250. (by setting dynamic_spawn_state to #$10) and will not impact the consecutive counters.
  251. The ringleader itself counts as normal, however. Ghini leaders also share this same
  252. behavior (through a similar mechanism).
  253.  
  254. Zols: While splitting enemies (zols and vires) don't normally count as kills
  255. when split, zols are vulnerable to an additional weapon hit on the frame they
  256. split, allowing them to be killed and counted as a consecutive kill.
  257. This is due to a bug where zols delete themselves before splitting
  258. (in case there aren't enough slots for the gels they're creating),
  259. but instead of exiting immediately afterward, their AI continues to do
  260. meaningful work on the deleted object, including collision checks.
  261. The deletion (through ClearObject at Bank7_FEB1) clears the object_iframes variable,
  262. which guarantees the zol can take a hit during this one last check.
  263. Because deletion clears the object's dynamic_id variable, the zol doesn't
  264. run again and thus can't drop an item nor increment the global counter.
  265. Its health is not cleared by ClearObject, so the weapons it collides with must
  266. do enough damage to kill it. Note that if a gel was spawned into the zol's slot,
  267. the gel will be hit, instead.
  268.  
  269. Vires are more robustly written and don't suffer from this bug.
  270.  
  271. Overkill: When an enemy is killed by a weapon, it still finishes checking the
  272. remaining weapons that frame, as normal. This means it can be hit by those additional
  273. weapons, which may also kill it. The consecutive kill counters are incremented at
  274. kill time, so these additional kills will each increment the counters like with
  275. any normal kill. As a result, killing a single enemy by hitting it with multiple
  276. weapons on one frame can add more than one to the counts.
  277. This can be done most practically by timing multiple attacks to hit when an enemy's iframes expire.
  278.  
  279. Note that the health the enemy has after a killing blow can vary.
  280. If the weapon damage was equal to the enemy's current health, the resulting health
  281. is 0, so any following hits will count as kills.
  282. However, if the damage was more than the current health, the health is unchanged.
  283. Furthermore, the order in which weapons are checked can impact how many kills the
  284. enemy gives because each weapon hit may reduce the health for the following weapons.
  285. Weapon check order is boomerang, beam (sword/rod), flame/bomb slot A, flame/bomb slot B,
  286. sword, arrow/rod.
  287.  
  288. Sub-frame behavior: Because everything in the game must be handled sequentially,
  289. events handled earlier can directly impact those handled later, so the order of
  290. execution can result in surprising behavior. For example, if an enemy is killed
  291. on the same frame that multiple other enemies are dropping items, and that kill
  292. sets the fairy counter to 16, then any drops handled before the kill was registered
  293. would be normal random drops, and drops after the kill would be forced fairies,
  294. despite all of the drops happening on the same frame.
  295. */
RAW Paste Data