PDA

View Full Version : Craft The World - what a game!



ReneMiner
09-01-2015, 11:00
Craft The World is a nice little role-playing-management-survival-sandbox-game which i like very much.

It's still in beta-phase - even though i played it already more than 1000 hours. I'm as addicted to this game as to thinBasic.

I combined both and created some "tool" for this game- not for modifying data to cheat but to balance some stuff.

A calculator for Grunts Shop! - written in thinBasic- that's why it ends up here... ;)



Going from the prices that Grunt would pay for natural resources the prices of all products get calculated from the cost of the required resources + manufacturing-cost, including technology-toll, Grunt will add some percents as a profit for himself and of course- there's the tax to pay!

The script loads CraftTheWorld\data -files:
craft_resources.xml
recipes.xml
default_techTree.csv

without having access to this data the program won't run!

It's able to save changed data as new files only- so no overwriting of existing data.

The only parameters to change for all resources are shop_cost and shop_count - for recipes there's only possible to change what crafting-station is required to craft the product and to adjust the amount of products crafted at once.
It's not intended to change recipes or any other data and it allows to set some imaginary global values for toll, taxes, profit & usage-fees for crafting stations that will be included into the calculation.

It will only calculate what prices were adequate and tell a Brutto-value - what price Grunt has to ask for to cover his expenses and get his profit - it will not change them by itself - but for a help it lists the difference of asked price and current sales price.

Because i have no idea about unicode the russian comments are not readeable any more in the saved data and it's probably a better idea to enter the calculated prices with some other software into the real game-data - else the game complains those files being corrupted sometimes when using an older savegame.

The intentions are very simple:

Let the shop have reasoneable prices. Eliminate all current "bargains", check overpriced items.

Excuse the condition - the executeable does not look as the scripted version - for the script to run you will need a thinBasic-version above 1.9.8, for the executeable you'lll need windows.

Oh yes, and for those who don't know Craft The World - can check it out on Steam (http://steamcommunity.com/app/248390?l)

ErosOlmi
09-01-2015, 15:31
Hi Rene,

sorry but I'm blocked at the beginning when it asks for the folder where (I presume) to find data.
What I need to specify? What files are needed?

Thanks
Eros

Petr Schreiber
09-01-2015, 20:21
Rene,

this is hardcore approach to gaming, I like the idea of script aided gaming a lot :D


Petr

ReneMiner
10-01-2015, 00:16
oh Eros- if you have the game, assumed "C:\Program Files (x86)\Steam\SteamApps\common\CraftTheWorld\" then you'll find in there some Main.pak,
have to rename this alike "xMain.pak" before, then use 7z and unpack it at same location ... thereafter you can modify and play from unpacked data,

