When I hear about C programs that were a disaster because they used OO-like techniques, the operative word is usually "disaster" and not "C" or "OO". In other words, there were other things wrong with the project that had nothing to do with the selection of language or programming paradigm, like hiring inexperienced programmers or mandating a single programming paradigm for the whole codebase.
Good C code will have a lot fewer objects than say, Java, because most of the things you want to use C for, you can accomplish just fine with structs and functions. But you shouldn't shy away from a struct full of function pointers or an ADT with opaque pointer types and appropriately-namespaced member functions just because you're afraid a maintenance programmer won't get it. It's their responsibility to learn the language.
For similar reasons, "cute" macro-heavy C code tends not to survive long-term, because it breaks too much tooling.
As ever, we have to apply common sense: as I mentioned in the article, 1-level inheritance is quite good, or maximum 2, but if we have more, it gets too verbose. Luckily, for most cases, 1-level is quite enough to create common API and reusable modules.
Maybe you overuse it? Of course if you try to build huge hierarchies like this, you most likely will end up using typecasts in client code, and the entire thing will quickly become a mess. The article proposes solutions that don't have typecasts in client code.
As I said before, we should apply common sense. Engineering is all about tradeoffs. If I were you, I wouldn't argue against any approach as aggressively as you just did.
The Linux kernel has some OO techniques in C. 2-part story:
https://lwn.net/Articles/444910/
https://lwn.net/Articles/446317/
I don't follow the Linux development mailing lists so I don't know if Linus Torvalds and other respected contributors regard those techniques as "disasters". Maybe they do.
Though, if your project is more of a toolkit, then a strictly procedural style is probably better.
Ended up doing a similar approach when forced to use C instead of C++ for a data structures university project.
Goal achieved, but not an experience to repeat ever again.
I have experience of an early nineties project that was entirely structured like this and trust me, it ends up as a disaster.
C is not meant to be OO, consequently all the tooling in editors and the like do not understand the links between classes and methods.
What it ends up like is an impenetrable mess with all the mechanics of C++ exposed but being impossible to navigate.
again... please do not do this in any project... for the sake of any who will follow you in maintaining your code!