add some more things

This commit is contained in:
josch 2014-06-21 14:50:18 +02:00
parent 12d1fcd2fa
commit 36d75698f1
22 changed files with 4228 additions and 0 deletions

70
decompress.py Normal file
View file

@ -0,0 +1,70 @@
#!/usr/bin/python
import zlib, os
import struct
import Image, ImageDraw
lod = open("H3bitmap.lod")
lod.seek(8)
files_count = struct.unpack("i", lod.read(4))[0]
files=[]
for file in range(2745,2793):
lod.seek(92+(file*32))
name = lod.read(16).split("\0")[0]
offset = struct.unpack("i", lod.read(4))[0] #offset
size_orig = struct.unpack("i", lod.read(4))[0] #size_original
type = struct.unpack("i", lod.read(4))[0] #type
size_comp = struct.unpack("i", lod.read(4))[0] #size_compressed
lod.seek(offset)
if size_comp:
pcx = zlib.decompress(lod.read(size_comp))
else:
pcx = lod.read(size_orig)
if type == 16:
size = struct.unpack("i", pcx[:4])[0]
width = struct.unpack("i", pcx[4:8])[0]
height = struct.unpack("I", pcx[8:12])[0]
print file, name, width, height
im = Image.new("RGBA", (width, height))
draw = ImageDraw.Draw(im)
bla=[]
for i in range(256):
bla.append((ord(pcx[12+size+i*3]),ord(pcx[12+size+i*3+1]),ord(pcx[12+size+i*3+2])))
for i in range(size):
a =ord(pcx[12+i])
if bla[a] == (0,255,255):
draw.point((i-int(i/width)*width,int(i/width)), fill=(0,0,0,0))
else:
draw.point((i-int(i/width)*width,int(i/width)), fill=bla[a])
im.save(' '.join([str(file),name]), "PNG")
elif type == 17:
size = struct.unpack("i", pcx[:4])[0]
width = struct.unpack("i", pcx[4:8])[0]
height = struct.unpack("I", pcx[8:12])[0]
print file, name, width, height
im = Image.new("RGB", (width, height))
draw = ImageDraw.Draw(im)
for i in range(size/3):
if ord(pcx[12+i*3]) == 0 and ord(pcx[13+i*3]) == 255 and ord(pcx[14+i*3]) == 255:
draw.point((i-int(i/width)*width,int(i/width)), fill=(0,0,0,0))
else:
draw.point((i-int(i/width)*width,int(i/width)), fill=(ord(pcx[12+i*3]),ord(pcx[13+i*3]),ord(pcx[14+i*3])))
im.save(' '.join([str(file),name]), "PNG")
elif type in (1, 2, 64, 65, 66, 67, 68, 69, 70, 71, 73, 79, 80, 96):
print file, name
file = open(' '.join([str(file),name]), "w")
file.write(pcx)
file.close()
else:
print i, name, type
sys.exit("not supported %d"%type)
lod.close()

View file

