Code:
int readguys(PACKFILE *f, zquestheader *Header, bool keepdata)
{
dword dummy;
word dummy2;
word guyversion=0;
if(Header->zelda_version >= 0x193)
{
//section version info
if(!p_igetw(&guyversion,f,true))
{
return qe_invalid;
}
//al_trace("Guys version %d\n", guyversion);
if(!p_igetw(&dummy2,f,true))
{
return qe_invalid;
}
//section size
if(!p_igetl(&dummy,f,true))
{
return qe_invalid;
}
}
if(guyversion > 3)
{
for(int i=0; i<MAXGUYS; i++)
{
char tempname[64];
// rev. 1511 : guyversion = 23. upped to 512 editable enemies. -Gleeok
// if guyversion < 23 then there is only 256 enemies in the packfile, so default the rest.
if(guyversion < 23 && i >= OLDBETAMAXGUYS && keepdata)
{
memset(tempname, 0, sizeof(char)*64);
sprintf(tempname, "e%03d", i);
strcpy(guy_string[i], tempname);
continue;
}
if(!pfread(tempname, 64, f, keepdata))
{
return qe_invalid;
}
// Don't retain names of uneditable enemy entries!
if(keepdata)
{
// for version upgrade to 2.5
if(guyversion < 23 && i >= 177)
{
// some of the older builds have names such as 'zz123',
// (this order gets messed up with some eXXX and some zzXXX)
// so let's update to the newer naming convection. -Gleeok
char tmpbuf[64];
memset(tmpbuf, 0, sizeof(char)*64);
sprintf(tmpbuf, "zz%03d", i);
if(memcmp(tempname, tmpbuf, size_t(5)) == 0)
{
memset(tempname, 0, sizeof(char)*64);
sprintf(tempname, "e%03d", i);
}
}
if(i >= OLDMAXGUYS || strlen(tempname)<1 || tempname[strlen(tempname)-1]!=' ')
{
strcpy(guy_string[i], tempname);
}
else
{
strcpy(guy_string[i],old_guy_string[i]);
}
}
}
}
else
{
if(keepdata)
{
for(int i=0; i<eMAXGUYS; i++)
{
sprintf(guy_string[i],"zz%03d",i);
}
for(int i=0; i<OLDMAXGUYS; i++)
{
strcpy(guy_string[i],old_guy_string[i]);
}
}
}
//finally... section data
if(keepdata)
{
init_guys(guyversion); //using default data for now...
// Goriya guy fix
if((Header->zelda_version < 0x211)||((Header->zelda_version == 0x211)&&(Header->build<7)))
{
if(get_bit(quest_rules,qr_NEWENEMYTILES))
{
guysbuf[gGORIYA].tile=130;
guysbuf[gGORIYA].e_tile=130;
}
}
}
if(Header->zelda_version < 0x193)
{
if(get_bit(deprecated_rules,46))
{
guysbuf[eDODONGO].cset=14;
guysbuf[eDODONGO].bosspal=spDIG;
}
}
// Not sure when this first changed, but it's necessary for 2.10, at least
if(Header->zelda_version <= 0x210)
{
guysbuf[eGLEEOK1F].misc6 = 16;
guysbuf[eGLEEOK2F].misc6 = 16;
guysbuf[eGLEEOK3F].misc6 = 16;
guysbuf[eGLEEOK4F].misc6 = 16;
guysbuf[eWIZ1].misc4 = 1;
guysbuf[eBATROBE].misc4 = 1;
guysbuf[eSUMMONER].misc4 = 1;
guysbuf[eWWIZ].misc4 = 1;
}
// The versions here may not be correct
// zelda_version>=0x211 handled at guyversion<24
if(Header->zelda_version <= 0x190)
{
guysbuf[eCENT1].misc3 = 0;
guysbuf[eCENT2].misc3 = 0;
guysbuf[eMOLDORM].misc2 = 0;
}
else if(Header->zelda_version <= 0x210)
{
guysbuf[eCENT1].misc3 = 1;
guysbuf[eCENT2].misc3 = 1;
guysbuf[eMOLDORM].misc2 = 0;
}
if(guyversion<=2)
{
return readlinksprites2(f, guyversion==2?0:-1, 0, keepdata);
}
if(guyversion > 3)
{
guydata tempguy;
for(int i=0; i<MAXGUYS; i++)
{
if(guyversion < 23 && keepdata) // May 2012 : 512 max enemies
{
if(i >= OLDBETAMAXGUYS)
{
memset(&guysbuf[i], 0, sizeof(guydata));
continue;
}
}
memset(&tempguy, 0, sizeof(guydata));
if(!p_igetl(&(tempguy.flags),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.flags2),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.tile),f,keepdata))
{
return qe_invalid;
}
if(!p_getc(&(tempguy.width),f,keepdata))
{
return qe_invalid;
}
if(!p_getc(&(tempguy.height),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.s_tile),f,keepdata))
{
return qe_invalid;
}
if(!p_getc(&(tempguy.s_width),f,keepdata))
{
return qe_invalid;
}
if(!p_getc(&(tempguy.s_height),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.e_tile),f,keepdata))
{
return qe_invalid;
}
if(!p_getc(&(tempguy.e_width),f,keepdata))
{
return qe_invalid;
}
if(!p_getc(&(tempguy.e_height),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.hp),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.family),f,keepdata))
{
return qe_invalid;
}
if(guyversion < 9 && (i==eDKNUT1 || i==eDKNUT2 || i==eDKNUT3 || i==eDKNUT4 || i==eDKNUT5)) // Whoops, forgot about Darknuts...
{
if(get_bit(quest_rules,qr_NEWENEMYTILES))
{
tempguy.s_tile=tempguy.e_tile+120;
tempguy.s_width=tempguy.e_width;
tempguy.s_height=tempguy.e_height;
}
else tempguy.s_tile=860;
}
if(!p_igetw(&(tempguy.cset),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.anim),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.e_anim),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.frate),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.e_frate),f,keepdata))
{
return qe_invalid;
}
if(guyversion < 13) // April 2009
{
if(get_bit(deprecated_rules, qr_SLOWENEMYANIM_DEP))
{
tempguy.frate *= 2;
tempguy.e_frate *= 2;
}
}
if(guyversion < 14) // May 1 2009
{
if(tempguy.anim==a2FRMSLOW)
{
tempguy.anim=a2FRM;
tempguy.frate *= 2;
}
if(tempguy.e_anim==a2FRMSLOW)
{
tempguy.e_anim=a2FRM;
tempguy.e_frate *= 2;
}
if(tempguy.anim==aFLIPSLOW)
{
tempguy.anim=aFLIP;
tempguy.frate *= 2;
}
if(tempguy.e_anim==aFLIPSLOW)
{
tempguy.e_anim=aFLIP;
tempguy.e_frate *= 2;
}
if(tempguy.anim == aNEWDWALK) tempguy.anim = a4FRM4DIR;
if(tempguy.e_anim == aNEWDWALK) tempguy.e_anim = a4FRM4DIR;
if(tempguy.anim == aNEWPOLV || tempguy.anim == a4FRM3TRAP)
{
tempguy.anim=a4FRM4DIR;
tempguy.s_tile=(get_bit(quest_rules,qr_NEWENEMYTILES) ? tempguy.e_tile : tempguy.tile)+20;
}
if(tempguy.e_anim == aNEWPOLV || tempguy.e_anim == a4FRM3TRAP)
{
tempguy.e_anim=a4FRM4DIR;
tempguy.s_tile=(get_bit(quest_rules,qr_NEWENEMYTILES) ? tempguy.e_tile : tempguy.tile)+20;
}
}
if(!p_igetw(&(tempguy.dp),f,keepdata))
{
return qe_invalid;
}
//correction for guy fire
if(guyversion < 6)
{
if(i == gFIRE)
tempguy.dp = 2;
}
if(!p_igetw(&(tempguy.wdp),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.weapon),f,keepdata))
{
return qe_invalid;
}
//correction for bosses using triple, "rising" fireballs
if(guyversion < 5)
{
if(i == eLAQUAM || i == eRAQUAM || i == eGOHMA1 || i == eGOHMA2 ||
i == eGOHMA3 || i == eGOHMA4)
{
if(tempguy.weapon == ewFireball)
tempguy.weapon = ewFireball2;
}
}
if(!p_igetw(&(tempguy.rate),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.hrate),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.step),f,keepdata))
{
return qe_invalid;
}
// HIGHLY UNORTHODOX UPDATING THING, part 2
if(fixpolsvoice && tempguy.family==eePOLSV)
{
tempguy.step /= 2;
}
if(!p_igetw(&(tempguy.homing),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.grumble),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.item_set),f,keepdata))
{
return qe_invalid;
}
if(guyversion>=22) // Version 22: Expand misc attributes to 32 bits
{
if(!p_igetl(&(tempguy.misc1),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc2),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc3),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc4),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc5),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc6),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc7),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc8),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc9),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc10),f,keepdata))
{
return qe_invalid;
}
}
else
{
short tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc1=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc2=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc3=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc4=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc5=tempMisc;
if(guyversion < 13) // April 2009 - a tiny Wizzrobe update
{
if(tempguy.family == eeWIZZ && !(tempguy.misc1))
tempguy.misc5 = 74;
}
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc6=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc7=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc8=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc9=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc10=tempMisc;
}
if(!p_igetw(&(tempguy.bgsfx),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.bosspal),f,keepdata))
{
return qe_invalid;
}
if(!p_igetw(&(tempguy.extend),f,keepdata))
{
return qe_invalid;
}
if(guyversion >= 16) // November 2009 - Super Enemy Editor
{
for(int j=0; j<edefLAST; j++)
{
if(!p_getc(&(tempguy.defense[j]),f,keepdata))
{
return qe_invalid;
}
}
}
if(guyversion >= 18)
{
if(!p_getc(&(tempguy.hitsfx),f,keepdata))
{
return qe_invalid;
}
if(!p_getc(&(tempguy.deadsfx),f,keepdata))
{
return qe_invalid;
}
}
if(guyversion >= 22)
{
if(!p_igetl(&(tempguy.misc11),f,keepdata))
{
return qe_invalid;
}
if(!p_igetl(&(tempguy.misc12),f,keepdata))
{
return qe_invalid;
}
}
if(guyversion >= 23) // Add new guyversion conditional statement
{
for(int j=0; j<scriptDEFLAST; j++)
{
if(!p_getc(&(tempguy.scriptdefense[j]),f,keepdata))
{
return qe_invalid;
}
}
}
else if(guyversion >= 19)
{
short tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc11=tempMisc;
if(!p_igetw(&tempMisc,f,keepdata))
{
return qe_invalid;
}
tempguy.misc12=tempMisc;
}
//miscellaneous other corrections
//fix the mirror wizzrobe -DD
if(guyversion < 7)
{
if(i == eMWIZ)
{
tempguy.misc2 = 0;
tempguy.misc4 = 1;
}
}
if(guyversion < 8)
{
if(i == eGLEEOK1 || i == eGLEEOK2 || i == eGLEEOK3 || i == eGLEEOK4 || i == eGLEEOK1F || i == eGLEEOK2F || i == eGLEEOK3F || i == eGLEEOK4F)
{
// Some of these are deliberately different to NewDefault/defdata.cpp, by the way. -L
tempguy.misc5 = 4; //neck length in segments
tempguy.misc6 = 8; //neck offset from first body tile
tempguy.misc7 = 40; //offset for each subsequent neck tile from the first neck tile
tempguy.misc8 = 168; //head offset from first body tile
tempguy.misc9 = 228; //flying head offset from first body tile
if(i == eGLEEOK1F || i == eGLEEOK2F || i == eGLEEOK3F || i == eGLEEOK4F)
{
tempguy.misc6 += 10; //neck offset from first body tile
tempguy.misc8 -= 12; //head offset from first body tile
}
}
}
if(guyversion < 10) // December 2007 - Dodongo CSet fix
{
if(get_bit(deprecated_rules,46) && tempguy.family==eeDONGO && tempguy.misc1==0)
tempguy.bosspal = spDIG;
}
if(guyversion < 11) // December 2007 - Spinning Tile fix
{
if(tempguy.family==eeSPINTILE)
{
tempguy.flags |= guy_superman;
tempguy.item_set = 0; // Don't drop items
tempguy.step = 300;
}
}
if(guyversion < 12) // October 2008 - Flashing Bubble, Rope 2, and Ghini 2 fix
{
if(get_bit(deprecated_rules, qr_NOROPE2FLASH_DEP))
{
if(tempguy.family==eeROPE)
{
tempguy.flags2 &= ~guy_flashing;
}
}
if(get_bit(deprecated_rules, qr_NOBUBBLEFLASH_DEP))
{
if(tempguy.family==eeBUBBLE)
{
tempguy.flags2 &= ~guy_flashing;
}
}
if((tempguy.family==eeGHINI)&&(tempguy.misc1))
{
if(get_bit(deprecated_rules, qr_GHINI2BLINK_DEP))
{
tempguy.flags2 |= guy_blinking;
}
if(get_bit(deprecated_rules, qr_PHANTOMGHINI2_DEP))
{
tempguy.flags2 |= guy_transparent;
}
}
}
if(guyversion < 15) // July 2009 - Guy Fire and Fairy fix
{
if(i==gFIRE)
{
tempguy.e_anim = aFLIP;
tempguy.e_frate = 24;
}
if(i==gFAIRY)
{
tempguy.e_anim = a2FRM;
tempguy.e_frate = 16;
}
}
if(guyversion < 16) // November 2009 - Super Enemy Editor part 1
{
if(i==0) Z_message("Updating guys to version 16...\n");
update_guy_1(&tempguy);
if(i==eMPOLSV)
{
tempguy.defense[edefARROW] = edCHINK;
tempguy.defense[edefMAGIC] = ed1HKO;
tempguy.defense[edefREFMAGIC] = ed1HKO;
}
}
if(guyversion < 17) // December 2009
{
if(tempguy.family==eePROJECTILE)
{
tempguy.misc1 = 0;
}
}
if(guyversion < 18) // January 2010
{
bool boss = (tempguy.family == eeAQUA || tempguy.family==eeDONGO || tempguy.family == eeMANHAN || tempguy.family == eeGHOMA || tempguy.family==eeDIG
|| tempguy.family == eeGLEEOK || tempguy.family==eePATRA || tempguy.family == eeGANON || tempguy.family==eeMOLD);
tempguy.hitsfx = (boss && tempguy.family != eeMOLD && tempguy.family != eeDONGO && tempguy.family != eeDIG) ? WAV_GASP : 0;
tempguy.deadsfx = (boss && (tempguy.family != eeDIG || tempguy.misc10 == 0)) ? WAV_GASP : WAV_EDEAD;
if(tempguy.family == eeAQUA)
for(int j=0; j<edefLAST; j++) tempguy.defense[j] = default_guys[eRAQUAM].defense[j];
else if(tempguy.family == eeMANHAN)
for(int j=0; j<edefLAST; j++) tempguy.defense[j] = default_guys[eMANHAN].defense[j];
else if(tempguy.family==eePATRA)
for(int j=0; j<edefLAST; j++) tempguy.defense[j] = default_guys[eGLEEOK1].defense[j];
else if(tempguy.family==eeGHOMA)
{
for(int j=0; j<edefLAST; j++)
tempguy.defense[j] = default_guys[eGOHMA1].defense[j];
tempguy.defense[edefARROW] = ((tempguy.misc1==3) ? edCHINKL8 : (tempguy.misc1==2) ? edCHINKL4 : 0);
if(tempguy.misc1==3 && !tempguy.weapon) tempguy.weapon = ewFlame;
tempguy.misc1--;
}
else if(tempguy.family == eeGLEEOK)
{
for(int j=0; j<edefLAST; j++)
tempguy.defense[j] = default_guys[eGLEEOK1].defense[j];
if(tempguy.misc3==1 && !tempguy.weapon) tempguy.weapon = ewFlame;
}
else if(tempguy.family == eeARMOS)
{
tempguy.family=eeWALK;
tempguy.hrate = 0;
tempguy.misc10 = tempguy.misc1;
tempguy.misc1 = tempguy.misc2 = tempguy.misc3 = tempguy.misc4 = tempguy.misc5 = tempguy.misc6 = tempguy.misc7 = tempguy.misc8 = 0;
tempguy.misc9 = e9tARMOS;
}
else if(tempguy.family == eeGHINI && !tempguy.misc1)
{
tempguy.family=eeWALK;
tempguy.hrate = 0;
tempguy.misc1 = tempguy.misc2 = tempguy.misc3 = tempguy.misc4 = tempguy.misc5 = tempguy.misc6 =
tempguy.misc7 = tempguy.misc8 = tempguy.misc9 = tempguy.misc10 = 0;
}
// Spawn animation flags
if(tempguy.family == eeWALK && (tempguy.flags2&cmbflag_armos || tempguy.flags2&cmbflag_ghini))
tempguy.flags |= guy_fadeflicker;
else
tempguy.flags &= 0x0F00000F; // Get rid of the unused flags!
}
if(guyversion < 20) // April 2010
{
if(tempguy.family == eeTRAP)
{
tempguy.misc2 = tempguy.misc10;
if(tempguy.misc10>=1)
{
tempguy.misc1++;
}
tempguy.misc10 = 0;
}
// Bomb Blast fix
if(tempguy.weapon==ewBomb && tempguy.family!=eeROPE && (tempguy.family!=eeWALK || tempguy.misc2 != e2tBOMBCHU))
tempguy.weapon = ewLitBomb;
else if(tempguy.weapon==ewSBomb && tempguy.family!=eeROPE && (tempguy.family!=eeWALK || tempguy.misc2 != e2tBOMBCHU))
tempguy.weapon = ewLitSBomb;
}
if(guyversion < 21) // September 2011
{
if(tempguy.family == eeKEESE || tempguy.family == eeKEESETRIB)
{
if(tempguy.family == eeKEESETRIB)
{
tempguy.family = eeKEESE;
tempguy.misc2 = e2tKEESETRIB;
tempguy.misc1 = 0;
}
tempguy.rate = 2;
tempguy.hrate = 8;
tempguy.homing = 0;
tempguy.step= (tempguy.family == eeKEESE && tempguy.misc1 ? 100:62);
}
else if(tempguy.family == eePEAHAT || tempguy.family==eePATRA)
{
if(tempguy.family == eePEAHAT)
{
tempguy.rate = 4;
tempguy.step = 62;
}
else
tempguy.step = 25;
tempguy.hrate = 8;
tempguy.homing = 0;
}
else if(tempguy.family == eeDIG || tempguy.family == eeMANHAN)
{
if(tempguy.family == eeMANHAN)
tempguy.step=50;
tempguy.hrate = 16;
tempguy.homing = 0;
}
else if(tempguy.family == eeGLEEOK)
{
tempguy.rate = 2;
tempguy.homing = 0;
tempguy.hrate = 9;
tempguy.step=89;
}
else if(tempguy.family == eeGHINI)
{
tempguy.rate = 4;
tempguy.hrate = 12;
tempguy.step=62;
tempguy.homing = 0;
}
// Bigdig random rate fix
if(tempguy.family==eeDIG && tempguy.misc10==1)
{
tempguy.rate = 2;
}
}
if(guyversion < 24) // November 2012
{
if(tempguy.family==eeLANM)
tempguy.misc3 = 1;
else if(tempguy.family==eeMOLD)
tempguy.misc2 = 0;
}
if(keepdata)
{
guysbuf[i] = tempguy;
}
}
}
return 0;
}