Completed
Pull Request — master (#192)
by Marek
01:39
created

IAIPiratePlayer.setStartingPlanet()   A

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nop 2
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
#
2
#  Copyright 2001 - 2016 Ludek Smid [http://www.ospace.net/]
3
#
4
#  This file is part of Outer Space.
5
#
6
#  Outer Space is free software; you can redistribute it and/or modify
7
#  it under the terms of the GNU General Public License as published by
8
#  the Free Software Foundation; either version 2 of the License, or
9
#  (at your option) any later version.
10
#
11
#  Outer Space is distributed in the hope that it will be useful,
12
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
#  GNU General Public License for more details.
15
#
16
#  You should have received a copy of the GNU General Public License
17
#  along with Outer Space; if not, write to the Free Software
18
#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
#
20
import math
21
import random
22
import sys
23
import time
24
25
import Const
26
import Rules
27
import Utils
28
29
from ige import log
30
from ige.IDataHolder import IDataHolder
31
from ige.IObject import public
32
from IPlayer import IPlayer
33
34
class IAIPiratePlayer(IPlayer):
35
36
    typeID = Const.T_AIPIRPLAYER
37
    resignTo = Const.T_PIRPLAYER
38
    forums = {"INBOX": 56, "OUTBOX": 56, "EVENTS": 0}
39
40
    def init(self, obj):
41
        IPlayer.init(self, obj)
42
        #
43
        obj.name = u'Pirate'
44
        obj.login = '*'
45
        #
46
        obj.pirateFame = 0
47
        obj.techLevel = 99
48
        # grant all TL1 ship techs except for colony module(s)
49
        for techID in Rules.techs:
50
            tech = Rules.techs[techID]
51
            if tech.level == 1 and (tech.isShipEquip or tech.isShipHull) and not tech.unpackStruct:
52
                obj.techs[techID] = Rules.techMaxImprovement
53
54 View Code Duplication
    def register(self, tran, obj, galaxyID):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
55
        log.debug("Registering player", obj.oid)
56
        counter = 1
57
        while 1:
58
            obj.name = u'Pirate faction %d' % counter
59
            obj.login = '*AIP*pirate%d' % counter
60
            if galaxyID in tran.gameMngr.accountGalaxies(obj.login):
61
                counter += 1
62
                continue
63
            tran.gameMngr.registerPlayer(obj.login, obj, obj.oid)
64
            tran.db[Const.OID_UNIVERSE].players.append(obj.oid)
65
            tran.gameMngr.clientMngr.createAIAccount(obj.login, obj.name, 'ais_pirate')
66
            break
67
        # grant techs and so on
68
        self.cmd(obj).update(tran, obj)
69
70
    @staticmethod
71
    def setStartingPlanet(tran, planet):
72
        planet.plSlots = max(planet.plSlots, 2)
73
        planet.plMaxSlots = max(planet.plMaxSlots, 2)
74
        planet.plDiameter = max(planet.plDiameter, 2000)
75
        planet.slots.append(Utils.newStructure(tran, Rules.Tech.PIRATEBASE, planet.owner, Const.STRUCT_STATUS_ON, Rules.structNewPlayerHpRatio))
76
        planet.slots.append(Utils.newStructure(tran, Rules.Tech.PIRATEDEN, planet.owner, Const.STRUCT_STATUS_ON, Rules.structNewPlayerHpRatio))
77
        planet.storPop = 6000
78
79
    @staticmethod
80
    def setStartingTechnologies(obj):
81
        for techID in Rules.techs:
82
            tech = Rules.techs[techID]
83
            if tech.level == 1 and (tech.isShipEquip or tech.isShipHull) and not tech.unpackStruct:
84
                obj.techs[techID] = Rules.techMaxImprovement
85
        obj.techs[Rules.Tech.EMCANNONTUR] = Rules.techMaxImprovement
86
        obj.techs[Rules.Tech.SSROCKET2] = Rules.techMaxImprovement
87
        obj.techs[Rules.Tech.TORPEDO] = Rules.techMaxImprovement
88
        obj.techs[Rules.Tech.PIRATEBASE] = Rules.techMaxImprovement
89
        obj.techs[Rules.Tech.PIRATEDEN] = Rules.techMaxImprovement
90
        obj.techs[Rules.Tech.PIRATESD] = Rules.techMaxImprovement
91
        obj.techs[Rules.Tech.PIRATEBREWERY] = Rules.techMaxImprovement
92
        obj.techs[Rules.Tech.PIRATEPRISON] = Rules.techMaxImprovement
93
        obj.techs[Rules.Tech.PIRATEPRISON] = Rules.techMaxImprovement
94
        obj.techs[Rules.Tech.PIRSMCOLONYMOD] = Rules.techMaxImprovement
95
        obj.techs[Rules.Tech.PIRATEFTLENG] = Rules.techMaxImprovement
96
        obj.techs[Rules.Tech.PIRCOLONYMOD] = Rules.techMaxImprovement
97
98
    @staticmethod
99
    def setStartingShipDesigns(obj):
100
        # these are generated by the AI itself
101
        pass
102
103
    def processINITPhase(self, tran, obj, data):
104
        IPlayer.processINITPhase(self, tran, obj, data)
105
        # TODO -- remove following lines
106
        obj.lastLogin = time.time()
107
        # delete itself if there are no fleets and planets
108
        if not obj.fleets and not obj.planets:
109
            self.cmd(obj).delete(tran, obj)
110
111
    def update(self, tran, obj):
112
        obj.techLevel = 99
113
        obj.race = "p"
114
        # call super method
115
        IPlayer.update(self, tran, obj)
116
        #
117
        obj.techLevel = 99
118
        # grant technologies
119
        obj.techs[Rules.Tech.EMCANNONTUR] = Rules.techMaxImprovement
120
        obj.techs[Rules.Tech.SSROCKET2] = Rules.techMaxImprovement
121
        obj.techs[Rules.Tech.TORPEDO] = Rules.techMaxImprovement
122
        # grant special technologies
123
        obj.techs[Rules.Tech.PIRATEBASE] = Rules.techMaxImprovement
124
        obj.techs[Rules.Tech.PIRATEDEN] = Rules.techMaxImprovement
125
        obj.techs[Rules.Tech.PIRATESD] = Rules.techMaxImprovement
126
        obj.techs[Rules.Tech.PIRATEBREWERY] = Rules.techMaxImprovement
127
        obj.techs[Rules.Tech.PIRATEPRISON] = Rules.techMaxImprovement
128
        obj.techs[Rules.Tech.PIRSMCOLONYMOD] = Rules.techMaxImprovement
129
        obj.techs[Rules.Tech.PIRATEFTLENG] = Rules.techMaxImprovement
130
        obj.techs[Rules.Tech.PIRCOLONYMOD] = Rules.techMaxImprovement
131
132 View Code Duplication
    def getDiplomacyWith(self, tran, obj, playerID):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
133
        if obj.oid == playerID:
134
            return Const.REL_UNITY
135
        # this AI battles with overyone
136
        # make default
137
        dipl = IDataHolder()
138
        dipl.type = Const.T_DIPLREL
139
        dipl.pacts = {}
140
        dipl.relation = Const.REL_ENEMY
141
        dipl.relChng = 0
142
        dipl.lastContact = tran.db[Const.OID_UNIVERSE].turn
143
        dipl.contactType = Const.CONTACT_NONE
144
        dipl.stats = None
145
        return dipl
146
147
    def isPactActive(self, tran, obj, partnerID, pactID):
148
        if partnerID == Const.OID_NONE:
149
            return 0
150
        partner = tran.db.get(partnerID, None)
151
        if partner.type == Const.T_AIEDENPLAYER:
152
            # force the peace!
153
            if pactID in (Const.PACT_ALLOW_CIVILIAN_SHIPS, Const.PACT_ALLOW_MILITARY_SHIPS):
154
                return Const.PACT_ACTIVE
155
        return 0
156
157
    @public(Const.AL_ADMIN)
158
    def processDIPLPhase(self, tran, obj, data):
159
        self.forceAllyWithEDEN(tran,obj)
160
        IPlayer.processDIPLPhase(self,tran, obj, data)
161
162
    @public(Const.AL_ADMIN)
163
    def processFINALPhase(self, tran, obj, data):
164
        obj.govPwr = Rules.pirateGovPwr
165
        IPlayer.processFINALPhase(self, tran, obj, data)
166
        # get fame every 1:00 turns
167
        if tran.db[Const.OID_UNIVERSE].turn % Rules.turnsPerDay == 0:
168
            Utils.sendMessage(tran, obj, Const.MSG_GAINED_FAME, obj.oid, Rules.pirateSurvivalFame)
169
            obj.pirateFame += Rules.pirateSurvivalFame
170
        # fix goverment power
171
        obj.govPwrCtrlRange = 10000
172
        # bonus for gained fame
173
        obj.prodEff += obj.pirateFame / 100.0
174
175
    @public(Const.AL_ADMIN)
176
    def processRSRCHPhase(self, tran, obj, data):
177
        # do not research anything
178
        return
179
180
    def distToNearestPiratePlanet(self,tran,obj,srcObj):
181
        # srcObj can be Planet or System type
182
        dist = sys.maxint
183
        for objID in obj.planets:
184
            pirPl = tran.db[objID]
185
            d = math.hypot(srcObj.x - pirPl.x, srcObj.y - pirPl.y)
186
            if d < dist:
187
                dist = d
188
        return dist
189
190 View Code Duplication
    def capturePlanet(self, tran, obj, planet):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
191
        # find distance to closes pirate's planet
192
        dist = self.distToNearestPiratePlanet(tran,obj,planet)
193
        if random.random() <= Rules.pirateGainFamePropability(dist):
194
            log.debug(obj.oid, "Pirate captured planet + fame", dist, planet.oid)
195
            obj.pirateFame += Rules.pirateCaptureInRangeFame
196
            Utils.sendMessage(tran, obj, Const.MSG_GAINED_FAME, planet.oid, Rules.pirateCaptureInRangeFame)
197
        elif random.random() <= Rules.pirateLoseFameProbability(dist):
198
            log.debug(obj.oid, "Pirate captured planet OUT OF range", dist, planet.oid)
199
            obj.pirateFame += Rules.pirateCaptureOutOfRangeFame
200
            Utils.sendMessage(tran, obj, Const.MSG_LOST_FAME, planet.oid, Rules.pirateCaptureOutOfRangeFame)
201
202 View Code Duplication
    def stealTechs(self, tran, piratePlayer, oldOwnerID, stealFromPlanetID):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
203
        if oldOwnerID == Const.OID_NONE:
204
            return
205
        log.debug(piratePlayer.oid, "IPiratePlayer stealing techs")
206
        oldOwner = tran.db[oldOwnerID]
207
        canSteal = Rules.pirateCanStealImprovements
208
        while canSteal > 0:
209
            stealed = False
210
            for techID in oldOwner.techs:
211
                tech = Rules.techs[techID]
212
                if oldOwner.techs[techID] <= piratePlayer.techs.get(techID, 0):
213
                    # skip techs that are already stealed
214
                    continue
215
                if (tech.isShipEquip or tech.isShipHull) and not tech.unpackStruct and canSteal > 0:
216
                    self.givePirateTech(tran, piratePlayer, oldOwner, techID, stealFromPlanetID)
217
                    canSteal -= 1
218
                    stealed = True
219
                if tech.isProject and canSteal > 0:
220
                    self.givePirateTech(tran, piratePlayer, oldOwner, techID, stealFromPlanetID)
221
                    canSteal -= 1
222
                    stealed = True
223
            if not stealed:
224
                break
225
        # update techs
226
        self.cmd(piratePlayer).update(tran, piratePlayer)
227
        return
228
229
    def givePirateTech(self, tran, piratePlayer, oldOwner, techID, stealFromPlanetID):
230
        piratePlayer.techs[techID] = min(piratePlayer.techs.get(techID, 0) + 1, oldOwner.techs[techID])
231
        Utils.sendMessage(tran, piratePlayer, Const.MSG_GAINED_TECH, stealFromPlanetID, (techID, piratePlayer.techs[techID]))
232
233 View Code Duplication
    def forceAllyWithEDEN(self,tran,obj):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
234
        for partyID in obj.diplomacyRels.keys():
235
            party = tran.db.get(partyID, None)
236
            if party.type == Const.T_AIEDENPLAYER:
237
                diplSelf = obj.diplomacyRels.get(party.oid, None)
238
                log.debug("Allying Pirate with EDEN (forced)", obj.oid, partyID)
239
                diplEDEN = IDataHolder()
240
                diplEDEN.type = Const.T_DIPLREL
241
                diplEDEN.pacts = {
242
                    Const.PACT_ALLOW_CIVILIAN_SHIPS: [Const.PACT_ACTIVE, Const.PACT_ALLOW_CIVILIAN_SHIPS],
243
                    Const.PACT_ALLOW_MILITARY_SHIPS: [Const.PACT_ACTIVE, Const.PACT_ALLOW_MILITARY_SHIPS]
244
                }
245
                diplEDEN.relation = Const.REL_FRIENDLY
246
                diplEDEN.relChng = 0
247
                diplEDEN.lastContact = tran.db[Const.OID_UNIVERSE].turn
248
                diplEDEN.contactType = Const.CONTACT_STATIC
249
                diplEDEN.stats = None
250
251
                diplSelf.relation = Const.REL_FRIENDLY
252
                diplSelf.pacts = {
253
                    Const.PACT_ALLOW_CIVILIAN_SHIPS: [Const.PACT_ACTIVE, Const.PACT_ALLOW_CIVILIAN_SHIPS],
254
                    Const.PACT_ALLOW_MILITARY_SHIPS: [Const.PACT_ACTIVE, Const.PACT_ALLOW_MILITARY_SHIPS]
255
                }
256
257
                obj.diplomacyRels[party.oid] = diplSelf
258
                party.diplomacyRels[obj.oid] = diplEDEN
259
260
261