Added ability to clear all encounter zones, and to set the avatar tile.

This commit is contained in:
Martin Haye 2016-07-10 17:18:03 -07:00
parent 31bf216f6e
commit be40d8f4f4
7 changed files with 116 additions and 7 deletions

View File

@ -68,6 +68,7 @@
<block type="events_set_sky"></block>
<block type="events_set_ground"></block>
<block type="events_add_encounter_zone"></block>
<block type="events_clr_encounter_zones"></block>
<block type="events_start_encounter"></block>
</category>
<category name="Text">
@ -108,6 +109,7 @@
<category name="Graphics">
<block type="graphics_set_portrait"></block>
<block type="graphics_clr_portrait"></block>
<block type="graphics_set_avatar"></block>
</category>
<category name="Sound">
</category>

View File

@ -391,6 +391,28 @@ if (typeof Mythos === "undefined") {
this.setTooltip('Add an encounter zone');
}
};
Blockly.Blocks['events_add_encounter_zone'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
this.setColour(54);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendDummyInput()
.appendField("Add encounter zone for enemy code")
.appendField(new Blockly.FieldTextInput(""), "CODE")
.appendField('at X=')
.appendField(new Blockly.FieldTextInput("0"), "X")
.appendField('Y=')
.appendField(new Blockly.FieldTextInput("0"), "Y")
.appendField('with max dist')
.appendField(new Blockly.FieldTextInput("0"), "MAXDIST")
.appendField('(0=inf), and chance')
.appendField(new Blockly.FieldTextInput("0.0"), "CHANCE")
.appendField('%');
this.setOutput(false);
this.setTooltip('Add an encounter zone');
}
};
Blockly.Blocks['events_start_encounter'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
@ -404,6 +426,18 @@ if (typeof Mythos === "undefined") {
this.setTooltip('Start an encounter');
}
};
Blockly.Blocks['events_clr_encounter_zones'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
this.setColour(54);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendDummyInput()
.appendField("Clear encounter zones");
this.setOutput(false);
this.setTooltip('Clear all encounter zones (for no encounters, or to add new zones)');
}
};
Blockly.Blocks['text_window'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
@ -721,6 +755,19 @@ if (typeof Mythos === "undefined") {
this.setTooltip('Display the given portait image (by name)');
}
};
Blockly.Blocks['graphics_set_avatar'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);
this.setColour(54);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendDummyInput()
.appendField("Set avatar to tile ")
.appendField(new Blockly.FieldTextInput(""), "NAME");
this.setOutput(false);
this.setTooltip('Use the given tile as the avatar image (by name)');
}
};
Blockly.Blocks['graphics_clr_portrait'] = {
init: function () {
this.setHelpUrl(Mythos.helpUrl);

View File

@ -51,6 +51,7 @@ class PackPartitions
def maps3D = [:] // map name to map.num, map.buf
def tiles = [:] // tile id to tile.buf
def tileSets = [:] // tileset name to tileset.num, tileset.buf
def avatars = [:] // avatar tile name to tile num (within the special tileset)
def textures = [:] // img name to img.num, img.buf
def frames = [:] // img name to img.num, img.buf
def portraits = [:] // img name to img.num, img.buf
@ -798,8 +799,9 @@ class PackPartitions
def name = tile.@name
def id = tile.@id
def data = tiles[id]
if (name.equalsIgnoreCase("Avatars1 - 2D")) {
if (name.toLowerCase().contains("avatar")) {
def num = tileMap.size()
avatars[name.toLowerCase().replaceAll(/\s*-\s*[23][dD]\s*/, "")] = num
tileIds.add(id)
tileMap[id] = num
data.flip() // crazy stuff to append one buffer to another
@ -807,7 +809,7 @@ class PackPartitions
nFound += 1
}
}
assert nFound == 1
assert nFound >= 1 : "Need at least one 'Avatar' tile."
tileSets[setName] = [num:setNum, buf:buf, tileMap:tileMap, tileIds:tileIds]
return [setNum, tileMap]
@ -2791,6 +2793,8 @@ end
packSetGround(blk); break
case 'events_add_encounter_zone':
packAddEncounterZone(blk); break
case 'events_clr_encounter_zones':
packClrEncounterZones(blk); break
case 'events_start_encounter':
packStartEncounter(blk); break
case 'events_teleport':
@ -2801,6 +2805,8 @@ end
packSetPortrait(blk); break
case 'graphics_clr_portrait':
packClrPortrait(blk); break
case 'graphics_set_avatar':
packSetAvatar(blk); break
case 'variables_set':
packVarSet(blk); break
case 'interaction_give_item':
@ -3093,6 +3099,17 @@ end
outIndented("clearPortrait()\n")
}
def packSetAvatar(blk)
{
def tileName = getSingle(blk.field, 'NAME').text()
def tile = avatars[tileName.toLowerCase()]
if (!tile) {
println(avatars.keySet())
throw new Exception("Can't find avatar '$tileName'")
}
outIndented("setAvatar(${tile})\n")
}
def packSetSky(blk)
{
def color = getSingle(blk.field, 'COLOR').text().toInteger()
@ -3124,6 +3141,11 @@ end
outIndented("addEncounterZone(${escapeString(code)}, $x, $y, $maxDist, $chance)\n")
}
def packClrEncounterZones(blk)
{
outIndented("clearEncounterZones()\n")
}
def packStartEncounter(blk)
{
assert blk.field.size() == 1

View File

@ -20,11 +20,11 @@ import gamelib
predef beep, showParty, mmgr, setWindow1, setWindow2, setWindow3, reboot, brk
predef encodeDice, rollDice, setPlural, getStringResponse
predef streqi, fatal, pause, tossStrings
predef addEncounterZone, showMapName, setMapWindow, makeModifier
predef addEncounterZone, clearEncounterZones, showMapName, setMapWindow, makeModifier
predef addGold, countGold, payGold
predef calcPlayerArmor, diskActivity, rdkey, initHeap, scriptCombat
predef giveItemToPlayer, takeItemFromPlayer, playerHasItem, getStat, setStat
predef setGameFlag, getGameFlag
predef setGameFlag, getGameFlag, setAvatar
// Shared string constants

View File

@ -205,6 +205,10 @@ asm getMapScript // params: none
+asmPlasm 0
jmp $601E
end
export asm setAvatar // params: tile number (in the global tileset)
+asmPlasm 1
jmp $6021
end
///////////////////////////////////////////////////////////////////////////////////////////////////
asm readAuxByte // params: ptr; ret: char
@ -1922,6 +1926,12 @@ export def addEncounterZone(code, x, y, dist, chance)
addToList(@global=>p_encounterZones, p)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
export def clearEncounterZones()
global=>p_encounterZones = NULL
mmgr(HEAP_COLLECT, 0)
end
///////////////////////////////////////////////////////////////////////////////////////////////////
// Compare two strings for equality, ignoring case.
export def streqi(a, b)

View File

@ -31,6 +31,7 @@ start:
jmp pl_render ; params: none
jmp pl_texControl ; params: 0=unload textures, 1=load textures
jmp pl_getScripts ; params: none
jmp pl_setAvatar ; params: A=tile number
; Conditional assembly flags
DOUBLE_BUFFER = 1 ; whether to double-buffer
@ -2058,6 +2059,14 @@ pl_getScripts: !zone {
rts
}
;-------------------------------------------------------------------------------
; Called by PLASMA code to set the avatar tile. Ignored by 3D engine.
; Parameters: A = tile number
; Returns: Nothing
pl_setAvatar: !zone {
rts
}
;-------------------------------------------------------------------------------
; The real action
pl_initMap: !zone

View File

@ -100,7 +100,8 @@ ORIGIN_Y = $A6 ; 16-bit origin for Y (add REL_Y to get avatar's global map Y)
AVATAR_DIR = $A8 ; direction (0-15, though only 0,4,8,12 are valid)
PLASMA_X = $A9 ; save for PLASMA's X reg
SCRIPTS_ID = $AA ; Module number of scripts
next_zp = $AB
PLAYER_TILE = $AB ; Tile number to show for player avatar
next_zp = $AC
;----------------------------------------------------------------------
; Here are the entry points for PLASMA code. Identical API for 2D and 3D.
@ -115,6 +116,7 @@ next_zp = $AB
JMP pl_render ; params: none
JMP pl_texControl ; params: 1=load, 0=unload
JMP pl_getScripts ; params: none
JMP pl_setAvatarTile ; params: A=tile number
;----------------------------------------------------------------------
; >> START LOADING MAP SECTIONS
@ -598,7 +600,12 @@ CROSS_WEST
+loadSection SW_MAP_LOC
jmp FINISH_MAP_LOAD
;----------------------------------------------------------------------
; >> SET PLAYER TILE (A = tile)
; >> pl_setAvatarTile
; SET PLAYER'S AVATAR TILE (A = tile)
pl_setAvatarTile:
STA PLAYER_TILE
RTS
;----------------------------------------------------------------------
; >> SET NPC TILE (A = tile, X,Y = coordinates in section)
;----------------------------------------------------------------------
@ -844,8 +851,16 @@ ROW_OFFSET = 3
STA AVATAR_SECTION
LDA DRAW_SECTION + 1
STA AVATAR_SECTION + 1
LDY GLOBAL_TILESET_LOC ; first tile in global tileset is avatar
LDA PLAYER_TILE ; get tile number
ASL ; 32 bytes per tile
ASL
ASL
ASL
ASL
ADC GLOBAL_TILESET_LOC
TAY
LDA GLOBAL_TILESET_LOC+1
ADC #0
BNE .store_src ; always taken
.notAvatar
LDA DRAW_SECTION+1
@ -966,6 +981,10 @@ pl_initMap: !zone
+crout
}
; Start with default avatar until overridden
LDA #0
STA PLAYER_TILE
; Record the facing direction for later use
JSR pl_setDir