@ -0,0 +1,143 @@
//--------------------------------------
//--- 010 Editor v2.1.3 Binary Template
//
// File: H3C SoD Template
// Author: crackedmind
// Revision: 001
// Purpose: just for fun :)
//--------------------------------------
#include "heroes3/hstring.bt"
#include "heroes3/secondaryskills.bt"
struct Header {
uint32 magic; // 05 00 00 00 - AB
// 06 00 00 00 - SoD
// ?? ?? ?? ?? - RoE
uchar map_number; // CampText.txt
hstring name;
hstring description;
uchar canPlayerChooseDifficult;
uchar whatMusic; // CmpMusic.txt, start from 0
};
struct ScenarioTravel {
uchar whatHeroKeep; // bit 1 - expirience
// bit 2 - primary skills
// bit 3 - secondary skills
// bit 4 - spells
// bit 5 - artefacts
uchar whatMonstresHeroKeep[19];
uchar whatArtifactsHeroKeep[18];
uchar startOptions; // 01 - start bonus
// 02 - traveling hero
// 03 - hero options
if ( startOptions == 1 ) {
uchar playerColor;
uchar bonusCount;
local int i;
for ( i = 0; i < bonusCount; i++ ) {
uchar bonusType;
switch(bonusType){
case 0: //spell
uint16 heroName; //0xFDFF - most powerfull hero
// other names from hotraits.txt
uchar spell;
break;
case 1: // monster
uint16 heroName; //0xFDFF - most powerfull hero
// other names from hotraits.txt
uint16 monsterType;
uint16 count;
case 2: // building
// TODO
break;
case 3:
uint16 heroName; //0xFDFF - most powerfull hero
// other names from hotraits.txt
uint16 artefact;
break;
case 4: // spell scroll
uint16 heroName; //0xFDFF - most powerfull hero
// other names from hotraits.txt
uchar spell;
break;
case 5: // primary skills
uint16 heroName; //0xFDFF - most powerfull hero
// other names from hotraits.txt
uchar primarySkills[4];
break;
case 6: // secondary skills
uint16 heroName; //0xFDFF - most powerfull hero
// other names from hotraits.txt
secskill_tag secskill;
break;
case 7: // resource
uchar type; // 0 - wood, 1 - Mercury
// 2 - ore, 3 - sulfur
// 4 - crystal, 5 - gem
// 6 - gold, FD - wood+ore
// FE - mercury+sulfur+crystal+gem
uint32 count;
break;
};
}
} else if ( startOptions == 2 ) {
uchar count;
local uchar i;
for ( i = 0; i < count; i++) {
uchar whichPlayer; // player color
uchar fromWhatScenario;
}
} else if ( startOptions == 3 ) {
uchar heroesCount; // max is 3
local uchar i;
for (i =0; i < heroesCount; i++ ) {
uchar playerColor;
uint16 hero; // FF FF is random
}
}
};
struct Scenario {
hstring map_name;
uint32 packedMapSize;
uchar preconditionRegion; // if equal to 0, then no region
uchar regionColor;
uchar difficult;
hstring regionText;
struct ScenarioProlog {
uchar isProlog;
if ( isProlog == 1 ) {
uchar prologVideo; // from CmpMovie.txt
uchar prologMusic; // from CmpMusic.txt
hstring prologText;
}
} prolog;
ScenarioProlog epilog;
ScenarioTravel travel;
};
Header header;
if ( header.magic != 0x00000006 ) {
Warning( "File is not a Heroes III SoD Company file. Template stopped." );
return -1;
}
// here must be a loop, iterations == map regions number, but it's hardcoded feature :(
Scenario scenario;

View file

