Merge branch 'lawAndOrder_to_lua', #3254

master
Karl F 2015-11-02 10:21:24 +01:00
commit ad4aa02c7f
32 changed files with 812 additions and 394 deletions

View File

@ -9,6 +9,7 @@ local f = Faction:new('Solar Federation')
:expansionRate(1.0)
:military_name('SolFed Military')
:police_name('SolFed Police Force')
:police_ship('kanara')
:colour(0.4,0.4,1.0)
f:govtype_weight('EARTHDEMOC', 60)

View File

@ -9,6 +9,7 @@ local f = Faction:new('Commonwealth of Independent Worlds')
:expansionRate(1.0)
:military_name('Confederation Fleet')
:police_name('Confederal Police')
:police_ship('pumpkinseed_police')
:colour(0.4,1.0,0.4)
f:govtype_weight('CISSOCDEM', 80)

View File

@ -907,18 +907,6 @@
"description" : "",
"message" : "Sep"
},
"MULTI_SCOOP" : {
"description" : "A ship equipment: a cargo scoop and fuel scoop combined to one",
"message" : "Multi Scoop"
},
"MULTI_SCOOP_DESCRIPTION" : {
"description" : "",
"message" : "Although less effective than a fuel scoop it permits scooping of both cargo and fuel"
},
"MURDER" : {
"description" : "",
"message" : "Murder"
},
"M_S_RELATIVE_TO" : {
"description" : "",
"message" : "%speed{f.0} m/s rel-to %frame"
@ -1111,10 +1099,6 @@
"description" : "",
"message" : "PIONEER"
},
"PIRACY" : {
"description" : "",
"message" : "Piracy"
},
"PITCH" : {
"description" : "",
"message" : "Pitch"
@ -1151,10 +1135,6 @@
"description" : "",
"message" : "Plutocratic dictatorship"
},
"POLICE_SHIP_REGISTRATION" : {
"description" : "",
"message" : "POLICE"
},
"POPULATION" : {
"description" : "",
"message" : "Population:"
@ -1707,10 +1687,6 @@
"description" : "",
"message" : "<unknown>"
},
"UNLAWFUL_WEAPONS_DISCHARGE" : {
"description" : "",
"message" : "Unlawful weapons discharge"
},
"USE_LOW_THRUST" : {
"description" : "",
"message" : "Use low thrust"
@ -1771,10 +1747,6 @@
"description" : "keybinding: x axis",
"message" : "X"
},
"X_CANNOT_BE_TOLERATED_HERE" : {
"description" : "",
"message" : "%crime cannot be tolerated here."
},
"Y" : {
"description" : "keybinding: y axis",
"message" : "Y"

View File

@ -196,7 +196,7 @@
"message" : "Crew Roster"
},
"CRIMINAL_RECORD" : {
"description" : "",
"description" : "Past crimes / crime history of character",
"message" : "Criminal record"
},
"DANGEROUS" : {
@ -255,6 +255,10 @@
"description" : "mission deadline date",
"message" : "Due"
},
"DUMPING" : {
"description" : "The illegal act of dumping waste",
"message" : "Dumping"
},
"D_DAYS_LEFT" : {
"description" : "",
"message" : "Days left: %d"
@ -771,6 +775,10 @@
"description" : "Player owing money to crew members",
"message" : "Owed"
},
"OUTSTANDING_FINES" : {
"description" : "Unpaid fines for crimes committed",
"message" : "Outstanding fines"
},
"PAY_FINE_OF_N" : {
"description" : "",
"message" : "Pay fine of {amount}"
@ -1126,5 +1134,9 @@
"YOU_NOT_ENOUGH_MONEY" : {
"description" : "",
"message" : "You do not have enough money"
},
"X_CANNOT_BE_TOLERATED_HERE" : {
"description" : "Message to be sent over comms by police when crime is committed by player",
"message" : "{crime} cannot be tolerated here!"
}
}

70
data/libs/Legal.lua Normal file
View File

@ -0,0 +1,70 @@
-- Copyright © 2008-2015 Pioneer Developers. See AUTHORS.txt for details
-- Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
local Comms = import("Comms")
local Game = import("Game")
local Lang = import("Lang")
local l = Lang.GetResource("ui-core")
--
-- Namespace: Legal
--
--
-- Constants: CrimeType
--
-- Different types of crimes and law offences
--
-- DUMPING - jettison of hazardous rubble/waste
-- MURDER - destruction of ship
-- PIRACY - fired on ship
-- TRADING_ILLEGAL_GOODS - attempted to sell illegal goods
-- WEAPONS_DISCHARGE - weapons discharged too close to station
--
-- Availability:
--
-- 2015 July
--
-- Status:
--
-- experimental
--
local Legal = {}
Legal.CrimeType = {}
Legal.CrimeType["DUMPING"] = {basefine = 1e4, name = l.DUMPING}
Legal.CrimeType["MURDER"] = {basefine = 1.5e6, name = l.MURDER}
Legal.CrimeType["PIRACY"] = {basefine = 1e5, name = l.PIRACY}
Legal.CrimeType["TRADING_ILLEGAL_GOODS"] = {basefine = 5e3, name = l.TRADING_ILLEGAL_GOODS}
Legal.CrimeType["WEAPONS_DISCHARGE"] = {basefine = 5e2, name = l.UNLAWFUL_WEAPONS_DISCHARGE}
function Legal:notifyOfCrime (ship, crime)
if not ship:IsPlayer() then return end
-- TODO: can this be called in hyperpace?
-- find closest law enforcing station
local station = Game.player:FindNearestTo("SPACESTATION")
-- too far away for crime to be noticed
if station.lawEnforcedRange < station:DistanceTo(Game.player) then
return
end
Comms.ImportantMessage(string.interp(l.X_CANNOT_BE_TOLERATED_HERE, {crime=self.CrimeType[crime].name}),
station.label)
local lawlessness = Game.system.lawlessness
local _, outstandingfines = Game.player:GetCrimeOutstanding()
local newFine = math.max(1, 1+math.floor(self.CrimeType[crime].basefine * (1.0-lawlessness)))
-- don't keep compounding fines, except for murder
if crime ~= "MURDER" and newFine < outstandingfines then newFine = 0 end
Game.player:AddCrime(crime, newFine)
end
return Legal

View File

