diff options
Diffstat (limited to '')
| -rw-r--r-- | src/koopatlas/mapdata.cpp | 10 | ||||
| -rw-r--r-- | src/koopatlas/mapdata.h | 10 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.cpp | 108 | ||||
| -rw-r--r-- | src/koopatlas/pathmanager.h | 7 | 
4 files changed, 128 insertions, 7 deletions
| diff --git a/src/koopatlas/mapdata.cpp b/src/koopatlas/mapdata.cpp index 9c84c4a..dd4646b 100644 --- a/src/koopatlas/mapdata.cpp +++ b/src/koopatlas/mapdata.cpp @@ -173,6 +173,7 @@ void dKPMapData_c::fixup() {  	fixRef(data->layers);  	fixRef(data->tilesets); +	fixRef(data->unlockData);  	for (int iLayer = 0; iLayer < data->layerCount; iLayer++) {  		dKPLayer_s *layer = fixRef(data->layers[iLayer]); @@ -225,10 +226,7 @@ void dKPMapData_c::fixup() {  	} -	// before we finish here, create the Node Extra classes - -	// before the first off, do the unlocking. -	SaveBlock *save = GetSaveFile()->GetBlock(-1); +	/*SaveBlock *save = GetSaveFile()->GetBlock(-1);  	for (int i = 0; i < pathLayer->pathCount; i++) {  		dKPPath_s *path = pathLayer->paths[i]; @@ -242,8 +240,10 @@ void dKPMapData_c::fixup() {  			else  				path->isAvailable = false;  		} -	} +	}*/ + +	// before we finish here, create the Node Extra classes  	// first off, count how many we need...  	int count = 0; diff --git a/src/koopatlas/mapdata.h b/src/koopatlas/mapdata.h index 18dd9ee..b9a32f3 100644 --- a/src/koopatlas/mapdata.h +++ b/src/koopatlas/mapdata.h @@ -95,12 +95,18 @@ struct dKPNode_s {  };  struct dKPPath_s { +	enum Availability { +		NOT_AVAILABLE = 0, +		AVAILABLE = 1, +		NEWLY_AVAILABLE = 2 +	}; +  	dKPNode_s *start, *end;  	dKPLayer_s *tileLayer, *doodadLayer;  	u8 unlockType; // 0 = always, 1 = normal, 2 = secret  	u8 unlockLevelNumber[2]; -	bool isAvailable; // computed on-the-fly - default from Koopatlas is true +	u8 isAvailable; // computed on-the-fly - default from Koopatlas is 1  	float speed;  	int animation;  }; @@ -164,6 +170,8 @@ struct dKPMapFile_s {  	int tilesetCount;  	GXTexObj *tilesets; +	u8 *unlockData; +  	dKPLayer_s::sector_s sectors[1]; // variable size  }; diff --git a/src/koopatlas/pathmanager.cpp b/src/koopatlas/pathmanager.cpp index 41515a6..444684c 100644 --- a/src/koopatlas/pathmanager.cpp +++ b/src/koopatlas/pathmanager.cpp @@ -61,11 +61,115 @@ void dWMPathManager_c::setup() {  		}  	} -	// unlock all needed paths  	SpammyReport("Unlocking paths\n"); +	isEnteringLevel = false; +	unlockPaths();  	SpammyReport("done\n");  } +static u8 *PathAvailabilityData = 0; + +dWMPathManager_c::~dWMPathManager_c() { +	if (PathAvailabilityData && !isEnteringLevel) { +		delete[] PathAvailabilityData; +		PathAvailabilityData = 0; +	} +} + +void dWMPathManager_c::unlockPaths() { +	u8 *oldAvData = PathAvailabilityData; +	PathAvailabilityData = new u8[pathLayer->pathCount]; + +	// unlock all needed paths +	for (int i = 0; i < pathLayer->pathCount; i++) +		PathAvailabilityData[i] = dKPPath_s::NOT_AVAILABLE; + +	SaveBlock *save = GetSaveFile()->GetBlock(-1); + +	u8 *in = (u8*)dScKoopatlas_c::instance->mapData.data->unlockData; + +	while (*in != 0) { +		// begin processing a block +		bool value = evaluateUnlockCondition(in, save); + +		// , get what it's supposed to affect +		// for now we'll assume that it affects one or more paths +		u8 affectedCount = *(in++); + +		for (int i = 0; i < affectedCount; i++) { +			u8 one = *(in++); +			u8 two = *(in++); +			u16 pathID = (one << 8) | two; + +			dKPPath_s *path = pathLayer->paths[pathID]; +			path->isAvailable = dKPPath_s::AVAILABLE; +			PathAvailabilityData[pathID] = dKPPath_s::AVAILABLE; +			// NEWLY_AVAILABLE is set later, when that stuff is figured out +		} + +		// now evaluate a condition. simple! +	} + +	// did anything become newly available?! +	int whatsNew = 0; + +	if (oldAvData) { +		for (int i = 0; i < pathLayer->pathCount; i++) { +			if ((PathAvailabilityData[i] > 0) && (oldAvData[i] == 0)) { +				dKPPath_s *path = pathLayer->paths[i]; +				path->isAvailable = dKPPath_s::NEWLY_AVAILABLE; +				whatsNew++; +			} +		} +		delete[] oldAvData; +	} + +	// todo: set a flag on Map to do the path fade/sound, with whatsNew +} + +bool dWMPathManager_c::evaluateUnlockCondition(u8 *&in, SaveBlock *save) { +	u8 controlByte = *(in++); + +	u8 conditionType = (controlByte >> 6); + +	if (conditionType == 0) +		return true; + +	if (conditionType == 1) { +		// Simple level + +		bool isSecret = (controlByte & 0x10); +		u8 worldNumber = controlByte & 0xF; +		u8 levelNumber = *(in++); + +		u32 conds = save->GetLevelCondition(worldNumber, levelNumber); + +		if (isSecret) +			return (conds & COND_SECRET) != 0; +		else +			return (conds & COND_NORMAL) != 0; +	} + +	// Type: 2 = AND, 3 = OR +	bool isAnd = (conditionType == 2); +	bool isOr = (conditionType == 3); + +	bool value = isOr ? false : true; + +	u8 termCount = (controlByte & 0x3F) + 1; + +	for (int i = 0; i < termCount; i++) { +		bool what = evaluateUnlockCondition(in, save); + +		if (isOr) +			value |= what; +		else +			value &= what; +	} + +	return value; +} +  void dWMPathManager_c::execute() {  	int nowPressed = Remocon_GetPressed(GetActiveRemocon()); @@ -354,6 +458,8 @@ void dWMPathManager_c::activatePoint() {  		MapSoundPlayer(SoundRelatedClass, SE_SYS_GAME_START, 1);  		daWMPlayer_c::instance->startAnimation(170, 1.2, 10.0, 0.0); +		isEnteringLevel = true; +  		dLevelInfo_c::entry_s *level = dScKoopatlas_c::instance->levelInfo.search(w, l);  		dScKoopatlas_c::instance->startLevel(level);  	} diff --git a/src/koopatlas/pathmanager.h b/src/koopatlas/pathmanager.h index 969bdb2..5d35f4c 100644 --- a/src/koopatlas/pathmanager.h +++ b/src/koopatlas/pathmanager.h @@ -10,6 +10,7 @@ extern "C" bool SpawnEffect(const char*, int, Vec*, S16Vec*, Vec*);  class dWMPathManager_c {  	public:  		void setup(); +		~dWMPathManager_c();  		void execute();  		bool canUseExit(dKPPath_s *path) { @@ -36,6 +37,12 @@ class dWMPathManager_c {  		bool reverseThroughPath; // direction we are going through the path  		bool mustComplainToMapCreator; + +	private: +		void unlockPaths(); +		bool evaluateUnlockCondition(u8 *&in, SaveBlock *save); + +		bool isEnteringLevel;  };  #endif | 