anyway this script is meant as an idea for the developers of the game (i linked it in CTW-Forum (http://crafttheworld.com/forum/index.php?topic=35937.0)) because prices in the shop are let's say "not all that reasonable and understandeable"

ReneMiner
10-01-2015, 14:58
...just mentioning 7z, i know there's some command-line-version on sourceforge somewhere-

i wonder if it were possible to let thinBasic call 7z-functionalities somehow so i would not need to unpack manually just to read the data... i smell a new module...

ErosOlmi
10-01-2015, 16:28
If I can find a 7Z SDK standard DLL, I can wrap some of the commands but actually I cannot find one, just COM libraries.

In the meantime you can install (if not yet) 7Z from http://www.7-zip.org/ and use its command line application with shell commands.

ReneMiner
11-01-2015, 00:52
and however - for those who don't have the game but want to try out the script - i modified some game-data , i.e. prices mostly, production-requirements (barrels & windows) and count of crafted items for clay & leather-gear.

So attached the prices as i would set them in the game - calculated using the script above - only used higher fees than default for smithys (0.66) and workshop (0.80)

Do not place this data next to the calculator but have it in a seperate folder please.

EDIT:attachement removed (game version changed in the meantime)

ErosOlmi
11-01-2015, 08:25
Thanks René, now I got it.

Thanks to this script I resolved a weird GPF occurring in UI function Dialog_BrowseForFolder. Fix will be present in next release.

And my compliment for the hard job you have done. Reading that XML data is not a simple task and the User Interface is very nice constructed and handled.

ReneMiner
11-01-2015, 10:05
... Reading that XML data is not a simple task and the User Interface is very nice constructed and handled.

oh please- thinBasic does the reading in one call, thinCore-string-functions do the rest and UI leaves me no other possibility than using it the way it works :D

ReneMiner
28-02-2015, 11:21
It might appear as a cheat - so call it "Trainer"

You need the Steam-Version of Craft The World on Windows-PC

The attached program will set your Mana-Regeneration-Time to intervals of 30 instead of 180 seconds.

-download the attachement and unzip
-run "manaRegen30.exe"
-play the game


Run this program again to restore the original game.

Its also possible to use this with Pete's Improvement-Mod. The mod has to be installed in advance then.


After an update of the game you might want to apply 30-seconds regeneration too.
In order to do this you MUST delete the obsolete backup (original_Main.pak) of your old Main.pak before you run this program

ReneMiner
28-02-2015, 20:12
thinBasic is so cool, it can unpack the game data, exchange values, repack the game data to a package (129MB) that is compressed 10% smaller than the original (142MB) and the game still runs! And all that without the need of any additional software nor libraries. UNBELIEVEABLE :D

Petr Schreiber
01-03-2015, 00:39
Hell yeah, I am happy you feel the power :drink:

ReneMiner
01-03-2015, 09:17
For the nosy audience: this is the script.
It won't work if you don't have the game, but it contains 3 useful functions (2 to call) as

Dir_Kill()
which will actually kill a directory with all it's content
(Dir_Remove only removes completely empty directories)

ZLib_PackFolder()
which will create a zip-file from a folder and all its content in one call

ZLib_AddSubdir()
gets called initially by ZLib_PackFolder on the parenting folder and
will add a specified folder and it's content to a zip-archive
(usually user does not call this)





Uses "Console", "FILE", "ZLib","UI"

' ---------------------------------------------------------------------

Function ZLib_PackFolder(ByVal sFolder As String, _
Optional ByVal sZipfilename As String, _
ByVal lFileTypes As Long = %FILE_NORMAL
) As Boolean
' ---------------------------------------------------------------------

' this function to make a zip from a complete folder
' sFolder: full path to the folder to pack as zip

' sZipfilename: full path & filename
' if omitted the folders name
' will be taken and ".zip" gets appended

' lFileTypes: combination of one or more FILE-module-equates
' only these are accepted/make sense:
' %FILE_NORMAL
' %FILE_READONLY
' %FILE_HIDDEN
' %FILE_SYSTEM
' %FILE_ARCHIVE

' it will pack a complete folder in one go
' -existing old zip-file will be deleted-
' this is NOT to ADD anything

Local lCheck As Long

If Not DIR_Exists(sFolder) Then Return FALSE

If Len(sZipFilename) = 0 Then
sZipFilename = Trim$(sFolder, "\") & ".zip"
EndIf
If RIGHT$(sFolder, 1) <> "\" Then
sFolder &= "\"
EndIf

If FILE_Exists(sZipFilename) Then
FILE_Kill(sZipfilename)
EndIf

' local check for valid flagged filetypes:
If (lFileTypes And %FILE_NORMAL) Then lCheck = %FILE_NORMAL
If (lFileTypes And %FILE_READONLY) Then lCheck = lCheck Or %FILE_READONLY
If (lFileTypes And %FILE_HIDDEN) Then lCheck = lCheck Or %FILE_HIDDEN
If (lFileTypes And %FILE_SYSTEM) Then lCheck = lCheck Or %FILE_SYSTEM
If (lFileTypes And %FILE_ARCHIVE) Then lCheck = lCheck Or %FILE_ARCHIVE


' start with the initial directory:
ZLib_AddSubDir(sZipfilename, sFolder, lCheck)

' close the zip finally
ZLib_AddEx(sZipfilename, "", %ZLIB_CLOSE)
' (ZLib_AddEx: helpfile is wrong here, it must be %ZLIB_, not %ZIP_)

' do we have data?
Function = (FILE_Size(sZipFilename) > 0)

End Function

' ---------------------------------------------------------------------
Function ZLib_AddSubDir(ByVal sZipfilename As String, _
ByVal sDir As String, _
ByVal lFileTypes As Long )
' ---------------------------------------------------------------------

' this function will add a subdir and all of its content
' it gets called ' from the function above if all is ok and then
' calls itself until all data is added to the zip

' it will not copy empty directories into a zip !

Local sFile() As String
Local sPath() As String
Local nFiles As Long = DIR_ListArray(sFile, sDir, "*.*", lFileTypes )
Local nDirs As Long = DIR_ListArray(sPath, sDir, "*", %FILE_SUBDIR )
Local i As Long

If nFiles Then
For i = 1 To nFiles
ZLib_AddEx(sZIPFileName, sDir & sFile(i), %ZLIB_REL_PATH )
Next
EndIf

' calls itself:
If nDirs Then
For i = 1 To nDirs
ZLib_AddSubDir(sZipFilename, sDir & sPath(i) & "\", lFileTypes )
Next
EndIf


End Function

'-----------------------------------------------------------------
Function DIR_Kill(ByVal sPath As String)

If RIGHT$(sPath, 1 ) <> "\" Then sPath &= "\"

Local sSubdir() As String
Local sFiles() As String
Local Index As Long

Local lDirs As Long = DIR_ListArray(sSubDir, sPath, "*", %FILE_SUBDIR)

Local lFiles As Long = DIR_ListArray(sFiles, sPath, "*", %FILE_NORMAL _
| %FILE_READONLY _ |
| %FILE_HIDDEN _
| %FILE_SYSTEM _
| %FILE_ARCHIVE )

If lFiles Then
For Index = 1 To lFiles
FILE_Kill( sPath & sFiles(Index) )
Next
EndIf

If lDirs Then
For Index = 1 To lDirs
Dir_Kill(sPath & sSubdir(Index))
Next
EndIf

DIR_Remove(sPath)

End Function


String sWorkingpath = APP_ScriptPath & "main\"
String sGamepath = "C:\Program Files (x86)\Steam\SteamApps\common\CraftTheWorld"
String sWorld, sLine(), sCheck, sValue
Long nLines, lLine, lPos
Byte bChar

While Not DIR_Exists(sGamepath)
' uses UI-module only for this one request- and only in certain cases...

sGamepath = Dialog_BrowseForFolder(0, "Please select your CraftTheWorld-folder", "C:\", TRUE)

If Not DIR_Exists(sGamepath) Then
Select Case MsgBox(0, "Invalid path specified. Retry to select another path, Cancel to quit",%MB_RETRYCANCEL, "ctw-modmana30")
Case %IDCANCEL
Stop

End Select
EndIf
Wend

If RIGHT$(sGamepath,1) <> "\" Then sGamepath += "\"

If Not DIR_Exists(sWorkingpath) Then DIR_Make(sWorkingpath)


If FILE_Exists(sGamepath & "main.pak") Then

If FILE_Exists(sGamepath & "original_Main.pak") Then
FILE_Kill(sGamePath & "Main.pak")
FILE_Rename(sGamepath & "original_Main.pak", sGamepath & "Main.Pak")
PrintL "original Gamedata restored."
PrintL "Press any key to end"
WaitKey
Stop
Else
FILE_Rename(sGamepath & "Main.pak", sGamepath & "original_Main.Pak")
PrintL "Main.Pak renamed to original_Main.Pak"
PrintL
EndIf
Else
PrintL "archive not found. Will abort. Press any key"
WaitKey
Stop
EndIf

If FILE_Exists(sGamepath & "original_Main.pak") Then

PrintL "extracting the package..."
Print "please wait"
PrintL
ZLib_Extract(sGamepath & "original_Main.Pak", sWorkingpath)


sWorld = FILE_Load(sWorkingpath & "data\world.xml")
If StrPtrLen(StrPtr(sWorld)) < 1000 Then
PrintL "!!! unexpected Error !!! Restoring original data..."
PrintL "Have To quit :("
FILE_Rename(sGamepath & "original_Main.pak", sGamepath & "Main.Pak")
WaitKey
Stop
EndIf

nLines = Parse sWorld, sLine, $CRLF
PrintL Str$(nLines) & " lines of code parsed"
For lLine = 1 To nLines

If StrPtrLen(StrPtr(sLine(lLine))) > 40 Then
sCheck = TrimFull$(sLine(lLine))
If StrPtrLen(StrPtr(sCheck)) > 38 Then
If Peek(StrPtr(sCheck) + 1) <> 33 Then
If InStr(sCheck, "ManaRestoreTime") Then
PrintL "ManaRestoreTime found at line" & Str$(lLine)
lPos = InStr(sCheck, "value=" )
If lPos Then
lPos += 6
bChar = Peek(StrPtr(sCheck) + lPos)
While bChar <> 34
sValue &= Chr$(bChar)
lPos += 1
bChar = Peek(StrPtr(sCheck)+lPos)
Wend
sCheck = Replace$(sLine(lLine), sValue, With "30" )
sWorld = Replace$(sWorld, sLine(lLine), With sCheck )
PrintL "implemented new ManaRestoreTime of 30 seconds"
FILE_Save(sWorkingpath & "data\world.xml", sWorld )
PrintL "creating new package- please wait..."
If ZLib_PackFolder(sWorkingPath, APP_ScriptPath & "Main.pak") Then
PrintL "copy the package to the gamefolder"
FILE_Copy(APP_ScriptPath & "Main.pak", sGamepath & "Main.pak")
Else
PrintL "!!! unexpected Error while creating the package !!!"
PrintL "Will abort now. Press any key"
WaitKey
Stop
EndIf
If DIR_Exists(sWorkingPath) Then
Dir_Kill(sWorkingpath)
PrintL "removing temporary data"
EndIf

PrintL "all done, have fun playing now..."
Exit For
EndIf
EndIf
EndIf
EndIf
EndIf
Next

EndIf

PrintL
PrintL "press any key to end"

WaitKey