Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import mmap
- import math
- import sys, getopt
- our_city = "Tingis"
- terrain_offset = 0x2009B
- def writeLong(value, len):
- return (value).to_bytes(len,byteorder='little')
- def writeShort(value, len):
- return (value).to_bytes(len,byteorder='big')
- def getQuotaOffset(city, good):
- offset = partners_offset + (partners[city] * 0x40) + (goods[good] * 0x04)
- return offset
- def getCityOffset(city):
- offset = cities_offset + 0x03 # city name id
- # Check if we found the city, since they aren't in order
- for i in range(28): # 0 to 27
- offset += 66
- mm.seek(offset)
- if mm.read_byte() == cities[city]:
- break
- ## then add 6 to get to buy flags (16 bytes) and then sell flags
- return offset
- def setTradeRoutePrice(city, price):
- offset = getCityOffset(city) - 0x03 + 0x26
- mm.seek(offset)
- mm.write( writeLong(price, 2) )
- def changeGoodsPrices(good, multi, type):
- # Type 0 = both, 1 = only buyers, 2 = only sellers
- offset = 0x125C3C
- mm.seek(offset)
- mm.seek(goods[good] * 0x08, 1)
- for i in range(2):
- if i == 0 and type == "sellers":
- mm.seek(4,1)
- continue
- if i == 1 and type == "buyers":
- continue
- price = math.floor(int(mm.read_byte()) * multi)
- mm.seek(-1,1)
- mm.write( writeLong(price, 4) )
- # print(mm.read_byte())
- def setLocalProduction(good, value):
- offset = getCityOffset(our_city) # cur byte is after city name
- mm.seek(2 + 16, 1)
- mm.seek(goods[good], 1)
- mm.write_byte(value)
- with open("D:\Games\Caesar 3 Julius\Test.c3u", "r+b") as f:
- # memory-map the file, size 0 means whole file
- mm = mmap.mmap(f.fileno(), 0)
- goods = {
- "wheat": 0x01,
- "vegetables": 0x02,
- "fruits": 0x03,
- "olives": 0x04,
- "vines": 0x05,
- "meat": 0x06,
- "wine": 0x07,
- "oil": 0x08,
- "iron": 0x09,
- "timber": 0x0A,
- "clay": 0x0B,
- "marble": 0x0C,
- "weapons": 0x0D,
- "furniture": 0x0E,
- "pottery": 0x0F,
- }
- partners_offset = 0x131702
- partners = {
- "Carthago Nova" : 0x01,
- "Caesarea" : 0x02,
- "Volubilis" : 0x03,
- "Valentia" : 0x04,
- "Tarraco" : 0x05,
- }
- cities_offset = 0x12516C
- cities = {
- "Roma" : 0x00,
- "Tarentum" : 0x01,
- "Capua" : 0x02,
- "Brundisium" : 0x03,
- "Mediolanum" : 0x04,
- "Carthago Nova" : 0x05,
- "Carthago" : 0x06,
- "Tarraco" : 0x07,
- "Athenae" : 0x08,
- "Pergamum" : 0x09,
- "Syracusae" : 0x0A,
- "Toletum" : 0x0B,
- "Tarsus" : 0x0C,
- "Leptis Magna" : 0x0D,
- "Tingis" : 0x0E,
- "Corinthus" : 0x0F,
- "Valentia" : 0x10,
- "Lindum" : 0x19,
- "Calleva" : 0x1A,
- "Lutetia" : 0x1B,
- "Caesarea" : 0x1F,
- "Augusta Trevorum" : 0x21,
- "Volubilis" : 0x23,
- "Londinium" : 0x24,
- }
- buildings = {
- "farms" : 1,
- }
- opts, args = getopt.getopt(sys.argv[1:],"wf")
- for opt, arg in opts:
- if opt in ['-w']:
- print("warehouse only")
- # Erase cliff tiles
- eraseTiles = [0x24593, 0x26B37, 0x26317, 0x25F49, 0x28C0F, 0x29BD7]
- for pos in eraseTiles:
- mm.seek(pos)
- mm.write_byte(0x00)
- # Add marble to warehouse
- warehouse = 0xE695A
- mm.seek(warehouse)
- mm.seek(0x0C,1)
- mm.write_byte(0x0C)
- mm.seek(warehouse)
- mm.seek(0x34,1)
- mm.write_byte(0x0C) # 12 marble in 1 tile why not
- # This replaces ramps with roads. Basically instead of a ramp being a 2x2 road, it becomes a 1x2 road
- rampscount = 0
- ramps = []
- mm.seek(terrain_offset) #2009B
- # elevation: 59b40
- rampBot = "0004"
- rampsBot = "00040004"
- rampTop = "0006"
- rampsTop = "00060006"
- mm.seek(terrain_offset-1)
- for i in range(int(162*162*2)):
- byte = mm.read(4)
- # find bottom of stairs - bottom of stairs
- # turn into road - empty
- if byte.hex() == rampsBot:
- # print(byte)
- mm.seek(-4,1)
- # bytes have to be written swapped
- mm.write_byte(0x40)
- mm.write_byte(0x00)
- mm.write_byte(0x00)
- mm.write_byte(0x00)
- print(terrain_offset + (i*2))
- rampscount += 1
- print("ramp")
- mm.seek(-2,1)
- print(rampscount)
- mm.seek(terrain_offset-1)
- for i in range(int(162*162*2)):
- byte = mm.read(4)
- # find top of stairs - top of stairs
- # turn into road w/elevation - elevation
- if byte.hex() == rampsTop:
- mm.seek(-4,1)
- # bytes have to be written swapped
- mm.write_byte(0x40)
- mm.write_byte(0x02)
- mm.write_byte(0x00)
- mm.write_byte(0x02)
- print(terrain_offset + (i*2))
- print("ramp elevated")
- mm.seek(-2,1)
- mm.seek(terrain_offset-1)
- for i in range(int(162*162*2)):
- byte = mm.read(4)
- # find bottom of stairs - top of stairs
- # turn into road w/elevation - elevation
- if byte.hex() == "00040006":
- mm.seek(-4,1)
- mm.seek(324,1)
- byte = mm.read(2)
- # if the tile on the next row is also a ramp, this tile becomes just a hill
- if byte.hex() == rampBot or byte.hex() == rampTop:
- mm.seek(-2,1)
- mm.seek(-324,1)
- # bytes have to be written swapped
- mm.write_byte(0x00)
- mm.write_byte(0x00)
- mm.write_byte(0x00)
- mm.write_byte(0x02)
- print("ramp low to high with other piece of ramp in next row")
- else:
- mm.seek(-2,1)
- mm.seek(-324,1)
- # bytes have to be written swapped
- mm.write_byte(0x40)
- mm.write_byte(0x00)
- mm.write_byte(0x40)
- mm.write_byte(0x02)
- print("ramp low to high with nothing next row")
- mm.seek(-2,1)
- mm.seek(terrain_offset-1)
- for i in range(int(162*162*2)):
- byte = mm.read(4)
- if byte.hex() == "00060004":
- mm.seek(-4,1)
- mm.seek(324,1)
- byte = mm.read(2)
- # if the tile on the next row is also a ramp, this tile becomes just a hill
- if byte.hex() == rampTop or byte.hex() == rampBot:
- mm.seek(-2,1)
- mm.seek(-324,1)
- # bytes have to be written swapped
- mm.write_byte(0x40)
- mm.write_byte(0x02)
- mm.write_byte(0x40)
- mm.write_byte(0x00)
- print("ramp high to low with other piece of ramp in next row")
- else:
- mm.seek(-2,1)
- mm.seek(-324,1)
- # bytes have to be written swapped
- mm.write_byte(0x00)
- mm.write_byte(0x02)
- mm.write_byte(0x00)
- mm.write_byte(0x00)
- print("ramp high to low with nothing next row")
- mm.seek(-2,1)
- # print("found %d ramps" % rampscount)
- if opt == '-f':
- print("finish")
- # Reset money to 5k
- mm.seek(0xE218C)
- mm.write_byte(0x88)
- mm.write_byte(0x13)
- mm.seek(0xE4CFC)
- mm.write_byte(0x88)
- mm.write_byte(0x13)
- # Disable buildings
- mm.seek(0x126342) # Fort
- mm.write_byte(0x00)
- mm.seek(0x12634A) # Large Temple
- mm.write_byte(0x00)
- # Burn Mars large temple (build first after warehouse)
- mm.seek(0xE6D5B)
- mm.seek(0x3F, 1)
- mm.write_byte(0x64) # 100 fire rate
- # Sets the next 5 buildings to never burn or collapse
- mm.seek(0xE6D5A)
- mm.seek(0x44, 1)
- for n in range(5):
- mm.seek(0x80, 1)
- mm.write_byte(0x01)
- mm.seek(-1, 1)
- # Change favor to 35
- mm.seek(0xE6314)
- mm.write_byte(35)
- # Change savings to 1500
- mm.seek(0xE6450)
- mm.write_byte(0xDC)
- mm.write_byte(0x05)
- # Makes all goods 20% less profitable
- for g, h in goods.items():
- changeGoodsPrices(g, 1.0 + 0.20, "buyers")
- changeGoodsPrices(g, 1.0 - 0.20, "sellers")
- # Remove unwanted quotas
- mm.seek(getQuotaOffset("Caesarea", "marble"))
- mm.write_byte(0x00)
- mm.seek(getQuotaOffset("Carthago Nova", "timber"))
- mm.write_byte(0x00)
- mm.seek(getQuotaOffset("Valentia", "timber"))
- mm.write_byte(0x00)
- mm.seek(getQuotaOffset("Tarraco", "timber"))
- mm.write_byte(0x00)
- mm.seek(getQuotaOffset("Volubilis", "iron"))
- mm.write_byte(0x0F)
- # changeGoodsPrices("vegetables", 1.20, "both")
- # changeGoodsPrices("iron", 0.875, "both")
- # changeGoodsPrices("pottery", 0.85, "both")
- # changeGoodsPrices("marble", 1.20, "both")
- # changeGoodsPrices("furniture", 0.75, "both")
- # changeGoodsPrices("timber", 0.5, "sellers")
- setTradeRoutePrice("Carthago Nova", 2100)
- setTradeRoutePrice("Caesarea", 800)
- setTradeRoutePrice("Volubilis", 2000)
- setTradeRoutePrice("Valentia", 900)
- setTradeRoutePrice("Tarraco", 2500)
- setLocalProduction("timber", 1)
- # close the map
- mm.close()
Advertisement
Add Comment
Please, Sign In to add comment