cniumunto Posted October 13, 2024 Share Posted October 13, 2024 In encounters.lua, line 217~227: local function HalfAdaptiveWaveCount(difficulty, spawner) -- Get a wave, cut it in half and ceil() it. -- Difficulty of this wave is easy earlier in dungeon. return math.ceil(spawner:GetCurrentAdaptiveWaveSize(difficulty)/2) end local function HalfAdaptiveWaveCountEasy(difficulty, spawner) -- Get a wave, cut it in half and floor() it. -- Distributes difficulty such that the early stages of the dungeon are easier. return math.ceil(spawner:GetCurrentAdaptiveWaveSize(difficulty)/2) end Code comment in function HalfAdaptiveWaveCountEasy() says it will floor() the wave, but it actually ceil() the wave. In sg_player_cannon.lua, line 338: local NO_AMMO_DODGEVELOCITY_MULT = 1 And line 523: local ammomult = inst.sg.statemem.blastshotammo and inst.sg.statemem.blastshotammo < 1 and NO_AMMO_DODGEVELOCITY_MULT or 1 -- Dodging with no ammo moves only 50% as far Code comment in function ConfigureNewDodge() says "Dodging with no ammo moves only 50% as far", but the multiplier is 1, not 0.5. And in game, no ammo dodging is actually a fixed distance shorter than normal dodging (see videos below), not 50% of the distance. 1.mp4 2.mp4 3.mp4 Link to comment https://forums.kleientertainment.com/forums/topic/160193-there-are-something-like-bugs-in-the-code/ Share on other sites More sharing options...
cniumunto Posted October 13, 2024 Author Share Posted October 13, 2024 5 hours ago, cniumunto said: In sg_player_cannon.lua, line 338: local NO_AMMO_DODGEVELOCITY_MULT = 1 And line 523: local ammomult = inst.sg.statemem.blastshotammo and inst.sg.statemem.blastshotammo < 1 and NO_AMMO_DODGEVELOCITY_MULT or 1 -- Dodging with no ammo moves only 50% as far Code comment in function ConfigureNewDodge() says "Dodging with no ammo moves only 50% as far", but the multiplier is 1, not 0.5. Note: The line numbers of these two lines of code are based on the beta branch. In the live branch, the line numbers are 322 and 507. Link to comment https://forums.kleientertainment.com/forums/topic/160193-there-are-something-like-bugs-in-the-code/#findComment-1753015 Share on other sites More sharing options...
cniumunto Posted October 15, 2024 Author Share Posted October 15, 2024 On 10/14/2024 at 12:12 AM, cniumunto said: And in game, no ammo dodging is actually a fixed distance shorter than normal dodging (see videos below), not 50% of the distance. Add: This fixed distance may be affected by function DoBlastKickback(). In sg_player_cannon.lua, line 581~583 (line 598~600 in the beta): local function DoBlastKickback(inst) inst.Physics:MoveRelFacing(-125 / 150) end 6*125/150=5, That's exactly the distance (number of grids) between the two lamps in the video. And line 1540~1545 (line 1625~1630 in the beta): FrameEvent(1, function(inst) if inst.sg.statemem.blastshotammo > 0 then DoBlastKickback(inst) -- Start with a strong burst end StartNewDodge(inst) end), Another thing like a bug (only in beta): In sg_player_cannon_skill_aim.lua, line 309: return StateGraph("sg_player_cannon_skill_butt", states, events, "skill_cannon_butt") Is it return to the StateGraph of another skill? Link to comment https://forums.kleientertainment.com/forums/topic/160193-there-are-something-like-bugs-in-the-code/#findComment-1753162 Share on other sites More sharing options...
cniumunto Posted October 22, 2024 Author Share Posted October 22, 2024 On 10/14/2024 at 12:12 AM, cniumunto said: In encounters.lua, line 217~227: local function HalfAdaptiveWaveCount(difficulty, spawner) -- Get a wave, cut it in half and ceil() it. -- Difficulty of this wave is easy earlier in dungeon. return math.ceil(spawner:GetCurrentAdaptiveWaveSize(difficulty)/2) end local function HalfAdaptiveWaveCountEasy(difficulty, spawner) -- Get a wave, cut it in half and floor() it. -- Distributes difficulty such that the early stages of the dungeon are easier. return math.ceil(spawner:GetCurrentAdaptiveWaveSize(difficulty)/2) end Code comment in function HalfAdaptiveWaveCountEasy() says it will floor() the wave, but it actually ceil() the wave. Add: The function HalfAdaptiveWaveCountEasy() is only used in encounter e02 and e03 in Great Rotwood Forest. In encounters.lua, line 649~683 (line 670~704 in the beta): e02 = { -- One melee, then an ambush! factor = 4, exec_fn = function(spawner) spawner:SpawnPropDestructibles(4) spawner:SpawnWave({ melee1 = 1 }) spawner:WaitForDefeatedPercentage(.66) spawner:WaitForSeconds(0.75) spawner:SpawnWave({ ranged1 = HalfAdaptiveWaveCountEasy(Difficulty.id.easy, spawner) }) spawner:SpawnWave({ ranged1 = HalfAdaptiveWaveCountEasy(Difficulty.id.easy, spawner) }) if IsAfterMiniboss(spawner) then -- If we're past miniboss, add some extra ambushers spawner:SpawnWave({ melee1 = HalfAdaptiveWaveCountEasy(Difficulty.id.easy, spawner) }) spawner:WaitForDefeatedPercentage(0.33) spawner:WaitForSeconds(0.75) spawner:SpawnWave({ melee2 = SpawnSometimes(1, spawner) }) end end, }, e03 = { -- Just melees, an onslought! factor = 4, exec_fn = function(spawner) spawner:SpawnPropDestructibles(4) SpawnRandomTraps(spawner) -- Spawn some traps to make it fun to kill these groups of cabbages spawner:SpawnWave({ melee1 = 2 }) spawner:WaitForDefeatedPercentage(0.5) spawner:WaitForSeconds(0.75) spawner:SpawnWave({ melee1 = 2 }) spawner:WaitForDefeatedPercentage(0.5) spawner:WaitForSeconds(0.75) spawner:SpawnWave({ melee1 = HalfAdaptiveWaveCount(Difficulty.id.easy, spawner) }) spawner:SpawnWave({ support1 = SpawnAfterMiniboss(1, spawner)}) spawner:WaitForSeconds(0.75) spawner:SpawnWave({ melee1 = HalfAdaptiveWaveCountEasy(Difficulty.id.easy, spawner) }) end, }, In these two encounters, the values passed to the argument "difficulty" are all "difficult.id.easy", and the only possible values for "adaptive_counts" (= adaptive wave size) on the easy difficulty are 4 (when progress<=0.5) or 5 (when progress>0.5), both of which are rounded down to 2 after divided by 2. Because of this, if the function HalfAdaptiveWaveCountEasy() floor() the wave instead of ceil() the wave, the expectation that "the early stages of the dungeon are easier" will not be achieved. Link to comment https://forums.kleientertainment.com/forums/topic/160193-there-are-something-like-bugs-in-the-code/#findComment-1753887 Share on other sites More sharing options...
cniumunto Posted October 24, 2024 Author Share Posted October 24, 2024 Encounter e04 and m03 in The Molded Grave are almost the same. Is this a bug or intentional? Encounter e04 in The Molded Grave, in encounters.lua, line 1255~1264 (line 1276~1285 in the beta): e04 = { --swarmy worms factor = 5, exec_fn = function(spawner) SpawnRandomTraps(spawner) spawner:SpawnPropDestructibles(4) spawner:SpawnWave(waves.Raw{ woworm = 2, swarmy = 2 }) spawner:WaitForDefeatedPercentage(0.8) spawner:SpawnWave(waves.Raw{ woworm = 1, swarmy = 3 }) end, }, And encounter m03 in The Molded Grave, in encounters.lua, line 1288~1297 (line 1309~1318 in the beta): m03 = { --Woworms factor = 2, exec_fn = function(spawner) SpawnRandomTraps(spawner) spawner:SpawnPropDestructibles(3) spawner:SpawnWave(waves.Raw{ woworm = 2, swarmy = 2 }) spawner:WaitForDefeatedPercentage(0.8) spawner:SpawnWave(waves.Raw{ swarmy = 3, woworm = 1 }) end, }, Link to comment https://forums.kleientertainment.com/forums/topic/160193-there-are-something-like-bugs-in-the-code/#findComment-1754215 Share on other sites More sharing options...
cniumunto Posted October 30, 2024 Author Share Posted October 30, 2024 Normal miniboss encounter in Nocturne Grove, compared to its previous version and hard version, has this line of code missing: spawner:WaitForMinibossHealthPercent(0.6) Is this a bug or intentional? For reference: Normal miniboss encounter in Nocturne Grove, in encounters.lua, line 1944~1958: Spoiler e01 = { constraint_fn = function(spawner) return not ResolveHuntModifiers().HardMiniboss end, exec_fn = function(spawner) SpawnTrapWave(spawner, waves.Raw{ trap_weed_spikes = 3 }) spawner:SpawnPropDestructibles(5) spawner:SpawnMiniboss(waves.Raw{ gourdo_miniboss = 2 }) if (TheNet:GetNrPlayersOnRoomChange() > 2) then spawner:SpawnWave(waves.Raw{ battoad = 1 }, 0, 0, nil, true) end spawner:WaitForMinibossHealthPercent(0) spawner:CleanUpRemainingEnemies() end, }, Previous version of normal miniboss encounter in Nocturne Grove (before the Splintershard Cavern Update): Spoiler e01 = { exec_fn = function(spawner) SpawnTrapWave(spawner, waves.Raw{ trap_weed_spikes = 3 }) spawner:SpawnPropDestructibles(5) spawner:SpawnMiniboss(waves.Raw{ gourdo_miniboss = 2 }) spawner:WaitForMinibossHealthPercent(0.6) if (TheNet:GetNrPlayersOnRoomChange() > 2) then spawner:SpawnWave(waves.Raw{ battoad = 1 }, 0, 0, nil, true) end spawner:WaitForMinibossHealthPercent(0) spawner:CleanUpRemainingEnemies() end, }, Hard miniboss encounter in Nocturne Grove, in encounters.lua, line 1959~1976: Spoiler e02 = { -- Encounter for hard miniboss constraint_fn = function(spawner) return ResolveHuntModifiers().HardMiniboss end, exec_fn = function(spawner) SpawnTrapWave(spawner, waves.Raw{ trap_weed_spikes = 3 }) spawner:SpawnPropDestructibles(5) spawner:SpawnMiniboss(waves.Raw{ gourdo_miniboss = 2 }) spawner:WaitForSeconds(4.9) spawner:SpawnWave(waves.Raw{ yammo_miniboss = 1}) spawner:WaitForMinibossHealthPercent(0.6) if (TheNet:GetNrPlayersOnRoomChange() > 2) then spawner:SpawnWave(waves.Raw{ battoad = 1 }, 0, 0, nil, true) end spawner:WaitForMinibossHealthPercent(0) spawner:CleanUpRemainingEnemies() end, }, Link to comment https://forums.kleientertainment.com/forums/topic/160193-there-are-something-like-bugs-in-the-code/#findComment-1755383 Share on other sites More sharing options...
cniumunto Posted November 14, 2024 Author Share Posted November 14, 2024 There is no "airborne" tag at any time in the "cannon_quickrise" and "cannon_quickrise_noammo" states. However, in the animation of these two states, the player character looks airborne for a period of time. The visual perception is not consistent with the actual condition. Is this a bug or intentional? In sg_player_cannon.lua, line 4141~4331(REV. 639146): Spoiler State({ name = "cannon_quickrise", tags = { "busy", "heavy_attack", "attack", "dodge", "dodging_backwards" }, onenter = function(inst, real_quickrise) inst.AnimState:PlayAnimation("cannon_getup_dodge") SGPlayerCommon.Fns.UnsetCanDodge(inst) SGPlayerCommon.Fns.SetRollPhysicsSize(inst) inst.HitBox:SetInvincible(true) SGCommon.Fns.StartJumpingOverHoles(inst) if real_quickrise then -- We can get here through the normal cannon Heavy combo, so only push the event + present effects when this is a true quickrise. inst:PushEvent("quick_rise") SGPlayerCommon.Fns.DoCannonQuickRise(inst) end inst:PushEvent("dodge") inst:PushEvent("attack_state_start") inst.sg.mem.attack_id = "QUICK_RISE" inst.sg.mem.attack_type = "heavy_attack" -- TODO: commonize this local hitstop = TUNING.HITSTOP_PLAYER_QUICK_RISE_FRAMES inst.components.hitstopper:PushHitStop(hitstop) inst:DoTaskInAnimFrames(hitstop, function() if inst ~= nil and inst:IsValid() then if GetRemainingAmmo(inst) > 0 then inst.Physics:StartPassingThroughObjects() combatutil.StartMeleeAttack(inst) inst.components.hitbox:PushCircle(0, 0, ATTACKS.QUICKRISE.RADIUS, HitPriority.MOB_DEFAULT) local focus = inst.sg.mem.focus_sequence[GetRemainingAmmo(inst)] -- fx, lots that would usually be done in embellisher but since focusness matters we'll do it here: EffectEvents.MakeEventSpawnEffect(inst, { fxname= focus and "cannon_aoe_explosion_med_focus" or "cannon_aoe_explosion_med", offx=0.2, offy=0.45, offz=-0.1, scalex=1.0, scalez=1.0, }) EffectEvents.MakeEventSpawnEffect(inst, { fxname=focus and "fx_cannon_smoke_aoe_focus" or "fx_cannon_smoke_aoe", offx=0.0, offy=0.0, offz=-0.1, scalex=1.2, scalez=1.2, }) ParticleSystemHelper.MakeEventSpawnParticles(inst, { duration=90.0, particlefxname= focus and "cannon_burst_aoe_sphere_sml_focus" or "cannon_burst_aoe_sphere_sml", }) ParticleSystemHelper.MakeEventSpawnParticles(inst, { duration=90.0, offx=1.2, offy=0.0, offz=0.0, particlefxname= focus and "cannon_shot_quickrise_focus" or "cannon_shot_quickrise", render_in_front=true, use_entity_facing=true, }) --sound local isFocusAttack = inst.sg.mem.focus_sequence[inst.sg.mem.ammo] soundutil.PlayCodeSound(inst, fmodtable.Event.Cannon_shoot_quickrise, { max_count = 1, fmodparams = { isFocusAttack = isFocusAttack, cannon_heavyShotType = 2, cannon_remainingAmmo_scaled = GetRemainingAmmo(inst) / GetMaxAmmo(inst), cannon_ammo_percentDelta = inst.sg.statemem.percent_ammo_changed_param, } }) local snapshot_ammo = inst.sg.mem.ammo UpdateAmmo(inst, 1) if inst.sg.mem.ammo and snapshot_ammo and (inst.sg.mem.ammo <= snapshot_ammo) then inst:DoTaskInAnimFrames(2, function(inst) PlayLowAmmoSound(inst, inst.sg.mem.ammo) end) end ConfigureNewDodge(inst) StartNewDodge(inst) end end end) end, onupdate = function(inst) DoDodgeMovement(inst, true) end, timeline = { FrameEvent(1, function(inst) combatutil.EndMeleeAttack(inst) end), FrameEvent(3, function(inst) DoQuickRiseKickback(inst) end), --CANCELS FrameEvent(8, function(inst) inst.sg.statemem.airplant = true if inst.sg.statemem.triedplantearly then local transitiondata = { maxspeed = inst.sg.statemem.maxspeed, speed = inst.sg.statemem.speed, framessliding = inst.sg.statemem.framessliding } inst.sg:GoToState("blast_TO_plant", transitiondata) end end), FrameEvent(11, function(inst) inst.sg.statemem.airplant = false inst.sg.statemem.groundplant = true SGCommon.Fns.SafeStopPassingThroughObjects(inst) end), FrameEvent(15, SGPlayerCommon.Fns.RemoveBusyState), }, onexit = function(inst) inst.HitBox:SetInvincible(false) SGPlayerCommon.Fns.UndoRollPhysicsSize(inst) SGCommon.Fns.SafeStopPassingThroughObjects(inst) inst.Physics:Stop() SGCommon.Fns.StopJumpingOverHoles(inst) end, events = { EventHandler("animover", function(inst) inst.sg:GoToState("idle") end), EventHandler("controlevent", function(inst, data) if data.control == "dodge" then local transitiondata = { maxspeed = inst.sg.statemem.maxspeed, speed = inst.sg.statemem.speed, framessliding = inst.sg.statemem.framessliding } if inst.sg.statemem.airplant then inst.sg:GoToState("blast_TO_plant", transitiondata) elseif inst.sg.statemem.groundplant then inst.sg:GoToState("cannon_plant_pre", transitiondata) else inst.sg.statemem.triedplantearly = true end end end), EventHandler("hitboxtriggered", OnQuickriseHitBoxTriggered), }, }), State({ name = "cannon_quickrise_noammo", tags = { "busy", "heavy_attack", "attack" }, onenter = function(inst, real_quickrise) inst.AnimState:PlayAnimation("cannon_getup_dodge") if real_quickrise then -- We can get here through the normal cannon Heavy combo, so only push the event + present effects when this is a true quickrise. inst:PushEvent("quick_rise") SGPlayerCommon.Fns.DoCannonQuickRise(inst) end end, onupdate = function(inst) end, timeline = { FrameEvent(1, function(inst) PlayNoAmmoSound(inst) end), }, onexit = function(inst) end, events = { EventHandler("animover", function(inst) inst.sg:GoToState("idle") end), }, }), And, although the code comment in the state "cannon_quickrise_noammo" says "We can get here through the normal cannon Heavy combo", it doesn't seem to actually be possible to get to this state through the normal cannon Heavy combo. Link to comment https://forums.kleientertainment.com/forums/topic/160193-there-are-something-like-bugs-in-the-code/#findComment-1757076 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.
Please be aware that the content of this thread may be outdated and no longer applicable.