@ -5,6 +5,275 @@ local Player = import_core("Player")
local Serializer = import("Serializer")
local Event = import("Event")
local Game = import("Game")
local utils = import("utils")
local Legal = import("Legal")
Player.record = {}
Player.record_old = {}
-- container for crimes committed
local CrimeRecord = utils.inherits(nil, "CrimeRecord")
function CrimeRecord.New(rec)
rec = rec or {}
setmetatable(rec, CrimeRecord.meta)
rec.fine = 0
rec.crimetype = {}
return rec
end
function CrimeRecord:Add(crime, fine)
if not fine then
fine = Legal.CrimeType[crime].basefine
end
-- if first time for this crime type
if not self.crimetype[crime] then
self.crimetype[crime] = {}
self.crimetype[crime].count = 0
end
self.crimetype[crime].count = self.crimetype[crime].count +1
self.fine = self.fine + fine
return self.fine
end
function CrimeRecord:SetFine(fine)
self.fine = fine
return self.fine
end
-- add two crime records together
function CrimeRecord:Append(record)
self.fine = self.fine + record.fine
for k,v in pairs(record.crimetype) do
for i = 1, record.crimetype[k].count do
self:Add(k, 0)
end
end
end
function CrimeRecord:Serialize()
local tmp = CrimeRecord.Super().Serialize(self)
local ret = {}
for k,v in pairs(tmp) do
ret[k] = v
end
return ret
end
function CrimeRecord.Unserialize(data)
obj = CrimeRecord.Super().Unserialize(data)
setmetatable(obj, CrimeRecord.meta)
return obj
end
--
-- Method: AddCrime
--
-- Add a crime to the player's criminal record
--
-- > Game.player:AddCrime(crime, fine, faction)
--
-- Parameters:
--
-- crime - a string constant describing the crime
--
-- fine - an amount to add to the player's fine
--
-- faction - optional argument, defaults to the faction id of the system
-- the player is currently in
--
--
-- Availability:
--
-- 2015 August
--
-- Status:
--
-- experimental
--
function Player:AddCrime (crime, fine, faction)
local forFaction = (faction and faction.id) or Game.system.faction.id
-- first time for this faction
if not self.record[forFaction] then
self.record[forFaction] = CrimeRecord.New()
end
self.record[forFaction]:Add(crime, fine)
end
local function __GetCrime (record)
-- return crime record and total fine for faction
local listOfCrime, fine
if Game.player.flightState == "HYPERSPACE" then
-- no crime in hyperspace
listOfCrime = {}
fine = 0
elseif not record then
-- first time for this faction, clean record
listOfCrime = {}
fine = 0
else
listOfCrime = record.crimetype
fine = record.fine
end
return listOfCrime, fine
end
--
-- Method: GetCrimeRecord
--
-- Get players past criminal record of and total payed fine for faction
--
-- > criminalRecord, fine = Game.player:GetCrimeRecord()
-- > criminalRecord, fine = Game.player:GetCrimeRecord(faction)
--
-- Parameters:
--
-- faction - optional argument, defaults to the faction id of the system
-- the player is in
--
--
-- Return:
--
-- criminalRecord - a table with key being "crime constant" and "count"
-- for each crime committed
--
-- fine - the total fine of the player in faction
--
--
-- Availability:
--
-- 2015 September
--
-- Status:
--
-- experimental
--
function Player:GetCrimeRecord (faction)
local forFaction = (faction and faction.id) or Game.system.faction.id
return __GetCrime(self.record_old[forFaction])
end
--
-- Method: GetCrimeOutstanding
--
-- Get players current outstanding criminal record and total unpayed fine for faction
--
-- > criminalRecord, fine = Game.player:GetCrimeOutstanding()
-- > criminalRecord, fine = Game.player:GetCrimeOutstanding(faction)
--
-- Parameters:
--
-- faction - optional argument, defaults to the faction id of the system
-- the player is currently in
--
--
-- Return:
--
-- criminalRecord - a table with key being "crime constant" and "count"
-- for each crime committed
--
-- fine - the total fine of the player in faction
--
--
-- Availability:
--
-- 2015 September
--
-- Status:
--
-- experimental
--
function Player:GetCrimeOutstanding (faction)
local forFaction = (faction and faction.id) or Game.system.faction.id
return __GetCrime(self.record[forFaction])
end
--
-- Method: ClearCrimeFine
--
-- Clear the current record of outstanding fines and crimes for player
--
-- > Game.player:ClearCrimeFine()
-- > Game.player:ClearCrimeFine(faction)
-- > Game.player:ClearCrimeFine(faction, clean)
--
-- Parameters:
--
-- faction - optional argument, defaults to the faction id of the system
-- the player is currently in
--
-- clean - optional Boolean argument, defaults to false, resulting in the
-- cleared fines to still be moved to the player's crime record
-- over past offences
--
--
-- Availability:
--
-- 2015 September
--
-- Status:
--
-- experimental
--
function Player:ClearCrimeFine (faction, forget)
local forFaction = (faction and faction.id) or Game.system.faction.id
self.record[forFaction].fine = 0 -- Clear fine
if not forget then
if not self.record_old[forFaction] then
self.record_old[forFaction] = CrimeRecord.New()
end
self.record_old[forFaction]:Append(self.record[forFaction], true)
end
self.record[forFaction] = nil -- Clear record
end
--
-- Method: ClearCrimeRecordHistory
--
-- Clear the player's crime record history, excluding current unpayed offences
--
-- > Game.player:ClearCrimeRecordHistory()
-- > Game.player:ClearCrimeRecordHistory(faction)
--
-- Parameters:
--
-- faction - optional argument, defaults to the faction if of the system
-- the player is currently in
--
--
-- Availability:
--
-- 2015 September
--
-- Status:
--
-- experimental
--
function Player:ClearCrimeRecordHistory (faction)
local forFaction = (faction and faction.id) or Game.system.faction.id
self.record_old[forFaction] = nil
end
--
-- Method: GetMoney
@ -82,21 +351,51 @@ end
local loaded_data
Event.Register("onGameStart", function ()
local onGameStart = function ()
-- Don't reset these in onGameEnd (where they belong), since that
-- sometimes clears out the data before autosave-exit can get to it
-- (call order for event triggers is arbitrary)...
Player.record = {}
Player.record_old = {}
if (loaded_data) then
Game.player:setprop("cash", loaded_data)
Game.player:setprop("cash", loaded_data.cash)
-- ...thus we need to manually unserialize them
Player.record = loaded_data.record
Player.record_old = loaded_data.record_old
loaded_data = nil
end
end)
end
Serializer:Register("Player",
function ()
return Game.player.cash
end,
function (data)
loaded_data = data
end
)
local serialize = function ()
local data = {
cash = Game.player.cash,
record = Game.player.record,
record_old = Game.player.record_old
}
return data
end
local unserialize = function (data)
loaded_data = data
Player.cash = data.cash
Player.record = data.record
Player.record_old = data.record_old
end
local onGameEnd = function ()
-- clean up for next game:
end
Event.Register("onGameEnd", onGameEnd)
Event.Register("onGameStart", onGameStart)
Serializer:RegisterClass("CrimeRecord", CrimeRecord)
Serializer:Register("Player", serialize, unserialize)
return Player

View File

