/atom/proc/shake_animation(var/intensity = 8) //Makes the object visibly shake var/initial_transform = new/matrix(transform) var/init_px = pixel_x var/shake_dir = pick(-1, 1) var/rotation = 2+soft_cap(intensity, 1, 1, 0.94) var/offset = 1+soft_cap(intensity*0.3, 1, 1, 0.8) var/time = 2+soft_cap(intensity*0.3, 2, 1, 0.92) animate(src, transform=turn(transform, rotation*shake_dir), pixel_x=init_px + offset*shake_dir, time=1) animate(transform=initial_transform, pixel_x=init_px, time=time, easing=ELASTIC_EASING) /* This proc makes the input taper off above cap. But there's no absolute cutoff. Chunks of the input value above cap, are reduced more and more with each successive one and added to the output A higher input value always makes a higher output value. but the rate of growth slows */ /proc/soft_cap(var/input, var/cap = 0, var/groupsize = 1, var/groupmult = 0.9) //The cap is a ringfenced amount. If we're below that, just return the input if (input <= cap) return input var/output = 0 var/buffer = 0 var/power = 1//We increment this after each group, then apply it to the groupmult as a power //Ok its above, so the cap is a safe amount, we move that to the output input -= cap output += cap //Now we start moving groups from input to buffer while (input > 0) buffer = min(input, groupsize) //We take the groupsize, or all the input has left if its less input -= buffer buffer *= groupmult**power //This reduces the group by the groupmult to the power of which index we're on. //This ensures that each successive group is reduced more than the previous one output += buffer power++ //Transfer to output, increment power, repeat until the input pile is all used return output