I'm an inexperienced programmer creating a "roguelike-like" game in the vein of FTL, using Python (no PyGame as of yet as I'm still only concerned with text).
My game will contain a large number of weapons (around 50 for starters) that yield unique abilities. I am struggling to understand how to structure the object code in a way that is both powerful (in terms of allowing weapons to have radically different effects) and extensible (so that I can easily add more weapons later by eg. dropping them into a folder).
My first instinct was to have a BasicWeapon class, and have different weapons inherit from that class. However, this seems problematic to me: either I have to make the BasicWeapon class so barebones that it's basically useless (the only features all weapons have in common are name and type (pistol, axe, etc)), or I have to predict every unique effect I will ever come up with and code that into BasicWeapon.
The latter is clearly impossible, but the former can still be worked. However, that leaves me with the question: where do I put the code for individual weapons?
Do I create plasmarifle.py, rocketlauncher.py, swarmofbees.py, etc etc, and drop them all into a folder from where the game can import them?
Or is there a way to have a database-style file (maybe something as simple as an Excel spreadsheet) that somehow contains unique code for each weapon - without needing to resort to eval/exec?
In terms of the latter solution (database), I think the fundamental issue that I'm struggling with is that while I understand that it is desirable to maintain separation between code and data, I feel like the weapons blur the line between "code" and "data" a little bit; they represent the great variety of similar things that can be found in the game, in which sense they are like data, but most of them will require at least some unique code not shared with any other item, in which sense they are, naturally, code.
A partial solution I have found elsewhere on this site suggests giving the BasicWeapon class a bunch of empty methods - on_round_start(), on_attack(), on_move() etc - and then overriding those methods for each weapon. At the relevant phase of the combat cycle, the game will call the appropriate method for every character's weapon, and only the ones that have methods defined will actually do something. This helps, but it still does not tell me where I must put the code and/or data for each weapon.
Is there a different language or tool out there that I can use as a sort of half-data, half-code chimera? Am I completely butchering good programming practice?
My understanding of OOP is sketchy at best, so I would appreciate responses that are not too computer science-y.
EDIT: Vaughan Hilts has made it clear in his post below that what I'm essentially talking about is data-driven programming. The essence of my question is this: how can I implement a data-driven design in such a way that the data can contain scripts, enabling new weapons to do new things without changing the main program code?