@ -0,0 +1,734 @@
//--------------------------------------
//--- 010 Editor v2.1.3 Binary Template
//
// File: H3M SoD Template
// Author: CrackedMind
// Revision: 019
// Purpose: just for fun :D
//
// History: 003 - add "player commands" interpretation
// 004 - fix map identification
// 005 - add "free heroes" block interpretation
// 006 - add "artefacts" block interpretation
// 007 - add "spells", "secondary skill" and "rumors" blocks
// 008 - add "hero options" block
// 009 - change some interpretation of some variables
// add landscape block
// 010 - add "objects" inerpretation
// 011 - add "artefact", "monster", "grail", "pandora box" attributes
// 012 - add "spell scroll", "resource" attributes
// 013 - add "dwellings", "shipyard", "scientist", "random artefacts", "random monsters" attributes
// change many "if" blocks to one big switch :)
// 014 - add "random dwellings", "shrines (1-3)"
// 015 - some refactoring
// add "town", "event", attributes
// 016 - some more refactoring (split to modules)
// add "ocean bottle", "sign", "prophet" (almost complete) attributes
// 017 - add "hero", "prison", "random hero", "prophet" (complete) attributes
// 018 - add "mine", "witch's hut", "hero placeholder" (almost complete) attributes
// fix "town", PLAYERS_ATTRIBUTES struct
// 019 - add global events
// add "lighthouse", "quest guard", "abandoned mine" (2 types)
// add "garrison", "special dwellings" (all types of golems & elementals)
// fix "random dwellings"
//--------------------------------------
// TODO: hero placeholder (defined hero), take more info about "junk" bytes
//
#include "heroes3/hstring.bt"
#include "heroes3/special_victory.bt"
#include "heroes3/secondaryskills.bt"
#include "heroes3/objects.bt"
struct BASIC_PARAMETRES {
int magic_header;
char junk;
uint32 size;
char under;
hstring name;
hstring description;
char difficult;
char levelLimit;
};
struct PLAYER_ATTRIBUTES {
char isHuman;
char isComputer;
char behavior; // 0-Random, 1-Warrior, 2-Builder, 3-Explorer
char isCityTypesOpt;
short cityTypes <format=binary>;;
char randomCity;
char mainCity;
if ( mainCity == 1 ) {
char generateHero;
uchar city[4]; // 0 - city type, 1-3 coords
}
uchar random_hero;
uchar hero_type;
if ( hero_type != 0xFF ) {
uchar hero_portret;
hstring hero_name;
}
char junk;
uint heroes_count;
if ( heroes_count > 0 ) {
struct Hero_tag {
uchar portret;
hstring name;
};
Hero_tag hero[heroes_count] <optimize=false>;
}
};
struct SpecialLossConditions {
uchar id;
if ( id != 0xFF ) {
if ( id == 0x00 || id == 0x01 ) {
uchar coord[3];
}
else if ( id == 0x02 )
ushort days;
}
};
struct Teams {
uchar commands_count;
if ( commands_count > 0 ) {
uchar commands[8];
}
};
struct FreeHeroes {
uchar free_heroes[20];
uchar junk[4];
uchar heroes_count;
if (heroes_count > 0) {
struct tuned_tag {
uchar heroID;
uchar heroPortrait;
hstring hero_name;
uchar players;
} tuned[heroes_count] <optimize=false>;
}
uchar junk2[31];
};
struct Artefacts {
uchar artefacts[18] <format=binary>;
};
struct Spells {
uchar spells[9] <format=binary>;
};
struct SecSkills {
uchar skills[4] <format=binary>;
};
struct Rumors {
uint32 total_rumors;
if ( total_rumors > 0 ) {
struct Rumor_tag {
hstring rumor_name;
hstring rumor_text;
} rumors[total_rumors] <optimize=false>;
}
};
struct HeroOptions_enabled {
uchar isExp;
if ( isExp == 1 )
uint32 exp;
uchar isSecSkill;
if ( isSecSkill == 1 ) {
uint32 skills_count;
secskill_tag secskills [skills_count];
}
uchar isArtefacts;
if ( isArtefacts == 1 ) {
ushort headID;
ushort shouldersID;
ushort neckID;
ushort rightHandID;
ushort leftHandID;
ushort trunkID;
ushort rightRingID;
ushort leftRingID;
ushort legsID;
ushort misc1ID;
ushort misc2ID;
ushort misc3ID;
ushort misc4ID;
ushort machine1ID;
ushort machine2ID;
ushort machine3ID;
ushort machine4ID;
ushort magicbook;
ushort misc5ID;
ushort knapsack_count;
if ( knapsack_count > 0 )
ushort knapsackID[knapsack_count];
}
uchar isBiography;
if (isBiography == 1)
hstring biography;
uchar gender <read=genderRead>;
uchar isSpells;
if ( isSpells == 1 )
uchar spells[9] <format=binary>;
uchar isPrimarySkills;
if ( isPrimarySkills == 1 ) {
uchar attack;
uchar defence;
uchar power;
uchar knowledge;
}
};
struct HeroOptions {
local int i;
for (i = 0; i < 156; i++) {
uchar enable;
if ( enable == 1 )
HeroOptions_enabled options;
}
};
struct LandCell {
uchar surfaceID;
uchar surfacePattern;
uchar riverID;
uchar riverPattern;
uchar roadID;
uchar roadPattern;
uchar mirroring <format=binary>;
};
struct Object {
hstring filename;
uchar passability[6];
uchar actions[6];
ushort landscape;
ushort land_edit_groups; // for editor
uint32 object_class;
uint32 object_number;
uchar object_group;
uchar isOverlay;
uchar junk[16];
};
struct ObjectOptions {
uchar coord[3]; // x, y, z;
uint32 objectID;
uchar junk[5];
};
struct ObjectShrine {
uint32 spellID;
};
struct ObjectEvent {
ObjectPandora event;
uchar players;
uchar isAICan;
uchar disableAfterFirstDay;
uint32 junk;
};
struct ObjectSign {
hstring text;
uint32 junk;
};
struct ObjectProphet {
uchar quest;
switch(quest) {
case 0:
break;
case 1:
uint32 level;
break;
case 2:
uchar offence;
uchar defence;
uchar power;
uchar knowledge;
break;
case 3:
uint32 heroID;
break;
case 4:
uint32 monsterID;
break;
case 5:
uchar art_quantity;
ushort arts[art_quantity];
break;
case 6:
uchar creatures_quantity;
if ( creatures_quantity > 0 ) {
GuardTag creatures[creatures_quantity];
}
break;
case 7:
uint32 resources[7];
break;
case 8:
uchar heroID;
break;
case 9:
uchar player_color;
break;
};
uint32 time_limit; // FF FF FF FF - no limit
hstring quest_begin;
hstring quest_inprocess;
hstring quest_end;
uchar reward;
switch(reward) {
case 0:
break;
case 1:
uint32 exp;
break;
case 2:
uint32 spell_points;
break;
case 3:
uchar morale;
break;
case 4:
uchar lucky;
break;
case 5:
uchar resID;
uint32 res_quantity;
break;
case 6:
uchar priSkillID;
uchar priSkillBonus;
break;
case 7:
uchar secSkillID;
uchar secSkillLevel;
break;
case 8:
ushort artID;
break;
case 9:
uchar spellID;
break;
case 10:
ushort creatureID;
ushort creatureQuantity;
break;
};
char junk[2];
};
struct ObjectHero {
uint32 heroID;
uchar color;
uchar hero; // FF - random
uchar isName;
if ( isName == 1 )
hstring name;
uchar isExp;
if ( isExp == 1 )
uint32 exp;
uchar isPortrait;
if ( isPortrait == 1)
uchar portrait;
uchar isSecondary;
if ( isSecondary == 1 ) {
uint32 skills_quantity;
if ( skills_quantity > 0 )
secskill_tag skills[skills_quantity];
}
uchar isCreature;
if ( isCreature == 1 )
GuardTag creatures[7];
uchar creaturesFormation;
uchar isArtefacts;
if ( isArtefacts == 1 ) {
ushort headID;
ushort shouldersID;
ushort neckID;
ushort rightHandID;
ushort leftHandID;
ushort trunkID;
ushort rightRingID;
ushort leftRingID;
ushort legsID;
ushort misc1ID;
ushort misc2ID;
ushort misc3ID;
ushort misc4ID;
ushort machine1ID;
ushort machine2ID;
ushort machine3ID;
ushort machine4ID;
ushort magicbook;
ushort misc5ID;
ushort knapsack_count;
if ( knapsack_count > 0 )
ushort knapsackID[knapsack_count];
}
uchar zoneRadius;
uchar isBiography;
if ( isBiography == 1 )
hstring biography;
uchar gender <read=genderRead>;
uchar isSpells;
if ( isSpells == 1 ) {
uchar spells[9] <format=binary>;
}
uchar isPrimary;
if ( isPrimary == 1 ) {
uchar offence;
uchar defence;
uchar power;
uchar knowledge;
}
uint32 unknown[4];
};
struct ObjectHeroPlaceholder {
uchar color;
uchar type;
};
struct ObjectMine {
uint32 color;
};
struct ObjectWitchHut {
uint32 secskills <format=binary>;
};
struct globalEvent {
hstring name;
hstring text;
int32 resources[7];
uchar players_affected;
uchar human_affected;
uchar ai_affected;
ushort day_of_first_event;
ushort event_iteration;
char junk[16];
};
struct ObjectQuestionGuard {
uchar quest;
switch(quest) {
case 0:
break;
case 1:
uint32 level;
break;
case 2:
uchar offence;
uchar defence;
uchar power;
uchar knowledge;
break;
case 3:
uint32 heroID;
break;
case 4:
uint32 monsterID;
break;
case 5:
uchar art_quantity;
ushort arts[art_quantity];
break;
case 6:
uchar creatures_quantity;
if ( creatures_quantity > 0 ) {
GuardTag creatures[creatures_quantity];
}
break;
case 7:
uint32 resources[7];
break;
case 8:
uchar heroID;
break;
case 9:
uchar player_color;
break;
};
uint32 time_limit; // FF FF FF FF - no limit
hstring quest_begin;
hstring quest_inprocess;
hstring quest_end;
};
struct ObjectGarrison {
uint32 color;
GuardTag guards[7];
uchar undeleteSoldiers;
uint32 junk[2];
};
struct ObjectAbandonedMine {
uchar resources <format=binary>;
uchar junk[3];
};
string genderRead(uchar &gend) {
string s;
if ( gend == 0 )
SPrintf(s, "%s", "male");
else if ( gend == 1 )
SPrintf(s, "%s", "female");
else if ( gend == 0xFF )
SPrintf(s, "%s", "by default");
return s;
}
//
// !!! entrypoint !!!
//
BASIC_PARAMETRES bp;
// Check for header
if( bp.magic_header != 0x0000001C )
{
Warning( "File is not a Heroes III SoD Map. Template stopped." );
return -1;
}
PLAYER_ATTRIBUTES red;
PLAYER_ATTRIBUTES blue;
PLAYER_ATTRIBUTES tan;
PLAYER_ATTRIBUTES green;
PLAYER_ATTRIBUTES orange;
PLAYER_ATTRIBUTES purple;
PLAYER_ATTRIBUTES teal;
PLAYER_ATTRIBUTES pink;
SpecialVictoryConditions svc <optimize=false>;
SpecialLossConditions slc <optimize=false>;
Teams cmd;
FreeHeroes fh;
Artefacts arts;
Spells sp;
SecSkills ss;
Rumors rumors;
HeroOptions options;
LandCell ground[bp.size*bp.size] <optimize=true>;
if ( bp.under == 1 )
LandCell underground[bp.size*bp.size];
uint32 objects_count;
if ( objects_count > 0 )
Object objects[objects_count] <optimize=false>;
uint32 tunedobj_count;
local int i;
if ( tunedobj_count > 0 ) {
for ( i = 0; i < tunedobj_count; i++ ) {
ObjectOptions obj;
switch(objects[obj.objectID].object_class)
{
case 5:
case 65:
case 66:
case 67:
case 68:
case 69:
ObjectArtefact artefact;
break;
case 6:
ObjectPandora pandora;
break;
case 17:
case 20:
case 42: //lighthouse
ObjectDwelling dwelling;
break;
case 26:
ObjectEvent localevent;
break;
case 33:
case 219:
ObjectGarrison garrison;
break;
case 34:
case 70:
ObjectHero hero;
break;
case 62:
ObjectHero hero;
break;
case 36:
ObjectGrail grail;
break;
case 53:
switch(objects[obj.objectID].object_number) {
case 7:
ObjectAbandonedMine abandoned; // bit0 - mercury, 1 - ore, 2 - sulfur,
break; // bit3 - crystal, 4 - gem, 5 - gold
default:
ObjectMine mine;
break;
}
break;
case 54:
case 71:
case 72:
case 73:
case 74:
case 75:
case 162:
case 163:
case 164:
ObjectMonster monster;
break;
case 76:
case 79:
ObjectResource res;
break;
case 81:
ObjectScientist scientist;
break;
case 83:
ObjectProphet prophet;
break;
case 87:
ObjectShipyard shipyard;
break;
case 88:
case 89:
case 90:
ObjectShrine shrine;
break;
case 91:
case 59:
ObjectSign sign;
break;
case 93:
ObjectSpell spell;
break;
case 98:
case 77:
ObjectTown town;
break;
case 113:
ObjectWitchHut whut;
break;
case 215:
ObjectQuestionGuard qguard;
break;
case 216:
ObjectGeneralRandomDwelling dwelling;
break;
case 217:
ObjectLevelRandomDwelling dwelling;
break;
case 218:
ObjectTownRandomDwelling dwelling;
break;
case 220:
ObjectAbandonedMine abandoned;
break;
};
}
}
uint32 gevents_quantity;
globalEvent gevents[gevents_quantity] <optimize=false>;
uchar main_junk[124];

