Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
trosnoth
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
3
Issues
3
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Games
trosnoth
Commits
e86ec3e6be3f
Commit
8b183d5f
authored
Jan 24, 2018
by
talljosh
Browse files
Options
Browse Files
Download
Plain Diff
Merging to include unstable, in preparation for releasing version 1.12.0.
parents
a4e9042b8245
f02a41c1600a
Changes
115
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
115 changed files
with
4203 additions
and
1522 deletions
+4203
-1522
.idea/codeStyleSettings.xml
.idea/codeStyleSettings.xml
+7
-0
changes.txt
changes.txt
+28
-0
encode-trosnoth-replay.py
encode-trosnoth-replay.py
+11
-19
get-player-scores.py
get-player-scores.py
+58
-0
inkscape/trosnoth_export.py
inkscape/trosnoth_export.py
+4
-3
inkscape/trosnoth_import.py
inkscape/trosnoth_import.py
+3
-2
setup.py
setup.py
+1
-1
trosnoth/bots/base.py
trosnoth/bots/base.py
+19
-9
trosnoth/bots/orders.py
trosnoth/bots/orders.py
+4
-1
trosnoth/bots/ranger.py
trosnoth/bots/ranger.py
+31
-9
trosnoth/bots/sirrobin.py
trosnoth/bots/sirrobin.py
+147
-0
trosnoth/bots/terminator.py
trosnoth/bots/terminator.py
+34
-0
trosnoth/const.py
trosnoth/const.py
+11
-0
trosnoth/data/config/colours.cfg
trosnoth/data/config/colours.cfg
+5
-0
trosnoth/djangoapp/admin.py
trosnoth/djangoapp/admin.py
+8
-1
trosnoth/djangoapp/migrations/0011_gameplayer_zonescore.py
trosnoth/djangoapp/migrations/0011_gameplayer_zonescore.py
+19
-0
trosnoth/djangoapp/migrations/0012_trosnotharena.py
trosnoth/djangoapp/migrations/0012_trosnotharena.py
+34
-0
trosnoth/djangoapp/migrations/0013_trosnothuser_ownselephant.py
...th/djangoapp/migrations/0013_trosnothuser_ownselephant.py
+23
-0
trosnoth/djangoapp/migrations/0014_auto_20171215_1505.py
trosnoth/djangoapp/migrations/0014_auto_20171215_1505.py
+18
-0
trosnoth/djangoapp/migrations/0015_remove_trosnothserversettings_autostartcountdown.py
.../0015_remove_trosnothserversettings_autostartcountdown.py
+18
-0
trosnoth/djangoapp/migrations/0016_auto_20171222_1548.py
trosnoth/djangoapp/migrations/0016_auto_20171222_1548.py
+18
-0
trosnoth/djangoapp/migrations/0017_auto_20180105_1255.py
trosnoth/djangoapp/migrations/0017_auto_20180105_1255.py
+19
-0
trosnoth/djangoapp/models.py
trosnoth/djangoapp/models.py
+70
-6
trosnoth/djangoapp/static/trosnoth/scoreboard.js
trosnoth/djangoapp/static/trosnoth/scoreboard.js
+9
-36
trosnoth/djangoapp/static/trosnoth/style.css
trosnoth/djangoapp/static/trosnoth/style.css
+46
-68
trosnoth/djangoapp/templates/registration/login.html
trosnoth/djangoapp/templates/registration/login.html
+24
-0
trosnoth/djangoapp/templates/trosnoth/arena.html
trosnoth/djangoapp/templates/trosnoth/arena.html
+170
-0
trosnoth/djangoapp/templates/trosnoth/base.html
trosnoth/djangoapp/templates/trosnoth/base.html
+18
-0
trosnoth/djangoapp/templates/trosnoth/index.html
trosnoth/djangoapp/templates/trosnoth/index.html
+124
-28
trosnoth/djangoapp/templates/trosnoth/viewgame.html
trosnoth/djangoapp/templates/trosnoth/viewgame.html
+3
-0
trosnoth/djangoapp/urls.py
trosnoth/djangoapp/urls.py
+11
-0
trosnoth/djangoapp/views.py
trosnoth/djangoapp/views.py
+173
-12
trosnoth/game.py
trosnoth/game.py
+10
-7
trosnoth/gamerecording/achievementlist.py
trosnoth/gamerecording/achievementlist.py
+112
-255
trosnoth/gamerecording/achievements.py
trosnoth/gamerecording/achievements.py
+6
-0
trosnoth/gamerecording/gamerecorder.py
trosnoth/gamerecording/gamerecorder.py
+1
-1
trosnoth/gamerecording/replays.py
trosnoth/gamerecording/replays.py
+1
-1
trosnoth/gamerecording/statgeneration.py
trosnoth/gamerecording/statgeneration.py
+3
-4
trosnoth/gamerecording/stats.py
trosnoth/gamerecording/stats.py
+68
-24
trosnoth/gui/app.py
trosnoth/gui/app.py
+36
-0
trosnoth/gui/common.py
trosnoth/gui/common.py
+1
-1
trosnoth/levels/base.py
trosnoth/levels/base.py
+21
-8
trosnoth/levels/catpigeon.py
trosnoth/levels/catpigeon.py
+105
-0
trosnoth/levels/defencedrill.py
trosnoth/levels/defencedrill.py
+25
-0
trosnoth/levels/freeforall.py
trosnoth/levels/freeforall.py
+76
-0
trosnoth/levels/hunted.py
trosnoth/levels/hunted.py
+110
-0
trosnoth/levels/orbchase.py
trosnoth/levels/orbchase.py
+181
-0
trosnoth/levels/positioningdrill.py
trosnoth/levels/positioningdrill.py
+27
-0
trosnoth/levels/standard.py
trosnoth/levels/standard.py
+12
-7
trosnoth/levels/trigger_demo.py
trosnoth/levels/trigger_demo.py
+1
-2
trosnoth/levels/trosball.py
trosnoth/levels/trosball.py
+5
-14
trosnoth/levels/tutorial.py
trosnoth/levels/tutorial.py
+6
-14
trosnoth/main.py
trosnoth/main.py
+3
-2
trosnoth/manholehelper.py
trosnoth/manholehelper.py
+5
-8
trosnoth/messages/__init__.py
trosnoth/messages/__init__.py
+2
-1
trosnoth/messages/setup.py
trosnoth/messages/setup.py
+69
-28
trosnoth/messages/special.py
trosnoth/messages/special.py
+48
-3
trosnoth/messages/upgrades.py
trosnoth/messages/upgrades.py
+4
-2
trosnoth/model/agent.py
trosnoth/model/agent.py
+37
-7
trosnoth/model/agenthub.py
trosnoth/model/agenthub.py
+10
-3
trosnoth/model/hub.py
trosnoth/model/hub.py
+7
-2
trosnoth/model/map.py
trosnoth/model/map.py
+50
-13
trosnoth/model/player.py
trosnoth/model/player.py
+21
-8
trosnoth/model/settingsmanager.py
trosnoth/model/settingsmanager.py
+40
-0
trosnoth/model/shot.py
trosnoth/model/shot.py
+2
-0
trosnoth/model/team.py
trosnoth/model/team.py
+16
-16
trosnoth/model/trosball.py
trosnoth/model/trosball.py
+9
-0
trosnoth/model/uithrottler.py
trosnoth/model/uithrottler.py
+2
-2
trosnoth/model/universe.py
trosnoth/model/universe.py
+177
-75
trosnoth/model/upgrades.py
trosnoth/model/upgrades.py
+5
-4
trosnoth/model/voteArbiter.py
trosnoth/model/voteArbiter.py
+79
-8
trosnoth/model/zone.py
trosnoth/model/zone.py
+7
-2
trosnoth/mumble.py
trosnoth/mumble.py
+2
-1
trosnoth/network/authcommands.py
trosnoth/network/authcommands.py
+1
-0
trosnoth/network/base.py
trosnoth/network/base.py
+6
-4
trosnoth/network/client.py
trosnoth/network/client.py
+6
-2
trosnoth/network/lobby.py
trosnoth/network/lobby.py
+9
-24
trosnoth/network/manhole.py
trosnoth/network/manhole.py
+72
-6
trosnoth/network/networkDefines.py
trosnoth/network/networkDefines.py
+3
-3
trosnoth/network/server.py
trosnoth/network/server.py
+10
-14
trosnoth/network/xmpp.py
trosnoth/network/xmpp.py
+0
-183
trosnoth/run/authserver.py
trosnoth/run/authserver.py
+333
-259
trosnoth/run/solotest.py
trosnoth/run/solotest.py
+2
-2
trosnoth/server/arena.py
trosnoth/server/arena.py
+312
-0
trosnoth/server/arenaamp.py
trosnoth/server/arenaamp.py
+100
-0
trosnoth/server/settings.py
trosnoth/server/settings.py
+2
-0
trosnoth/server/urls.py
trosnoth/server/urls.py
+4
-0
trosnoth/settings.py
trosnoth/settings.py
+0
-20
trosnoth/themes.py
trosnoth/themes.py
+19
-19
trosnoth/triggers/bots.py
trosnoth/triggers/bots.py
+3
-0
trosnoth/triggers/coins.py
trosnoth/triggers/coins.py
+4
-3
trosnoth/triggers/deathmatch.py
trosnoth/triggers/deathmatch.py
+232
-0
trosnoth/triggers/rabbits.py
trosnoth/triggers/rabbits.py
+2
-1
trosnoth/trosnothgui/ingame/chatBox.py
trosnoth/trosnothgui/ingame/chatBox.py
+1
-1
trosnoth/trosnothgui/ingame/detailsInterface.py
trosnoth/trosnothgui/ingame/detailsInterface.py
+7
-2
trosnoth/trosnothgui/ingame/dialogs.py
trosnoth/trosnothgui/ingame/dialogs.py
+65
-33
trosnoth/trosnothgui/ingame/gameInterface.py
trosnoth/trosnothgui/ingame/gameInterface.py
+31
-9
trosnoth/trosnothgui/ingame/gamevote.py
trosnoth/trosnothgui/ingame/gamevote.py
+45
-5
trosnoth/trosnothgui/ingame/joincontroller.py
trosnoth/trosnothgui/ingame/joincontroller.py
+7
-1
trosnoth/trosnothgui/ingame/minimap.py
trosnoth/trosnothgui/ingame/minimap.py
+9
-0
trosnoth/trosnothgui/ingame/playerInterface.py
trosnoth/trosnothgui/ingame/playerInterface.py
+5
-0
trosnoth/trosnothgui/ingame/sprites.py
trosnoth/trosnothgui/ingame/sprites.py
+41
-18
trosnoth/trosnothgui/ingame/universegui.py
trosnoth/trosnothgui/ingame/universegui.py
+8
-3
trosnoth/trosnothgui/ingame/viewManager.py
trosnoth/trosnothgui/ingame/viewManager.py
+36
-2
trosnoth/trosnothgui/interface.py
trosnoth/trosnothgui/interface.py
+1
-3
trosnoth/trosnothgui/pregame/playscreen.py
trosnoth/trosnothgui/pregame/playscreen.py
+100
-63
trosnoth/trosnothgui/pregame/serverSelectionScreen.py
trosnoth/trosnothgui/pregame/serverSelectionScreen.py
+1
-15
trosnoth/trosnothgui/pregame/startup.py
trosnoth/trosnothgui/pregame/startup.py
+6
-9
trosnoth/utils/event.py
trosnoth/utils/event.py
+19
-1
trosnoth/utils/lifespan.py
trosnoth/utils/lifespan.py
+29
-0
trosnoth/utils/profiling.py
trosnoth/utils/profiling.py
+18
-0
trosnoth/utils/utils.py
trosnoth/utils/utils.py
+5
-3
trosnoth/version.py
trosnoth/version.py
+1
-1
trosnoth/web/server.py
trosnoth/web/server.py
+51
-69
wininstall/buildInstallScript.py
wininstall/buildInstallScript.py
+27
-26
No files found.
.idea/codeStyleSettings.xml
View file @
e86ec3e6be3f
...
...
@@ -12,6 +12,13 @@
<option
name=
"DICT_NEW_LINE_BEFORE_RIGHT_BRACE"
value=
"true"
/>
<option
name=
"OPTIMIZE_IMPORTS_JOIN_FROM_IMPORTS_WITH_SAME_SOURCE"
value=
"true"
/>
</Python>
<codeStyleSettings
language=
"HTML"
>
<indentOptions>
<option
name=
"INDENT_SIZE"
value=
"2"
/>
<option
name=
"CONTINUATION_INDENT_SIZE"
value=
"4"
/>
<option
name=
"TAB_SIZE"
value=
"2"
/>
</indentOptions>
</codeStyleSettings>
<codeStyleSettings
language=
"Python"
>
<option
name=
"ALIGN_MULTILINE_PARAMETERS"
value=
"false"
/>
<option
name=
"ALIGN_MULTILINE_PARAMETERS_IN_CALLS"
value=
"false"
/>
...
...
changes.txt
View file @
e86ec3e6be3f
v1.12.0
* Added indicator lights around orbs to show the ownership status of
surrounding zones.
* Added box on minimap showing current view area.
* Added guage to all ghosts to show how close they are to respawning.
* Adjusted item costs based on actual usage in a tournament.
* Display more timing info when timing info is enabled.
* Trosnoth server can now run multiple arenas, each of which runs in its
own process. Clients have the option of which arena to join.
* Updates to server web interface, including admin controls to pause and
resume games, reset to lobby, and enable/disable shooting and zone caps
for each team.
* Added new levels: Cat Among Pigeons, Hunted, Free for All, Orb Chase.
* In the lobby, players can vote for the next level to play from the top menu.
* Spectators are no longer prompted to join the game every time the map
resets.
* When joining a game, the join screen now only shows the teams allowed by
the current level.
* Fixed and updated server game record displays, including updating player
score calculation, and fixing record of player teams.
* Fixed Trosball bug where sometimes the ball would start with a player
rather than starting in the centre.
* Fixed bug in chat display that caused issues after a player had received
100 chat messages.
* Fixed some bugs in bots.
* Updated logging to show asctime rather than milliseconds since startup.
* Other minor bug fixes.
v1.11.0
* Standard games now automatically add a bot to the game to keep teams even.
* Player movement is now based on momentum (retro mode can be activated
...
...
encode-trosnoth-replay.py
View file @
e86ec3e6be3f
#!/usr/bin/env python
from
__future__
import
print_function
import
logging
from
optparse
import
OptionParser
import
os
...
...
@@ -14,9 +15,6 @@ from trosnoth.game import RemoteGame
from
trosnoth.gamerecording
import
replays
from
trosnoth.gui.screenManager.screenManager
import
ScreenFonts
from
trosnoth.gui.sound.soundPlayer
import
SoundPlayer
from
trosnoth.model.gameStates
import
(
InProgress
,
Solo
,
Trosball
,
SoloTrosball
,
)
from
trosnoth.model.mapLayout
import
LayoutDatabase
from
trosnoth.settings
import
DisplaySettings
from
trosnoth.trosnothgui.ingame
import
viewManager
...
...
@@ -42,10 +40,10 @@ CAMERA_TERMINAL_VELOCITY = 4800 # game units / s
CAMERA_ACCELERATION
=
2400
# game units / s / s
SHOW_EVERY
=
1
MINIMAP_MAX_SIZE
=
(
100000
,
100000
)
MINIMAP_ONLY
=
Tru
e
MINIMAP_ONLY
=
Fals
e
# To speed things up when debugging
NO_ZOOM
=
Tru
e
NO_ZOOM
=
Fals
e
NO_VIDEOS
=
False
NO_COUNTDOWN
=
False
...
...
@@ -61,7 +59,7 @@ class CustomArgVideoWriter(VideoWriter):
import
subprocess
cmd
=
[
self
.
convert_command
,
'-loglevel'
,
'error'
,
'-f'
,
'rawvideo'
,
'ffmpeg'
,
'-loglevel'
,
'error'
,
'-f'
,
'rawvideo'
,
'-pix_fmt'
,
'rgb24'
,
'-s'
,
'%dx%d'
%
(
self
.
width
,
self
.
height
),
'-r'
,
str
(
self
.
fps
),
'-i'
,
'-'
]
codecs_map
=
{
...
...
@@ -76,6 +74,7 @@ class CustomArgVideoWriter(VideoWriter):
vcodec
=
self
.
fourcc
cmd
+=
[
'-vcodec'
,
vcodec
,
'-b:v'
,
self
.
video_bitrate
]
cmd
+=
[
self
.
filename
]
log
.
debug
(
'Calling %r'
,
cmd
)
self
.
proc
=
subprocess
.
Popen
(
cmd
,
stdin
=
subprocess
.
PIPE
)
...
...
@@ -101,7 +100,7 @@ class FakeSoundPlayer(SoundPlayer):
def
setTime
(
self
,
t
):
self
.
time
=
t
def
addSound
(
self
,
filename
,
action
,
maxSimultaneous
=
8
):
def
addSound
(
self
,
filename
,
action
,
channel
=
None
):
self
.
sounds
[
action
]
=
AudioSegment
.
from_ogg
(
getPath
(
sound
,
filename
))
def
play
(
self
,
action
,
volume
=
1
):
...
...
@@ -155,15 +154,15 @@ class EventListener(object):
self
.
app
.
soundPlayer
.
play
(
sound
)
def
subscribe
(
self
):
self
.
world
.
onGameOver
.
addListener
(
self
.
gameOver
)
self
.
world
.
onGameStateChanged
.
addListener
(
self
.
startGame
)
self
.
world
.
onSound
.
addListener
(
self
.
gotSound
)
self
.
world
.
onGrenadeExplosion
.
addListener
(
self
.
grenadeExploded
)
self
.
world
.
onTrosballExplosion
.
addListener
(
self
.
trosballExploded
)
self
.
world
.
onBomberExplosion
.
addListener
(
self
.
bomberExploded
)
self
.
world
.
onPlayerAdded
.
addListener
(
self
.
playerAdded
)
self
.
world
.
onPlayerRemoved
.
addListener
(
self
.
playerRemoved
)
# TODO: trosball goal sound
def
gotSound
(
self
,
filename
):
self
.
app
.
soundPlayer
.
playFromServerCommand
(
filename
)
def
playerAdded
(
self
,
player
):
player
.
onShotFired
.
addListener
(
self
.
shotFired
)
...
...
@@ -173,13 +172,6 @@ class EventListener(object):
player
.
onShotFired
.
removeListener
(
self
.
shotFired
)
player
.
onUsedUpgrade
.
removeListener
(
self
.
upgradeUsed
)
def
gameOver
(
self
,
*
args
,
**
kwargs
):
self
.
playSound
(
'gameLose'
)
def
startGame
(
self
,
*
args
,
**
kwargs
):
if
self
.
world
.
state
in
(
InProgress
,
Solo
,
Trosball
,
SoloTrosball
):
self
.
playSound
(
'startGame'
)
def
grenadeExploded
(
self
,
pos
,
radius
):
self
.
playSound
(
'explodeGrenade'
)
self
.
app
.
worldgui
.
addExplosion
(
pos
)
...
...
@@ -614,7 +606,7 @@ class Main(object):
if
MINIMAP_ONLY
:
filenames
=
[
minimapVid
]
else
:
filename
=
[
replayVid
,
minimapVid
,
progressVid
,
messageVid
]
filename
s
=
[
replayVid
,
minimapVid
,
progressVid
,
messageVid
]
for
filename
in
filenames
:
if
os
.
path
.
exists
(
filename
):
os
.
unlink
(
filename
)
...
...
@@ -689,7 +681,7 @@ class Main(object):
finally
:
for
w
in
writers
:
w
.
release
()
print
'Saving audio...'
print
(
'Saving audio...'
)
self
.
soundPlayer
.
save
(
os
.
path
.
join
(
self
.
opts
.
output_path
,
'replay.mp3'
))
...
...
get-player-scores.py
0 → 100755
View file @
e86ec3e6be3f
#!/usr/bin/env python
# coding=utf-8
# Make sure that this version of trosnoth is run.
from
__future__
import
print_function
import
os
import
sys
sys
.
path
.
insert
(
0
,
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
)))
# Init django environment for database use
import
django
os
.
environ
.
setdefault
(
'DJANGO_SETTINGS_MODULE'
,
'trosnoth.server.settings'
)
django
.
setup
()
from
trosnoth.const
import
POINT_VALUES
from
trosnoth.djangoapp.models
import
GameRecord
def
get_score
(
player
):
score
=
0
entry
=
{
'player'
:
player
,
'nick'
:
player
.
user
.
nick
if
player
.
user
else
player
.
botName
,
'accuracy'
:
(
100.0
*
player
.
shotsHit
/
player
.
shotsFired
)
if
player
.
shotsFired
else
0.
,
'score'
:
0
,
'kdr'
:
u
'{:2.2f}'
.
format
(
player
.
kills
/
player
.
deaths
)
if
player
.
deaths
else
u
'∞'
,
'adr'
:
u
'{:2.2f}'
.
format
(
player
.
timeAlive
/
player
.
timeDead
)
if
player
.
timeDead
else
u
'∞'
,
}
for
stat
,
weighting
in
POINT_VALUES
.
items
():
if
stat
in
entry
:
value
=
entry
[
stat
]
else
:
value
=
getattr
(
player
,
stat
)
score
+=
value
*
weighting
return
score
player_scores
=
{}
for
parameter
in
sys
.
argv
[
1
:]:
game_id
=
int
(
parameter
)
game
=
GameRecord
.
objects
.
get
(
pk
=
game_id
)
for
player
in
game
.
gameplayer_set
.
all
():
if
player
.
user
:
username
=
player
.
user
.
username
player_scores
.
setdefault
(
username
,
0
)
player_scores
[
username
]
+=
get_score
(
player
)
scores
=
[(
score
,
username
)
for
username
,
score
in
player_scores
.
items
()]
scores
.
sort
(
reverse
=
True
)
for
score
,
player
in
scores
:
print
(
'{}
\t
{:.2f}'
.
format
(
player
,
score
))
inkscape/trosnoth_export.py
View file @
e86ec3e6be3f
#!/usr/bin/env python
from
__future__
import
print_function
from
lxml
import
etree
import
os
from
subprocess
import
Popen
,
PIPE
,
STDOUT
...
...
@@ -445,17 +446,17 @@ def isSymmetrical(obstacles):
def
warning
(
message
):
print
>>
sys
.
stderr
,
'WARNING: '
+
message
print
(
'WARNING: '
+
message
,
file
=
sys
.
stderr
)
def
error
(
message
):
print
>>
sys
.
stderr
,
'ERROR: '
+
message
print
(
'ERROR: '
+
message
,
file
=
sys
.
stderr
)
sys
.
exit
(
1
)
if
__name__
==
'__main__'
:
try
:
print
run_export
(
sys
.
argv
[
1
]
)
print
(
run_export
(
sys
.
argv
[
1
])
)
except
SystemExit
:
raise
except
:
...
...
inkscape/trosnoth_import.py
View file @
e86ec3e6be3f
...
...
@@ -17,6 +17,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
from
__future__
import
print_function
from
lxml
import
etree
import
os
import
sys
...
...
@@ -208,11 +209,11 @@ def storeGraphics(filename, data):
try
:
open
(
imgPath
,
'wb'
).
write
(
data
.
decode
(
'base64'
))
except
IOError
:
print
>>
sys
.
stderr
,
'WARNING: could not write image data'
print
(
'WARNING: could not write image data'
,
file
=
sys
.
stderr
)
if
__name__
==
'__main__'
:
try
:
print
run_import
(
sys
.
argv
[
1
]
)
print
(
run_import
(
sys
.
argv
[
1
])
)
except
:
traceback
.
print_exc
(
file
=
sys
.
stderr
)
sys
.
exit
(
1
)
setup.py
View file @
e86ec3e6be3f
...
...
@@ -66,7 +66,7 @@ def main():
'data_files'
:
data
,
'options'
:
{
'py2exe'
:
{
'includes'
:
'zope.interface,pygame._view,trosnoth.bots.john,trosnoth.bots.ranger'
,
'includes'
:
'zope.interface,pygame._view,trosnoth.bots.john,trosnoth.bots.ranger
,trosnoth.bots.balance,trosnoth.bots.sirrobin,trosnoth.bots.puppet,trosnoth.bots.onezone
'
,
},
},
}
...
...
trosnoth/bots/base.py
View file @
e86ec3e6be3f
...
...
@@ -104,9 +104,16 @@ class AIAgent(ConcreteAgent):
self
.
ai
=
None
self
.
team
=
None
self
.
requestedNick
=
None
self
.
_onBotSet
=
Event
()
self
.
_onBotSet
=
Event
(
[]
)
self
.
_loop
=
WeakLoopingCall
(
self
,
'_tick'
)
def
__str__
(
self
):
if
self
.
ai
:
bot
=
self
.
ai
else
:
bot
=
'None (was {})'
.
format
(
self
.
aiClass
.
__name__
)
return
'{}<{}>'
.
format
(
self
.
__class__
.
__name__
,
bot
)
def
start
(
self
,
team
=
None
):
self
.
team
=
team
self
.
_loop
.
start
(
2
)
...
...
@@ -169,21 +176,19 @@ class AIAgent(ConcreteAgent):
if
player
:
self
.
requestedNick
=
None
self
.
ai
=
self
.
aiClass
(
self
.
world
,
self
.
localState
.
player
,
self
)
self
.
_onBotSet
()
self
.
_onBotSet
(
self
.
ai
)
self
.
_onBotSet
.
clear
()
@
defer
.
inlineCallbacks
def
getBot
(
self
):
'''
@return: a Deferred which fires with this agent's Bot object,
as soon as it has one.
'''
d
=
defer
.
Deferred
()
if
self
.
ai
is
not
None
:
d
.
callback
(
self
.
ai
)
else
:
self
.
_onBotSet
.
addListener
(
d
.
callback
,
weak
=
False
)
return
d
d
efer
.
returnValue
(
self
.
ai
)
yield
self
.
_onBotSet
.
wait
(
)
defer
.
returnValue
(
self
.
ai
)
@
TickMsg
.
handler
def
handle_TickMsg
(
self
,
msg
):
...
...
@@ -236,6 +241,11 @@ class Bot(MessageConsumer):
self
.
start
()
def
__str__
(
self
):
return
'{}: {}'
.
format
(
self
.
__class__
.
__name__
,
repr
(
self
.
player
.
nick
)
if
self
.
player
else
'-'
)
def
sendRequest
(
self
,
msg
):
self
.
agent
.
sendRequest
(
msg
)
...
...
trosnoth/bots/orders.py
View file @
e86ec3e6be3f
...
...
@@ -78,6 +78,7 @@ class MoveGhostToPoint(BotOrder):
super
(
MoveGhostToPoint
,
self
).
__init__
(
bot
)
self
.
pos
=
pos
self
.
stopOnZoneEntry
=
stopOnZoneEntry
self
.
recheckIn
=
0
def
start
(
self
):
self
.
_doAim
()
...
...
@@ -90,9 +91,11 @@ class MoveGhostToPoint(BotOrder):
self
.
bot
.
sendRequest
(
AimPlayerAtMsg
(
theta
,
1.0
,
self
.
bot
.
world
.
lastTickId
))
self
.
recheckIn
=
20
def
tick
(
self
):
if
self
.
bot
.
player
.
ghostThrust
==
0
:
self
.
recheckIn
-=
1
if
self
.
bot
.
player
.
ghostThrust
==
0
or
self
.
recheckIn
<=
0
:
self
.
_doAim
()
if
self
.
stopOnZoneEntry
:
...
...
trosnoth/bots/ranger.py
View file @
e86ec3e6be3f
...
...
@@ -7,6 +7,7 @@ from trosnoth.bots.goalsetter import (
)
from
trosnoth.const
import
(
BOT_GOAL_HUNT_RABBITS
,
BOT_GOAL_SCORE_TROSBALL_POINT
,
BOT_GOAL_CAPTURE_MAP
,
BOT_GOAL_KILL_THINGS
,
)
from
trosnoth.model
import
upgrades
from
trosnoth.utils.math
import
distance
...
...
@@ -42,6 +43,8 @@ class ReachCurrentObjective(Goal):
self
.
setSubGoal
(
HuntTheRabbits
(
self
.
bot
,
self
))
elif
botGoal
==
BOT_GOAL_CAPTURE_MAP
:
self
.
setSubGoal
(
WinStandardTrosnothGame
(
self
.
bot
,
self
))
elif
botGoal
==
BOT_GOAL_KILL_THINGS
:
self
.
setSubGoal
(
HuntEnemies
(
self
.
bot
,
self
))
else
:
self
.
setSubGoal
(
RunAroundKillingHumans
(
self
.
bot
,
self
))
...
...
@@ -98,6 +101,7 @@ class RunAroundKillingThings(Goal):
def
stop
(
self
):
super
(
RunAroundKillingThings
,
self
).
stop
()
self
.
cancelNextCheck
()
def
scheduleNextCheck
(
self
):
self
.
cancelNextCheck
()
...
...
@@ -159,17 +163,17 @@ class RunAroundKillingHumans(RunAroundKillingThings):
for
p
in
zone
.
players
)
class
Hunt
TheRabbits
(
Goal
):
class
Hunt
ingGoal
(
Goal
):
def
start
(
self
):
self
.
huntedPlayer
=
None
self
.
bot
.
onOrderFinished
.
addListener
(
self
.
orderFinished
)
self
.
bot
.
player
.
onRespawned
.
addListener
(
self
.
respawned
)
super
(
Hunt
TheRabbits
,
self
).
start
()
super
(
Hunt
ingGoal
,
self
).
start
()
def
stop
(
self
):
self
.
bot
.
onOrderFinished
.
removeListener
(
self
.
orderFinished
)
self
.
bot
.
player
.
onRespawned
.
removeListener
(
self
.
respawned
)
super
(
Hunt
TheRabbits
,
self
).
stop
()
super
(
Hunt
ingGoal
,
self
).
stop
()
def
orderFinished
(
self
):
if
self
.
subGoal
is
None
:
...
...
@@ -190,12 +194,7 @@ class HuntTheRabbits(Goal):
rabbits
=
[
p
for
p
in
self
.
bot
.
world
.
players
if
self
.
isEnemyRabbit
(
p
)]
if
not
rabbits
:
if
self
.
bot
.
player
.
dead
:
self
.
bot
.
respawn
()
return
# All survining rabbits are on this player's team
self
.
setSubGoal
(
RunAway
(
self
.
bot
,
self
))
self
.
noMoreRabbits
()
return
self
.
huntedPlayer
=
random
.
choice
(
rabbits
)
...
...
@@ -209,6 +208,29 @@ class HuntTheRabbits(Goal):
self
.
bot
.
attackPlayer
(
self
.
huntedPlayer
)
def
noMoreRabbits
(
self
):
raise
NotImplementedError
(
'{}.noMoreRabbits'
.
format
(
self
.
__class__
.
__name__
))
class
HuntTheRabbits
(
HuntingGoal
):
def
noMoreRabbits
(
self
):
if
self
.
bot
.
player
.
dead
:
self
.
bot
.
respawn
()
return
# All survining rabbits are on this player's team
self
.
setSubGoal
(
RunAway
(
self
.
bot
,
self
))
class
HuntEnemies
(
HuntingGoal
):
def
noMoreRabbits
(
self
):
if
self
.
bot
.
player
.
dead
:
self
.
bot
.
respawn
()
return
self
.
bot
.
world
.
callLater
(
3
,
self
.
reevaluate
)
self
.
setSubGoal
(
MessAroundInZone
(
self
.
bot
,
self
))
class
RunAway
(
Goal
):
'''
...
...
trosnoth/bots/sirrobin.py
0 → 100644
View file @
e86ec3e6be3f
import
logging
import
random
from
trosnoth.bots.goalsetter
import
GoalSetterBot
,
Goal
,
MessAroundInZone
log
=
logging
.
getLogger
(
__name__
)
class
BravelyRunAway
(
Goal
):
'''
He was not at all afraid to be killed in nasty ways,
Brave, brave, brave, brave Sir Robin!
'''
def
__init__
(
self
,
bot
,
parent
):
super
(
BravelyRunAway
,
self
).
__init__
(
bot
,
parent
)
self
.
nextCheck
=
None
self
.
messing
=
False
def
start
(
self
):
self
.
bot
.
setAggression
(
False
)
self
.
bot
.
setDodgesBullets
(
True
)
self
.
bot
.
onOrderFinished
.
addListener
(
self
.
orderFinished
)
self
.
bot
.
onTick
.
addListener
(
self
.
tick
)
super
(
BravelyRunAway
,
self
).
start
()
self
.
scheduleNextCheck
()
def
stop
(
self
):
super
(
BravelyRunAway
,
self
).
stop
()
self
.
bot
.
onOrderFinished
.
removeListener
(
self
.
orderFinished
)
self
.
bot
.
onTick
.
removeListener
(
self
.
tick
)
self
.
cancelNextCheck
()
def
scheduleNextCheck
(
self
):
self
.
cancelNextCheck
()
self
.
nextCheck
=
self
.
bot
.
world
.
callLater
(
5
,
self
.
reevaluate
)
def
cancelNextCheck
(
self
):
if
self
.
nextCheck
:
self
.
nextCheck
.
cancel
()
self
.
nextCheck
=
None
def
tick
(
self
):
if
self
.
messing
and
self
.
inScaryZone
():
self
.
reevaluate
()
def
orderFinished
(
self
):
self
.
reevaluate
()
def
reevaluate
(
self
):
self
.
cancelNextCheck
()
self
.
messing
=
False
if
self
.
bot
.
player
.
dead
:
self
.
setSubGoal
(
RespawnFarAway
(
self
.
bot
,
self
))
return
if
self
.
inScaryZone
():
self
.
runAway
()
else
:
self
.
messing
=
True
self
.
setSubGoal
(
MessAroundInZone
(
self
.
bot
,
self
))
self
.
scheduleNextCheck
()
def
inScaryZone
(
self
):
thisPlayer
=
self
.
bot
.
player
zone
=
thisPlayer
.
getZone
()
if
zone
is
None
:
return
True
return
any
(
not
thisPlayer
.
isFriendsWith
(
p
)
for
p
in
zone
.
players
)
def
runAway
(
self
):
player
=
self
.
bot
.
player
curZone
=
player
.
getZone
()
neighbours
=
list
(
curZone
.
getUnblockedNeighbours
())
if
curZone
is
None
:
targetZone
=
random
.
choice
(
list
(
self
.
bot
.
world
.
zones
))
elif
not
neighbours
:
targetZone
=
curZone
else
:
targetZone
=
getBestZone
(
player
,
neighbours
)
self
.
setSubGoal
(
None
)
self
.
bot
.
moveToOrb
(
targetZone
)
def
getBestZone
(
player
,
zones
,
prefer
=
None
):
enemiesByZone
=
{
z
:
sum
(
not
player
.
isFriendsWith
(
p
)
for
p
in
z
.
players
)
for
z
in
zones
}
minEnemies
=
min
(
enemiesByZone
.
values
())
okZones
=
[
z
for
z
in
zones
if
enemiesByZone
[
z
]
==
minEnemies
]
if
prefer
and
prefer
in
okZones
:
return
prefer
return
random
.
choice
(
okZones
)
class
RespawnFarAway
(
Goal
):
'''
Respawns somewhere away from enemies.
'''
def
start
(
self
):
self
.
bot
.
onOrderFinished
.
addListener
(
self
.
orderFinished
)
super
(
RespawnFarAway
,
self
).
start
()
def
stop
(
self
):
super
(
RespawnFarAway
,
self
).
stop
()
self
.
bot
.
onOrderFinished
.
removeListener
(
self
.
orderFinished
)
def
orderFinished
(
self
):
self
.
reevaluate
()
def
reevaluate
(
self
):
player
=
self
.
bot
.
player
if
not
player
.
dead
:
self
.
returnToParent
()
return
curZone
=
player
.
getZone
()
okZones
=
[
z
for
z
in
self
.
bot
.
world
.
zones
if
player
.
isZoneRespawnable
(
z
)]
zone
=
getBestZone
(
player
,
okZones
,
prefer
=
curZone
)
if
zone
!=
curZone
:
self
.
bot
.
moveToOrb
(
zone
)
return
if
player
.
timeTillRespawn
>
0
:
self
.
bot
.
world
.
callLater
(
player
.
timeTillRespawn
,
self
.
reevaluate
)
else
:
self
.
bot
.
respawn
()
class
SirRobinBot
(
GoalSetterBot
):
nick
=
'SirRobinBot'
generic
=
True
MainGoalClass
=
BravelyRunAway
BotClass
=
SirRobinBot
trosnoth/bots/terminator.py
0 → 100644
View file @
e86ec3e6be3f
from
trosnoth.bots.goalsetter
import
Goal
from
trosnoth.bots.ranger
import
RangerBot
,
HuntEnemies
class
KillThings
(
Goal
):
'''
Just kill things. Forever.
'''
def
start
(
self
):