Use non-blocking stream API here and everywhere. ⋯
|
|||
usleep(1000 * mt_rand(100000, 100000)); ⋯
|
|||
fwrite() may not be able to write the entire buffer and may return number lower than its length (verified to happen on Windows when fwrite() buffer is longer than 65536 bytes). This likely needs to be fixed but to do so we need to add buffers and retransmissions across a lot of places, as well as figure if fwrite() of 0 means an error or not (a comment in PHP docs suggests that 0, not false is returned on any problem with the stream). See HeroWO's api.php's WatchdogSseClient for what it may look like. ⋯
|
|||
Consider common ancestor for Plugins/Extensions/Protocols. ⋯
|
|||
function suggestParams() { ⋯
|
|||
If an unknown opcode is received, the receiving endpoint MUST _Fail the WebSocket Connection_. ⋯
|
|||
Must include the relevant HTTP code instead of 204 because: "Servers should use a 5xx status code to indicate capacity problems, as this will prevent conforming clients from reconnecting automatically." https://www.w3.org/TR/eventsource/#iana-considerations ⋯
|
|||
Check if this is implemented: "If the data buffer's last character is a U+000A LINE FEED (LF) character, then remove the last character from the data buffer." ⋯
|
|||
Looks like $handle context must be changed to supply cert path, etc. in 'ssl' group. See comments on the stream_socket_enable_crypto()'s help page. "If this fails (e.g., the client indicated a host name in the extended client hello "server_name" extension that the server does not host), then close the connection [...]" ⋯
|
|||
PHP ignores multiple headers, only keeping last as 'HTTP_' in $_SERVER. This can create problems because WebSocket spec explicitly allows some headers to duplicate (like Sec-WebSocket-Protocols). HTTP spec specifies that headers that are comma-separated list of values can be merged into one header without side effects, but PHP doesn't do that, dropping all values but last header's. See Section 9.1 (page 49). ¶
|
|||
Also test fractional timeout. ⋯
|
|||
Test class constants (e.g. Status::SWITCHING). ¶
|
|||
Ensure all accessors are defined for public properties in BaseTun, etc. ¶
|
|||
Ensure all events are listed in Plugin. ¶
|
|||
HeroWO is a work in progress and includes hundreds of small and large to-do tasks (`XXX`). These are embedded directly in code to make them versioned, easy to modify en masse and tightly bound to their context. **noXXXep** is what [presents them nicely](https://herowo.io/noXXXep/). ¶
|
|||
RH |
$SAVE_VERSION = 1; // XXX ¶
|
||
RH |
$REPLAY_VERSION = 1; // XXX ¶
|
||
R |
replace with picker()/at() of _/Sqimitive? ⋯
|
||
O |
Optimization idea: store a compiled test closure within Effect that does all the tests and returns a result indicating if the Effect matches current Calculator options or not. Or implement calculation in webasm. ¶
|
||
There is currently no way to signal recalculation if whatever data test() depends on has changed. ⋯
|
|||
Detect circular dependency between sub-mcalc'ulators (e.g. when calculating creature_damageMin/Max - first has a modifier [custom, rules, damageMax] while second has [..., damageMin] so they continue to create calculators infinitely (if using oneShotEffectCalculator()). ⋯
|
|||
#rm |
the same applies pretty much to every other calculator user (in Bits, etc.); need to review and add cascade remove where needed (some places like updateOn() already do it properly) ⋯
|
||
// This optimization is disabled because it seems to slow down map loading by ~15%. XXX ¶
|
|||
case this._constants.operation.spellSpec: // XXX H3 subsystem ¶
|
|||
RH |
var obj = this.map._actionableAtter(id, 0, 0, 0) ⋯
|
||
party, creature cannot change? ⋯
|
|||
As explained in rm, technically we should not expect that an object explicitly specified as _opt.iCC is not present in combat - client of this calc must remove calc when iCC is removed; however, this is not properly done ATM and causes failure in walkImpassable() below (for example, try casting Armageddon - Combat.State's _calcs holds creature_flying and others with explicit iCC and are not removed at all). ⋯
|
|||
R |
rep.walkImpassable(cr, function (o) { ⋯
|
||
instanceof would be better but needs module require; add "isCreature" like in other Map classes? ⋯
|
|||
many of the above is H3 subsystem ⋯
|
|||
H3 subsystem ⋯
|
|||
B, R |
for mapMove this currently plays one tick earlier (two ticks at the beginning before DOM.Map starts animating the movement, then each tick at N-1 when Map is animating N, then completion one tick earlier while Map is still playing animation); either mapMove ticks should be adjusted (e.g. transitionFace with tick of N, subsequent coords change at N+1, then transitionFace before next move at N+1, coords at N+2, etc.) or DOM.Map should play them differently ⋯
|
||
H3-specific ⋯
|
|||
I |
should respect transition ticks, i.e. gradually open the shroud during moveHero ⋯
|
||
#mmpso | I |
partial shroud currently reveals presence of objects like border guard, hero, boat (albeit not their ownership thanks to grayscale being applied); but they can't be simply hidden (like DOM.Map does) because map.miniMap stores info about either the impassable object or the terrain so if we hide the object we don't know what type of terrain to show; MiniMapTile can be (and should be) changed to store both fields ⋯
|
|
I |
↳ if (visible >= 0 && this._fogBits) { ⋯
|
||
should not depend on H3 (Bits.Window) ¶
|
|||
// There's actually CHAT.WAV in Heroes3.snd but it's 3 times larger. There's also DEFAULT.WAV that is suspiciously similar to the real ICQ sound (but more intrusive). Replace? XXX ¶
|
|||
direct DOM access bypassing gridCellAt() ⋯
|
|||
should also re-format() Message-s ⋯
|
|||
R |
297 corresponds to the inner area of Hchat-room__msgs; it's hardcoded for now because messages may be incoming before final node dimensions are known. The general intention is to create a max-width: 100%; max-height: 10em restriction while maintaining aspect ratio (something that these combined with explicit width; height; can't do). ⋯
|
||
RH |
var players = ['', 'red', 'blue', 'tan', 'green', 'orange', 'purple', 'teal', 'pink'] ⋯
|
||
R |
copy/paste of Sqimitive.Ordered.staticProps.indexFor(); could use toString() + replace() but that won't work when minified due to name mangling ⋯
|
||
#ll | R |
Change "_.log && _.log(...)" paradigm to "_.L# && _.log(...)" where L# is a bunch of properties on _ (alike to _.debug) that toggle logging of specific channels (e.g. Map loading). This will also remove the need for oldLog() - log() will be always available. ⋯
|
|
R |
Previous rule was that Map doesn't change between first init and last render so it's possible to set up hooks in attach and iterate in render (like Bits.ObjectList does), but this is no longer correct and such old code (chiefly in DOM.Bits) should be updated. `#Module can produce "sub-modules". Each module is owned by a `#ModuleContainer (such as `#Context or `#Screen), not the module that has produced it. Children (`'nest()) of `#Module can be only other `#Module-s, not unrelated classes (such as `@DOM.Slider`@) - these must be stored in `#Module's properties, possibly in a separate `@Common.Sqimitive`@ collection. Submodules are automatically removed when `'this is removed and are removed from `'this when removed from `#ModuleContainer. However, their `'el can be attached to any point in DOM (by default it appends to `#Module's `'el). This is how submodules are usually created: ⋯
|
||
R |
var cls = calc ⋯
|
||
R |
classic: false, // XXX move to Screen? ¶
|
||
creating an instance every time calculator() is called just to normalize _opt, call key() and throw it away sounds wasteful ⋯
|
|||
temporary, until counter-based _opt.update is implemented; client may specify desired mode and shared calc will adjust its _opt.update automatically since a user of listening calc with update = false can transparently use an existing calc with update = 'defer' or true (updateIfNeeded() will be a no-op in this case), and a user of update of 'defer' can work with update of true; removing requirement that shared listening calcs must have update of true will allow better calc sharing ⋯
|
|||
move to a better place ⋯
|
|||
4 should client include actionableSpot in from when giving this arg? ⋯
|
|||
4 should pathFindFor return de-adjusted by act. spot? ⋯
|
|||
4 it seems adjusting breaks AI ⋯
|
|||
C, O |
doing this in-thread has significant impact (100s of ms) on initial Context rendering; _.defer() fixes that ⋯
|
||
this doesn't affect CreatureAnimation because it's using a timer, not CSS ⋯
|
|||
IC |
Difference: in SoD RMB info box on ADVMAP never leaves the active area of the map, i.e. never overlaps EDG, right-side panel and the bottom help bar. ⋯
|
||
I |
add list of AObject->$pending ⋯
|
||
I |
case 'hasBuilt': // XXX ¶
|
||
I |
DOM.Map draws shadows incorrectly: SoD separates shadow from picture while def2png.php combines them. If an object overlaps another, its shadow should be drawn behind the other, not on top of it like it currently happens. This won't be fixed in DOM.Map (as it will double the required number of nodes). ⋯
|
||
C |
XXX maybe add a databank property and move there ⋯
|
||
R |
// XXX XXX maybe add a databank property and move there ¶
|
||
I |
SoD does smooth scroll (not tile-by-tile) - add "mapLockMove" to Screen, set it during transition and manually animate scroll position ⋯
|
||
R |
4 duplicates with _moveOpt() ⋯
|
||
4 H3 subsystem ⋯
|
|||
I |
// This is technically incorrect but XXX transitions currently don't ¶
|
||
R |
shroud logic is H3-specific; refactor it to a subclass or, more likely, to a dynamic mixin since DOM.Map is nested by environment ⋯
|
||
I |
should respect transition ticks, i.e. gradually open the shroud during moveHero ⋯
|
||
R |
duplicates with H3.Rules ⋯
|
||
// DEF's duration is too long so take 67% of it to obtain some normalized, good for defaults duration. XXX fix def2png.php? ¶
|
|||
R |
Take Z into account on small maps only. On over/underworld switching, relying on Z causes much bigger amount of nodes to be updated, making the switch very slow. ⋯
|
||
H3 subsystem? ⋯
|
|||
IC |
wheelScroll: 1, // XXX should be disabled everywhere in classic mode ¶
|
||
We'd use CSS to specify when animations should play and when not, but this is a no goer given it may affect thousands of nodes. One way would be to iterate over visible DOM.Map object nodes and set style.animationPlayState but that breaks into DOM.Map's domain (what is "object node"? when is it "visible"?) and besides, changing style still triggers partial reflow. Recent Web Animations draft (2020) helps but getAnimation/s() methods are extremely slow if results (i.e. animated map objects) are counted in hundreds. https://drafts.csswg.org/web-animations-1/#example-e7bbf635 Update: this was a good try but it causes bizarre effects on hero animations (AH??_ objects): enable mapAnimate, then drag ADVMAP or open a dialog (these call pauseAnimations(true)), then stop/close (pauseAnimations(false)). Observe that heroes no longer reflect changes to className - they are always in idle animation group, and even disabling mapAnimate or meddling with CSS via the inspector doesn't prevent their idle animation! Update: another approach making animation-duration dependent on --var (as generated by def2png.php) works but is as slow as manipulating CSS classes. ⋯
|
|||
C, O |
doing in-thread has significant impact (100s of ms) on initial Context rendering; _.defer() would fix this ⋯
|
||
I |
proper unhooking ⋯
|
||
if old and new are in byTarget, there's no need to update anything because $target cannot change; however, this breaks Shroud.Effects because it no longer detects changes in Effects in non-bySpot mode (when global Effects exist); see the comment in _effectsChanged()'s switch; fixing it is not trivial because Shroud doesn't reconstruct old object to see if the change would be handled by _byTargetChanged(), moreover, byTarget's ochange may occur both before and after _effectsChanged() so it needs to defer the decision smartly ⋯
|
|||
I |
case 'highScores': // XXX ¶
|
||
I |
case 'newCampaign': // XXX ¶
|
||
this assumes human players are selected on game start/load and remain the same until game session ends or this page is unloaded ⋯
|
|||
#clsi | IC |
// as well. XXX When a separate _opt for simultaneous mode is created, do ¶
|
|
we are currently creating a Screen per each playable player, which is to support hot-seat, and it works but lagging due to inefficient DOM.Mini/Map implementations; for now try to reuse map instance (or at least DOM subtree) in different screens and hide all Screen-s except the one used for the first player of currently interactive-able players ⋯
|
|||
I |
//set('quickCombat', false) // XXX ¶
|
||
keystrokes must be handled by currently visible Screen only ⋯
|
|||
when running on the server (websocket server), strings will be delivered in server's language, for events generated on the server (like combat) ⋯
|
|||
//.append(HeroWO.strings) // XXX finish localization ¶
|
|||
recreate on change_team, change_controller/s ⋯
|
|||
I |
finish localization ⋯
|
||
I |
not permitted because Worker currently has no means to show GrantModules notifications; also, 3rd party modules may not expect to be run in Worker context without access to DOM ⋯
|
||
// observer may change on the server but sans admin's intervention this may only happen via do=configure by host, and that involves resetting client's connection, carrying new observer state on reconnect. Therefore not listening to change_observer. XXX ¶
|
|||
RH |
state: this.rpc._createCombatState(combat, this.player), ⋯
|
||
decision should be based on ally/enemy strength ratio ⋯
|
|||
I |
this.do('tacticsEnd') ⋯
|
||
R |
2 _controlCreature: function () { ⋯
|
||
2 This is using databank stats (rules) for speed, instead of factual combat values. Should be revised in the future, once calculators are fast enough. ⋯
|
|||
R |
duplicates with _updateAttackable; XXX slow ⋯
|
||
R |
// XXX duplicates with _updateAttackable; XXX slow ¶
|
||
RH |
return this.rpc._controlCreature(this.combat, creature) ⋯
|
||
// Logically thinking, we should also cap if cannot reach for attack (!enemy.damage) but I'm not sure how. XXX ¶
|
|||
R |
8 _castSpell: function (enemies, allCost, done) { ⋯
|
||
I |
8 check immunities when estimating targets ⋯
|
||
I |
8 currently spells are checked in fixed order; they should be examined all together, sorted and best chosen based on damage to SP ratio (e.g. if spell A deals 10 damage and costs 5 SP while B deals 15 damage and costs 10 SP then A is better because for 10 SP during 2 turns we inflict 20 damage, not 15) ⋯
|
||
this is necessary until databank access here is replaced by calculating actual values so e.g. after applying slow the target's speed will drop so much that normal speed threshold check will (?) suffice ⋯
|
|||
this is under assumption chain lightning strikes random creatures (as it currently does) ⋯
|
|||
this uses enemies order which is dependent on current creature and, for example, a less suitable enemy may be ranked top because it's within current creature's reach ⋯
|
|||
for simplicity only check casting with eye = enemy's spot; there may be more optimal cases when casting spot is shifted but they are not checked ⋯
|
|||
R |
duplicates with H3.Rules.RPC ⋯
|
||
R |
may be merged with fireball's calculations ⋯
|
||
R |
may be merged with fireball's calculations ⋯
|
||
RH |
state: this.rpc._createCombatState(combat, this.player), ⋯
|
||
clumsy, need some unification of transitions' option names ⋯
|
|||
Similarly, when changing vehicles, we should record the original vehicle type without spot since there is (usually) more than one spot to transfer between ground and water. But it seems to work fine? ⋯
|
|||
I |
currently buying the most suitable creature only; should check all other available creatures and buy multiple during one visit ⋯
|
||
use databank ⋯
|
|||
R |
_refreshHero: function (hero) { ⋯
|
||
R |
_controlTown: function (town) { ⋯
|
||
rely on building features/effects rather than hardcoded IDs ⋯
|
|||
this is trying listed buildings in sequential order and presence of a permanently unavailable/disabled building will be a roadblock ⋯
|
|||
R |
_controlHero: function (hero) { ⋯
|
||
RH |
move this and other constants to _opt ⋯
|
||
I |
12 would be good to exchange garrisons directly with heroes (heroTrade) without using town as a relay ⋯
|
||
12 this assumes garrison commands are executed in the same order as called (IdleTasks guarantees that but `#RPC doesn't) ⋯
|
|||
I |
Ideally should check aiValue and swap with town's garrison if hero's creature is stronger. ⋯
|
||
R |
This ensures combined garrisons of hero and town don't have duplicate creature IDs. It doesn't reorder creatures in any particular way so for example if hero and town had 1*C1 then town will have 0*C1, hero - 2*C1, or if only town had two slots, each 1*C1 then it will have one slot 2*C1. Reordering must be done later, once the returned async completes. ⋯
|
||
R |
Note: heroTotal, [2] is old (current) aiValue's of hero's garrison, not the value it will have after combining (this value is total, [0]). ⋯
|
||
R |
//> maxCost `- from `'spot (the town), not `'hero, measured over any terrain and thus only an estimate ⋯
|
||
// When on ship, add all terrain tiles that can be disembarked upon. In any case, add all guarded tiles - because our path finder currently doesn't allow building path to a monster through its impassable guarded area, the AI will never interact with monsters if we don't add them (XXX). ¶
|
|||
R |
Doesn't check reachability. ⋯
|
||
_triggerSpotEffects() has more complex logic determining if there will be a fight when interacting with this tile; the check below works when disembarking but on land it erroneously treats an object that causes hero to stop rather than step on its tile as guarded, such as an artifact: [M][A][H] - Monster guards Artifact but Hero can pick it without a fight ⋯
|
|||
garrison may not be initialized before encounter? ⋯
|
|||
hardcoded check for town's buildings; check the Effect target for fortifications instead ⋯
|
|||
case '_dwelling': // XXX garrison isn't initialized before encounter ¶
|
|||
I |
check if guards were already defeated, if yes then set guards=0 ⋯
|
||
R |
25 replace with ShipState? ⋯
|
||
25 check actionable spot? ⋯
|
|||
I |
tactics for distance from combat field edge (currently only implemented for distance from creature's original position) ⋯
|
||
C |
First Aid Tent's shadow is much more dark than in SoD. Check def2png.php? ¶
|
||
RH |
to databank? ⋯
|
||
add Generator constructor options to control this behaviour in detail ⋯
|
|||
RH |
artifact ID ⋯
|
||
#ddd | R |
props.width = props.width || 1 // databank defaults; XXX why do we need them? just put 1 into databank (also check other similar places) ¶
|
|
R |
↳ set to 1 explicitly ⋯
|
||
C |
review and make more in line with SoD ⋯
|
||
I |
options.formation ⋯
|
||
C |
8 currently assuming shoot penalty if distance (diagonal) is >= half of the combat field's width ⋯
|
||
I |
8 check for obstacles/fortifications along the trajectory ⋯
|
||
C |
formulae ⋯
|
||
R |
this calculator thing remains from pre-rewrite of Calc.Effect where Calc was much less flexible in terms of listen and update; it's likely that members of _calcs and calcs of attackTargets can be merged or have their options optimized (e.g. might not need to listen on WS server) ⋯
|
||
In SoD there's always exactly 2 parties so determining which party's stats affect whom is trivial. Not so in HeroWO since we allow arbitrary combat configuration. Currently we take just the first enemy's stats. ⋯
|
|||
R |
if (this.combat.tc) { // XXX duplicates in H3.Rules.RPC ¶
|
||
RH |
return this._pathFind._neighboursOf([ ⋯
|
||
B |
got stack traces telling pos is null; shouldn't happen, research and remove && when figured out ⋯
|
||
IC |
SoD plays last BGM (XXX) if there's no current object (e.g. after dismissing a hero, new object isn't automatically selected and previous sounds continue) ⋯
|
||
C |
// XXX SoD plays last BGM (XXX) if there's no current object (e.g. after dismissing a hero, new object isn't automatically selected and previous sounds continue) ¶
|
||
C |
// Rules for audibility were determined empirically. Recheck (XXX). ¶
|
||
R |
it's probably more flexible and less hardcoded to define max audible distance in AClass on the per-object basis (rationale: big loud objects are heard from afar); add a new field to map.byPassable (or create a new index) telling which sounds (or objects) are heard on a given spot, and at what volume; this will allow very far-heard objects and Audio won't need to traverse the map on every update to determine them ⋯
|
||
IC |
// We play music until switch to non-town or to another town of different type (i.e. switch from Castle to Castle doesn't restart the track). XXX implement as SoD in classic mode ¶
|
||
IC |
In SoD, if you set music volume to 0 and then to non-0, you will hear the same combat track (not new random track picked) continuing from the same position. We should maintain a per-combat resumePositions, also because our combat window can be hidden and shown at will and it's best if showing a previously viewed window resumes the track rather than starts a random one from 0. ⋯
|
||
IC |
SoD blocks any user interaction until BATTLE*.WAV is played (though I find it quite annoying). We should do this at least in classic mode. ⋯
|
||
IC |
SoD seems to start certain BGM tracks from random position. For example, town themes start from 0 (unless already started in this game) while terrain isn't resumed, as if started from random position every time instead. ⋯
|
||
R |
duplicates with H3.Rules ⋯
|
||
DEF images are large (450x400) and the game somehow decides where the center is individually (compare how it shows CPKMAN and CABEHE and you'll see that their offsets are different, as seen in creature info animation) ⋯
|
|||
R |
duplicates with H3.Rules.RPC ⋯
|
||
R |
duplicates with H3.DOM.UI ⋯
|
||
I |
4 support SoD help bar here and in all other windows/screens ⋯
|
||
R |
4 add helper methods to quickly build MessageBox'es with frequently used layouts (e.g. OK/Cancel) ⋯
|
||
6 revise margins of inline boxes; currently it depends on whitespace between them but it's not ideal and not all boxes are split by whitespace ⋯
|
|||
R |
6 uniformize all format functions to create boxes with captions (like SpellImage), not only images ⋯
|
||
#mmrl | I |
morale, luck (sign() in classic), atk/def/knw/spp ("+# Defense [Skill]"), skill ("Advanced Wisdom"), spell ⋯
|
|
↳ default: ⋯
|
|||
R |
duplicates with `{Checks`} ⋯
|
||
// as multiple images since we (SoD) lack negative images for now (XXX). ¶
|
|||
I |
that's still a problem if a party is removed mid-combat (e.g. due to fleeing); we don't have this feature yet so not addressing it Also not clearing _animateHero timers because that method is playing cheers animation in non-classic mode upon combat end. ⋯
|
||
I |
aborting doesn't work well ATM (at least on combatMove), likely due to improper handling of transitions abort ⋯
|
||
I |
2 even though mode is disabled while transitions are pending, bottom panel buttons are currently kept enabled ⋯
|
||
IC |
2 SoD also hides active outline (yellow) of current creature during animations ⋯
|
||
R |
_cast: function (book, spell) { ⋯
|
||
I |
// Barely adequate (XXX) preloading. Without this animations even with local server are horrid. ¶
|
||
R |
duplicates with CreatureInfo's ⋯
|
||
I |
show total "(hp)" of top stack in nonclassic mode ⋯
|
||
R |
clicked: function () { ⋯
|
||
IC |
// SoD displays a more detailed message: XXX ¶
|
||
IC |
// SoD displays a more detailed message: XXX ¶
|
||
IC |
SoD also has a similar off-field area for hovering of the top tower; currently we only allow hovering of it by the impassable cell it stands on (11;0) - while in SoD hovering it produces impassable cursor without targeting the tower ⋯
|
||
R |
SpellAffectorList's logic must be extracted into a H3.Rules calculator and used here ⋯
|
||
IC |
SoD employs some uncertain logic in regards to the Y coord (sometimes the box is on top of the hex cell, sometimes on the bottom) ⋯
|
||
I |
currently affectors are not updated within a transition ⋯
|
||
I |
Lower and mid-lower walls should use a kind of "inverse Z": unlike normal order, they overlay creatures standing on the right of them and underlay those on the left. This troublesome exception isn't implemented currently except for lower wall that overlays creatures both on the right (good) and left (bad). ⋯
|
||
IC |
in classic mode arrow towers should not play idle (shuffle) and on-hover animations ¶
|
||
I |
outlines of activeTurn and hover must be pulsating like in SoD ⋯
|
||
ID |
case 'combatRamHit': // XXX draw animations for this group ¶
|
||
ID |
we lack impact animations for walls so not playing them (group.hit is used for damaged wall) ⋯
|
||
B |
got stack traces with null cr; remove || ⋯
|
||
ID |
case 'combatRamMiss': // XXX draw animations for this group ¶
|
||
ID |
var sound = sound || 'XXX' ¶
|
||
RH |
sound = 'ATK2' // XXX exceptions to file names should be defined in databank, not in code ¶
|
||
I |
shooter must turn before and after shooting if target is on the left (like in combatMove) ⋯
|
||
C |
adjusting by TXT-provided X seems to cause more problems than good ⋯
|
||
I |
add shootingCloud effect at this point and wait for completion before continuing execution below (+ DEATHCLD sfx) ¶
|
||
IC |
for catapult, SoD pauses at hurling climax frame and waits until impact animation ends playing, then finishes hurling animation (we play this ending in parallel with impact) ⋯
|
||
RH |
var def = def || 'CSGRCK' // XXX ¶
|
||
RH |
var def = def || 'SGEXPL' // XXX ¶
|
||
RH |
var sound = sound || 'WALLHIT' // XXX ¶
|
||
B |
case 'combatMoraleGood': // XXX should play over creature's spot at the time of transition, not current ¶
|
||
RH |
var def = def || 'C09SPW0' // XXX ¶
|
||
RH |
var sound = sound || 'GOODMRLE' // XXX ¶
|
||
RH |
var def = def || 'C14SPE0' // XXX ¶
|
||
RH |
var sound = sound || 'BADMRLE' // XXX ¶
|
||
C |
if need to play on-hit animation for bad morale and other similar statuses ⋯
|
||
RH |
var def = def || 'C09SPA0' // XXX ¶
|
||
RH |
var sound = sound || 'GOODLUCK' // XXX ¶
|
||
RH |
var def = def || 'SP12_' // XXX ¶
|
||
RH |
var sound = sound || 'REGENER' // XXX ¶
|
||
I |
for better effect unlock/parallel should happen in impact's climax frame (some point in the middle of playing it), not immediately ⋯
|
||
R |
this is walking the entire view.path on tick 0 but more correct is to walk one step at a time at the specific tick to allow other consumers of combatMove update precisely in sync with the creature move animation; there are no such consumers currently (except mapCountImage but it's hidden until last tick) ⋯
|
||
I |
update Z index during move (not so trivial for flying) ⋯
|
||
I |
44 It appears making perfect move animation requires too much time so using quick and dirty method for now: force 70 ms per walk frame and 0.1 second per moved cell, then adjust movement speed ($.animate()) so that move animation ends on the last frame. SoD is using a more complex and fluent approach which remains to be researched. ⋯
|
||
44 Use CreatureAnimation's walkTime/attackTime to reduce animation interval used by def2png.php and remember about --HC. ⋯
|
|||
RH |
var distance = pathFind._heuristic(path[pathIndex - 1], path[pathIndex]) ⋯
|
||
I |
when a creature is hit or is dying, it should turn to face the attacker ⋯
|
||
RH |
'SP09_' ⋯
|
||
C |
// In SoD, hero cast animation pauses on the fifth (XXX) frame and waits until other cast animations finish. ¶
|
||
R |
partially duplicates with _playTransitionCreatureOverlay() ⋯
|
||
RH |
var ai = !angle ? 1 : angle <= 27 ? 2 : angle <= 45 ? 3 : angle <= 72 ? 4 : 5 ⋯
|
||
I |
duration depends on pixels, not the best concept for portability ⋯
|
||
R |
partially duplicates with _playTransitionCreatureOverlay ⋯
|
||
RH |
bottom: 560, // XXX ¶
|
||
R |
Duplicates with cast_missileEvery(). ⋯
|
||
B |
user clicked before Map has reacted to mousemove and updated mouseCell which is a problem because it means mouseSide (any others) that we need here are out of date; need to figure why there is a delay ⋯
|
||
IC |
SoD shows creature info at a fixed position outside of combat but (unlike us) inside of combat it shows info near the creature ⋯
|
||
IC |
SoD draws on-hover outline for creatures of different damageGroup (e.g. if currently active creature is Griffin, hover of Catapult is outlined in SoD but not in HeroWO; same if active is Catapult and hovered is Griffin) ⋯
|
||
RH |
if (pos[0] == 12 && pos[1] == 10) { // XXX ¶
|
||
R |
'=_updateCursor': function (sup) { ⋯
|
||
RH |
if (cur[0] == 9 && cur[1] == 5) { // XXX ¶
|
||
RH |
} else if (walls.length && ((cur[0] == 10 && cur[1] == 5) || (cur[0] == 12 && cur[1] == 10)) && this.cmap._opt.mouseSide == 'bl') { // XXX ¶
|
||
O |
// Try from all spots around the enemy (slow). XXX ¶
|
||
I |
also highlight cells under creatures that can be healed (in non-classic mode) ⋯
|
||
RH |
switch (cr.get('special')) { // XXX ¶
|
||
IC |
condition: if classic && targeting 1 cell ⋯
|
||
IC |
currently HeroWO always keeps active turn's outline even for area spells (Fireball) ⋯
|
||
O |
var source = this.cx.map.effects.propertyIndex('source') ⋯
|
||
IC |
if there is a log entry from previous turn and _lastNew's height is 1, last line of that entry is displayed; need to add padding --------------------------------------- | "Some entry from the previous turn" | << this should not be visible | "Next round begins." | --------------------------------------- --------------------------------------- | "Next round begins." | << should look like this | | --------------------------------------- ⋯
|
||
R |
attach: function () { ⋯
|
||
#ccrx | B |
got many stack traces pointing out that cr is null; not sure how that's possible that no this.get('objects') had any matching obj.party == first ⋯
|
|
R |
audio may technically change so must update hooks when it happens ⋯
|
||
I |
if not supported, must additionally reset Screen's speed options to 1.0 on start; while implementing, remember they're not supported in FF <57, not just in IE ⋯
|
||
I |
implement quick combat/auto combat and enable all Auto-Combat Options checkboxes ⋯
|
||
C |
numbers determined arbitrarily ⋯
|
||
B |
79 must hide duplicate spells ⋯
|
||
IC |
79 in combat, if hero has spells (set in editor) but no spell book (no artifact), SoD disables the button in the bottom panel but allows clicking on the hero image in the corner to open the book, and upon selecting a spell there it says "%s recites the incantations but they seem to have no effect." XXX also check if this spends SP or not ⋯
|
||
C |
// XXX in combat, if hero has spells (set in editor) but no spell book (no artifact), SoD disables the button in the bottom panel but allows clicking on the hero image in the corner to open the book, and upon selecting a spell there it says "%s recites the incantations but they seem to have no effect." XXX also check if this spends SP or not ¶
|
||
I |
add efficiency explanation ("Does X points of damage", "Chances of success are X%", etc.) ⋯
|
||
IC |
don't show in wrong context (combat spell on advmap, etc.); SoD shows spell info in this case ⋯
|
||
B |
as with other CSS animations based on APNG, Chrome behaves strangely: it seems to "play" APNG in background even after the animation ends, so that when the animation is restarted, it "continues" playing APNG instead of playing it from the first frame. likely need to ditch APNG and use CSS animations like doing with DEF animations - possibly putting them to the same animations.css in the databank ⋯
|
||
got many stack traces telling SpellBook is trying to show a spell with false schools (i.e. special/of creatures); this isn't supposed to happen and unsure how to properly handle that; for now just putting ||[] ⋯
|
|||
I |
when replay playback is implemented, replace the useless Load > Tutorial button with load replay button ⋯
|
||
C, I |
recheck this and other game screens (ADVMAP, SpellBook, Combat, etc.), add missing hotkeys ⋯
|
||
R |
use H3.DOM.Audio ⋯
|
||
I |
playback of replays ⋯
|
||
showPicker() often fails with "blocked due to lack of user activation" or "requires a user gesture" for unknown reason. ⋯
|
|||
R |
duplicates with _uploadSaved() ⋯
|
||
I |
not implemented because decompression API is recent (Chrome 80+, no FF) and its compatibility with gzencode() is unknown ⋯
|
||
R |
// May be improved in the future (XXX). ¶
|
||
RH |
var REPLAY_VERSION = 1 // XXX ¶
|
||
IC |
some of these texts are different in Main Menu and in scenario info window (in-game); for example, 'oc' says: 'Accumulate %d %s in your kingdom's armies.' ⋯
|
||
I |
storing binary stuff in localStorage is inefficient, IndexedDB is much better and has no quota but the API is troublous ⋯
|
||
RH |
case 7: // XXX 7 ¶
|
||
RH |
var msg = _.format(this.cx.s('map', '%s, you only have %d days left to capture a town or you will be banished from this land.'), this.rules.databank.players.atCoords(this.pl.get('player'), 0, 0, 'name', 0), 7 - now) // XXX ¶
|
||
IC |
ARRAYTXT.TXT has a message where there are 2 entries for "growth" and the last line says "...increase IN population." (can be seen after building Grail in Inferno) ⋯
|
||
I |
upon monster encounter, replace its image with AVWATTAK.DEF until the combat ends (or possibly replace the image during any active $pending on the monster's AObject) ⋯
|
||
IC |
SoD plays this sound N times where N = number of defeated parties (max 2 in SoD). ⋯
|
||
IC |
SoD seems to select 2nd (random?) town if had a single hero that was selected and now is gone ⋯
|
||
C |
do we need to scroll immediately or wait (like until uiAudio ends?)? ⋯
|
||
C |
ensure message text and display of player flag shown in different cases by HeroWO and SoD match ¶
|
||
#wmn | IC |
SoD message includes the hero's/town's name but it may be removed by now and we can't calculate it ⋯
|
|
IC |
↳ msg.push(me ? 'You have captured the designated town, and claim victory!' ⋯
|
||
IC |
↳ msg.push(me ? 'The hero under your protection has suffered defeat.' ⋯
|
||
IC |
↳ msg.push(me ? 'The principal town has fallen.' ⋯
|
||
RH |
7 hardcoded; to databank? ⋯
|
||
make transition? window will overlap if an event occurs in background, or another player's won changes ⋯
|
|||
RH |
var el = box._inlineBox().appendTo(box.el) // XXX ¶
|
||
I |
15 there is currently no way to either cancel message on timeout or bring it up again for user to act (think of event log from AoW), which is a problem if user reloads the page (transitions added before the reload will be dropped, not reprocessed); for now, prefixing most channels here with '!' to ensure cleanup actions are always run (even if after some time, such as when user is in a combat) except if user reloads the page ⋯
|
||
#trsr | I |
15 when saving a game, pending transitions are also saved; they must be picked up when loading and either resumed (if possible) or deleted (if can't resume without data lost at the collect step that happened before load); perhaps add a "resume_..." that fulfills the role of select_... and collect_... for such transitions ⋯
|
|
#huic | I |
these require confirmation to close and confirmation is only possible to non-observer because it involves calling an RPC command; ideally observer should see choices the main player is making by means of a system similar to Tracker ⋯
|
|
I |
↳ if (this.sc.rpc.get('observer')) { return } ⋯
|
||
I |
↳ if (this.sc.rpc.get('observer')) { return } ⋯
|
||
I |
↳ if (this.sc.rpc.get('observer')) { return } ⋯
|
||
I |
↳ if (this.sc.rpc.get('observer')) { return } ⋯
|
||
R |
defining strings in code isn't ideal but quest_choices messages can't be part of effects since they often need custom MessageBox set up ⋯
|
||
RH |
while (slot < 7 && slot < sub.size().x && sub.anyAtCoords(slot, 0, 0, 0) && sub.atCoords(slot, 0, 0, 'creature', 0) != this.creature()) { ⋯
|
||
I |
SoD also allows building ships on owned shipyard by merely clicking on it rather than encountering ⋯
|
||
RH |
var el = box._inlineBox().appendTo(box.el) // XXX ¶
|
||
RH |
var el = box._inlineBox().appendTo(box.el) // XXX ¶
|
||
IC |
SoD uses currently selected hero's garrisonSee ability while we use combined of all heroes including allies (XXX do allies in SoD provide garrisonSee?) ⋯
|
||
C |
// XXX SoD uses currently selected hero's garrisonSee ability while we use combined of all heroes including allies (XXX do allies in SoD provide garrisonSee?) ¶
|
||
RH |
// Determined empirically. XXX to databank? ¶
|
||
I |
add aggression info (likely to join, pay so much gold) ⋯
|
||
C |
at least with garrison, rogue's spying seems to take effect not only if it's close to the garrison's actionable spot but also to any of its impassable spots: [ ][#] [ ][@] @ = Garrison [ ][#] [H][ ] H = hero with Rogue ⋯
|
||
I |
this check is not accurate as certain objects (e.g. Warrior's Tomb, banks) do not disclose fulfillment status until encountered; perhaps add a selector to quest_fulfilled target like ifPeeking that will allow the object determine when it's being previewed and when it's encountered ⋯
|
||
perhaps add a $name property to AObject, for $type-s other than ground/hero/town/monster? ⋯
|
|||
IC |
SoD immediately switches to hero/town panel if no object was selected before. ⋯
|
||
I |
Kingdom Overview ⋯
|
||
I |
// SoD doesn't permit disembarking on top of an Event (which is the only ground object with passable actionable spot) but allows on top of Grail (which is hidden in HeroWO and ignored by pathfinder, cursor, spot effects, etc.). Currently this disembarking rule is an artificial limitation on the side of UI (XXX should be enforced in PathCost). ¶
|
||
I |
show growth affectors ⋯
|
||
RH |
garList._store.release() // XXX; also grep for other /\._store\./ occurrences ¶
|
||
IC |
SoD shows on the right of the portrait ⋯
|
||
I |
auto-cancel windows if building gets deleted ⋯
|
||
I |
in SoD it only costs gold; show others in the UI too and make it use calc (artifactCost) ⋯
|
||
I |
for producing buildings and production upgrades SoD shows a different box with the creature's animation, cost and available count ⋯
|
||
R, I |
review all places where classic is accessed and add listening to change_classic (possibly after/together with #clsi) ⋯
|
||
RH |
var backgrounds = ['TPTHBKCS', 'TPTHBKRM', 'TPTHBKTW', 'TPTHBKIN', ⋯
|
||
ID |
same as Conflux (TPTHBKEL) but we don't have Complete version's resources yet so using that one ⋯
|
||
#huig | IC |
put Gold first in classic (implement in EntityCost?) ⋯
|
|
↳ // SoD puts Gold first (XXX). ¶
|
|||
RH |
while (slot < 7 && slot < sub.size().x && sub.anyAtCoords(slot, 0, 0, 0) && sub.atCoords(slot, 0, 0, 'creature', 0) != this.creature()) { ⋯
|
||
C |
in combat, SoD shows in brackets attack/defense adjusted by hero stats and terrain info (+1 for creatures native to combat terrain); need to research other bonuses and implement showing them ⋯
|
||
R |
refactor upgraded creature forms into a Rules Calculator ⋯
|
||
IC |
SoD doesn't draw boat's shadow in this place ⋯
|
||
RH |
duplicates elsewhere; move "trophy exclusion list" to databank ⋯
|
||
RH |
move limit to databank ⋯
|
||
RH |
_.times(5, function (level) { // XXX ¶
|
||
RH |
var windows = ['TPMAGECS', 'TPMAGERM', 'TPMAGETW', 'TPMAGEIN', ⋯
|
||
RH |
var byLevel = [0, 0, 0, 0, 0, 0] // XXX ¶
|
||
PlayerName calc to allow players specifying custom names rather than using hardcoded colors like in SoD? ⋯
|
|||
IC |
until we use SoD's font ⋯
|
||
C |
numbers determined arbitrarily ⋯
|
||
C |
numbers determined arbitrarily ⋯
|
||
I |
//this.nested('quickCombat').set('checked', this.sc.get('quickCombat')) ⋯
|
||
I |
//this.nested('subtitles').set('checked', this.sc.get('subtitles')) ⋯
|
||
I |
determine if replay saving is available; if not, disable, else on click reroute directly to replay saving ⋯
|
||
R |
center: true, // XXX use _opt.center on all other H3 windows and remove left/top from CSS? ¶
|
||
SoD doesn't permit more than 8 heroes per player; we do (sans the artificial limit) so display scroll buttons for future proofness (they won't look too good right now but they're easy to redraw) ⋯
|
|||
IC |
SoD draws transparent flags instead of gray, and no shadow ⋯
|
||
RH |
opt.slider = {height: 7} // XXX ¶
|
||
IC |
for ballista/FAT/ammo cart the message appears on attempt to drop to backpack while dragging starts successfully ⋯
|
||
I |
This is fine except it allows bypassing Artifact->$slots requirement of not accepting backpack. It's expected that the user has to put the artifact back to some slot eventually, but he can easily avoid this (e.g. by cancelling HeroInfo). It's probably a good idea to forcefully put "in-progress" artifacts back after some timeout, upon change of Player._opt.screen, pending, etc. (but then what to do if another artifact already occupies that slot and that artifact can't fit into backpack either?). ⋯
|
||
IC |
SoD shows this message in the top part of the screen rather than centered ⋯
|
||
RH |
box._markUp_BonusesImages(null, box.el, {bonuses: {heroes: {0: {artifacts: [this.get('artifact')]}}}}) ⋯
|
||
IC |
in SoD if backpack has visible scroll buttons then using them wraps around the artifact list (i.e. there's no start/end restrictions) ⋯
|
||
R |
Very lazy update. ⋯
|
||
RH |
icon detection logic is similar to H3.DOM.MainMenu's ⋯
|
||
I |
account for garrison_reinforce/reduce ⋯
|
||
I |
don't allow garrison to consist only of creatures with maxCombats <> false; also update checks in RPC ⋯
|
||
I |
draw popup ⋯
|
||
IC |
SoD allows splitting even if stack count is 1 ⋯
|
||
I |
also disable when have no AP to travel first route segment ⋯
|
||
R |
this old code was supposed to notify us when hero becomes or ceases to be garrisoned/visiting but it's flaky because hero can enter/leave town without moving on ADVMAP; we now have visiting/garrisoned properties for hero AObject-s so should instead hook ochange_p_VIS/GAR ⋯
|
||
IC |
in classic mode replace all available with hourglass panel indicating turn of another player (animated hourglass if AI's turn) ⋯
|
||
// If set, invisible bits in map.shroud for hero's owner are regarded as impassable; with fog though this doesn't fully work (XXX): DOM.Mini/Map hide non-permanent objects in fog (like heroes, not trees), yet info about which is leaked through PathCost, which checks byPassable and may report an explored tile as impassable even though there's no object shown standing on it in ADVMAP. ¶
|
|||
this is now !delayRender so no need for workaround ⋯
|
|||
I |
Pathfinder should take into account target object's passability. However, it is returned by triggerSpotEffects ('stand', 'stop', etc.) which is not known beforehand (and it may depend on arbitrary world properties, moreover - those set after part of the move route was traversed). For example, in SoD placing a Scholar and wearing Angel Wings or Boots of Levitation results in the following move route (¹ to ³): [_²[S³[_] _ = ground, S = scholar [ ¹[ ][ ] water [_][H][_] H = hero Interestingly, placing an actionable spot of some object (like Windmill) on the left of Scholar (in ²) makes the latter unreachable (even though ² itself is reachable and can be triggered as normal travel destination). For this to work, we likely need to move passability detection from triggerSpotEffects into a more specialized, almost constant method. ¶
|
||
I, C |
Some diagonal movements (where any adjacent tile is a ground?) are prohibited on water. For example, one cannot interact with Mermaids after boarding [S] here (Mermaids shifted by one to the left are reachable): [_][_][ ][ ] _ = ground [ ][ ][ ][ ] [ ] = water [ ][#][@][#] [#@#] = Mermaids [ ][S][H][_] S = ship, H = hero on ground [ ][ ][_][_] A simpler example where ² is only reachable via ¹: [ ²[_] _ = ground [ ¹[S] ¶
|
||
here and in other places: replace such calls with map.to/fromContiguous? ⋯
|
|||
RH |
vehicle characteristics ⋯
|
||
consider eliminating bySpot usage in PathCost, extending byPassable properties instead ⋯
|
|||
I |
Since a monster prevents movement around itself, it is impossible to encounter the monster's own actionable spot: [ ][.][.][.] [.] = guarded [H][.][@][.] H = hero, @ = monster (unreachable in HeroWO) [ ][.][.][.] However, SoD makes an exception, allowing building route to [@] through any [.] (guarded by target [@] only) if [@] is the travel destination. This purportedly improves user experience even though technically it works exactly as if moving onto a [.] (the hero stops and combat starts without reaching [@]). ⋯
|
||
R |
we currently have a variety of tracing log methods: here, AI, Calculator, etc. try to unify them; also see ll ⋯
|
||
R |
refactor and move generic methods to `#RPC, extract and move logic to H3.Rules ⋯
|
||
B |
3 Hero will pause over invalid spot (impassable, different terrain, etc.) if features change in such a way that continued movement is impossible (movement-triggered changes - a new impassable appears, terrain changes, etc.) or if client-supplied route is suboptimal. While some cases can be potentially solved by examining the move route ahead, it still won't protect against map changes unless we somehow lock certain map regions. Perhaps if this happens hero should be transported back to the last valid spot. ⋯
|
||
B |
3 a similar problem is that PathCost is not aware of APs, they may run out over water with Boots of Levitation or over impassable with that or Angel Wings, and hero will also stop ⋯
|
||
R |
should pathFindFor() adjust returned path to subtract actionableSpot? just like it automatically adds it. ⋯
|
||
R |
do_hireHero: function (args) { ⋯
|
||
RH |
if (this.get('player').heroes.length >= 8) { // XXX limit ¶
|
||
RH |
hardcoded class ID ⋯
|
||
R |
hardcoded building ID, need to make an Effect target ⋯
|
||
R |
In SoD all types of taverns and towns are on solid ground so vehicle will be always horse. However, we allow water-based taverns in custom maps. This is still assuming only water terrain needs ship and others need horse because there's no terrain type -> vehicle index. We could figure that by iterating over all vehicle types and querying hero_walkTerrain Effect target but doesn't sound good either. ⋯
|
||
R |
do_heroLevelSkill: function (args) { ⋯
|
||
R |
do_heroArtifactSwap: function (args) { ⋯
|
||
I |
14 receiving hero must be adjacent or be garrisoned while other is visiting (same as in do=garrison, see comments there) ⋯
|
||
I |
14 check Player._opt.screen* ⋯
|
||
IC |
SoD allows buying only if the slot is free ⋯
|
||
I |
check $pending for both bonus and hero objects; here and in other do_... ⋯
|
||
IC |
SoD allows buying only 1 and only if the slot is free (since can't fit these into backpack) ⋯
|
||
R |
Very similar to _disembark(). ⋯
|
||
I |
implement encounter of standalone tradingPost ⋯
|
||
RH |
this.rules._erect(town.get('id'), [args.building], calc._buildings._calc.get('affectors')) // XXX ¶
|
||
R |
see if this conundrum can be eased by using the new "^" event prefix in Sqimitive ⋯
|
||
R |
logically, this should be moved to: Combat.State = Common.Sqimitive.extend('HeroWO.H3.Combat.State', { _update: function () { this.batch(null, function () { <here> }) this way, changes done after batch() ends but before _update's override handler is reached will be noticed ⋯
|
||
R |
this and all other combat-related methods do not need to be part of RPC, they are not using anything except _opt.context plus do_combat can be called for player different from H3 RPC's player; make a separate class This assumes AObject-s of all parties are frozen with $pending. ⋯
|
||
I |
allow decisionMaker make a counter-offer with up to +30% difference from the counted price Normally, pendingSurrender cannot be serialized as part of Party because surrenderAsk's Async is part of WS pending until surrenderAccept is called, which unsets pendingSurrender. ⋯
|
||
C |
giving bonus = 20% of defense ⋯
|
||
C |
does SoD allow defending artifact creatures (Ballista, etc.)? in-combat log says it isn't gaining +N defense but DEF do have defending animation ⋯
|
||
R |
duplicates with tacticsNext ⋯
|
||
RH |
var max = doCalc(Calculator.Effect.GenericNumber, c.cx.map.constants.effect.target.spellMastery) >= c.cx.map.constants.spell.mastery.advanced ? 5 : 4 ⋯
|
||
IC |
SoD seeks nearest, not random ⋯
|
||
O |
c.cx.map.effects.find(0, function ($, effect) { ⋯
|
||
R |
calc is removed but expandModifier() is semi-static so can use it like that ⋯
|
||
R |
this partially matches Effect::fromShort() and it only supports some modifier formats (which our spells currently evaluate to); need to implement generic priority calculation like in PHP ⋯
|
||
O |
c.cx.map.effects.find(0, function ($, effect) { ⋯
|
||
O |
c.cx.map.effects.find(0, function ($, effect) { ⋯
|
||
R |
First aid should be reworked: add a new creature-only spell "heal" (similar to dispel <-> dispel helpful) and add it to FAT's creature_spells. This way there will be no stat interference (currently what affects damageMin/Max also affects FAT's efficiency) and no checks for creature type (like one below) or team will be needed (can use spellImmune), plus other spell targets will be possible to use (like making healing global using spellGlobal). This is not done now because creature spells are not implemented yet. ⋯
|
||
I |
add check or Effects for disabling healing Ballista and other artifacts ⋯
|
||
I |
refresh the others var since _makeDamage() (hooks) could have some side effects on arbitrary creatures ⋯
|
||
C, I |
looks like in SoD some creatures' cloud (Magog) has friendly fire, some (Lich) doesn't ⋯
|
||
#ang | R |
var angle = Math.atan2(target.get('y') - attacker.get('y'), target.get('x') - target.get('y') % 2 / 2 - attacker.get('x') + attacker.get('y') % 2 / 2) * (180 / Math.PI) ⋯
|
|
R |
↳ var angle = Math.atan2(cell.y - attacker[1], cell.x - cell.y % 2 / 2 - attacker[0] - attacker[1] % 2 / 2) * (180 / Math.PI) ⋯
|
||
R |
↳ var angle = Math.atan2(curTarget.get('y') - attacker.get('y'), curTarget.get('x') - curTarget.get('y') % 2 / 2 - attacker.get('x') + attacker.get('y') % 2 / 2) * (180 / Math.PI) ⋯
|
||
#rrl | R, I |
as it stands now, msg[0] cannot be localized because it joins many targets together: "The ... do ... damage. [Target1 perish] [Target2 perish] ..." ⋯
|
|
R, I |
↳ SoD has different messages for ripple-type spells: - The Death spell does %d damage \n to all living creatures. - The %s spell does %d damage \n to all undead creatures. - The Armageddon does %d damage. We're using the same message for ripple- and arrow-type spells since HeroWO has a complex system of deciding which creature is hit (livind, undead, etc.), and we also explain how many targets perished. ⋯
|
||
R |
//= targets array`, Set ⋯
|
||
IC |
SoD logs different messages for artifact creatures (First Aid Tent, etc.) ⋯
|
||
R |
_startCombat: function (combat) { ⋯
|
||
C |
If a garrison (creature.party) entirely consists of creatures due for un-summoning (maxCombats < 2) then such a party loses (not part of alive). Perhaps it should not lose, but then it's unclear how to address the now-empty garrison (perhaps can give one first-level creature as when fleeing). Empty alive indicates a tie. ⋯
|
||
C |
sum up all fallen enemy creatures' aiValue 5% and divide by number of alive heroes ⋯
|
||
RH |
51 case c.rules.artifactSlotsID.warMachine1: ⋯
|
||
I |
51 this currently examines slots where the artifact is in, allowing blacklisted artifacts if they're in backpack (e.g. editor allows placing Ballista in Backpack) ⋯
|
||
I |
this rounding creates a disparity because artifacts are distributed from each hero's pool: suppose there are 3 defeated heroes, each with 10 artifacts, and 3 alive heroes; 3rd alive hero receives 4*3=12 artifacts while others - 3*3=9; if we were to collect all enemy artifacts in a common pool and only then distribute, then every hero would receive the same amount of artifacts (3*10/3=10) ⋯
|
||
RH |
var spots = [10, 10, 9, 9, 8, null, 8, 9, 9, 10, 10] // XXX ¶
|
||
RH |
var sx = creature.get('x') - 1 // XXX ¶
|
||
C |
SoD doesn't seem to choose random enemy for every shot, instead it picks some (random one?) at the beginning and shoots it until it dies (or for several turns at least) ⋯
|
||
C |
if FAT and Ammo Cart affect allies too; currently they affect their own party only. ⋯
|
||
R |
review H3.*.js Bits and Calcs to check if owner changes are correctly listened to ¶
|
||
R |
_applyModifier: function (o, operation, params) { ⋯
|
||
C |
This doesn't take into account hero_experienceGain (Learning skill). As a result, visiting Tree of Knowledge will add more experience than needed to reach the next level. Conversely, if hero_experienceGain is < 1 then Tree will give less experience and no level up will occur - but maybe this is actually a good feature? Regardless, need to check how Tree + Learning works in SoD. ⋯
|
||
RH |
return o.value = Math.max(10, o.subCalc('knowledge').calc.updateIfNeeded().get('value') * 10) // XXX consts ¶
|
||
RH |
prop + (level + 1 < 10 ? 'L' : 'H'), // XXX 10 ¶
|
||
C |
Apparently, SoD adjusts tower damage based on buildings constructed in the town (base + upgraded count as one). For example, with Castle alone damages are 10-15/6-9 (main/other towers) but with Tavern they are 12-18/6-9, with Blacksmith 14-21/8-12. Based on tests with Castle (town type) in the editor, main tower's damage grows at +2/+3 min/max for every building (not counting the Castle/Citadel) while other towers' damage grows at the same rate but for every other building (Castle = 6/9, Tavern = same, Blacksmith = 8/12, Marketplace = same, Guardhouse = 10/15, etc.). However, there are either special exceptions or bugs. For example, Citadel + Griffin Tower + Bastion gives 14/21 as expected, but Citadel + Upgraded Griffin Tower + Bastion gives 12/18 (i.e. UGT is not counted as a building). For classic mode such exceptions should be determined and implemented (XXX). ⋯
|
||
IC |
// However, there are either special exceptions or bugs. For example, Citadel + Griffin Tower + Bastion gives 14/21 as expected, but Citadel + Upgraded Griffin Tower + Bastion gives 12/18 (i.e. UGT is not counted as a building). For classic mode such exceptions should be determined and implemented (XXX). ¶
|
||
C |
formulae ⋯
|
||
RH |
var markets = 5 // Trading Post; XXX to databank ¶
|
||
RH |
var rates = [ // XXX to databank ¶
|
||
R |
consider reworking ..._message into general purpose handlers with some kind of selectors/filters without a hardcoded mode number ⋯
|
||
I |
// 3 is used for Pandora's Box. Conditions are matched in order. (*) are not implemented conditions because they are Effects and not tracked by addedBonuses (XXX). ¶
|
||
not sure if this should be a subcalc or if a one-off calculation is fine ⋯
|
|||
C |
do upgraded versions count? e.g. quest needs 10 pikemen and hero has 10 halberdiers ⋯
|
||
R |
var HeroItemCollection = Effects.Collection.extend({ ⋯
|
||
maybe require do=leave and keep dwelling and hero locked (GE alive), then hook just one unpending_... and do screen reset there, like done with townscape? ⋯
|
|||
I |
Must ignore guards when the triggered spot effects resulted in the hero not stepping on this spot. This means guards around the entered and exited monoliths are ignored, as are guards when attacking/trading with a hero. As a special exception, water-based guards around the boat are ignored when embarking (but ground guards around the disembarkation spot are not). But, for example, a guarded Lean To can be only interacted after defeating the guards. Currently we ignore guards when there's anything that will be acted upon except actionable without impassable (Event). UI cursor detection should be updated too. ⋯
|
||
C, I |
which monster of multiple guards is chosen? with max object ID (closest to right-bottom map corner)? ⋯
|
||
C |
18 does doubling happen before or after adding creature growth? ⋯
|
||
C |
18 does horde affect dwellings in the way it's implemented? ⋯
|
||
R |
// SoD doesn't allow picking hero for CPU. XXX Duplicates with WebSocket.Server.Client. ¶
|
||
RH |
strings here and above ⋯
|
||
I |
newly built building should also trigger its encounter, immediately ⋯
|
||
C |
23 SoD usually automatically adds spells into visiting and garrisoned heroes' books but sometimes this happens only if explicitly opening Mage Guild. Research. ⋯
|
||
23 Spells should be also automatically transferred after building or upgrading Mage Guild (right?). Maybe remake do=openMageGuild into an encounter effect? ⋯
|
|||
R |
duplicates with H3.DOM.Bits ⋯
|
||
R |
combine with existing effect instead of always adding new (as in other places) ⋯
|
||
I |
SoD has special behaviour when defending a town with visiting hero but none garrisoned: it combines garrisons of town and hero; if there are more different creatures then slots then some algorithm is used to leave certain town creatures in town, i.e. omit from combat; if defender wins, those extra creatures remain in town intact; if he loses, they are removed (town's garrison is cleared upon defeat); we currently don't do any of this - if the hero loses, the attacker will have to attack the town's garrison next (both combats happen with fortifications) ⋯
|
||
#h3t | R |
cls = _.sample(this.objectsID['hero_' + cls]) ⋯
|
|
R |
↳ cls = _.sample(this.rules.objectsID['hero_' + cls]) ⋯
|
||
R |
↳ _.each(['texture', 'animation'], function (prop) { ⋯
|
||
R |
↳ var cls = _.sample(self.objectsID['artifact_' + art[1]]) ⋯
|
||
R |
↳ var cls = self.objectsID['resource_' + type] ⋯
|
||
R |
↳ var cls = _.sample(self.objectsID['monster_' + creature]) ⋯
|
||
R |
↳ var cls = _.sample(self.objectsID['town_' + town]) ⋯
|
||
R |
↳ var cls = _.sample(self.objectsID['hero_' + hero]) ⋯
|
||
RH |
var obj = this.map._actionableAtter(_.sample(pool), 0, 0, 0) ⋯
|
||
C |
recheck how SoD determines the "weakest" stack; it seems not by fightValue/aiValue but simply by level and then by creature ID ⋯
|
||
currently we treat low number as "set count to 1" if original count is above 1; think how to extend creature_whirlpoolPenalty to be able to specify removal even if original is > 1 ⋯
|
|||
need to apply creature_whirlpoolPenalty to count == 1 as well to allow Effects cancel stack removal ⋯
|
|||
IC |
36 SoD: not shown if have Admiral's Hat but shown if don't have it and no stack was reduced ⋯
|
||
IC |
36 SoD plays the sound upon showing the message if message is shown, or upon mapTeleport if not (we play on mapTeleport always) ⋯
|
||
I |
38 altarOfSacrifice ⋯
|
||
I |
38 blackMarket ⋯
|
||
I |
38 denOfThieves ⋯
|
||
I |
38 freelancerGuild ⋯
|
||
I |
38 hillFort ⋯
|
||
I |
38 obelisk ⋯
|
||
I |
38 refugeeCamp ⋯
|
||
I |
38 sirens ⋯
|
||
I |
38 tradingPost ⋯
|
||
I |
38 university ⋯
|
||
I |
pathfinder should regard a fulfilled borderGate as fully passable (even though cursor shows it's interactive it does nothing) ⋯
|
||
#mof | I |
implement monster fleeing ⋯
|
|
I |
↳ //['retreatCan', true, 'ifObjectType' => array_search('monster', AObject::type)], ⋯
|
||
I |
↳ 0 25%/50%/100% of creatures normally fleeing from your army offer to join ⋯
|
||
I | |||
I |
↳ //> retreatCan bool `- possibility for fleeing, for combat hero >>and for ADVMAP monster (XXX) before combat (this happens after check for 'creature_join')<< (XXX rename target for this case) ¶
|
||
I |
↳ //$this->effect(['retreatCan', $this->o_false, 'ifObject' => $obj->id]); ⋯
|
||
IC |
SoD shows the message on ADVMAP's background, we show on combat ⋯
|
||
I |
new hero object should respect quest removal transition (currently prison disappears when actor moves to it but new hero appears immediately, before that) ⋯
|
||
I |
count should be a word: "few", "several", etc. (XXX respecting garrisonSee?) ⋯
|
||
C |
// XXX count should be a word: "few", "several", etc. (XXX respecting garrisonSee?) ¶
|
||
R |
duplicates with `{Checks`} ⋯
|
||
IC |
SoD shows the message on ADVMAP's background, we show on combat ⋯
|
||
RH |
gar.extendTo(7-1) // XXX ¶
|
||
RH |
if (slot >= 7) { // XXX ¶
|
||
IC |
for single creature show: "A %s joins your army." ADVEVENT.TXT[186] ⋯
|
||
R |
_grantExperience: function (hero, delta) { ⋯
|
||
RH |
if (skills.length < 8) { // XXX ¶
|
||
RH |
while (potential.length < 2) { // XXX ¶
|
||
R |
implement merging with previously set Effect as in _initializeTownSpells() ⋯
|
||
RH |
this.rpc.do_heroLevelSkill({hero: hero.get('id'), skill: potential[0].skill}) ⋯
|
||
R |
duplicates with h3m2herowo.php ⋯
|
||
I, C |
67 SoD updates state of heroes at the beginning of their turn rather than the day. example: have P1, P2; P1's turn is before P2; do P2's spellpoints regen when P1 starts turn or this happens only after P1 ends turn and P2's turn starts? ⋯
|
||
I, C |
67 same for timed events: they must occur at the beginning of turn (in non-simultaneous/classic turn mode), not daybreak ⋯
|
||
C |
is this correct? since all creatures share the same count pool for buildings, we determine the best growth and increment the count by it; keep in mind this method is used for week/month bonus growth (and plague) too; same question applies to _erect() ⋯
|
||
C |
70 on-map monsters should grow too but it has some uncertain algorithm as to when it happens (not every Monday and/or not for all; in fact, sometimes monsters diminish!); when implementing this, account for GenericEncounter's garrison renewal mechanism ⋯
|
||
C |
70 what hordeGrowth in CRTRAITS.TXT (creature_hordeGrowth) is for? on 'horde' world bonus all counts supposedly just double ⋯
|
||
R |
duplicates with Effects.Collection ⋯
|
||
O |
this.map.effects.find(0, function ($1, $2, $3, $4, $5, n) { ⋯
|
||
R |
to avoid conflicts there likely needs to be a central hook on all AObject fields affecting appearance, such as on subclass, that will update texture/animation; this is not implemented currently, as only the town fort/less factor affects object appearance in SoD ⋯
|
||
RH |
_.times(5 /*XXX*/, function (level) { ¶
|
||
RH |
taken from SoD editor's help ⋯
|
||
I |
update duration ⋯
|
||
I |
support hero placeholders ⋯
|
||
R |
duplicates with _initializePlayers() ⋯
|
||
I |
update duration ⋯
|
||
I |
this works if initial experience is < level 2; if not, SoD does some kind of (XXX random-based?) "unattended level-up" (automatically choosing stats and skills); at very least, $level should be bumped here ¶
|
||
C |
// XXX this works if initial experience is < level 2; if not, SoD does some kind of (XXX random-based?) "unattended level-up" (automatically choosing stats and skills); at very least, $level should be bumped here ¶
|
||
C |
check what happens if experience is set for an on-map hero (not in custom heroes dialog) - maybe he also does the same unattended level-up, if so then h3m2herowo.php should be updated ⋯
|
||
C |
// Also unlike others, new dwelling may be smaller than the random placeholder (which is 3x3 with 2 actionable spots but, for example, Goblin Barracts is 2x2 with just one spot). XXX How does SoD adjust position of the new object? ¶
|
||
IC |
after buying the first 2 heroes others must start with the garrison consisting of a single creature: https://forum.herowo.net/t/35 ⋯
|
||
RH |
var size = 2 // XXX to databank ¶
|
||
C |
no idea how SoD handicap works since I have never seen it in the wild; is it even supported? ⋯
|
||
RH |
to databank? Determined empirically. ⋯
|
||
add an atter to provide defaults to props by copying fields from AClass? like done in _initializePlayers() ⋯
|
|||
RH |
if (now == 7) { // XXX ¶
|
||
IC |
In SoD, if you have no initial town on map, the warning message appears not immediately on game start but after a certain action (at least after a combat). If no action is done until end of the day, no initial warning message appears. ⋯
|
||
RH |
!!self.rpc._endTurn(self.cx, self.map.players.nested(lastPlayer)) ⋯
|
||
IC |
// SoD doesn't recognize creatures put (hired) in the town's own garrison (not hero's) but if you enter a visiting hero and then just close the town's screen, the condition will trigger. We don't have this quirk currently (XXX). ¶
|
||
remove Effect target, make a field on AObject instead? ⋯
|
|||
I |
Determines if hero's encounter with this object will be allowed to produce bonuses. This is currently used to check if a Windmill was visited this week, if Border Guard can be passed, etc. but it has several issues, like revealing info that the player shouldn't see until he carries the visit - like if a Shipwreck has been already sacked. ⋯
|
||
RH |
sub.extendTo(7 - 1) // XXX ¶
|
||
IC |
guardians of objects owned by human players must be controlled by the AI and the combat screen shouldn't even be presented to the owning player (currently that player carries the combat as if his town or hero was attacked) ⋯
|
||
RH |
var slots = placement == 'middle' ? 5 : 7 ⋯
|
||
relying on databank data rather than creature_shots ⋯
|
|||
R |
The fact that we are modifying entries when evaluating is against HeroWO's general rule that all data should stored already prepared. Ideally, entries should be marked right when they are added (possibly using a new Effects property); this would need updating of all places where bonus_effects are produced (or at least some generic mechanism on both PHP and JS sides). For now, the entry detection mechanism is an implementation detail that might change. ⋯
|
||
I |
SoD shows messages for both bonus buildings and available (but make sure to not show message for buildings created as a result of Random town initialization in h3m2herowo.php) ⋯
|
||
This assumes all upgraded building forms have the same growth rate as is the case in SoD. If not, available count will use rate of an arbitrary building from bonus_buildings of this timed event. ⋯
|
|||
I |
currently we're pushing creatures to hero's garrison until it's full; the remainder is lost; implement SoD's exchange dialog (GARRISON) - but only for some encounters (like bank reward), not others (like 1-st level dwellings) ⋯
|
||
RH |
sub.extendTo(7-1) // XXX ¶
|
||
RH |
if (slot >= 7 /*XXX*/) { return true } ¶
|
||
C |
SoD's editor help suggests that artifacts may be lost due to full backpack but I have never seen this in game so not implementing it ⋯
|
||
I |
granting during handleInitiallyOwned should be "non-interactive" (no transitions) ⋯
|
||
make min/max normalization universal in GenericNumber? ⋯
|
|||
I |
should appear before levelup Messages are processed in the end, once all addedBonuses were filled. ⋯
|
||
R |
need to implement generic priority calculation like in PHP ⋯
|
||
#mk | R |
refactor other methods to uniform "makeXXX" ⋯
|
|
R |
↳ move to make...() factory on cx ⋯
|
||
R |
state: 'created', // XXX replace with just 'loading' bool ¶
|
||
I |
turnLength: 0, // XXX ¶
|
||
#mstr | I |
rather than serializing no transitions, we should serialize those with unset collect (not yet selected); also, perhaps skipTransitions is unnecessary at all, and that all transitions should be serialized in all cases to allow the client to resume some of them (trsr) ⋯
|
|
B |
↳ Currently fails when loading certain saved games. ⋯
|
||
R |
Code is no longer used. ¶
|
||
R |
here and in other files: anyAtCoords doesn't check for bounds but very often need to check both in-bounds and "any object"; need to either add another method that checks for both or make any... check bounds ⋯
|
||
R |
replace neutral checks that look like so: !p.get('player') with a new prop/method check: p.isNeutral ⋯
|
||
we should have a property for custom player names, to replace obtaining display name from rules (Player->$name) ⋯
|
|||
IC, R |
32 is the cost of moving over cobblestone road, i.e. the fastest terrain (see databank-effects.php); https://forum.herowo.net/t/27 ⋯
|
||
R |
duplicates with CombatLog in databank.php but there's no way to transfer this schema given MapBuilder doesn't create any combats ⋯
|
||
R |
since these are mutually exclusive, combine into one option with 'r'/'s'/null (or numeric consts) values? ⋯
|
||
review and add missing "#-bounds". ⋯
|
|||
O |
an easy optimization would be possible: redefine _padding slots, if any; this will require no _layers shifting (but traversal is still needed to "zero them out", i.e. set values of former _padding slots to false or null) ⋯
|
||
I |
This implementation supports pathfinding within the same Z only. ⋯
|
||
C |
Is it okay for the algorithm that costFunc's result varies per neigh depending on current (as in H3.PathCost)? ⋯
|
||
B |
This still does not work in all cases. ⋯
|
||
C |
likely not good enough ⋯
|
||
C |
/\ /\ /\ /\ /\ hex square | |3.|4.| | | < odd 1 L = L /\ /\./\./\ /\ / 2 R = R ⋯
|
||
R |
Refactor: improve code quality • client/RPC.js ¶
|
||
RH |
schema: store._schema == superStore._subSchemas[prop] ? null : store._schema, ⋯
|
||
R |
more correct would be to have some kind of "mini-server" where clients could be attached, ot a list of all created syncs; current implementation works for visual clients (a client per Screen) but not for special clients (like Replay); "mini-server" might also allow cleaner rewrite of H3.Rules' "mini-server" (initializeSinglePlayer()), possibly merging some single/multi-player code ⋯
|
||
I |
3 require giving hero to be controller by current player but allow receiving hero to be anyone - except for 'swap' where both heroes must be controlled ⋯
|
||
I |
3 check spatial relations of receiver/giver (if both are heroes - they must be adjacent, if one is town - another (hero) must be garrisoned or visiting) ⋯
|
||
I |
3 check Player._opt.screen* ⋯
|
||
I |
6 add checks ⋯
|
||
I |
6 check that hero being entered/left and town are not $pending ⋯
|
||
RH |
var maxSlots = 7 // XXX ¶
|
||
this triggers encounters with town's buildings and opens the town's view so user can manipulate it. but there are no checks on whether such manipulations come as a result of do_townscape or not. for SoD this is not a problem since buildings' encounters are all positive (more AP, SP, etc.) but technically this is not correct. it seems the master must track clients' open/close actions of townscapes and require that all town commands happen while a view is opened, and also prevent having more than one town views simultaneously opened ⋯
|
|||
RH |
gar.extendTo(7-1) // XXX ¶
|
||
RH |
if (slot >= 7) { // XXX ¶
|
||
I |
Add more features, such as: add switching buttons on the right panel of ADVMAP (a button per observable player - neutral observer = all players, others = players in their team). All buttons are in one group and only 0 or 1 in the group must be pressed; if all are off then automatic following of the player's screen is disabled, if 1 then restore() is called. ⋯
|
||
I |
mapHideEnemy: false, // during enemy turn hides ADVMAP (shows fog of war everywhere) and shows shield in place of minimap, even when enemy moves in places explored by the player (makes mapEnemySpeed ineffective) ⋯
|
||
C |
operation of target=shroud Effects was not tested ⋯
|
||
R |
This works for bySpot because every change (i.e. assignment of value different from old) causes ochange on bySpot. However, it is fragile with byTarget and depends on implementation details of Effects' BatchIndexUpdater: if $ifX is set while $ifY is not, and $ifY is being set while $ifX is unset - such Effect is still part of byTarget but as of now the updater does remove + add so we still receive ochange. If the updater becomes more intelligent, we would skip change in this switch without receiving ochange in byTarget and doing _fire_changes(). ⋯
|
||
O |
Would be interesting to learn which of the two (from() or toString()) is faster. ⋯
|
||
R |
0 check existing code and extract HTML <chunks> (usually fed to el.html()) into templates ⋯
|
||
0 consider putting HTML and CSS (extracted from herowo.css) into separate files retireved and bundled using require.js ⋯
|
|||
param = param || 'Hh3-btn_cur' // XXX H3 subsystem ¶
|
|||
I |
$(document) // XXX no off() ¶
|
||
H3 subsystem ⋯
|
|||
R |
// unused values (if they're known). However, some modules wrongly access H3-specific constants as map.constants so that needs to be fixed first (XXX). ¶
|
||
H3 subsystem ⋯
|
|||
I |
public $maxLevel; // 0/null/false unlimited XXX ¶
|
||
RH |
public $won = false; // false; 0/1/2 loss/victory/both (XXX to const?) ¶
|
||
R |
fix this and other similar consts to count from 1? ⋯
|
||
R |
make float short modifier use two's complement (will allow zero const) Float-fix note: even though PHP and JSON have distinct types for representing integer and float values, JavaScript does not (Number.isInteger(1.0) === true). To work around this, if a float has 0 fraction then it's increased by 0.0001 - this is too little to have any affect on final values but enough to recognize it as float. Note: in PHP, do not use round()/floor()/etc. to specify short integer modifier (`'delta) because they take float and return float. Use `[(integer)`] instead: ⋯
|
||
confusing to name priority 'defaults'/'initial' but source 'initial'/'initialize' ⋯
|
|||
how does compact work with string labels in front of bonus_effects? fromShort() returns an Effect object so it should be converted to flat store and then leading "labels" prepended to it ¶
|
|||
since 2D cannot grow, dimensions must be determined right now, but this prevents JS modules from using custom target identifiers; same with other stores here and in AObject::makeIndexes() ⋯
|
|||
I |
// There may be multiple `'``> lines with the same object type if the type is further split into subtypes (for example, `'hero is the type but a property may have different sets of value types for regular heroes and random heroes). Currently (XXX) typesets of all object type's lines are internally merged into one so it doesn't make a difference, but in the future the schema generation algorithm may be improved to account for subtypes and generate more compact schemas. For example, if regular hero uses property `'$A but not `'$B while random hero uses `'$B but not `'$A - current algorithm allocates separate slots for `'hero object type for both `'$A and `'$B, instead of placing them on the same slot. ¶
|
||
I |
refugeeCamp - must reset each Monday ⋯
|
||
R |
$subclass turned out to be a "union in itself" property, i.e. multiple type-dependent properties combined into one slot under the same name. It may be worth breaking it into different properties, each with a proper name (like "heroID" for prison or "animationGroup" for terrain). ⋯
|
||
R |
replace mirrorX/mirrorY with $mirror array, $compact'ed like $passable: [true, false] = '10'; $mirror[0] is x, [1] is y, or with a bitfield ⋯
|
||
RH |
make these indexes consts (same for $animation) ⋯
|
||
retrieving an object's actionable spot is a very common task currently done on run-time (Map.actionableSpot()); put it into a property? ⋯
|
|||
#arbp | R |
`> hero non-layered 1D sub-store `- `'X is ArtifactSlot->$id; when >= `'$id of `'backpack, means the artifact is not equipped (XXX this usage prevents modifications from adding new artifactSlotsID as they'd be considered part of backpack); may have gaps ¶
|
|
R |
↳ throw new Error('Extending ' + prop + ' is currently disallowed.') ⋯
|
||
I |
public $patrol; // XXX ¶
|
||
I |
`> hero ditto `- as `'dwelling; not implemented (XXX) ¶
|
||
RH |
consts ⋯
|
||
// simplicity (XXX) we assume they are point (1x1) because this is the ¶
|
|||
C |
[['surrenderCost', 0.95, true]], ⋯
|
||
C |
[['surrenderCost', 0.90, true]], ⋯
|
||
C |
[['surrenderCost', 0.85, true]], ⋯
|
||
C |
does it affect creatures' spells? ⋯
|
||
I |
need to use certain Effect priority/stack to clear only creatures' immunities and keep immunities like those of Sphere of Permanence ⋯
|
||
I |
// Angelic Alliance XXX ¶
|
||
I |
// Cloak of the Undead King XXX ¶
|
||
I |
// Elixir of Life XXX ¶
|
||
I |
// Titan's Thunder XXX ¶
|
||
#hoshi | I |
when it's on, SoD seems to maintain two AP values: one for ship, one for horse; when dis/embarking, it just swaps the two so that after embark you get a lot of APs and if you immediately disembark, you get the same amount of land APs as before; or, if the artifact's description is right, the game maintains one AP value but "converts" between them when dis/embarking ⋯
|
|
#grl | I |
grail buildings: TOCS/TOF/...+HOLY except: TOFHLYAA TONHOLYA TOSHOLYA TOTHOLYA; icons: BOEGRAIL BOFGRAIL BONHOLYG BOTGRAIL ¶
|
|
I |
↳ create new grail object and place it anywhere if got no premade object, provided there is any obelisk object ⋯
|
||
I |
↳ //buildings.push(self.grailBuildings) ⋯
|
||
I |
↳ with Aurora Borealis, replace all spells' icons with SPELLSCR.DEF frame 70 ⋯
|
||
I |
↳ //array_fill_keys($c_grail, [XXX), ¶
|
||
I |
↳ 'skyship' => 13, // XXX ¶
|
||
C |
costs were obtained from the in-game dialog; need to validate against BUILDING.TXT ¶
|
||
all four shapes/outlines NN/NS/MS/MK are identical $z + 1 (25 for $castle: 24 + 1) is reserved for overlaying shipyard outline when a ship is present (TBCSBOAT). See TownBuildingList.Item. If changing $z here, update CSS. ⋯
|
|||
I |
hallFrame 20 if with ship, also different outline (TOELBOAT) ⋯
|
||
C |
4 hero_actionPoints ⋯
|
||
C |
4 does this stack? if you have 2 towns with 2 lighthouses ⋯
|
||
B |
fix $z, it must overlay shipyard ⋯
|
||
#dbst | I |
there also exists BOCSCV2S.BMP and it's likely an $icon version used when trainingGroundsU is present but I dunno where BO* appear in SoD so can't check that, plus we don't have $iconU ⋯
|
|
I |
↳ $icon variants exist: BORDWF1T BORDWF1H BORDWF1B BORDWF1 BORDWF2T BORDWF2H BORDWF2B BORDWF2 ⋯
|
||
I |
↳ $icon variant exists: BOSMRK2C ⋯
|
||
C |
9 hero_actionPoints ⋯
|
||
C |
9 does this stack? if you have 2 towns with 2 stables Matches effects of on-map Stables. ⋯
|
||
I |
'mysticPond' => [ ⋯
|
||
I |
'treasury' => [ ⋯
|
||
I |
'castleGate' => [ ⋯
|
||
C |
is it applied immediately or on next turn of this player? ⋯
|
||
I |
'skeletonTransformer' => [ ⋯
|
||
I |
'portalOfSummoning' => [ ⋯
|
||
I |
'freelancerGuild' => [ ⋯
|
||
I |
'ballistaYard' => [ ⋯
|
||
I |
'magicUniversity' => [ ⋯
|
||
C, ID |
Must be rechecked and remaining OB* filled in. ⋯
|
||
localize Siege backgrounds. ⋯
|
|||
C |
'missileOfCreature' => [ ⋯
|
||
I |
in SoD is using a beam attack ⋯
|
||
ID |
$enchanter => 'PMAGEX', // XXX ¶
|
||
I |
in SoD is using a beam attack ⋯
|
||
ID |
$evilEye => 'PMAGEX', // XXX ¶
|
||
I |
new spells provided or existing spells overridden by the map are ignored because databank spells are hardcoded; same issue in defining object effects (Corpse), etc. ⋯
|
||
C |
While doing this, I have noticed that casting Armageddon on Diamond Golems deals different damage per group. If you fight 3 groups of Golems and cast it, some groups may have 4 creatures perished, some 5, some 6. Not sure what causes this - Armageddon is supposed to deal the same damage to every party sans their resistance % (which is the same for the same type of creature). ⋯
|
||
C |
'LCRS', // XXX does sharpshooter use the same sounds as archer? ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 20% chance for both spells. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 10% chance. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I |
// 20% chance. XXX ¶
|
||
I, ID |
Unknown chance. ⋯
|
||
IC |
Magic Arrow belongs to all 4 schools but casting it on Firebird is impossible in SoD. Let's suppose the hero has Expert Air Magic and no other skills; HeroWO would choose ifSpellSchool = [Air] and allow casting but SoD seems to check all schools and if the creature has immunity against any of them the spell cannot be cast. ⋯
|
||
I, ID |
Unknown chance. ⋯
|
||
I |
// 20% chance. XXX ¶
|
||
C |
if destroyed - cancel effect? if so then can add new Effect->whileCombatCreature and use it here ⋯
|
||
#dcj | C |
review jousting bonus ⋯
|
|
C |
↳ $champion => ['jousting' => 2, 'width' => 2], ⋯
|
||
I |
Implement extra skill (Rebirth). ⋯
|
||
I |
Implement extra skill (drains spellpoints). ⋯
|
||
I |
Implement extra skill (Fire Shield). ⋯
|
||
I |
"channel 20% of spell points spent by enemy spellcasters directly into their hero’s spell point pool". ⋯
|
||
C |
damage numbers ⋯
|
||
I |
hide these from H3.DOM.Combat.Queue ⋯
|
||
'Trench' => [ // XXX localize ¶
|
|||
C |
are towers affected by hero's attack and other stats? currently they are, using the standard damageRange() formulas ⋯
|
||
C |
numbers ⋯
|
||
#twm | I |
tower's fortification must be land mines placed along the walls, doing 150 damage but only once per spot/mine per combat; this should be implemented after spells like land mines and quicksand are implemented ⋯
|
|
I |
↳ //$siegeObstacles[] = ["SG{$s}MOAT", $bmp, $c_moat, ${"g_$town"}, 0, 0, 1, 1, '1']; ⋯
|
||
C |
is tower affected by luck? in H2 it was ⋯
|
||
C |
validate actually generated Effects against % in BALLIST.TXT ⋯
|
||
C |
chances of bonuses ⋯
|
||
C |
Is the upgraded creature growth boosted (at least weekly) if base creature was selected? SoD's message includes only the base creature name but I haven't checked actual numbers in dwellings; I assume in towns both creatures grow (since they share the same building's availability number) but what about on-map dwellings? Also strange that the only case (?) when the message includes both Imp and Familiar is after building Grail in Inferno. In any case, the inverse probably doesn't apply (i.e. Black Dragon grows alone). ⋯
|
||
R |
change to a recurring target similarly to creature_strikes and combatCasts ⋯
|
||
C |
4 ['hero_actionCost', -50.0, 'ifRoad' => array_search('dirt', AClass::road), 'stack' => [$st_terrain, 1]], ⋯
|
||
I |
4 Angel Wings affects path cost ⋯
|
||
C |
See if there are movement bonuses for different heroes much like native terrain to creatures. ¶
|
||
C |
"$planeswalker $male" => "CH17", // XXX and update Images.txt ¶
|
||
C |
"$planeswalker $female" => "CH17", // XXX and update Images.txt ¶
|
||
C |
"$elementalist $male" => "CH16", // XXX and update Images.txt ¶
|
||
C |
"$elementalist $female" => "CH16", // XXX and update Images.txt ¶
|
||
C |
// Audio data is coming from Sounds.txt. XXX `{Audio`}-s need to be checked with the actual game sounds. ¶
|
||
I |
//array_fill_keys($c_altarofSacrifice, [XXX]), ¶
|
||
IC |
2 SoD filters learned secondary skills in the message by ignoring ones the hero already has (or all, if he has 8 skills already) ⋯
|
||
IC |
2 SoD may show multiple messages if it deems the content to be displayed is too large; each message uses its own text detection (i.e. if first bonus shown on that message is 'creatures' that it'd use that text, no matter what was the first bonus of the first message) ⋯
|
||
C |
need to check for spell book and wisdom (quest_fulfilled)? ⋯
|
||
IC |
Slightly different message from SoD (SoD shows "A" instead of count "1"); also it has a bug: it only checks first creature's stack size; if it's 1 then this message is used even if there are other creatures granted (or the same creature but in another stack) ⋯
|
||
IC |
Slightly different message from SoD (SoD shows no count) ⋯
|
||
I |
//array_fill_keys($c_blackMarket, [XXX]), ¶
|
||
#dlc | I |
the replaced substring is not found in localized TXTs ⋯
|
|
I |
↳ str_replace('1000 gold', '`{Checks`}', toMarkup($adve[73], '`{Audio FAERIE`}')), ⋯
|
||
I |
↳ str_replace('1500 gold', '`{Bonuses`}', toMarkup($adve[118], '`{BonusesImages`}`{Audio CHEST`}')), ⋯
|
||
I |
↳ str_replace('2000 gold', '`{Checks`}', toMarkup($adve[150], '`{Audio GAZEBO`}')), ⋯
|
||
I | |||
I |
↳ str_replace('1000 gold', '`{Checks`}', toMarkup($adve[160], '`{Audio MILITARY`}')), ⋯
|
||
B |
HeroAP remains full at the end of the move because its update is called twice: first in response to GenericEncounter setting AP to 0, then during running transaction of do=heroMove that triggered the encounter ⋯
|
||
IC |
Slightly different from SoD: it shows one neutral luck (0) icon for -1 luck or one +1 for others. We in classic mode show 2/3 +1 icons for +2/+3 luck. ⋯
|
||
I |
//array_fill_keys($c_hillFort, [XXX]), ¶
|
||
#eyom | I |
SoD also shows every Eye, pausing for several seconds before going to next; we should do the same, plus allow breaking out of this by clicking anywhere (in non-classic mode) ⋯
|
|
I |
//array_fill_keys($c_marketOfTime, [XXX]), ¶
|
||
I |
//array_fill_keys($c_obelisk, [XXX]), ¶
|
||
IC |
Slightly different message from SoD ⋯
|
||
IC |
SoD doesn't play sound for Spell Scroll ⋯
|
||
C, I |
SoD sometimes (randomly?) adds quests to some artifact objects (have Wisdom, have Leadership, have gold, have gold and precious resource, etc(?)); this needs research randomArtifact: Places a random artifact on the Adventure Map. Artifact can be any class. Grail is excluded. randomTreasureArtifact: Places a random Treasure class artifact on the Adventure Map. randomMinorArtifact: Places a random Minor class artifact on the Adventure Map. randomMajorArtifact: Places a random Major class artifact on the Adventure Map. randomRelic: Places a random Relic class artifact on the Adventure Map. spellScroll: This scroll contains a spell, which is added into a hero’s spell book for as long as you carry the scroll. I think I've seen another (unused?) class for spell scroll somewhere. At least the editor's help has this second entry: 01 spell per scroll. Appears in hero's spell book if artifact is equipped. ¶
|
||
I |
instead of modal message show it in the right-side panel ⋯
|
||
I |
//array_fill_keys($c_refugeeCamp, [XXX]), ¶
|
||
#sclr | C |
22 what happens if hero has no room for more secondary skills? ⋯
|
|
I | |||
#sclr | I |
22 SoD never chooses a spell bonus if hero's no book ⋯
|
|
I | |||
C |
// Don't know about 3+ (XXX). ¶
|
||
C |
can backpack be full? see also other effects here ¶
|
||
#shwr | C |
is shipwreck impassable from ground? it stands on water and pathcost may consider it passable for water only (in SoD it's passable for both because the hero doesn't move onto the object when interacting with it) ⋯
|
|
I |
spells are not handled by Bonuses/Images ⋯
|
||
I |
//array_fill_keys($c_sirens, [XXX]), ¶
|
||
#stcv | I |
upgrade cavaliers ⋯
|
|
I |
//array_fill_keys($c_denOfThieves, [XXX]), ¶
|
||
I |
//array_fill_keys($c_tradingPost, [XXX]), ¶
|
||
I |
35 the message should appear before LevelUp window ⋯
|
||
35 Audio for lupDo is the same as for choices with lupG/J ⋯
|
|||
I |
//array_fill_keys($c_university, [XXX]), ¶
|
||
IC |
38 Slightly different message from SoD ⋯
|
||
C |
ADVEVENT.TXT[190] suggests that Witch Hut can be deserted ⋯
|
||
should count "visible" skills, filtered by source? ⋯
|
|||
I |
//array_fill_keys($c_freelancerGuild, [XXX]), ¶
|
||
I |
//array_fill_keys($c_heroPlaceholder, [XXX]), ¶
|
||
I |
45 a visit to already owned mine allows leaving garrison (for abandoned too) ⋯
|
||
IC |
45 SoD doesn't play FLAGMINE for Abandoned Mine (but it plays it when entering an already owned AM to leave garrison) ⋯
|
||
C |
['quest_garrison', [$troglodyte => [0, $random, 100, 200]], 'ifGrantedMax' => 0], // XXX garrison count numbers ¶
|
||
ADVMAP's status bar text and RMB help box is as such: if player owns the mine "Abandoned Mine Owned by red player (Gems)", if doesn't and the mine has guards "Abandoned Mine Guarded by a throng of Troglodytes", if not guarded "Abandoned Mine Owned by red player" ¶
|
|||
C |
affects creature spells? ⋯
|
||
I |
add growth effect in towns for these creatures whileOwned, and to their upgraded forms ⋯
|
||
'name' => 'Random Dwelling By Level', // XXX localize ¶
|
|||
'name' => 'Random Dwelling By Town', // XXX localize ¶
|
|||
C, ID |
add missing ⋯
|
||
R |
do we need it, given Lich's attach is implemented using shootingCloud/creature_shootingCloud? ⋯
|
||
R |
do we need it, given it doesn't have (XXX) any special effects other than damage? ⋯
|
||
C |
// XXX do we need it, given it doesn't have (XXX) any special effects other than damage? ¶
|
||
C |
the game seems to play, on impact, ICERAY followed by ICERAYEX ⋯
|
||
C |
the game seems to play another sound in parallel with this one (WGHTKILL?) ⋯
|
||
C |
'castAnimationOfSpell' => [ ⋯
|
||
C |
when does SoD show the first part (drop) of the animation? I did see it a few times; if it didn't show it, this would be just: ⋯
|
||
I |
must use custom animation (polyline) ⋯
|
||
I |
custom animation (red overlay fade-in-out) ⋯
|
||
I |
custom animation (fade-out) ⋯
|
||
I |
custom animation (fade-in) ⋯
|
||
I |
custom animation (fade-in) ⋯
|
||
I |
custom animation (fade-in) ⋯
|
||
I |
custom animation (fade-in) ⋯
|
||
#sssl | I |
H3.Rules is calculating creature_attack and other creature_... stat targets without respect to who is being attacked ⋯
|
|
C |
no giant? ⋯
|
||
#sscs | I |
this must increment the recurring Garrison->retaliating so that target may retaliate again this turn ⋯
|
|
C |
recheck order (precedence, e.g. cartographer vs cover of darkness) ⋯
|
||
R |
use 'terrain' rather than 'other' for non-interactive objects like Kelp ⋯
|
||
C |
public $isGround; // purpose not entirely clear/implemented XXX ¶
|
||
make part of AObject similarly to $texture? ⋯
|
|||
perhaps also normalize to a valid identifier (remove spaces)? ⋯
|
|||
I |
$ifVisiting may be also set to the hero that visits a garrison (gates). ⋯
|
||
I |
//> spellMastery `- if casting by creature XXX creature casting ¶
|
||
I |
//> artifactChance `- if buying from Artifact Merchant XXX ¶
|
||
I |
//> creature_hordeGrowth int `- not currently used (horde world bonus = double creature_growth) XXX ¶
|
||
I |
//> retreatCan bool `- possibility for fleeing, for combat hero >>and for ADVMAP monster (XXX) before combat (this happens after check for 'creature_join')<< (XXX rename target for this case) ¶
|
||
I |
//> creature_join int % multiplier `- chance whether monster group will join hero on encounter (XXX) ¶
|
||
I, R |
// Archers to Sharpshooters, etc. (XXX also merge with creature_upgradeCan?) ¶
|
||
//> creature_dispelImmune bool `- immunity to Dispel; in SoD, this is separate from regular spell immunity (creature_spellImmune); XXX replace with special spell context/ifContext? ¶
|
|||
R |
//> ownable_shroud int `- number of tiles around owned non-hero/town objects (e.g. mine); XXX merge with *_shroud? ¶
|
||
I |
//> creature_reanimate int `- number of new creatures to create after combat (XXX) ¶
|
||
RH |
//> creature_hitChance array associative type => int % multiplier `- for wall attacks (hurl/ram); 0 = chance of a strike doing no damage, 1 = hitting another wall (ignored if there're none or if 'ram'; if picked, a wall is chosen from all alive walls' combined creature_hitChance 2 chances), 2 = hitting the user-specified wall (XXX to const?) ¶
|
||
IC |
SoD shows "Spell Scroll" for all scrolls on ADVMAP and "<spell name>" in message boxes. ⋯
|
||
R |
localize $name ⋯
|
||
like with Creature->$effects, these 4 can be split into dynamic and static ($ifHero); this will allow faster map initialization since less Effects will be $dynamic (but will also increase the number of static ones, most of which won't be used, just like with Creature - not sure how problematic is that) ⋯
|
|||
localize ⋯
|
|||
localize ⋯
|
|||
C |
SoD seems to determine combat terrain based on other things, not only underlying terrain. For example, a lava near water has another combat background ("beach") and creatures native to lava (like Imps) don't get bonuses there. Not sure if HeroWO respects this, need to check type of tile generated on shores - maybe the editor changes it from lava to other, then we're good. ⋯
|
||
C |
public $hordeGrowth; // 0 for most creatures; unknown purpose XXX ¶
|
||
C |
public $flightDistance; // all 1.00 (1000) in SoD; unknown purpose XXX ¶
|
||
C |
public $upgrade; // 0-100 (%) // XXX some kind of chance ¶
|
||
C |
which OB* obstacles can be removed with the spell in SoD? ⋯
|
||
CROGUE.DEF is the only DEF missing turnRight. Since it has turnLeft, can add mirrored turnRight. ⋯
|
|||
R |
DefPreview 1.0.0 stores groups sequentially while 1.2.1 properly indexes them, resulting in gaps (that we skip over here). For 1.2.1, we could skip reading H3L but hopefully we'll move from DefPreview to some console tool in a future rather than fixing this. ⋯
|
||
C |
According to h3m-The-Corpus.txt, if last number in OBJECTS.TXT is not 0 then shadow should not be drawn. def2png.php doesn't process OBJECTS.TXT and it seems that DEF shadows of all such objects don't stick out anyway. ⋯
|
||
validate speed against real in-game animations ⋯
|
|||
I |
{Checks} only works for existing objects; it will fail when hero/monster was defeated ¶
|
||
#hhqm | IC |
Slightly different message in SoD. ⋯
|
|
IC |
↳ 'This land is menaced by `{Checks`}. If you could be so bold as to defeat them, I would reward you richly.', ⋯
|
||
IC |
↳ 'Faugh. You again. Come back when you are `{Checks`}, as I told you.', ⋯
|
||
IC |
↳ 'Not even close to `{Checks`}, leave me until you are there!', ⋯
|
||
IC |
↳ 'You are unworthy. Only someone who is `{Checks`} will be worthy enough.', ⋯
|
||
IC |
↳ 'Don\'t lose heart. Defeating `{Checks`} is a difficult task, but you will surely succeed.', ⋯
|
||
IC |
↳ 'No, `{Checks`} have not been driven off. Until then we cannot go home.', ⋯
|
||
IC |
↳ 'My route is still infested with `{Checks`}. Please hurry, mother becomes more ill each day.', ⋯
|
||
IC |
↳ 'No luck in finding `{Checks`}? Please hurry, the empire depends on you.', ⋯
|
||
IC |
↳ 'I am sorry, but we really want `{Checks`} as guards.', ⋯
|
||
IC |
↳ 'No, those will simply not do. You must bring me `{Checks`} before I can go to my bride to be.', ⋯
|
||
IC |
↳ 'I thought you had promise. You have indeed reached `{Checks`}. Come in, come in. Here, I have something to reward you for your efforts. Do you accept?', ⋯
|
||
IC |
↳ 'Ahhh, you have reached `{Checks`}. Would you like to receive a reward?', ⋯
|
||
IC |
↳ 'Finally, there is someone to whom I can bequeath my worldly possessions, now that you have achieved `{Checks`} do you wish to inherit?', ⋯
|
||
IC |
↳ 'At last, you defeated `{Checks`}, and the countryside is safe again! Are you ready to accept the reward?', ⋯
|
||
IC |
↳ 'Finally, `{Checks`} are gone from our home and we can return! Will you accept this reward?', ⋯
|
||
IC |
↳ 'The route is clear, I thank you deeply. Take this as a symbol of my gratitude.', ⋯
|
||
IC |
↳ 'Yes! `{Checks`} is perfect! Now if you\'ll kindly give it to me, I shall pay what I promised.', ⋯
|
||
IC |
↳ 'I am sorry, but this is a guildhouse, and only those who are experienced enough can join. Only those who are part of the guildhouse may pass. Until you reach `{Checks`}, you may not join.', ⋯
|
||
IC |
↳ 'We have a problem with our King. He doesn\'t like to be surrounded by immature people. Therefore you need to be of `{Checks`} in order to pass through.', ⋯
|
||
IC |
↳ 'The Belted Knights of Erathia guard this tower. They will only let one of their own pass. To join the order, you must first defeat `{Checks`}.', ⋯
|
||
IC |
↳ 'Beware, `{Checks`} are running loose out there. We can\'t open the doors until each and every one is driven from the land.', ⋯
|
||
IC |
↳ 'A small, henpecked man preers over the gate. "No one may pass. My dog ate my wife\'s, `{Checks`}, and I\'m not leaving here until I find a replacement.', ⋯
|
||
IC |
↳ 'The guards here simply will not permit anyone below `{Checks`} to pass.', ⋯
|
||
IC |
↳ 'There is no way we\'re going to let a wimp like you into our guild. Not until you are of `{Checks`} can you join.', ⋯
|
||
IC |
↳ 'Only when you are of `{Checks`} will our King stand for your presence.', ⋯
|
||
IC |
↳ 'The Belted Knights still will not let you pass, so you have not conquered `{Checks`}.', ⋯
|
||
IC |
↳ 'No, `{Checks`} are still running loose.', ⋯
|
||
IC |
↳ 'I am sorry, but the King wants to only see `{Checks`}, nothing else will do.', ⋯
|
||
IC |
↳ 'The guards acknowledge that you have indeed reached `{Checks`}. Do you wish to pass at this time?', ⋯
|
||
IC |
↳ 'Now that you have reached `{Checks`} level you may join our guild. Membership is free. Do you wish to pass at this time?', ⋯
|
||
IC |
↳ 'Excellent! Now that you are of `{Checks`} our King will not have any problems with you. Do you wish to pass at this time?', ⋯
|
||
IC |
↳ 'News of your defeat of `{Checks`} traveled quickly. Do you wish to pass, oh newly Belted Knight?', ⋯
|
||
IC |
↳ '"Give it here and you can pass. Want a dog? Just kidding, will you give `{Checks`} to me?"', ⋯
|
||
#hhsi | R |
Databank's Spell->$id is declared as different from SPTRAITS.TXT index. However, we don't have means to map the two other than by idName which for some spells is different from makeIdentifier(). But not only that, we don't have access to SPTRAITS.TXT and can't look up spell name (or other info, e.g. $description). All we have is SoD's spell ID. Leaving fixing this for later since as of now Spell->$id-s of "userland" spells do match. ⋯
|
|
R |
↳ $spells = [['hero_spells', $this->o_append($hero->spells), 'ifObject' => true, 'stack' => $this->const('effect.stack.classStats')]]; ⋯
|
||
R |
↳ 'spells' => $details->spells, ⋯
|
||
R |
↳ $this->effect(['town_spells', $this->o_append($details->existingSpells), 'ifObject' => $obj->id, 'source' => $this->const('effect.source.initialize')]); ⋯
|
||
R |
↳ $this->effect(['town_spellChance', $this->o_clamp00, 'ifSpell' => $spell, 'ifObject' => $obj->id, 'source' => $this->const('effect.source.initialize')]); ⋯
|
||
R |
↳ $this->effect(['hero_spells', $this->o_append($details->spells), 'ifObject' => $obj->id, 'source' => $this->const('effect.source.initialize'), 'stack' => [array_search('classStats', H3Effect::stack), 1]]); ⋯
|
||
R |
↳ if (isset($details->spell)) { ⋯
|
||
R |
↳ $artifact = $this->spells->atCoords($details->spell, 0, 0, 'scroll'); ⋯
|
||
C |
37 do map-provided rumors have a higher chance of being shown in Tavern? ⋯
|
||
C |
37 do they override standard rumors? ⋯
|
||
#clc | R |
$copyProps = [ ⋯
|
|
R |
↳ 'type', 'texture', 'animation', 'duration', 'width', 'height', 'miniMap', 'passableType', 'passable', 'actionable', 'actionableFromTop']) ⋯
|
||
R |
↳ 'type', 'texture', 'animation', 'duration', 'width', 'height', 'miniMap', 'passableType', 'passable', 'actionable', 'actionableFromTop']) ⋯
|
||
R |
↳ 'type', 'texture', 'animation', 'duration', 'width', 'height', 'miniMap', 'passableType', 'passable', 'actionable', 'actionableFromTop']) ⋯
|
||
R |
↳ var props = ['type', 'duration', 'width', 'height', 'miniMap', 'passableType', 'passable', 'actionable', 'actionableFromTop'] ⋯
|
||
R |
↳ _.each(['type', 'texture', 'animation', 'duration', 'width', 'height', 'miniMap', 'passableType', 'passable', 'actionable', 'actionableFromTop'], function (prop) { ⋯
|
||
R |
↳ 'type', 'texture', 'animation', 'duration', 'width', 'height', 'miniMap', 'passableType', 'passable', 'actionable', 'actionableFromTop']) ⋯
|
||
C |
foreach ($objects as $from) { ⋯
|
||
R |
This should be generally addressed by parsing RoE's and AB's OBJECTS.TXT and creating a compatibility list rather than hardcoding an array here. ⋯
|
||
C |
If SoD uses a universal algorithm for all objects then for the life of me I cannot figure it out. It seems there are either exceptions for hardcoded object classes (notably mountains and trees) or final order depends on individual passability bits. It's easy to spot by comparing against the upper level of "Adventures of Jared Haret" - if you change this calculation, some objects become correctly positioned while others break. For now, this formula at least makes (most) maps playable. 26 18 17 16 2 0 1 11111111b 1 0 11111111111111b 00 !ground y actionable * h3mID zero (*) set for objects moved on run-time; h3mID then specifies X (H3.Rules) If changing this calculation, update addMapMargin() and copies of this in JS (XXX). ⋯
|
||
#dor | R |
// If changing this calculation, update addMapMargin() and copies of this in JS (XXX). ¶
|
|
R |
↳ res.displayOrder = 1 << 26 | spot[1] + opt.height - 1 << 18 | 3 << 16 | spot[0] << 2 ⋯
|
||
R |
↳ displayOrder: 1 << 26 | spot[1] + hero.get('height') - 1 << 18 | 3 << 16 | spot[0] << 2, ⋯
|
||
R |
↳ displayOrder: 1 << 26 | state.get('y') - act[1] + boat.height - 1 << 18 | 3 << 16 | (state.get('x') - act[0]) << 2, ⋯
|
||
R |
↳ displayOrder: 1 << 26 | from[1] - act[1] + boat.height - 1 << 18 | 3 << 16 | (from[0] - act[0]) << 2, ⋯
|
||
R |
↳ displayOrder: 1 << 26 | dest[1] + actor.get('height') - 1 << 18 | 3 << 16 | dest[0] << 2, ⋯
|
||
R |
↳ this.map.objects.setAtCoords(hero, 0, 0, 0, 'displayOrder', 1 << 26 | this._bonusSpot[1] + this.map.objects.atCoords(hero, 0, 0, 'height', 0) - 1 << 18 | 3 << 16 | this._bonusSpot[0] << 2) ⋯
|
||
RH |
slot ⋯
|
||
IC |
compare the shape of our circle with the algorithm SoD uses circle() relies on the fact map margin wasn't yet added so comparing with 0 and width/height compares with the playable area. We don't want to place Grail inside margin, where players cannot reach it. "+ 1" is for [ ][X] - Grail MapObject's actionable spot. ⋯
|
||
I |
Must remove Lighthouse and Shipyard if the town is not near water (SoD allows them but factually ignores "Built" state for these two in Town Properties). XXX However, this likely has to be done on the JS side because this has to apply to Timed Event buildings as well. ¶
|
||
C |
// XXX Must remove Lighthouse and Shipyard if the town is not near water (SoD allows them but factually ignores "Built" state for these two in Town Properties). XXX However, this likely has to be done on the JS side because this has to apply to Timed Event buildings as well. ¶
|
||
R |
duplicates with JS code Determines hero level by the number of experience points. ⋯
|
||
C |
is it purely random or depends on other factors? like hero's army strength ⋯
|
||
count should depend on garrisonSee and could be a word: "few", "several", etc. ⋯
|
|||
R |
duplicates with `{Checks`} ⋯
|
||
hardcoding numbers of the original reward; they may be changed by Effects but we don't know actual numbers at this point because the message (prompt) appears before giving out bonuses (filling addedBonuses); not sure if this should be fixed at all since it might be expected, plus the only way to do it is to carry out a fake _handle_bonus() session ⋯
|
|||
#hhlm | IC |
SoD shows 1 icon of +1 morale no matter the number; we show 3 +1 icons in classic mode ⋯
|
|
IC |
↳ return $s .= "`{LuckImage $reward->luck`}"; ⋯
|
||
META_OBJECT_DWELLING_ABSOD XXX not defined in h3m! ¶
|
|||
META_OBJECT_TOWN_ABSOD XXX not defined in h3m! ¶
|
|||
META_OBJECT_MONSTER_ABSOD XXX not defined in h3m! ¶
|
|||
META_OBJECT_ARTIFACT_AB XXX not defined in h3m! ¶
|
|||
META_OBJECT_ARTIFACT_SOD XXX not defined in h3m! ¶
|
|||
I |
//0x1D => 'CHR', // XXX ¶
|
||
I |
//0x33 => 'WoG', // XXX ¶
|
||
I |
//0xF0 => 'VCMI', // XXX ¶
|
||
I |
throw new CliError('Converting from JSON (-ij) is not implemented yet.'); // XXX ¶
|
||
I |
protected function collectStatistics(H3M $h3m, array &$stats) { ⋯
|
||
I |
protected function printStatistics(array &$stats) { ⋯
|
||
C |
check if this file and index.php templates use hardcoded values (flag images, etc.) rather than relying on databank */ ¶
|
||
consider contain for performance: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Containment ⋯
|
|||
split CSS and templates (HTML) into individual files per module (*.js); create a common CSS file for styles shared by multiple modules (like for text-overflow: ellipsis) */ ¶
|
|||
Chrome and FF (Safar unknown) have a weird bug. If backdrop-filter: grayscale (with any argument) is applied to any node (i.e. there is at least one .Hgrid__cell_fog in the document) and there is an element (such as body or .Hweb-top) with background: teal then this element's content becomes blurry (especially easy to notice if text color is red). Doesn't happen with white instead of teal. ¶
|
|||
animation: 30s Hh3-menu-p steps(20) alternate; /* XXX reflect real loading progress */ ¶
|
|||
RH |
practically, this stuff should be part of the databank; extract gameplay-specific rules to a separate CSS file included from the databank */ ¶
|
||
I |
in SoD width depends on amount of content; also need to add scrollbar if content is too long */ ⋯
|
||
#fish | R |
margin-left: calc(-274px + 40em); /* XXX fishy calculation */ ¶
|
|
R |
↳ all this shifting smells real peccant */ ⋯
|
||
R |
↳ more peccant shifting, yay */ ⋯
|
||
IC |
/* SoD shows empty boxes in places of empty spell slots (up to 3). We don't but need to, in classic mode. XXX */ ¶
|
||
auto is supposed to fill columns as they go but as of now Chrome has buggy support for this - when there are 8 visible spells, it shows them in columns of 4 rather than two columns 6+2. I say "buggy" because if you add padding-bottom: 100px to the 6th spell and then change 100px to 0px, Chrome rebalances columns to be exactly 6+2. Hopefully this will be fixed soon and we won't have to contrive a workaround. */ ⋯
|
|||
doc |
<!--https://XXX/docs/map.html#Context--> ¶
|
||
I |
<!-- SoD allows customizing difficulty mode without opening Advanced Options. XXX --> ¶
|
||
I |
On (not implemented) <!--XXX--> ¶
|
||
$lastForumText = ''; // XXX ¶
|
|||
": "" ⋯
|
|||
": "", Show Available Scenarios": "Показать сценарии" ⋯
|
|||
#ART | |||
#art0 | COMPATIBILITY, Unused |
Spell Book ¶
|
|
#art1 | COMPATIBILITY |
Spell Scroll ¶
|
|
#art2 | COMPATIBILITY | ||
#art3 | COMPATIBILITY |
Catapult ¶
|
|
#art4 | COMPATIBILITY |
Ballista ¶
|
|
#art5 | COMPATIBILITY |
Ammo Cart ¶
|
|
#art6 | COMPATIBILITY |
First Aid Tent ¶
|
|
#art7 | COMPATIBILITY, Common |
Centaurs Axe ¶
|
|
#art8 | COMPATIBILITY, Minor |
Blackshard of the Dead Knight ¶
|
|
#art9 | COMPATIBILITY, Minor |
Greater Gnoll's Flail ¶
|
|
#art10 | COMPATIBILITY, Major |
Ogre's Club of Havoc ¶
|
|
#art11 | COMPATIBILITY, Major |
Sword of Hellfire ¶
|
|
#art12 | COMPATIBILITY, Relic |
Titan's Gladius ¶
|
|
#art13 | COMPATIBILITY, Common |
Shield of the Dwarven Lords ¶
|
|
#art14 | COMPATIBILITY, Minor |
Shield of the Yawning Dead ¶
|
|
#art15 | COMPATIBILITY, Minor |
Buckler of the Gnoll King ¶
|
|
#art16 | COMPATIBILITY, Major |
Targ of the Rampaging Ogre ¶
|
|
#art17 | COMPATIBILITY, Major |
Shield of the Damned ¶
|
|
#art18 | COMPATIBILITY, Relic |
Sentinel's Shield ¶
|
|
#art19 | COMPATIBILITY, Common |
Helm of the Alabaster Unicorn ¶
|
|
#art20 | COMPATIBILITY, Common |
Skull Helmet ¶
|
|
#art21 | COMPATIBILITY, Minor |
Helm of Chaos ¶
|
|
#art22 | COMPATIBILITY, Minor |
Crown of the Supreme Magi ¶
|
|
#art23 | COMPATIBILITY, Major |
Hellstorm Helmet ¶
|
|
#art24 | COMPATIBILITY, Relic |
Thunder Helmet ¶
|
|
#art25 | COMPATIBILITY, Common |
Breastplate of Petrified Wood ¶
|
|
#art26 | COMPATIBILITY, Minor |
Rib Cage ¶
|
|
#art27 | COMPATIBILITY, Minor |
Scales of the Greater Basilisk ¶
|
|
#art28 | COMPATIBILITY, Major |
Tunic of the Cyclops King ¶
|
|
#art29 | COMPATIBILITY, Major |
Breastplate of Brimstone ¶
|
|
#art30 | COMPATIBILITY, Relic |
Titan's Cuirass ¶
|
|
#art31 | COMPATIBILITY, Minor |
Armor of Wonder ¶
|
|
#art32 | COMPATIBILITY, Relic |
Sandals of the Saint ¶
|
|
#art33 | COMPATIBILITY, Relic |
Celestial Necklace of Bliss ¶
|
|
#art34 | COMPATIBILITY, Relic |
Lion's Shield of Courage ¶
|
|
#art35 | COMPATIBILITY, Relic |
Sword of Judgement ¶
|
|
#art36 | COMPATIBILITY, Relic |
Helm of Heavenly Enlightenment ¶
|
|
#art37 | COMPATIBILITY, Common |
Quiet Eye of the Dragon ¶
|
|
#art38 | COMPATIBILITY, Minor |
Red Dragon Flame Tongue ¶
|
|
#art39 | COMPATIBILITY, Major |
Dragon Scale Shield ¶
|
|
#art40 | COMPATIBILITY, Relic |
Dragon Scale Armor ¶
|
|
#art41 | COMPATIBILITY, Common |
Dragonbone Greaves ¶
|
|
#art42 | COMPATIBILITY, Minor |
Dragon Wing Tabard ¶
|
|
#art43 | COMPATIBILITY, Major |
Necklace of Dragonteeth ¶
|
|
#art44 | COMPATIBILITY, Relic |
Crown of Dragontooth ¶
|
|
#art45 | COMPATIBILITY, Common |
Still Eye of the Dragon ¶
|
|
#art46 | COMPATIBILITY, Common |
Clover of Fortune ¶
|
|
#art47 | COMPATIBILITY, Common |
Cards of Prophecy ¶
|
|
#art48 | COMPATIBILITY, Common |
Ladybird of Luck ¶
|
|
#art49 | COMPATIBILITY, Common |
Badge of Courage ¶
|
|
#art50 | COMPATIBILITY, Common |
Crest of Valor ¶
|
|
#art51 | COMPATIBILITY, Common |
Glyph of Gallantry ¶
|
|
#art52 | COMPATIBILITY, Common |
Speculum ¶
|
|
#art53 | COMPATIBILITY, Common |
Spyglass ¶
|
|
#art54 | COMPATIBILITY, Common |
Amulet of the Undertaker ¶
|
|
#art55 | COMPATIBILITY, Minor |
Vampire's Cowl ¶
|
|
#art56 | COMPATIBILITY, Major |
Dead Man's Boots ¶
|
|
#art57 | COMPATIBILITY, Major |
Garniture of Interference ¶
|
|
#art58 | COMPATIBILITY, Major |
Surcoat of Counterpoise ¶
|
|
#art59 | COMPATIBILITY, Relic |
Boots of Polarity ¶
|
|
#art60 | COMPATIBILITY, Common |
Bow of Elven Cherrywood ¶
|
|
#art61 | COMPATIBILITY, Minor |
Bowstring of the Unicorn's Mane ¶
|
|
#art62 | COMPATIBILITY, Major |
Angel Feather Arrows ¶
|
|
#art63 | COMPATIBILITY, Common |
Bird of Perception ¶
|
|
#art64 | COMPATIBILITY, Common |
Stoic Watchman ¶
|
|
#art65 | COMPATIBILITY, Minor |
Emblem of Cognizance ¶
|
|
#art66 | COMPATIBILITY, Major |
Statesman's Medal ¶
|
|
#art67 | COMPATIBILITY, Major |
Diplomat's Ring ¶
|
|
#art68 | COMPATIBILITY, Major |
Ambassador's Sash ¶
|
|
#art69 | COMPATIBILITY, Major |
Ring of the Wayfarer ¶
|
|
#art70 | COMPATIBILITY, Minor |
Equestrian's Gloves ¶
|
|
#art71 | COMPATIBILITY, Major |
Necklace of Ocean Guidance ¶
|
|
#art72 | COMPATIBILITY, Relic |
Angel Wings ¶
|
|
#art73 | COMPATIBILITY, Common |
Charm of Mana ¶
|
|
#art74 | COMPATIBILITY, Common |
Talisman of Mana ¶
|
|
#art75 | COMPATIBILITY, Common |
Mystic Orb of Mana ¶
|
|
#art76 | COMPATIBILITY, Common |
Collar of Conjuring ¶
|
|
#art77 | COMPATIBILITY, Common |
Ring of Conjuring ¶
|
|
#art78 | COMPATIBILITY, Common |
Cape of Conjuring ¶
|
|
#art79 | COMPATIBILITY, Major |
Orb of the Firmament ¶
|
|
#art80 | COMPATIBILITY, Major |
Orb of Silt ¶
|
|
#art81 | COMPATIBILITY, Major |
Orb of Tempestuous Fire ¶
|
|
#art82 | COMPATIBILITY, Major |
Orb of Driving Rain ¶
|
|
#art83 | COMPATIBILITY, Major |
Recanter's Cloak ¶
|
|
#art84 | COMPATIBILITY, Common |
Spirit of Oppression ¶
|
|
#art85 | COMPATIBILITY, Common |
Hourglass of the Evil Hour ¶
|
|
#art86 | COMPATIBILITY, Relic |
Tome of Fire Magic ¶
|
|
#art87 | COMPATIBILITY, Relic |
Tome of Air Magic ¶
|
|
#art88 | COMPATIBILITY, Relic |
Tome of Water Magic ¶
|
|
#art89 | COMPATIBILITY, Relic |
Tome of Earth Magic ¶
|
|
#art90 | COMPATIBILITY, Relic |
Boots of Levitation ¶
|
|
#art91 | COMPATIBILITY, Major |
Golden Bow ¶
|
|
#art92 | COMPATIBILITY, Major |
Sphere of Permanence ¶
|
|
#art93 | COMPATIBILITY, Relic |
Orb of Vulnerability ¶
|
|
#art94 | COMPATIBILITY, Common |
Ring of Vitality ¶
|
|
#art95 | COMPATIBILITY, Minor |
Ring of Life ¶
|
|
#art96 | COMPATIBILITY, Major |
Vial of Lifeblood ¶
|
|
#art97 | COMPATIBILITY, Common |
Necklace of Swiftness ¶
|
|
#art98 | COMPATIBILITY, Minor |
Boots of Speed ¶
|
|
#art99 | COMPATIBILITY, Major |
Cape of Velocity ¶
|
|
#art100 | COMPATIBILITY, Common |
Pendant of Dispassion ¶
|
|
#art101 | COMPATIBILITY, Major |
Pendant of Second Sight ¶
|
|
#art102 | COMPATIBILITY, Common |
Pendant of Holiness ¶
|
|
#art103 | COMPATIBILITY, Common |
Pendant of Life ¶
|
|
#art104 | COMPATIBILITY, Common |
Pendant of Death ¶
|
|
#art105 | COMPATIBILITY, Common |
Pendant of Free Will ¶
|
|
#art106 | COMPATIBILITY, Major |
Pendant of Negativity ¶
|
|
#art107 | COMPATIBILITY, Common |
Pendant of Total Recall ¶
|
|
#art108 | COMPATIBILITY, Major |
Pendant of Courage ¶
|
|
#art109 | COMPATIBILITY, Major |
Everflowing Crystal Cloak ¶
|
|
#art110 | COMPATIBILITY, Major |
Ring of Infinite Gems ¶
|
|
#art111 | COMPATIBILITY, Major |
Everpouring Vial of Mercury ¶
|
|
#art112 | COMPATIBILITY, Minor |
Inexhaustible Cart of Ore ¶
|
|
#art113 | COMPATIBILITY, Major |
Eversmoking Ring of Sulfur ¶
|
|
#art114 | COMPATIBILITY, Minor |
Inexhaustible Cart of Lumber ¶
|
|
#art115 | COMPATIBILITY, Relic |
Endless Sack of Gold ¶
|
|
#art116 | COMPATIBILITY, Major |
Endless Bag of Gold ¶
|
|
#art117 | COMPATIBILITY, Major |
Endless Purse of Gold ¶
|
|
#art118 | COMPATIBILITY, Common |
Legs of Legion ¶
|
|
#art119 | COMPATIBILITY, Minor |
Loins of Legion ¶
|
|
#art120 | COMPATIBILITY, Minor |
Torso of Legion ¶
|
|
#art121 | COMPATIBILITY, Major |
Arms of Legion ¶
|
|
#art122 | COMPATIBILITY, Major |
Head of Legion ¶
|
|
#art123 | COMPATIBILITY, Relic |
Sea Captain's Hat ¶
|
|
#art124 | COMPATIBILITY, Relic |
Spellbinder's Hat ¶
|
|
#art125 | COMPATIBILITY, Major |
Shackles of War ¶
|
|
#art126 | COMPATIBILITY, Relic |
Orb of Inhibition ¶
|
|
#art127 | COMPATIBILITY, Relic |
Vial of Dragon Blood ¶
|
|
#art128 | COMPATIBILITY, Relic |
Armageddon's Blade ¶
|
|
#art129 | COMPATIBILITY, Relic |
Angelic Alliance ¶
|
|
#art130 | COMPATIBILITY, Relic |
Cloak of the Undead King ¶
|
|
#art131 | COMPATIBILITY, Relic |
Elixir of Life ¶
|
|
#art132 | COMPATIBILITY, Relic |
Armor of the Damned ¶
|
|
#art133 | COMPATIBILITY, Relic |
Statue of Legion ¶
|
|
#art134 | COMPATIBILITY, Relic |
Power of the Dragon Father ¶
|
|
#art135 | COMPATIBILITY, Relic |
Titan's Thunder ¶
|
|
#art136 | COMPATIBILITY, Relic | ||
#art137 | COMPATIBILITY, Relic |
Bow of the Sharpshooter ¶
|
|
#art138 | COMPATIBILITY, Relic |
Wizard's Well ¶
|
|
#art139 | COMPATIBILITY, Relic |
Ring of the Magi ¶
|
|
#art140 | COMPATIBILITY, Relic |
Cornucopia ¶
|
|
#art141 | COMPATIBILITY, Unused |
Diplomat's Suit ¶
|
|
#art142 | COMPATIBILITY, Unused |
Mired in Neutrality ¶
|
|
#art143 | COMPATIBILITY, Unused |
Ironfist of the Ogre ¶
|
|
#BLD | |||
COMPATIBILITY |
Village Hall ¶
|
||
COMPATIBILITY |
Town Hall ¶
|
||
COMPATIBILITY |
City Hall ¶
|
||
COMPATIBILITY |
Capitol ¶
|
||
COMPATIBILITY |
Fort ¶
|
||
COMPATIBILITY |
Citadel ¶
|
||
COMPATIBILITY |
Castle ¶
|
||
COMPATIBILITY |
Tavern ¶
|
||
COMPATIBILITY |
Blacksmith ¶
|
||
COMPATIBILITY |
Marketplace ¶
|
||
COMPATIBILITY, Conflux, Fortress, Necropolis, Castle |
Shipyard ¶
|
||
COMPATIBILITY, Castle |
Lighthouse ¶
|
||
COMPATIBILITY, Conflux, Dungeon, Tower |
Artifact Merchants ¶
|
||
COMPATIBILITY, Fortress, Stronghold, Necropolis, Castle |
Resource Silo ¶
|
||
COMPATIBILITY, Rampart |
Resource Silo ¶
|
||
COMPATIBILITY, Tower |
Resource Silo ¶
|
||
COMPATIBILITY, Conflux, Inferno |
Resource Silo ¶
|
||
COMPATIBILITY, Dungeon |
Resource Silo ¶
|
||
COMPATIBILITY |
Mage Guild Level 1 ¶
|
||
COMPATIBILITY |
Mage Guild Level 2 ¶
|
||
COMPATIBILITY |
Mage Guild Level 3 ¶
|
||
COMPATIBILITY, Conflux, Dungeon, Necropolis, Inferno, Tower, Rampart, Castle |
Mage Guild Level 4 ¶
|
||
COMPATIBILITY, Conflux, Dungeon, Necropolis, Inferno, Tower, Rampart |
Mage Guild Level 5 ¶
|
||
COMPATIBILITY, Castle |
Brotherhood of the Sword ¶
|
||
COMPATIBILITY, Castle |
Stables ¶
|
||
COMPATIBILITY, Castle |
Griffin Bastion ¶
|
||
COMPATIBILITY, Castle |
Guardhouse ¶
|
||
COMPATIBILITY, Castle |
Upg. Guardhouse ¶
|
||
COMPATIBILITY, Castle |
Archers' Tower ¶
|
||
COMPATIBILITY, Castle |
Upg. Archers' Tower ¶
|
||
COMPATIBILITY, Castle |
Griffin Tower ¶
|
||
COMPATIBILITY, Castle |
Upg. Griffin Tower ¶
|
||
COMPATIBILITY, Castle |
Barracks ¶
|
||
COMPATIBILITY, Castle |
Upg. Barracks ¶
|
||
COMPATIBILITY, Castle |
Monastery ¶
|
||
COMPATIBILITY, Castle |
Upg. Monastery ¶
|
||
COMPATIBILITY, Castle |
Training Grounds ¶
|
||
COMPATIBILITY, Castle |
Upg. Training Grounds ¶
|
||
COMPATIBILITY, Castle |
Portal of Glory ¶
|
||
COMPATIBILITY, Castle |
Upg. Portal of Glory ¶
|
||
COMPATIBILITY, Rampart |
Mystic Pond ¶
|
||
COMPATIBILITY, Rampart |
Fountain of Fortune ¶
|
||
COMPATIBILITY, Rampart |
Treasury ¶
|
||
COMPATIBILITY, Rampart |
Miners' Guild ¶
|
||
COMPATIBILITY, Rampart |
Dendroid Saplings ¶
|
||
COMPATIBILITY, Rampart |
Centaur Stables ¶
|
||
COMPATIBILITY, Rampart |
Upg. Centaur Stables ¶
|
||
COMPATIBILITY, Rampart |
Dwarf Cottage ¶
|
||
COMPATIBILITY, Rampart |
Upg. Dwarf Cottage ¶
|
||
COMPATIBILITY, Rampart |
Homestead ¶
|
||
COMPATIBILITY, Rampart |
Upg. Homestead ¶
|
||
COMPATIBILITY, Rampart |
Enchanted Spring ¶
|
||
COMPATIBILITY, Rampart |
Upg. Enchanted Spring ¶
|
||
COMPATIBILITY, Rampart |
Dendroid Arches ¶
|
||
COMPATIBILITY, Rampart |
Upg. Dendroid Arches ¶
|
||
COMPATIBILITY, Rampart |
Unicorn Glade ¶
|
||
COMPATIBILITY, Rampart |
Upg. Unicorn Glade ¶
|
||
COMPATIBILITY, Rampart |
Dragon Cliffs ¶
|
||
COMPATIBILITY, Rampart |
Upg. Dragon Cliffs ¶
|
||
COMPATIBILITY, Tower |
Library ¶
|
||
COMPATIBILITY, Tower |
Wall of Knowledge ¶
|
||
COMPATIBILITY, Tower |
Lookout Tower ¶
|
||
COMPATIBILITY, Tower |
Sculptor's Wings ¶
|
||
COMPATIBILITY, Tower |
Workshop ¶
|
||
COMPATIBILITY, Tower |
Upg. Workshop ¶
|
||
COMPATIBILITY, Tower |
Parapet ¶
|
||
COMPATIBILITY, Tower |
Upg. Parapet ¶
|
||
COMPATIBILITY, Tower |
Golem Factory ¶
|
||
COMPATIBILITY, Tower |
Upg. Golem Factory ¶
|
||
COMPATIBILITY, Tower |
Mage Tower ¶
|
||
COMPATIBILITY, Tower |
Upg. Mage Tower ¶
|
||
COMPATIBILITY, Tower |
Altar of Wishes ¶
|
||
COMPATIBILITY, Tower |
Upg. Altar of Wishes ¶
|
||
COMPATIBILITY, Tower |
Golden Pavilion ¶
|
||
COMPATIBILITY, Tower |
Upg. Golden Pavilion ¶
|
||
COMPATIBILITY, Tower |
Cloud Temple ¶
|
||
COMPATIBILITY, Tower |
Upg. Cloud Temple ¶
|
||
COMPATIBILITY, Inferno |
Order of Fire ¶
|
||
COMPATIBILITY, Inferno |
Brimstone Stormclouds ¶
|
||
COMPATIBILITY, Inferno |
Castle Gate ¶
|
||
COMPATIBILITY, Inferno |
Birthing Pools ¶
|
||
COMPATIBILITY, Inferno |
Cages ¶
|
||
COMPATIBILITY, Inferno |
Imp Crucible ¶
|
||
COMPATIBILITY, Inferno |
Upg. Imp Crucible ¶
|
||
COMPATIBILITY, Inferno |
Hall of Sins ¶
|
||
COMPATIBILITY, Inferno |
Upg. Hall of Sins ¶
|
||
COMPATIBILITY, Inferno |
Kennels ¶
|
||
COMPATIBILITY, Inferno |
Upg. Kennels ¶
|
||
COMPATIBILITY, Inferno |
Demon Gate ¶
|
||
COMPATIBILITY, Inferno |
Upg. Demon Gate ¶
|
||
COMPATIBILITY, Inferno |
Hell Hole ¶
|
||
COMPATIBILITY, Inferno |
Upg. Hell Hole ¶
|
||
COMPATIBILITY, Inferno |
Fire Lake ¶
|
||
COMPATIBILITY, Inferno |
Upg. Fire Lake ¶
|
||
COMPATIBILITY, Inferno |
Forsaken Palace ¶
|
||
COMPATIBILITY, Inferno |
Upg. Forsaken Palace ¶
|
||
COMPATIBILITY, Necropolis |
Necromancy Amplifier ¶
|
||
COMPATIBILITY, Necropolis |
Cover of Darkness ¶
|
||
COMPATIBILITY, Necropolis |
Skeleton Transformer ¶
|
||
COMPATIBILITY, Necropolis |
Unearthed Graves ¶
|
||
COMPATIBILITY, Necropolis |
Cursed Temple ¶
|
||
COMPATIBILITY, Necropolis |
Upg. Cursed Temple ¶
|
||
COMPATIBILITY, Necropolis |
Graveyard ¶
|
||
COMPATIBILITY, Necropolis |
Upg. Graveyard ¶
|
||
COMPATIBILITY, Necropolis |
Tomb of Souls ¶
|
||
COMPATIBILITY, Necropolis |
Upg. Tomb of Souls ¶
|
||
COMPATIBILITY, Necropolis |
Estate ¶
|
||
COMPATIBILITY, Necropolis |
Upg. Estate ¶
|
||
COMPATIBILITY, Necropolis |
Mausoleum ¶
|
||
COMPATIBILITY, Necropolis |
Upg. Mausoleum ¶
|
||
COMPATIBILITY, Necropolis |
Hall of Darkness ¶
|
||
COMPATIBILITY, Necropolis |
Upg. Hall of Darkness ¶
|
||
COMPATIBILITY, Necropolis |
Dragon Vault ¶
|
||
COMPATIBILITY, Necropolis |
Upg. Dragon Vault ¶
|
||
COMPATIBILITY, Dungeon |
Mana Vortex ¶
|
||
COMPATIBILITY, Dungeon |
Portal of Summoning ¶
|
||
COMPATIBILITY, Dungeon |
Battle Scholar Academy ¶
|
||
COMPATIBILITY, Dungeon |
Mushroom Rings ¶
|
||
COMPATIBILITY, Dungeon |
Warren ¶
|
||
COMPATIBILITY, Dungeon |
Upg. Warren ¶
|
||
COMPATIBILITY, Dungeon |
Harpy Loft ¶
|
||
COMPATIBILITY, Dungeon |
Upg. Harpy Loft ¶
|
||
COMPATIBILITY, Dungeon |
Pillar of Eyes ¶
|
||
COMPATIBILITY, Dungeon |
Upg. Pillar of Eyes ¶
|
||
COMPATIBILITY, Dungeon |
Chapel of Stilled Voices ¶
|
||
COMPATIBILITY, Dungeon |
Upg. Stilled Voices ¶
|
||
COMPATIBILITY, Dungeon |
Labyrinth ¶
|
||
COMPATIBILITY, Dungeon |
Upg. Labyrinth ¶
|
||
COMPATIBILITY, Dungeon |
Manticore Lair ¶
|
||
COMPATIBILITY, Dungeon |
Upg. Manticore Lair ¶
|
||
COMPATIBILITY, Dungeon |
Dragon Cave ¶
|
||
COMPATIBILITY, Dungeon |
Upg. Dragon Cave ¶
|
||
COMPATIBILITY, Stronghold |
Hall of Valhalla ¶
|
||
COMPATIBILITY, Stronghold |
Escape Tunnel ¶
|
||
COMPATIBILITY, Stronghold |
Freelancer's Guild ¶
|
||
COMPATIBILITY, Stronghold |
Ballista Yard ¶
|
||
COMPATIBILITY, Stronghold |
Mess Hall ¶
|
||
COMPATIBILITY, Stronghold |
Goblin Barracks ¶
|
||
COMPATIBILITY, Stronghold |
Upg. Goblin Barracks ¶
|
||
COMPATIBILITY, Stronghold |
Wolf Pen ¶
|
||
COMPATIBILITY, Stronghold |
Upg. Wolf Pen ¶
|
||
COMPATIBILITY, Stronghold |
Orc Tower ¶
|
||
COMPATIBILITY, Stronghold |
Upg. Orc Tower ¶
|
||
COMPATIBILITY, Stronghold |
Ogre Fort ¶
|
||
COMPATIBILITY, Stronghold |
Upg. Ogre Fort ¶
|
||
COMPATIBILITY, Stronghold |
Cliff Nest ¶
|
||
COMPATIBILITY, Stronghold |
Upg. Cliff Nest ¶
|
||
COMPATIBILITY, Stronghold |
Cyclops Cave ¶
|
||
COMPATIBILITY, Stronghold |
Upg. Cyclops Cave ¶
|
||
COMPATIBILITY, Stronghold |
Behemoth Lair ¶
|
||
COMPATIBILITY, Stronghold |
Upg. Behemoth Lair ¶
|
||
COMPATIBILITY, Fortress |
Cage of Warlords ¶
|
||
COMPATIBILITY, Fortress |
Glyphs of Fear ¶
|
||
COMPATIBILITY, Fortress |
Blood Obelisk ¶
|
||
COMPATIBILITY, Fortress |
Captain's Quarters ¶
|
||
COMPATIBILITY, Fortress |
Gnoll Hut ¶
|
||
COMPATIBILITY, Fortress |
Upg. Gnoll Hut ¶
|
||
COMPATIBILITY, Fortress |
Lizard Den ¶
|
||
COMPATIBILITY, Fortress |
Upg. Lizard Den ¶
|
||
COMPATIBILITY, Fortress |
Serpent Fly Hive ¶
|
||
COMPATIBILITY, Fortress |
Upg. Serpent Fly Hive ¶
|
||
COMPATIBILITY, Fortress |
Basilisk Pit ¶
|
||
COMPATIBILITY, Fortress |
Upg. Basilisk Pit ¶
|
||
COMPATIBILITY, Fortress |
Gorgon Lair ¶
|
||
COMPATIBILITY, Fortress |
Upg. Gorgon Lair ¶
|
||
COMPATIBILITY, Fortress |
Wyvern Nest ¶
|
||
COMPATIBILITY, Fortress |
Upg. Wyvern Nest ¶
|
||
COMPATIBILITY, Fortress |
Hydra Pond ¶
|
||
COMPATIBILITY, Fortress |
Upg. Hydra Pond ¶
|
||
COMPATIBILITY, Conflux |
Magic University ¶
|
||
COMPATIBILITY, Conflux |
Garden of Life ¶
|
||
COMPATIBILITY, Conflux |
Magic Lantern ¶
|
||
COMPATIBILITY, Conflux |
Upg. Magic Lantern ¶
|
||
COMPATIBILITY, Conflux |
Altar of Air ¶
|
||
COMPATIBILITY, Conflux |
Upg. Altar of Air ¶
|
||
COMPATIBILITY, Conflux |
Altar of Water ¶
|
||
COMPATIBILITY, Conflux |
Upg. Altar of Water ¶
|
||
COMPATIBILITY, Conflux |
Altar of Fire ¶
|
||
COMPATIBILITY, Conflux |
Upg. Altar of Fire ¶
|
||
COMPATIBILITY, Conflux |
Altar of Earth ¶
|
||
COMPATIBILITY, Conflux |
Upg. Altar of Earth ¶
|
||
COMPATIBILITY, Conflux |
Altar of Thought ¶
|
||
COMPATIBILITY, Conflux |
Upg. Altar of Thought ¶
|
||
COMPATIBILITY, Conflux |
Pyre ¶
|
||
COMPATIBILITY, Conflux |
Upg. Pyre ¶
|
||
COMPATIBILITY, Conflux | |||
COMPATIBILITY, Fortress | |||
COMPATIBILITY, Castle | |||
COMPATIBILITY, Inferno | |||
COMPATIBILITY, Dungeon | |||
COMPATIBILITY, Tower | |||
COMPATIBILITY, Necropolis | |||
COMPATIBILITY, Rampart | |||
COMPATIBILITY, Stronghold | |||
COMPATIBILITY | |||
#CR | |||
#cr0 | COMPATIBILITY, L1, Castle |
Pikeman ¶
|
|
#cr1 | COMPATIBILITY, L1, Castle |
Halberdier ¶
|
|
#cr2 | COMPATIBILITY, L2, Castle |
Archer ¶
|
|
#cr3 | COMPATIBILITY, L2, Castle |
Marksman ¶
|
|
#cr4 | COMPATIBILITY, L3, Castle |
Griffin ¶
|
|
#cr5 | COMPATIBILITY, L3, Castle |
Royal Griffin ¶
|
|
#cr6 | COMPATIBILITY, L4, Castle |
Swordsman ¶
|
|
#cr7 | COMPATIBILITY, L4, Castle |
Crusader ¶
|
|
#cr8 | COMPATIBILITY, L5, Castle |
Monk ¶
|
|
#cr9 | COMPATIBILITY, L5, Castle |
Zealot ¶
|
|
#cr10 | COMPATIBILITY, L6, Castle | ||
#cr11 | COMPATIBILITY, L6, Castle | ||
#cr12 | COMPATIBILITY, L7, Castle |
Angel ¶
|
|
#cr13 | COMPATIBILITY, L7, Castle |
Archangel ¶
|
|
#cr14 | COMPATIBILITY, L1, Rampart |
Centaur ¶
|
|
#cr15 | COMPATIBILITY, L1, Rampart |
Centaur Captain ¶
|
|
#cr16 | COMPATIBILITY, L2, Rampart |
Dwarf ¶
|
|
#cr17 | COMPATIBILITY, L2, Rampart |
Battle Dwarf ¶
|
|
#cr18 | COMPATIBILITY, L3, Rampart |
Wood Elf ¶
|
|
#cr19 | COMPATIBILITY, L3, Rampart |
Grand Elf ¶
|
|
#cr20 | COMPATIBILITY, L4, Rampart |
Pegasus ¶
|
|
#cr21 | COMPATIBILITY, L4, Rampart |
Silver Pegasus ¶
|
|
#cr22 | COMPATIBILITY, L5, Rampart |
Dendroid Guard ¶
|
|
#cr23 | COMPATIBILITY, L5, Rampart |
Dendroid Soldier ¶
|
|
#cr24 | COMPATIBILITY, L6, Rampart |
Unicorn (no ability) ¶
|
|
#cr25 | COMPATIBILITY, L6, Rampart |
War Unicorn (no ability) ¶
|
|
#cr26 | COMPATIBILITY, L7, Rampart |
Green Dragon ¶
|
|
#cr27 | COMPATIBILITY, L7, Rampart |
Gold Dragon ¶
|
|
#cr28 | COMPATIBILITY, L1, Tower |
Gremlin ¶
|
|
#cr29 | COMPATIBILITY, L1, Tower |
Master Gremlin ¶
|
|
#cr30 | COMPATIBILITY, L2, Tower |
Stone Gargoyle ¶
|
|
#cr31 | COMPATIBILITY, L2, Tower |
Obsidian Gargoyle ¶
|
|
#cr32 | COMPATIBILITY, L3, Tower |
Stone Golem ¶
|
|
#cr33 | COMPATIBILITY, L3, Tower |
Iron Golem ¶
|
|
#cr34 | COMPATIBILITY, L4, Tower |
Mage ¶
|
|
#cr35 | COMPATIBILITY, L4, Tower |
Arch Mage ¶
|
|
#cr36 | COMPATIBILITY, L5, Tower |
Genie ¶
|
|
#cr37 | COMPATIBILITY, L5, Tower |
Master Genie ¶
|
|
#cr38 | COMPATIBILITY, L6, Tower |
Naga ¶
|
|
#cr39 | COMPATIBILITY, L6, Tower |
Naga Queen ¶
|
|
#cr40 | COMPATIBILITY, L7, Tower |
Giant ¶
|
|
#cr41 | COMPATIBILITY, L7, Tower |
Titan ¶
|
|
#cr42 | COMPATIBILITY, L1, Inferno |
Imp ¶
|
|
#cr43 | COMPATIBILITY, L1, Inferno |
Familiar (no ability) ¶
|
|
#cr44 | COMPATIBILITY, L2, Inferno |
Gog ¶
|
|
#cr45 | COMPATIBILITY, L2, Inferno |
Magog ¶
|
|
#cr46 | COMPATIBILITY, L3, Inferno |
Hell Hound ¶
|
|
#cr47 | COMPATIBILITY, L3, Inferno |
Cerberus ¶
|
|
#cr48 | COMPATIBILITY, L4, Inferno |
Demon ¶
|
|
#cr49 | COMPATIBILITY, L4, Inferno |
Horned Demon ¶
|
|
#cr50 | COMPATIBILITY, L5, Inferno |
Pit Fiend ¶
|
|
#cr51 | COMPATIBILITY, L5, Inferno |
Pit Lord ¶
|
|
#cr52 | COMPATIBILITY, L6, Inferno |
Efreeti ¶
|
|
#cr53 | COMPATIBILITY, L6, Inferno |
Efreet Sultan (no ability) ¶
|
|
#cr54 | COMPATIBILITY, L7, Inferno |
Devil ¶
|
|
#cr55 | COMPATIBILITY, L7, Inferno |
Arch Devil ¶
|
|
#cr56 | COMPATIBILITY, L1, Necropolis |
Skeleton ¶
|
|
#cr57 | COMPATIBILITY, L1, Necropolis |
Skeleton Warrior ¶
|
|
#cr58 | COMPATIBILITY, L2, Necropolis |
Walking Dead ¶
|
|
#cr59 | COMPATIBILITY, L2, Necropolis |
Zombie (no ability) ¶
|
|
#cr60 | COMPATIBILITY, L3, Necropolis |
Wight ¶
|
|
#cr61 | COMPATIBILITY, L3, Necropolis |
Wraith (no ability) ¶
|
|
#cr62 | COMPATIBILITY, L4, Necropolis |
Vampire ¶
|
|
#cr63 | COMPATIBILITY, L4, Necropolis |
Vampire Lord ¶
|
|
#cr64 | COMPATIBILITY, L5, Necropolis |
Lich ¶
|
|
#cr65 | COMPATIBILITY, L5, Necropolis |
Power Lich ¶
|
|
#cr66 | COMPATIBILITY, L6, Necropolis |
Black Knight (no ability) ¶
|
|
#cr67 | COMPATIBILITY, L6, Necropolis |
Dread Knight (no ability) ¶
|
|
#cr68 | COMPATIBILITY, L7, Necropolis |
Bone Dragon ¶
|
|
#cr69 | COMPATIBILITY, L7, Necropolis |
Ghost Dragon (no ability) ¶
|
|
#cr70 | COMPATIBILITY, L1, Dungeon |
Troglodyte ¶
|
|
#cr71 | COMPATIBILITY, L1, Dungeon |
Infernal Troglodyte ¶
|
|
#cr72 | COMPATIBILITY, L2, Dungeon |
Harpy ¶
|
|
#cr73 | COMPATIBILITY, L2, Dungeon |
Harpy Hag ¶
|
|
#cr74 | COMPATIBILITY, L3, Dungeon |
Beholder ¶
|
|
#cr75 | COMPATIBILITY, L3, Dungeon |
Evil Eye ¶
|
|
#cr76 | COMPATIBILITY, L4, Dungeon |
Medusa (no ability) ¶
|
|
#cr77 | COMPATIBILITY, L4, Dungeon |
Medusa Queen (no ability) ¶
|
|
#cr78 | COMPATIBILITY, L5, Dungeon |
Minotaur ¶
|
|
#cr79 | COMPATIBILITY, L5, Dungeon |
Minotaur King ¶
|
|
#cr80 | COMPATIBILITY, L6, Dungeon |
Manticore ¶
|
|
#cr81 | COMPATIBILITY, L6, Dungeon |
Scorpicore (no ability) ¶
|
|
#cr82 | COMPATIBILITY, L7, Dungeon |
Red Dragon ¶
|
|
#cr83 | COMPATIBILITY, L7, Dungeon |
Black Dragon ¶
|
|
#cr84 | COMPATIBILITY, L1, Stronghold |
Goblin ¶
|
|
#cr85 | COMPATIBILITY, L1, Stronghold |
Hobgoblin ¶
|
|
#cr86 | COMPATIBILITY, L2, Stronghold |
Wolf Rider ¶
|
|
#cr87 | COMPATIBILITY, L2, Stronghold |
Wolf Raider ¶
|
|
#cr88 | COMPATIBILITY, L3, Stronghold |
Orc ¶
|
|
#cr89 | COMPATIBILITY, L3, Stronghold |
Orc Chieftain ¶
|
|
#cr90 | COMPATIBILITY, L4, Stronghold |
Ogre ¶
|
|
#cr91 | COMPATIBILITY, L4, Stronghold |
Ogre Mage ¶
|
|
#cr92 | COMPATIBILITY, L5, Stronghold |
Roc ¶
|
|
#cr93 | COMPATIBILITY, L5, Stronghold |
Thunderbird (no ability) ¶
|
|
#cr94 | COMPATIBILITY, L6, Stronghold |
Cyclops ¶
|
|
#cr95 | COMPATIBILITY, L6, Stronghold |
Cyclops King ¶
|
|
#cr96 | COMPATIBILITY, L7, Stronghold |
Behemoth ¶
|
|
#cr97 | COMPATIBILITY, L7, Stronghold |
Ancient Behemoth ¶
|
|
#cr98 | COMPATIBILITY, L1, Fortress |
Gnoll ¶
|
|
#cr99 | COMPATIBILITY, L1, Fortress |
Gnoll Marauder ¶
|
|
#cr100 | COMPATIBILITY, L2, Fortress |
Lizardman ¶
|
|
#cr101 | COMPATIBILITY, L2, Fortress |
Lizard Warrior ¶
|
|
#cr102 | COMPATIBILITY, L5, Fortress |
Gorgon ¶
|
|
#cr103 | COMPATIBILITY, L5, Fortress |
Mighty Gorgon (no ability) ¶
|
|
#cr104 | COMPATIBILITY, L3, Fortress |
Serpent Fly ¶
|
|
#cr105 | COMPATIBILITY, L3, Fortress |
Dragon Fly ¶
|
|
#cr106 | COMPATIBILITY, L4, Fortress |
Basilisk (no ability) ¶
|
|
#cr107 | COMPATIBILITY, L4, Fortress |
Greater Basilisk (no ability) ¶
|
|
#cr108 | COMPATIBILITY, L6, Fortress |
Wyvern ¶
|
|
#cr109 | COMPATIBILITY, L6, Fortress |
Wyvern Monarch (no ability) ¶
|
|
#cr110 | COMPATIBILITY, L7, Fortress |
Hydra ¶
|
|
#cr111 | COMPATIBILITY, L7, Fortress |
Chaos Hydra ¶
|
|
#cr112 | COMPATIBILITY, L2, Conflux |
Air Elemental ¶
|
|
#cr113 | COMPATIBILITY, L5, Conflux |
Earth Elemental ¶
|
|
#cr114 | COMPATIBILITY, L4, Conflux |
Fire Elemental ¶
|
|
#cr115 | COMPATIBILITY, L3, Conflux |
Water Elemental ¶
|
|
#cr116 | COMPATIBILITY, L4, Neutral |
Gold Golem ¶
|
|
#cr117 | COMPATIBILITY, L5, Neutral |
Diamond Golem ¶
|
|
#cr118 | COMPATIBILITY, L1, Conflux |
Pixie ¶
|
|
#cr119 | COMPATIBILITY, L1, Conflux |
Sprite ¶
|
|
#cr120 | COMPATIBILITY, L6, Conflux |
Psychic Elemental ¶
|
|
#cr121 | COMPATIBILITY, L6, Conflux |
Magic Elemental ¶
|
|
#cr122 | COMPATIBILITY, L0, Neutral |
NOT USED (1) ¶
|
|
#cr123 | COMPATIBILITY, L3, Conflux |
Ice Elemental ¶
|
|
#cr124 | COMPATIBILITY, L0, Neutral |
NOT USED (2) ¶
|
|
#cr125 | COMPATIBILITY, L5, Conflux |
Magma Elemental ¶
|
|
#cr126 | COMPATIBILITY, L0, Neutral |
NOT USED (3) ¶
|
|
#cr127 | COMPATIBILITY, L2, Conflux |
Storm Elemental ¶
|
|
#cr128 | COMPATIBILITY, L0, Neutral |
NOT USED (4) ¶
|
|
#cr129 | COMPATIBILITY, L4, Conflux |
Energy Elemental ¶
|
|
#cr130 | COMPATIBILITY, L7, Conflux |
Firebird ¶
|
|
#cr131 | COMPATIBILITY, L7, Conflux |
Phoenix (no ability) ¶
|
|
#cr132 | COMPATIBILITY, L10, Neutral |
Azure Dragon (no ability) ¶
|
|
#cr133 | COMPATIBILITY, L10, Neutral |
Crystal Dragon ¶
|
|
#cr134 | COMPATIBILITY, L8, Neutral |
Faerie Dragon ¶
|
|
#cr135 | COMPATIBILITY, L10, Neutral |
Rust Dragon ¶
|
|
#cr136 | COMPATIBILITY, L6, Neutral |
Enchanter ¶
|
|
#cr137 | COMPATIBILITY, L4, Neutral |
Sharpshooter ¶
|
|
#cr138 | COMPATIBILITY, L1, Neutral |
Halfling ¶
|
|
#cr139 | COMPATIBILITY, L1, Neutral |
Peasant ¶
|
|
#cr140 | COMPATIBILITY, L2, Neutral |
Boar ¶
|
|
#cr141 | COMPATIBILITY, L3, Neutral |
Mummy ¶
|
|
#cr142 | COMPATIBILITY, L3, Neutral |
Nomad ¶
|
|
#cr143 | COMPATIBILITY, L2, Neutral |
Rogue ¶
|
|
#cr144 | COMPATIBILITY, L5, Neutral |
Troll ¶
|
|
#cr145 | COMPATIBILITY, L0, Neutral |
Catapult ¶
|
|
#cr146 | COMPATIBILITY, L0, Neutral |
Ballista ¶
|
|
#cr147 | COMPATIBILITY, L0, Neutral |
First Aid Tent ¶
|
|
#cr148 | COMPATIBILITY, L0, Neutral |
Ammo Cart ¶
|
|
#cr149 | COMPATIBILITY, L0, Neutral |
Arrow Tower ¶
|
|
#OBJ | |||
#class0 | COMPATIBILITY, Unused |
Nothing ¶
|
|
#class2 | COMPATIBILITY |
Altar of Sacrifice ¶
|
|
#class3 | COMPATIBILITY |
Anchor Point ¶
|
|
#class4 | COMPATIBILITY |
Arena ¶
|
|
#class5 | COMPATIBILITY |
Artifact ¶
|
|
#class6 | COMPATIBILITY |
Pandora's Box ¶
|
|
#class7 | COMPATIBILITY |
Black Market ¶
|
|
#class8 | COMPATIBILITY |
Boat ¶
|
|
#class9 | COMPATIBILITY |
Border Guard ¶
|
|
#class10 | COMPATIBILITY, Actionable |
Keymaster's Tent ¶
|
|
#class11 | COMPATIBILITY, Actionable |
Buoy ¶
|
|
#class12 | COMPATIBILITY, Actionable |
Campfire ¶
|
|
#class13 | COMPATIBILITY, Actionable |
Cartographer ¶
|
|
#class14 | COMPATIBILITY, Actionable |
Swan Pond ¶
|
|
#class15 | COMPATIBILITY, Actionable |
Cover of Darkness ¶
|
|
#class16 | COMPATIBILITY, Actionable |
Creature Bank ¶
|
|
#class17 | COMPATIBILITY, Actionable |
Creature Generator 1 ¶
|
|
#class18 | COMPATIBILITY, Actionable |
Creature Generator 2 ¶
|
|
#class19 | COMPATIBILITY, Actionable |
Creature Generator 3 ¶
|
|
#class20 | COMPATIBILITY, Actionable |
Creature Generator 4 ¶
|
|
#class21 | COMPATIBILITY |
Cursed Ground ¶
|
|
#class22 | COMPATIBILITY, Actionable |
Corpse ¶
|
|
#class23 | COMPATIBILITY, Actionable |
Marletto Tower ¶
|
|
#class24 | COMPATIBILITY, Actionable |
Derelict Ship ¶
|
|
#class25 | COMPATIBILITY, Actionable |
Dragon Utopia ¶
|
|
#class26 | COMPATIBILITY, Actionable |
Event ¶
|
|
#class27 | COMPATIBILITY, Actionable | ||
#class28 | COMPATIBILITY, Actionable |
Faerie Ring ¶
|
|
#class29 | COMPATIBILITY, Actionable |
Flotsam ¶
|
|
#class30 | COMPATIBILITY, Actionable |
Fountain of Fortune ¶
|
|
#class31 | COMPATIBILITY, Actionable |
Fountain of Youth ¶
|
|
#class32 | COMPATIBILITY, Actionable |
Garden of Revelation ¶
|
|
#class33 | COMPATIBILITY, Actionable |
Garrison ¶
|
|
#class34 | COMPATIBILITY, Actionable |
Hero ¶
|
|
#class35 | COMPATIBILITY, Actionable |
Hill Fort ¶
|
|
#class36 | COMPATIBILITY, Actionable | ||
#class37 | COMPATIBILITY, Actionable |
Hut of the Magi ¶
|
|
#class38 | COMPATIBILITY, Actionable |
Idol of Fortune ¶
|
|
#class39 | COMPATIBILITY, Actionable |
Lean To ¶
|
|
#class41 | COMPATIBILITY, Actionable |
Library of Enlightenment ¶
|
|
#class42 | COMPATIBILITY, Actionable |
Lighthouse ¶
|
|
#class43 | COMPATIBILITY, Actionable |
Monolith One Way Entrance ¶
|
|
#class44 | COMPATIBILITY, Actionable |
Monolith One Way Exit ¶
|
|
#class45 | COMPATIBILITY, Actionable |
Monolith Two Way ¶
|
|
#class46 | COMPATIBILITY |
Magic Plains ¶
|
|
#class47 | COMPATIBILITY, Actionable |
School of Magic ¶
|
|
#class48 | COMPATIBILITY, Actionable |
Magic Spring ¶
|
|
#class49 | COMPATIBILITY, Actionable |
Magic Well ¶
|
|
#class50 | COMPATIBILITY, Actionable, Unused |
Market of Time ¶
|
|
#class51 | COMPATIBILITY, Actionable |
Mercenary Camp ¶
|
|
#class52 | COMPATIBILITY, Actionable |
Mermaids ¶
|
|
#class53 | COMPATIBILITY, Actionable |
Mine ¶
|
|
#class54 | COMPATIBILITY, Actionable |
Monster ¶
|
|
#class55 | COMPATIBILITY, Actionable |
Mystical Garden ¶
|
|
#class56 | COMPATIBILITY, Actionable |
Oasis ¶
|
|
#class57 | COMPATIBILITY, Actionable |
Obelisk ¶
|
|
#class58 | COMPATIBILITY, Actionable |
Redwood Observatory ¶
|
|
#class59 | COMPATIBILITY, Actionable |
Ocean Bottle ¶
|
|
#class60 | COMPATIBILITY, Actionable |
Pillar of Fire ¶
|
|
#class61 | COMPATIBILITY, Actionable |
Star Axis ¶
|
|
#class62 | COMPATIBILITY, Actionable |
Prison ¶
|
|
#class63 | COMPATIBILITY, Actionable |
Pyramid ¶
|
|
#class64 | COMPATIBILITY, Actionable |
Rally Flag ¶
|
|
#class65 | COMPATIBILITY, Actionable |
Random Artifact ¶
|
|
#class66 | COMPATIBILITY, Actionable |
Random Treasure Artifact ¶
|
|
#class67 | COMPATIBILITY, Actionable |
Random Minor Artifact ¶
|
|
#class68 | COMPATIBILITY, Actionable |
Random Major Artifact ¶
|
|
#class69 | COMPATIBILITY, Actionable |
Random Relic ¶
|
|
#class70 | COMPATIBILITY, Actionable |
Random Hero ¶
|
|
#class71 | COMPATIBILITY, Actionable |
Random Monster ¶
|
|
#class72 | COMPATIBILITY, Actionable |
Random Monster 1 ¶
|
|
#class73 | COMPATIBILITY, Actionable |
Random Monster 2 ¶
|
|
#class74 | COMPATIBILITY, Actionable |
Random Monster 3 ¶
|
|
#class75 | COMPATIBILITY, Actionable |
Random Monster 4 ¶
|
|
#class76 | COMPATIBILITY, Actionable |
Random Resource ¶
|
|
#class77 | COMPATIBILITY, Actionable |
Random Town ¶
|
|
#class78 | COMPATIBILITY, Actionable |
Refugee Camp ¶
|
|
#class79 | COMPATIBILITY, Actionable |
Resource ¶
|
|
#class80 | COMPATIBILITY, Actionable |
Sanctuary ¶
|
|
#class81 | COMPATIBILITY, Actionable | ||
#class82 | COMPATIBILITY, Actionable |
Sea Chest ¶
|
|
#class83 | COMPATIBILITY, Actionable |
Seer's Hut ¶
|
|
#class84 | COMPATIBILITY, Actionable |
Crypt ¶
|
|
#class85 | COMPATIBILITY, Actionable | ||
#class86 | COMPATIBILITY, Actionable |
Shipwreck Survivor ¶
|
|
#class87 | COMPATIBILITY, Actionable |
Shipyard ¶
|
|
#class88 | COMPATIBILITY, Actionable |
Shrine of Magic Incantation ¶
|
|
#class89 | COMPATIBILITY, Actionable |
Shrine of Magic Gesture ¶
|
|
#class90 | COMPATIBILITY, Actionable |
Shrine of Magic Thought ¶
|
|
#class91 | COMPATIBILITY, Actionable |
Sign ¶
|
|
#class92 | COMPATIBILITY, Actionable |
Sirens ¶
|
|
#class93 | COMPATIBILITY, Actionable |
Spell Scroll ¶
|
|
#class94 | COMPATIBILITY, Actionable | ||
#class95 | COMPATIBILITY, Actionable |
Tavern ¶
|
|
#class96 | COMPATIBILITY, Actionable |
Temple ¶
|
|
#class97 | COMPATIBILITY, Actionable |
Den of Thieves ¶
|
|
#class98 | COMPATIBILITY, Actionable |
Town ¶
|
|
#class99 | COMPATIBILITY, Actionable |
Trading Post ¶
|
|
#class100 | COMPATIBILITY, Actionable |
Learning Stone ¶
|
|
#class101 | COMPATIBILITY, Actionable |
Treasure Chest ¶
|
|
#class102 | COMPATIBILITY, Actionable |
Tree of Knowledge ¶
|
|
#class103 | COMPATIBILITY, Actionable |
Subterranean Gate ¶
|
|
#class104 | COMPATIBILITY, Actionable |
University ¶
|
|
#class105 | COMPATIBILITY, Actionable |
Wagon ¶
|
|
#class106 | COMPATIBILITY, Actionable |
War Machine Factory ¶
|
|
#class107 | COMPATIBILITY, Actionable |
School of War ¶
|
|
#class108 | COMPATIBILITY, Actionable |
Warrior's Tomb ¶
|
|
#class109 | COMPATIBILITY, Actionable |
Water Wheel ¶
|
|
#class110 | COMPATIBILITY, Actionable |
Watering Hole ¶
|
|
#class111 | COMPATIBILITY, Actionable |
Whirlpool ¶
|
|
#class112 | COMPATIBILITY, Actionable |
Windmill ¶
|
|
#class113 | COMPATIBILITY, Actionable |
Witch Hut ¶
|
|
#class114 | COMPATIBILITY, Unused |
Brush ¶
|
|
#class115 | COMPATIBILITY, Unused |
Bush ¶
|
|
#class116 | COMPATIBILITY |
Cactus ¶
|
|
#class117 | COMPATIBILITY |
Canyon ¶
|
|
#class118 | COMPATIBILITY |
Crater ¶
|
|
#class119 | COMPATIBILITY |
Dead Vegetation ¶
|
|
#class120 | COMPATIBILITY |
Flowers ¶
|
|
#class121 | COMPATIBILITY |
Frozen Lake ¶
|
|
#class122 | COMPATIBILITY, Unused |
Hedge ¶
|
|
#class123 | COMPATIBILITY, Unused |
Hill ¶
|
|
#class124 | COMPATIBILITY |
Hole ¶
|
|
#class125 | COMPATIBILITY |
Kelp ¶
|
|
#class126 | COMPATIBILITY |
Lake ¶
|
|
#class127 | COMPATIBILITY |
Lava Flow ¶
|
|
#class128 | COMPATIBILITY |
Lava Lake ¶
|
|
#class129 | COMPATIBILITY |
Mushrooms ¶
|
|
#class130 | COMPATIBILITY |
Log ¶
|
|
#class131 | COMPATIBILITY |
Mandrake ¶
|
|
#class132 | COMPATIBILITY |
Moss ¶
|
|
#class133 | COMPATIBILITY |
Mound ¶
|
|
#class134 | COMPATIBILITY |
Mountain ¶
|
|
#class135 | COMPATIBILITY |
Oak Trees ¶
|
|
#class136 | COMPATIBILITY |
Outcropping ¶
|
|
#class137 | COMPATIBILITY |
Pine Trees ¶
|
|
#class138 | COMPATIBILITY, Unused |
Plant ¶
|
|
#class143 | COMPATIBILITY |
River Delta ¶
|
|
#class147 | COMPATIBILITY |
Rock ¶
|
|
#class148 | COMPATIBILITY |
Sand Dune ¶
|
|
#class149 | COMPATIBILITY |
Sand Pit ¶
|
|
#class150 | COMPATIBILITY |
Shrub ¶
|
|
#class151 | COMPATIBILITY |
Skull ¶
|
|
#class152 | COMPATIBILITY, Unused |
Stalagmite ¶
|
|
#class153 | COMPATIBILITY |
Stump ¶
|
|
#class154 | COMPATIBILITY, Unused |
Tar Pit ¶
|
|
#class155 | COMPATIBILITY |
Trees ¶
|
|
#class156 | COMPATIBILITY, Unused |
Vine ¶
|
|
#class157 | COMPATIBILITY, Unused |
Volcanic Vent ¶
|
|
#class158 | COMPATIBILITY |
Volcano ¶
|
|
#class159 | COMPATIBILITY, Unused |
Willow Trees ¶
|
|
#class160 | COMPATIBILITY, Unused |
Yucca Trees ¶
|
|
#class161 | COMPATIBILITY |
Reef ¶
|
|
#class162 | COMPATIBILITY, Actionable |
Random Monster 5 ¶
|
|
#class163 | COMPATIBILITY, Actionable |
Random Monster 6 ¶
|
|
#class164 | COMPATIBILITY, Actionable |
Random Monster 7 ¶
|
|
#class165 | COMPATIBILITY, Unused |
Brush ¶
|
|
#class166 | COMPATIBILITY, Unused |
Bush ¶
|
|
#class167 | COMPATIBILITY, Unused |
Cactus ¶
|
|
#class168 | COMPATIBILITY, Unused |
Canyon ¶
|
|
#class169 | COMPATIBILITY, Unused |
Crater ¶
|
|
#class170 | COMPATIBILITY, Unused |
Dead Vegetation ¶
|
|
#class171 | COMPATIBILITY, Unused |
Flowers ¶
|
|
#class172 | COMPATIBILITY, Unused |
Frozen Lake ¶
|
|
#class173 | COMPATIBILITY, Unused |
Hedge ¶
|
|
#class174 | COMPATIBILITY, Unused |
Hill ¶
|
|
#class175 | COMPATIBILITY, Unused |
Hole ¶
|
|
#class176 | COMPATIBILITY, Unused |
Kelp ¶
|
|
#class177 | COMPATIBILITY |
Lake ¶
|
|
#class178 | COMPATIBILITY, Unused |
Lava Flow ¶
|
|
#class179 | COMPATIBILITY, Unused |
Lava Lake ¶
|
|
#class180 | COMPATIBILITY, Unused |
Mushrooms ¶
|
|
#class181 | COMPATIBILITY, Unused |
Log ¶
|
|
#class182 | COMPATIBILITY, Unused |
Mandrake ¶
|
|
#class183 | COMPATIBILITY, Unused |
Moss ¶
|
|
#class184 | COMPATIBILITY, Unused |
Mound ¶
|
|
#class185 | COMPATIBILITY, Unused |
Mountain ¶
|
|
#class186 | COMPATIBILITY, Unused |
Oak Trees ¶
|
|
#class187 | COMPATIBILITY, Unused |
Outcropping ¶
|
|
#class188 | COMPATIBILITY, Unused |
Pine Trees ¶
|
|
#class189 | COMPATIBILITY, Unused |
Plant ¶
|
|
#class190 | COMPATIBILITY, Unused |
River Delta ¶
|
|
#class191 | COMPATIBILITY, Unused |
Rock ¶
|
|
#class192 | COMPATIBILITY, Unused |
Sand Dune ¶
|
|
#class193 | COMPATIBILITY, Unused |
Sand Pit ¶
|
|
#class194 | COMPATIBILITY, Unused |
Shrub ¶
|
|
#class195 | COMPATIBILITY, Unused |
Skull ¶
|
|
#class196 | COMPATIBILITY, Unused |
Stalagmite ¶
|
|
#class197 | COMPATIBILITY, Unused |
Stump ¶
|
|
#class198 | COMPATIBILITY, Unused |
Tar Pit ¶
|
|
#class199 | COMPATIBILITY |
Trees ¶
|
|
#class200 | COMPATIBILITY, Unused |
Vine ¶
|
|
#class201 | COMPATIBILITY, Unused |
Volcanic Vent ¶
|
|
#class202 | COMPATIBILITY, Unused |
Volcano ¶
|
|
#class203 | COMPATIBILITY, Unused |
Willow Trees ¶
|
|
#class204 | COMPATIBILITY, Unused |
Yucca Trees ¶
|
|
#class205 | COMPATIBILITY, Unused |
Reef ¶
|
|
#class206 | COMPATIBILITY |
Desert Hills ¶
|
|
#class207 | COMPATIBILITY |
Dirt Hills ¶
|
|
#class208 | COMPATIBILITY |
Grass Hills ¶
|
|
#class209 | COMPATIBILITY |
Rough Hills ¶
|
|
#class210 | COMPATIBILITY |
Subterranean Rocks ¶
|
|
#class211 | COMPATIBILITY |
Swamp Foliage ¶
|
|
#class212 | COMPATIBILITY, Actionable |
Border Gate ¶
|
|
#class213 | COMPATIBILITY, Actionable |
Freelancer's Guild ¶
|
|
#class214 | COMPATIBILITY, Actionable |
Hero Placeholder ¶
|
|
#class215 | COMPATIBILITY, Actionable |
Quest Guard ¶
|
|
#class216 | COMPATIBILITY, Actionable |
Random Dwelling ¶
|
|
#class219 | COMPATIBILITY, Actionable |
Garrison ¶
|
|
#class220 | COMPATIBILITY, Actionable |
Mine ¶
|
|
#class221 | COMPATIBILITY, Actionable |
Trading Post ¶
|
|
#class222 | COMPATIBILITY |
Clover Field ¶
|
|
#class223 | COMPATIBILITY |
Cursed Ground ¶
|
|
#class224 | COMPATIBILITY |
Evil Fog ¶
|
|
#class225 | COMPATIBILITY |
Favorable Winds ¶
|
|
#class226 | COMPATIBILITY |
Fiery Fields ¶
|
|
#class227 | COMPATIBILITY |
Holy Ground ¶
|
|
#class228 | COMPATIBILITY |
Lucid Pools ¶
|
|
#class229 | COMPATIBILITY |
Magic Clouds ¶
|
|
#class230 | COMPATIBILITY |
Magic Plains ¶
|
|
#class231 | COMPATIBILITY |
Rocklands ¶
|
|
#SK | |||
#sk0 | COMPATIBILITY |
Pathfinding ¶
|
|
#sk1 | COMPATIBILITY |
Archery ¶
|
|
#sk2 | COMPATIBILITY |
Logistics ¶
|
|
#sk3 | COMPATIBILITY |
Scouting ¶
|
|
#sk4 | COMPATIBILITY |
Diplomacy (affects only surrender cost) ¶
|
|
#sk5 | COMPATIBILITY |
Navigation ¶
|
|
#sk6 | COMPATIBILITY |
Leadership ¶
|
|
#sk7 | COMPATIBILITY |
Wisdom ¶
|
|
#sk8 | COMPATIBILITY |
Mysticism ¶
|
|
#sk9 | COMPATIBILITY |
Luck ¶
|
|
#sk10 | COMPATIBILITY |
Ballistics ¶
|
|
#sk11 | COMPATIBILITY |
Eagle Eye ¶
|
|
#sk12 | COMPATIBILITY |
Necromancy ¶
|
|
#sk13 | COMPATIBILITY |
Estates ¶
|
|
#sk14 | COMPATIBILITY |
Fire Magic ¶
|
|
#sk15 | COMPATIBILITY |
Air Magic ¶
|
|
#sk16 | COMPATIBILITY |
Water Magic ¶
|
|
#sk17 | COMPATIBILITY |
Earth Magic ¶
|
|
#sk18 | COMPATIBILITY |
Scholar ¶
|
|
#sk19 | COMPATIBILITY |
Tactics ¶
|
|
#sk20 | COMPATIBILITY |
Artillery ¶
|
|
#sk21 | COMPATIBILITY |
Learning ¶
|
|
#sk22 | COMPATIBILITY |
Offense ¶
|
|
#sk23 | COMPATIBILITY |
Armorer ¶
|
|
#sk24 | COMPATIBILITY |
Intelligence ¶
|
|
#sk25 | COMPATIBILITY |
Sorcery ¶
|
|
#sk26 | COMPATIBILITY |
Resistance ¶
|
|
#sk27 | COMPATIBILITY |
First Aid ¶
|
|
#SP | |||
#sp0 | COMPATIBILITY, L1, Adventure, Water |
Summon Boat ¶
|
|
#sp1 | COMPATIBILITY, L2, Adventure, Water |
Scuttle Boat ¶
|
|
#sp2 | COMPATIBILITY, L2, Adventure, Earth, Water, Fire, Air |
Visions ¶
|
|
#sp3 | COMPATIBILITY, L1, Adventure, Earth |
View Earth ¶
|
|
#sp4 | COMPATIBILITY, L2, Adventure, Air |
Disguise ¶
|
|
#sp5 | COMPATIBILITY, L1, Adventure, Air |
View Air ¶
|
|
#sp6 | COMPATIBILITY, L5, Adventure, Air |
Fly ¶
|
|
#sp7 | COMPATIBILITY, L4, Adventure, Water |
Water Walk ¶
|
|
#sp8 | COMPATIBILITY, L5, Adventure, Air |
Dimension Door ¶
|
|
#sp9 | COMPATIBILITY, L4, Adventure, Earth |
Town Portal ¶
|
|
#sp10 | COMPATIBILITY, L2, Combat, Earth |
Quicksand ¶
|
|
#sp11 | COMPATIBILITY, L3, Combat, Fire |
Land Mine ¶
|
|
#sp12 | COMPATIBILITY, L3, Combat, Earth |
Force Field ¶
|
|
#sp13 | COMPATIBILITY, L2, Combat, Fire |
Fire Wall ¶
|
|
#sp14 | COMPATIBILITY, L3, Combat, Earth |
Earthquake ¶
|
|
#sp15 | COMPATIBILITY, L1, Combat, Earth, Water, Fire, Air |
Magic Arrow ¶
|
|
#sp16 | COMPATIBILITY, L2, Combat, Water |
Ice Bolt ¶
|
|
#sp17 | COMPATIBILITY, L2, Combat, Air |
Lightning Bolt ¶
|
|
#sp18 | COMPATIBILITY, L5, Combat, Earth |
Implosion ¶
|
|
#sp19 | COMPATIBILITY, L4, Combat, Air |
Chain Lightning ¶
|
|
#sp20 | COMPATIBILITY, L3, Combat, Water |
Frost Ring ¶
|
|
#sp21 | COMPATIBILITY, L3, Combat, Fire |
Fireball ¶
|
|
#sp22 | COMPATIBILITY, L4, Combat, Fire |
Inferno ¶
|
|
#sp23 | COMPATIBILITY, L4, Combat, Earth |
Meteor Shower ¶
|
|
#sp24 | COMPATIBILITY, L2, Combat, Earth |
Death Ripple ¶
|
|
#sp25 | COMPATIBILITY, L3, Combat, Air |
Destroy Undead ¶
|
|
#sp26 | COMPATIBILITY, L4, Combat, Fire |
Armageddon ¶
|
|
#sp27 | COMPATIBILITY, L1, Combat, Earth |
Shield ¶
|
|
#sp28 | COMPATIBILITY, L3, Combat, Air |
Air Shield ¶
|
|
#sp29 | COMPATIBILITY, L4, Combat, Fire |
Fire Shield ¶
|
|
#sp30 | COMPATIBILITY, L2, Combat, Air |
Protection from Air ¶
|
|
#sp31 | COMPATIBILITY, L1, Combat, Fire |
Protection from Fire ¶
|
|
#sp32 | COMPATIBILITY, L1, Combat, Water |
Prot. from Water ¶
|
|
#sp33 | COMPATIBILITY, L3, Combat, Earth |
Prot. from Earth ¶
|
|
#sp34 | COMPATIBILITY, L3, Combat, Earth |
Anti-Magic ¶
|
|
#sp35 | COMPATIBILITY, L1, Combat, Water |
Dispel ¶
|
|
#sp36 | COMPATIBILITY, L5, Combat, Air |
Magic Mirror ¶
|
|
#sp37 | COMPATIBILITY, L1, Combat, Water |
Cure ¶
|
|
#sp38 | COMPATIBILITY, L4, Combat, Earth |
Resurrection ¶
|
|
#sp39 | COMPATIBILITY, L3, Combat, Earth |
Animate Dead ¶
|
|
#sp40 | COMPATIBILITY, L5, Combat, Fire |
Sacrifice ¶
|
|
#sp41 | COMPATIBILITY, L1, Combat, Water |
Bless ¶
|
|
#sp42 | COMPATIBILITY, L1, Combat, Fire |
Curse ¶
|
|
#sp43 | COMPATIBILITY, L1, Combat, Fire |
Bloodlust ¶
|
|
#sp44 | COMPATIBILITY, L2, Combat, Air |
Precision ¶
|
|
#sp45 | COMPATIBILITY, L2, Combat, Water |
Weakness ¶
|
|
#sp46 | COMPATIBILITY, L1, Combat, Earth |
Stone Skin ¶
|
|
#sp47 | COMPATIBILITY, L2, Combat, Air |
Disrupting Ray ¶
|
|
#sp48 | COMPATIBILITY, L4, Combat, Water |
Prayer ¶
|
|
#sp49 | COMPATIBILITY, L3, Combat, Water |
Mirth ¶
|
|
#sp50 | COMPATIBILITY, L4, Combat, Earth |
Sorrow ¶
|
|
#sp51 | COMPATIBILITY, L2, Combat, Air |
Fortune ¶
|
|
#sp52 | COMPATIBILITY, L3, Combat, Fire |
Misfortune ¶
|
|
#sp53 | COMPATIBILITY, L1, Combat, Air |
Haste ¶
|
|
#sp54 | COMPATIBILITY, L1, Combat, Earth |
Slow ¶
|
|
#sp55 | COMPATIBILITY, L4, Combat, Fire | ||
#sp56 | COMPATIBILITY, L4, Combat, Fire |
Frenzy ¶
|
|
#sp57 | COMPATIBILITY, L5, Combat, Air |
Titan's Lightning Bolt ¶
|
|
#sp58 | COMPATIBILITY, L4, Combat, Air | ||
#sp59 | COMPATIBILITY, L4, Combat, Fire |
Berserk ¶
|
|
#sp60 | COMPATIBILITY, L3, Combat, Air |
Hypnotize ¶
|
|
#sp61 | COMPATIBILITY, L3, Combat, Water |
Forgetfulness ¶
|
|
#sp62 | COMPATIBILITY, L2, Combat, Fire |
Blind ¶
|
|
#sp63 | COMPATIBILITY, L3, Combat, Water |
Teleport ¶
|
|
#sp64 | COMPATIBILITY, L2, Combat, Water |
Remove Obstacle ¶
|
|
#sp65 | COMPATIBILITY, L4, Combat, Water |
Clone ¶
|
|
#sp66 | COMPATIBILITY, L5, Combat, Fire |
Fire Elemental ¶
|
|
#sp67 | COMPATIBILITY, L5, Combat, Earth |
Earth Elemental ¶
|
|
#sp68 | COMPATIBILITY, L5, Combat, Water |
Water Elemental ¶
|
|
#sp69 | COMPATIBILITY, L5, Combat, Air |
Air Elemental ¶
|
|
COMPATIBILITY, L3, Creature |
Stone Gaze ¶
|
||
COMPATIBILITY, Creature |
Poison ¶
|
||
COMPATIBILITY, Creature |
Bind ¶
|
||
COMPATIBILITY, L2, Creature |
Disease ¶
|
||
COMPATIBILITY, L4, Creature |
Paralyze ¶
|
||
COMPATIBILITY, L5, Creature |
Age ¶
|
||
COMPATIBILITY, Creature |
Death Cloud ¶
|
||
COMPATIBILITY, Creature |
Thunderbolt ¶
|
||
COMPATIBILITY, Creature |
Dispel Helpful Spells ¶
|
||
COMPATIBILITY, Creature |
Death Stare ¶
|
||
COMPATIBILITY, Creature |
Acid breath ¶
|