View file

@ -0,0 +1,15 @@
typedef struct {
uint32 str_len;
if ( str_len > 0 )
char str[str_len];
}hstring <read=hstringRead>;
string hstringRead (hstring &str) {
string s;
if ( str.str_len > 0 )
SPrintf( s, "%s", str.str );
else
return "empty";
return s;
}

View file

@ -0,0 +1,18 @@
struct ObjectArtefact {
uchar isText;
if ( isText == 1 ) {
hstring text;
uchar isGuards;
if ( isGuards == 1 ) {
struct GuardTag {
ushort GuardID;
ushort GuardCount;
} Guards[7];
}
uchar junk[4];
}
};

View file

@ -0,0 +1,30 @@
struct ObjectDwelling {
uint32 owner; // FF - nobody
};
struct ObjectShipyard {
ObjectDwelling shipyard;
};
struct ObjectGeneralRandomDwelling {
uint32 owner;
uint32 junk;
if (junk == 0 )
ushort towns;
uchar minlevel;
uchar maxlevel;
};
struct ObjectLevelRandomDwelling {
uint32 owner;
uint32 junk;
if ( junk == 0 )
ushort towns;
};
struct ObjectTownRandomDwelling {
uint32 owner;
uchar minlevel;
uchar maxlevel;
};

