add some more things
This commit is contained in:
parent
12d1fcd2fa
commit
36d75698f1
22 changed files with 4228 additions and 0 deletions
70
decompress.py
Normal file
70
decompress.py
Normal 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()
|
143
h3c_and_h3m_formats/H3C_SoD_Template.bt
Normal file
143
h3c_and_h3m_formats/H3C_SoD_Template.bt
Normal 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;
|
734
h3c_and_h3m_formats/H3M_SoD_Template.bt
Normal file
734
h3c_and_h3m_formats/H3M_SoD_Template.bt
Normal 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];
|
15
h3c_and_h3m_formats/Heroes3/hstring.bt
Normal file
15
h3c_and_h3m_formats/Heroes3/hstring.bt
Normal 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;
|
||||||
|
}
|
18
h3c_and_h3m_formats/Heroes3/object/artefact.bt
Normal file
18
h3c_and_h3m_formats/Heroes3/object/artefact.bt
Normal 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];
|
||||||
|
}
|
||||||
|
};
|
30
h3c_and_h3m_formats/Heroes3/object/dwellings.bt
Normal file
30
h3c_and_h3m_formats/Heroes3/object/dwellings.bt
Normal 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;
|
||||||
|
};
|
4
h3c_and_h3m_formats/Heroes3/object/grail.bt
Normal file
4
h3c_and_h3m_formats/Heroes3/object/grail.bt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
struct ObjectGrail {
|
||||||
|
char radius;
|
||||||
|
uchar junk2[3];
|
||||||
|
};
|
24
h3c_and_h3m_formats/Heroes3/object/monster.bt
Normal file
24
h3c_and_h3m_formats/Heroes3/object/monster.bt
Normal 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];
|
||||||
|
};
|
44
h3c_and_h3m_formats/Heroes3/object/pandorabox.bt
Normal file
44
h3c_and_h3m_formats/Heroes3/object/pandorabox.bt
Normal 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];
|
||||||
|
};
|
5
h3c_and_h3m_formats/Heroes3/object/resource.bt
Normal file
5
h3c_and_h3m_formats/Heroes3/object/resource.bt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
struct ObjectResource {
|
||||||
|
ObjectArtefact res;
|
||||||
|
uint32 quantity;
|
||||||
|
uchar junk[4];
|
||||||
|
};
|
9
h3c_and_h3m_formats/Heroes3/object/scientist.bt
Normal file
9
h3c_and_h3m_formats/Heroes3/object/scientist.bt
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
struct ObjectScientist {
|
||||||
|
uchar bonus_type; // FF - Random
|
||||||
|
union {
|
||||||
|
uint32 primaryID;
|
||||||
|
uint32 secondaryID;
|
||||||
|
uint32 spellID;
|
||||||
|
} bonus;
|
||||||
|
uchar junk2[3];
|
||||||
|
};
|
4
h3c_and_h3m_formats/Heroes3/object/spellscroll.bt
Normal file
4
h3c_and_h3m_formats/Heroes3/object/spellscroll.bt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
struct ObjectSpell {
|
||||||
|
ObjectArtefact spell;
|
||||||
|
uint32 spellID;
|
||||||
|
};
|
57
h3c_and_h3m_formats/Heroes3/object/town.bt
Normal file
57
h3c_and_h3m_formats/Heroes3/object/town.bt
Normal 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;
|
||||||
|
};
|
9
h3c_and_h3m_formats/Heroes3/objects.bt
Normal file
9
h3c_and_h3m_formats/Heroes3/objects.bt
Normal 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"
|
4
h3c_and_h3m_formats/Heroes3/secondaryskills.bt
Normal file
4
h3c_and_h3m_formats/Heroes3/secondaryskills.bt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
struct secskill_tag {
|
||||||
|
uchar skillID;
|
||||||
|
uchar skillLevel;
|
||||||
|
};
|
39
h3c_and_h3m_formats/Heroes3/special_victory.bt
Normal file
39
h3c_and_h3m_formats/Heroes3/special_victory.bt
Normal 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;
|
||||||
|
}
|
||||||
|
};
|
1005
h3c_and_h3m_formats/h3m_description.TXT
Normal file
1005
h3c_and_h3m_formats/h3m_description.TXT
Normal file
File diff suppressed because it is too large
Load diff
40
image_viewer.py
Executable file
40
image_viewer.py
Executable 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
52
lodextract.py
Normal 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
19
lodlist.py
Normal 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
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
102
logo_alt.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 28 KiB |
Loading…
Reference in a new issue