@ -15,6 +15,9 @@ local Model = import("SceneGraph.Model")
local ModelSkin = import("SceneGraph.ModelSkin")
local Serializer = import("Serializer")
local Equipment = import("Equipment")
local Faction = import("Faction")
local Lang = import("Lang")
local l = Lang.GetResource("ui-core")
--
-- Class: SpaceStation
@ -289,6 +292,117 @@ local function updateShipsOnSale (station)
end
--
-- Attribute: lawEnforcedRange
--
-- The distance, in meters, at which a station upholds the law,
-- (is 100 km for all at the moment)
--
-- Availability:
--
-- 2015 September
--
-- Status:
--
-- experimental
--
SpaceStation.lawEnforcedRange = 100000
local police = {}
--
-- Method: LaunchPolice
--
-- Launch station police
--
-- > station:LaunchPolice(targetShip)
--
-- Parameters:
--
-- targetShip - the ship to intercept
--
-- Availability:
--
-- 2015 September
--
-- Status:
--
-- experimental
--
function SpaceStation:LaunchPolice(targetShip)
if not targetShip then error("Ship targeted invalid") end
-- if no police created for this station yet:
if not police[self] then
police[self] = {}
-- decide how many to create
local lawlessness = Game.system.lawlessness
local maxPolice = math.min(9, self.numDocks)
local numberPolice = math.ceil(Engine.rand:Integer(1,maxPolice)*lawlessness)
local shiptype = ShipDef[Game.system.faction.policeShip]
-- create and equip them
while numberPolice > 0 do
local policeShip = Space.SpawnShipDocked(shiptype.id, self)
if policeShip == nil then
return
else
numberPolice = numberPolice - 1
--policeShip:SetLabel(Game.system.faction.policeName) -- this is cool, but not translatable right now
policeShip:SetLabel(l.POLICE)
policeShip:AddEquip(Equipment.laser.pulsecannon_dual_1mw)
policeShip:AddEquip(Equipment.misc.atmospheric_shielding)
policeShip:AddEquip(Equipment.misc.laser_cooling_booster)
policeShip:AddEquip(Equipment.cargo.hydrogen, 1)
table.insert(police[self], policeShip)
end
end
end
for _, policeShip in pairs(police[self]) do
-- if docked
if policeShip.flightState == "DOCKED" then
policeShip:Undock()
end
-- if not shot down
if policeShip:exists() then
policeShip:AIKill(targetShip)
end
end
end
--
-- Method: LandPolice
--
-- Clear any target assigned and land flying station police.
--
-- > station:LandPolice()
--
--
-- Availability:
--
-- 2015 September
--
-- Status:
--
-- experimental
--
function SpaceStation:LandPolice()
-- land command issued before creation of police
if not police[self] then return end
for _, policeShip in pairs(police[self]) do
if not (policeShip.flightState == "DOCKED") and policeShip:exists() then
policeShip:CancelAI()
policeShip:AIDockWith(self)
end
end
end
--
-- Group: Methods
--
@ -532,6 +646,8 @@ local function destroySystem ()
equipmentStock = {}
equipmentPrice = {}
police = {}
shipsOnSale = {}
for station,ads in pairs(SpaceStation.adverts) do
@ -549,6 +665,7 @@ Event.Register("onGameStart", function ()
if (loaded_data) then
equipmentStock = loaded_data.equipmentStock
equipmentPrice = loaded_data.equipmentPrice or {} -- handle missing in old saves
police = loaded_data.police
for station,list in pairs(loaded_data.shipsOnSale) do
shipsOnSale[station] = {}
for i,entry in pairs(loaded_data.shipsOnSale[station]) do
@ -587,6 +704,7 @@ Event.Register("onGameEnd", function ()
nextRef = 0
equipmentStock = {}
equipmentPrice = {}
police = {}
shipsOnSale = {}
end)
@ -596,6 +714,7 @@ Serializer:Register("SpaceStation",
local data = {
equipmentStock = equipmentStock,
equipmentPrice = equipmentPrice,
police = police, --todo fails if a police ship is killed
shipsOnSale = {},
}
for station,list in pairs(shipsOnSale) do

View File

@ -0,0 +1,21 @@
material smallship_fuselage-material
diffuse 1.0 1.0 1.0
specular 0.9 0.9 0.9
shininess 70
tex_diff pumpkinseed_police_diff.dds
tex_glow pumpkinseed_police_glow.dds
tex_spec pumpkinseed_police_spec.dds
lod 50
mesh pumpkinseed_3low.dae
lod 100
mesh pumpkinseed_2med.dae
lod 300
mesh pumpkinseed_1hi.dae
mesh pumpkinseed_shield.dae
collision pumpkinseed_collision.dae
anim gear_down 0 100

View File

@ -0,0 +1,16 @@
material Material-material
diffuse 1.0 1.0 1.0
specular 0.8 0.8 0.8
tex_diff sinonatrix_tex_police.dds
tex_spec sinonatrix_spec.dds
tex_glow sinonatrix_glow.dds
mesh sinonatrix.dae
anim gear_down 1 100
collision sinonatrix_col.obj
lod 75
mesh sinonatrix_LOD.dae
mesh sinonatrix_shield.dae

Binary file not shown.

View File

@ -0,0 +1,124 @@
-- Copyright © 2008-2015 Pioneer Developers. See AUTHORS.txt for details
-- Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
local Event = import("Event")
local Game = import("Game")
local Engine = import("Engine")
local Timer = import("Timer")
local Serializer = import("Serializer")
local Legal = import("Legal")
-- Fine at which police will launch and hunt donwn outlaw player
local maxFineTolerated = 300
-- store which station sent them out
local policeDispatched = false
-- check if we should dispatch police, or call them back
local function doLawAndOrder ()
if Game.player.flightState == "HYPERSPACE" then return end
local crimes, fine = Game.player:GetCrimeOutstanding()
if not policeDispatched then
if fine > maxFineTolerated and
Game.player.flightState == "FLYING" and
Engine.rand:Integer(0,1) > Game.system.lawlessness then
local station = Game.player:FindNearestTo("SPACESTATION")
if station.lawEnforcedRange >= station:DistanceTo(Game.player) then
station:LaunchPolice(Game.player)
policeDispatched = station
end
return
end
end
-- if police are out flying about, check if they should land
-- Note: If player docks police will land.
if policeDispatched then
if fine < maxFineTolerated or
Game.player.flightState == "DOCKED" or Game.player.flightState == "DOCKING" then
policeDispatched:LandPolice()
policeDispatched = false
end
end
end
local loaded_data
local onGameStart = function ()
if (loaded_data) then
policeDispatched = loaded_data.policeDispatched
end
loaded_data = nil
Timer:CallEvery(5, doLawAndOrder)
end
local serialize = function ()
local data = {
policeDispatched = policeDispatched,
}
return data
end
local unserialize = function (data)
loaded_data = data
end
local onJettison = function(ship, cargo)
if ship:IsPlayer() then
if cargo.price <= 0 or not Game.system:IsCommodityLegal(cargo) then
Legal:notifyOfCrime(ship,"DUMPING")
end
end
end
local onShipHit = function(ship, attacker)
if attacker and attacker:IsPlayer() then
Legal:notifyOfCrime(ship,"PIRACY")
end
end
local onShipDestroyed = function(ship, attacker)
-- Note: crash issue #887, this _should_ no longer trigger crash.
-- Also, attacker can be a body, which does not have an IsPlayer()
if attacker and attacker:isa("Ship") and attacker:IsPlayer() then
Legal:notifyOfCrime(ship,"MURDER")
end
end
local onShipFiring = function(ship)
if ship:IsPlayer() then
Legal:notifyOfCrime(ship,"WEAPONS_DISCHARGE")
end
end
local onLeaveSystem = function(ship)
if not ship:IsPlayer() then return end
-- if we leave the system, the space station object will be invalid
policeDispatched = nil
end
local onGameEnd = function ()
policeDispatched = nil
end
Event.Register("onShipHit", onShipHit)
Event.Register("onShipDestroyed", onShipDestroyed)
Event.Register("onShipFiring", onShipFiring)
Event.Register("onJettison", onJettison)
Event.Register("onGameStart", onGameStart)
Event.Register("onGameEnd", onGameEnd)
Event.Register("onLeaveSystem", onLeaveSystem)
Serializer:Register("CrimeTracking", serialize, unserialize)

View File

@ -0,0 +1,31 @@
{
"angular_thrust" : 16500000.0,
"capacity" : 17,
"cockpit" : "",
"down_thrust" : 350000.0,
"effective_exhaust_velocity" : 29000000.0,
"forward_thrust" : 3200000.0,
"fuel_tank_mass" : 9,
"hull_mass" : 8,
"hyperdrive_class" : 1,
"left_thrust" : 350000.0,
"manufacturer" : "kaluri",
"max_crew" : 1,
"min_crew" : 1,
"model" : "pumpkinseed_police",
"name" : "Police Pumpkinseed",
"price" : 0.0,
"reverse_thrust" : 1200000.0,
"right_thrust" : 350000.0,
"ship_class" : "light_courier",
"slots" : {
"cargo" : 10,
"scoop" : 0,
"laser_front" : 1,
"laser_rear" : 1,
"missile" : 4,
"sensor" : 8
},
"thruster_fuel_use" : -1.0,
"up_thrust" : 550000.0
}

View File

@ -0,0 +1,30 @@
{
"model" : "sinonatrix_police",
"name" : "Police Sinonatrix",
"cockpit" : "",
"manufacturer" : "opli",
"ship_class" : "light_fighter",
"min_crew" : 1,
"max_crew" : 2,
"price" : 0.0,
"hull_mass" : 22,
"capacity" : 35,
"slots" : {
"cargo" : 35,
"scoop" : 0,
"laser_front" : 1,
"missile" : 4,
"sensor" : 8
},
"effective_exhaust_velocity" : 10000000.0,
"thruster_fuel_use" : -1.0,
"fuel_tank_mass" : 30,
"hyperdrive_class" : 0,
"forward_thrust" : 6150000.0,
"reverse_thrust" : 1250000.0,
"up_thrust" : 1600000.0,
"down_thrust" : 1200000.0,
"left_thrust" : 1200000.0,
"right_thrust" : 1200000.0,
"angular_thrust" : 27000000.0
}

View File

@ -9,6 +9,7 @@ local Lang = import("Lang")
local Comms = import("Comms")
local InfoFace = import("ui/InfoFace")
local MessageBox = import("ui/MessageBox")
local l = Lang.GetResource("ui-core")
@ -22,13 +23,16 @@ local lobby = function (tab)
local launchButton = ui:Button(l.REQUEST_LAUNCH):SetFont("HEADING_LARGE")
launchButton.onClick:Connect(function ()
local crimes, fine = Game.player:GetCrime()
local crimes, fine = Game.player:GetCrimeOutstanding()
if not Game.player:HasCorrectCrew() then
MessageBox.Message(l.LAUNCH_PERMISSION_DENIED_CREW)
Comms.ImportantMessage(l.LAUNCH_PERMISSION_DENIED_CREW, station.label)
elseif fine > 0 then
MessageBox.Message(l.LAUNCH_PERMISSION_DENIED_FINED)
Comms.ImportantMessage(l.LAUNCH_PERMISSION_DENIED_FINED, station.label)
elseif not Game.player:Undock() then
MessageBox.Message(l.LAUNCH_PERMISSION_DENIED_BUSY)
Comms.ImportantMessage(l.LAUNCH_PERMISSION_DENIED_BUSY, station.label)
else
Game.SwitchView()

View File

@ -8,6 +8,7 @@ local Rand = import("Rand")
local Character = import("Character")
local Format = import("Format")
local utils = import("utils")
local Legal = import("Legal")
local InfoFace = import("ui/InfoFace")
local SmallLabeledButton = import("ui/SmallLabeledButton")
@ -16,14 +17,9 @@ local MessageBox = import("ui/MessageBox")
local ui = Engine.ui
local l = Lang.GetResource("ui-core")
local crimeStrings = {
TRADING_ILLEGAL_GOODS = l.TRADING_ILLEGAL_GOODS,
WEAPON_DISCHARGE = l.UNLAWFUL_WEAPONS_DISCHARGE,
PIRACY = l.PIRACY,
MURDER = l.MURDER,
}
local police = function (tab)
local station = Game.player:GetDockedWith()
local rand = Rand.New(util.hash_random(station.seed .. '-police', 2^31-1) - 1)
@ -32,26 +28,52 @@ local police = function (tab)
armour = true,
}, rand))
local crimes, fine = Game.player:GetCrime()
local crimes, fine = Game.player:GetCrimeOutstanding()
local tmp_table = {}
for k,v in pairs(crimes) do
table.insert(tmp_table,k)
end
local infoBox = ui:VBox(10)
if #crimes > 0 then
if #utils.build_array(pairs(crimes)) > 0 then
infoBox:PackEnd({
ui:Label(l.CRIMINAL_RECORD):SetFont("HEADING_LARGE"),
ui:Label(l.OUTSTANDING_FINES):SetFont("HEADING_LARGE"),
ui:VBox():PackEnd(
utils.build_table(utils.map(function (k,v) return k,crimeStrings[v] end, pairs(crimes)))
),
utils.build_table(utils.map(function (k,v)
return k, ui:Label(crimes[v].count.."\t"..Legal.CrimeType[v].name)
end, pairs(tmp_table)))),
})
end
local actionBox = ui:VBox()
infoBox:PackEnd(actionBox)
local past_crimes, stump = Game.player:GetCrimeRecord()
local tmp_table_old = {}
for k,v in pairs(past_crimes) do
table.insert(tmp_table_old, k)
print(v.count.."\t"..Legal.CrimeType[k].name) -- todo xxx
end
local grey = { r = 0.3, g = 0.3, b = 0.3}
local past_crimes_infoBox = ui:VBox(10)
if #utils.build_array(pairs(past_crimes)) > 0 then
past_crimes_infoBox:PackEnd({
ui:Label(l.CRIMINAL_RECORD):SetFont("HEADING_LARGE"):SetColor(grey),
ui:VBox():PackEnd(
utils.build_table(utils.map(function (k,v)
return k, ui:Label(past_crimes[v].count.."\t"..Legal.CrimeType[v].name):SetColor(grey)
end, pairs(tmp_table_old)))),
})
end
local function noBusiness ()
actionBox:Clear()
actionBox:PackEnd(l.WE_HAVE_NO_BUSINESS_WITH_YOU)
end
if fine == 0 then
noBusiness()
else
@ -73,7 +95,7 @@ local police = function (tab)
return
ui:Grid({48,4,48},1)
:SetColumn(0, {
infoBox
ui:VBox(50):PackEnd({infoBox, past_crimes_infoBox})
})
:SetColumn(2, {
face.widget

View File

@ -174,6 +174,16 @@ static int l_fac_police_name(lua_State *L)
return 1;
}
//preferred police ship model
static int l_fac_police_ship(lua_State *L)
{
Faction *fac = l_fac_check(L, 1);
std::string police_ship = luaL_checkstring(L, 2);
fac->police_ship = police_ship;
lua_settop(L, 1);
return 1;
}
//commodity legality
static int l_fac_illegal_goods_probability(lua_State *L)
{
@ -268,6 +278,7 @@ static luaL_Reg LuaFaction_meta[] = {
{ "expansionRate", &l_fac_expansionRate },
{ "military_name", &l_fac_military_name },
{ "police_name", &l_fac_police_name },
{ "police_ship", &l_fac_police_ship },
{ "illegal_goods_probability", &l_fac_illegal_goods_probability },
{ "colour", &l_fac_colour },
{ "add_to_factions", &l_fac_add_to_factions },

View File

@ -46,7 +46,7 @@ public:
std::string military_name; // "Space Defense Force", "Imperial Will Enforcement Division"...
//military logo
std::string police_name; // "Police", "Polizia Locale"...
std::string police_ship; // "kanara", "varada"...
//police logo
//goods/equipment availability (1-per-economy-type: aka agricultural, industrial, tourist, etc)

View File

@ -77,7 +77,6 @@ Game::Game(const SystemPath &path, double time) :
m_player->SetPosition(vector3d(0, 1.5*sbody->GetRadius(), 0));
m_player->SetVelocity(vector3d(0,0,0));
}
Polit::Init(m_galaxy);
CreateViews();
@ -168,9 +167,6 @@ m_forceTimeAccel(false)
for (Uint32 i = 0; i < hyperspaceCloudArray.size(); i++)
m_hyperspaceClouds.push_back(static_cast<HyperspaceCloud*>(Body::FromJson(hyperspaceCloudArray[i], 0)));
// system political stuff
Polit::FromJson(jsonObj, m_galaxy);
// views
LoadViewsFromJson(jsonObj);
@ -225,9 +221,6 @@ void Game::ToJson(Json::Value &jsonObj)
}
jsonObj["hyperspace_clouds"] = hyperspaceCloudArray; // Add hyperspace cloud array to supplied object.
// system political data (crime etc)
Polit::ToJson(jsonObj);
// views. must be saved in init order
m_gameViews->m_cpan->SaveToJson(jsonObj);
m_gameViews->m_sectorView->SaveToJson(jsonObj);

View File

@ -131,10 +131,6 @@ DECLARE_STRING(ALERT_CANCELLED)
DECLARE_STRING(SHIP_DETECTED_NEARBY)
DECLARE_STRING(DOWNGRADING_ALERT_STATUS)
DECLARE_STRING(LASER_FIRE_DETECTED)
DECLARE_STRING(TRADING_ILLEGAL_GOODS)
DECLARE_STRING(UNLAWFUL_WEAPONS_DISCHARGE)
DECLARE_STRING(PIRACY)
DECLARE_STRING(MURDER)
DECLARE_STRING(NO_ESTABLISHED_ORDER)
DECLARE_STRING(HARD_CAPITALIST)
DECLARE_STRING(CAPITALIST)
@ -151,7 +147,6 @@ DECLARE_STRING(MILITARY_DICTATORSHIP)
DECLARE_STRING(COMMUNIST)
DECLARE_STRING(PLUTOCRATIC_DICTATORSHIP)
DECLARE_STRING(VIOLENT_ANARCHY)
DECLARE_STRING(X_CANNOT_BE_TOLERATED_HERE)
DECLARE_STRING(SECTOR_X_Y_Z)
DECLARE_STRING(CURRENT_SYSTEM)
DECLARE_STRING(SELECTED_SYSTEM)
@ -219,7 +214,6 @@ DECLARE_STRING(SHIP_NEARBY)
DECLARE_STRING(DOCKING_CLEARANCE_EXPIRED)
DECLARE_STRING(MESSAGE_FROM_X)
DECLARE_STRING(SELECT_A_TARGET)
DECLARE_STRING(POLICE_SHIP_REGISTRATION)
DECLARE_STRING(CLEARANCE_ALREADY_GRANTED_BAY_N)
DECLARE_STRING(CLEARANCE_GRANTED_BAY_N)
DECLARE_STRING(CLEARANCE_DENIED_NO_BAYS)

View File

@ -204,25 +204,6 @@ void LuaConstants::Register(lua_State *l)
* experimental
*/
/*
* Constants: PolitCrime
*
* Crimes
*
* TRADING_ILLEGAL_GOODS - .
* WEAPON_DISCHARGE - .
* PIRACY - .
* MURDER - .
*
* Availability:
*
* alpha 10
*
* Status:
*
* experimental
*/
/*
* Constants: PolitEcon
*

View File

@ -239,6 +239,30 @@ static int l_faction_attr_police_name(lua_State *l)
return 1;
}
/*
* Attribute: policeShip
*
* The ships used by the police
*
* Availability:
*
* 2015 September
*
* Status:
*
* experimental
*/
static int l_faction_attr_police_ship(lua_State *l)
{
Faction *faction = LuaObject<Faction>::CheckFromLua(1);
if(faction->police_ship.empty())
faction->police_ship = "sinonatrix_police"; // set default ship
lua_pushlstring(l, faction->police_ship.c_str(), faction->police_ship.size());
return 1;
}
/*
* Attribute: colour
*
@ -283,6 +307,7 @@ template <> void LuaObject<Faction>::RegisterClass()
{ "radius", l_faction_attr_radius },
{ "militaryName", l_faction_attr_military_name },
{ "policeName", l_faction_attr_police_name },
{ "policeShip", l_faction_attr_police_ship },
{ "colour", l_faction_attr_colour },
{ 0, 0 }
};

View File

@ -5,7 +5,6 @@
#include "LuaUtils.h"
#include "LuaConstants.h"
#include "Player.h"
#include "Polit.h"
#include "Pi.h"
#include "Game.h"
#include "SectorView.h"
@ -24,66 +23,6 @@ static int l_player_is_player(lua_State *l)
return 1;
}
/*
* Method: AddCrime
*
* Add a crime to the player's criminal record
*
* > player:AddCrime(crime, fine)
*
* Parameters:
*
* crime - a <Constants.PolitCrime> string describing the crime
*
* fine - an amount to add to the player's fine
*
* Availability:
*
* alpha 10
*
* Status:
*
* stable
*/
static int l_player_add_crime(lua_State *l)
{
LuaObject<Player>::CheckFromLua(1); // check that the method is being called on a Player object
Sint64 crimeBitset = LuaConstants::GetConstantFromArg(l, "PolitCrime", 2);
Sint64 fine = Sint64(luaL_checknumber(l, 3) * 100.0);
Polit::AddCrime(crimeBitset, fine);
return 0;
}
// XXX temporary until crime is moved out to Lua properly
static int l_player_get_crime(lua_State *l)
{
LuaObject<Player>::CheckFromLua(1); // check that the method is being called on a Player object
Sint64 crimeBitset, fine;
Polit::GetCrime(&crimeBitset, &fine);
lua_newtable(l);
for (Sint64 i = 0; i < 4; i++) { // hardcoding 4 possible Polit::Crime flags
if (crimeBitset & (Sint64(1)<<i)) {
lua_pushstring(l, EnumStrings::GetString("PolitCrime", 1<<i));
lua_rawseti(l, -2, lua_rawlen(l, -2)+1);
}
}
lua_pushnumber(l, double(fine) * 0.01);
return 2;
}
static int l_player_clear_crime_fine(lua_State *l)
{
LuaObject<Player>::CheckFromLua(1); // check that the method is being called on a Player object
Sint64 crimeBitset, fine;
Polit::GetCrime(&crimeBitset, &fine);
Polit::AddCrime(0, -fine);
return 0;
}
/*
* Method: GetNavTarget
*
@ -278,10 +217,6 @@ template <> void LuaObject<Player>::RegisterClass()
static const luaL_Reg l_methods[] = {
{ "IsPlayer", l_player_is_player },
{ "AddCrime", l_player_add_crime },
{ "GetCrime", l_player_get_crime },
{ "ClearCrimeFine", l_player_clear_crime_fine },
{ "GetNavTarget", l_get_nav_target },
{ "SetNavTarget", l_set_nav_target },
{ "GetCombatTarget", l_get_combat_target },

View File

@ -13,7 +13,6 @@
#include "Ship.h"
#include "ShipCpanel.h"
#include "SpaceStation.h"
#include "PersistSystemData.h"
#include "Lang.h"
#include "StringF.h"
#include "Game.h"
@ -21,28 +20,6 @@
namespace Polit {
static PersistSystemData<Sint64> s_criminalRecord;
static PersistSystemData<Sint64> s_outstandingFine;
struct crime_t {
crime_t() : record(0), fine(0) {}
Sint64 record;
Sint64 fine;
};
static std::vector<crime_t> s_playerPerBlocCrimeRecord;
const char *crimeNames[64] = {
Lang::TRADING_ILLEGAL_GOODS,
Lang::UNLAWFUL_WEAPONS_DISCHARGE,
Lang::PIRACY,
Lang::MURDER
};
// in 1/100th credits, as all money is
static const Sint64 crimeBaseFine[64] = {
50000,
100000,
1000000,
1500000,
};
const char *s_econDesc[ECON_MAX] = {
Lang::NO_ESTABLISHED_ORDER,
Lang::HARD_CAPITALIST,
@ -77,148 +54,10 @@ static politDesc_t s_govDesc[GOV_MAX] = {
{ Lang::VIOLENT_ANARCHY, 2, ECON_NONE, fixed(90,100) },
};
void Init(RefCountedPtr<Galaxy> galaxy)
{
s_criminalRecord.Clear();
s_outstandingFine.Clear();
// setup the per faction criminal records
const Uint32 numFactions = galaxy->GetFactions()->GetNumFactions();
s_playerPerBlocCrimeRecord.clear();
s_playerPerBlocCrimeRecord.resize( numFactions );
}
void ToJson(Json::Value &jsonObj)
{
Json::Value politObj(Json::objectValue); // Create JSON object to contain polit data.
Json::Value criminalRecordObj(Json::objectValue); // Create JSON object to contain criminal record data.
s_criminalRecord.ToJson(criminalRecordObj);
politObj["criminal_record"] = criminalRecordObj; // Add criminal record object to polit object.
Json::Value outstandingFineObj(Json::objectValue); // Create JSON object to contain outstanding fine data.
s_outstandingFine.ToJson(outstandingFineObj);
politObj["outstanding_fine"] = outstandingFineObj; // Add outstanding fine object to polit object.
Json::Value crimeRecordArray(Json::arrayValue); // Create JSON array to contain crime record data.
for (Uint32 i = 0; i < s_playerPerBlocCrimeRecord.size(); i++)
{
Json::Value crimeRecordArrayEl(Json::objectValue); // Create JSON object to contain crime record element.
crimeRecordArrayEl["record"] = SInt64ToStr(s_playerPerBlocCrimeRecord[i].record);
crimeRecordArrayEl["fine"] = SInt64ToStr(s_playerPerBlocCrimeRecord[i].fine);
crimeRecordArray.append(crimeRecordArrayEl); // Append crime record object to array.
}
politObj["crime_record"] = crimeRecordArray; // Add crime record array to polit object.
jsonObj["polit"] = politObj; // Add polit object to supplied object.
}
void FromJson(const Json::Value &jsonObj, RefCountedPtr<Galaxy> galaxy)
{
Init(galaxy);
if (!jsonObj.isMember("polit")) throw SavedGameCorruptException();
Json::Value politObj = jsonObj["polit"];
if (!politObj.isMember("criminal_record")) throw SavedGameCorruptException();
if (!politObj.isMember("outstanding_fine")) throw SavedGameCorruptException();
if (!politObj.isMember("crime_record")) throw SavedGameCorruptException();
Json::Value criminalRecordObj = politObj["criminal_record"];
PersistSystemData<Sint64>::FromJson(criminalRecordObj, &s_criminalRecord);
Json::Value outstandingFineObj = politObj["outstanding_fine"];
PersistSystemData<Sint64>::FromJson(outstandingFineObj, &s_outstandingFine);
Json::Value crimeRecordArray = politObj["crime_record"];
if (!crimeRecordArray.isArray()) throw SavedGameCorruptException();
assert(s_playerPerBlocCrimeRecord.size() == crimeRecordArray.size());
for (Uint32 i = 0; i < s_playerPerBlocCrimeRecord.size(); i++)
{
Json::Value crimeRecordArrayEl = crimeRecordArray[i];
if (!crimeRecordArrayEl.isMember("record")) throw SavedGameCorruptException();
if (!crimeRecordArrayEl.isMember("fine")) throw SavedGameCorruptException();
s_playerPerBlocCrimeRecord[i].record = StrToSInt64(crimeRecordArrayEl["record"].asString());
s_playerPerBlocCrimeRecord[i].fine = StrToSInt64(crimeRecordArrayEl["fine"].asString());
}
}
fixed GetBaseLawlessness(GovType gov) {
return s_govDesc[gov].baseLawlessness;
}
/* The drawbacks of stuffing stuff into integers */
static int GetCrimeIdxFromEnum(enum Crime crime)
{
assert(crime);
for (int i = 0; i < 64; ++i) {
if (crime & 1) return i;
crime = Crime(crime >> 1); // cast needed because this gets promoted to 'int'
}
return 0;
}
void NotifyOfCrime(Ship *s, enum Crime crime)
{
// ignore crimes of NPCs for the time being
if (!s->IsType(Object::PLAYER)) return;
// find nearest starport to this evil criminal
SpaceStation *station = static_cast<SpaceStation*>(Pi::game->GetSpace()->FindNearestTo(s, Object::SPACESTATION));
if (station) {
double dist = station->GetPositionRelTo(s).Length();
// too far away for crime to be noticed :)
if (dist > 100000.0) return;
const int crimeIdx = GetCrimeIdxFromEnum(crime);
Pi::game->log->Add(station->GetLabel(),
stringf(Lang::X_CANNOT_BE_TOLERATED_HERE, formatarg("crime", crimeNames[crimeIdx])));
float lawlessness = Pi::game->GetSpace()->GetStarSystem()->GetSysPolit().lawlessness.ToFloat();
Sint64 oldCrimes, oldFine;
GetCrime(&oldCrimes, &oldFine);
Sint64 newFine = std::max(1, 1 + int(crimeBaseFine[crimeIdx] * (1.0-lawlessness)));
// don't keep compounding fines (maybe should for murder, etc...)
if ( (!(crime & CRIME_MURDER)) && (newFine < oldFine) ) newFine = 0;
AddCrime(crime, newFine);
}
}
void AddCrime(Sint64 crimeBitset, Sint64 addFine)
{
const Faction *faction = (Pi::game->GetSpace()->GetStarSystem()->GetFaction());
if (faction->IsValid()) {
s_playerPerBlocCrimeRecord[faction->idx].record |= crimeBitset;
s_playerPerBlocCrimeRecord[faction->idx].fine += addFine;
} else {
SystemPath path = Pi::game->GetSpace()->GetStarSystem()->GetPath();
Sint64 record = s_criminalRecord.Get(path, 0);
record |= crimeBitset;
s_criminalRecord.Set(path, crimeBitset);
s_outstandingFine.Set(path, s_outstandingFine.Get(path, 0) + addFine);
}
}
void GetCrime(Sint64 *crimeBitset, Sint64 *fine)
{
// no crime in hyperspace :)
if (Pi::game->IsHyperspace()) {
*crimeBitset = 0;
*fine = 0;
return ;
}
const Faction *faction = Pi::game->GetSpace()->GetStarSystem()->GetFaction();
if (faction->IsValid()) {
*crimeBitset = s_playerPerBlocCrimeRecord[faction->idx].record;
*fine = s_playerPerBlocCrimeRecord[faction->idx].fine;
} else {
SystemPath path = Pi::game->GetSpace()->GetStarSystem()->GetPath();
*crimeBitset = s_criminalRecord.Get(path, 0);
*fine = s_outstandingFine.Get(path, 0);
}
}
}
const char *SysPolit::GetGovernmentDesc() const