View file

@ -0,0 +1,4 @@
struct ObjectGrail {
char radius;
uchar junk2[3];
};

View file

@ -0,0 +1,24 @@
struct ObjectMonster {
uint32 monsterID;
ushort monsters_count; // if 0, then random
uchar mood;
uchar isTreasureOrText;
if ( isTreasureOrText == 1 ) {
hstring text;
uint32 wood;
uint32 mercury;
uint32 ore;
uint32 sulfur;
uint32 crystal;
uint32 gem;
uint32 gold;
ushort artefactID;
}
uchar monsterNeverRunAway; // 1 - yes, 0 - no
uchar monsterDontGrowUp; // 1 - yes, 0 - no
uchar junk2[2];
};

View file

@ -0,0 +1,44 @@
struct ObjectPandora {
ObjectArtefact art;
uint32 exp;
int32 spell_points;
char morals;
char luck;
int32 wood;
int32 mercury;
int32 ore;
int32 sulfur;
int32 crystal;
int32 gem;
int32 gold;
uchar offence;
uchar defence;
uchar power;
uchar knowledge;
uchar secskills;
if ( secskills > 0 ) {
secskill_tag sec_skills [secskills];
}
uchar artefacts;
if ( artefacts > 0 ) {
ushort artID[artefacts];
}
uchar spells;
if ( spells > 0 ) {
uchar spellID[spells];
}
uchar monstres_count;
if ( monstres_count > 0 ) {
GuardTag monstres[monstres_count];
}
uchar junk3[8];
};

