Modified TMX Parser to read new map spawn format. Fix missing spawns. Added errors when spawns are missing from a monster.
This commit is contained in:
parent
1d1c12004e
commit
4557138662
@ -415,6 +415,7 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MonsterData.h" />
|
||||
<ClInclude Include="olcPGEX_SplashScreen.h" />
|
||||
<ClInclude Include="PlayerMoneyLabel.h">
|
||||
<SubType>
|
||||
|
@ -633,6 +633,9 @@
|
||||
<ClInclude Include="Minimap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MonsterData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Player.cpp">
|
||||
|
@ -261,15 +261,6 @@ bool AiL::OnUserCreate(){
|
||||
|
||||
VisualNovel::Initialize();
|
||||
|
||||
InitializeLevels();
|
||||
|
||||
//Initialize Camera.
|
||||
camera=Camera2D{WINDOW_SIZE};
|
||||
camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow);
|
||||
camera.SetTarget(player->GetPos());
|
||||
camera.SetWorldBoundary({0,0},GetCurrentMap().MapData.MapSize*GetCurrentMap().MapData.TileSize);
|
||||
camera.EnableWorldBoundary(false);
|
||||
|
||||
ItemAttribute::Initialize();
|
||||
|
||||
ItemInfo::InitializeItems();
|
||||
@ -290,6 +281,15 @@ bool AiL::OnUserCreate(){
|
||||
MonsterData::InitializeMonsterData();
|
||||
MonsterData::InitializeNPCData();
|
||||
|
||||
InitializeLevels();
|
||||
|
||||
//Initialize Camera.
|
||||
camera=Camera2D{WINDOW_SIZE};
|
||||
camera.SetMode(olc::utils::Camera2D::Mode::LazyFollow);
|
||||
camera.SetTarget(player->GetPos());
|
||||
camera.SetWorldBoundary({0,0},GetCurrentMap().MapData.MapSize*GetCurrentMap().MapData.TileSize);
|
||||
camera.EnableWorldBoundary(false);
|
||||
|
||||
sig::Animation::SetupPlayerAnimations();
|
||||
view=TileTransformedView{GetScreenSize(),{1,1}};
|
||||
|
||||
|
@ -42,11 +42,11 @@ All rights reserved.
|
||||
#include "olcUTIL_Animate2D.h"
|
||||
#include "DEFINES.h"
|
||||
#include "Attributable.h"
|
||||
#include "Item.h"
|
||||
#include "safemap.h"
|
||||
#include "Pathfinding.h"
|
||||
#include "GameEvent.h"
|
||||
#include "TMXParser.h"
|
||||
#include "MonsterData.h"
|
||||
|
||||
INCLUDE_ITEM_DATA
|
||||
|
||||
@ -62,62 +62,6 @@ enum class MonsterAnimation{
|
||||
DEATH
|
||||
};
|
||||
|
||||
struct MonsterDropData{
|
||||
ItemInfo*item;
|
||||
float dropChance;
|
||||
int minQty=1;
|
||||
int maxQty=1;
|
||||
MonsterDropData(std::string itemName,float dropChance,int minQty=1,int maxQty=1)
|
||||
:item(&ITEM_DATA.at(itemName)),dropChance(dropChance),minQty(minQty),maxQty(maxQty){}
|
||||
};
|
||||
|
||||
struct MonsterData{
|
||||
private:
|
||||
std::string name;
|
||||
int hp;
|
||||
int atk;
|
||||
uint32_t xp;
|
||||
float moveSpd;//1.0=100%
|
||||
float size;
|
||||
std::vector<std::string> animations;
|
||||
std::string strategy;
|
||||
int collisionDmg;
|
||||
std::string jumpAnimation="WARRIOR_IDLE_S";
|
||||
std::string shootAnimation="WARRIOR_IDLE_S";
|
||||
std::string deathAnimation="WARRIOR_IDLE_S";
|
||||
EventName hurtSound="";
|
||||
EventName deathSound="";
|
||||
EventName walkSound="";
|
||||
std::vector<MonsterDropData> dropData;
|
||||
bool isNPC=false;
|
||||
public:
|
||||
MonsterData();
|
||||
MonsterData(std::string name,int hp,int atk,const uint32_t xp,std::vector<std::string>animations,std::vector<MonsterDropData>drops,float moveSpd=1.0f,float size=1.0f,std::string strategy="Run Towards",int collisionDmg=0);
|
||||
int GetHealth();
|
||||
int GetAttack();
|
||||
const uint32_t GetXP()const;
|
||||
float GetMoveSpdMult();
|
||||
float GetSizeMult();
|
||||
const std::string&GetAIStrategy()const;
|
||||
int GetCollisionDmg();
|
||||
std::string GetIdleAnimation();
|
||||
std::string GetJumpAnimation();
|
||||
std::string GetShootAnimation();
|
||||
std::string GetDeathAnimation();
|
||||
const EventName&GetHurtSound();
|
||||
const EventName&GetDeathSound();
|
||||
const EventName&GetWalkSound();
|
||||
const bool IsNPC()const;
|
||||
std::vector<std::string>GetAnimations(){
|
||||
return animations;
|
||||
}
|
||||
const std::vector<MonsterDropData>&GetDropData();
|
||||
std::string GetDisplayName();
|
||||
static void InitializeMonsterData();
|
||||
static void InitializeNPCData();
|
||||
static std::map<std::string,Renderable*>imgs;
|
||||
};
|
||||
|
||||
class GameEvent;
|
||||
|
||||
class Monster:IAttributable{
|
||||
|
98
Adventures in Lestoria/MonsterData.h
Normal file
98
Adventures in Lestoria/MonsterData.h
Normal file
@ -0,0 +1,98 @@
|
||||
#pragma region License
|
||||
/*
|
||||
License (OLC-3)
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions or derivations of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions or derivative works in binary form must reproduce the above
|
||||
copyright notice. This list of conditions and the following disclaimer must be
|
||||
reproduced in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Portions of this software are copyright © 2024 The FreeType
|
||||
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
#pragma once
|
||||
#include "DEFINES.h"
|
||||
#include "Item.h"
|
||||
|
||||
INCLUDE_ITEM_DATA
|
||||
|
||||
struct MonsterDropData{
|
||||
ItemInfo*item;
|
||||
float dropChance;
|
||||
int minQty=1;
|
||||
int maxQty=1;
|
||||
MonsterDropData(std::string itemName,float dropChance,int minQty=1,int maxQty=1)
|
||||
:item(&ITEM_DATA.at(itemName)),dropChance(dropChance),minQty(minQty),maxQty(maxQty){}
|
||||
};
|
||||
|
||||
struct MonsterData{
|
||||
private:
|
||||
std::string name;
|
||||
int hp;
|
||||
int atk;
|
||||
uint32_t xp;
|
||||
float moveSpd;//1.0=100%
|
||||
float size;
|
||||
std::vector<std::string> animations;
|
||||
std::string strategy;
|
||||
int collisionDmg;
|
||||
std::string jumpAnimation="WARRIOR_IDLE_S";
|
||||
std::string shootAnimation="WARRIOR_IDLE_S";
|
||||
std::string deathAnimation="WARRIOR_IDLE_S";
|
||||
EventName hurtSound="";
|
||||
EventName deathSound="";
|
||||
EventName walkSound="";
|
||||
std::vector<MonsterDropData> dropData;
|
||||
bool isNPC=false;
|
||||
public:
|
||||
MonsterData();
|
||||
MonsterData(std::string name,int hp,int atk,const uint32_t xp,std::vector<std::string>animations,std::vector<MonsterDropData>drops,float moveSpd=1.0f,float size=1.0f,std::string strategy="Run Towards",int collisionDmg=0);
|
||||
int GetHealth();
|
||||
int GetAttack();
|
||||
const uint32_t GetXP()const;
|
||||
float GetMoveSpdMult();
|
||||
float GetSizeMult();
|
||||
const std::string&GetAIStrategy()const;
|
||||
int GetCollisionDmg();
|
||||
std::string GetIdleAnimation();
|
||||
std::string GetJumpAnimation();
|
||||
std::string GetShootAnimation();
|
||||
std::string GetDeathAnimation();
|
||||
const EventName&GetHurtSound();
|
||||
const EventName&GetDeathSound();
|
||||
const EventName&GetWalkSound();
|
||||
const bool IsNPC()const;
|
||||
std::vector<std::string>GetAnimations(){
|
||||
return animations;
|
||||
}
|
||||
const std::vector<MonsterDropData>&GetDropData();
|
||||
std::string GetDisplayName();
|
||||
static void InitializeMonsterData();
|
||||
static void InitializeNPCData();
|
||||
static std::map<std::string,Renderable*>imgs;
|
||||
};
|
@ -45,7 +45,9 @@ All rights reserved.
|
||||
#include "safemap.h"
|
||||
#include "ItemMapData.h"
|
||||
#include "Class.h"
|
||||
#include "MonsterData.h"
|
||||
|
||||
INCLUDE_MONSTER_DATA
|
||||
|
||||
using MapName=std::string;
|
||||
using namespace olc;
|
||||
@ -61,7 +63,7 @@ struct XMLTag{
|
||||
float GetFloat(std::string dataTag);
|
||||
double GetDouble(std::string dataTag);
|
||||
bool GetBool(std::string dataTag);
|
||||
std::string GetString(std::string dataTag);
|
||||
std::string GetString(std::string dataTag)const;
|
||||
};
|
||||
|
||||
struct ForegroundTileTag:public XMLTag{
|
||||
@ -224,13 +226,13 @@ class TMXParser{
|
||||
double XMLTag::GetDouble(std::string dataTag) {
|
||||
return std::stod(data[dataTag]);
|
||||
}
|
||||
std::string XMLTag::GetString(std::string dataTag) {
|
||||
return data[dataTag];
|
||||
std::string XMLTag::GetString(std::string dataTag)const{
|
||||
return data.at(dataTag);
|
||||
}
|
||||
bool XMLTag::GetBool(std::string dataTag) {
|
||||
if (data[dataTag]=="0"||data[dataTag]=="false") {
|
||||
return false;
|
||||
} else {
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -246,7 +248,7 @@ class TMXParser{
|
||||
bool Property::GetBool() {
|
||||
if (value=="0") {
|
||||
return false;
|
||||
} else {
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -396,7 +398,7 @@ class TMXParser{
|
||||
#if _DEBUG
|
||||
if(_DEBUG_MAP_LOAD_INFO)LOG("Tag: "<<newTag.tag<<"\n");
|
||||
#endif
|
||||
} else {
|
||||
}else{
|
||||
std::string key = data.substr(0,data.find("="));
|
||||
std::string value = data.substr(data.find("=")+1,std::string::npos);
|
||||
|
||||
@ -416,6 +418,16 @@ class TMXParser{
|
||||
|
||||
XMLTag newTag=ReadNextTag();
|
||||
|
||||
auto ParseMonsterTemplateName=[](const XMLTag&monsterTag){
|
||||
std::string monsterName=monsterTag.GetString("template").substr("../maps/Monsters/"s.length());
|
||||
monsterName=monsterName.substr(0,monsterName.find(".tx"));
|
||||
return monsterName;
|
||||
};
|
||||
|
||||
if(newTag.tag!="property"&&newTag.tag!="properties"&&monsterPropertyTagCount==0){
|
||||
ERR(std::format("WARNING! Monster {} at ({},{}) in Map {} does not have a spawn set!",ParseMonsterTemplateName(monsterTag),monsterTag.GetFloat("x"),monsterTag.GetFloat("y"),fileName));
|
||||
}
|
||||
|
||||
if (newTag.tag=="object"&&newTag.data["type"]!="StagePlate"){
|
||||
currentStagePlate=nullptr;
|
||||
}
|
||||
@ -433,10 +445,10 @@ class TMXParser{
|
||||
if(newTag.data.find("class")==newTag.data.end())ERR(std::format("WARNING! Map {} does not have a class set!",fileName));
|
||||
if(newTag.data["class"]!="Map")ERR(std::format("WARNING! Map {} is not set to the map class! Class is set to {} instead.",fileName,newTag.data["class"]));
|
||||
parsedMapInfo.MapData={stoi(newTag.data["width"]),stoi(newTag.data["height"]),stoi(newTag.data["tilewidth"]),stoi(newTag.data["tileheight"])};
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="tileset"){
|
||||
parsedMapInfo.TilesetData.push_back(newTag);
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="layer"){
|
||||
LayerTag l = {newTag};
|
||||
parsedMapInfo.LayerData.push_back(l);
|
||||
@ -447,86 +459,84 @@ class TMXParser{
|
||||
parsedMapInfo.SpawnerData[newTag.GetInteger("id")]={newTag};
|
||||
prevSpawner=newTag.GetInteger("id");
|
||||
}
|
||||
} else
|
||||
}else
|
||||
if(newTag.tag=="property"&&newTag.data["name"]=="Layer Unlock Condition"&¤tLayerTag!=nullptr){
|
||||
currentLayerTag->unlockCondition=newTag.data["value"];
|
||||
} else
|
||||
}else
|
||||
if(newTag.tag=="property"&&newTag.data["name"]=="Upper?"&&prevZoneData!=nullptr){
|
||||
prevZoneData->isUpper=newTag.GetBool("value");
|
||||
}else
|
||||
if (newTag.tag=="property"&&newTag.data["name"]=="Optimize"&&newTag.data["value"]=="true") {
|
||||
parsedMapInfo.MapData.optimized=true;
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="property"&&newTag.data["name"]=="Boss Title Display") {
|
||||
parsedMapInfo.SpawnerData[prevSpawner].bossNameDisplay=newTag.data["value"];
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="property"&&newTag.data["name"]=="Level Type") {
|
||||
parsedMapInfo.mapType=newTag.data["value"];
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="property"&&newTag.data["name"]=="Background Music") {
|
||||
if(newTag.data["value"]!="None"){ //None is a default value that we ignore.
|
||||
parsedMapInfo.bgmSongName=newTag.data["value"];
|
||||
}
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="property"&&newTag.data["name"].starts_with("Dev Completion Time")) {
|
||||
if(newTag.data.count("value")){ //None is a default value that we ignore.
|
||||
size_t classStartPos="Dev Completion Time - "s.length();
|
||||
std::string className=newTag.data["name"].substr(classStartPos,newTag.data["name"].find(' ',classStartPos)-classStartPos);
|
||||
parsedMapInfo.devCompletionTrialTime[classutils::StringToClass(className)]=newTag.GetFloat("value");
|
||||
}
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="property"&&newTag.data["name"]=="Backdrop") {
|
||||
if(newTag.data["value"]!="None"){ //None is a default value that we ignore.
|
||||
parsedMapInfo.backdrop=newTag.data["value"];
|
||||
}
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="AudioEnvironmentalSound") {
|
||||
parsedMapInfo.environmentalAudioData.emplace_back();
|
||||
prevAudioData=&parsedMapInfo.environmentalAudioData.back();
|
||||
prevAudioData->SetPos({newTag.GetFloat("x"),newTag.GetFloat("y")});
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="property"&&newTag.data["propertytype"]=="EnvironmentalSounds") {
|
||||
if(newTag.data["value"]!="None"){ //None is a default value that we ignore.
|
||||
prevAudioData->SetAudioName(newTag.data["value"]);
|
||||
}
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="PlayerSpawnLocation") {
|
||||
float width=1.f;
|
||||
float height=1.f;
|
||||
if(newTag.data.count("width")>0)width=newTag.GetFloat("width");
|
||||
if(newTag.data.count("height")>0)height=newTag.GetFloat("height");
|
||||
parsedMapInfo.MapData.playerSpawnLocation={int(newTag.GetFloat("x")-width/2),int(newTag.GetFloat("y")-height/2)};
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="NPC") {
|
||||
if(inNPCTag)parsedMapInfo.npcs.push_back(NPCData{npcTag});
|
||||
npcTag=newTag;
|
||||
inNPCTag=true;
|
||||
} else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="Monster") {
|
||||
if (newTag.tag=="object"&&newTag.data["template"].starts_with("../maps/Monsters")) {
|
||||
monsterTag=newTag;
|
||||
monsterPropertyTagCount=0;
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="property"&&inNPCTag) {
|
||||
npcTag.data[newTag.data["name"]]=newTag.data["value"];
|
||||
}
|
||||
}else
|
||||
if (newTag.tag=="property"&&monsterPropertyTagCount==0) {
|
||||
if(newTag.data["value"]=="None")ERR(std::format("WARNING! Invalid monster type provided: {} in map {}",newTag.data["value"],fileName));
|
||||
monsterTag.data["value"]=newTag.data["value"];
|
||||
parsedMapInfo.spawns.insert(newTag.GetString("value"));
|
||||
monsterPropertyTagCount++;
|
||||
} else
|
||||
if (newTag.tag=="property"&&monsterPropertyTagCount==1) {
|
||||
std::string monsterName=ParseMonsterTemplateName(monsterTag);
|
||||
if(!MONSTER_DATA.count(monsterName))ERR(std::format("WARNING! Could not find monster type {}",monsterName));
|
||||
parsedMapInfo.spawns.insert(monsterName);
|
||||
spawnerLinkTag=newTag;
|
||||
monsterTag.data["value"]=monsterName;
|
||||
monsterTag.data["spawnerLink"]=spawnerLinkTag.data["value"];
|
||||
accumulatedMonsterTags.push_back(monsterTag);
|
||||
monsterPropertyTagCount=-1;
|
||||
} else
|
||||
}else
|
||||
if (newTag.tag=="object"&&newTag.data["type"]=="StagePlate") {
|
||||
if(newTag.GetInteger("id")!=0){
|
||||
stagePlates[newTag.GetInteger("id")]={newTag};
|
||||
currentStagePlate=&stagePlates.at(newTag.GetInteger("id"));
|
||||
}
|
||||
} else
|
||||
}else
|
||||
if(newTag.tag=="property"&¤tStagePlate!=nullptr){
|
||||
currentStagePlate->properties[newTag.data["name"]]={newTag.data["name"],newTag.data["value"]};
|
||||
}else
|
||||
@ -586,7 +596,7 @@ class TMXParser{
|
||||
if(accumulator.length()>1&&accumulator.find('>')!=std::string::npos){
|
||||
accumulator=""; //Restart because this tag has nothing in it!
|
||||
}
|
||||
} else {
|
||||
}else{
|
||||
//Start reading in data for this layer.
|
||||
std::vector<int>rowData;
|
||||
while (data.find(",")!=std::string::npos) {
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 2
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 8926
|
||||
#define VERSION_BUILD 8944
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -885,14 +885,34 @@
|
||||
<object id="23" name="Spawn 4" type="SpawnGroup" x="1385.33" y="2518.67" width="406.667" height="340">
|
||||
<ellipse/>
|
||||
</object>
|
||||
<object id="24" template="../maps/Monsters/Flower Turret.tx" type="Monster" x="1485.33" y="2676"/>
|
||||
<object id="24" template="../maps/Monsters/Flower Turret.tx" type="Monster" x="1485.33" y="2676">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="23"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="25" name="Spawn 5" type="SpawnGroup" x="1375.33" y="1923.33" width="486.667" height="476">
|
||||
<ellipse/>
|
||||
</object>
|
||||
<object id="26" template="../maps/Monsters/Blue Slime.tx" type="Monster" x="1609.33" y="2589.33"/>
|
||||
<object id="27" template="../maps/Monsters/Blue Slime.tx" type="Monster" x="1542.67" y="2630.67"/>
|
||||
<object id="28" template="../maps/Monsters/Blue Slime.tx" type="Monster" x="1669.33" y="2633.33"/>
|
||||
<object id="29" template="../maps/Monsters/Red Slime.tx" type="Monster" x="1589.33" y="2708"/>
|
||||
<object id="26" template="../maps/Monsters/Blue Slime.tx" type="Monster" x="1609.33" y="2589.33">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="23"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="27" template="../maps/Monsters/Blue Slime.tx" type="Monster" x="1542.67" y="2630.67">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="23"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="28" template="../maps/Monsters/Blue Slime.tx" type="Monster" x="1669.33" y="2633.33">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="23"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="29" template="../maps/Monsters/Red Slime.tx" type="Monster" x="1589.33" y="2708">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="23"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="30" name="Spawn 6" type="SpawnGroup" x="1346" y="1522" width="508" height="210.667">
|
||||
<ellipse/>
|
||||
</object>
|
||||
|
@ -675,7 +675,11 @@
|
||||
<property name="spawner" type="object" value="2"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="40" template="../maps/Monsters/Windhound.tx" type="Monster" x="1117.33" y="1394.67"/>
|
||||
<object id="40" template="../maps/Monsters/Windhound.tx" type="Monster" x="1117.33" y="1394.67">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="2"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="41" template="../maps/Monsters/Yellow Slime.tx" type="Monster" x="1140" y="938.667">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="3"/>
|
||||
|
@ -1331,7 +1331,11 @@
|
||||
<object id="24" name="Spawn 15" type="SpawnGroup" x="2638" y="1912" width="1072" height="664">
|
||||
<ellipse/>
|
||||
</object>
|
||||
<object id="26" template="../maps/Monsters/Bear.tx" type="Monster" x="3550" y="2263"/>
|
||||
<object id="26" template="../maps/Monsters/Bear.tx" type="Monster" x="3550" y="2263">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="16"/>
|
||||
</properties>
|
||||
</object>
|
||||
<object id="27" name="Spawn 15" type="SpawnGroup" x="849" y="34" width="2028" height="808">
|
||||
<properties>
|
||||
<property name="spawner" type="object" value="27"/>
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user