pedroff_1

Untitled

Apr 21st, 2020
443
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 14.18 KB | None | 0 0
  1. local LilLarry = {}
  2. LilLarry.item = PassiveItem("Lil Larry")
  3. LilLarry.head = Isaac.GetEntityVariantByName("Lil Larry's Head")
  4. LilLarry.body = Isaac.GetEntityVariantByName("Lil Larry's Body")
  5. LilLarry.guideType = Isaac.GetEntityTypeByName("Lil Larry's Head's Guide")
  6. LilLarry.guideVariant = Isaac.GetEntityVariantByName("Lil Larry's Head's Guide")
  7. -- parameters for the familiar's characteristics
  8. LilLarry.maxSegmentDistance = 30
  9. LilLarry.maxTargetDistanceForTracking = 400
  10. LilLarry.minTargetDistanceForTracking = 60
  11. LilLarry.minTargetDistance = 0.1
  12. LilLarry.maxTargetDistance = 500
  13. LilLarry.segmentFollowingSpeed = 7
  14. LilLarry.HeadSpeed = 5
  15. LilLarry.baseDamage = 0.1
  16. LilLarry.baseDamageIncrement = 0.1
  17. LilLarry.baseSize = 14
  18.  
  19. --why does it behave oddly around portals?
  20. --External Item Description text
  21. __eidItemDescriptions[LilLarry.item.ID] = "Chases enemies #Gains 1 segment for each floor you progress"
  22.  
  23. --creating a saved table for tracking the length of each larry Jr. even if you leave the game
  24. if IpecacCM.SaveData.LilLarryFamiliarData == nil then
  25.   IpecacCM.SaveData.LilLarryFamiliarData = {}
  26.  
  27. end
  28.  
  29. function LilLarry.RecoverFamilarLength (_,save) -- recalling the saved values of each larry's length
  30.  
  31.   if save then
  32.     for i,npc in pairs(Isaac.FindByType(3,LilLarry.head,-1,false,false)) do
  33.       if IpecacCM.SaveData.LilLarryFamiliarData[i] ~= nil then
  34.         npc:GetData().LilLarrySegmentCount = IpecacCM.SaveData.LilLarryFamiliarData[i]
  35.       else
  36.         npc:GetData().LilLarrySegmentCount = 1
  37.       end
  38.     end
  39.   else
  40.     IpecacCM.SaveData.LilLarryFamiliarData = {}
  41.   end
  42.  
  43. end
  44.  
  45. IpecacMod:AddCallback(ModCallbacks.MC_POST_GAME_STARTED,LilLarry.RecoverFamilarLength)
  46.  
  47.  
  48. function LilLarry.UpdateFamiliarCount (_) -- gives you a nex head for each instance of the item or of its effect you have
  49.  
  50.   local player = Isaac.GetPlayer(0)
  51.   if player:GetEffects():GetCollectibleEffectNum( LilLarry.item.ID) >= 1 then
  52.     player:CheckFamiliar(LilLarry.head,player:GetCollectibleNum(LilLarry.item.ID)+ player:GetEffects():GetCollectibleEffectNum( LilLarry.item.ID),player:GetCollectibleRNG(LilLarry.item.ID))
  53.   else
  54.     player:CheckFamiliar(LilLarry.head,player:GetCollectibleNum(LilLarry.item.ID),player:GetCollectibleRNG(LilLarry.item.ID))
  55.   end
  56.  
  57.  
  58. end
  59.  
  60. IpecacMod:AddCallback(ModCallbacks.MC_EVALUATE_CACHE,LilLarry.UpdateFamiliarCount)
  61. IpecacMod:AddCallback(ModCallbacks.MC_USE_ITEM,LilLarry.UpdateFamiliarCount,CollectibleType.COLLECTIBLE_BOX_OF_FRIENDS)
  62. IpecacMod:AddCallback(ModCallbacks.MC_POST_NEW_ROOM,LilLarry.UpdateFamiliarCount)
  63.  
  64. function LilLarry.Behaviour (_,npc) --determines how the head behaves
  65.  
  66.   local sprite = npc:GetSprite()
  67.   local angle = npc.Velocity:GetAngleDegrees()%360
  68.   npc.FlipX = false
  69.   if angle < 45 or ( angle >= 315 ) then -- gives a different sprite depending on the direction it's facing
  70.     sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_head_side.png")
  71.   elseif angle < 135 then
  72.     sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_head_front.png")
  73.   elseif angle < 225 then
  74.     sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_head_side.png")
  75.     npc.FlipX = true
  76.   else
  77.     sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_head_back.png")
  78.   end
  79.   sprite:LoadGraphics()
  80.  
  81.   local room = IpecacCM.Game:GetLevel():GetCurrentRoom()
  82.   local gridentity = room:GetGridEntityFromPos(npc.Position + (npc.Velocity):Normalized() * 30)
  83.   if gridentity ~= nil and  gridentity:GetType() == GridEntityType.GRID_POOP and math.random() <= 0.8 then --makes it destroy poop. Just like its parents!
  84.     gridentity:Destroy(false)
  85.    
  86.   end
  87.  
  88.   sprite:SetFrame("Idle",npc.FrameCount%12 + 1)
  89.  
  90.   npc.CollisionDamage = LilLarry.baseDamage
  91.   LilLarry.RecoverFamilarLength(_,true)
  92.   npc.CollisionDamage = math.min(LilLarry.baseDamage + LilLarry.baseDamageIncrement * npc:GetData().LilLarrySegmentCount,LilLarry.baseDamage + 5 * LilLarry.baseDamageIncrement)
  93.  
  94.  -- if npc:GetData().LilLarrySegmentCount > 1 then
  95.     local entity = npc
  96.     for i = 1,npc:GetData().LilLarrySegmentCount do -- creates a train of familiar parts connected to each other!
  97.       entity:GetData().LilLarryHead = npc
  98.       entity:GetData().LilLarrySegmentNumber = i
  99.       entity:GetData().LilLarryParentSegmentCount = npc:GetData().LilLarrySegmentCount
  100.       if Isaac.GetPlayer(0):HasCollectible(CollectibleType.COLLECTIBLE_BFFS) or Isaac.GetPlayer(0):GetEffects():HasCollectibleEffect(CollectibleType.COLLECTIBLE_BFFS) then
  101.        
  102.         entity.CollisionDamage = LilLarry.baseSize * 1.3
  103.         entity.CollisionDamage = math.min(LilLarry.baseDamage + LilLarry.baseDamageIncrement * npc:GetData().LilLarrySegmentCount,5 * LilLarry.baseDamageIncrement + LilLarry.baseDamage) * 2
  104.       else
  105.         entity.CollisionDamage = math.min(LilLarry.baseDamage + LilLarry.baseDamageIncrement * npc:GetData().LilLarrySegmentCount,5 * LilLarry.baseDamageIncrement + LilLarry.baseDamage)
  106.       end
  107.      
  108.       if entity:GetData().LilLarryChild ~= nil and entity:GetData().LilLarryChild:Exists() then
  109.         entity = entity:GetData().LilLarryChild  
  110.         entity:GetData().LilLarrySegmentNumber = i + 1
  111.       else
  112.         local child = Isaac.Spawn(EntityType.ENTITY_FAMILIAR,LilLarry.body,0,entity.Position,Vector(0,0),entity)
  113.         entity:GetData().LilLarryChild = child
  114.         entity:GetData().LilLarrySegmentNumber = i
  115.         child:GetData().LilLarryParent = entity
  116.        
  117.         if Isaac.GetPlayer(0):HasCollectible(CollectibleType.COLLECTIBLE_BFFS) or Isaac.GetPlayer(0):GetEffects():HasCollectibleEffect(CollectibleType.COLLECTIBLE_BFFS) then
  118.           child.CollisionDamage = LilLarry.baseSize * 1.3
  119.           child.CollisionDamage = math.min(LilLarry.baseDamage + LilLarry.baseDamageIncrement * npc:GetData().LilLarrySegmentCount,5 * LilLarry.baseDamageIncrement + LilLarry.baseDamage) * 2
  120.         else
  121.           child.CollisionDamage = math.min(LilLarry.baseDamage + LilLarry.baseDamageIncrement * npc:GetData().LilLarrySegmentCount,5 * LilLarry.baseDamageIncrement + LilLarry.baseDamage)
  122.         end
  123.        
  124.         entity = child
  125.         entity:GetData().LilLarryParentSegmentCount = npc:GetData().LilLarrySegmentCount
  126.         entity:GetData().LilLarrySegmentNumber = i + 1
  127.       end    
  128.      
  129.     end
  130.    
  131.  -- end
  132.  
  133.   if Isaac.GetPlayer(0):HasCollectible(CollectibleType.COLLECTIBLE_BFFS) or Isaac.GetPlayer(0):GetEffects():HasCollectibleEffect(CollectibleType.COLLECTIBLE_BFFS) then
  134.    
  135.     npc.Size = LilLarry.baseSize * 1.3
  136.    
  137.   end
  138.  
  139.  
  140.   if npc:GetData().LilLarryHeadGuide == nil or not (npc:GetData().LilLarryHeadGuide:Exists()) then -- creates an entity to guide the head. Piber advised me against it, but it is way simpler than creating our own pathfinder. If someone else does for me, I can remove this. Oherwise, don't expect me to do so
  141.     npc:GetData().LilLarryHeadGuide = Isaac.Spawn(LilLarry.guideType,LilLarry.guideVariant, 0, npc.Position,Vector(0,0),npc)
  142.     npc:GetData().LilLarryHeadGuide.GridCollisionClass = GridCollisionClass.COLLISION_OBJECT
  143.     npc:GetData().LilLarryHeadGuide.EntityCollisionClass = EntityCollisionClass.ENTCOLL_NONE
  144.     npc:GetData().LilLarryHeadGuide:GetData().LilLarrysHead = npc
  145.     npc:GetData().LilLarryHeadGuide:AddEntityFlags(EntityFlag.FLAG_FRIENDLY,EntityFlag.FLAG_CHARM)
  146.   else
  147.     npc.Position = npc:GetData().LilLarryHeadGuide.Position
  148.     npc.Velocity = npc:GetData().LilLarryHeadGuide.Velocity
  149.   end
  150.  
  151.  
  152.    
  153.   if npc.Target == nil or not npc.Target:Exists() then -- if the familiar doesn't yet have a target, it should seek one
  154.    
  155.     local selectedentity = nil
  156.     local distance = LilLarry.maxTargetDistanceForTracking
  157.     for m,n in pairs(Isaac.GetRoomEntities()) do
  158.      currentdistance = ( n.Position - npc.Position ):Length()
  159.       if currentdistance < distance and n:IsActiveEnemy() and n:IsVulnerableEnemy() and n:HasEntityFlags(EntityFlag.FLAG_FRIENDLY) == false and LilLarry.guideType ~= n.Type and currentdistance > LilLarry.minTargetDistanceForTracking then
  160.         distance = currentdistance
  161.         selectedentity = n
  162.       end
  163.     end
  164.    
  165.     if selectedentity ~= nil then
  166.       npc.Target = selectedentity
  167.     end
  168.    
  169.    
  170.   else
  171.    
  172.     if npc.Target ~= nil and ((npc.Target.Position - npc.Position):Length() > LilLarry.maxTargetDistance or (npc.Target.Position - npc.Position):Length() < LilLarry.minTargetDistance ) then
  173.       npc.Target = nil
  174.      
  175.     end
  176.    
  177.   end
  178.  
  179. end
  180.  
  181. IpecacMod:AddCallback(ModCallbacks.MC_FAMILIAR_UPDATE,LilLarry.Behaviour,LilLarry.head)
  182.  
  183. --[[function LilLarry.OnBoxOfFriends(_)
  184.   local player = Isaac.GetPlayer(0)
  185.   if player:HasCollectible(LilLarry.item.ID) then
  186.     player:GetEffects():AddCollectibleEffect(LilLarry.item.ID)
  187.     LilLarry.UpdateFamiliarCount()
  188.     player:GetEffects():RemoveCollectibleEffect(CollectibleType.COLLECTIBLE_DEMON_BABY)
  189.   end
  190. end
  191.  
  192. IpecacMod:AddCallback(ModCallbacks.MC_USE_ITEM,LilLarry.OnBoxOfFriends,CollectibleType.COLLECTIBLE_BOX_OF_FRIENDS)]]
  193.  
  194. function LilLarry.GuideLilLarrysHead(_,npc)
  195.  
  196.  
  197.   if npc.Variant == LilLarry.guideVariant and npc:GetData().LilLarrysHead and npc:GetData().LilLarrysHead:Exists() then
  198.     npc.GridCollisionClass = GridCollisionClass.COLLISION_OBJECT
  199.    
  200.     if npc:GetData().LilLarrysHead.Target ~= nil then
  201.       if not npc.Pathfinder:HasPathToPos(npc:GetData().LilLarrysHead.Target.Position,true) then
  202.         npc:GetData().LilLarrysHead.Target = nil
  203.       end
  204.     end
  205.     if npc:GetData().LilLarrysHead.Target ~= nil then
  206.       if (npc.Position - npc:GetData().LilLarrysHead.Target.Position):Length() > 30 then
  207.         npc.Pathfinder:FindGridPath(npc:GetData().LilLarrysHead.Target.Position,1,0,true)
  208.       elseif npc.Pathfinder:HasPathToPos(npc:GetData().LilLarrysHead.Target.Position,true) then
  209.        
  210.         npc.Velocity = (npc:GetData().LilLarrysHead.Target.Position - npc.Position):Normalized() * math.min(LilLarry.HeadSpeed,(npc.Position - npc:GetData().LilLarrysHead.Target.Position):Length())
  211.        
  212.       end
  213.     else
  214.       if npc:GetData().LilLarryGuideTemporaryTarget ~= nil and (npc:GetData().LilLarryGuideTemporaryTarget - npc.Position):Length() > 70 and npc.Pathfinder:HasPathToPos(npc:GetData().LilLarryGuideTemporaryTarget,true) then
  215.         npc.Pathfinder:FindGridPath(npc:GetData().LilLarryGuideTemporaryTarget,1,0,true)
  216.       else
  217.         npc:GetData().LilLarryGuideTemporaryTarget = IpecacCM.Game:GetLevel():GetCurrentRoom():GetClampedPosition(Isaac.GetRandomPosition(),5)
  218.    
  219.       end
  220.     end
  221.   elseif npc.Variant == LilLarry.guideVariant then
  222.     npc:Remove()
  223.   end
  224.  
  225. end
  226.  
  227.  
  228. IpecacMod:AddCallback(ModCallbacks.MC_NPC_UPDATE,LilLarry.GuideLilLarrysHead,LilLarry.guideType)
  229.  
  230. function IpecacMod:IncreaseLilLarrysSize (_)
  231.  
  232.   for i,npc in pairs(Isaac.FindByType(3,LilLarry.head,-1,false,false)) do
  233.    
  234.     if npc:GetData().LilLarrySegmentCount == nil then
  235.       if IpecacCM.SaveData.LilLarryFamiliarData[i] ~= nil then
  236.         npc:GetData().LilLarrySegmentCount = IpecacCM.SaveData.LilLarryFamiliarData[i] + 1
  237.       else
  238.         npc:GetData().LilLarrySegmentCount = 1
  239.       end
  240.     else
  241.       npc:GetData().LilLarrySegmentCount = npc:GetData().LilLarrySegmentCount +1
  242.     end
  243.     local level = IpecacCM.Game:GetLevel()
  244.     if level:GetCurses() & LevelCurse.CURSE_OF_LABYRINTH == LevelCurse.CURSE_OF_LABYRINTH then
  245.       npc:GetData().LilLarrySegmentCount = npc:GetData().LilLarrySegmentCount + 1
  246.     end
  247.     IpecacCM.SaveData.LilLarryFamiliarData[i] = npc:GetData().LilLarrySegmentCount
  248.   end
  249. end
  250.  
  251. IpecacMod:AddCallback(ModCallbacks.MC_POST_NEW_LEVEL,IpecacMod.IncreaseLilLarrysSize)
  252.  
  253. function LilLarry.BodyFollowsParent (_,npc)
  254.   npc.GridCollisionClass = GridCollisionClass.COLLISION_OBJECT
  255.   local sprite = npc:GetSprite()
  256.   sprite:SetFrame("Idle",npc.FrameCount%12 + 1)
  257.   local angle = npc.Velocity:GetAngleDegrees()%360
  258.   npc.FlipX = false
  259.   if npc.Velocity:Length() > 0.5 then
  260.     if angle < 45 or ( angle >= 315 ) then
  261.       sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_body_side.png")
  262.     elseif angle < 135 then
  263.       sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_body_front.png")
  264.     elseif angle < 225 then
  265.       sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_body_side.png")
  266.       npc.FlipX = true
  267.     else
  268.       if npc:GetData().LilLarryChild and npc:GetData().LilLarryChild:Exists() then
  269.         sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_body_front.png")
  270.       else
  271.         sprite:ReplaceSpritesheet(0,"gfx/familiar/familiar_lil_larry_body_back.png")
  272.       end
  273.     end
  274.   end
  275.   sprite:LoadGraphics()
  276.  
  277.  
  278.   if npc:GetData().LilLarryParent and npc:GetData().LilLarryParent:Exists() then
  279.     local parent = npc:GetData().LilLarryParent
  280.     npc:GetData().LilLarryParentSegmentCount = parent:GetData().LilLarryParentSegmentCount
  281.     if  type(npc:GetData().LilLarryParentSegmentCount) ~= "number" or npc:GetData().LilLarryParentSegmentCount + 1 < npc:GetData().LilLarrySegmentNumber then
  282.       npc:Remove()
  283.     end
  284.     if (parent.Position - npc.Position ):Length() > LilLarry.maxSegmentDistance then
  285.       npc.Velocity = (parent.Position - npc.Position):Normalized() * LilLarry.segmentFollowingSpeed
  286.     elseif npc.Velocity:Length() > LilLarry.segmentFollowingSpeed / 6 then
  287.       npc.Velocity = npc.Velocity - (npc.Velocity):Normalized() * LilLarry.segmentFollowingSpeed /6
  288.     else
  289.       npc.Velocity = npc.Velocity * 0.9
  290.     end
  291.    
  292.   else
  293.     npc:Remove()
  294.   end
  295.  
  296. end
  297. IpecacMod:AddCallback(ModCallbacks.MC_FAMILIAR_UPDATE,LilLarry.BodyFollowsParent,LilLarry.body)
  298. -- Idea: Make a function for Lil larry pooping when it kills an enemy
  299.  
  300.  
  301.  
  302.  
  303. function IpecacMod:LilLarryLock ( collectible, pool, decrease, seed) -- can't find the item if you haven't unlocked it
  304.   if collectible == LilLarry.item.ID and (not ( IpecacCM.SaveData.Unlocks ~= nil and IpecacCM.SaveData.Unlocks.LilLarry ~= nil and IpecacCM.SaveData.Unlocks.LilLarry.unlocked  )) then
  305.     local returnid = IpecacCM.Game:GetItemPool():GetCollectible(pool,true,seed)
  306.     if returnid ~= LilLarry.item.ID then
  307.       return returnid
  308.     else
  309.       return IpecacCM.Game:GetItemPool():GetCollectible(pool,true,seed)
  310.     end
  311.   end
  312. end
  313.  
  314. IpecacMod:AddCallback(ModCallbacks.MC_POST_GET_COLLECTIBLE,IpecacMod.LilLarryLock)
Advertisement
Add Comment
Please, Sign In to add comment