View file

@ -0,0 +1,5 @@
struct ObjectResource {
ObjectArtefact res;
uint32 quantity;
uchar junk[4];
};

View file

@ -0,0 +1,9 @@
struct ObjectScientist {
uchar bonus_type; // FF - Random
union {
uint32 primaryID;
uint32 secondaryID;
uint32 spellID;
} bonus;
uchar junk2[3];
};

View file

@ -0,0 +1,4 @@
struct ObjectSpell {
ObjectArtefact spell;
uint32 spellID;
};

View file

@ -0,0 +1,57 @@
struct ObjectTown {
char junk[4];
uchar owner;
uchar isName;
if ( isName == 1 )
hstring name;
uchar isGuard;
if (isGuard == 1 )
GuardTag guards[7];
uchar formation; // 00 - standalone, 01 - group
uchar isBuildings;
if ( isBuildings == 1 ) {
uchar built[6];
uchar active[6];
} else {
uchar isFort;
}
uchar mustSpells[9];
uchar canSpells[9];
uint32 event_quantity;
if ( event_quantity > 0 ) {
struct TownEvent {
hstring event_name;
hstring event_text;
int32 wood;
int32 mercury;
int32 ore;
int32 sulfur;
int32 crystal;
int32 gem;
int32 gold;
uchar players_affected;
uchar human_affected;
uchar ai_affected;
ushort day_of_first_event;
ushort event_iteration;
uint32 junk[4];
uchar buildings[6];
ushort creatures[7];
uint32 junk2;
} events[event_quantity] <optimize=false>;
}
uint32 junk3;
};

View file

@ -0,0 +1,9 @@
#include "heroes3/object/monster.bt"
#include "heroes3/object/artefact.bt"
#include "heroes3/object/grail.bt"
#include "heroes3/object/pandorabox.bt"
#include "heroes3/object/spellscroll.bt"
#include "heroes3/object/resource.bt"
#include "heroes3/object/town.bt"
#include "heroes3/object/dwellings.bt"
#include "heroes3/object/scientist.bt"

View file

@ -0,0 +1,4 @@
struct secskill_tag {
uchar skillID;
uchar skillLevel;
};

View file

