2017-05-26 03:24:38 +00:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
2017-06-05 17:10:47 +00:00
|
|
|
|
|
|
|
#include "sludge/allfiles.h"
|
|
|
|
#include "sludge/sprites.h"
|
|
|
|
#include "sludge/sprbanks.h"
|
|
|
|
#include "sludge/sludger.h"
|
|
|
|
#include "sludge/objtypes.h"
|
|
|
|
#include "sludge/region.h"
|
|
|
|
#include "sludge/people.h"
|
|
|
|
#include "sludge/talk.h"
|
|
|
|
#include "sludge/newfatal.h"
|
|
|
|
#include "sludge/variable.h"
|
|
|
|
#include "sludge/moreio.h"
|
|
|
|
#include "sludge/loadsave.h"
|
|
|
|
#include "sludge/floor.h"
|
|
|
|
#include "sludge/zbuffer.h"
|
|
|
|
#include "sludge/sound.h"
|
|
|
|
#include "sludge/CommonCode/version.h"
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
#define ANGLEFIX (180.0 / 3.14157)
|
|
|
|
#define ANI_STAND 0
|
|
|
|
#define ANI_WALK 1
|
|
|
|
#define ANI_TALK 2
|
|
|
|
|
2017-05-26 19:25:11 +00:00
|
|
|
namespace Sludge {
|
|
|
|
|
2017-05-26 03:24:38 +00:00
|
|
|
extern speechStruct *speech;
|
|
|
|
|
|
|
|
extern variableStack *noStack;
|
|
|
|
|
|
|
|
extern int ssgVersion;
|
|
|
|
|
|
|
|
extern int cameraX, cameraY;
|
|
|
|
screenRegion personRegion;
|
|
|
|
extern screenRegion *lastRegion;
|
|
|
|
extern flor *currentFloor;
|
|
|
|
|
|
|
|
extern inputType input;
|
|
|
|
onScreenPerson *allPeople = NULL;
|
|
|
|
short int scaleHorizon = 75;
|
|
|
|
short int scaleDivide = 150;
|
|
|
|
extern screenRegion *allScreenRegions;
|
|
|
|
|
|
|
|
#define TF_max(a, b) ((a > b) ? a : b)
|
|
|
|
|
|
|
|
inline int TF_abs(int a) {
|
|
|
|
return (a > 0) ? a : -a;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setFrames(onScreenPerson &m, int a) {
|
2017-06-05 09:49:19 +00:00
|
|
|
m.myAnim = m.myPersona->animation[(a * m.myPersona->numDirections) + m.direction];
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
personaAnimation *createPersonaAnim(int num, variableStack *&stacky) {
|
|
|
|
personaAnimation *newP = new personaAnimation;
|
|
|
|
checkNew(newP);
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
newP->numFrames = num;
|
|
|
|
newP->frames = new animFrame[num];
|
|
|
|
checkNew(newP->frames);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
int a = num, frameNum, howMany;
|
|
|
|
|
|
|
|
while (a) {
|
2017-05-29 06:02:59 +00:00
|
|
|
a--;
|
2017-05-27 18:16:54 +00:00
|
|
|
newP->frames[a].noise = 0;
|
|
|
|
if (stacky->thisVar.varType == SVT_FILE) {
|
|
|
|
newP->frames[a].noise = stacky->thisVar.varData.intValue;
|
|
|
|
} else if (stacky->thisVar.varType == SVT_FUNC) {
|
2017-05-29 06:02:59 +00:00
|
|
|
newP->frames[a].noise = -stacky->thisVar.varData.intValue;
|
2017-05-27 18:16:54 +00:00
|
|
|
} else if (stacky->thisVar.varType == SVT_STACK) {
|
2017-06-05 09:49:19 +00:00
|
|
|
getValueType(frameNum, SVT_INT, stacky->thisVar.varData.theStack->first->thisVar);
|
|
|
|
getValueType(howMany, SVT_INT, stacky->thisVar.varData.theStack->first->next->thisVar);
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-27 18:16:54 +00:00
|
|
|
getValueType(frameNum, SVT_INT, stacky->thisVar);
|
2017-05-26 03:24:38 +00:00
|
|
|
howMany = 1;
|
|
|
|
}
|
|
|
|
trimStack(stacky);
|
2017-05-27 18:16:54 +00:00
|
|
|
newP->frames[a].frameNum = frameNum;
|
|
|
|
newP->frames[a].howMany = howMany;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return newP;
|
|
|
|
}
|
|
|
|
|
|
|
|
personaAnimation *makeNullAnim() {
|
2017-05-29 06:02:59 +00:00
|
|
|
personaAnimation *newAnim = new personaAnimation;
|
|
|
|
if (!checkNew(newAnim))
|
|
|
|
return NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
newAnim->theSprites = NULL;
|
|
|
|
newAnim->numFrames = 0;
|
|
|
|
newAnim->frames = NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
return newAnim;
|
|
|
|
}
|
|
|
|
|
|
|
|
personaAnimation *copyAnim(personaAnimation *orig) {
|
2017-05-27 18:16:54 +00:00
|
|
|
int num = orig->numFrames;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
personaAnimation *newAnim = new personaAnimation;
|
|
|
|
if (!checkNew(newAnim))
|
|
|
|
return NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// Copy the easy bits...
|
2017-05-29 06:02:59 +00:00
|
|
|
newAnim->theSprites = orig->theSprites;
|
|
|
|
newAnim->numFrames = num;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
if (num) {
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
// Argh!Frames!We need a whole NEW array of animFrame structures...
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
newAnim->frames = new animFrame[num];
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!checkNew(newAnim->frames))
|
|
|
|
return NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-06-05 10:03:50 +00:00
|
|
|
for (int a = 0; a < num; a++) {
|
2017-05-27 18:16:54 +00:00
|
|
|
newAnim->frames[a].frameNum = orig->frames[a].frameNum;
|
|
|
|
newAnim->frames[a].howMany = orig->frames[a].howMany;
|
|
|
|
newAnim->frames[a].noise = orig->frames[a].noise;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
} else {
|
2017-05-27 18:16:54 +00:00
|
|
|
newAnim->frames = NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return newAnim;
|
|
|
|
}
|
|
|
|
|
|
|
|
void deleteAnim(personaAnimation *orig) {
|
|
|
|
|
|
|
|
if (orig) {
|
2017-05-27 18:16:54 +00:00
|
|
|
if (orig->numFrames) {
|
|
|
|
delete[] orig->frames;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
delete orig;
|
|
|
|
orig = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void turnMeAngle(onScreenPerson *thisPerson, int direc) {
|
2017-05-27 18:16:54 +00:00
|
|
|
int d = thisPerson->myPersona->numDirections;
|
|
|
|
thisPerson->angle = direc;
|
|
|
|
direc += (180 / d) + 180 + thisPerson->angleOffset;
|
2017-05-29 06:02:59 +00:00
|
|
|
while (direc >= 360)
|
|
|
|
direc -= 360;
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->direction = (direc * d) / 360;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool initPeople() {
|
|
|
|
personRegion.sX = 0;
|
|
|
|
personRegion.sY = 0;
|
|
|
|
personRegion.di = -1;
|
|
|
|
allScreenRegions = NULL;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void spinStep(onScreenPerson *thisPerson) {
|
2017-05-27 18:16:54 +00:00
|
|
|
int diff = (thisPerson->angle + 360) - thisPerson->wantAngle;
|
2017-06-05 09:49:19 +00:00
|
|
|
int eachSlice = thisPerson->spinSpeed ? thisPerson->spinSpeed : (360 / thisPerson->myPersona->numDirections);
|
2017-05-26 03:24:38 +00:00
|
|
|
while (diff > 180) {
|
|
|
|
diff -= 360;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (diff >= eachSlice) {
|
2017-05-27 18:16:54 +00:00
|
|
|
turnMeAngle(thisPerson, thisPerson->angle - eachSlice);
|
2017-05-29 06:02:59 +00:00
|
|
|
} else if (diff <= -eachSlice) {
|
2017-05-27 18:16:54 +00:00
|
|
|
turnMeAngle(thisPerson, thisPerson->angle + eachSlice);
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-27 18:16:54 +00:00
|
|
|
turnMeAngle(thisPerson, thisPerson->wantAngle);
|
|
|
|
thisPerson->spinning = false;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void rethinkAngle(onScreenPerson *thisPerson) {
|
2017-05-27 18:16:54 +00:00
|
|
|
int d = thisPerson->myPersona->numDirections;
|
|
|
|
int direc = thisPerson->angle + (180 / d) + 180 + thisPerson->angleOffset;
|
2017-05-29 06:02:59 +00:00
|
|
|
while (direc >= 360)
|
|
|
|
direc -= 360;
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->direction = (direc * d) / 360;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool turnPersonToFace(int thisNum, int direc) {
|
|
|
|
onScreenPerson *thisPerson = findPerson(thisNum);
|
|
|
|
if (thisPerson) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (thisPerson->continueAfterWalking)
|
|
|
|
abortFunction(thisPerson->continueAfterWalking);
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->continueAfterWalking = NULL;
|
|
|
|
thisPerson->walking = false;
|
|
|
|
thisPerson->spinning = false;
|
2017-05-26 03:24:38 +00:00
|
|
|
turnMeAngle(thisPerson, direc);
|
2017-06-05 09:49:19 +00:00
|
|
|
setFrames(*thisPerson, (thisPerson == speech->currentTalker) ? ANI_TALK : ANI_STAND);
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool setPersonExtra(int thisNum, int extra) {
|
|
|
|
onScreenPerson *thisPerson = findPerson(thisNum);
|
|
|
|
if (thisPerson) {
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->extra = extra;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (extra & EXTRA_NOSCALE)
|
|
|
|
thisPerson->scale = 1;
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setScale(short int h, short int d) {
|
|
|
|
scaleHorizon = h;
|
|
|
|
scaleDivide = d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void moveAndScale(onScreenPerson &me, float x, float y) {
|
|
|
|
me.x = x;
|
|
|
|
me.y = y;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!(me.extra & EXTRA_NOSCALE) && scaleDivide)
|
|
|
|
me.scale = (me.y - scaleHorizon) / scaleDivide;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
onScreenPerson *findPerson(int v) {
|
|
|
|
onScreenPerson *thisPerson = allPeople;
|
|
|
|
while (thisPerson) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (v == thisPerson->thisType->objectNum)
|
|
|
|
break;
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson = thisPerson->next;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
return thisPerson;
|
|
|
|
}
|
|
|
|
|
|
|
|
void movePerson(int x, int y, int objNum) {
|
|
|
|
onScreenPerson *moveMe = findPerson(objNum);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (moveMe)
|
|
|
|
moveAndScale(*moveMe, x, y);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void setShown(bool h, int ob) {
|
|
|
|
onScreenPerson *moveMe = findPerson(ob);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (moveMe)
|
|
|
|
moveMe->show = h;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
enum drawModes {
|
|
|
|
drawModeNormal,
|
|
|
|
drawModeTransparent1,
|
|
|
|
drawModeTransparent2,
|
|
|
|
drawModeTransparent3,
|
|
|
|
drawModeDark1,
|
|
|
|
drawModeDark2,
|
|
|
|
drawModeDark3,
|
|
|
|
drawModeBlack,
|
|
|
|
drawModeShadow1,
|
|
|
|
drawModeShadow2,
|
|
|
|
drawModeShadow3,
|
|
|
|
drawModeFoggy1,
|
|
|
|
drawModeFoggy2,
|
|
|
|
drawModeFoggy3,
|
|
|
|
drawModeFoggy4,
|
|
|
|
drawModeGlow1,
|
|
|
|
drawModeGlow2,
|
|
|
|
drawModeGlow3,
|
|
|
|
drawModeGlow4,
|
|
|
|
drawModeInvisible,
|
|
|
|
numDrawModes
|
|
|
|
};
|
|
|
|
|
|
|
|
void setMyDrawMode(onScreenPerson *moveMe, int h) {
|
|
|
|
switch (h) {
|
2017-06-05 09:49:19 +00:00
|
|
|
case drawModeTransparent3:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 0;
|
|
|
|
moveMe->transparency = 64;
|
|
|
|
break;
|
|
|
|
case drawModeTransparent2:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 0;
|
|
|
|
moveMe->transparency = 128;
|
|
|
|
break;
|
|
|
|
case drawModeTransparent1:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 0;
|
|
|
|
moveMe->transparency = 192;
|
|
|
|
break;
|
|
|
|
case drawModeInvisible:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 0;
|
|
|
|
moveMe->transparency = 254;
|
|
|
|
break;
|
|
|
|
case drawModeDark1:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 192;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeDark2:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 128;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeDark3:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 64;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeBlack:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 255;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeShadow1:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 255;
|
|
|
|
moveMe->transparency = 64;
|
|
|
|
break;
|
|
|
|
case drawModeShadow2:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 255;
|
|
|
|
moveMe->transparency = 128;
|
|
|
|
break;
|
|
|
|
case drawModeShadow3:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 255;
|
|
|
|
moveMe->transparency = 192;
|
|
|
|
break;
|
|
|
|
case drawModeFoggy3:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 128;
|
|
|
|
moveMe->colourmix = 192;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeFoggy2:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 128;
|
|
|
|
moveMe->colourmix = 128;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeFoggy1:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 128;
|
|
|
|
moveMe->colourmix = 64;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeFoggy4:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 128;
|
|
|
|
moveMe->colourmix = 255;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeGlow3:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 255;
|
|
|
|
moveMe->colourmix = 192;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeGlow2:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 255;
|
|
|
|
moveMe->colourmix = 128;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeGlow1:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 255;
|
|
|
|
moveMe->colourmix = 64;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
case drawModeGlow4:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 255;
|
|
|
|
moveMe->colourmix = 255;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
moveMe->r = moveMe->g = moveMe->b = 0;
|
|
|
|
moveMe->colourmix = 0;
|
|
|
|
moveMe->transparency = 0;
|
|
|
|
break;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void setDrawMode(int h, int ob) {
|
|
|
|
onScreenPerson *moveMe = findPerson(ob);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!moveMe)
|
|
|
|
return;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
setMyDrawMode(moveMe, h);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setPersonTransparency(int ob, unsigned char x) {
|
|
|
|
onScreenPerson *moveMe = findPerson(ob);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!moveMe)
|
|
|
|
return;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
if (x > 254)
|
|
|
|
x = 254;
|
2017-05-26 03:24:38 +00:00
|
|
|
moveMe->transparency = x;
|
|
|
|
}
|
|
|
|
|
2017-06-05 09:49:19 +00:00
|
|
|
void setPersonColourise(int ob, unsigned char r, unsigned char g, unsigned char b, unsigned char colourmix) {
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson *moveMe = findPerson(ob);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!moveMe)
|
|
|
|
return;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
moveMe->r = r;
|
|
|
|
moveMe->g = g;
|
|
|
|
moveMe->b = b;
|
|
|
|
moveMe->colourmix = colourmix;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern screenRegion *overRegion;
|
|
|
|
|
|
|
|
void shufflePeople() {
|
2017-05-29 06:02:59 +00:00
|
|
|
onScreenPerson * * thisReference = &allPeople;
|
|
|
|
onScreenPerson *A, *B;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!allPeople)
|
|
|
|
return;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
while ((*thisReference)->next) {
|
|
|
|
float y1 = (*thisReference)->y;
|
|
|
|
if ((*thisReference)->extra & EXTRA_FRONT)
|
|
|
|
y1 += 1000;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
float y2 = (*thisReference)->next->y;
|
|
|
|
if ((*thisReference)->next->extra & EXTRA_FRONT)
|
|
|
|
y2 += 1000;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
if (y1 > y2) {
|
2017-05-29 06:02:59 +00:00
|
|
|
A = (*thisReference);
|
|
|
|
B = (*thisReference)->next;
|
2017-05-27 18:16:54 +00:00
|
|
|
A->next = B->next;
|
|
|
|
B->next = A;
|
2017-05-29 06:02:59 +00:00
|
|
|
(*thisReference) = B;
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-29 06:02:59 +00:00
|
|
|
thisReference = &((*thisReference)->next);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void drawPeople() {
|
|
|
|
shufflePeople();
|
|
|
|
|
|
|
|
onScreenPerson *thisPerson = allPeople;
|
|
|
|
personaAnimation *myAnim = NULL;
|
|
|
|
overRegion = NULL;
|
|
|
|
|
|
|
|
while (thisPerson) {
|
2017-05-27 18:16:54 +00:00
|
|
|
if (thisPerson->show) {
|
|
|
|
myAnim = thisPerson->myAnim;
|
|
|
|
if (myAnim != thisPerson->lastUsedAnim) {
|
|
|
|
thisPerson->lastUsedAnim = myAnim;
|
|
|
|
thisPerson->frameNum = 0;
|
|
|
|
thisPerson->frameTick = myAnim->frames[0].howMany;
|
|
|
|
if (myAnim->frames[thisPerson->frameNum].noise > 0) {
|
2017-06-05 09:49:19 +00:00
|
|
|
startSound(myAnim->frames[thisPerson->frameNum].noise, false);
|
2017-05-29 06:02:59 +00:00
|
|
|
thisPerson->frameNum++;
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->frameNum %= thisPerson->myAnim->numFrames;
|
2017-06-05 09:49:19 +00:00
|
|
|
thisPerson->frameTick = thisPerson->myAnim->frames[thisPerson->frameNum].howMany;
|
2017-05-27 18:16:54 +00:00
|
|
|
} else if (myAnim->frames[thisPerson->frameNum].noise) {
|
2017-06-05 09:49:19 +00:00
|
|
|
startNewFunctionNum(-myAnim->frames[thisPerson->frameNum].noise, 0,
|
|
|
|
NULL, noStack);
|
2017-05-29 06:02:59 +00:00
|
|
|
thisPerson->frameNum++;
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->frameNum %= thisPerson->myAnim->numFrames;
|
2017-06-05 09:49:19 +00:00
|
|
|
thisPerson->frameTick = thisPerson->myAnim->frames[thisPerson->frameNum].howMany;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
2017-05-27 18:16:54 +00:00
|
|
|
int fNumSign = myAnim->frames[thisPerson->frameNum].frameNum;
|
2017-05-26 03:24:38 +00:00
|
|
|
int m = fNumSign < 0;
|
|
|
|
int fNum = abs(fNumSign);
|
2017-05-27 18:16:54 +00:00
|
|
|
if (fNum >= myAnim->theSprites->bank.total) {
|
2017-05-26 03:24:38 +00:00
|
|
|
fNum = 0;
|
|
|
|
m = 2 - m;
|
|
|
|
}
|
|
|
|
if (m != 2) {
|
|
|
|
bool r = false;
|
2017-06-05 09:49:19 +00:00
|
|
|
r = scaleSprite(myAnim->theSprites->bank.sprites[fNum], myAnim->theSprites->bank.myPalette, thisPerson, m);
|
2017-05-26 03:24:38 +00:00
|
|
|
if (r) {
|
2017-05-27 18:16:54 +00:00
|
|
|
if (thisPerson->thisType->screenName[0]) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (personRegion.thisType != thisPerson->thisType)
|
|
|
|
lastRegion = NULL;
|
2017-05-27 18:16:54 +00:00
|
|
|
personRegion.thisType = thisPerson->thisType;
|
2017-05-29 06:02:59 +00:00
|
|
|
overRegion = &personRegion;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!--thisPerson->frameTick) {
|
|
|
|
thisPerson->frameNum++;
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->frameNum %= thisPerson->myAnim->numFrames;
|
2017-06-05 09:49:19 +00:00
|
|
|
thisPerson->frameTick = thisPerson->myAnim->frames[thisPerson->frameNum].howMany;
|
2017-05-27 18:16:54 +00:00
|
|
|
if (thisPerson->show && myAnim && myAnim->frames) {
|
|
|
|
if (myAnim->frames[thisPerson->frameNum].noise > 0) {
|
2017-06-05 09:49:19 +00:00
|
|
|
startSound(myAnim->frames[thisPerson->frameNum].noise, false);
|
2017-05-29 06:02:59 +00:00
|
|
|
thisPerson->frameNum++;
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->frameNum %= thisPerson->myAnim->numFrames;
|
2017-06-05 09:49:19 +00:00
|
|
|
thisPerson->frameTick = thisPerson->myAnim->frames[thisPerson->frameNum].howMany;
|
2017-05-27 18:16:54 +00:00
|
|
|
} else if (myAnim->frames[thisPerson->frameNum].noise) {
|
2017-06-05 09:49:19 +00:00
|
|
|
startNewFunctionNum(-myAnim->frames[thisPerson->frameNum].noise, 0,
|
|
|
|
NULL, noStack);
|
2017-05-29 06:02:59 +00:00
|
|
|
thisPerson->frameNum++;
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->frameNum %= thisPerson->myAnim->numFrames;
|
2017-06-05 09:49:19 +00:00
|
|
|
thisPerson->frameTick = thisPerson->myAnim->frames[thisPerson->frameNum].howMany;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson = thisPerson->next;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void makeTalker(onScreenPerson &me) {
|
|
|
|
setFrames(me, ANI_TALK);
|
|
|
|
}
|
|
|
|
|
|
|
|
void makeSilent(onScreenPerson &me) {
|
|
|
|
setFrames(me, ANI_STAND);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool handleClosestPoint(int &setX, int &setY, int &setPoly) {
|
2017-06-05 09:49:19 +00:00
|
|
|
int gotX = 320, gotY = 200, gotPoly = -1, i, j, xTest1, yTest1, xTest2, yTest2, closestX, closestY, oldJ, currentDistance = 0xFFFFF, thisDistance;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// FILE * dbug = fopen ("debug_closest.txt", "at");
|
|
|
|
// fprintf (dbug, "\nGetting closest point to %i, %i\n", setX, setY);
|
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
for (i = 0; i < currentFloor->numPolygons; i++) {
|
2017-05-27 18:16:54 +00:00
|
|
|
oldJ = currentFloor->polygon[i].numVertices - 1;
|
2017-05-29 06:02:59 +00:00
|
|
|
for (j = 0; j < currentFloor->polygon[i].numVertices; j++) {
|
2017-05-26 03:24:38 +00:00
|
|
|
// fprintf (dbug, "Polygon %i, line %i... ", i, j);
|
2017-06-05 09:49:19 +00:00
|
|
|
xTest1 = currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].x;
|
|
|
|
yTest1 = currentFloor->vertex[currentFloor->polygon[i].vertexID[j]].y;
|
|
|
|
xTest2 = currentFloor->vertex[currentFloor->polygon[i].vertexID[oldJ]].x;
|
|
|
|
yTest2 = currentFloor->vertex[currentFloor->polygon[i].vertexID[oldJ]].y;
|
|
|
|
closestPointOnLine(closestX, closestY, xTest1, yTest1, xTest2, yTest2, setX, setY);
|
2017-05-26 03:24:38 +00:00
|
|
|
// fprintf (dbug, "closest point is %i, %i... ", closestX, closestY);
|
|
|
|
xTest1 = setX - closestX;
|
|
|
|
yTest1 = setY - closestY;
|
|
|
|
thisDistance = xTest1 * xTest1 + yTest1 * yTest1;
|
|
|
|
// fprintf (dbug, "Distance squared %i\n", thisDistance);
|
|
|
|
|
|
|
|
if (thisDistance < currentDistance) {
|
2017-05-27 18:16:54 +00:00
|
|
|
// fprintf (dbug, "** We have a new winner!**\n");
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
currentDistance = thisDistance;
|
|
|
|
gotX = closestX;
|
|
|
|
gotY = closestY;
|
|
|
|
gotPoly = i;
|
|
|
|
}
|
|
|
|
oldJ = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// fclose (dbug);
|
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
if (gotPoly == -1)
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
setX = gotX;
|
|
|
|
setY = gotY;
|
|
|
|
setPoly = gotPoly;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool doBorderStuff(onScreenPerson *moveMe) {
|
2017-05-27 18:16:54 +00:00
|
|
|
if (moveMe->inPoly == moveMe->walkToPoly) {
|
|
|
|
moveMe->inPoly = -1;
|
|
|
|
moveMe->thisStepX = moveMe->walkToX;
|
|
|
|
moveMe->thisStepY = moveMe->walkToY;
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
|
|
|
// The section in which we need to be next...
|
2017-05-27 18:16:54 +00:00
|
|
|
int newPoly = currentFloor->matrix[moveMe->inPoly][moveMe->walkToPoly];
|
2017-05-29 06:02:59 +00:00
|
|
|
if (newPoly == -1)
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// Grab the index of the second matching corner...
|
|
|
|
int ID, ID2;
|
2017-06-05 09:49:19 +00:00
|
|
|
if (!getMatchingCorners(currentFloor->polygon[moveMe->inPoly], currentFloor->polygon[newPoly], ID, ID2))
|
2017-05-26 03:24:38 +00:00
|
|
|
return fatal("Not a valid floor plan!");
|
|
|
|
|
|
|
|
// Remember that we're walking to the new polygon...
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->inPoly = newPoly;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// Calculate the destination position on the coincidantal line...
|
2017-05-27 18:16:54 +00:00
|
|
|
int x1 = moveMe->x, y1 = moveMe->y;
|
|
|
|
int x2 = moveMe->walkToX, y2 = moveMe->walkToY;
|
|
|
|
int x3 = currentFloor->vertex[ID].x, y3 = currentFloor->vertex[ID].y;
|
|
|
|
int x4 = currentFloor->vertex[ID2].x, y4 = currentFloor->vertex[ID2].y;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
int xAB = x1 - x2;
|
|
|
|
int yAB = y1 - y2;
|
|
|
|
int xCD = x4 - x3;
|
|
|
|
int yCD = y4 - y3;
|
|
|
|
|
|
|
|
double m = (yAB * (x3 - x1) - xAB * (y3 - y1));
|
|
|
|
m /= ((xAB * yCD) - (yAB * xCD));
|
|
|
|
|
|
|
|
if (m > 0 && m < 1) {
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->thisStepX = x3 + m * xCD;
|
|
|
|
moveMe->thisStepY = y3 + m * yCD;
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
|
|
|
int dx13 = x1 - x3, dx14 = x1 - x4, dx23 = x2 - x3, dx24 = x2 - x4;
|
|
|
|
int dy13 = y1 - y3, dy14 = y1 - y4, dy23 = y2 - y3, dy24 = y2 - y4;
|
|
|
|
|
|
|
|
dx13 *= dx13;
|
|
|
|
dx14 *= dx14;
|
|
|
|
dx23 *= dx23;
|
|
|
|
dx24 *= dx24;
|
|
|
|
dy13 *= dy13;
|
|
|
|
dy14 *= dy14;
|
|
|
|
dy23 *= dy23;
|
|
|
|
dy24 *= dy24;
|
|
|
|
|
2017-06-05 09:49:19 +00:00
|
|
|
if (sqrt((double)dx13 + dy13) + sqrt((double)dx23 + dy23) < sqrt((double)dx14 + dy14) + sqrt((double)dx24 + dy24)) {
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->thisStepX = x3;
|
|
|
|
moveMe->thisStepY = y3;
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->thisStepX = x4;
|
|
|
|
moveMe->thisStepY = y4;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
float yDiff = moveMe->thisStepY - moveMe->y;
|
|
|
|
float xDiff = moveMe->x - moveMe->thisStepX;
|
2017-05-26 03:24:38 +00:00
|
|
|
if (xDiff || yDiff) {
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->wantAngle = 180 + ANGLEFIX * atan2(xDiff, yDiff * 2);
|
|
|
|
moveMe->spinning = true;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
setFrames(*moveMe, ANI_WALK);
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool walkMe(onScreenPerson *thisPerson, bool move = true) {
|
|
|
|
float xDiff, yDiff, maxDiff, s;
|
|
|
|
|
|
|
|
for (;;) {
|
2017-05-27 18:16:54 +00:00
|
|
|
xDiff = thisPerson->thisStepX - thisPerson->x;
|
|
|
|
yDiff = (thisPerson->thisStepY - thisPerson->y) * 2;
|
|
|
|
s = thisPerson->scale * thisPerson->walkSpeed;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (s < 0.2)
|
|
|
|
s = 0.2;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-06-05 09:49:19 +00:00
|
|
|
maxDiff = (TF_abs(xDiff) >= TF_abs(yDiff)) ? TF_abs(xDiff) : TF_abs(yDiff);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
if (TF_abs(maxDiff) > s) {
|
2017-05-27 18:16:54 +00:00
|
|
|
if (thisPerson->spinning) {
|
2017-05-26 03:24:38 +00:00
|
|
|
spinStep(thisPerson);
|
2017-05-29 06:02:59 +00:00
|
|
|
setFrames(*thisPerson, ANI_WALK);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
s = maxDiff / s;
|
|
|
|
if (move)
|
2017-06-05 09:49:19 +00:00
|
|
|
moveAndScale(*thisPerson, thisPerson->x + xDiff / s, thisPerson->y + yDiff / (s * 2));
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
if (thisPerson->inPoly == -1) {
|
|
|
|
if (thisPerson->directionWhenDoneWalking != -1) {
|
|
|
|
thisPerson->wantAngle = thisPerson->directionWhenDoneWalking;
|
|
|
|
thisPerson->spinning = true;
|
2017-05-26 03:24:38 +00:00
|
|
|
spinStep(thisPerson);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!doBorderStuff(thisPerson))
|
|
|
|
break;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson->walking = false;
|
2017-05-29 06:02:59 +00:00
|
|
|
setFrames(*thisPerson, ANI_STAND);
|
|
|
|
moveAndScale(*thisPerson, thisPerson->walkToX, thisPerson->walkToY);
|
2017-05-26 03:24:38 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool makeWalkingPerson(int x, int y, int objNum, loadedFunction *func, int di) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (x == 0 && y == 0)
|
|
|
|
return false;
|
|
|
|
if (currentFloor->numPolygons == 0)
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson *moveMe = findPerson(objNum);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!moveMe)
|
|
|
|
return false;
|
2017-05-27 18:16:54 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
if (moveMe->continueAfterWalking)
|
|
|
|
abortFunction(moveMe->continueAfterWalking);
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->continueAfterWalking = NULL;
|
|
|
|
moveMe->walking = true;
|
|
|
|
moveMe->directionWhenDoneWalking = di;
|
|
|
|
|
|
|
|
moveMe->walkToX = x;
|
|
|
|
moveMe->walkToY = y;
|
|
|
|
moveMe->walkToPoly = inFloor(x, y);
|
|
|
|
if (moveMe->walkToPoly == -1) {
|
2017-06-05 09:49:19 +00:00
|
|
|
if (!handleClosestPoint(moveMe->walkToX, moveMe->walkToY, moveMe->walkToPoly))
|
2017-05-29 06:02:59 +00:00
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->inPoly = inFloor(moveMe->x, moveMe->y);
|
|
|
|
if (moveMe->inPoly == -1) {
|
|
|
|
int xxx = moveMe->x, yyy = moveMe->y;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!handleClosestPoint(xxx, yyy, moveMe->inPoly))
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
doBorderStuff(moveMe);
|
2017-05-27 18:16:54 +00:00
|
|
|
if (walkMe(moveMe, false) || moveMe->spinning) {
|
|
|
|
moveMe->continueAfterWalking = func;
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool stopPerson(int o) {
|
|
|
|
onScreenPerson *moveMe = findPerson(o);
|
|
|
|
if (moveMe)
|
2017-05-27 18:16:54 +00:00
|
|
|
if (moveMe->continueAfterWalking) {
|
|
|
|
abortFunction(moveMe->continueAfterWalking);
|
|
|
|
moveMe->continueAfterWalking = NULL;
|
|
|
|
moveMe->walking = false;
|
|
|
|
moveMe->spinning = false;
|
2017-05-29 06:02:59 +00:00
|
|
|
setFrames(*moveMe, ANI_STAND);
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-06-05 09:49:19 +00:00
|
|
|
bool forceWalkingPerson(int x, int y, int objNum, loadedFunction *func, int di) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (x == 0 && y == 0)
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson *moveMe = findPerson(objNum);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!moveMe)
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
if (moveMe->continueAfterWalking)
|
|
|
|
abortFunction(moveMe->continueAfterWalking);
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->walking = true;
|
|
|
|
moveMe->continueAfterWalking = NULL;
|
|
|
|
moveMe->directionWhenDoneWalking = di;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->walkToX = x;
|
|
|
|
moveMe->walkToY = y;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// Let's pretend the start and end points are both in the same
|
|
|
|
// polygon (which one isn't important)
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->inPoly = 0;
|
|
|
|
moveMe->walkToPoly = 0;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
doBorderStuff(moveMe);
|
2017-05-27 18:16:54 +00:00
|
|
|
if (walkMe(moveMe) || moveMe->spinning) {
|
|
|
|
moveMe->continueAfterWalking = func;
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void jumpPerson(int x, int y, int objNum) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (x == 0 && y == 0)
|
|
|
|
return;
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson *moveMe = findPerson(objNum);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!moveMe)
|
|
|
|
return;
|
|
|
|
if (moveMe->continueAfterWalking)
|
|
|
|
abortFunction(moveMe->continueAfterWalking);
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->continueAfterWalking = NULL;
|
|
|
|
moveMe->walking = false;
|
|
|
|
moveMe->spinning = false;
|
2017-05-29 06:02:59 +00:00
|
|
|
moveAndScale(*moveMe, x, y);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool floatCharacter(int f, int objNum) {
|
|
|
|
onScreenPerson *moveMe = findPerson(objNum);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!moveMe)
|
|
|
|
return false;
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->floaty = f;
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool setCharacterWalkSpeed(int f, int objNum) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (f <= 0)
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson *moveMe = findPerson(objNum);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!moveMe)
|
|
|
|
return false;
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->walkSpeed = f;
|
2017-05-26 03:24:38 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void walkAllPeople() {
|
|
|
|
onScreenPerson *thisPerson = allPeople;
|
|
|
|
|
|
|
|
while (thisPerson) {
|
2017-05-27 18:16:54 +00:00
|
|
|
if (thisPerson->walking) {
|
2017-05-26 03:24:38 +00:00
|
|
|
walkMe(thisPerson);
|
2017-05-27 18:16:54 +00:00
|
|
|
} else if (thisPerson->spinning) {
|
2017-05-26 03:24:38 +00:00
|
|
|
spinStep(thisPerson);
|
2017-05-29 06:02:59 +00:00
|
|
|
setFrames(*thisPerson, ANI_STAND);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
2017-06-05 09:49:19 +00:00
|
|
|
if ((!thisPerson->walking) && (!thisPerson->spinning) && thisPerson->continueAfterWalking) {
|
2017-05-27 18:16:54 +00:00
|
|
|
restartFunction(thisPerson->continueAfterWalking);
|
|
|
|
thisPerson->continueAfterWalking = NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
2017-05-27 18:16:54 +00:00
|
|
|
thisPerson = thisPerson->next;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool addPerson(int x, int y, int objNum, persona *p) {
|
|
|
|
onScreenPerson *newPerson = new onScreenPerson;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!checkNew(newPerson))
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// EASY STUFF
|
2017-05-27 18:16:54 +00:00
|
|
|
newPerson->thisType = loadObjectType(objNum);
|
|
|
|
newPerson->scale = 1;
|
|
|
|
newPerson->extra = 0;
|
|
|
|
newPerson->continueAfterWalking = NULL;
|
2017-05-29 06:02:59 +00:00
|
|
|
moveAndScale(*newPerson, x, y);
|
2017-05-27 18:16:54 +00:00
|
|
|
newPerson->frameNum = 0;
|
|
|
|
newPerson->walkToX = x;
|
|
|
|
newPerson->walkToY = y;
|
|
|
|
newPerson->walking = false;
|
|
|
|
newPerson->spinning = false;
|
|
|
|
newPerson->show = true;
|
|
|
|
newPerson->direction = 0;
|
|
|
|
newPerson->angle = 180;
|
|
|
|
newPerson->wantAngle = 180;
|
|
|
|
newPerson->angleOffset = 0;
|
|
|
|
newPerson->floaty = 0;
|
|
|
|
newPerson->walkSpeed = newPerson->thisType->walkSpeed;
|
|
|
|
newPerson->myAnim = NULL;
|
|
|
|
newPerson->spinSpeed = newPerson->thisType->spinSpeed;
|
|
|
|
newPerson->r = 0;
|
|
|
|
newPerson->g = 0;
|
|
|
|
newPerson->b = 0;
|
|
|
|
newPerson->colourmix = 0;
|
|
|
|
newPerson->transparency = 0;
|
|
|
|
newPerson->myPersona = p;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
setFrames(*newPerson, ANI_STAND);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// HEIGHT (BASED ON 1st FRAME OF 1st ANIMATION... INC. SPECIAL CASES)
|
2017-05-27 18:16:54 +00:00
|
|
|
int fNumSigned = p->animation[0]->frames[0].frameNum;
|
2017-05-26 03:24:38 +00:00
|
|
|
int fNum = abs(fNumSigned);
|
2017-05-27 18:16:54 +00:00
|
|
|
if (fNum >= p->animation[0]->theSprites->bank.total) {
|
2017-05-26 03:24:38 +00:00
|
|
|
if (fNumSigned < 0) {
|
2017-05-27 18:16:54 +00:00
|
|
|
newPerson->height = 5;
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-06-05 09:49:19 +00:00
|
|
|
newPerson->height = p->animation[0]->theSprites->bank.sprites[0].yhot + 5;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
} else {
|
2017-06-05 09:49:19 +00:00
|
|
|
newPerson->height = p->animation[0]->theSprites->bank.sprites[fNum].yhot + 5;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// NOW ADD IT IN THE RIGHT PLACE
|
2017-05-29 06:02:59 +00:00
|
|
|
onScreenPerson * * changethat = &allPeople;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
while (((*changethat) != NULL) && ((*changethat)->y < y))
|
|
|
|
changethat = &((*changethat)->next);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
newPerson->next = (*changethat);
|
|
|
|
(*changethat) = newPerson;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-06-05 09:49:19 +00:00
|
|
|
return (bool)(newPerson->thisType != NULL);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int timeForAnim(personaAnimation *fram) {
|
|
|
|
int total = 0;
|
2017-06-05 10:03:50 +00:00
|
|
|
for (int a = 0; a < fram->numFrames; a++) {
|
2017-05-27 18:16:54 +00:00
|
|
|
total += fram->frames[a].howMany;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
void animatePerson(int obj, personaAnimation *fram) { // Set a new SINGLE animation
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson *moveMe = findPerson(obj);
|
|
|
|
if (moveMe) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (moveMe->continueAfterWalking)
|
|
|
|
abortFunction(moveMe->continueAfterWalking);
|
2017-05-27 18:16:54 +00:00
|
|
|
moveMe->continueAfterWalking = NULL;
|
|
|
|
moveMe->walking = false;
|
|
|
|
moveMe->spinning = false;
|
|
|
|
moveMe->myAnim = fram;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void animatePerson(int obj, persona *per) { // Set a new costume
|
|
|
|
onScreenPerson *moveMe = findPerson(obj);
|
|
|
|
if (moveMe) {
|
2017-05-27 18:16:54 +00:00
|
|
|
// if (moveMe->continueAfterWalking) abortFunction (moveMe->continueAfterWalking);
|
|
|
|
// moveMe->continueAfterWalking = NULL;
|
|
|
|
// moveMe->walking = false;
|
|
|
|
moveMe->spinning = false;
|
|
|
|
moveMe->myPersona = per;
|
2017-05-26 03:24:38 +00:00
|
|
|
rethinkAngle(moveMe);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (moveMe->walking) {
|
|
|
|
setFrames(*moveMe, ANI_WALK);
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-29 06:02:59 +00:00
|
|
|
setFrames(*moveMe, ANI_STAND);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void killAllPeople() {
|
|
|
|
onScreenPerson *killPeople;
|
|
|
|
while (allPeople) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (allPeople->continueAfterWalking)
|
|
|
|
abortFunction(allPeople->continueAfterWalking);
|
2017-05-27 18:16:54 +00:00
|
|
|
allPeople->continueAfterWalking = NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
killPeople = allPeople;
|
2017-05-27 18:16:54 +00:00
|
|
|
allPeople = allPeople->next;
|
|
|
|
removeObjectType(killPeople->thisType);
|
2017-05-26 03:24:38 +00:00
|
|
|
delete killPeople;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void killMostPeople() {
|
|
|
|
onScreenPerson *killPeople;
|
2017-05-29 06:02:59 +00:00
|
|
|
onScreenPerson * * lookyHere = &allPeople;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
while (*lookyHere) {
|
|
|
|
if ((*lookyHere)->extra & EXTRA_NOREMOVE) {
|
|
|
|
lookyHere = &(*lookyHere)->next;
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-29 06:02:59 +00:00
|
|
|
killPeople = (*lookyHere);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// Change last pointer to NEXT in the list instead
|
2017-05-29 06:02:59 +00:00
|
|
|
(*lookyHere) = killPeople->next;
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// Gone from the list... now free some memory
|
2017-05-29 06:02:59 +00:00
|
|
|
if (killPeople->continueAfterWalking)
|
|
|
|
abortFunction(killPeople->continueAfterWalking);
|
2017-05-27 18:16:54 +00:00
|
|
|
killPeople->continueAfterWalking = NULL;
|
|
|
|
removeObjectType(killPeople->thisType);
|
2017-05-26 03:24:38 +00:00
|
|
|
delete killPeople;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void removeOneCharacter(int i) {
|
|
|
|
onScreenPerson *p = findPerson(i);
|
|
|
|
|
|
|
|
if (p) {
|
2017-06-05 09:49:19 +00:00
|
|
|
if (overRegion == &personRegion && overRegion->thisType == p->thisType) {
|
2017-05-26 03:24:38 +00:00
|
|
|
overRegion = NULL;
|
|
|
|
}
|
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
if (p->continueAfterWalking)
|
|
|
|
abortFunction(p->continueAfterWalking);
|
2017-05-27 18:16:54 +00:00
|
|
|
p->continueAfterWalking = NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson * * killPeople;
|
|
|
|
|
2017-06-05 09:49:19 +00:00
|
|
|
for (killPeople = &allPeople; *killPeople != p; killPeople = &((*killPeople)->next)) {
|
2017-05-26 03:24:38 +00:00
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
*killPeople = p->next;
|
2017-05-27 18:16:54 +00:00
|
|
|
removeObjectType(p->thisType);
|
2017-05-26 03:24:38 +00:00
|
|
|
delete p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
bool saveAnim(personaAnimation *p, Common::WriteStream *stream) {
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeUint16BE(p->numFrames);
|
2017-05-27 18:16:54 +00:00
|
|
|
if (p->numFrames) {
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeUint32LE(p->theSprites->ID);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-06-05 10:03:50 +00:00
|
|
|
for (int a = 0; a < p->numFrames; a++) {
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeUint32LE(p->frames[a].frameNum);
|
|
|
|
stream->writeUint32LE(p->frames[a].howMany);
|
|
|
|
stream->writeUint32LE(p->frames[a].noise);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
bool loadAnim(personaAnimation *p, Common::SeekableReadStream *stream) {
|
2017-05-30 07:59:56 +00:00
|
|
|
p->numFrames = stream->readUint16BE();
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
if (p->numFrames) {
|
2017-05-30 07:59:56 +00:00
|
|
|
int a = stream->readUint32LE();
|
2017-05-27 18:16:54 +00:00
|
|
|
p->frames = new animFrame[p->numFrames];
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!checkNew(p->frames))
|
|
|
|
return false;
|
2017-05-27 18:16:54 +00:00
|
|
|
p->theSprites = loadBankForAnim(a);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-06-05 10:03:50 +00:00
|
|
|
for (a = 0; a < p->numFrames; a++) {
|
2017-05-30 07:59:56 +00:00
|
|
|
p->frames[a].frameNum = stream->readUint32LE();
|
|
|
|
p->frames[a].howMany = stream->readUint32LE();
|
2017-05-26 03:24:38 +00:00
|
|
|
if (ssgVersion >= VERSION(2, 0)) {
|
2017-05-30 07:59:56 +00:00
|
|
|
p->frames[a].noise = stream->readUint32LE();
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-27 18:16:54 +00:00
|
|
|
p->frames[a].noise = 0;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2017-05-27 18:16:54 +00:00
|
|
|
p->theSprites = NULL;
|
|
|
|
p->frames = NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/*
|
2017-05-29 06:02:59 +00:00
|
|
|
void debugCostume (char * message, persona * cossy) {
|
|
|
|
FILE * db = fopen ("debuTURN.txt", "at");
|
|
|
|
fprintf (db, " %s costume with %i directions...\n", message, cossy->numDirections);
|
2017-06-05 10:03:50 +00:00
|
|
|
for (int a = 0; a < cossy->numDirections * 3; a++) {
|
2017-05-29 06:02:59 +00:00
|
|
|
fprintf (db, " %i frames:", cossy->animation[a]->numFrames);
|
|
|
|
for (int b = 0; b < cossy->animation[a]->numFrames; b ++) {
|
|
|
|
fprintf (db, " %i", cossy->animation[a]->frames[b]);
|
|
|
|
}
|
|
|
|
fprintf (db, "\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
fclose (db);
|
|
|
|
}
|
|
|
|
*/
|
2017-05-27 18:16:54 +00:00
|
|
|
bool saveCostume(persona *cossy, Common::WriteStream *stream) {
|
2017-05-26 03:24:38 +00:00
|
|
|
int a;
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeUint16BE(cossy->numDirections);
|
2017-06-05 10:03:50 +00:00
|
|
|
for (a = 0; a < cossy->numDirections * 3; a++) {
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!saveAnim(cossy->animation[a], stream))
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
// debugCostume ("Saved", cossy);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
bool loadCostume(persona *cossy, Common::SeekableReadStream *stream) {
|
2017-05-26 03:24:38 +00:00
|
|
|
int a;
|
2017-05-30 07:59:56 +00:00
|
|
|
cossy->numDirections = stream->readUint16BE();
|
2017-05-29 06:02:59 +00:00
|
|
|
cossy->animation = new personaAnimation *[cossy->numDirections * 3];
|
|
|
|
if (!checkNew(cossy->animation))
|
|
|
|
return false;
|
2017-06-05 10:03:50 +00:00
|
|
|
for (a = 0; a < cossy->numDirections * 3; a++) {
|
2017-05-27 18:16:54 +00:00
|
|
|
cossy->animation[a] = new personaAnimation;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!checkNew(cossy->animation[a]))
|
|
|
|
return false;
|
2017-05-27 18:16:54 +00:00
|
|
|
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!loadAnim(cossy->animation[a], stream))
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
// debugCostume ("Loaded", cossy);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
bool savePeople(Common::WriteStream *stream) {
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson *me = allPeople;
|
|
|
|
int countPeople = 0, a;
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
putSigned(scaleHorizon, stream);
|
|
|
|
putSigned(scaleDivide, stream);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
while (me) {
|
2017-05-29 06:02:59 +00:00
|
|
|
countPeople++;
|
2017-05-27 18:16:54 +00:00
|
|
|
me = me->next;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeUint16BE(countPeople);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
me = allPeople;
|
2017-06-05 10:03:50 +00:00
|
|
|
for (a = 0; a < countPeople; a++) {
|
2017-05-27 18:16:54 +00:00
|
|
|
|
|
|
|
putFloat(me->x, stream);
|
|
|
|
putFloat(me->y, stream);
|
|
|
|
|
|
|
|
saveCostume(me->myPersona, stream);
|
|
|
|
saveAnim(me->myAnim, stream);
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeByte(me->myAnim == me->lastUsedAnim);
|
2017-05-27 18:16:54 +00:00
|
|
|
|
|
|
|
putFloat(me->scale, stream);
|
|
|
|
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeUint16BE(me->extra);
|
|
|
|
stream->writeUint16BE(me->height);
|
|
|
|
stream->writeUint16BE(me->walkToX);
|
|
|
|
stream->writeUint16BE(me->walkToY);
|
|
|
|
stream->writeUint16BE(me->thisStepX);
|
|
|
|
stream->writeUint16BE(me->thisStepY);
|
|
|
|
stream->writeUint16BE(me->frameNum);
|
|
|
|
stream->writeUint16BE(me->frameTick);
|
|
|
|
stream->writeUint16BE(me->walkSpeed);
|
|
|
|
stream->writeUint16BE(me->spinSpeed);
|
2017-05-27 18:16:54 +00:00
|
|
|
putSigned(me->floaty, stream);
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeByte(me->show);
|
|
|
|
stream->writeByte(me->walking);
|
|
|
|
stream->writeByte(me->spinning);
|
2017-05-27 18:16:54 +00:00
|
|
|
if (me->continueAfterWalking) {
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeByte(1);
|
2017-05-27 18:16:54 +00:00
|
|
|
saveFunction(me->continueAfterWalking, stream);
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeByte(0);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeUint16BE(me->direction);
|
|
|
|
stream->writeUint16BE(me->angle);
|
|
|
|
stream->writeUint16BE(me->angleOffset);
|
|
|
|
stream->writeUint16BE(me->wantAngle);
|
2017-05-27 18:16:54 +00:00
|
|
|
putSigned(me->directionWhenDoneWalking, stream);
|
|
|
|
putSigned(me->inPoly, stream);
|
|
|
|
putSigned(me->walkToPoly, stream);
|
|
|
|
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->writeByte(me->r);
|
|
|
|
stream->writeByte(me->g);
|
|
|
|
stream->writeByte(me->b);
|
|
|
|
stream->writeByte(me->colourmix);
|
|
|
|
stream->writeByte(me->transparency);
|
2017-05-27 18:16:54 +00:00
|
|
|
|
|
|
|
saveObjectRef(me->thisType, stream);
|
|
|
|
|
|
|
|
me = me->next;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
bool loadPeople(Common::SeekableReadStream *stream) {
|
2017-05-29 06:02:59 +00:00
|
|
|
onScreenPerson * * pointy = &allPeople;
|
2017-05-26 03:24:38 +00:00
|
|
|
onScreenPerson *me;
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
scaleHorizon = getSigned(stream);
|
|
|
|
scaleDivide = getSigned(stream);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
2017-05-30 07:59:56 +00:00
|
|
|
int countPeople = stream->readUint16BE();
|
2017-05-26 03:24:38 +00:00
|
|
|
int a;
|
|
|
|
|
|
|
|
allPeople = NULL;
|
2017-06-05 10:03:50 +00:00
|
|
|
for (a = 0; a < countPeople; a++) {
|
2017-05-26 03:24:38 +00:00
|
|
|
me = new onScreenPerson;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!checkNew(me))
|
|
|
|
return false;
|
2017-05-27 18:16:54 +00:00
|
|
|
|
|
|
|
me->myPersona = new persona;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!checkNew(me->myPersona))
|
|
|
|
return false;
|
2017-05-27 18:16:54 +00:00
|
|
|
|
|
|
|
me->myAnim = new personaAnimation;
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!checkNew(me->myAnim))
|
|
|
|
return false;
|
2017-05-27 18:16:54 +00:00
|
|
|
|
|
|
|
me->x = getFloat(stream);
|
|
|
|
me->y = getFloat(stream);
|
|
|
|
|
|
|
|
loadCostume(me->myPersona, stream);
|
|
|
|
loadAnim(me->myAnim, stream);
|
|
|
|
|
2017-05-30 07:59:56 +00:00
|
|
|
me->lastUsedAnim = stream->readByte() ? me->myAnim : NULL;
|
2017-05-27 18:16:54 +00:00
|
|
|
|
|
|
|
me->scale = getFloat(stream);
|
|
|
|
|
2017-05-30 07:59:56 +00:00
|
|
|
me->extra = stream->readUint16BE();
|
|
|
|
me->height = stream->readUint16BE();
|
|
|
|
me->walkToX = stream->readUint16BE();
|
|
|
|
me->walkToY = stream->readUint16BE();
|
|
|
|
me->thisStepX = stream->readUint16BE();
|
|
|
|
me->thisStepY = stream->readUint16BE();
|
|
|
|
me->frameNum = stream->readUint16BE();
|
|
|
|
me->frameTick = stream->readUint16BE();
|
|
|
|
me->walkSpeed = stream->readUint16BE();
|
|
|
|
me->spinSpeed = stream->readUint16BE();
|
2017-05-27 18:16:54 +00:00
|
|
|
me->floaty = getSigned(stream);
|
2017-05-30 07:59:56 +00:00
|
|
|
me->show = stream->readByte();
|
|
|
|
me->walking = stream->readByte();
|
|
|
|
me->spinning = stream->readByte();
|
|
|
|
if (stream->readByte()) {
|
2017-05-27 18:16:54 +00:00
|
|
|
me->continueAfterWalking = loadFunction(stream);
|
2017-05-29 06:02:59 +00:00
|
|
|
if (!me->continueAfterWalking)
|
|
|
|
return false;
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-27 18:16:54 +00:00
|
|
|
me->continueAfterWalking = NULL;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
2017-05-30 07:59:56 +00:00
|
|
|
me->direction = stream->readUint16BE();
|
|
|
|
me->angle = stream->readUint16BE();
|
2017-05-26 03:24:38 +00:00
|
|
|
if (ssgVersion >= VERSION(2, 0)) {
|
2017-05-30 07:59:56 +00:00
|
|
|
me->angleOffset = stream->readUint16BE();
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-27 18:16:54 +00:00
|
|
|
me->angleOffset = 0;
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
2017-05-30 07:59:56 +00:00
|
|
|
me->wantAngle = stream->readUint16BE();
|
2017-05-27 18:16:54 +00:00
|
|
|
me->directionWhenDoneWalking = getSigned(stream);
|
|
|
|
me->inPoly = getSigned(stream);
|
|
|
|
me->walkToPoly = getSigned(stream);
|
2017-05-26 03:24:38 +00:00
|
|
|
if (ssgVersion >= VERSION(2, 0)) {
|
2017-05-30 07:59:56 +00:00
|
|
|
me->r = stream->readByte();
|
|
|
|
me->g = stream->readByte();
|
|
|
|
me->b = stream->readByte();
|
|
|
|
me->colourmix = stream->readByte();
|
|
|
|
me->transparency = stream->readByte();
|
2017-05-26 03:24:38 +00:00
|
|
|
} else {
|
2017-05-30 07:59:56 +00:00
|
|
|
setMyDrawMode(me, stream->readUint16BE());
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
2017-05-27 18:16:54 +00:00
|
|
|
me->thisType = loadObjectRef(stream);
|
2017-05-26 03:24:38 +00:00
|
|
|
|
|
|
|
// Anti-aliasing settings
|
|
|
|
if (ssgVersion >= VERSION(1, 6)) {
|
|
|
|
if (ssgVersion < VERSION(2, 0)) {
|
|
|
|
// aaLoad
|
2017-05-30 07:59:56 +00:00
|
|
|
stream->readByte();
|
2017-05-27 18:16:54 +00:00
|
|
|
getFloat(stream);
|
|
|
|
getFloat(stream);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-27 18:16:54 +00:00
|
|
|
me->next = NULL;
|
2017-05-29 06:02:59 +00:00
|
|
|
*pointy = me;
|
|
|
|
pointy = &(me->next);
|
2017-05-26 03:24:38 +00:00
|
|
|
}
|
|
|
|
// db ("End of loadPeople");
|
|
|
|
return true;
|
|
|
|
}
|
2017-05-26 19:25:11 +00:00
|
|
|
|
|
|
|
} // End of namespace Sludge
|