summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MMFullWorld.wmbin1192 -> 1515 bytes
-rw-r--r--MMFullWorld.xml48
-rw-r--r--src/wm_map.cpp3
-rw-r--r--src/wm_path_manager.cpp47
-rw-r--r--src/worldmap.cpp1
-rw-r--r--src/worldmap.h30
-rw-r--r--src/worldmapdata.cpp7
-rw-r--r--src/worldmapdata.h9
-rw-r--r--worldmap_gen.rb112
9 files changed, 234 insertions, 23 deletions
diff --git a/MMFullWorld.wm b/MMFullWorld.wm
index ce430e9..d7c30b7 100644
--- a/MMFullWorld.wm
+++ b/MMFullWorld.wm
Binary files differ
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