@ -0,0 +1,39 @@
struct SpecialVictoryConditions {
uchar id;
if ( id != 0xFF ) {
char canStandardEnd;
char canComputer;
}
if ( id == 0x00 ) {
struct svc_acqSpecArt_tag {
char artID;
} svc_acqSpecArt;
} else if ( id == 0x01 ) {
struct svc_accCreatures_tag {
ushort creatureID;
DWORD creatureCount;
}svc_accCreatures;
} else if ( id == 0x02 ) {
struct svc_accRes_tag {
char resID;
DWORD resCount;
} svc_accRes;
} else if ( id == 0x03 ) {
struct svc_upgSpecTown_tag {
uchar coord[3];
char hall_level;
char castle_level;
} svc_upgSpecTown;
} else if ( id == 0x04 || id == 0x05 || id == 0x06 || id == 0x07 ) {
uchar coord[3];
} else if ( id == 0x08 || id == 0x09) {
// no more data
} else if ( id == 0x0A ) {
struct svc_tranSpecArt_tag {
uchar artID;
uchar coord[3];
} svc_tranSpecArt;
}
};

File diff suppressed because it is too large Load diff

40
image_viewer.py Executable file
View file

@ -0,0 +1,40 @@
#!/usr/bin/env python
import pyglet
images = [
pyglet.image.load("puzzle/cas/%d PuzCas%02d.pcx"%(i+2745, i)) for i in xrange(20)
]
bin = pyglet.image.atlas.TextureBin()
images = [bin.add(image) for image in images]
window = pyglet.window.Window(800,600)
image = pyglet.resource.image('interface/3178 Puzzle.pcx')
image1 = pyglet.resource.image('interface/153 AResBar.pcx')
@window.event
def on_draw():
window.clear()
image.blit(0, 0)
image1.blit(3, 3)
images[0].blit(7,414)
images[1].blit(7,402)
images[2].blit(7,412)
images[3].blit(7,359)
images[4].blit(7,264)
images[5].blit(7,49)
images[6].blit(16,527)
images[7].blit(22,49)
images[8].blit(70,49)
images[9].blit(72,285)
@window.event
def on_key_press(symbol, modifiers):
if symbol == pyglet.window.key.Q:
pyglet.app.exit()
pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA, pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
pyglet.app.run()

52
lodextract.py Normal file
View file

@ -0,0 +1,52 @@
#!/usr/bin/python
import zlib, os
import struct
import Image, ImageDraw
import StringIO
lod = open("H3bitmap.lod")
lod.seek(8)
files_count = struct.unpack("i", lod.read(4))[0]
files=[]
for file in range(32,33):
lod.seek(92+(file*32))
name = lod.read(16).split("\0")[0]
offset = struct.unpack("i", lod.read(4))[0] #offset
size_orig = struct.unpack("i", lod.read(4))[0] #size_original
type = struct.unpack("i", lod.read(4))[0] #type
size_comp = struct.unpack("i", lod.read(4))[0] #size_compressed
lod.seek(offset)
if size_comp:
pcx = zlib.decompress(lod.read(size_comp))
else:
pcx = lod.read(size_orig)
if type == 16:
size = struct.unpack("i", pcx[:4])[0]
width = struct.unpack("i", pcx[4:8])[0]
height = struct.unpack("I", pcx[8:12])[0]
print size, width, height
im = Image.fromstring("L", (width, height), pcx[12:12+size])
im.putpalette(pcx[12+size:12+size+768])
im.save(' '.join([str(file),name]), "PNG")
if type == 17:
size = struct.unpack("i", pcx[:4])[0]
width = struct.unpack("i", pcx[4:8])[0]
height = struct.unpack("I", pcx[8:12])[0]
print size, width, height
im = Image.fromstring("RGB", (width, height), pcx[12:12+size])
im.save(' '.join([str(file),name]), "PNG")
elif type in (1, 2, 64, 65, 66, 67, 68, 69, 70, 71, 73, 79, 80, 96):
print file, name
file = open(' '.join([str(file),name]), "w")
file.write(pcx)
file.close()
else:
print i, name, type
sys.exit("not supported %d"%type)
lod.close()

19
lodlist.py Normal file
View file

@ -0,0 +1,19 @@
#!/usr/bin/python
import struct
from sys import argv
lod = open(argv[1])
lod.seek(8)
files_count = struct.unpack("i", lod.read(4))[0]
files=[]
for file in xrange(files_count):
lod.seek(92+(file*32))
name = lod.read(16).split("\0")[0]
offset = struct.unpack("i", lod.read(4))[0] #offset
size_orig = struct.unpack("i", lod.read(4))[0] #size_original
type = struct.unpack("i", lod.read(4))[0] #type
size_comp = struct.unpack("i", lod.read(4))[0] #size_compressed
print name
lod.close()

1801
logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 711 KiB

102
logo_alt.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB