Hi alexs. If you read this, I have some infos for you.
I think that make executable version is necessary and should help with gaining popularity.
There are some issues related to AI. First, if PC gone from monster's FOV, enemy don't move towards to player. Will be good to implement sort of 'memory' for monsters. Opponents should search to player in a place where he disappeared.
Moreover - 'ranged ai'. When player move closer to ranged unit, monster step back and shoot every time, like in loop
Unfortunely, when 'shooter' has wall behind him, he still try to move back, and he bump into wall, what take a turn in your game. It's illogical, enemy - in this position - should move to other way or shoot all the time.
Next - constrols. I can move diagonally with vi-keys or with end/home/pgup/pgdn. I looked at your code. I don't know what was your intention, but seems (I think that because 'wait' is assigned to KP5 key) like you wanted to make two things in one piece of code. Make not-vi-controls possible with arrow-keys + home/etcetera keys AND make numpad controls with simpliest code. It doesn't work for me. In libtcod you cannot use 'HOME', 'END' 'UPARROW' etc. both for numeric keypad and 'standard 'keys.
Then instead
elif key_char == 'h':
player_move_or_attack(-1, 0)
elif key_char == 'k':
player_move_or_attack(0, -1)
(...)
elif key.vk == libtcod.KEY_RIGHT:# or libtcod.KEY_L:
player_move_or_attack(1, 0)
elif key.vk == libtcod.KEY_HOME:# or libtcod.KEY_Y:
player_move_or_attack(-1, -1)
you should use something like that:
elif key.vk == libtcod.KEY_RIGHT or key.vk == libtcod.KEY_KP6 or key_char == 'l':
player_move_or_attack(1, 0)
elif key.vk == libtcod.KEY_HOME or key.vk == libtcod.KEY_KP7 or key_char == 'y':
player_move_or_attack(-1, -1)