Wave mode instances - walkthrough conversions (#3884)
* Wave mode instances - walkthrough conversions * NPC_EMOTION and NPC_EMOTION_ON disrupted the walking system and have been restricted on the maps. * Implemented AI_SPECIALs. AI and normal monsters can naturally fight each others. However monsters with AI_SPECIAL can't be hit by normal monsters. * Implemented mob_setidleevent command. `mob_setidleevent <GID>,<event>;` This command will attach an event label to the monster with the given <GID> which will execute when the <GID> is idle. * Added parameters to unitskilluseid and unitskillusepos -- `<cancel>`: define if the skill can be interrupted when hit (by default the cancel value was 'castcancel' from skill_db.txt) -- `<Line_ID>` : the monster will say the message from 'Line_ID' in mob_chat_db.yml when casting the skill * Added `UMOB_IGNORE_CELL_STACK_LIMIT` for setunitdata/getunitdata script command. When true, the monster will ignore the stack limit (max number of characters that can stack within a single cell) defined by 'official_cell_stack_limit' in misc.conf * The script is disabled by default like on KRO Thanks to @Lemongrass3110 @aleos89 @Badarosk0 @sigtus @Questune09 !
This commit is contained in:
parent
eda43a6295
commit
3abc86e02d
@ -107,11 +107,13 @@ Body:
|
||||
- Id: 37
|
||||
Dialog: Is there anyone waiting for you outside of here? Throw them all away, you are mine now...
|
||||
- Id: 38
|
||||
Dialog: Discard your life and stay confined here. You will yearn for freedom in captivity !!
|
||||
Dialog: Discard your life and stay confined here. You will yearn for freedom in captivity !!
|
||||
- Id: 39
|
||||
Dialog: How much will the outside world change if you stay here in solitude for one thousand years?
|
||||
- Id: 40
|
||||
Dialog: Yes! Yearn for your freedom from this confined place, your captivity here will be permanent !!
|
||||
- Id: 41
|
||||
Dialog: Arrival!
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
|
@ -198,18 +198,18 @@ Body:
|
||||
Map: 1@glast
|
||||
X: 367
|
||||
Y: 304
|
||||
# - Id: 22
|
||||
# Name: Wave Mode - Forest
|
||||
# Enter:
|
||||
# Map: 1@def01
|
||||
# X: 50
|
||||
# Y: 21
|
||||
# - Id: 23
|
||||
# Name: Wave Mode - Sky
|
||||
# Enter:
|
||||
# Map: 1@def02
|
||||
# X: 29
|
||||
# Y: 35
|
||||
- Id: 22
|
||||
Name: Wave Mode - Forest
|
||||
Enter:
|
||||
Map: 1@def01
|
||||
X: 50
|
||||
Y: 21
|
||||
- Id: 23
|
||||
Name: Wave Mode - Sky
|
||||
Enter:
|
||||
Map: 1@def02
|
||||
X: 29
|
||||
Y: 35
|
||||
- Id: 24
|
||||
Name: Nightmarish Jitterbug
|
||||
Enter:
|
||||
|
@ -19,6 +19,7 @@
|
||||
// 1024 - restricted in zone 6
|
||||
// 2048 - restricted in zone 7
|
||||
// 4096 - restricted in zone 8
|
||||
// 8192 - restricted in zone 9
|
||||
//
|
||||
// Passing negative value as flag will unset the flag instead.
|
||||
//
|
||||
@ -240,45 +241,45 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// WoE:TE Items - Only can be used in WoE:TE Castles (All except &16)
|
||||
//----------------------------------------------------------------------------
|
||||
1299,8175 // TE_Woe_Katar
|
||||
1319,8175 // TE_Woe_Axe
|
||||
1399,8175 // TE_Woe_Two_Handed_Axe
|
||||
1437,8175 // TE_Woe_Pike
|
||||
1495,8175 // TE_Woe_Lance
|
||||
1591,8175 // TE_Woe_Book
|
||||
1667,8175 // TE_Woe_Staff
|
||||
1834,8175 // TE_Woe_Fist
|
||||
1932,8175 // TE_Woe_Guitar
|
||||
1987,8175 // TE_Woe_Rope
|
||||
2019,8175 // TE_Woe_Two_Hand_Staff
|
||||
2178,8175 // TE_Woe_Buckler
|
||||
2179,8175 // TE_Woe_Shield
|
||||
2180,8175 // TE_Woe_Magic_Guard
|
||||
2496,8175 // TE_Woe_Shoes
|
||||
2497,8175 // TE_Woe_Boots
|
||||
2498,8175 // TE_Woe_Magic_Sandal
|
||||
2944,8175 // TE_Ring_Of_Protection
|
||||
2945,8175 // TE_Ring_Of_Rage
|
||||
2946,8175 // TE_Ring_Of_Defiance
|
||||
11557,8175 // TE_White_Potion
|
||||
11558,8175 // TE_White_Slim_Potion
|
||||
13083,8175 // TE_Woe_Knife
|
||||
13117,8175 // TE_Woe_Pistol
|
||||
13184,8175 // TE_Woe_Rifle
|
||||
13185,8175 // TE_Woe_Gatling
|
||||
13186,8175 // TE_Woe_Shotgun
|
||||
13187,8175 // TE_Woe_Grenade
|
||||
13317,8175 // TE_Woe_Huuma
|
||||
13439,8175 // TE_Woe_Sword
|
||||
15062,8175 // TE_Woe_Coat
|
||||
15063,8175 // TE_Woe_Chain_Mail
|
||||
15064,8175 // TE_Woe_Mage_Coat
|
||||
16025,8175 // TE_Woe_Mace
|
||||
18118,8175 // TE_Woe_Bow
|
||||
18732,8175 // TE_Woe_Cap
|
||||
18733,8175 // TE_Woe_Bone_Helm
|
||||
18734,8175 // TE_Woe_Magic_Eyes
|
||||
20702,8175 // TE_Woe_Muffler
|
||||
20703,8175 // TE_Woe_Manteau
|
||||
20704,8175 // TE_Woe_Magic_Manteau
|
||||
21006,8175 // TE_Woe_Two_Hand_Sword
|
||||
1299,16367 // TE_Woe_Katar
|
||||
1319,16367 // TE_Woe_Axe
|
||||
1399,16367 // TE_Woe_Two_Handed_Axe
|
||||
1437,16367 // TE_Woe_Pike
|
||||
1495,16367 // TE_Woe_Lance
|
||||
1591,16367 // TE_Woe_Book
|
||||
1667,16367 // TE_Woe_Staff
|
||||
1834,16367 // TE_Woe_Fist
|
||||
1932,16367 // TE_Woe_Guitar
|
||||
1987,16367 // TE_Woe_Rope
|
||||
2019,16367 // TE_Woe_Two_Hand_Staff
|
||||
2178,16367 // TE_Woe_Buckler
|
||||
2179,16367 // TE_Woe_Shield
|
||||
2180,16367 // TE_Woe_Magic_Guard
|
||||
2496,16367 // TE_Woe_Shoes
|
||||
2497,16367 // TE_Woe_Boots
|
||||
2498,16367 // TE_Woe_Magic_Sandal
|
||||
2944,16367 // TE_Ring_Of_Protection
|
||||
2945,16367 // TE_Ring_Of_Rage
|
||||
2946,16367 // TE_Ring_Of_Defiance
|
||||
11557,16367 // TE_White_Potion
|
||||
11558,16367 // TE_White_Slim_Potion
|
||||
13083,16367 // TE_Woe_Knife
|
||||
13117,16367 // TE_Woe_Pistol
|
||||
13184,16367 // TE_Woe_Rifle
|
||||
13185,16367 // TE_Woe_Gatling
|
||||
13186,16367 // TE_Woe_Shotgun
|
||||
13187,16367 // TE_Woe_Grenade
|
||||
13317,16367 // TE_Woe_Huuma
|
||||
13439,16367 // TE_Woe_Sword
|
||||
15062,16367 // TE_Woe_Coat
|
||||
15063,16367 // TE_Woe_Chain_Mail
|
||||
15064,16367 // TE_Woe_Mage_Coat
|
||||
16025,16367 // TE_Woe_Mace
|
||||
18118,16367 // TE_Woe_Bow
|
||||
18732,16367 // TE_Woe_Cap
|
||||
18733,16367 // TE_Woe_Bone_Helm
|
||||
18734,16367 // TE_Woe_Magic_Eyes
|
||||
20702,16367 // TE_Woe_Muffler
|
||||
20703,16367 // TE_Woe_Manteau
|
||||
20704,16367 // TE_Woe_Magic_Manteau
|
||||
21006,16367 // TE_Woe_Two_Hand_Sword
|
||||
|
1268
db/re/mob_db.yml
1268
db/re/mob_db.yml
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@
|
||||
// 1024 - cannot be used in zone 6 maps
|
||||
// 2048 - cannot be used in zone 7 maps
|
||||
// 4096 - cannot be used in zone 8 maps
|
||||
// 8192 - cannot be used in zone 9 maps
|
||||
//
|
||||
// Example:
|
||||
// 8,6 // Endure cannot be used in PvP and GvG maps (2+4)
|
||||
@ -229,3 +230,17 @@
|
||||
409,4096 // WE_CALLPARENT
|
||||
410,4096 // WE_CALLBABY
|
||||
5063,4096 //WE_CALLALLFAMILY
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Zone 9 - Wave Mode
|
||||
//----------------------------------------------------------------------------
|
||||
26,8192 //AL_TELEPORT
|
||||
87,8192 //WZ_ICEWALL
|
||||
197,8192 //NPC_EMOTION
|
||||
219,8192 //RG_INTIMIDATE
|
||||
405,8192 //PF_SPIDERWEB
|
||||
474,8192 //NPC_EMOTION_ON
|
||||
674,8192 //NPC_EXPULSION
|
||||
2284,8192 //SC_FATALMENACE
|
||||
2294,8192 //SC_IGNORANCE
|
||||
2300,8192 //SC_DIMENSIONDOOR
|
||||
|
@ -143,7 +143,7 @@ to move away from their specified spawn region.
|
||||
|
||||
Monster name is the name the monsters will have on screen, and has no relation
|
||||
whatsoever to their names anywhere else. It's the mob id that counts, which
|
||||
identifies monster record in 'mob_db.txt' database of monsters. If the mob name
|
||||
identifies monster record in 'mob_db.yml' database of monsters. If the mob name
|
||||
is given as "--ja--", the 'japanese name' field from the monster database is
|
||||
used, (which, in rAthena, actually contains an English name) if it's "--en--",
|
||||
it's the 'english name' from the monster database (which contains an uppercase
|
||||
@ -168,6 +168,7 @@ player who triggers the script must be within 'trigger' range for the event to
|
||||
work.
|
||||
|
||||
There are two optional fields for monster size and AI.
|
||||
Natural enemies for AI monsters are normal monsters.
|
||||
|
||||
<mob size> can be:
|
||||
Size_Small (0)
|
||||
@ -182,6 +183,7 @@ There are two optional fields for monster size and AI.
|
||||
AI_ZANZOU (4) (Kagerou/Oboro skill)
|
||||
AI_LEGION (5) (Sera skill)
|
||||
AI_FAW (6) (Mechanic skill)
|
||||
AI_WAVEMODE (7) Normal monsters will ignore attack from AI_WAVEMODE monsters
|
||||
|
||||
Alternately, a monster spawned using 'boss_monster' instead of 'monster' is able
|
||||
to be detected on the map with the SC_BOSSMAPINFO status (used by Convex Mirror).
|
||||
@ -246,7 +248,7 @@ it's facing 5.)
|
||||
Sprite ID is the sprite number or constant used to display this particular NPC.
|
||||
You may also use a monster's ID instead to display a monster sprite for this NPC.
|
||||
It is possible to use a job sprite as well, but you must first define it as a
|
||||
monster sprite in 'mob_avail.txt', a full description on how to do this is not
|
||||
monster sprite in 'mob_avail.yml', a full description on how to do this is not
|
||||
in the scope of this manual.
|
||||
A '-1' Sprite ID will make the NPC invisible (and unclickable).
|
||||
A '111' Sprite ID will make an NPC which does not have a sprite, but is still
|
||||
@ -2954,7 +2956,7 @@ recreate these items perfectly if they are destroyed. Here's what you get:
|
||||
@inventorylist_option_id5[] - fifth array of random option IDs
|
||||
@inventorylist_option_value5[] - fifth array of random option values
|
||||
@inventorylist_option_parameter5[] - fifth array of random option parameters
|
||||
@inventorylist_tradable - Returns if an item is tradable or not (Pass item_trade.txt, bound, and rental restrictions).
|
||||
@inventorylist_tradable - Returns if an item is tradable or not (Pass item_db.yml, bound, and rental restrictions).
|
||||
@inventorylist_favorite - Returns if an item is favorite or not
|
||||
|
||||
This could be handy to save/restore a character's inventory, since no other
|
||||
@ -3085,7 +3087,7 @@ Examples
|
||||
*mergeitem2({"<item name>"{,<char_id>}});
|
||||
|
||||
Merge all stackable items that separated by GUID flags
|
||||
(either by flag 4 item_flag.txt or GUID in item_group).
|
||||
(UniqueId in item_db or in item_group).
|
||||
If no item ID/name given, all possible items in player's inventory will be merged.
|
||||
|
||||
---------------------------------------
|
||||
@ -3435,7 +3437,7 @@ of his/her guild, or, if a guild ID is specified, of that guild.
|
||||
*getcastlename("<map name>")
|
||||
|
||||
This function returns the name of the castle when given the map name for that
|
||||
castle. The data is read from 'db/castle_db.txt'.
|
||||
castle. The data is read from 'db/castle_db.yml'.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -4781,7 +4783,7 @@ eggs, and may hatch from either, although, I'm not sure what kind of a mess will
|
||||
this really cause.
|
||||
|
||||
'getitem3' is advance version of 'getitem2' that also use Item Random Option as additional values.
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.txt
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.yml
|
||||
<RandomValueArray> : Array variable of item random option's value.
|
||||
<RandomParamArray> : Array variable of item random option's param.
|
||||
|
||||
@ -4823,7 +4825,7 @@ some cases cannot be traded or stored.
|
||||
For a list of bound types see 'getitembound'.
|
||||
|
||||
'getitembound3' is advance version of 'getitembound2' that also use Item Random Option as additional values.
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.txt
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.yml
|
||||
<RandomValueArray> : Array variable of item random option's value.
|
||||
<RandomParamArray> : Array variable of item random option's param.
|
||||
|
||||
@ -4889,7 +4891,7 @@ in <time> seconds and be automatically deleted. See 'rentitem' for further detai
|
||||
See 'getitem2' for an explanation of the expanded parameters.
|
||||
|
||||
'rentitem3' is advance version of 'rentitem2' that also use Item Random Option as additional values.
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.txt
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.yml
|
||||
<RandomValueArray> : Array variable of item random option's value.
|
||||
<RandomParamArray> : Array variable of item random option's param.
|
||||
|
||||
@ -4929,7 +4931,7 @@ further details.
|
||||
See 'getitem2' for an explanation of the expanded parameters.
|
||||
|
||||
'makeitem3' is advance version of 'makeitem2' that also use Item Random Option as additional values.
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.txt
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.yml
|
||||
<RandomValueArray> : Array variable of item random option's value.
|
||||
<RandomParamArray> : Array variable of item random option's param.
|
||||
|
||||
@ -5015,7 +5017,7 @@ This command will remove a specified amount of items from the invoking/target ch
|
||||
See 'getitem2' for an explanation of the expanded parameters.
|
||||
|
||||
'delitem3' is advance version of 'delitem2' that also use Item Random Option as criteria.
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.txt
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.yml
|
||||
<RandomValueArray> : Array variable of item random option's value.
|
||||
<RandomParamArray> : Array variable of item random option's param.
|
||||
|
||||
@ -5109,7 +5111,7 @@ other parameters that the invoking character has in the inventory.
|
||||
See 'getitem2' for an explanation of the expanded parameters.
|
||||
|
||||
'countitem3' is advance version of 'countitem2' that also use Item Random Option as criteria.
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.txt
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.yml
|
||||
<RandomValueArray> : Array variable of item random option's value.
|
||||
<RandomParamArray> : Array variable of item random option's param.
|
||||
|
||||
@ -5150,7 +5152,7 @@ other parameters that the invoking character has in the inventory.
|
||||
See 'getitem2' for an explanation of the expanded parameters.
|
||||
|
||||
'rentalcountitem3' is advance version of 'rentalcountitem2' that also use Item Random Option as criteria.
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.txt
|
||||
<RandomIDArray> : Array variable of ID for item random option, see db/[pre-]re/item_randomopt_db.yml
|
||||
<RandomValueArray> : Array variable of item random option's value.
|
||||
<RandomParamArray> : Array variable of item random option's param.
|
||||
|
||||
@ -5178,7 +5180,7 @@ Example:
|
||||
*groupranditem <group id>{,<sub_group>};
|
||||
|
||||
Returns the item_id of a random item picked from the group specified. The
|
||||
different groups and their group number are specified in 'db/(pre-)re/item_group_db.txt'.
|
||||
different groups and their group number are specified in 'db/(pre-)re/item_group_db.yml'.
|
||||
|
||||
When used in conjunction with other functions, you can get a random item. For
|
||||
example, for a random pet lure:
|
||||
@ -5196,7 +5198,7 @@ More info, see doc/item_group.txt.
|
||||
|
||||
Similar to the above example, this command allows players to obtain the specified
|
||||
quantity of a random item from the group "<group id>". The different groups and
|
||||
their group number are specified in db/(pre-)re/item_group_db.txt
|
||||
their group number are specified in db/(pre-)re/item_group_db.yml
|
||||
|
||||
If 'quantity' is not defined or 0, it will uses defined amount from Item Group list.
|
||||
|
||||
@ -6417,6 +6419,7 @@ The variable 'killedgid' is set to the ID (unique mob game ID) of the monster ki
|
||||
AI_ZANZOU (4) (Kagerou/Oboro skill)
|
||||
AI_LEGION (5) (Sera skill)
|
||||
AI_FAW (6) (Mechanic skill)
|
||||
AI_WAVEMODE (7) Normal monsters will ignore attack from AI_WAVEMODE monsters
|
||||
|
||||
monster "place",60,100,"Poring",1002,1,"NPCNAME::OnLabel";
|
||||
|
||||
@ -6520,7 +6523,7 @@ command, simply use 1 for type. Any other number won't be recognized.
|
||||
*strmobinfo(<type>,<monster id>);
|
||||
|
||||
This function will return information about a monster record in the database, as
|
||||
per 'db/(pre-)re/mob_db.txt'. Type is the kind of information returned. Valid types are:
|
||||
per 'db/(pre-)re/mob_db.yml'. Type is the kind of information returned. Valid types are:
|
||||
It will return 0 if there is no such monster (or the type value is invalid),
|
||||
or an empty string if you requested the monster's name.
|
||||
|
||||
@ -6623,6 +6626,22 @@ Examples:
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*mob_setidleevent <GID>,<event>;
|
||||
|
||||
This command will attach an event label to the monster with the given <GID> which will execute
|
||||
when the <GID> is idle.
|
||||
|
||||
Example:
|
||||
monster "prontera",0,0,"Quest Poring",1002,1;
|
||||
mob_setidleevent $@mobid[0], "NPC NAME::OnIdle";
|
||||
end;
|
||||
|
||||
OnIdle:
|
||||
mobchat getattachedrid(),0,0x00FF00,"I'm IDLE!";
|
||||
end;
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*disablenpc {"<NPC object name>"};
|
||||
*enablenpc {"<NPC object name>"};
|
||||
|
||||
@ -7636,7 +7655,7 @@ unnerving.
|
||||
Only a few NPC sprites have walking animations, and those that do, do not get
|
||||
the animation invoked when moving the NPC, due to the problem in the NPC walking
|
||||
code, which looks a bit silly. You might have better success by defining a job-
|
||||
sprite based sprite id in 'db/mob_avail.txt' with this.
|
||||
sprite based sprite id in 'db/mob_avail.yml' with this.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -8068,10 +8087,10 @@ flag: Specify target
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*unitskilluseid <GID>,<skill id>,<skill lvl>{,<target id>,<casttime>};
|
||||
*unitskilluseid <GID>,"<skill name>",<skill lvl>{,<target id>,<casttime>};
|
||||
*unitskillusepos <GID>,<skill id>,<skill lvl>,<x>,<y>{,<casttime>};
|
||||
*unitskillusepos <GID>,"<skill name>",<skill lvl>,<x>,<y>{,<casttime>};
|
||||
*unitskilluseid <GID>,<skill id>,<skill lvl>{,<target id>,<casttime>,<cancel>,<Line_ID>};
|
||||
*unitskilluseid <GID>,"<skill name>",<skill lvl>{,<target id>,<casttime>,<cancel>,<Line_ID>};
|
||||
*unitskillusepos <GID>,<skill id>,<skill lvl>,<x>,<y>{,<casttime>,<cancel>,<Line_ID>};
|
||||
*unitskillusepos <GID>,"<skill name>",<skill lvl>,<x>,<y>{,<casttime>,<cancel>,<Line_ID>};
|
||||
|
||||
This is the replacement of the older commands, these use the same values for
|
||||
GID as the other unit* commands (See 'GID').
|
||||
@ -8081,6 +8100,12 @@ Cast time is the amount of seconds to add or remove from the skill. Use a positi
|
||||
add and negative value to subtract. Using 0 or no value will use the default skill cast time.
|
||||
For the position, the x and y are given in the UnitSkillUsePos.
|
||||
|
||||
<cancel> defines if the cast can be interrupted when hit (true/false).
|
||||
CastCancel from skill_db.yml is the default value of <cancel>.
|
||||
|
||||
If <Line_ID> is defined (positive number, default 0) the monster will say the message from 'Line_ID'
|
||||
in mob_chat_db.yml when casting the skill.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*unitexists <GID>;
|
||||
@ -8208,6 +8233,7 @@ Parameters (indexes) for monsters are:
|
||||
UMOB_ROBE
|
||||
UMOB_BODY2
|
||||
UMOB_GROUP_ID
|
||||
UMOB_IGNORE_CELL_STACK_LIMIT
|
||||
|
||||
-----
|
||||
|
||||
|
808
npc/re/instances/WaveMode.txt
Normal file
808
npc/re/instances/WaveMode.txt
Normal file
@ -0,0 +1,808 @@
|
||||
//===== rAthena Script =======================================
|
||||
//= Wave Mode
|
||||
//===== Description: =========================================
|
||||
//= [Walkthrough Conversion]
|
||||
//= Wave Mode Forest and Sky Instances
|
||||
//- Officially monsters can use their skills
|
||||
// (NPC_SUMMONSLAVE, at least). NPC_EMOTION and
|
||||
// NPC_EMOTION_ON have been blocked since it disrupts the
|
||||
// walk system of the instance on rAthena.
|
||||
//- Note: The instance is currently disabled on KRO.
|
||||
//===== Changelogs: ==========================================
|
||||
//= 1.0 First version. [Capuche]
|
||||
//============================================================
|
||||
|
||||
// Simple function to move the monster when idle.
|
||||
// Move the monster to the next coordinates + end the script on successful; kill the monster + return on failure
|
||||
// callfunc( "F_mobidle", <npc name + idle label>, <size coord>, <defined x array>, <x shift>, <defined y array>, <defined spot-spot distance array> );
|
||||
function script F_mobidle {
|
||||
sleep2 1000; // stop if no RID
|
||||
|
||||
.@game_id = getattachedrid();
|
||||
.@dist_min = 300;
|
||||
.@size = getarg(1);
|
||||
.@dx = getarg(3);
|
||||
getunitdata .@game_id, .@data;
|
||||
|
||||
for ( .@i = 0; .@i < .@size; .@i++ ) {
|
||||
.@dist_to_spot[.@i] = distance( .@data[UMOB_X], .@data[UMOB_Y], (getelementofarray( getarg(2),.@i ) + .@dx), getelementofarray( getarg(4),.@i ) );
|
||||
if (.@dist_min >= .@dist_to_spot[.@i]) {
|
||||
.@dist_min = .@dist_to_spot[.@i];
|
||||
.@index = .@i;
|
||||
}
|
||||
}
|
||||
|
||||
if (.@dist_min <= 1) {
|
||||
.@index++;
|
||||
if (.@index >= .@size) {
|
||||
unitskilluseid .@game_id,301,1,.@game_id,1,false,41; // SA_INSTANTDEATH
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (.@index < (.@size -1)) {
|
||||
.@total[0] = .@dist_min + getelementofarray( getarg(5), .@index );
|
||||
.@total[1] = .@dist_to_spot[.@index + 1] + getelementofarray( getarg(5), .@index+1 );
|
||||
if (.@total[0] > .@total[1])
|
||||
.@index = .@index + 1;
|
||||
}
|
||||
|
||||
if (.@dist_to_spot[.@index] > 14) {
|
||||
unitkill .@game_id;
|
||||
end;
|
||||
}
|
||||
if (!.@data[UMOB_TARGETID]) {
|
||||
unitwalk .@game_id, (getelementofarray( getarg(2),.@index ) + .@dx), getelementofarray( getarg(4),.@index );
|
||||
sleep2 50; // for now a delay between unitwalk and mob_setidleevent is needed
|
||||
}
|
||||
mob_setidleevent .@game_id, getarg(0);
|
||||
end;
|
||||
}
|
||||
|
||||
prontera,146,75,1 script Zonda Rep#pron 4_F_ZONDAGIRL,{
|
||||
.@player_name$ = strcharinfo(0);
|
||||
getmapxy .@map_name$,.@x,.@y, BL_PC;
|
||||
|
||||
if (is_party_leader() == true) {
|
||||
.@party_id = getcharid(1);
|
||||
getpartymember .@party_id, 1;
|
||||
getpartymember .@party_id, 2;
|
||||
for ( .@i = 0; .@i < $@partymembercount; .@i++ ) {
|
||||
if (isloggedin($@partymemberaid[.@i], $@partymembercid[.@i]) == 1)
|
||||
.@count_online++;
|
||||
}
|
||||
.@menu_entry$ = "Request entry.";
|
||||
}
|
||||
|
||||
mes "[Belka]";
|
||||
mes "Welcome to Zonda, where innovation begins. What can I do for you?";
|
||||
next;
|
||||
switch( select( "Why are you here?", .@menu_entry$, "Enter ^6B9900<Wave Mode - Forest>^000000.", "Enter ^6B9900<Wave Mode - Sky>^000000.", "Cancel." ) ) {
|
||||
case 1:
|
||||
mes "[Belka]";
|
||||
mes "We now offer a new service. Have you heard about the dimensional rifts?";
|
||||
next;
|
||||
mes "[Belka]";
|
||||
mes "In case you haven't, many organizations and scientists study the rifts formed between dimensions.";
|
||||
next;
|
||||
mes "[Belka]";
|
||||
mes "One of them is my company, Zonda, and after long, painstaking research...";
|
||||
next;
|
||||
mes "[Belka]";
|
||||
mes "We've developed two different dimensional rifts that we call Wave Modes - Forest and Sky!";
|
||||
next;
|
||||
mes "[Belka]";
|
||||
mes "Do you have any questions about Zonda's ambitious new project, Wave Mode?";
|
||||
while(true) {
|
||||
next;
|
||||
switch( select( "About ^6B9900<Wave Mode - Forest>^000000", "About ^6B9900<Wave Mode - Sky>^000000", "No." ) ) {
|
||||
case 1:
|
||||
mes "[Belka]";
|
||||
mes "The ^6B9900<Wave Mode - Forest>^000000";
|
||||
mes "Introducing the first Wave Mode service, Zonda's objective is to work with your party members to keep monster waves from reaching the other side of the bridge.";
|
||||
next;
|
||||
mes "[Belka]";
|
||||
mes "Monsters will advance without fighting, but the party will fail if 20 monsters are let go..";
|
||||
break;
|
||||
case 2:
|
||||
mes "[Belka]";
|
||||
mes "The ^6B9900<Wave Mode - Sky>^000000";
|
||||
mes "Available once a day. Like the other Wave Mode, keep the monsters away from reaching the other side of the map.";
|
||||
next;
|
||||
mes "[Belka]";
|
||||
mes "Feel free to come back with your party.";
|
||||
break;
|
||||
case 3:
|
||||
mes "[Belka]";
|
||||
mes "Thank you for visiting Zonda, where innovation begins.";
|
||||
close;
|
||||
}
|
||||
next;
|
||||
mes "[Belka]";
|
||||
mes "Any other questions?";
|
||||
}
|
||||
case 2:
|
||||
mes "[Belka]";
|
||||
mes "Which Wave Mode would you like to enter: Forest or Sky?";
|
||||
next;
|
||||
.@s = select( "Enter ^6B9900<Wave Mode - Forest>^000000.", "Enter ^6B9900<Wave Mode - Sky>^000000." ) - 1;
|
||||
setarray .@instance_name$[0], "Wave Mode - Forest", "Wave Mode - Sky";
|
||||
mes "[Belka]";
|
||||
mes "" + .@count_online + " party " + (.@count_online == 1 ? "member" : "members") + " found " + .@player_name$ + ", right? To enter the ^6B9900<" + .@instance_name$[.@s] + ">^000000, please sign here.";
|
||||
next;
|
||||
select("Sign.");
|
||||
mes "[Belka]";
|
||||
mes "" + .@player_name$ + " has requested to enter the ^6B9900<" + .@instance_name$[.@s] + ">^000000. Please come back when it's your turn to enter.";
|
||||
if (instance_create(.@instance_name$[.@s]) < 0) {
|
||||
mes "Party Name: " + getpartyname( getcharid(1) );
|
||||
mes "Party Leader: " + strcharinfo(0);
|
||||
mes "^0000ff" + .@instance_name$[.@s] + " ^000000 - Reservation Failed.";
|
||||
close;
|
||||
}
|
||||
close;
|
||||
case 3:
|
||||
switch( instance_enter("Wave Mode - Forest") ) {
|
||||
case IE_OTHER:
|
||||
mes "[Belka]";
|
||||
mes "An unknown error has occurred.";
|
||||
close;
|
||||
case IE_NOINSTANCE:
|
||||
case IE_NOMEMBER:
|
||||
mes "[Belka]";
|
||||
mes "Please wait for ^6B9900<Wave Mode - Forest>^000000 stabilization.";
|
||||
close;
|
||||
case IE_OK:
|
||||
mapannounce .@map_name$, "" + .@player_name$ + " of the party " + getpartyname(getcharid(1)) + " is entering <Wave Mode - Forest>.", bc_map,0xFF99;
|
||||
// warp "1@def01",50,21;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
switch( instance_enter("Wave Mode - Sky") ) {
|
||||
case IE_OTHER:
|
||||
mes "[Belka]";
|
||||
mes "An unknown error has occurred.";
|
||||
close;
|
||||
case IE_NOINSTANCE:
|
||||
case IE_NOMEMBER:
|
||||
mes "[Belka]";
|
||||
mes "Currently the ^6B9900<Wave Mode - Sky>^000000 is being stabilized for your convenience. Please wait.";
|
||||
close;
|
||||
case IE_OK:
|
||||
mapannounce .@map_name$, "" + .@player_name$ + " of the party " + getpartyname(getcharid(1)) + " is entering <Wave Mode - Sky>.", bc_map,0xFF99;
|
||||
// warp "1@def02",29,35;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
mes "[Belka]";
|
||||
mes "Thank you for visiting Zonda, where innovation begins.";
|
||||
close;
|
||||
}
|
||||
wave_mode_map$ = .@map_name$;
|
||||
wave_mode_x = .@x;
|
||||
wave_mode_y = .@y;
|
||||
end;
|
||||
}
|
||||
payon,166,98,1 duplicate(Zonda Rep#pron) Zonda Rep#pay 4_F_ZONDAGIRL
|
||||
moc_para01,45,89,3 duplicate(Zonda Rep#pron) Zonda Rep#para 4_F_ZONDAGIRL
|
||||
morocc,168,271,4 duplicate(Zonda Rep#pron) Zonda Rep#mor 4_F_ZONDAGIRL
|
||||
|
||||
|
||||
// Wave mode forest
|
||||
1@def01,50,21,0 script #wave_mode_forest_entrance HIDDEN_WARP_NPC,1,1,{
|
||||
end;
|
||||
OnTouch:
|
||||
disablenpc instance_npcname("#wave_mode_forest_entrance");
|
||||
initnpctimer;
|
||||
end;
|
||||
OnTimer2000:
|
||||
mapannounce 'map_def01$, "We would like to thank all loyal customers of the Cool Event Corporation.", bc_map;
|
||||
end;
|
||||
OnTimer7000:
|
||||
mapannounce 'map_def01$, "<Wave mode - Forest> prevent monsters from reaching the other side of the bridge.", bc_map;
|
||||
end;
|
||||
OnTimer12000:
|
||||
mapannounce 'map_def01$, "If 20 monsters reach the other side, the game is over.", bc_map;
|
||||
end;
|
||||
OnTimer17000:
|
||||
mapannounce 'map_def01$, "Ok, here they come.", bc_map;
|
||||
end;
|
||||
OnTimer22000:
|
||||
stopnpctimer;
|
||||
donpcevent instance_npcname("#wave_mode_forest_system") + "::OnStart";
|
||||
end;
|
||||
}
|
||||
|
||||
1@def01,1,1,0 script #wave_mode_forest_system -1,{
|
||||
end;
|
||||
OnStart:
|
||||
initnpctimer;
|
||||
end;
|
||||
OnTimer1000:
|
||||
mapannounce 'map_def01$, "3", bc_map;
|
||||
end;
|
||||
OnTimer2000:
|
||||
mapannounce 'map_def01$, "2", bc_map;
|
||||
end;
|
||||
OnTimer3000:
|
||||
mapannounce 'map_def01$, "1", bc_map;
|
||||
end;
|
||||
OnTimer4000:
|
||||
'wave++;
|
||||
if ('wave % 5)
|
||||
mapannounce 'map_def01$, "-- Wave " + 'wave + " --", bc_map;
|
||||
else
|
||||
mapannounce 'map_def01$, "!! Champions summoned !!", bc_map;
|
||||
donpcevent 'npc_name$ + "::OnSpawn";
|
||||
end;
|
||||
OnTimer24000:
|
||||
mapannounce 'map_def01$, "Next monsters will come out soon. Get ready.", bc_map;
|
||||
initnpctimer;
|
||||
end;
|
||||
OnStop:
|
||||
stopnpctimer;
|
||||
end;
|
||||
}
|
||||
|
||||
1@def01,1,1,0 script #wave_mode_forest_spawn -1,{
|
||||
end;
|
||||
OnSpawn:
|
||||
switch( 'wave % 70 ) {
|
||||
case 1:
|
||||
'mob_id = 2401; // G_PORING
|
||||
break;
|
||||
case 2:
|
||||
'mob_id = 2582; // G_LUNATIC
|
||||
break;
|
||||
case 3:
|
||||
'mob_id = 2573; // G_CHONCHON
|
||||
break;
|
||||
case 4:
|
||||
'mob_id = 2590; // G_ROCKER
|
||||
break;
|
||||
case 5:
|
||||
'mob_id = 2699; // C1_PORING
|
||||
break;
|
||||
|
||||
case 6:
|
||||
'mob_id = 2577; // G_FABRE
|
||||
break;
|
||||
case 7:
|
||||
'mob_id = 1747; // G_SNAKE
|
||||
break;
|
||||
case 8:
|
||||
'mob_id = 2595; // G_STAINER
|
||||
break;
|
||||
case 9:
|
||||
'mob_id = 2576; // G_CREAMY
|
||||
break;
|
||||
case 10:
|
||||
'mob_id = 2678; // C3_RODA_FROG
|
||||
break;
|
||||
|
||||
case 11:
|
||||
'mob_id = 2572; // G_CARAMEL
|
||||
break;
|
||||
case 12:
|
||||
'mob_id = 1603; // G_BIGFOOT
|
||||
break;
|
||||
case 13:
|
||||
'mob_id = 2589; // G_POPORING
|
||||
break;
|
||||
case 14:
|
||||
'mob_id = 2578; // G_HORN
|
||||
break;
|
||||
case 15:
|
||||
'mob_id = 2670; // C5_SCORPION
|
||||
break;
|
||||
|
||||
case 16:
|
||||
'mob_id = 2601; // G_YOYO
|
||||
break;
|
||||
case 17:
|
||||
'mob_id = 2575; // G_COCO
|
||||
break;
|
||||
case 18:
|
||||
'mob_id = 2583; // G_MARTIN
|
||||
break;
|
||||
case 19:
|
||||
'mob_id = 2600; // G_WOLF
|
||||
break;
|
||||
case 20:
|
||||
'mob_id = 2705; // C2_POISON_SPORE
|
||||
break;
|
||||
|
||||
case 21:
|
||||
'mob_id = 1430; // G_ARGOS
|
||||
break;
|
||||
case 22:
|
||||
'mob_id = 2597; // G_STEEL_CHONCHON
|
||||
break;
|
||||
case 23:
|
||||
'mob_id = 1431; // G_BAPHOMET_
|
||||
break;
|
||||
case 24:
|
||||
'mob_id = 2591; // G_SAVAGE
|
||||
break;
|
||||
case 25:
|
||||
'mob_id = 2857; // C5_DENIRO
|
||||
break;
|
||||
|
||||
case 26:
|
||||
'mob_id = 1457; // G_MANTIS
|
||||
break;
|
||||
case 27:
|
||||
'mob_id = 1424; // G_SIDE_WINDER
|
||||
break;
|
||||
case 28:
|
||||
'mob_id = 1429; // G_ARGIOPE
|
||||
break;
|
||||
case 29:
|
||||
'mob_id = 1441; // G_PENOMENA
|
||||
break;
|
||||
case 30:
|
||||
'mob_id = 2648; // C3_SOLDIER_SKELETON
|
||||
break;
|
||||
|
||||
case 31:
|
||||
'mob_id = 1422; // G_HUNTER_FLY
|
||||
break;
|
||||
case 32:
|
||||
'mob_id = 2585; // G_MOLE
|
||||
break;
|
||||
case 33:
|
||||
'mob_id = 2592; // G_SIORAVA
|
||||
break;
|
||||
case 34:
|
||||
'mob_id = 2571; // G_BUTOIJO
|
||||
break;
|
||||
case 35:
|
||||
'mob_id = 2673; // C3_SAVAGE
|
||||
break;
|
||||
|
||||
case 36:
|
||||
'mob_id = 2574; // G_CIVIL_SERVANT
|
||||
break;
|
||||
case 37:
|
||||
'mob_id = 1459; // G_MARIONETTE
|
||||
break;
|
||||
case 38:
|
||||
'mob_id = 1565; // G_WILD_GINSENG
|
||||
break;
|
||||
case 39:
|
||||
'mob_id = 2602; // G_ZIPPER_BEAR
|
||||
break;
|
||||
case 40:
|
||||
'mob_id = 2644; // C4_STALACTIC_GOLEM
|
||||
break;
|
||||
|
||||
case 41:
|
||||
'mob_id = 2588; // G_PITMAN
|
||||
break;
|
||||
case 42:
|
||||
'mob_id = 1624; // G_WASTE_STOVE
|
||||
break;
|
||||
case 43:
|
||||
'mob_id = 2570; // G_BREEZE
|
||||
break;
|
||||
case 44:
|
||||
'mob_id = 1573; // G_ELDER
|
||||
break;
|
||||
case 45:
|
||||
'mob_id = 2811; // C3_GRAND_PECO
|
||||
break;
|
||||
|
||||
case 46:
|
||||
'mob_id = 2598; // G_UNGOLIANT
|
||||
break;
|
||||
case 47:
|
||||
'mob_id = 1606; // G_GARM_BABY
|
||||
break;
|
||||
case 48:
|
||||
'mob_id = 1794; // G_ROWEEN
|
||||
break;
|
||||
case 49:
|
||||
'mob_id = 2596; // G_STAPO
|
||||
break;
|
||||
case 50:
|
||||
'mob_id = 2838; // C5_EVIL_DRUID
|
||||
break;
|
||||
|
||||
case 51:
|
||||
'mob_id = 2569; // G_ANOPHELES
|
||||
break;
|
||||
case 52:
|
||||
'mob_id = 2584; // G_MINERAL
|
||||
break;
|
||||
case 53:
|
||||
'mob_id = 2599; // G_WILD_RIDER
|
||||
break;
|
||||
case 54:
|
||||
'mob_id = 1531; // G_EVIL_CLOUD_HERMIT
|
||||
break;
|
||||
case 55:
|
||||
'mob_id = 2612; // C5_WOOD_GOBLIN
|
||||
break;
|
||||
|
||||
case 56:
|
||||
'mob_id = 2587; // G_OBSIDIAN
|
||||
break;
|
||||
case 57:
|
||||
'mob_id = 1564; // G_WICKED_NYMPH
|
||||
break;
|
||||
case 58:
|
||||
'mob_id = 2586; // G_NERAID
|
||||
break;
|
||||
case 59:
|
||||
'mob_id = 1483; // G_RYBIO
|
||||
break;
|
||||
case 60:
|
||||
'mob_id = 2888; // C2_BANASPATY
|
||||
break;
|
||||
|
||||
case 61:
|
||||
'mob_id = 2593; // G_SIROMA
|
||||
break;
|
||||
case 62:
|
||||
'mob_id = 2580; // G_KAHO
|
||||
break;
|
||||
case 63:
|
||||
'mob_id = 1600; // G_HEATER
|
||||
break;
|
||||
case 64:
|
||||
'mob_id = 1791; // G_GALION
|
||||
break;
|
||||
case 65:
|
||||
'mob_id = 2629; // C3_UNGOLIANT
|
||||
break;
|
||||
|
||||
case 66:
|
||||
'mob_id = 2581; // G_LUDE
|
||||
break;
|
||||
case 67:
|
||||
'mob_id = 2579; // G_HYLOZOIST
|
||||
break;
|
||||
case 68:
|
||||
'mob_id = 1549; // G_LAVA_GOLEM
|
||||
break;
|
||||
case 69:
|
||||
'mob_id = 2594; // G_SNOWIER
|
||||
break;
|
||||
default:
|
||||
'mob_id = 2730; // C2_NOVUS
|
||||
break;
|
||||
}
|
||||
initnpctimer;
|
||||
end;
|
||||
OnTimer1000:
|
||||
stopnpctimer;
|
||||
if (('wave % 5) == 0) { // champion
|
||||
donpcevent 'npc_name$ + "::OnSpawn0";
|
||||
donpcevent 'npc_name$ + "::OnSpawn1";
|
||||
donpcevent 'npc_name$ + "::OnSpawn2";
|
||||
donpcevent 'npc_name$ + "::OnSpawn3";
|
||||
donpcevent 'npc_name$ + "::OnSpawn4";
|
||||
end;
|
||||
}
|
||||
if ('wave == 1) // first wave at x = 51
|
||||
.@dx = 3;
|
||||
else
|
||||
.@dx = 2;
|
||||
for ( .@i = 0; .@i < 24; .@i++ ) {
|
||||
donpcevent 'npc_name$ + "::OnSpawn" + .@dx;
|
||||
sleep 300;
|
||||
}
|
||||
// total ~7 secs
|
||||
end;
|
||||
OnSpawn0: callsub( S_Spawn, 0 );
|
||||
OnSpawn1: callsub( S_Spawn, 1 );
|
||||
OnSpawn2: callsub( S_Spawn, 2 );
|
||||
OnSpawn3: callsub( S_Spawn, 3 );
|
||||
OnSpawn4: callsub( S_Spawn, 4 );
|
||||
S_Spawn:
|
||||
.@x = 48 + getarg(0);
|
||||
monster 'map_def01$,.@x,74, "Invader!", 'mob_id,1;
|
||||
.@gid = $@mobid[0];
|
||||
setunitdata .@gid, UMOB_MODE, ( MD_CANMOVE|MD_NORANDOMWALK );
|
||||
setunitdata .@gid, UMOB_IGNORE_CELL_STACK_LIMIT, true;
|
||||
mob_setidleevent .@gid, 'npc_name$ + "::OnIdle" + getarg(0);
|
||||
end;
|
||||
|
||||
OnIdle0: callsub( S_Idle, 0 );
|
||||
OnIdle1: callsub( S_Idle, 1 );
|
||||
OnIdle2: callsub( S_Idle, 2 );
|
||||
OnIdle3: callsub( S_Idle, 3 );
|
||||
OnIdle4: callsub( S_Idle, 4 );
|
||||
S_Idle:
|
||||
callfunc( "F_mobidle", ('npc_name$ + "::OnIdle" + getarg(0)), 'size_coord, 'x_mob, getarg(0), 'y_mob, 'dist_spot_AZ );
|
||||
'mob_escaped++;
|
||||
if ('mob_escaped <= 20)
|
||||
mapannounce 'map_def01$, "" + 'mob_escaped + " " + ('mob_escaped == 1 ? "monster has" : "monsters have") + " escaped.", bc_map;
|
||||
if ('mob_escaped == 20)
|
||||
donpcevent instance_npcname("#wave_mode_forest_out") + "::OnFail";
|
||||
end;
|
||||
}
|
||||
|
||||
// 1@def01,50,23,0 script #wave_mode_forest_warp WARPNPC,2,2,{
|
||||
1@def01,50,30,0 script #wave_mode_forest_warp WARPNPC,2,2,{// official warp out
|
||||
end;
|
||||
OnTouch:
|
||||
if (wave_mode_map$ == "")
|
||||
warp "prontera",0,0;
|
||||
else {
|
||||
warp wave_mode_map$, wave_mode_x, wave_mode_y;
|
||||
wave_mode_map$ = "";
|
||||
wave_mode_x = wave_mode_y = 0;
|
||||
}
|
||||
end;
|
||||
}
|
||||
|
||||
1@def01,1,1,0 script #wave_mode_forest_out -1,{
|
||||
end;
|
||||
OnFail:
|
||||
donpcevent instance_npcname("#wave_mode_forest_system") + "::OnStop";
|
||||
|
||||
mapannounce 'map_def01$, "You have failed the <Wave mode - Forest> challenge.", bc_map;
|
||||
enablenpc instance_npcname("#wave_mode_forest_warp");
|
||||
initnpctimer;
|
||||
end;
|
||||
OnTimer1000:
|
||||
mapannounce 'map_def01$, "<Wave mode - Forest> service has closed. You will be returned to the place you entered if you use the warp at the entrance.", bc_map;
|
||||
end;
|
||||
OnTimer30000:
|
||||
stopnpctimer;
|
||||
instance_destroy();
|
||||
end;
|
||||
|
||||
OnInstanceInit:
|
||||
'wave = 'mob_escaped = 0;
|
||||
|
||||
'map_def01$ = instance_mapname("1@def01");
|
||||
'npc_name$ = instance_npcname("#wave_mode_forest_spawn");
|
||||
|
||||
disablenpc instance_npcname("#wave_mode_forest_system");
|
||||
disablenpc instance_npcname("#wave_mode_forest_warp");
|
||||
disablenpc instance_npcname("#wave_mode_forest_out");
|
||||
|
||||
setarray 'x_mob[0], 48, 48, 48, 48, 48, 48, 48;
|
||||
setarray 'y_mob[0], 74, 65, 56, 48, 40, 31, 23;
|
||||
|
||||
'size_coord = getarraysize('y_mob);
|
||||
for ( .@i = 0; .@i < 'size_coord -1; .@i++ ) {
|
||||
.@dist_mob[.@i+1] = distance( 'x_mob[.@i], 'y_mob[.@i], 'x_mob[.@i+1], 'y_mob[.@i+1] );
|
||||
.@total_mob += .@dist_mob[.@i+1];
|
||||
}
|
||||
for ( .@i = 0; .@i < 'size_coord -1; .@i++ )
|
||||
'dist_spot_AZ[.@i] = .@total_mob - .@dist_mob[.@i];
|
||||
end;
|
||||
}
|
||||
|
||||
|
||||
// Wave mode sky
|
||||
1@def02,30,35,0 script #wave_mode_sky_entrance WARPNPC,1,1,{
|
||||
end;
|
||||
OnTouch:
|
||||
if ('status_instance == 1)
|
||||
end;
|
||||
else if ('status_instance == 0) {
|
||||
'status_instance = 1;
|
||||
initnpctimer;
|
||||
disablenpc instance_npcname("#wave_mode_sky_entrance");
|
||||
}
|
||||
else if ('status_instance == 2) {
|
||||
if (wave_mode_map$ == "")
|
||||
warp "prontera",0,0;
|
||||
else {
|
||||
warp wave_mode_map$, wave_mode_x, wave_mode_y;
|
||||
wave_mode_map$ = "";
|
||||
wave_mode_x = wave_mode_y = 0;
|
||||
}
|
||||
}
|
||||
end;
|
||||
OnTimer4000:
|
||||
stopnpctimer;
|
||||
donpcevent instance_npcname("#wave_mode_sky_system") + "::OnStart";
|
||||
end;
|
||||
}
|
||||
|
||||
1@def02,1,1,0 script #wave_mode_sky_system -1,{
|
||||
end;
|
||||
OnStart:
|
||||
initnpctimer;
|
||||
mapannounce 'map_def02$, "We would like to thank all costumers who always use Zonda Agency.", bc_map;
|
||||
end;
|
||||
OnTimer1000:
|
||||
mapannounce 'map_def02$, "3", bc_map;
|
||||
end;
|
||||
OnTimer2000:
|
||||
mapannounce 'map_def02$, "2", bc_map;
|
||||
end;
|
||||
OnTimer3000:
|
||||
mapannounce 'map_def02$, "1", bc_map;
|
||||
end;
|
||||
OnTimer4000:
|
||||
'wave_num++;
|
||||
if ('wave_num % 5) {
|
||||
donpcevent 'npc_name_mob$ + "::OnSpawn";
|
||||
donpcevent 'npc_name_mercenary$ + "::OnStart";
|
||||
donpcevent 'npc_name_mercenary$ + "::OnStart";
|
||||
}
|
||||
else {
|
||||
donpcevent 'npc_name_treasure$ + "::OnStart";
|
||||
}
|
||||
end;
|
||||
OnTimer24000:
|
||||
mapannounce 'map_def02$, "Next monster wave will come out soon. Get ready.", bc_map;
|
||||
initnpctimer;
|
||||
end;
|
||||
OnStop:
|
||||
stopnpctimer;
|
||||
end;
|
||||
}
|
||||
|
||||
1@def02,1,1,0 script #wave_mode_sky_treasure -1,{
|
||||
end;
|
||||
OnStart:
|
||||
if ('treasure_num < 5)
|
||||
'treasure_num++;
|
||||
mapannounce 'map_def02$, "!! " + 'treasure_num + " treasure box appeared !!", bc_map;
|
||||
for ( .@i = 0; .@i < 'treasure_num; .@i++ ) {
|
||||
monster 'map_def02$,0,0, "Treasure box",3075,1; // WA_TREASURE
|
||||
'treasure_gid[.@i] = $@mobid[0];
|
||||
}
|
||||
initnpctimer;
|
||||
end;
|
||||
OnTimer16500: callsub( S_Dice, ET_DICE3 );
|
||||
OnTimer17500: callsub( S_Dice, ET_DICE2 );
|
||||
OnTimer18500: callsub( S_Dice, ET_DICE1 );
|
||||
OnTimer19500:
|
||||
for ( .@i = 0; .@i < 'treasure_num; .@i++ ) {
|
||||
if (unitexists('treasure_gid[.@i]))
|
||||
unitskilluseid 'treasure_gid[.@i],301,1,'treasure_gid[.@i],-1; // SA_INSTANTDEATH
|
||||
}
|
||||
donpcevent 'npc_name_treasure$ + "::OnStop";
|
||||
end;
|
||||
|
||||
S_Dice:
|
||||
.@emotion_num = getarg(0);
|
||||
for ( .@i = 0; .@i < 'treasure_num; .@i++ ) {
|
||||
if (unitexists('treasure_gid[.@i]))
|
||||
emotion .@emotion_num, 'treasure_gid[.@i];
|
||||
}
|
||||
end;
|
||||
|
||||
OnStop:
|
||||
deletearray 'treasure_gid[0], 'treasure_num;
|
||||
stopnpctimer;
|
||||
end;
|
||||
}
|
||||
|
||||
1@def02,1,1,0 script #wave_mode_sky_mercenary -1,{
|
||||
end;
|
||||
OnStart:
|
||||
monster 'map_def02$,29,35, "Mercenary", 3086,1, "",0,AI_WAVEMODE; // WA_MERCENARY
|
||||
.@gid = $@mobid[0];
|
||||
emotion ET_SURPRISE, .@gid;
|
||||
setunitdata .@gid, UMOB_IGNORE_CELL_STACK_LIMIT, true;
|
||||
mob_setidleevent .@gid, 'npc_name_mercenary$ + "::OnIdle";
|
||||
sleep 45000;
|
||||
if (unitexists(.@gid))
|
||||
unitskilluseid .@gid,301,1,.@gid,1,false; // SA_INSTANTDEATH
|
||||
end;
|
||||
|
||||
OnIdle:
|
||||
callfunc( "F_mobidle", ('npc_name_mercenary$ + "::OnIdle"), 'size_coord, 'x_merc, 0, 'y_merc, 'dist_spot_ZA );
|
||||
end;
|
||||
}
|
||||
|
||||
1@def02,1,1,0 script #wave_mode_sky_mob_spawn -1,{
|
||||
end;
|
||||
OnSpawn:
|
||||
mapannounce 'map_def02$, "-- Wave " + 'wave_num + " --", bc_map;
|
||||
|
||||
.@i = ('wave_num % 10) - 1;
|
||||
setarray .@mob_list[0],
|
||||
3076, // WA_MONSTER_1
|
||||
3077, // WA_MONSTER_2
|
||||
3078, // WA_MONSTER_3
|
||||
3079, // WA_MONSTER_4
|
||||
3080, // WA_MONSTER_5 (skipped)
|
||||
3081, // WA_MONSTER_6
|
||||
3082, // WA_MONSTER_7
|
||||
3083, // WA_MONSTER_8
|
||||
3084, // WA_MONSTER_9
|
||||
3085; // WA_MONSTER_10 (skipped)
|
||||
'mob_id = .@mob_list[.@i];
|
||||
initnpctimer;
|
||||
end;
|
||||
OnTimer1000: callsub( S_Spawn, true ); // aggressive
|
||||
OnTimer1500: callsub( S_Spawn, false ); // passive
|
||||
OnTimer2000: callsub( S_Spawn, true );
|
||||
OnTimer2500: callsub( S_Spawn, false );
|
||||
OnTimer3000: callsub( S_Spawn, true );
|
||||
OnTimer3500: callsub( S_Spawn, false );
|
||||
OnTimer4000: callsub( S_Spawn, true );
|
||||
OnTimer4500: callsub( S_Spawn, false );
|
||||
OnTimer5000: callsub( S_Spawn, true );
|
||||
OnTimer5500: callsub( S_Spawn, false );
|
||||
OnTimer6000: callsub( S_Spawn, true );
|
||||
OnTimer6500: callsub( S_Spawn, false );
|
||||
OnTimer7000: callsub( S_Spawn, true );
|
||||
OnTimer7500: callsub( S_Spawn, false );
|
||||
OnTimer8000: callsub( S_Spawn, true );
|
||||
OnTimer8500:
|
||||
stopnpctimer;
|
||||
end;
|
||||
|
||||
S_Spawn:
|
||||
monster 'map_def02$,48,67, "Go!", 'mob_id,1;
|
||||
if (getarg(0) == true)
|
||||
setunitdata $@mobid[0], UMOB_MODE, ( MD_CANMOVE|MD_NORANDOMWALK|MD_AGGRESSIVE|MD_CANATTACK );
|
||||
.@gid = $@mobid[0];
|
||||
emotion ET_SURPRISE, .@gid;
|
||||
setunitdata .@gid, UMOB_IGNORE_CELL_STACK_LIMIT, true;
|
||||
mob_setidleevent .@gid, 'npc_name_mob$ + "::OnIdle";
|
||||
end;
|
||||
|
||||
OnIdle:
|
||||
// monster are walking to the nearest next spot
|
||||
callfunc( "F_mobidle", ('npc_name_mob$ + "::OnIdle"), 'size_coord, 'x_mob, 0, 'y_mob, 'dist_spot_AZ );
|
||||
'mob_escaped++;
|
||||
if ('mob_escaped <= 20)
|
||||
mapannounce 'map_def02$, "" + 'mob_escaped + " " + ('mob_escaped == 1 ? "monster has" : "monsters have") + " escaped.", bc_map;
|
||||
if ('mob_escaped == 20)
|
||||
donpcevent instance_npcname("#wave_mode_sky_out") + "::OnFail";
|
||||
end;
|
||||
}
|
||||
|
||||
|
||||
1@def02,1,1,0 script #wave_mode_sky_out -1,{
|
||||
end;
|
||||
OnFail:
|
||||
// monsters timers continue
|
||||
donpcevent instance_npcname("#wave_mode_sky_system") + "::OnStop";
|
||||
|
||||
mapannounce 'map_def02$, "You have failed the <Wave mode - Sky> challenge.", bc_map;
|
||||
'status_instance = 2;
|
||||
enablenpc instance_npcname("#wave_mode_sky_entrance");
|
||||
initnpctimer;
|
||||
end;
|
||||
OnTimer1000:
|
||||
mapannounce 'map_def02$, "<Wave mode - Sky> service has closed. You will be returned to the place you entered if you use the warp at the entrance.", bc_map;
|
||||
end;
|
||||
OnTimer30000:
|
||||
stopnpctimer;
|
||||
instance_destroy();
|
||||
end;
|
||||
|
||||
OnInstanceInit:
|
||||
deletearray 'treasure_gid[0], 'treasure_num;
|
||||
'wave_num = 'treasure_num = 'status_instance = 'mob_escaped = 0;
|
||||
|
||||
'map_def02$ = instance_mapname("1@def02");
|
||||
|
||||
'npc_name_mob$ = instance_npcname("#wave_mode_sky_mob_spawn");
|
||||
'npc_name_treasure$ = instance_npcname("#wave_mode_sky_treasure");
|
||||
'npc_name_mercenary$ = instance_npcname("#wave_mode_sky_mercenary");
|
||||
|
||||
disablenpc instance_npcname("#wave_mode_sky_out");
|
||||
|
||||
setarray 'x_mob[0], 48, 38, 30, 30, 29, 38, 47, 51, 50, 42, 33, 29;
|
||||
setarray 'y_mob[0], 67, 67, 64, 58, 52, 52, 51, 45, 36, 36, 36, 35;
|
||||
|
||||
setarray 'x_merc[0], 29, 33, 42, 50, 51, 47, 38, 29, 30, 30, 38, 47;
|
||||
setarray 'y_merc[0], 35, 36, 36, 36, 45, 51, 52, 52, 58, 64, 67, 67;
|
||||
|
||||
'size_coord = getarraysize('x_mob);
|
||||
for ( .@i = 0; .@i < 'size_coord -1; .@i++ ) {
|
||||
.@dist_mob[.@i+1] = distance( 'x_mob[.@i], 'y_mob[.@i], 'x_mob[.@i+1], 'y_mob[.@i+1] );
|
||||
.@total_mob += .@dist_mob[.@i+1];
|
||||
.@dist_merc[.@i+1] = distance( 'x_merc[.@i], 'y_merc[.@i], 'x_merc[.@i+1], 'y_merc[.@i+1] );
|
||||
.@total_merc += .@dist_merc[.@i+1];
|
||||
}
|
||||
for ( .@i = 0; .@i < 'size_coord -1; .@i++ ) {
|
||||
'dist_spot_AZ[.@i] = .@total_mob - .@dist_mob[.@i];
|
||||
'dist_spot_ZA[.@i] = .@total_merc - .@dist_merc[.@i];
|
||||
}
|
||||
end;
|
||||
}
|
@ -25,9 +25,9 @@
|
||||
2@gl_k mapflag restricted 6
|
||||
|
||||
// Wave Mode Memorial Dungeon ====
|
||||
1@def01 mapflag restricted 6
|
||||
1@def02 mapflag restricted 6
|
||||
1@def03 mapflag restricted 6
|
||||
1@def01 mapflag restricted 9
|
||||
1@def02 mapflag restricted 9
|
||||
1@def03 mapflag restricted 9
|
||||
|
||||
// Heroes' Trail - Part 1 ========
|
||||
1@face mapflag restricted 6
|
||||
|
@ -87,7 +87,7 @@ npc: npc/re/instances/RoomOfConsciousness.txt
|
||||
npc: npc/re/instances/SarahAndFenrir.txt
|
||||
npc: npc/re/instances/SaraMemory.txt
|
||||
npc: npc/re/instances/SkyFortress.txt
|
||||
|
||||
//npc: npc/re/instances/WaveMode.txt
|
||||
npc: npc/re/instances/WernerLaboratoryCentralRoom.txt
|
||||
npc: npc/re/instances/WolfchevLaboratory.txt
|
||||
//npc: npc/custom/official/GeffenMagicTournament.txt
|
||||
|
@ -8424,9 +8424,9 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
|
||||
{ //Normal mobs
|
||||
if(
|
||||
( target->type == BL_MOB && t_bl->type == BL_PC && ( ((TBL_MOB*)target)->special_state.ai != AI_ZANZOU && ((TBL_MOB*)target)->special_state.ai != AI_ATTACK ) ) ||
|
||||
( t_bl->type == BL_MOB && !((TBL_MOB*)t_bl)->special_state.ai )
|
||||
( t_bl->type == BL_MOB && (((TBL_MOB*)t_bl)->special_state.ai == AI_NONE || ((TBL_MOB*)t_bl)->special_state.ai == AI_WAVEMODE ))
|
||||
)
|
||||
state |= BCT_PARTY; //Normal mobs with no ai are friends.
|
||||
state |= BCT_PARTY; //Normal mobs with no ai or with AI_WAVEMODE are friends.
|
||||
else
|
||||
state |= BCT_ENEMY; //However, all else are enemies.
|
||||
}
|
||||
|
@ -381,6 +381,7 @@ enum mob_ai {
|
||||
AI_LEGION,
|
||||
AI_FAW,
|
||||
AI_GUILD,
|
||||
AI_WAVEMODE,
|
||||
AI_MAX
|
||||
};
|
||||
|
||||
|
@ -1516,6 +1516,10 @@ int mob_unlocktarget(struct mob_data *md, t_tick tick)
|
||||
//Because it is not unset when the mob finishes walking.
|
||||
md->state.skillstate = MSS_IDLE;
|
||||
case MSS_IDLE:
|
||||
if( md->ud.walktimer == INVALID_TIMER && md->idle_event[0] && npc_event_do_id( md->idle_event, md->bl.id ) > 0 ){
|
||||
md->idle_event[0] = 0;
|
||||
break;
|
||||
}
|
||||
// Idle skill.
|
||||
if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL) && mobskill_use(md, tick, -1))
|
||||
break;
|
||||
@ -1543,7 +1547,8 @@ int mob_unlocktarget(struct mob_data *md, t_tick tick)
|
||||
md->ud.target_to = 0;
|
||||
unit_set_target(&md->ud, 0);
|
||||
}
|
||||
if (battle_config.official_cell_stack_limit > 0
|
||||
|
||||
if (!md->ud.state.ignore_cell_stack_limit && battle_config.official_cell_stack_limit > 0
|
||||
&& (md->min_chase == md->db->range3 || battle_config.mob_ai & 0x8)
|
||||
&& map_count_oncell(md->bl.m, md->bl.x, md->bl.y, BL_CHAR | BL_NPC, 1) > battle_config.official_cell_stack_limit) {
|
||||
unit_walktoxy(&md->bl, md->bl.x, md->bl.y, 8);
|
||||
@ -2045,6 +2050,15 @@ static int mob_ai_sub_lazy(struct mob_data *md, va_list args)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (md->ud.walktimer == INVALID_TIMER) {
|
||||
// Because it is not unset when the mob finishes walking.
|
||||
md->state.skillstate = MSS_IDLE;
|
||||
if (md->idle_event[0] && npc_event_do_id( md->idle_event, md->bl.id ) > 0) {
|
||||
md->idle_event[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if( DIFF_TICK(md->next_walktime,tick) < 0 && status_has_mode(&md->status,MD_CANMOVE) && unit_can_move(&md->bl) )
|
||||
{
|
||||
// Move probability for mobs away from players
|
||||
@ -2056,9 +2070,6 @@ static int mob_ai_sub_lazy(struct mob_data *md, va_list args)
|
||||
}
|
||||
else if( md->ud.walktimer == INVALID_TIMER )
|
||||
{
|
||||
//Because it is not unset when the mob finishes walking.
|
||||
md->state.skillstate = MSS_IDLE;
|
||||
|
||||
// Probability for mobs far from players from doing their IDLE skill.
|
||||
// In Aegis, this is 100% for mobs that have been activated by players and none otherwise.
|
||||
if( mob_is_spotted(md) &&
|
||||
@ -3657,6 +3668,24 @@ struct mob_data *mob_getfriendstatus(struct mob_data *md,int cond1,int cond2)
|
||||
return fr;
|
||||
}
|
||||
|
||||
// Display message from mob_chat_db.yml
|
||||
bool mob_chat_display_message(mob_data &md, uint16 msg_id) {
|
||||
std::shared_ptr<s_mob_chat> mc = mob_chat_db.find(msg_id);
|
||||
|
||||
if (mc != nullptr) {
|
||||
std::string name = md.name, output;
|
||||
std::size_t unique = name.find("#");
|
||||
|
||||
if (unique != std::string::npos)
|
||||
name = name.substr(0, unique); // discard extra name identifier if present [Daegaladh]
|
||||
output = name + " : " + mc->msg;
|
||||
|
||||
clif_messagecolor(&md.bl, mc->color, output.c_str(), true, AREA_CHAT_WOC);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Skill use judging
|
||||
*------------------------------------------*/
|
||||
@ -3856,18 +3885,7 @@ int mobskill_use(struct mob_data *md, t_tick tick, int event)
|
||||
}
|
||||
//Skill used. Post-setups...
|
||||
if ( ms[i]->msg_id ){ //Display color message [SnakeDrak]
|
||||
std::shared_ptr<s_mob_chat> mc = mob_chat_db.find(ms[i]->msg_id);
|
||||
|
||||
if (mc) {
|
||||
std::string name = md->name, output;
|
||||
std::size_t unique = name.find("#");
|
||||
|
||||
if (unique != std::string::npos)
|
||||
name = name.substr(0, unique); // discard extra name identifier if present [Daegaladh]
|
||||
output = name + " : " + mc->msg;
|
||||
|
||||
clif_messagecolor(&md->bl, mc->color, output.c_str(), true, AREA_CHAT_WOC);
|
||||
}
|
||||
mob_chat_display_message(*md, ms[i]->msg_id);
|
||||
}
|
||||
if(!(battle_config.mob_ai&0x200)) { //pass on delay to same skill.
|
||||
for (j = 0; j < ms.size(); j++)
|
||||
@ -4446,7 +4464,7 @@ uint64 MobDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
mob->status.rhw.atk2 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (this->nodeExists(node, "Defense")) {
|
||||
uint16 def;
|
||||
|
||||
@ -4463,7 +4481,7 @@ uint64 MobDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
if (!exists)
|
||||
mob->status.def = 0;
|
||||
}
|
||||
|
||||
|
||||
if (this->nodeExists(node, "MagicDefense")) {
|
||||
uint16 def;
|
||||
|
||||
@ -4480,7 +4498,7 @@ uint64 MobDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
if (!exists)
|
||||
mob->status.mdef = 0;
|
||||
}
|
||||
|
||||
|
||||
if (this->nodeExists(node, "Str")) {
|
||||
uint16 stat;
|
||||
|
||||
@ -4552,7 +4570,7 @@ uint64 MobDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
if (!exists)
|
||||
mob->status.luk = 1;
|
||||
}
|
||||
|
||||
|
||||
if (this->nodeExists(node, "AttackRange")) {
|
||||
uint16 range;
|
||||
|
||||
|
@ -333,6 +333,7 @@ struct mob_data {
|
||||
int8 skill_idx; // Index of last used skill from db->skill[]
|
||||
t_tick skilldelay[MAX_MOBSKILL];
|
||||
char npc_event[EVENT_NAME_LENGTH];
|
||||
char idle_event[EVENT_NAME_LENGTH];
|
||||
/**
|
||||
* Did this monster summon something?
|
||||
* Used to flag summon deletions, saves a worth amount of memory
|
||||
@ -487,6 +488,7 @@ int mob_class_change(struct mob_data *md,int mob_id);
|
||||
int mob_warpslave(struct block_list *bl, int range);
|
||||
int mob_linksearch(struct block_list *bl,va_list ap);
|
||||
|
||||
bool mob_chat_display_message (mob_data &md, uint16 msg_id);
|
||||
int mobskill_use(struct mob_data *md,t_tick tick,int event);
|
||||
int mobskill_event(struct mob_data *md,struct block_list *src,t_tick tick, int flag);
|
||||
int mob_summonslave(struct mob_data *md2,int *value,int amount,uint16 skill_id);
|
||||
|
@ -18157,6 +18157,7 @@ BUILDIN_FUNC(getunitdata)
|
||||
getunitdata_sub(UMOB_ROBE, md->vd->robe);
|
||||
getunitdata_sub(UMOB_BODY2, md->vd->body_style);
|
||||
getunitdata_sub(UMOB_GROUP_ID, md->ud.group_id);
|
||||
getunitdata_sub(UMOB_IGNORE_CELL_STACK_LIMIT, md->ud.state.ignore_cell_stack_limit);
|
||||
break;
|
||||
|
||||
case BL_HOM:
|
||||
@ -18561,6 +18562,7 @@ BUILDIN_FUNC(setunitdata)
|
||||
case UMOB_ROBE: clif_changelook(bl, LOOK_ROBE, (unsigned short)value); break;
|
||||
case UMOB_BODY2: clif_changelook(bl, LOOK_BODY2, (unsigned short)value); break;
|
||||
case UMOB_GROUP_ID: md->ud.group_id = value; unit_refresh(bl); break;
|
||||
case UMOB_IGNORE_CELL_STACK_LIMIT: md->ud.state.ignore_cell_stack_limit = value > 0; break;
|
||||
default:
|
||||
ShowError("buildin_setunitdata: Unknown data identifier %d for BL_MOB.\n", type);
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
@ -19284,8 +19286,8 @@ BUILDIN_FUNC(unitemote)
|
||||
|
||||
/// Makes the unit cast the skill on the target or self if no target is specified.
|
||||
///
|
||||
/// unitskilluseid <unit_id>,<skill_id>,<skill_lv>{,<target_id>,<casttime>};
|
||||
/// unitskilluseid <unit_id>,"<skill name>",<skill_lv>{,<target_id>,<casttime>};
|
||||
/// unitskilluseid <unit_id>,<skill_id>,<skill_lv>{,<target_id>,<casttime>,<cancel>,<Line_ID>};
|
||||
/// unitskilluseid <unit_id>,"<skill name>",<skill_lv>{,<target_id>,<casttime>,<cancel>,<Line_ID>};
|
||||
BUILDIN_FUNC(unitskilluseid)
|
||||
{
|
||||
int unit_id, target_id, casttime;
|
||||
@ -19311,15 +19313,26 @@ BUILDIN_FUNC(unitskilluseid)
|
||||
skill_lv = script_getnum(st,4);
|
||||
target_id = ( script_hasdata(st,5) ? script_getnum(st,5) : unit_id );
|
||||
casttime = ( script_hasdata(st,6) ? script_getnum(st,6) : 0 );
|
||||
|
||||
bool cancel = ( script_hasdata(st,7) ? script_getnum(st,7) > 0 : skill_get_castcancel(skill_id) );
|
||||
int msg_id = (script_hasdata(st, 8) ? script_getnum(st, 8) : 0);
|
||||
|
||||
if(script_rid2bl(2,bl)){
|
||||
if (msg_id > 0) {
|
||||
if (bl->type != BL_MOB) {
|
||||
ShowError("buildin_unitskilluseid: Msg can only be used for monster.\n");
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
TBL_MOB* md = map_id2md(bl->id);
|
||||
if (md)
|
||||
mob_chat_display_message(*md, static_cast<uint16>(msg_id));
|
||||
}
|
||||
if (bl->type == BL_NPC) {
|
||||
if (!((TBL_NPC*)bl)->status.hp)
|
||||
status_calc_npc(((TBL_NPC*)bl), SCO_FIRST);
|
||||
else
|
||||
status_calc_npc(((TBL_NPC*)bl), SCO_NONE);
|
||||
}
|
||||
unit_skilluse_id2(bl, target_id, skill_id, skill_lv, (casttime * 1000) + skill_castfix(bl, skill_id, skill_lv), skill_get_castcancel(skill_id));
|
||||
unit_skilluse_id2(bl, target_id, skill_id, skill_lv, (casttime * 1000) + skill_castfix(bl, skill_id, skill_lv), cancel);
|
||||
}
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
@ -19327,8 +19340,8 @@ BUILDIN_FUNC(unitskilluseid)
|
||||
|
||||
/// Makes the unit cast the skill on the target position.
|
||||
///
|
||||
/// unitskillusepos <unit_id>,<skill_id>,<skill_lv>,<target_x>,<target_y>{,<casttime>};
|
||||
/// unitskillusepos <unit_id>,"<skill name>",<skill_lv>,<target_x>,<target_y>{,<casttime>};
|
||||
/// unitskillusepos <unit_id>,<skill_id>,<skill_lv>,<target_x>,<target_y>{,<casttime>,<cancel>,<Line_ID>};
|
||||
/// unitskillusepos <unit_id>,"<skill name>",<skill_lv>,<target_x>,<target_y>{,<casttime>,<cancel>,<Line_ID>};
|
||||
BUILDIN_FUNC(unitskillusepos)
|
||||
{
|
||||
int skill_x, skill_y, casttime;
|
||||
@ -19354,15 +19367,26 @@ BUILDIN_FUNC(unitskillusepos)
|
||||
skill_x = script_getnum(st,5);
|
||||
skill_y = script_getnum(st,6);
|
||||
casttime = ( script_hasdata(st,7) ? script_getnum(st,7) : 0 );
|
||||
bool cancel = ( script_hasdata(st,8) ? script_getnum(st,8) > 0 : skill_get_castcancel(skill_id) );
|
||||
int msg_id = (script_hasdata(st, 9) ? script_getnum(st, 9) : 0);
|
||||
|
||||
if(script_rid2bl(2,bl)){
|
||||
if (msg_id > 0) {
|
||||
if (bl->type != BL_MOB) {
|
||||
ShowError("buildin_unitskilluseid: Msg can only be used for monster.\n");
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
TBL_MOB* md = map_id2md(bl->id);
|
||||
if (md)
|
||||
mob_chat_display_message(*md, static_cast<uint16>(msg_id));
|
||||
}
|
||||
if (bl->type == BL_NPC) {
|
||||
if (!((TBL_NPC*)bl)->status.hp)
|
||||
status_calc_npc(((TBL_NPC*)bl), SCO_FIRST);
|
||||
else
|
||||
status_calc_npc(((TBL_NPC*)bl), SCO_NONE);
|
||||
}
|
||||
unit_skilluse_pos2(bl, skill_x, skill_y, skill_id, skill_lv, (casttime * 1000) + skill_castfix(bl, skill_id, skill_lv), skill_get_castcancel(skill_id));
|
||||
unit_skilluse_pos2(bl, skill_x, skill_y, skill_id, skill_lv, (casttime * 1000) + skill_castfix(bl, skill_id, skill_lv), cancel);
|
||||
}
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
@ -25256,6 +25280,33 @@ BUILDIN_FUNC(getenchantgrade){
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* mob_setidleevent( <monster game ID>, "<event label>" )
|
||||
*------------------------------------------*/
|
||||
BUILDIN_FUNC(mob_setidleevent){
|
||||
struct block_list* bl;
|
||||
|
||||
if( !script_rid2bl( 2, bl ) ){
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
if( bl->type != BL_MOB ){
|
||||
ShowError( "buildin_mob_setidleevent: the target GID was not a monster.\n" );
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
}
|
||||
|
||||
struct mob_data* md = (struct mob_data*)bl;
|
||||
if (md == nullptr)
|
||||
return SCRIPT_CMD_FAILURE;
|
||||
|
||||
const char* idle_event = script_getstr( st, 3 );
|
||||
|
||||
check_event( st, idle_event );
|
||||
safestrncpy( md->idle_event, idle_event, EVENT_NAME_LENGTH );
|
||||
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#include "../custom/script.inc"
|
||||
|
||||
// declarations that were supposed to be exported from npc_chat.cpp
|
||||
@ -25709,8 +25760,8 @@ struct script_function buildin_func[] = {
|
||||
BUILDIN_DEF(unitstopwalk,"i?"),
|
||||
BUILDIN_DEF(unittalk,"is?"),
|
||||
BUILDIN_DEF_DEPRECATED(unitemote,"ii","20170811"),
|
||||
BUILDIN_DEF(unitskilluseid,"ivi??"), // originally by Qamera [Celest]
|
||||
BUILDIN_DEF(unitskillusepos,"iviii?"), // [Celest]
|
||||
BUILDIN_DEF(unitskilluseid,"ivi????"), // originally by Qamera [Celest]
|
||||
BUILDIN_DEF(unitskillusepos,"iviii???"), // [Celest]
|
||||
// <--- [zBuffer] List of unit control commands
|
||||
BUILDIN_DEF(sleep,"i"),
|
||||
BUILDIN_DEF(sleep2,"i"),
|
||||
@ -25950,6 +26001,7 @@ struct script_function buildin_func[] = {
|
||||
|
||||
BUILDIN_DEF(getenchantgrade, ""),
|
||||
|
||||
BUILDIN_DEF(mob_setidleevent, "is"),
|
||||
#include "../custom/script_def.inc"
|
||||
|
||||
{NULL,NULL,NULL},
|
||||
|
@ -480,6 +480,7 @@ enum unitdata_mobtypes {
|
||||
UMOB_ROBE,
|
||||
UMOB_BODY2,
|
||||
UMOB_GROUP_ID,
|
||||
UMOB_IGNORE_CELL_STACK_LIMIT,
|
||||
};
|
||||
|
||||
enum unitdata_homuntypes {
|
||||
|
@ -3847,6 +3847,7 @@
|
||||
export_constant(AI_LEGION);
|
||||
export_constant(AI_FAW);
|
||||
export_constant(AI_GUILD);
|
||||
export_constant(AI_WAVEMODE);
|
||||
|
||||
/* battle flags */
|
||||
export_constant(BF_NONE);
|
||||
@ -4380,6 +4381,7 @@
|
||||
export_constant(UMOB_ROBE);
|
||||
export_constant(UMOB_BODY2);
|
||||
export_constant(UMOB_GROUP_ID);
|
||||
export_constant(UMOB_IGNORE_CELL_STACK_LIMIT);
|
||||
|
||||
/* unit control - homunculus */
|
||||
export_constant(UHOM_SIZE);
|
||||
|
@ -628,7 +628,8 @@ static TIMER_FUNC(unit_walktoxy_timer)
|
||||
ud->to_x = bl->x;
|
||||
ud->to_y = bl->y;
|
||||
|
||||
if(battle_config.official_cell_stack_limit > 0
|
||||
if (!ud->state.ignore_cell_stack_limit
|
||||
&& battle_config.official_cell_stack_limit > 0
|
||||
&& map_count_oncell(bl->m, x, y, BL_CHAR|BL_NPC, 1) > battle_config.official_cell_stack_limit) {
|
||||
//Walked on occupied cell, call unit_walktoxy again
|
||||
if(ud->steptimer != INVALID_TIMER) {
|
||||
|
@ -57,6 +57,7 @@ struct unit_data {
|
||||
unsigned walk_script : 1;
|
||||
unsigned blockedmove : 1;
|
||||
unsigned blockedskill : 1;
|
||||
unsigned ignore_cell_stack_limit : 1;
|
||||
} state;
|
||||
char walk_done_event[EVENT_NAME_LENGTH];
|
||||
char title[NAME_LENGTH];
|
||||
|
Loading…
x
Reference in New Issue
Block a user