diff options
| -rw-r--r-- | MMFullWorld.wm | bin | 1192 -> 1515 bytes | |||
| -rw-r--r-- | MMFullWorld.xml | 48 | ||||
| -rw-r--r-- | src/wm_map.cpp | 3 | ||||
| -rw-r--r-- | src/wm_path_manager.cpp | 47 | ||||
| -rw-r--r-- | src/worldmap.cpp | 1 | ||||
| -rw-r--r-- | src/worldmap.h | 30 | ||||
| -rw-r--r-- | src/worldmapdata.cpp | 7 | ||||
| -rw-r--r-- | src/worldmapdata.h | 9 | ||||
| -rw-r--r-- | worldmap_gen.rb | 112 | 
9 files changed, 234 insertions, 23 deletions
diff --git a/MMFullWorld.wm b/MMFullWorld.wm Binary files differindex ce430e9..d7c30b7 100644 --- a/MMFullWorld.wm +++ b/MMFullWorld.wm diff --git a/MMFullWorld.xml b/MMFullWorld.xml index 2c87199..99e3de6 100644 --- a/MMFullWorld.xml +++ b/MMFullWorld.xml @@ -1,44 +1,44 @@  <map> -	<point name="drydry" position="-266.624,61.122,244.628" type="level" params="2,9,0,0"> +	<point name="drydry" position="-266.624,61.122,244.628" type="level" level="2-9">  		<exit direction="up" to="drydry to columns" />  		<exit direction="right" to="drydry to oasis" />  		<exit direction="down" to="drydry to toadhouse" />  	</point> -	<!--<point name="toadhouse" position="-320.172,41.155,344.66" type="level" params="2,11,0,0">--> -	<point name="toadhouse" position="-320.172,41.155,344.66" type="level" params="1,1,0,0"> +	<!--<point name="toadhouse" position="-320.172,41.155,344.66" type="level" level="2-11">--> +	<point name="toadhouse" position="-320.172,41.155,344.66" type="level" level="1-1">  		<exit direction="up" to="drydry to toadhouse" reverse="yes" />  		<exit direction="right" to="toadhouse to basement" />  		<exit direction="down" to="toadhouse to basement" />  	</point> -	<point name="basement" position="-95.274,-35.167,385.463" type="level" params="2,14,0,0"> +	<point name="basement" position="-95.274,-35.167,385.463" type="level" level="2-14">  		<exit direction="left" to="toadhouse to basement" reverse="yes" />  		<exit direction="down" to="toadhouse to basement" reverse="yes" />  		<exit direction="up" to="basement to castle" />  	</point> -	<point name="columns" position="-168.286,61.122,165.593" type="level" params="2,10,0,0"> +	<point name="columns" position="-168.286,61.122,165.593" type="level" level="2-10">  		<exit direction="down" to="drydry to columns" reverse="yes" />  		<exit direction="right" to="columns to sinkysand" />  	</point> -	<point name="sinkysand" position="-78.644,35.327,205.595" type="level" params="2,13,0,0"> +	<point name="sinkysand" position="-78.644,35.327,205.595" type="level" level="2-13">  		<exit direction="left" to="columns to sinkysand" reverse="yes" />  		<exit direction="right" to="sinkysand to castle" />  	</point> -	<point name="gulch" position="-76.596,61.122,379.174" type="level" params="2,15,0,0"> +	<point name="gulch" position="-76.596,61.122,379.174" type="level" level="2-15">  		<exit direction="left" to="oasis to gulch" reverse="yes" />  		<exit direction="up" to="gulch to castle" />  	</point> -	<point name="oasis" position="-154.073,52.178,322.023" type="level" params="2,12,0,0"> +	<point name="oasis" position="-154.073,52.178,322.023" type="level" level="2-12">  		<exit direction="left" to="drydry to oasis" reverse="yes" />  		<exit direction="right" to="oasis to gulch" />  	</point> -	<point name="castle" position="-58.448,62.185,293.062" type="level" params="2,16,0,0"> +	<point name="castle" position="-58.448,62.185,293.062" type="level" level="2-16">  		<exit direction="up" to="sinkysand to castle" reverse="yes" />  		<exit direction="left" to="basement to castle" reverse="yes" />  		<exit direction="down" to="gulch to castle" reverse="yes" /> @@ -46,39 +46,51 @@  	</point> -	<path name="drydry to columns" start="drydry" end="columns"> +	<path name="drydry to columns" start="drydry" end="columns" required="drydry_normal">  		<segment from="drydry" to="columns" /> +		<material>World2_PathstoColumns</material>  	</path> -	<path name="columns to sinkysand" start="columns" end="sinkysand"> +	<path name="columns to sinkysand" start="columns" end="sinkysand" required="columns_normal">  		<segment from="columns" to="sinkysand" /> +		<material>World2_PathstoSinky</material>  	</path> -	<path name="sinkysand to castle" start="sinkysand" end="castle"> +	<path name="sinkysand to castle" start="sinkysand" end="castle" required="sinkysand_normal">  		<segment from="sinkysand" to="castle" /> +		<material>World2_PathsSinkytoPyramid</material>  	</path> -	<path name="drydry to oasis" start="drydry" end="oasis"> +	<path name="drydry to oasis" start="drydry" end="oasis" required="drydry_normal">  		<segment from="drydry" to="oasis" /> +		<material>World2_PathstoOasis</material>  	</path> -	<path name="oasis to gulch" start="oasis" end="gulch"> +	<path name="oasis to gulch" start="oasis" end="gulch" required="oasis_normal">  		<segment from="oasis" to="gulch" /> +		<material>World2_PathstoDeserted</material>  	</path> -	<path name="gulch to castle" start="gulch" end="castle"> +	<path name="gulch to castle" start="gulch" end="castle" required="gulch_normal">  		<segment from="gulch" to="castle" /> +		<material>World2_PathsDesertedtoPyramid</material>  	</path> -	<path name="drydry to toadhouse" start="drydry" end="toadhouse"> +	<path name="drydry to toadhouse" start="drydry" end="toadhouse" required="drydry_secret">  		<segment from="drydry" to="toadhouse" /> +		<material>World2_PathstoToad1</material> +		<material>World2_PathstoToad2</material>  	</path> -	<path name="toadhouse to basement" start="toadhouse" end="basement"> +	<path name="toadhouse to basement" start="toadhouse" end="basement" required="drydry_secret">  		<segment from="toadhouse" to="basement" /> +		<material>World2_PathstoPlumbing1</material> +		<material>World2_PathstoPlumbing2</material> +		<material>World2_PathstoPlumbing3</material> +		<material>World2_PathsPlumbing</material>  	</path> -	<path name="basement to castle" start="basement" end="castle"> +	<path name="basement to castle" start="basement" end="castle" required="basement_normal">  		<segment from="basement" to="castle" />  	</path>  </map> diff --git a/src/wm_map.cpp b/src/wm_map.cpp index 1fa4065..73ae1c8 100644 --- a/src/wm_map.cpp +++ b/src/wm_map.cpp @@ -48,6 +48,9 @@ int dWMMap_c::onCreate() {  	SpammyReport("Unlinking allocator\n");  	allocator.unlink(); +	SpammyReport("Loading paths\n"); +	dWMPathManager_c::instance->setInitialPathVisibility(); +  	SpammyReport("dWMMap_c::onCreate() completed\n");  	return true;  } diff --git a/src/wm_path_manager.cpp b/src/wm_path_manager.cpp index d94e5be..03c11d4 100644 --- a/src/wm_path_manager.cpp +++ b/src/wm_path_manager.cpp @@ -209,3 +209,50 @@ void dWMPathManager_c::setup() {  } + + +void dWMPathManager_c::setInitialPathVisibility() { +	for (int i = 0; i < pathData.pathCount(); i++) { +		WMPathDef *path = pathData.getPath(i); + +		char **materials = path->getMaterialArray(); +		u8 alphaToUse = 255; +		if (path->eventRequired != 0xFFFF) { +			if (!events[path->eventRequired]) +				alphaToUse = 128; +		} + +		for (int j = 0; j < path->materialCount; j++) { +			// TODO: fix this +			dWMMap_c::instance->nodes[0].updateAlpha(materials[j], alphaToUse); +		} +	} +} + + + +void dWMPathManager_c::computeEvents() { +	for (int i = 0; i < EVENT_COUNT; i++) +		events[i] = false; + +	SaveBlock *save = GetSaveFile()->GetBlock(-1); + +	// loop through every point, and apply the event from it if necessary +	for (int i = 0; i < pathData.pointCount(); i++) { +		WMPathPoint *point = pathData.getPoint(i); + +		if (point->type == WMPathPoint::LEVEL_TYPE) { +			// TODO: check if the world/level need to be -1 or not +			u32 conds = save->GetLevelCondition(point->params[0], point->params[1]); + +			if (conds & COND_NORMAL && point->params[2] != -1) +				events[point->params[2]] = true; +			if (conds & COND_SECRET && point->params[3] != -1) +				events[point->params[3]] = true; + +			OSReport("checking level %d-%d with events %d,%d set them to %d,%d\n", point->params[0], point->params[1], point->params[2], point->params[3], events[point->params[2]], events[point->params[3]]); +		} +	} +} + + diff --git a/src/worldmap.cpp b/src/worldmap.cpp index 288d2bb..50e82c7 100644 --- a/src/worldmap.cpp +++ b/src/worldmap.cpp @@ -175,6 +175,7 @@ bool WMInit_SetupExtra(void *ptr) {  	// since we've got all the resources, set up the path data too
  	wm->pathManager->setup();
 +	wm->pathManager->computeEvents();
  	// and now Player setup
  	wm->player = (daWMPlayer_c*)CreateParentedObject(WM_PLAYER, wm, 0, 2);
 diff --git a/src/worldmap.h b/src/worldmap.h index ef08b99..b356bac 100644 --- a/src/worldmap.h +++ b/src/worldmap.h @@ -14,6 +14,8 @@  #define WM_DEBUGGING
  //#define WM_SPAMMY_DEBUGGING
 +#include <m_dynarray.h>
 +
  #include <common.h>
  #include <game.h>
  #include <g3dhax.h>
 @@ -70,6 +72,9 @@ class dWMHud_c : public dBase_c {  };
 +
 +#define EVENT_COUNT 512
 +
  class dWMPathManager_c : public dBase_c {
  	public:
  		dWMPathManager_c();
 @@ -81,6 +86,25 @@ class dWMPathManager_c : public dBase_c {  		dWMPathData_c pathData;
 +		/* Paths */
 +		struct pathFadeInfo {
 +			char *materialName;
 +			u16 currentAlpha;
 +			u16 framesRemaining;
 +			int delta;
 +		};
 +
 +		mDynArray_c<pathFadeInfo *,32> fadingPaths;
 +
 +		void setInitialPathVisibility();
 +
 +		/* Event Data - 512 events should be more than enough for everyone */
 +		mDynArray_c<u16,32> newlyActivatedEvents;
 +		bool events[EVENT_COUNT];
 +
 +		void computeEvents();
 +
 +		/* Movement Data/Methods */
  		bool isMoving;
  		WMPathPoint *currentPoint;
  		WMPathPoint *nextPoint;
 @@ -90,15 +114,17 @@ class dWMPathManager_c : public dBase_c {  		int currentSegmentID;
  		bool reverseThroughPath; // direction we are going through the path
 -		void setup();
 -
  		void startMovementTo(WMDirection direction);
  		void moveToSegment(int id);
  		void moveThroughPath();
 +		/* Other Methods */
 +		void setup();
 +
  		void activatePoint();
 +		/* Process Housekeeping */
  		static dWMPathManager_c *build();
  		static dWMPathManager_c *instance;
  };
 diff --git a/src/worldmapdata.cpp b/src/worldmapdata.cpp index 2f23afc..a8e0cf9 100644 --- a/src/worldmapdata.cpp +++ b/src/worldmapdata.cpp @@ -48,6 +48,13 @@ bool dWMPathData_c::load(void *data) {  		for (int j = 0; j < thisPath->segCount; j++) {  			thisPath->segments[j] = header->segmentList[(u32)thisPath->segments[j]];  		} + +		MapReport("Path @ %p\n", thisPath); +		char **materialArray = thisPath->getMaterialArray(); +		MapReport("Material Array @ %p, Count is %d\n", materialArray, thisPath->materialCount); +		for (int j = 0; j < thisPath->materialCount; j++) { +			materialArray[j] = (char*)((u32)materialArray[j] + ptr); +		}  	}  	MapReport("Fixing up point pointers [%d]\n", header->pointCount); diff --git a/src/worldmapdata.h b/src/worldmapdata.h index a436114..71071f0 100644 --- a/src/worldmapdata.h +++ b/src/worldmapdata.h @@ -102,8 +102,15 @@ struct WMPathDef {  	WMPathPoint *endPoint;  	u16 eventRequired; -	u16 segCount; +	u8 segCount; +	u8 materialCount;  	WMPathSegment *segments[1]; // variable-length array + +	char **getMaterialArray() { +		u8 *ptr = (u8*)(this + 1); +		ptr += sizeof(segments[0]) * (segCount - 1); +		return (char **)ptr; +	}  }; diff --git a/worldmap_gen.rb b/worldmap_gen.rb index e52eefc..6169acf 100644 --- a/worldmap_gen.rb +++ b/worldmap_gen.rb @@ -5,6 +5,75 @@ File::open("#{ARGV[0]}.xml") do |f|  	doc = REXML::Document.new(f.read)  end + +# this code is a mess + + +$events = {} +$current_event_id = 0 + +def make_event_number(name) +	return $events[name] if $events.key?(name) + +	puts "making event for #{name}" + +	$events[name] = $current_event_id +	$current_event_id += 1 + +	if /(?<level_name>.+)_(?<type>normal|special)/ =~ name +		raise "level #{level_name} not known" unless $points.key?(level_name) + +		point = $points[level_name] +		point.params[2] = $events[name] if type == 'normal' +		point.params[3] = $events[name] if type == 'special' +	end + +	$events[name] +end + + + +class StringTable +	attr_reader :size +	attr_accessor :start_offset + +	def initialize +		@strings = [] +		@offset_hash = {} +		@size = 0 +		@start_offset = 0 +	end + +	def include?(str) +		@offset_hash.key? str +	end + +	def push(str) +		return if include? str + +		str = str.dup +		@strings << str +		@offset_hash[str] = @size +		@size += str.length + 1 +	end + +	def offset(str) +		@start_offset + @offset_hash[str] +	end + +	def to_a +		@strings.dup +	end + +	def to_s +		out = [] +		@strings.each {|str| out << str; out << "\0" } +		out.join '' +	end + +	alias :<< :push +end +  class Exit  	attr_accessor :path  	attr_accessor :reverse @@ -41,6 +110,20 @@ class Point  		@type = type.value unless type.nil?  		@params = params.value.split(',').collect { |v| v.to_i } unless params.nil? +		if @type == 'level' +			level = element.attribute('level').value.split('-').map(&:to_i) +			#normal_event = element.attribute('event') +			#special_event = element.attribute('special_event') +			 +			#normal_event = normal_event.nil? ? 0xFFFF : normal_event.value.to_i +			#special_event = special_event.nil? ? 0xFFFF : special_event.value.to_i + +			# phased those out for now +			normal_event, special_event = 0xFFFF, 0xFFFF + +			@params = level + [normal_event, special_event] +		end +  		element.each_element 'exit' do |e|  			@exits[e.attribute('direction').value] = Exit.new(e)  		end @@ -143,6 +226,8 @@ class Path  	attr_accessor :start_point  	attr_accessor :end_point  	attr_reader :id +	attr_accessor :materials +	attr_accessor :event  	def initialize(element)  		@start_point = element.attribute('start').value @@ -156,6 +241,17 @@ class Path  			@segment_ids << @segments.last.id  		end +		@materials = [] +		element.each_element 'material' do |m| +			@materials << m.get_text.value.strip +		end + +		event_attrib = element.attribute('required') +		@event = 0xFFFFFFFF +		unless event_attrib.nil? +			@event = make_event_number(event_attrib.value) +		end +  		@id = $path_id  		$path_id += 1  	end @@ -182,6 +278,8 @@ end  directions = {'left' => 0, 'right' => 1, 'up' => 2, 'down' => 3} +$string_table = StringTable.new +  # first, collect every point  $points = {}  $point_id = 0 @@ -236,7 +334,7 @@ File::open("#{ARGV[0]}.wm", "w") do |f|  	current_offset = data_offset  	$paths.each_value do |p|  		f << [current_offset].pack('N') -		current_offset += 0xC + (p.segments.count * 4) +		current_offset += 0xC + (p.segments.count * 4) + (p.materials.count * 4)  	end  	$points.each_value do |p| @@ -250,12 +348,20 @@ File::open("#{ARGV[0]}.wm", "w") do |f|  	end  	# nothing for actions yet! +	 +	# write the string table +	$string_table.start_offset = current_offset  	# now write the data  	$paths.each_value do |p|  		f << [$points[p.start_point].id, $points[p.end_point].id].pack('NN') -		f << [p.segments.count].pack('N') +		f << [p.event, p.segments.count, p.materials.count].pack('ncc')  		f << p.segment_ids.pack('N*') +		 +		p.materials.each do |mat| +			$string_table << mat +			f << [$string_table.offset(mat)].pack('N') +		end  	end  	$points.each_value do |p| @@ -287,5 +393,7 @@ File::open("#{ARGV[0]}.wm", "w") do |f|  		end  		f << [0].pack('N')  	end + +	f << $string_table.to_s  end  | 