View File

@ -5,8 +5,6 @@
#define _POLIT_H
#include "galaxy/Economy.h"
#include "Serializer.h"
#include "json/json.h"
class Galaxy;
class StarSystem;
@ -14,13 +12,6 @@ class SysPolit;
class Ship;
namespace Polit {
enum Crime { // <enum scope='Polit' name=PolitCrime prefix=CRIME_ public>
CRIME_TRADING_ILLEGAL_GOODS = (1<<0),
CRIME_WEAPON_DISCHARGE = (1<<1),
CRIME_PIRACY = (1<<2),
CRIME_MURDER = (1<<3),
};
enum PolitEcon { // <enum scope='Polit' name=PolitEcon prefix=ECON_ public>
ECON_NONE,
ECON_VERY_CAPITALIST,
@ -53,15 +44,7 @@ namespace Polit {
GOV_RAND_MAX = GOV_MAX-1, // <enum skip>
};
void NotifyOfCrime(Ship *s, enum Crime c);
void Init(RefCountedPtr<Galaxy> galaxy);
void ToJson(Json::Value &jsonObj);
void FromJson(const Json::Value &jsonObj, RefCountedPtr<Galaxy> galaxy);
void AddCrime(Sint64 crimeBitset, Sint64 addFine);
void GetCrime(Sint64 *crimeBitset, Sint64 *fine);
fixed GetBaseLawlessness(GovType gov);
extern const char *crimeNames[64];
}
class SysPolit {

View File

@ -434,16 +434,10 @@ bool Ship::OnDamage(Object *attacker, float kgDamage, const CollisionContact& co
if (attacker) {
if (attacker->IsType(Object::BODY))
LuaEvent::Queue("onShipDestroyed", this, dynamic_cast<Body*>(attacker));
if (attacker->IsType(Object::SHIP))
Polit::NotifyOfCrime(static_cast<Ship*>(attacker), Polit::CRIME_MURDER);
}
Explode();
} else {
if (attacker && attacker->IsType(Object::SHIP))
Polit::NotifyOfCrime(static_cast<Ship*>(attacker), Polit::CRIME_PIRACY);
if (Pi::rng.Double() < kgDamage)
Sfx::Add(this, Sfx::TYPE_DAMAGE);
@ -931,7 +925,6 @@ void Ship::FireWeapon(int num)
Projectile::Add(this, lifespan, damage, length, width, mining, c, pos, baseVel, dirVel);
}
Polit::NotifyOfCrime(this, Polit::CRIME_WEAPON_DISCHARGE);
Sound::BodyMakeNoise(this, "Pulse_Laser", 1.0f);
lua_pop(prop.GetLua(), 1);
LuaEvent::Queue("onShipFiring", this);

View File

@ -74,7 +74,6 @@ void SpaceStation::SaveToJson(Json::Value &jsonObj, Space *space)
spaceStationObj["ports"] = portArray; // Add port array to space station object.
spaceStationObj["index_for_system_body"] = space->GetIndexForSystemBody(m_sbody);
spaceStationObj["num_police_docked"] = m_numPoliceDocked;
spaceStationObj["door_animation_step"] = DoubleToStr(m_doorAnimationStep);
spaceStationObj["door_animation_state"] = DoubleToStr(m_doorAnimationState);
@ -95,7 +94,6 @@ void SpaceStation::LoadFromJson(const Json::Value &jsonObj, Space *space)
if (!spaceStationObj.isMember("ship_docking")) throw SavedGameCorruptException();
if (!spaceStationObj.isMember("ports")) throw SavedGameCorruptException();
if (!spaceStationObj.isMember("index_for_system_body")) throw SavedGameCorruptException();
if (!spaceStationObj.isMember("num_police_docked")) throw SavedGameCorruptException();
if (!spaceStationObj.isMember("door_animation_step")) throw SavedGameCorruptException();
if (!spaceStationObj.isMember("door_animation_state")) throw SavedGameCorruptException();
@ -156,7 +154,6 @@ void SpaceStation::LoadFromJson(const Json::Value &jsonObj, Space *space)
}
m_sbody = space->GetSystemBodyByIndex(spaceStationObj["index_for_system_body"].asUInt());
m_numPoliceDocked = spaceStationObj["num_police_docked"].asInt();
m_doorAnimationStep = StrToDouble(spaceStationObj["door_animation_step"].asString());
m_doorAnimationState = StrToDouble(spaceStationObj["door_animation_state"].asString());
@ -177,7 +174,6 @@ void SpaceStation::PostLoadFixup(Space *space)
SpaceStation::SpaceStation(const SystemBody *sbody): ModelBody()
{
m_sbody = sbody;
m_numPoliceDocked = Pi::rng.Int32(3,10);
m_oldAngDisplacement = 0.0;
@ -541,7 +537,6 @@ void SpaceStation::PositionDockedShip(Ship *ship, int port) const
void SpaceStation::StaticUpdate(const float timeStep)
{
DoLawAndOrder(timeStep);
DockingUpdate(timeStep);
m_navLights->Update(timeStep);
}
@ -681,47 +676,6 @@ vector3d SpaceStation::GetTargetIndicatorPosition(const Frame *relTo) const
return GetInterpPositionRelTo(relTo);
}
// XXX this whole thing should be done by Lua
void SpaceStation::DoLawAndOrder(const double timeStep)
{
Sint64 fine, crimeBitset;
Polit::GetCrime(&crimeBitset, &fine);
if (Pi::player->GetFlightState() != Ship::DOCKED
&& m_numPoliceDocked
&& (fine > 1000)
&& (GetPositionRelTo(Pi::player).Length() < 100000.0)) {
Ship *ship = new Ship(ShipType::POLICE);
int port = GetFreeDockingPort(ship);
// at 60 Hz updates (ie, 1x time acceleration),
// this spawns a police ship with probability ~0.83% each frame
// This makes it unlikely (but not impossible) that police will spawn on top of each other
// the expected number of game-time seconds between spawns: 120 (2*60 Hz)
// variance is quite high though
if (port != -1 && 2.0*Pi::rng.Double() < timeStep) {
m_numPoliceDocked--;
// Make police ship intent on killing the player
ship->AIKill(Pi::player);
ship->SetFrame(GetFrame());
ship->SetDockedWith(this, port);
Pi::game->GetSpace()->AddBody(ship);
ship->SetLabel(Lang::POLICE_SHIP_REGISTRATION);
lua_State *l = Lua::manager->GetLuaState();
LUA_DEBUG_START(l);
pi_lua_import(l, "Equipment");
LuaTable equip(l, -1);
LuaTable misc = equip.Sub("misc");
LuaObject<Ship>::CallMethod(ship, "AddEquip", equip.Sub("laser").Sub("pulsecannon_dual_1mw"));
LuaObject<Ship>::CallMethod(ship, "AddEquip", misc.Sub("laser_cooling_booster"));
LuaObject<Ship>::CallMethod(ship, "AddEquip", misc.Sub("atmospheric_shielding"));
lua_pop(l, 6);
LUA_DEBUG_END(l, 0);
ship->UpdateEquipStats();
} else {
delete ship;
}
}
}
bool SpaceStation::IsPortLocked(const int bay) const
{
for (auto &bayIter : m_ports ) {

View File

@ -110,7 +110,6 @@ private:
const SpaceStationType *m_type;
const SystemBody *m_sbody;
CityOnPlanet *m_adjacentCity;
int m_numPoliceDocked;
enum { NUM_STATIC_SLOTS = 4 };
bool m_staticSlot[NUM_STATIC_SLOTS];

View File

@ -53,14 +53,6 @@ const struct EnumItem ENUM_PhysicsObjectType[] = {
{ 0, 0 },
};
const struct EnumItem ENUM_PolitCrime[] = {
{ "TRADING_ILLEGAL_GOODS", int(Polit::CRIME_TRADING_ILLEGAL_GOODS) },
{ "WEAPON_DISCHARGE", int(Polit::CRIME_WEAPON_DISCHARGE) },
{ "PIRACY", int(Polit::CRIME_PIRACY) },
{ "MURDER", int(Polit::CRIME_MURDER) },
{ 0, 0 },
};
const struct EnumItem ENUM_PolitEcon[] = {
{ "NONE", int(Polit::ECON_NONE) },
{ "VERY_CAPITALIST", int(Polit::ECON_VERY_CAPITALIST) },
@ -457,7 +449,6 @@ const struct EnumTable ENUM_TABLES[] = {
{ "DetailLevel", ENUM_DetailLevel },
{ "FileSystemRoot", ENUM_FileSystemRoot },
{ "PhysicsObjectType", ENUM_PhysicsObjectType },
{ "PolitCrime", ENUM_PolitCrime },
{ "PolitEcon", ENUM_PolitEcon },
{ "PolitGovType", ENUM_PolitGovType },
{ "ShipFlightState", ENUM_ShipFlightState },
@ -500,7 +491,6 @@ const struct EnumTable ENUM_TABLES_PUBLIC[] = {
{ "DetailLevel", ENUM_DetailLevel },
{ "FileSystemRoot", ENUM_FileSystemRoot },
{ "PhysicsObjectType", ENUM_PhysicsObjectType },
{ "PolitCrime", ENUM_PolitCrime },
{ "PolitEcon", ENUM_PolitEcon },
{ "PolitGovType", ENUM_PolitGovType },
{ "ShipFlightState", ENUM_ShipFlightState },

View File

@ -13,7 +13,6 @@ struct EnumTable { const char *name; const EnumItem *first; };
extern const struct EnumItem ENUM_DetailLevel[];
extern const struct EnumItem ENUM_FileSystemRoot[];
extern const struct EnumItem ENUM_PhysicsObjectType[];
extern const struct EnumItem ENUM_PolitCrime[];
extern const struct EnumItem ENUM_PolitEcon[];
extern const struct EnumItem ENUM_PolitGovType[];
extern const struct EnumItem ENUM_ShipFlightState[];