Compare commits

...

11 Commits

Author SHA1 Message Date
Zukero
4a4cf36c02 New game objects methods available in scripting language. 2013-12-15 23:17:27 +01:00
Zukero
5886e746b5 Added player.base.ac & player.base.bc variables in scripting language. 2013-12-01 15:59:59 +01:00
Zukero
fc97efdf75 Engine updates.
New in-game hooks : item.onEquip & item.onUnequip
Many new variables accessible in scripting language :
- player.base.[maxAP, maxHP, ad.min, ad.max, equipCost, moveCost,
useCost]
- actor.[hp.cur, hp.max, ap.cur, ap.max, ad.min, ad.max]
2013-12-01 15:56:44 +01:00
Zukero
0d7ab1a710 Forgot to include new package to index in last commit... 2013-11-20 23:21:15 +01:00
Zukero
43e374e5d3 Items usage effects can be impacted (AP, HP), need to add some kind of
array support in the scripting language to add impact on actor
conditions.
ActorConditions can have scripted effects.
New values in the debug data to test it all ! An actor condition makes
your potions give twice as much HP !
2013-11-19 23:54:28 +01:00
Zukero
05dae1bc74 New primitive operator : '%' used for string concatenation. Works using
.toString(), so it's rather type independant.
New in-game hook : item.onUse. Unfinished because it can't impact te
effects of the item, only add more effects (positive or negative)
New local variable scope awareness system. No-more "all-purpose"
Hashmap, but a dedicated object.
2013-11-18 23:26:13 +01:00
Zukero
f592207470 New in-game hook : player.statsUpdated to be used by Actor Conditions,
items (and skills in the future) to impact player's stats (AC, BC, AD,
HP...)
Enhanced local variables handling by script parser. Now scope-aware.
Implemented the public vs private scripts system : some game objects
have private scripts, that get executed only when the object itself is
the cause of the event. Included example is a special case :
player.statsUpdated runs the player's actor condtion and equiped items
private scripts that trigger on plyaer.statsUpdated.
Added scripts reference parsing in JSON parsers, hooked to items and
actor conditions.
2013-11-16 17:19:05 +01:00
Zukero
8a62fb847f Rebased on latest upstream master 2013-11-04 20:49:56 +01:00
Zukero
0028d361c6 Almost full engine rewrite. Only grammar & in-game hooking system kept.
* No script text interpreter anymore
* Scripts are statically compiled to an object AST
* Engine can evaluate the script's AST without reflection, and minimum
casting
* Script local variables are preallocated, but without scope awareness
yet (declare them all at top level scope for max efficiency)
* While loop added
* Boolean AND and OR added.
* Boolean constants true & false added.
* String constants can be used as local variables.
2013-11-04 20:47:50 +01:00
Zukero
57a88f437f Engine updates
* Slightly more efficient interpreter
* ScriptEngine now implements existing listener interface instead of
in-code hooks
Language updates :
* actor references now expose the addActorCondition &
clearActorCondition methods
2013-11-04 20:47:49 +01:00
Zukero
9a8e7d3cb7 First working version of my scripting engine.
* Only two trigger types : map.onEnter & map.onLeave
* Very limited field access : player.ac; player.bc & map.outdoor
However, it is integrated & tested.
2013-11-04 20:44:12 +01:00
69 changed files with 9284 additions and 33 deletions

View File

@@ -0,0 +1,24 @@
[
{
"id": "chaotic_grip",
"iconID": "actorconditions_1:96",
"name": "Chaotic grip",
"category": "mental",
"abilityEffect": {
"increaseBlockChance": -10,
"increaseDamageResistance": -1
}
},
{
"id": "scripted_potion_efficiency",
"iconID": "actorconditions_1:89",
"name": "Potion Scripter",
"category": "mental",
"isPositive" : 1,
"scripts": [
{
"name": "scripted_potion_boost"
}
]
}
]

View File

@@ -94,6 +94,14 @@
"max": 1 "max": 1
}, },
"chance": 100 "chance": 100
},
{
"itemID": "health_minor",
"quantity": {
"min": 10,
"max": 10
},
"chance": 100
} }
] ]
}, },

View File

@@ -3,7 +3,7 @@
"id": "debug_dagger1", "id": "debug_dagger1",
"iconID": "items_weapons:20", "iconID": "items_weapons:20",
"name": "Black heart dagger", "name": "Black heart dagger",
"category": 0, "category": "dagger",
"displaytype": "extraordinary", "displaytype": "extraordinary",
"hasManualPrice": 1, "hasManualPrice": 1,
"baseMarketCost": 6, "baseMarketCost": 6,
@@ -22,7 +22,7 @@
"id": "debug_ring1", "id": "debug_ring1",
"iconID": "items_jewelry:4", "iconID": "items_jewelry:4",
"name": "Black heart ring", "name": "Black heart ring",
"category": 7, "category": "ring",
"displaytype": "quest", "displaytype": "quest",
"hasManualPrice": 1, "hasManualPrice": 1,
"baseMarketCost": 3, "baseMarketCost": 3,
@@ -32,13 +32,18 @@
"min": 10, "min": 10,
"max": 10 "max": 10
} }
} },
"privateScripts": [
{
"name": "player_boostAC"
}
]
}, },
{ {
"id": "shadow_slayer", "id": "shadow_slayer",
"iconID": "items_weapons:60", "iconID": "items_weapons:60",
"name": "Shadow of the slayer", "name": "Shadow of the slayer",
"category": 0, "category": "ssword",
"displaytype": "extraordinary", "displaytype": "extraordinary",
"hasManualPrice": 1, "hasManualPrice": 1,
"baseMarketCost": 0, "baseMarketCost": 0,
@@ -59,5 +64,19 @@
"max": 1 "max": 1
} }
} }
},
{
"id": "health_minor",
"iconID": "items_consumables:35",
"name": "Minor vial of health",
"category": "pot",
"hasManualPrice": 1,
"baseMarketCost": 5,
"useEffect": {
"increaseCurrentHP": {
"min": 1,
"max": 1
}
}
} }
] ]

View File

@@ -0,0 +1,37 @@
"map_boostAC" map.onEnter [
player.addActorCondition("scripted_potion_efficiency",5, 2, 50);
]
"map_unboostAC" map.onLeave [
player.clearActorCondition("scripted_potion_efficiency", 50);
]
"player_boostAC" player.statsUpdated [
player.ac = player.ac * 1.5;
][Boosts your AC by 50% of current value.]
"useless_one" map.onEnter [
num a = 5;
if (a < 3) {
bool b = true;
num c = 2;
} else if (a == 5 ) {
string d = "TestString";
} else {
num b = 12.3;
bool c = true;
while (c) {
a = a - 1;
if (a == 0) {
c = false;
}
}
}
][Simple test of local variables scoping]
"scripted_potion_boost" item.onUse [
if (item.category == "pot") {
item.reward.hp.max = item.reward.hp.max * 2;
item.reward.hp.min = item.reward.hp.min * 2;
}
][Doubles the health gained by drinking potions]

View File

@@ -638,4 +638,8 @@
<item>@xml/tradehouse1</item> <item>@xml/tradehouse1</item>
<item>@xml/tradehouse0a</item> <item>@xml/tradehouse0a</item>
</array> </array>
<array name="loadresource_scripts">
</array>
</resources> </resources>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<array name="loadresource_items_debug"> <array name="loadresource_items_debug">
<item>@raw/itemlist_money</item> <item>@raw/itemlist_money</item>
<item>@raw/itemlist_weapons</item> <item>@raw/itemlist_weapons</item>
@@ -25,5 +26,14 @@
<array name="loadresource_maps_debug"> <array name="loadresource_maps_debug">
<item>@xml/debugmap</item> <item>@xml/debugmap</item>
<item>@xml/debugmap_scripts</item>
</array>
<array name="loadresource_scripts_debug">
<item>@raw/scripts_debug</item>
</array>
<array name="loadresource_actorconditions_debug">
<item>@raw/actorconditions_debug</item>
</array> </array>
</resources> </resources>

View File

@@ -161,7 +161,7 @@
</object> </object>
<object name="place2" type="mapchange" x="192" y="256" width="32" height="32"> <object name="place2" type="mapchange" x="192" y="256" width="32" height="32">
<properties> <properties>
<property name="map" value="debugmap"/> <property name="map" value="debugmap_scripts"/>
<property name="place" value="place1"/> <property name="place" value="place1"/>
</properties> </properties>
</object> </object>

View File

@@ -0,0 +1,215 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="10" height="10" tilewidth="32" tileheight="32">
<properties>
<property name="outside" value="0"/>
<property name="script" value="map_boostAC;map_unboostAC;useless_one"/>
</properties>
<tileset firstgid="1" name="map_bed_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_bed_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="129" name="map_border_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_border_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="257" name="map_bridge_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_bridge_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="385" name="map_bridge_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_bridge_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="513" name="map_broken_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_broken_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="641" name="map_cavewall_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_cavewall_1.png" width="576" height="192"/>
</tileset>
<tileset firstgid="749" name="map_cavewall_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_cavewall_2.png" width="576" height="192"/>
</tileset>
<tileset firstgid="857" name="map_cavewall_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_cavewall_3.png" width="576" height="192"/>
</tileset>
<tileset firstgid="965" name="map_cavewall_4" tilewidth="32" tileheight="32">
<image source="../drawable/map_cavewall_4.png" width="576" height="192"/>
</tileset>
<tileset firstgid="1073" name="map_chair_table_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_chair_table_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1201" name="map_chair_table_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_chair_table_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1329" name="map_crate_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_crate_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1457" name="map_cupboard_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_cupboard_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1585" name="map_curtain_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_curtain_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1713" name="map_entrance_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_entrance_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1841" name="map_entrance_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_entrance_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="1969" name="map_fence_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_fence_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2097" name="map_fence_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_fence_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2225" name="map_fence_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_fence_3.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2353" name="map_fence_4" tilewidth="32" tileheight="32">
<image source="../drawable/map_fence_4.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2481" name="map_ground_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2609" name="map_ground_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2737" name="map_ground_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_3.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2865" name="map_ground_4" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_4.png" width="512" height="256"/>
</tileset>
<tileset firstgid="2993" name="map_ground_5" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_5.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3121" name="map_ground_6" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_6.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3249" name="map_ground_7" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_7.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3377" name="map_ground_8" tilewidth="32" tileheight="32">
<image source="../drawable/map_ground_8.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3505" name="map_house_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_house_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3633" name="map_house_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_house_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3761" name="map_indoor_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_indoor_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="3889" name="map_indoor_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_indoor_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4017" name="map_kitchen_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_kitchen_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4145" name="map_outdoor_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_outdoor_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4273" name="map_pillar_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_pillar_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4401" name="map_pillar_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_pillar_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4529" name="map_plant_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_plant_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4657" name="map_plant_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_plant_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4785" name="map_rock_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_rock_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="4913" name="map_rock_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_rock_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="5041" name="map_roof_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_roof_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="5169" name="map_roof_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_roof_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="5297" name="map_roof_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_roof_3.png" width="512" height="256"/>
</tileset>
<tileset firstgid="5425" name="map_shop_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_shop_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="5553" name="map_sign_ladder_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_sign_ladder_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="5681" name="map_table_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_table_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="5809" name="map_trail_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_trail_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="5937" name="map_transition_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_transition_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="6065" name="map_transition_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_transition_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="6193" name="map_transition_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_transition_3.png" width="512" height="256"/>
</tileset>
<tileset firstgid="6321" name="map_transition_4" tilewidth="32" tileheight="32">
<image source="../drawable/map_transition_4.png" width="512" height="256"/>
</tileset>
<tileset firstgid="6449" name="map_tree_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_tree_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="6577" name="map_tree_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_tree_2.png" width="512" height="256"/>
</tileset>
<tileset firstgid="6705" name="map_wall_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_wall_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="6833" name="map_wall_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_wall_2.png" width="480" height="256"/>
</tileset>
<tileset firstgid="6953" name="map_wall_3" tilewidth="32" tileheight="32">
<image source="../drawable/map_wall_3.png" width="480" height="256"/>
</tileset>
<tileset firstgid="7073" name="map_wall_4" tilewidth="32" tileheight="32">
<image source="../drawable/map_wall_4.png" width="480" height="256"/>
</tileset>
<tileset firstgid="7193" name="map_window_1" tilewidth="32" tileheight="32">
<image source="../drawable/map_window_1.png" width="512" height="256"/>
</tileset>
<tileset firstgid="7321" name="map_window_2" tilewidth="32" tileheight="32">
<image source="../drawable/map_window_2.png" width="512" height="256"/>
</tileset>
<layer name="Ground" width="10" height="10">
<data encoding="base64" compression="zlib">
eJxtkNEJADEIQ7vAjasbmA2yb3ugEIIfofWpSWl859RTLsJTyP0/2YxSQ3ZKGLqGeZbMDqN4hjHKHCRDvTcGy3AP79P2hsH6ueTOm+dvhqWwshmIovsXDeQ4MA==
</data>
</layer>
<layer name="Objects" width="10" height="10">
<data encoding="base64" compression="zlib">
eJxjYBgFgwkAAAGQAAE=
</data>
</layer>
<layer name="Above" width="10" height="10">
<data encoding="base64" compression="zlib">
eJxjYBgFgwkAAAGQAAE=
</data>
</layer>
<layer name="Walkable" width="10" height="10">
<data encoding="base64" compression="zlib">
eJxjYBgFgwkAAAGQAAE=
</data>
</layer>
<objectgroup name="Mapevents" width="10" height="10">
<object name="place1" type="mapchange" x="0" y="0" width="32" height="320">
<properties>
<property name="map" value="debugmap"/>
<property name="place" value="place2"/>
</properties>
</object>
</objectgroup>
<objectgroup name="Spawn" width="10" height="10"/>
<objectgroup name="Keys" width="10" height="10"/>
<objectgroup name="Replace" width="10" height="10"/>
</map>

View File

@@ -8,6 +8,7 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.ModelContainer; import com.gpl.rpg.AndorsTrail.model.ModelContainer;
import com.gpl.rpg.AndorsTrail.resource.ResourceLoader; import com.gpl.rpg.AndorsTrail.resource.ResourceLoader;
import com.gpl.rpg.AndorsTrail.savegames.Savegames; import com.gpl.rpg.AndorsTrail.savegames.Savegames;
import com.gpl.rpg.AndorsTrail.scripting.ScriptEngine;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@@ -31,6 +32,7 @@ public final class WorldSetup {
public WorldSetup(WorldContext world, ControllerContext controllers, Context androidContext) { public WorldSetup(WorldContext world, ControllerContext controllers, Context androidContext) {
this.world = world; this.world = world;
this.controllers = controllers; this.controllers = controllers;
ScriptEngine.initializeEngine(controllers, world);
this.androidContext = new WeakReference<Context>(androidContext); this.androidContext = new WeakReference<Context>(androidContext);
} }

View File

@@ -275,7 +275,7 @@ public final class MainActivity
public void onPlayerMoved(Coord newPosition, Coord previousPosition) { } public void onPlayerMoved(Coord newPosition, Coord previousPosition) { }
@Override @Override
public void onPlayerEnteredNewMap(PredefinedMap map, Coord p) { } public void onPlayerEnteredNewMap(PredefinedMap map, Coord p, PredefinedMap oldMap) { }
@Override @Override
public void onCombatStarted() { public void onCombatStarted() {

View File

@@ -21,6 +21,8 @@ import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea; import com.gpl.rpg.AndorsTrail.model.map.MonsterSpawnArea;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap; import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection; import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptEngine;
import java.util.ArrayList; import java.util.ArrayList;
@@ -36,16 +38,14 @@ public final class ActorStatsController {
this.world = world; this.world = world;
} }
public void addConditionsFromEquippedItem(Player player, ItemType itemType) { public void addConditionsFromEquippedItem(Player player, ItemTraits_OnEquip equipEffects) {
ItemTraits_OnEquip equipEffects = itemType.effects_equip;
if (equipEffects == null) return; if (equipEffects == null) return;
if (equipEffects.addedConditions == null) return; if (equipEffects.addedConditions == null) return;
for (ActorConditionEffect e : equipEffects.addedConditions) { for (ActorConditionEffect e : equipEffects.addedConditions) {
applyActorCondition(player, e, ActorCondition.DURATION_FOREVER); applyActorCondition(player, e, ActorCondition.DURATION_FOREVER);
} }
} }
public void removeConditionsFromUnequippedItem(Player player, ItemType itemType) { public void removeConditionsFromUnequippedItem(Player player, ItemTraits_OnEquip equipEffects) {
ItemTraits_OnEquip equipEffects = itemType.effects_equip;
if (equipEffects == null) return; if (equipEffects == null) return;
if (equipEffects.addedConditions == null) return; if (equipEffects.addedConditions == null) return;
for (ActorConditionEffect e : equipEffects.addedConditions) { for (ActorConditionEffect e : equipEffects.addedConditions) {
@@ -197,6 +197,7 @@ public final class ActorStatsController {
controllers.skillController.applySkillEffects(player); controllers.skillController.applySkillEffects(player);
applyEffectsFromCurrentConditions(player); applyEffectsFromCurrentConditions(player);
ItemController.recalculateHitEffectsFromWornItems(player); ItemController.recalculateHitEffectsFromWornItems(player);
ScriptEngine.instance.onPlayerStatsUpdate(player);
capActorHealthAtMax(player); capActorHealthAtMax(player);
capActorAPAtMax(player); capActorAPAtMax(player);
} }
@@ -332,7 +333,7 @@ public final class ActorStatsController {
} }
} }
private void rollForConditionEffect(Actor actor, ActorConditionEffect conditionEffect) { public void rollForConditionEffect(Actor actor, ActorConditionEffect conditionEffect) {
int chanceRollBias = 0; int chanceRollBias = 0;
if (actor.isPlayer) chanceRollBias = SkillController.getActorConditionEffectChanceRollBias(conditionEffect, (Player) actor); if (actor.isPlayer) chanceRollBias = SkillController.getActorConditionEffectChanceRollBias(conditionEffect, (Player) actor);

View File

@@ -10,6 +10,9 @@ import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits;
import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.*; import com.gpl.rpg.AndorsTrail.model.item.*;
import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry; import com.gpl.rpg.AndorsTrail.model.item.ItemContainer.ItemEntry;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptEngine;
import com.gpl.rpg.AndorsTrail.scripting.proxyobjects.Item;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@@ -49,12 +52,23 @@ public final class ItemController {
} }
player.inventory.setItemTypeInWearSlot(slot, type); player.inventory.setItemTypeInWearSlot(slot, type);
controllers.actorStatsController.addConditionsFromEquippedItem(player, type);
//Item public scripts activation
int scriptsCount = type.scripts == null ? 0 : type.scripts.length;
slot.slotScripts = new Script[scriptsCount];
while (scriptsCount-- >= 0) {
slot.slotScripts[scriptsCount] = ScriptEngine.instantiateScript(type.scripts[scriptsCount]);
ScriptEngine.instance.activateScript(slot.slotScripts[scriptsCount]);
}
Item item = new Item(type, null, type.effects_equip);
ScriptEngine.instance.onItemEquip(item, slot);
controllers.actorStatsController.addConditionsFromEquippedItem(player, item.reward.toEquipEffect());
controllers.actorStatsController.recalculatePlayerStats(player); controllers.actorStatsController.recalculatePlayerStats(player);
} }
public void unequipSlot(ItemType type, Inventory.WearSlot slot) { public void unequipSlot(ItemType type, Inventory.WearSlot slot) {
if (!type.isEquippable()) return; if (!type.isEquippable()) return; // WTF ? Useless ? Checkable two lines below by acquiring ItemType from slot, and removing it from signature...
final Player player = world.model.player; final Player player = world.model.player;
if (player.inventory.isEmptySlot(slot)) return; if (player.inventory.isEmptySlot(slot)) return;
@@ -72,7 +86,16 @@ public final class ItemController {
if (removedItemType == null) return; if (removedItemType == null) return;
player.inventory.addItem(removedItemType); player.inventory.addItem(removedItemType);
player.inventory.setItemTypeInWearSlot(slot, null); player.inventory.setItemTypeInWearSlot(slot, null);
controllers.actorStatsController.removeConditionsFromUnequippedItem(player, removedItemType);
Item item = new Item(removedItemType, null, removedItemType.effects_equip);
ScriptEngine.instance.onItemUnequip(item, slot);
controllers.actorStatsController.removeConditionsFromUnequippedItem(player, removedItemType.effects_equip);
//Item public scripts deactivation
for (Script s : slot.slotScripts) {
ScriptEngine.instance.deactivateScript(s);
}
slot.slotScripts = null;
} }
public void useItem(ItemType type) { public void useItem(ItemType type) {
@@ -85,9 +108,12 @@ public final class ItemController {
if (!player.inventory.removeItem(type.id, 1)) return; if (!player.inventory.removeItem(type.id, 1)) return;
controllers.actorStatsController.applyUseEffect(player, null, type.effects_use); //Let the scripting work on a copy of the effects, not altering the definition of the objects, only its effects.
Item scriptProxyItem = new Item(type, type.effects_use, null);
ScriptEngine.instance.onItemUse(scriptProxyItem);
controllers.actorStatsController.applyUseEffect(player, null, scriptProxyItem.reward.toUseEffect());
world.model.statistics.addItemUsage(type); world.model.statistics.addItemUsage(type);
//TODO: provide feedback that the item has been used. //TODO: provide feedback that the item has been used.
//context.mainActivity.message(androidContext.getResources().getString(R.string.inventory_item_used, type.name)); //context.mainActivity.message(androidContext.getResources().getString(R.string.inventory_item_used, type.name));
} }

View File

@@ -12,6 +12,8 @@ import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.Loot; import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.model.map.*; import com.gpl.rpg.AndorsTrail.model.map.*;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection; import com.gpl.rpg.AndorsTrail.resource.tiles.TileCollection;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptEngine;
import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.L; import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.TimedMessageTask; import com.gpl.rpg.AndorsTrail.util.TimedMessageTask;
@@ -31,10 +33,11 @@ public final class MovementController implements TimedMessageTask.Callback {
public void placePlayerAsyncAt(final MapObject.MapObjectType objectType, final String mapName, final String placeName, final int offset_x, final int offset_y) { public void placePlayerAsyncAt(final MapObject.MapObjectType objectType, final String mapName, final String placeName, final int offset_x, final int offset_y) {
AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
PredefinedMap oldMap;
@Override @Override
protected Void doInBackground(Void... arg0) { protected Void doInBackground(Void... arg0) {
stopMovement(); stopMovement();
oldMap = world.model.currentMap;
placePlayerAt(controllers.getResources(), objectType, mapName, placeName, offset_x, offset_y); placePlayerAt(controllers.getResources(), objectType, mapName, placeName, offset_x, offset_y);
return null; return null;
@@ -44,7 +47,7 @@ public final class MovementController implements TimedMessageTask.Callback {
protected void onPostExecute(Void result) { protected void onPostExecute(Void result) {
super.onPostExecute(result); super.onPostExecute(result);
stopMovement(); stopMovement();
playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position); playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position, oldMap);
controllers.gameRoundController.resume(); controllers.gameRoundController.resume();
} }
@@ -91,8 +94,10 @@ public final class MovementController implements TimedMessageTask.Callback {
public void prepareMapAsCurrentMap(PredefinedMap newMap, Resources res, boolean spawnMonsters) { public void prepareMapAsCurrentMap(PredefinedMap newMap, Resources res, boolean spawnMonsters) {
final ModelContainer model = world.model; final ModelContainer model = world.model;
model.currentMap = newMap; model.currentMap = newMap;
cacheCurrentMapData(res, newMap); cacheCurrentMapData(res, newMap);
//Apply replacements before spawning, so that MonsterSpawnArea's isActive variable is up to date. //Apply replacements before spawning, so that MonsterSpawnArea's isActive variable is up to date.
controllers.mapController.applyCurrentMapReplacements(res, false); controllers.mapController.applyCurrentMapReplacements(res, false);
if (spawnMonsters) { if (spawnMonsters) {
@@ -239,8 +244,9 @@ public final class MovementController implements TimedMessageTask.Callback {
} }
public void respawnPlayer(Resources res) { public void respawnPlayer(Resources res) {
PredefinedMap oldMap = world.model.currentMap;
placePlayerAt(res, MapObject.MapObjectType.rest, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0); placePlayerAt(res, MapObject.MapObjectType.rest, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0);
playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position); playerMovementListeners.onPlayerEnteredNewMap(world.model.currentMap, world.model.player.position, oldMap);
} }
public void respawnPlayerAsync() { public void respawnPlayerAsync() {
placePlayerAsyncAt(MapObject.MapObjectType.rest, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0); placePlayerAsyncAt(MapObject.MapObjectType.rest, world.model.player.getSpawnMap(), world.model.player.getSpawnPlace(), 0, 0);

View File

@@ -5,5 +5,5 @@ import com.gpl.rpg.AndorsTrail.util.Coord;
public interface PlayerMovementListener { public interface PlayerMovementListener {
void onPlayerMoved(Coord newPosition, Coord previousPosition); void onPlayerMoved(Coord newPosition, Coord previousPosition);
void onPlayerEnteredNewMap(PredefinedMap map, Coord p); void onPlayerEnteredNewMap(PredefinedMap map, Coord p, PredefinedMap oldMap);
} }

View File

@@ -10,8 +10,8 @@ public final class PlayerMovementListeners extends ListOfListeners<PlayerMovemen
@Override public void call(PlayerMovementListener listener, Coord newPosition, Coord previousPosition) { listener.onPlayerMoved(newPosition, previousPosition); } @Override public void call(PlayerMovementListener listener, Coord newPosition, Coord previousPosition) { listener.onPlayerMoved(newPosition, previousPosition); }
}; };
private final Function2<PlayerMovementListener, PredefinedMap, Coord> onPlayerEnteredNewMap = new Function2<PlayerMovementListener, PredefinedMap, Coord>() { private final Function3<PlayerMovementListener, PredefinedMap, Coord, PredefinedMap> onPlayerEnteredNewMap = new Function3<PlayerMovementListener, PredefinedMap, Coord, PredefinedMap>() {
@Override public void call(PlayerMovementListener listener, PredefinedMap map, Coord p) { listener.onPlayerEnteredNewMap(map, p); } @Override public void call(PlayerMovementListener listener, PredefinedMap map, Coord p, PredefinedMap oldMap) { listener.onPlayerEnteredNewMap(map, p, oldMap); }
}; };
@Override @Override
@@ -20,7 +20,7 @@ public final class PlayerMovementListeners extends ListOfListeners<PlayerMovemen
} }
@Override @Override
public void onPlayerEnteredNewMap(PredefinedMap map, Coord p) { public void onPlayerEnteredNewMap(PredefinedMap map, Coord p, PredefinedMap oldMap) {
callAllListeners(this.onPlayerEnteredNewMap, map, p); callAllListeners(this.onPlayerEnteredNewMap, map, p, oldMap);
} }
} }

View File

@@ -1,6 +1,8 @@
package com.gpl.rpg.AndorsTrail.model.ability; package com.gpl.rpg.AndorsTrail.model.ability;
import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptEngine;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -13,6 +15,9 @@ public final class ActorCondition {
public final ActorConditionType conditionType; public final ActorConditionType conditionType;
public int magnitude; public int magnitude;
public int duration; public int duration;
public Script[] scripts;
public Script[] private_scripts;
public ActorCondition( public ActorCondition(
ActorConditionType conditionType ActorConditionType conditionType
@@ -22,6 +27,21 @@ public final class ActorCondition {
this.conditionType = conditionType; this.conditionType = conditionType;
this.magnitude = magnitude; this.magnitude = magnitude;
this.duration = duration; this.duration = duration;
int length;
if (conditionType.scripts != null) {
length = conditionType.scripts.length;
scripts = new Script[length];
while (length-->0) {
scripts[length] = ScriptEngine.instantiateScript(conditionType.scripts[length]);
}
}
if (conditionType.private_scripts != null) {
length = conditionType.private_scripts.length;
private_scripts = new Script[length];
while (length-->0) {
private_scripts[length] = ScriptEngine.instantiateScript(conditionType.private_scripts[length]);
}
}
} }
public boolean isTemporaryEffect() { return isTemporaryEffect(duration); } public boolean isTemporaryEffect() { return isTemporaryEffect(duration); }

View File

@@ -28,4 +28,8 @@ public final class ActorConditionEffect {
public ActorCondition createCondition(final int duration) { public ActorCondition createCondition(final int duration) {
return new ActorCondition(conditionType, magnitude, duration); return new ActorCondition(conditionType, magnitude, duration);
} }
public ActorConditionEffect clone() {
return new ActorConditionEffect(conditionType, magnitude, duration, chance);
}
} }

View File

@@ -2,6 +2,7 @@ package com.gpl.rpg.AndorsTrail.model.ability;
import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits; import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits;
import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits; import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits;
import com.gpl.rpg.AndorsTrail.scripting.Script;
public final class ActorConditionType { public final class ActorConditionType {
public static enum ConditionCategory { public static enum ConditionCategory {
@@ -17,6 +18,8 @@ public final class ActorConditionType {
public final StatsModifierTraits statsEffect_everyRound; public final StatsModifierTraits statsEffect_everyRound;
public final StatsModifierTraits statsEffect_everyFullRound; public final StatsModifierTraits statsEffect_everyFullRound;
public final AbilityModifierTraits abilityEffect; public final AbilityModifierTraits abilityEffect;
public final String[] scripts;
public final String[] private_scripts;
public ActorConditionType( public ActorConditionType(
String conditionTypeID String conditionTypeID
@@ -28,6 +31,8 @@ public final class ActorConditionType {
, StatsModifierTraits statsEffect_everyRound , StatsModifierTraits statsEffect_everyRound
, StatsModifierTraits statsEffect_everyFullRound , StatsModifierTraits statsEffect_everyFullRound
, AbilityModifierTraits abilityEffect , AbilityModifierTraits abilityEffect
, String[] scripts
, String[] private_scripts
) { ) {
this.conditionTypeID = conditionTypeID; this.conditionTypeID = conditionTypeID;
this.name = name; this.name = name;
@@ -38,5 +43,7 @@ public final class ActorConditionType {
this.statsEffect_everyRound = statsEffect_everyRound; this.statsEffect_everyRound = statsEffect_everyRound;
this.statsEffect_everyFullRound = statsEffect_everyFullRound; this.statsEffect_everyFullRound = statsEffect_everyFullRound;
this.abilityEffect = abilityEffect; this.abilityEffect = abilityEffect;
this.scripts = scripts;
this.private_scripts = private_scripts;
} }
} }

View File

@@ -5,8 +5,8 @@ import com.gpl.rpg.AndorsTrail.util.ConstRange;
public final class StatsModifierTraits { public final class StatsModifierTraits {
public final VisualEffectCollection.VisualEffectID visualEffectID; public final VisualEffectCollection.VisualEffectID visualEffectID;
public final ConstRange currentHPBoost; public ConstRange currentHPBoost;
public final ConstRange currentAPBoost; public ConstRange currentAPBoost;
public StatsModifierTraits( public StatsModifierTraits(
VisualEffectCollection.VisualEffectID visualEffectID VisualEffectCollection.VisualEffectID visualEffectID
@@ -45,4 +45,8 @@ public final class StatsModifierTraits {
final int costBoostAP = (int)(1033*Math.pow(Math.max(0,averageAPBoost), 2.5) + 300*averageAPBoost); final int costBoostAP = (int)(1033*Math.pow(Math.max(0,averageAPBoost), 2.5) + 300*averageAPBoost);
return costBoostHP + costBoostAP; return costBoostHP + costBoostAP;
} }
public StatsModifierTraits clone() {
return new StatsModifierTraits(visualEffectID, new ConstRange(currentHPBoost), new ConstRange(currentAPBoost));
}
} }

View File

@@ -2,6 +2,7 @@ package com.gpl.rpg.AndorsTrail.model.item;
import com.gpl.rpg.AndorsTrail.context.WorldContext; import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForItemContainer; import com.gpl.rpg.AndorsTrail.savegames.LegacySavegameFormatReaderForItemContainer;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@@ -23,12 +24,13 @@ public final class Inventory extends ItemContainer {
if (s == null) return default_; if (s == null) return default_;
return valueOf(s); return valueOf(s);
} }
public Script[] slotScripts;
} }
public int gold = 0; public int gold = 0;
private static final int NUM_WORN_SLOTS = WearSlot.values().length; private static final int NUM_WORN_SLOTS = WearSlot.values().length;
public static final int NUM_QUICK_SLOTS = 3; public static final int NUM_QUICK_SLOTS = 3;
private final ItemType[] wear = new ItemType[NUM_WORN_SLOTS]; public final ItemType[] wear = new ItemType[NUM_WORN_SLOTS];
public final ItemType[] quickitem = new ItemType[NUM_QUICK_SLOTS]; public final ItemType[] quickitem = new ItemType[NUM_QUICK_SLOTS];
public Inventory() { } public Inventory() { }

View File

@@ -33,4 +33,18 @@ public final class ItemTraits_OnUse {
final int costStats = changedStats == null ? 0 : changedStats.calculateKillCost(); final int costStats = changedStats == null ? 0 : changedStats.calculateKillCost();
return costStats; return costStats;
} }
public ItemTraits_OnUse clone() {
int i = addedConditions_source.length;
ActorConditionEffect[] addedToSource = new ActorConditionEffect[i];
while (i-- > 0) {
addedToSource[i] = addedConditions_source[i].clone();
}
i = addedConditions_target.length;
ActorConditionEffect[] addedToTarget = new ActorConditionEffect[i];
while (i-- > 0) {
addedToTarget[i] = addedConditions_target[i].clone();
}
return new ItemTraits_OnUse(changedStats.clone(), addedToSource, addedToTarget);
}
} }

View File

@@ -3,6 +3,7 @@ package com.gpl.rpg.AndorsTrail.model.item;
import com.gpl.rpg.AndorsTrail.controller.Constants; import com.gpl.rpg.AndorsTrail.controller.Constants;
import com.gpl.rpg.AndorsTrail.model.actor.Player; import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager; import com.gpl.rpg.AndorsTrail.resource.tiles.TileManager;
import com.gpl.rpg.AndorsTrail.scripting.Script;
public final class ItemType { public final class ItemType {
@@ -34,6 +35,8 @@ public final class ItemType {
public final ItemTraits_OnUse effects_use; public final ItemTraits_OnUse effects_use;
public final ItemTraits_OnUse effects_hit; public final ItemTraits_OnUse effects_hit;
public final ItemTraits_OnUse effects_kill; public final ItemTraits_OnUse effects_kill;
public final String[] scripts;
public final Script[] private_scripts;
public ItemType( public ItemType(
String id String id
@@ -48,6 +51,8 @@ public final class ItemType {
, ItemTraits_OnUse effects_use , ItemTraits_OnUse effects_use
, ItemTraits_OnUse effects_hit , ItemTraits_OnUse effects_hit
, ItemTraits_OnUse effects_kill , ItemTraits_OnUse effects_kill
, String[] scripts
, Script[] private_scripts
) { ) {
this.id = id; this.id = id;
this.iconID = iconID; this.iconID = iconID;
@@ -62,6 +67,8 @@ public final class ItemType {
this.effects_use = effects_use; this.effects_use = effects_use;
this.effects_hit = effects_hit; this.effects_hit = effects_hit;
this.effects_kill = effects_kill; this.effects_kill = effects_kill;
this.scripts = scripts;
this.private_scripts = private_scripts;
this.hasPersonalizedName = name.contains(Constants.PLACEHOLDER_PLAYERNAME); this.hasPersonalizedName = name.contains(Constants.PLACEHOLDER_PLAYERNAME);
} }

View File

@@ -26,7 +26,7 @@ public final class MapObject {
public final String id; //placeName on this map or phraseID public final String id; //placeName on this map or phraseID
public final String map; public final String map;
public final String place; public final String place;
private final String group; public final String group;
public final Requirement enteringRequirement; public final Requirement enteringRequirement;
public final DropList dropList; public final DropList dropList;
public final MapObjectEvaluationType evaluateWhen; public final MapObjectEvaluationType evaluateWhen;

View File

@@ -8,6 +8,7 @@ import com.gpl.rpg.AndorsTrail.controller.VisualEffectController.BloodSplatter;
import com.gpl.rpg.AndorsTrail.model.actor.Monster; import com.gpl.rpg.AndorsTrail.model.actor.Monster;
import com.gpl.rpg.AndorsTrail.model.item.ItemType; import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.item.Loot; import com.gpl.rpg.AndorsTrail.model.item.Loot;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.util.Coord; import com.gpl.rpg.AndorsTrail.util.Coord;
import com.gpl.rpg.AndorsTrail.util.CoordRect; import com.gpl.rpg.AndorsTrail.util.CoordRect;
import com.gpl.rpg.AndorsTrail.util.L; import com.gpl.rpg.AndorsTrail.util.L;
@@ -27,6 +28,7 @@ public final class PredefinedMap {
public final Size size; public final Size size;
public final MapObject[] eventObjects; public final MapObject[] eventObjects;
public final MonsterSpawnArea[] spawnAreas; public final MonsterSpawnArea[] spawnAreas;
public final Script[] scripts;
public final ArrayList<Loot> groundBags = new ArrayList<Loot>(); public final ArrayList<Loot> groundBags = new ArrayList<Loot>();
public boolean visited = false; public boolean visited = false;
public long lastVisitTime = VISIT_RESET; public long lastVisitTime = VISIT_RESET;
@@ -41,6 +43,7 @@ public final class PredefinedMap {
, Size size , Size size
, MapObject[] eventObjects , MapObject[] eventObjects
, MonsterSpawnArea[] spawnAreas , MonsterSpawnArea[] spawnAreas
, Script[] scripts
, boolean isOutdoors , boolean isOutdoors
) { ) {
this.xmlResourceId = xmlResourceId; this.xmlResourceId = xmlResourceId;
@@ -48,6 +51,7 @@ public final class PredefinedMap {
this.size = size; this.size = size;
this.eventObjects = eventObjects; this.eventObjects = eventObjects;
this.spawnAreas = spawnAreas; this.spawnAreas = spawnAreas;
this.scripts = scripts;
assert(size.width > 0); assert(size.width > 0);
assert(size.height > 0); assert(size.height > 0);
this.isOutdoors = isOutdoors; this.isOutdoors = isOutdoors;

View File

@@ -10,6 +10,8 @@ import com.gpl.rpg.AndorsTrail.model.map.TMXMapFileParser.*;
import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress; import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
import com.gpl.rpg.AndorsTrail.model.script.Requirement; import com.gpl.rpg.AndorsTrail.model.script.Requirement;
import com.gpl.rpg.AndorsTrail.resource.tiles.TileCache; import com.gpl.rpg.AndorsTrail.resource.tiles.TileCache;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptEngine;
import com.gpl.rpg.AndorsTrail.util.*; import com.gpl.rpg.AndorsTrail.util.*;
import java.security.MessageDigest; import java.security.MessageDigest;
@@ -41,8 +43,15 @@ public final class TMXMapTranslator {
assert(m.height > 0); assert(m.height > 0);
boolean isOutdoors = false; boolean isOutdoors = false;
final List<Script> scripts = new ArrayList<Script>();
for (TMXProperty p : m.properties) { for (TMXProperty p : m.properties) {
if(p.name.equalsIgnoreCase("outdoors")) isOutdoors = (Integer.parseInt(p.value) != 0); if(p.name.equalsIgnoreCase("outdoors")) isOutdoors = (Integer.parseInt(p.value) != 0);
else if (p.name.equalsIgnoreCase("script")) {
String[] names = p.value.split(";");
for (String name : names) {
scripts.add(ScriptEngine.instantiateScript(name));
}
}
else if(AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("OPTIMIZE: Map " + m.name + " has unrecognized property \"" + p.name + "\"."); else if(AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) L.log("OPTIMIZE: Map " + m.name + " has unrecognized property \"" + p.name + "\".");
} }
@@ -185,8 +194,10 @@ public final class TMXMapTranslator {
_eventObjects = mapObjects.toArray(_eventObjects); _eventObjects = mapObjects.toArray(_eventObjects);
MonsterSpawnArea[] _spawnAreas = new MonsterSpawnArea[spawnAreas.size()]; MonsterSpawnArea[] _spawnAreas = new MonsterSpawnArea[spawnAreas.size()];
_spawnAreas = spawnAreas.toArray(_spawnAreas); _spawnAreas = spawnAreas.toArray(_spawnAreas);
Script[] _scripts = new Script[scripts.size()];
_scripts = scripts.toArray(_scripts);
result.add(new PredefinedMap(m.xmlResourceId, m.name, mapSize, _eventObjects, _spawnAreas, isOutdoors)); result.add(new PredefinedMap(m.xmlResourceId, m.name, mapSize, _eventObjects, _spawnAreas, _scripts, isOutdoors));
} }
return result; return result;

View File

@@ -8,6 +8,9 @@ import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.conversation.ConversationCollection; import com.gpl.rpg.AndorsTrail.model.conversation.ConversationCollection;
import com.gpl.rpg.AndorsTrail.model.map.TMXMapTranslator; import com.gpl.rpg.AndorsTrail.model.map.TMXMapTranslator;
import com.gpl.rpg.AndorsTrail.resource.parsers.*; import com.gpl.rpg.AndorsTrail.resource.parsers.*;
import com.gpl.rpg.AndorsTrail.scripting.ScriptEngine;
import com.gpl.rpg.AndorsTrail.scripting.collectionparser.ATCollectionParser;
import com.gpl.rpg.AndorsTrail.scripting.collectionparser.ParseException;
import com.gpl.rpg.AndorsTrail.util.L; import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.Size; import com.gpl.rpg.AndorsTrail.util.Size;
@@ -20,13 +23,14 @@ import java.util.Collection;
public final class ResourceLoader { public final class ResourceLoader {
private static final int itemCategoriesResourceId = R.array.loadresource_itemcategories; private static final int itemCategoriesResourceId = R.array.loadresource_itemcategories;
private static final int actorConditionsResourceId = R.array.loadresource_actorconditions; private static final int actorConditionsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_actorconditions_debug : R.array.loadresource_actorconditions;
private static final int itemsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_items_debug : R.array.loadresource_items; private static final int itemsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_items_debug : R.array.loadresource_items;
private static final int droplistsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_droplists_debug : R.array.loadresource_droplists; private static final int droplistsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_droplists_debug : R.array.loadresource_droplists;
private static final int questsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_quests_debug : R.array.loadresource_quests; private static final int questsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_quests_debug : R.array.loadresource_quests;
private static final int conversationsListsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_conversationlists_debug : R.array.loadresource_conversationlists; private static final int conversationsListsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_conversationlists_debug : R.array.loadresource_conversationlists;
private static final int monstersResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_monsters_debug : R.array.loadresource_monsters; private static final int monstersResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_monsters_debug : R.array.loadresource_monsters;
private static final int mapsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_maps_debug : R.array.loadresource_maps; private static final int mapsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_maps_debug : R.array.loadresource_maps;
private static final int scriptsResourceId = AndorsTrailApplication.DEVELOPMENT_DEBUGRESOURCES ? R.array.loadresource_scripts_debug : R.array.loadresource_scripts;
private static long taskStart; private static long taskStart;
private static void timingCheckpoint(String loaderName) { private static void timingCheckpoint(String loaderName) {
@@ -65,6 +69,23 @@ public final class ResourceLoader {
} }
// ========================================================================
// Load scripts
final TypedArray scriptsToLoad = r.obtainTypedArray(scriptsResourceId);
for (int i = 0; i < scriptsToLoad.length(); ++i) {
try {
InputStream is = r.openRawResource(scriptsToLoad.getResourceId(i, -1));
BufferedReader br = new BufferedReader(new InputStreamReader(is));
ScriptEngine.LIBRARY.putAll(ATCollectionParser.parseCollection(br));
} catch (ParseException e) {
if (AndorsTrailApplication.DEVELOPMENT_VALIDATEDATA) {
L.log("Error loading script collection file");
e.printStackTrace();
}
}
}
if (AndorsTrailApplication.DEVELOPMENT_DEBUGMESSAGES) timingCheckpoint("ScriptsLoader");
// ======================================================================== // ========================================================================
// Load effects // Load effects
world.visualEffectTypes.initialize(loader); world.visualEffectTypes.initialize(loader);

View File

@@ -32,6 +32,8 @@ public final class ActorConditionsTypeParser extends JsonCollectionParserFor<Act
,ResourceParserUtils.parseStatsModifierTraits(o.optJSONObject(JsonFieldNames.ActorCondition.roundEffect)) ,ResourceParserUtils.parseStatsModifierTraits(o.optJSONObject(JsonFieldNames.ActorCondition.roundEffect))
,ResourceParserUtils.parseStatsModifierTraits(o.optJSONObject(JsonFieldNames.ActorCondition.fullRoundEffect)) ,ResourceParserUtils.parseStatsModifierTraits(o.optJSONObject(JsonFieldNames.ActorCondition.fullRoundEffect))
,ResourceParserUtils.parseAbilityModifierTraits(o.optJSONObject(JsonFieldNames.ActorCondition.abilityEffect)) ,ResourceParserUtils.parseAbilityModifierTraits(o.optJSONObject(JsonFieldNames.ActorCondition.abilityEffect))
,ResourceParserUtils.parseScriptsNamesReference(o.optJSONArray(JsonFieldNames.ActorCondition.scripts))
,ResourceParserUtils.parseScriptsNamesReference(o.optJSONArray(JsonFieldNames.ActorCondition.privateScripts))
); );
return new Pair<String, ActorConditionType>(conditionTypeID, result); return new Pair<String, ActorConditionType>(conditionTypeID, result);
} }

View File

@@ -9,6 +9,7 @@ import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader;
import com.gpl.rpg.AndorsTrail.resource.TranslationLoader; import com.gpl.rpg.AndorsTrail.resource.TranslationLoader;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonCollectionParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.util.Pair; import com.gpl.rpg.AndorsTrail.util.Pair;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@@ -41,6 +42,9 @@ public final class ItemTypeParser extends JsonCollectionParserFor<ItemType> {
final ItemTraits_OnUse hitEffect = itemTraitsParser.parseItemTraits_OnUse(o.optJSONObject(JsonFieldNames.ItemType.hitEffect)); final ItemTraits_OnUse hitEffect = itemTraitsParser.parseItemTraits_OnUse(o.optJSONObject(JsonFieldNames.ItemType.hitEffect));
final ItemTraits_OnUse killEffect = itemTraitsParser.parseItemTraits_OnUse(o.optJSONObject(JsonFieldNames.ItemType.killEffect)); final ItemTraits_OnUse killEffect = itemTraitsParser.parseItemTraits_OnUse(o.optJSONObject(JsonFieldNames.ItemType.killEffect));
final String[] scripts = ResourceParserUtils.parseScriptsNamesReference(o.optJSONArray(JsonFieldNames.ItemType.scripts));
final Script[] private_scripts = ResourceParserUtils.parseScriptsReference(o.optJSONArray(JsonFieldNames.ItemType.privateScripts));
final int baseMarketCost = o.optInt(JsonFieldNames.ItemType.baseMarketCost); final int baseMarketCost = o.optInt(JsonFieldNames.ItemType.baseMarketCost);
final boolean hasManualPrice = o.optInt(JsonFieldNames.ItemType.hasManualPrice, 0) > 0; final boolean hasManualPrice = o.optInt(JsonFieldNames.ItemType.hasManualPrice, 0) > 0;
final ItemType itemType = new ItemType( final ItemType itemType = new ItemType(
@@ -56,6 +60,8 @@ public final class ItemTypeParser extends JsonCollectionParserFor<ItemType> {
, useEffect , useEffect
, hitEffect , hitEffect
, killEffect , killEffect
, scripts
, private_scripts
); );
return new Pair<String, ItemType>(id, itemType); return new Pair<String, ItemType>(id, itemType);
} }

View File

@@ -5,10 +5,15 @@ import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits;
import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits; import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits;
import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader; import com.gpl.rpg.AndorsTrail.resource.DynamicTileLoader;
import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection; import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonArrayParserFor;
import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames; import com.gpl.rpg.AndorsTrail.resource.parsers.json.JsonFieldNames;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptEngine;
import com.gpl.rpg.AndorsTrail.util.ConstRange; import com.gpl.rpg.AndorsTrail.util.ConstRange;
import com.gpl.rpg.AndorsTrail.util.L; import com.gpl.rpg.AndorsTrail.util.L;
import com.gpl.rpg.AndorsTrail.util.Size; import com.gpl.rpg.AndorsTrail.util.Size;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@@ -125,4 +130,27 @@ public final class ResourceParserUtils {
if (min == 10 && max == 10) return ten; if (min == 10 && max == 10) return ten;
return parseConstRange(obj); return parseConstRange(obj);
} }
public static JsonArrayParserFor<Script> scriptParser = new JsonArrayParserFor<Script>(Script.class) {
@Override
protected Script parseObject(JSONObject o) throws JSONException {
return ScriptEngine.instantiateScript(o.getString(JsonFieldNames.Script.name));
}
};
public static Script[] parseScriptsReference(JSONArray optJSONArray) throws JSONException {
return scriptParser.parseArray(optJSONArray);
}
public static JsonArrayParserFor<String> scriptNameParser = new JsonArrayParserFor<String>(String.class) {
@Override
protected String parseObject(JSONObject o) throws JSONException {
return o.getString(JsonFieldNames.Script.name);
}
};
public static String[] parseScriptsNamesReference(JSONArray optJSONArray) throws JSONException {
return scriptNameParser.parseArray(optJSONArray);
}
} }

View File

@@ -11,6 +11,8 @@ public final class JsonFieldNames {
public static final String roundEffect = "roundEffect"; public static final String roundEffect = "roundEffect";
public static final String fullRoundEffect = "fullRoundEffect"; public static final String fullRoundEffect = "fullRoundEffect";
public static final String abilityEffect = "abilityEffect"; public static final String abilityEffect = "abilityEffect";
public static final String scripts = "scripts";
public static final String privateScripts = "privateScripts";
} }
public static final class StatsModifierTraits { public static final class StatsModifierTraits {
@@ -156,7 +158,12 @@ public final class JsonFieldNames {
public static final String useEffect = "useEffect"; public static final String useEffect = "useEffect";
public static final String hitEffect = "hitEffect"; public static final String hitEffect = "hitEffect";
public static final String killEffect = "killEffect"; public static final String killEffect = "killEffect";
public static final String scripts = "scripts";
public static final String privateScripts = "privateScripts";
} }
public static final class Script {
public static final String name = "name";
}
} }

View File

@@ -143,7 +143,7 @@ public final class LegacySavegameFormatReaderForPlayer {
} }
if (hasItemWithCondition) return; if (hasItemWithCondition) return;
controllers.actorStatsController.removeConditionsFromUnequippedItem(player, world.itemTypes.getItemType(itemTypeIDWithCondition)); controllers.actorStatsController.removeConditionsFromUnequippedItem(player, world.itemTypes.getItemType(itemTypeIDWithCondition).effects_equip);
} }
public static void readCombatTraitsPreV034(DataInputStream src, int fileversion) throws IOException { public static void readCombatTraitsPreV034(DataInputStream src, int fileversion) throws IOException {

View File

@@ -0,0 +1,31 @@
package com.gpl.rpg.AndorsTrail.scripting;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSNode;
public class Script {
public final String id;
public final String description;
public final ScriptTrigger trigger;
public final ATSNode scriptASTRoot;
public final int localNumsSize;
public final int localBoolsSize;
public final int localStringsSize;
public final int localObjectsSize;
public Script(String id, String description, ScriptTrigger trigger, ATSNode scriptASTRoot, int localNumsSize, int localBoolsSize, int localStringsSize, int localObjectsSize) {
this.id = id;
this.description = description;
this.trigger = trigger;
this.scriptASTRoot = scriptASTRoot;
this.localNumsSize = localNumsSize;
this.localBoolsSize = localBoolsSize;
this.localStringsSize = localStringsSize;
this.localObjectsSize = localObjectsSize;
}
public Script clone() {
return new Script(id, description, trigger, scriptASTRoot, localNumsSize, localBoolsSize, localStringsSize, localObjectsSize);
}
}

View File

@@ -0,0 +1,316 @@
package com.gpl.rpg.AndorsTrail.scripting;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.controller.listeners.ActorConditionListener;
import com.gpl.rpg.AndorsTrail.controller.listeners.PlayerMovementListener;
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.Inventory;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ScriptContext;
import com.gpl.rpg.AndorsTrail.scripting.proxyobjects.Item;
import com.gpl.rpg.AndorsTrail.util.Coord;
public class ScriptEngine implements PlayerMovementListener, ActorConditionListener {
public static final Map<String, Script> LIBRARY = new HashMap<String, Script>();
public static final ScriptEngine instance = new ScriptEngine();
public ControllerContext controllers = null;
public WorldContext world = null;
public static void initializeEngine(ControllerContext controllers, WorldContext world) {
ScriptEngine.instance.controllers = controllers;
ScriptEngine.instance.world = world;
controllers.movementController.playerMovementListeners.add(instance);
controllers.actorStatsController.actorConditionListeners.add(instance);
}
public static Script instantiateScript(String scriptId) {
if (!LIBRARY.containsKey(scriptId)) {
//TODO log error
return null;
}
return LIBRARY.get(scriptId).clone();
}
public void activateScript(Script s) {
for (List<Script> listenerList : getListenersListsForScript(s)) {
if (listenerList.contains(s)) continue;
listenerList.add(s);
}
}
public void deactivateScript(Script s) {
for (List<Script> listenerList : getListenersListsForScript(s)) {
if (!listenerList.contains(s)) continue;
listenerList.remove(s);
}
}
private List<List<Script>> getListenersListsForScript(Script s) {
List<List<Script>> result = new ArrayList<List<Script>>();
switch (s.trigger.category) {
case map :
switch (s.trigger.event) {
case onEnter :
result.add(mapOnEnter);
break;
case onLeave :
result.add(mapOnLeave);
break;
}
break;
case player :
switch (s.trigger.event) {
case statsUpdated :
result.add(playerStatsUpdated);
break;
}
break;
case item :
switch (s.trigger.event) {
case onUse :
result.add(itemUsed);
break;
case onEquip :
result.add(itemEquipped);
break;
case onUnequip :
result.add(itemUnequipped);
break;
}
break;
}
return result;
}
/*
* MAPS
*/
public void onPlayerEnteredNewMap(PredefinedMap map, com.gpl.rpg.AndorsTrail.util.Coord p, PredefinedMap oldMap) {
if (oldMap != null) {
mapLeft(oldMap);
for (Script s : oldMap.scripts) {
deactivateScript(s);
}
}
for (Script s: map.scripts) {
activateScript(s);
}
mapEntered(map);
}
public void onPlayerMoved(Coord newPosition, Coord previousPosition) {
}
private final List<Script> mapOnEnter = new ArrayList<Script>();
private void mapEntered(PredefinedMap map) {
ScriptContext context = new ScriptContext(world, controllers);
context.map = map;
context.player = world.model.player;
context.actor = world.model.player;
for (Script script : mapOnEnter) {
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
}
private final List<Script> mapOnLeave = new ArrayList<Script>();
private void mapLeft(PredefinedMap map) {
ScriptContext context = new ScriptContext(world, controllers);
context.map = map;
context.player = world.model.player;
context.actor = world.model.player;
for (Script script : mapOnLeave) {
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
}
/*
* PLAYER
*/
public void onPlayerStatsUpdate(Player p) {
statsUpdated(p);
}
private final List<Script> playerStatsUpdated = new ArrayList<Script>();
private void statsUpdated(Player p) {
ScriptContext context = new ScriptContext(world, controllers);
context.map = world.model.currentMap;
context.player = p;
context.actor = p;
for (Script script : playerStatsUpdated) {
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
for (ActorCondition ac : p.conditions) {
if (ac.conditionType.private_scripts == null) continue;
for (Script script : ac.private_scripts) {
if (script.trigger.category != ScriptTrigger.Categories.player) continue;
if (script.trigger.event != ScriptTrigger.Events.statsUpdated) continue;
context.ac = ac;
script.scriptASTRoot.evaluate(context);
}
}
context.ac = null;
for (ItemType item : p.inventory.wear) {
if (item == null) continue;
if (item.private_scripts == null) continue;
for (Script script : item.private_scripts) {
if (script == null) continue;
if (script.trigger.category != ScriptTrigger.Categories.player) continue;
if (script.trigger.event != ScriptTrigger.Events.statsUpdated) continue;
context.item = new Item(item, null, item.effects_equip);
script.scriptASTRoot.evaluate(context);
}
}
context.item = null;
}
/*
* ITEMS
*/
public void onItemUse(Item item) {
itemOnUse(item);
}
private final List<Script> itemUsed = new ArrayList<Script>();
private void itemOnUse(Item item) {
ScriptContext context = new ScriptContext(world, controllers);
context.map = world.model.currentMap;
context.item = item;
context.player = world.model.player;
context.actor = world.model.player;
for (Script script : itemUsed) {
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
if (item.privateScripts != null) {
for (Script script : item.privateScripts) {
if (script == null) continue;
if (script.trigger.category != ScriptTrigger.Categories.item) continue;
if (script.trigger.event != ScriptTrigger.Events.onUse) continue;
context.item = item;
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
}
}
public void onItemEquip(Item item, Inventory.WearSlot slot) {
itemOnEquip(item, slot);
}
private final List<Script> itemEquipped = new ArrayList<Script>();
private void itemOnEquip(Item item, Inventory.WearSlot slot) {
ScriptContext context = new ScriptContext(world, controllers);
context.map = world.model.currentMap;
context.item = item;
context.player = world.model.player;
context.actor = world.model.player;
context.slot = slot.name();
for (Script script : itemEquipped) {
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
if (item.privateScripts != null) {
for (Script script : item.privateScripts) {
if (script == null) continue;
if (script.trigger.category != ScriptTrigger.Categories.item) continue;
if (script.trigger.event != ScriptTrigger.Events.onEquip) continue;
context.item = item;
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
}
}
public void onItemUnequip(Item item, Inventory.WearSlot slot) {
itemOnUnequip(item, slot);
}
private final List<Script> itemUnequipped = new ArrayList<Script>();
private void itemOnUnequip(Item item, Inventory.WearSlot slot) {
ScriptContext context = new ScriptContext(world, controllers);
context.map = world.model.currentMap;
context.item = item;
context.player = world.model.player;
context.actor = world.model.player;
context.slot = slot.name();
for (Script script : itemUnequipped) {
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
if (item.privateScripts != null) {
for (Script script : item.privateScripts) {
if (script == null) continue;
if (script.trigger.category != ScriptTrigger.Categories.item) continue;
if (script.trigger.event != ScriptTrigger.Events.onUnequip) continue;
context.item = item;
context.initializeLocalVars(script.localBoolsSize, script.localNumsSize, script.localStringsSize, script.localObjectsSize);
script.scriptASTRoot.evaluate(context);
}
}
}
/*
* ACTOR CONDITIONS
*/
@Override
public void onActorConditionAdded(Actor actor, ActorCondition condition) {
for(Script s : condition.scripts) {
activateScript(s);
}
}
@Override
public void onActorConditionDurationChanged(Actor actor, ActorCondition condition) {
//Do nothing
}
@Override
public void onActorConditionMagnitudeChanged(Actor actor, ActorCondition condition) {
//Do nothing
}
@Override
public void onActorConditionRemoved(Actor actor, ActorCondition condition) {
for(Script s : condition.scripts) {
deactivateScript(s);
}
}
@Override
public void onActorConditionRoundEffectApplied(Actor actor, ActorCondition condition) {
//Do nothing
}
}

View File

@@ -0,0 +1,56 @@
package com.gpl.rpg.AndorsTrail.scripting;
public class ScriptTrigger {
public static enum Categories {
map(new Events[]{Events.onEnter, Events.onLeave}),
attack(new Events[]{Events.onTry, Events.onHit, Events.onMiss}),
item(new Events[]{Events.onEquip, Events.onUnequip, Events.onUse}),
player(new Events[]{Events.onReceivedHit, Events.onKilled, Events.onLevelUp, Events.onSkillUp, Events.onRewardReceived, Events.statsUpdated}),
actor(new Events[]{Events.onReceivedHit, Events.onKilled, Events.statsUpdated});
private final Events[] allowedEvents;
private Categories(Events[] allowedEvents) {
this.allowedEvents = allowedEvents;
}
public boolean isAllowed(Events ev) {
for (Events e : allowedEvents) {
if (e.equals(ev)) return true;
}
return false;
}
}
public static enum Events {
onEnter,
onLeave,
onTry,
onHit,
onMiss,
onEquip,
onUse,
onLevelUp,
onSkillUp,
onRewardReceived,
onReceivedHit,
onKilled,
statsUpdated,
onUnequip,
}
public final Categories category;
public final Events event;
public ScriptTrigger(String category, String event) {
this.category = Categories.valueOf(category);
this.event = Events.valueOf(event);
if (!this.category.isAllowed(this.event)){
throw new RuntimeException("ERROR : "+event+" is not an event type for category "+category);
}
}
}

View File

@@ -0,0 +1,437 @@
/* Generated By:JavaCC: Do not edit this line. ATCollectionParser.java */
package com.gpl.rpg.AndorsTrail.scripting.collectionparser;
import java.io.Reader;
import java.util.Map;
import java.util.HashMap;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptTrigger;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATScriptParser;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSNode;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSReturnStatement;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSConstantReference;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSLocalVarsHelper;
public class ATCollectionParser implements ATCollectionParserConstants {
public static Map < String, Script > parseCollection(Reader scriptCollectionReader) throws ParseException {
Map < String, Script > scripts = new HashMap < String, Script > ();
ATCollectionParser parser = new ATCollectionParser(scriptCollectionReader);
try {
parser.optionalWhiteSpacePrefix(scripts);
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
return scripts;
}
final public void optionalWhiteSpacePrefix(Map < String, Script > scripts) throws ParseException, com.gpl.rpg.AndorsTrail.scripting.interpreter.ParseException {
Script s;
label_1:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case WHITESPACE:
;
break;
default:
jj_la1[0] = jj_gen;
break label_1;
}
jj_consume_token(WHITESPACE);
}
scriptCollection(scripts);
}
final public void scriptCollection(Map < String, Script > scripts) throws ParseException, com.gpl.rpg.AndorsTrail.scripting.interpreter.ParseException {
Script s;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case DQUO:
s = script();
scriptCollection(scripts);
scripts.put(s.id, s);
break;
case 0:
jj_consume_token(0);
break;
default:
jj_la1[1] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
}
final public Script script() throws ParseException, com.gpl.rpg.AndorsTrail.scripting.interpreter.ParseException {
Token id;
Token code = null;
Token desc = null;
ScriptTrigger trigger;
jj_consume_token(DQUO);
id = jj_consume_token(SCRIPT_ID);
jj_consume_token(DQUO);
label_2:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case WHITESPACE:
;
break;
default:
jj_la1[2] = jj_gen;
break label_2;
}
jj_consume_token(WHITESPACE);
}
trigger = trigger();
label_3:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case WHITESPACE:
;
break;
default:
jj_la1[3] = jj_gen;
break label_3;
}
jj_consume_token(WHITESPACE);
}
jj_consume_token(LBRAC);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case CODE:
code = jj_consume_token(CODE);
break;
default:
jj_la1[4] = jj_gen;
;
}
jj_consume_token(RBRAC);
label_4:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case WHITESPACE:
;
break;
default:
jj_la1[5] = jj_gen;
break label_4;
}
jj_consume_token(WHITESPACE);
}
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case LBRAC:
jj_consume_token(LBRAC);
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case CODE:
desc = jj_consume_token(CODE);
break;
default:
jj_la1[6] = jj_gen;
;
}
jj_consume_token(RBRAC);
label_5:
while (true) {
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case WHITESPACE:
;
break;
default:
jj_la1[7] = jj_gen;
break label_5;
}
jj_consume_token(WHITESPACE);
}
break;
default:
jj_la1[8] = jj_gen;
;
}
String description = desc == null ? null : desc.image;
if (code != null) {
ATSLocalVarsHelper localVarsRefHelp = new ATSLocalVarsHelper();
ATSNode scriptASTRoot = ATScriptParser.parseScript(code.image, localVarsRefHelp);
{if (true) return new Script(id.image, description, trigger, scriptASTRoot, localVarsRefHelp.maxNumNeeded, localVarsRefHelp.maxBoolNeeded, localVarsRefHelp.maxStringNeeded, localVarsRefHelp.maxObjectNeeded);}
} else {
//Dummy script returning 0;
ATSNode scriptASTRoot = new ATSReturnStatement(new ATSConstantReference(0));
{if (true) return new Script(id.image, description, trigger, scriptASTRoot, 0, 0, 0, 0);}
}
throw new Error("Missing return statement in function");
}
final public ScriptTrigger trigger() throws ParseException {
Token category;
String event;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case MAP:
category = jj_consume_token(MAP);
jj_consume_token(DOT);
event = mapEvents();
{if (true) return new ScriptTrigger(category.image, event);}
break;
case ATTACK:
category = jj_consume_token(ATTACK);
jj_consume_token(DOT);
event = attackEvents();
{if (true) return new ScriptTrigger(category.image, event);}
break;
case PLAYER:
category = jj_consume_token(PLAYER);
jj_consume_token(DOT);
event = playerEvents();
{if (true) return new ScriptTrigger(category.image, event);}
break;
case ITEM:
category = jj_consume_token(ITEM);
jj_consume_token(DOT);
event = itemEvents();
{if (true) return new ScriptTrigger(category.image, event);}
break;
default:
jj_la1[9] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
throw new Error("Missing return statement in function");
}
final public String mapEvents() throws ParseException {
Token event;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case ON_ENTER:
event = jj_consume_token(ON_ENTER);
{if (true) return event.image;}
break;
case ON_LEAVE:
event = jj_consume_token(ON_LEAVE);
{if (true) return event.image;}
break;
default:
jj_la1[10] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
throw new Error("Missing return statement in function");
}
final public String attackEvents() throws ParseException {
Token event;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case ON_HIT:
event = jj_consume_token(ON_HIT);
{if (true) return event.image;}
break;
case ON_MISS:
event = jj_consume_token(ON_MISS);
{if (true) return event.image;}
break;
default:
jj_la1[11] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
throw new Error("Missing return statement in function");
}
final public String playerEvents() throws ParseException {
Token event;
event = jj_consume_token(STATS_UPDATED);
{if (true) return event.image;}
throw new Error("Missing return statement in function");
}
final public String itemEvents() throws ParseException {
Token event;
switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
case ON_USE:
event = jj_consume_token(ON_USE);
{if (true) return event.image;}
break;
case ON_EQUIP:
event = jj_consume_token(ON_EQUIP);
{if (true) return event.image;}
break;
case ON_UNEQUIP:
event = jj_consume_token(ON_UNEQUIP);
{if (true) return event.image;}
break;
default:
jj_la1[12] = jj_gen;
jj_consume_token(-1);
throw new ParseException();
}
throw new Error("Missing return statement in function");
}
/** Generated Token Manager. */
public ATCollectionParserTokenManager token_source;
SimpleCharStream jj_input_stream;
/** Current token. */
public Token token;
/** Next token. */
public Token jj_nt;
private int jj_ntk;
private int jj_gen;
final private int[] jj_la1 = new int[13];
static private int[] jj_la1_0;
static {
jj_la1_init_0();
}
private static void jj_la1_init_0() {
jj_la1_0 = new int[] {0x20000,0x3,0x20000,0x20000,0x80000,0x20000,0x80000,0x20000,0x8,0x1490,0x60,0x300,0xe000,};
}
/** Constructor with InputStream. */
public ATCollectionParser(java.io.InputStream stream) {
this(stream, null);
}
/** Constructor with InputStream and supplied encoding */
public ATCollectionParser(java.io.InputStream stream, String encoding) {
try { jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source = new ATCollectionParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 13; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(java.io.InputStream stream) {
ReInit(stream, null);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream stream, String encoding) {
try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 13; i++) jj_la1[i] = -1;
}
/** Constructor. */
public ATCollectionParser(java.io.Reader stream) {
jj_input_stream = new SimpleCharStream(stream, 1, 1);
token_source = new ATCollectionParserTokenManager(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 13; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader stream) {
jj_input_stream.ReInit(stream, 1, 1);
token_source.ReInit(jj_input_stream);
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 13; i++) jj_la1[i] = -1;
}
/** Constructor with generated Token Manager. */
public ATCollectionParser(ATCollectionParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 13; i++) jj_la1[i] = -1;
}
/** Reinitialise. */
public void ReInit(ATCollectionParserTokenManager tm) {
token_source = tm;
token = new Token();
jj_ntk = -1;
jj_gen = 0;
for (int i = 0; i < 13; i++) jj_la1[i] = -1;
}
private Token jj_consume_token(int kind) throws ParseException {
Token oldToken;
if ((oldToken = token).next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
if (token.kind == kind) {
jj_gen++;
return token;
}
token = oldToken;
jj_kind = kind;
throw generateParseException();
}
/** Get the next Token. */
final public Token getNextToken() {
if (token.next != null) token = token.next;
else token = token.next = token_source.getNextToken();
jj_ntk = -1;
jj_gen++;
return token;
}
/** Get the specific Token. */
final public Token getToken(int index) {
Token t = token;
for (int i = 0; i < index; i++) {
if (t.next != null) t = t.next;
else t = t.next = token_source.getNextToken();
}
return t;
}
private int jj_ntk() {
if ((jj_nt=token.next) == null)
return (jj_ntk = (token.next=token_source.getNextToken()).kind);
else
return (jj_ntk = jj_nt.kind);
}
private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
private int[] jj_expentry;
private int jj_kind = -1;
/** Generate ParseException. */
public ParseException generateParseException() {
jj_expentries.clear();
boolean[] la1tokens = new boolean[20];
if (jj_kind >= 0) {
la1tokens[jj_kind] = true;
jj_kind = -1;
}
for (int i = 0; i < 13; i++) {
if (jj_la1[i] == jj_gen) {
for (int j = 0; j < 32; j++) {
if ((jj_la1_0[i] & (1<<j)) != 0) {
la1tokens[j] = true;
}
}
}
}
for (int i = 0; i < 20; i++) {
if (la1tokens[i]) {
jj_expentry = new int[1];
jj_expentry[0] = i;
jj_expentries.add(jj_expentry);
}
}
int[][] exptokseq = new int[jj_expentries.size()][];
for (int i = 0; i < jj_expentries.size(); i++) {
exptokseq[i] = jj_expentries.get(i);
}
return new ParseException(token, exptokseq, tokenImage);
}
/** Enable tracing. */
final public void enable_tracing() {
}
/** Disable tracing. */
final public void disable_tracing() {
}
}

View File

@@ -0,0 +1,81 @@
/* Generated By:JavaCC: Do not edit this line. ATCollectionParserConstants.java */
package com.gpl.rpg.AndorsTrail.scripting.collectionparser;
/**
* Token literal values and constants.
* Generated by org.javacc.parser.OtherFilesGen#start()
*/
public interface ATCollectionParserConstants {
/** End of File. */
int EOF = 0;
/** RegularExpression Id. */
int DQUO = 1;
/** RegularExpression Id. */
int DOT = 2;
/** RegularExpression Id. */
int LBRAC = 3;
/** RegularExpression Id. */
int MAP = 4;
/** RegularExpression Id. */
int ON_ENTER = 5;
/** RegularExpression Id. */
int ON_LEAVE = 6;
/** RegularExpression Id. */
int ATTACK = 7;
/** RegularExpression Id. */
int ON_HIT = 8;
/** RegularExpression Id. */
int ON_MISS = 9;
/** RegularExpression Id. */
int PLAYER = 10;
/** RegularExpression Id. */
int STATS_UPDATED = 11;
/** RegularExpression Id. */
int ITEM = 12;
/** RegularExpression Id. */
int ON_USE = 13;
/** RegularExpression Id. */
int ON_EQUIP = 14;
/** RegularExpression Id. */
int ON_UNEQUIP = 15;
/** RegularExpression Id. */
int SCRIPT_ID = 16;
/** RegularExpression Id. */
int WHITESPACE = 17;
/** RegularExpression Id. */
int RBRAC = 18;
/** RegularExpression Id. */
int CODE = 19;
/** Lexical state. */
int DEFAULT = 0;
/** Lexical state. */
int SCRIPT_CODE = 1;
/** Literal token values. */
String[] tokenImage = {
"<EOF>",
"\"\\\"\"",
"\".\"",
"\"[\"",
"\"map\"",
"\"onEnter\"",
"\"onLeave\"",
"\"attack\"",
"\"onHit\"",
"\"onMiss\"",
"\"player\"",
"\"statsUpdated\"",
"\"item\"",
"\"onUse\"",
"\"onEquip\"",
"\"onUnequip\"",
"<SCRIPT_ID>",
"<WHITESPACE>",
"\"]\"",
"<CODE>",
};
}

View File

@@ -0,0 +1,833 @@
/* Generated By:JavaCC: Do not edit this line. ATCollectionParserTokenManager.java */
package com.gpl.rpg.AndorsTrail.scripting.collectionparser;
import java.io.Reader;
import java.util.Map;
import java.util.HashMap;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptTrigger;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATScriptParser;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSNode;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSReturnStatement;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSConstantReference;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSLocalVarsHelper;
/** Token Manager. */
public class ATCollectionParserTokenManager implements ATCollectionParserConstants
{
/** Debug output. */
public java.io.PrintStream debugStream = System.out;
/** Set debug output. */
public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
private final int jjStopStringLiteralDfa_0(int pos, long active0)
{
switch (pos)
{
case 0:
if ((active0 & 0xfff0L) != 0L)
{
jjmatchedKind = 16;
return 1;
}
return -1;
case 1:
if ((active0 & 0xfff0L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 1;
return 1;
}
return -1;
case 2:
if ((active0 & 0xffe0L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 2;
return 1;
}
if ((active0 & 0x10L) != 0L)
return 1;
return -1;
case 3:
if ((active0 & 0xefe0L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 3;
return 1;
}
if ((active0 & 0x1000L) != 0L)
return 1;
return -1;
case 4:
if ((active0 & 0xcee0L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 4;
return 1;
}
if ((active0 & 0x2100L) != 0L)
return 1;
return -1;
case 5:
if ((active0 & 0xc860L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 5;
return 1;
}
if ((active0 & 0x680L) != 0L)
return 1;
return -1;
case 6:
if ((active0 & 0x8800L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 6;
return 1;
}
if ((active0 & 0x4060L) != 0L)
return 1;
return -1;
case 7:
if ((active0 & 0x8800L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 7;
return 1;
}
return -1;
case 8:
if ((active0 & 0x8000L) != 0L)
return 1;
if ((active0 & 0x800L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 8;
return 1;
}
return -1;
case 9:
if ((active0 & 0x800L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 9;
return 1;
}
return -1;
case 10:
if ((active0 & 0x800L) != 0L)
{
jjmatchedKind = 16;
jjmatchedPos = 10;
return 1;
}
return -1;
default :
return -1;
}
}
private final int jjStartNfa_0(int pos, long active0)
{
return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1);
}
private int jjStopAtPos(int pos, int kind)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
return pos + 1;
}
private int jjMoveStringLiteralDfa0_0()
{
switch(curChar)
{
case 34:
return jjStopAtPos(0, 1);
case 46:
return jjStopAtPos(0, 2);
case 91:
return jjStopAtPos(0, 3);
case 97:
return jjMoveStringLiteralDfa1_0(0x80L);
case 105:
return jjMoveStringLiteralDfa1_0(0x1000L);
case 109:
return jjMoveStringLiteralDfa1_0(0x10L);
case 111:
return jjMoveStringLiteralDfa1_0(0xe360L);
case 112:
return jjMoveStringLiteralDfa1_0(0x400L);
case 115:
return jjMoveStringLiteralDfa1_0(0x800L);
default :
return jjMoveNfa_0(0, 0);
}
}
private int jjMoveStringLiteralDfa1_0(long active0)
{
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(0, active0);
return 1;
}
switch(curChar)
{
case 97:
return jjMoveStringLiteralDfa2_0(active0, 0x10L);
case 108:
return jjMoveStringLiteralDfa2_0(active0, 0x400L);
case 110:
return jjMoveStringLiteralDfa2_0(active0, 0xe360L);
case 116:
return jjMoveStringLiteralDfa2_0(active0, 0x1880L);
default :
break;
}
return jjStartNfa_0(0, active0);
}
private int jjMoveStringLiteralDfa2_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(0, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(1, active0);
return 2;
}
switch(curChar)
{
case 69:
return jjMoveStringLiteralDfa3_0(active0, 0x4020L);
case 72:
return jjMoveStringLiteralDfa3_0(active0, 0x100L);
case 76:
return jjMoveStringLiteralDfa3_0(active0, 0x40L);
case 77:
return jjMoveStringLiteralDfa3_0(active0, 0x200L);
case 85:
return jjMoveStringLiteralDfa3_0(active0, 0xa000L);
case 97:
return jjMoveStringLiteralDfa3_0(active0, 0xc00L);
case 101:
return jjMoveStringLiteralDfa3_0(active0, 0x1000L);
case 112:
if ((active0 & 0x10L) != 0L)
return jjStartNfaWithStates_0(2, 4, 1);
break;
case 116:
return jjMoveStringLiteralDfa3_0(active0, 0x80L);
default :
break;
}
return jjStartNfa_0(1, active0);
}
private int jjMoveStringLiteralDfa3_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(1, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(2, active0);
return 3;
}
switch(curChar)
{
case 97:
return jjMoveStringLiteralDfa4_0(active0, 0x80L);
case 101:
return jjMoveStringLiteralDfa4_0(active0, 0x40L);
case 105:
return jjMoveStringLiteralDfa4_0(active0, 0x300L);
case 109:
if ((active0 & 0x1000L) != 0L)
return jjStartNfaWithStates_0(3, 12, 1);
break;
case 110:
return jjMoveStringLiteralDfa4_0(active0, 0x8020L);
case 113:
return jjMoveStringLiteralDfa4_0(active0, 0x4000L);
case 115:
return jjMoveStringLiteralDfa4_0(active0, 0x2000L);
case 116:
return jjMoveStringLiteralDfa4_0(active0, 0x800L);
case 121:
return jjMoveStringLiteralDfa4_0(active0, 0x400L);
default :
break;
}
return jjStartNfa_0(2, active0);
}
private int jjMoveStringLiteralDfa4_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(2, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(3, active0);
return 4;
}
switch(curChar)
{
case 97:
return jjMoveStringLiteralDfa5_0(active0, 0x40L);
case 99:
return jjMoveStringLiteralDfa5_0(active0, 0x80L);
case 101:
if ((active0 & 0x2000L) != 0L)
return jjStartNfaWithStates_0(4, 13, 1);
return jjMoveStringLiteralDfa5_0(active0, 0x8400L);
case 115:
return jjMoveStringLiteralDfa5_0(active0, 0xa00L);
case 116:
if ((active0 & 0x100L) != 0L)
return jjStartNfaWithStates_0(4, 8, 1);
return jjMoveStringLiteralDfa5_0(active0, 0x20L);
case 117:
return jjMoveStringLiteralDfa5_0(active0, 0x4000L);
default :
break;
}
return jjStartNfa_0(3, active0);
}
private int jjMoveStringLiteralDfa5_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(3, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(4, active0);
return 5;
}
switch(curChar)
{
case 85:
return jjMoveStringLiteralDfa6_0(active0, 0x800L);
case 101:
return jjMoveStringLiteralDfa6_0(active0, 0x20L);
case 105:
return jjMoveStringLiteralDfa6_0(active0, 0x4000L);
case 107:
if ((active0 & 0x80L) != 0L)
return jjStartNfaWithStates_0(5, 7, 1);
break;
case 113:
return jjMoveStringLiteralDfa6_0(active0, 0x8000L);
case 114:
if ((active0 & 0x400L) != 0L)
return jjStartNfaWithStates_0(5, 10, 1);
break;
case 115:
if ((active0 & 0x200L) != 0L)
return jjStartNfaWithStates_0(5, 9, 1);
break;
case 118:
return jjMoveStringLiteralDfa6_0(active0, 0x40L);
default :
break;
}
return jjStartNfa_0(4, active0);
}
private int jjMoveStringLiteralDfa6_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(4, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(5, active0);
return 6;
}
switch(curChar)
{
case 101:
if ((active0 & 0x40L) != 0L)
return jjStartNfaWithStates_0(6, 6, 1);
break;
case 112:
if ((active0 & 0x4000L) != 0L)
return jjStartNfaWithStates_0(6, 14, 1);
return jjMoveStringLiteralDfa7_0(active0, 0x800L);
case 114:
if ((active0 & 0x20L) != 0L)
return jjStartNfaWithStates_0(6, 5, 1);
break;
case 117:
return jjMoveStringLiteralDfa7_0(active0, 0x8000L);
default :
break;
}
return jjStartNfa_0(5, active0);
}
private int jjMoveStringLiteralDfa7_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(5, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(6, active0);
return 7;
}
switch(curChar)
{
case 100:
return jjMoveStringLiteralDfa8_0(active0, 0x800L);
case 105:
return jjMoveStringLiteralDfa8_0(active0, 0x8000L);
default :
break;
}
return jjStartNfa_0(6, active0);
}
private int jjMoveStringLiteralDfa8_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(6, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(7, active0);
return 8;
}
switch(curChar)
{
case 97:
return jjMoveStringLiteralDfa9_0(active0, 0x800L);
case 112:
if ((active0 & 0x8000L) != 0L)
return jjStartNfaWithStates_0(8, 15, 1);
break;
default :
break;
}
return jjStartNfa_0(7, active0);
}
private int jjMoveStringLiteralDfa9_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(7, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(8, active0);
return 9;
}
switch(curChar)
{
case 116:
return jjMoveStringLiteralDfa10_0(active0, 0x800L);
default :
break;
}
return jjStartNfa_0(8, active0);
}
private int jjMoveStringLiteralDfa10_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(8, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(9, active0);
return 10;
}
switch(curChar)
{
case 101:
return jjMoveStringLiteralDfa11_0(active0, 0x800L);
default :
break;
}
return jjStartNfa_0(9, active0);
}
private int jjMoveStringLiteralDfa11_0(long old0, long active0)
{
if (((active0 &= old0)) == 0L)
return jjStartNfa_0(9, old0);
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) {
jjStopStringLiteralDfa_0(10, active0);
return 11;
}
switch(curChar)
{
case 100:
if ((active0 & 0x800L) != 0L)
return jjStartNfaWithStates_0(11, 11, 1);
break;
default :
break;
}
return jjStartNfa_0(10, active0);
}
private int jjStartNfaWithStates_0(int pos, int kind, int state)
{
jjmatchedKind = kind;
jjmatchedPos = pos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return pos + 1; }
return jjMoveNfa_0(state, pos + 1);
}
private int jjMoveNfa_0(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 3;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0x100002600L & l) != 0L)
kind = 17;
break;
case 1:
if ((0x3ff200000000000L & l) == 0L)
break;
kind = 16;
jjstateSet[jjnewStateCnt++] = 1;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0x7fffffe07fffffeL & l) == 0L)
break;
if (kind > 16)
kind = 16;
jjCheckNAdd(1);
break;
case 1:
if ((0x7fffffe87fffffeL & l) == 0L)
break;
if (kind > 16)
kind = 16;
jjCheckNAdd(1);
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
private final int jjStopStringLiteralDfa_1(int pos, long active0)
{
switch (pos)
{
default :
return -1;
}
}
private final int jjStartNfa_1(int pos, long active0)
{
return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
}
private int jjMoveStringLiteralDfa0_1()
{
switch(curChar)
{
case 93:
return jjStopAtPos(0, 18);
default :
return jjMoveNfa_1(0, 0);
}
}
static final long[] jjbitVec0 = {
0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
};
private int jjMoveNfa_1(int startState, int curPos)
{
int startsAt = 0;
jjnewStateCnt = 1;
int i = 1;
jjstateSet[0] = startState;
int kind = 0x7fffffff;
for (;;)
{
if (++jjround == 0x7fffffff)
ReInitRounds();
if (curChar < 64)
{
long l = 1L << curChar;
do
{
switch(jjstateSet[--i])
{
case 0:
kind = 19;
jjstateSet[jjnewStateCnt++] = 0;
break;
default : break;
}
} while(i != startsAt);
}
else if (curChar < 128)
{
long l = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((0xffffffffdfffffffL & l) == 0L)
break;
kind = 19;
jjstateSet[jjnewStateCnt++] = 0;
break;
default : break;
}
} while(i != startsAt);
}
else
{
int i2 = (curChar & 0xff) >> 6;
long l2 = 1L << (curChar & 077);
do
{
switch(jjstateSet[--i])
{
case 0:
if ((jjbitVec0[i2] & l2) == 0L)
break;
if (kind > 19)
kind = 19;
jjstateSet[jjnewStateCnt++] = 0;
break;
default : break;
}
} while(i != startsAt);
}
if (kind != 0x7fffffff)
{
jjmatchedKind = kind;
jjmatchedPos = curPos;
kind = 0x7fffffff;
}
++curPos;
if ((i = jjnewStateCnt) == (startsAt = 1 - (jjnewStateCnt = startsAt)))
return curPos;
try { curChar = input_stream.readChar(); }
catch(java.io.IOException e) { return curPos; }
}
}
static final int[] jjnextStates = {
};
/** Token literal values. */
public static final String[] jjstrLiteralImages = {
"", "\42", "\56", "\133", "\155\141\160", "\157\156\105\156\164\145\162",
"\157\156\114\145\141\166\145", "\141\164\164\141\143\153", "\157\156\110\151\164",
"\157\156\115\151\163\163", "\160\154\141\171\145\162",
"\163\164\141\164\163\125\160\144\141\164\145\144", "\151\164\145\155", "\157\156\125\163\145", "\157\156\105\161\165\151\160",
"\157\156\125\156\145\161\165\151\160", null, null, "\135", null, };
/** Lexer state names. */
public static final String[] lexStateNames = {
"DEFAULT",
"SCRIPT_CODE",
};
/** Lex State array. */
public static final int[] jjnewLexState = {
-1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1,
};
protected SimpleCharStream input_stream;
private final int[] jjrounds = new int[3];
private final int[] jjstateSet = new int[6];
protected char curChar;
/** Constructor. */
public ATCollectionParserTokenManager(SimpleCharStream stream){
if (SimpleCharStream.staticFlag)
throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
input_stream = stream;
}
/** Constructor. */
public ATCollectionParserTokenManager(SimpleCharStream stream, int lexState){
this(stream);
SwitchTo(lexState);
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream)
{
jjmatchedPos = jjnewStateCnt = 0;
curLexState = defaultLexState;
input_stream = stream;
ReInitRounds();
}
private void ReInitRounds()
{
int i;
jjround = 0x80000001;
for (i = 3; i-- > 0;)
jjrounds[i] = 0x80000000;
}
/** Reinitialise parser. */
public void ReInit(SimpleCharStream stream, int lexState)
{
ReInit(stream);
SwitchTo(lexState);
}
/** Switch to specified lex state. */
public void SwitchTo(int lexState)
{
if (lexState >= 2 || lexState < 0)
throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
else
curLexState = lexState;
}
protected Token jjFillToken()
{
final Token t;
final String curTokenImage;
final int beginLine;
final int endLine;
final int beginColumn;
final int endColumn;
String im = jjstrLiteralImages[jjmatchedKind];
curTokenImage = (im == null) ? input_stream.GetImage() : im;
beginLine = input_stream.getBeginLine();
beginColumn = input_stream.getBeginColumn();
endLine = input_stream.getEndLine();
endColumn = input_stream.getEndColumn();
t = Token.newToken(jjmatchedKind, curTokenImage);
t.beginLine = beginLine;
t.endLine = endLine;
t.beginColumn = beginColumn;
t.endColumn = endColumn;
return t;
}
int curLexState = 0;
int defaultLexState = 0;
int jjnewStateCnt;
int jjround;
int jjmatchedPos;
int jjmatchedKind;
/** Get the next Token. */
public Token getNextToken()
{
Token matchedToken;
int curPos = 0;
EOFLoop :
for (;;)
{
try
{
curChar = input_stream.BeginToken();
}
catch(java.io.IOException e)
{
jjmatchedKind = 0;
matchedToken = jjFillToken();
return matchedToken;
}
switch(curLexState)
{
case 0:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_0();
break;
case 1:
jjmatchedKind = 0x7fffffff;
jjmatchedPos = 0;
curPos = jjMoveStringLiteralDfa0_1();
break;
}
if (jjmatchedKind != 0x7fffffff)
{
if (jjmatchedPos + 1 < curPos)
input_stream.backup(curPos - jjmatchedPos - 1);
matchedToken = jjFillToken();
if (jjnewLexState[jjmatchedKind] != -1)
curLexState = jjnewLexState[jjmatchedKind];
return matchedToken;
}
int error_line = input_stream.getEndLine();
int error_column = input_stream.getEndColumn();
String error_after = null;
boolean EOFSeen = false;
try { input_stream.readChar(); input_stream.backup(1); }
catch (java.io.IOException e1) {
EOFSeen = true;
error_after = curPos <= 1 ? "" : input_stream.GetImage();
if (curChar == '\n' || curChar == '\r') {
error_line++;
error_column = 0;
}
else
error_column++;
}
if (!EOFSeen) {
input_stream.backup(1);
error_after = curPos <= 1 ? "" : input_stream.GetImage();
}
throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR);
}
}
private void jjCheckNAdd(int state)
{
if (jjrounds[state] != jjround)
{
jjstateSet[jjnewStateCnt++] = state;
jjrounds[state] = jjround;
}
}
private void jjAddStates(int start, int end)
{
do {
jjstateSet[jjnewStateCnt++] = jjnextStates[start];
} while (start++ != end);
}
private void jjCheckNAddTwoStates(int state1, int state2)
{
jjCheckNAdd(state1);
jjCheckNAdd(state2);
}
}

View File

@@ -0,0 +1,179 @@
/**
* JavaCC template file created by SF JavaCC plugin 1.5.17+ wizard for JavaCC 1.5.0+
*/
options {
JDK_VERSION = "1.5";
static = false;
}
PARSER_BEGIN(ATCollectionParser)
package com.gpl.rpg.AndorsTrail.scripting.collectionparser;
import java.io.Reader;
import java.util.Map;
import java.util.HashMap;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import com.gpl.rpg.AndorsTrail.scripting.ScriptTrigger;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATScriptParser;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSNode;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSReturnStatement;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSConstantReference;
import com.gpl.rpg.AndorsTrail.scripting.interpreter.ATSLocalVarsHelper;
public class ATCollectionParser {
public static Map < String, Script > parseCollection(Reader scriptCollectionReader) throws ParseException {
Map < String, Script > scripts = new HashMap < String, Script > ();
ATCollectionParser parser = new ATCollectionParser(scriptCollectionReader);
try {
parser.optionalWhiteSpacePrefix(scripts);
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
return scripts;
}
}
PARSER_END(ATCollectionParser)
TOKEN : {
< DQUO : "\"" >
| < DOT : "." >
| < LBRAC : "[" > : SCRIPT_CODE
| < MAP : "map" >
| < ON_ENTER : "onEnter" >
| < ON_LEAVE : "onLeave" >
| < ATTACK : "attack" >
| < ON_HIT : "onHit" >
| < ON_MISS : "onMiss" >
| < PLAYER : "player" >
| < STATS_UPDATED : "statsUpdated" >
| < ITEM : "item" >
| < ON_USE : "onUse" >
| < ON_EQUIP : "onEquip" >
| < ON_UNEQUIP : "onUnequip" >
| < SCRIPT_ID : [ "a"-"z", "A"-"Z" ] ([ "a"-"z", "A"-"Z", "0"-"9", "_", "-" ])* >
| < WHITESPACE : [" ","\r","\t","\n"] >
}
< SCRIPT_CODE >
TOKEN : {
< RBRAC : "]" > : DEFAULT
| < CODE : (~[ "]" ])+ >
}
void optionalWhiteSpacePrefix(Map < String, Script > scripts) throws com.gpl.rpg.AndorsTrail.scripting.interpreter.ParseException : {
Script s;
} {
(<WHITESPACE>)* scriptCollection(scripts)
}
void scriptCollection(Map < String, Script > scripts) throws com.gpl.rpg.AndorsTrail.scripting.interpreter.ParseException : {
Script s;
} {
s = script() (scriptCollection(scripts))
{
scripts.put(s.id, s);
}
| < EOF >
}
Script script() throws com.gpl.rpg.AndorsTrail.scripting.interpreter.ParseException : {
Token id;
Token code = null;
Token desc = null;
ScriptTrigger trigger;
} {
< DQUO > id = < SCRIPT_ID > < DQUO > (<WHITESPACE>)* trigger = trigger() (<WHITESPACE>)* < LBRAC > (code = < CODE >)? < RBRAC > (<WHITESPACE>)* (( < LBRAC > ( desc = <CODE>) ? <RBRAC> ) (<WHITESPACE>)* )?
{
String description = desc == null ? null : desc.image;
if (code != null) {
ATSLocalVarsHelper localVarsRefHelp = new ATSLocalVarsHelper();
ATSNode scriptASTRoot = ATScriptParser.parseScript(code.image, localVarsRefHelp);
return new Script(id.image, description, trigger, scriptASTRoot, localVarsRefHelp.maxNumNeeded, localVarsRefHelp.maxBoolNeeded, localVarsRefHelp.maxStringNeeded, localVarsRefHelp.maxObjectNeeded);
} else {
//Dummy script returning 0;
ATSNode scriptASTRoot = new ATSReturnStatement(new ATSConstantReference(0));
return new Script(id.image, description, trigger, scriptASTRoot, 0, 0, 0, 0);
}
}
}
ScriptTrigger trigger() : {
Token category;
String event;
} {
category = < MAP > < DOT > event = mapEvents()
{
return new ScriptTrigger(category.image, event);
}
| category = < ATTACK > < DOT > event = attackEvents()
{
return new ScriptTrigger(category.image, event);
}
| category = < PLAYER > < DOT > event = playerEvents()
{
return new ScriptTrigger(category.image, event);
}
| category = < ITEM > < DOT > event = itemEvents()
{
return new ScriptTrigger(category.image, event);
}
}
String mapEvents() : {
Token event;
} {
event = < ON_ENTER >
{
return event.image;
}
| event = < ON_LEAVE >
{
return event.image;
}
}
String attackEvents() : {
Token event;
} {
event = < ON_HIT >
{
return event.image;
}
| event = < ON_MISS >
{
return event.image;
}
}
String playerEvents() : {
Token event;
} {
event = < STATS_UPDATED >
{
return event.image;
}
}
String itemEvents() : {
Token event;
} {
event = < ON_USE >
{
return event.image;
}
| event = < ON_EQUIP >
{
return event.image;
}
| event = < ON_UNEQUIP >
{
return event.image;
}

View File

@@ -0,0 +1,187 @@
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
/* JavaCCOptions:KEEP_LINE_COL=null */
package com.gpl.rpg.AndorsTrail.scripting.collectionparser;
/**
* This exception is thrown when parse errors are encountered.
* You can explicitly create objects of this exception type by
* calling the method generateParseException in the generated
* parser.
*
* You can modify this class to customize your error reporting
* mechanisms so long as you retain the public fields.
*/
public class ParseException extends Exception {
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/**
* This constructor is used by the method "generateParseException"
* in the generated parser. Calling this constructor generates
* a new object of this type with the fields "currentToken",
* "expectedTokenSequences", and "tokenImage" set.
*/
public ParseException(Token currentTokenVal,
int[][] expectedTokenSequencesVal,
String[] tokenImageVal
)
{
super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
currentToken = currentTokenVal;
expectedTokenSequences = expectedTokenSequencesVal;
tokenImage = tokenImageVal;
}
/**
* The following constructors are for use by you for whatever
* purpose you can think of. Constructing the exception in this
* manner makes the exception behave in the normal way - i.e., as
* documented in the class "Throwable". The fields "errorToken",
* "expectedTokenSequences", and "tokenImage" do not contain
* relevant information. The JavaCC generated code does not use
* these constructors.
*/
public ParseException() {
super();
}
/** Constructor with message. */
public ParseException(String message) {
super(message);
}
/**
* This is the last token that has been consumed successfully. If
* this object has been created due to a parse error, the token
* followng this token will (therefore) be the first error token.
*/
public Token currentToken;
/**
* Each entry in this array is an array of integers. Each array
* of integers represents a sequence of tokens (by their ordinal
* values) that is expected at this point of the parse.
*/
public int[][] expectedTokenSequences;
/**
* This is a reference to the "tokenImage" array of the generated
* parser within which the parse error occurred. This array is
* defined in the generated ...Constants interface.
*/
public String[] tokenImage;
/**
* It uses "currentToken" and "expectedTokenSequences" to generate a parse
* error message and returns it. If this object has been created
* due to a parse error, and you do not catch it (it gets thrown
* from the parser) the correct error message
* gets displayed.
*/
private static String initialise(Token currentToken,
int[][] expectedTokenSequences,
String[] tokenImage) {
String eol = System.getProperty("line.separator", "\n");
StringBuffer expected = new StringBuffer();
int maxSize = 0;
for (int i = 0; i < expectedTokenSequences.length; i++) {
if (maxSize < expectedTokenSequences[i].length) {
maxSize = expectedTokenSequences[i].length;
}
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
}
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
expected.append("...");
}
expected.append(eol).append(" ");
}
String retval = "Encountered \"";
Token tok = currentToken.next;
for (int i = 0; i < maxSize; i++) {
if (i != 0) retval += " ";
if (tok.kind == 0) {
retval += tokenImage[0];
break;
}
retval += " " + tokenImage[tok.kind];
retval += " \"";
retval += add_escapes(tok.image);
retval += " \"";
tok = tok.next;
}
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
retval += "." + eol;
if (expectedTokenSequences.length == 1) {
retval += "Was expecting:" + eol + " ";
} else {
retval += "Was expecting one of:" + eol + " ";
}
retval += expected.toString();
return retval;
}
/**
* The end of line string for this machine.
*/
protected String eol = System.getProperty("line.separator", "\n");
/**
* Used to convert raw characters to their escaped version
* when these raw version cannot be used as part of an ASCII
* string literal.
*/
static String add_escapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
}
/* JavaCC - OriginalChecksum=7bc9fb1c630164a3ecb25264fc0d7392 (do not edit this line) */

View File

@@ -0,0 +1,471 @@
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package com.gpl.rpg.AndorsTrail.scripting.collectionparser;
/**
* An implementation of interface CharStream, where the stream is assumed to
* contain only ASCII characters (without unicode processing).
*/
public class SimpleCharStream
{
/** Whether parser is static. */
public static final boolean staticFlag = false;
int bufsize;
int available;
int tokenBegin;
/** Position in buffer. */
public int bufpos = -1;
protected int bufline[];
protected int bufcolumn[];
protected int column = 0;
protected int line = 1;
protected boolean prevCharIsCR = false;
protected boolean prevCharIsLF = false;
protected java.io.Reader inputStream;
protected char[] buffer;
protected int maxNextCharInd = 0;
protected int inBuf = 0;
protected int tabSize = 8;
protected void setTabSize(int i) { tabSize = i; }
protected int getTabSize(int i) { return tabSize; }
protected void ExpandBuff(boolean wrapAround)
{
char[] newbuffer = new char[bufsize + 2048];
int newbufline[] = new int[bufsize + 2048];
int newbufcolumn[] = new int[bufsize + 2048];
try
{
if (wrapAround)
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
}
else
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos -= tokenBegin);
}
}
catch (Throwable t)
{
throw new Error(t.getMessage());
}
bufsize += 2048;
available = bufsize;
tokenBegin = 0;
}
protected void FillBuff() throws java.io.IOException
{
if (maxNextCharInd == available)
{
if (available == bufsize)
{
if (tokenBegin > 2048)
{
bufpos = maxNextCharInd = 0;
available = tokenBegin;
}
else if (tokenBegin < 0)
bufpos = maxNextCharInd = 0;
else
ExpandBuff(false);
}
else if (available > tokenBegin)
available = bufsize;
else if ((tokenBegin - available) < 2048)
ExpandBuff(true);
else
available = tokenBegin;
}
int i;
try {
if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
{
inputStream.close();
throw new java.io.IOException();
}
else
maxNextCharInd += i;
return;
}
catch(java.io.IOException e) {
--bufpos;
backup(0);
if (tokenBegin == -1)
tokenBegin = bufpos;
throw e;
}
}
/** Start. */
public char BeginToken() throws java.io.IOException
{
tokenBegin = -1;
char c = readChar();
tokenBegin = bufpos;
return c;
}
protected void UpdateLineColumn(char c)
{
column++;
if (prevCharIsLF)
{
prevCharIsLF = false;
line += (column = 1);
}
else if (prevCharIsCR)
{
prevCharIsCR = false;
if (c == '\n')
{
prevCharIsLF = true;
}
else
line += (column = 1);
}
switch (c)
{
case '\r' :
prevCharIsCR = true;
break;
case '\n' :
prevCharIsLF = true;
break;
case '\t' :
column--;
column += (tabSize - (column % tabSize));
break;
default :
break;
}
bufline[bufpos] = line;
bufcolumn[bufpos] = column;
}
/** Read a character. */
public char readChar() throws java.io.IOException
{
if (inBuf > 0)
{
--inBuf;
if (++bufpos == bufsize)
bufpos = 0;
return buffer[bufpos];
}
if (++bufpos >= maxNextCharInd)
FillBuff();
char c = buffer[bufpos];
UpdateLineColumn(c);
return c;
}
@Deprecated
/**
* @deprecated
* @see #getEndColumn
*/
public int getColumn() {
return bufcolumn[bufpos];
}
@Deprecated
/**
* @deprecated
* @see #getEndLine
*/
public int getLine() {
return bufline[bufpos];
}
/** Get token end column number. */
public int getEndColumn() {
return bufcolumn[bufpos];
}
/** Get token end line number. */
public int getEndLine() {
return bufline[bufpos];
}
/** Get token beginning column number. */
public int getBeginColumn() {
return bufcolumn[tokenBegin];
}
/** Get token beginning line number. */
public int getBeginLine() {
return bufline[tokenBegin];
}
/** Backup a number of characters. */
public void backup(int amount) {
inBuf += amount;
if ((bufpos -= amount) < 0)
bufpos += bufsize;
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
if (buffer == null || buffersize != buffer.length)
{
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
prevCharIsLF = prevCharIsCR = false;
tokenBegin = inBuf = maxNextCharInd = 0;
bufpos = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Get token literal value. */
public String GetImage()
{
if (bufpos >= tokenBegin)
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
else
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
new String(buffer, 0, bufpos + 1);
}
/** Get the suffix. */
public char[] GetSuffix(int len)
{
char[] ret = new char[len];
if ((bufpos + 1) >= len)
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
else
{
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
len - bufpos - 1);
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
}
return ret;
}
/** Reset buffer when finished. */
public void Done()
{
buffer = null;
bufline = null;
bufcolumn = null;
}
/**
* Method to adjust line and column numbers for the start of a token.
*/
public void adjustBeginLineColumn(int newLine, int newCol)
{
int start = tokenBegin;
int len;
if (bufpos >= tokenBegin)
{
len = bufpos - tokenBegin + inBuf + 1;
}
else
{
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
}
int i = 0, j = 0, k = 0;
int nextColDiff = 0, columnDiff = 0;
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
{
bufline[j] = newLine;
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
bufcolumn[j] = newCol + columnDiff;
columnDiff = nextColDiff;
i++;
}
if (i < len)
{
bufline[j] = newLine++;
bufcolumn[j] = newCol + columnDiff;
while (i++ < len)
{
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
bufline[j] = newLine++;
else
bufline[j] = newLine;
}
}
line = bufline[j];
column = bufcolumn[j];
}
}
/* JavaCC - OriginalChecksum=f848550e3fc74470745e2333917cd56b (do not edit this line) */

View File

@@ -0,0 +1,131 @@
/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package com.gpl.rpg.AndorsTrail.scripting.collectionparser;
/**
* Describes the input token stream.
*/
public class Token implements java.io.Serializable {
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/**
* An integer that describes the kind of this token. This numbering
* system is determined by JavaCCParser, and a table of these numbers is
* stored in the file ...Constants.java.
*/
public int kind;
/** The line number of the first character of this Token. */
public int beginLine;
/** The column number of the first character of this Token. */
public int beginColumn;
/** The line number of the last character of this Token. */
public int endLine;
/** The column number of the last character of this Token. */
public int endColumn;
/**
* The string image of the token.
*/
public String image;
/**
* A reference to the next regular (non-special) token from the input
* stream. If this is the last token from the input stream, or if the
* token manager has not read tokens beyond this one, this field is
* set to null. This is true only if this token is also a regular
* token. Otherwise, see below for a description of the contents of
* this field.
*/
public Token next;
/**
* This field is used to access special tokens that occur prior to this
* token, but after the immediately preceding regular (non-special) token.
* If there are no such special tokens, this field is set to null.
* When there are more than one such special token, this field refers
* to the last of these special tokens, which in turn refers to the next
* previous special token through its specialToken field, and so on
* until the first special token (whose specialToken field is null).
* The next fields of special tokens refer to other special tokens that
* immediately follow it (without an intervening regular token). If there
* is no such token, this field is null.
*/
public Token specialToken;
/**
* An optional attribute value of the Token.
* Tokens which are not used as syntactic sugar will often contain
* meaningful values that will be used later on by the compiler or
* interpreter. This attribute value is often different from the image.
* Any subclass of Token that actually wants to return a non-null value can
* override this method as appropriate.
*/
public Object getValue() {
return null;
}
/**
* No-argument constructor
*/
public Token() {}
/**
* Constructs a new token for the specified Image.
*/
public Token(int kind)
{
this(kind, null);
}
/**
* Constructs a new token for the specified Image and Kind.
*/
public Token(int kind, String image)
{
this.kind = kind;
this.image = image;
}
/**
* Returns the image.
*/
public String toString()
{
return image;
}
/**
* Returns a new Token object, by default. However, if you want, you
* can create and return subclass objects based on the value of ofKind.
* Simply add the cases to the switch for all those special cases.
* For example, if you have a subclass of Token called IDToken that
* you want to create if ofKind is ID, simply add something like :
*
* case MyParserConstants.ID : return new IDToken(ofKind, image);
*
* to the following switch statement. Then you can cast matchedToken
* variable to the appropriate type and use sit in your lexical actions.
*/
public static Token newToken(int ofKind, String image)
{
switch(ofKind)
{
default : return new Token(ofKind, image);
}
}
public static Token newToken(int ofKind)
{
return newToken(ofKind, null);
}
}
/* JavaCC - OriginalChecksum=31e350463171d252f8cdd13f05f39d22 (do not edit this line) */

View File

@@ -0,0 +1,147 @@
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
/* JavaCCOptions: */
package com.gpl.rpg.AndorsTrail.scripting.collectionparser;
/** Token Manager Error. */
public class TokenMgrError extends Error
{
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/*
* Ordinals for various reasons why an Error of this type can be thrown.
*/
/**
* Lexical error occurred.
*/
static final int LEXICAL_ERROR = 0;
/**
* An attempt was made to create a second instance of a static token manager.
*/
static final int STATIC_LEXER_ERROR = 1;
/**
* Tried to change to an invalid lexical state.
*/
static final int INVALID_LEXICAL_STATE = 2;
/**
* Detected (and bailed out of) an infinite loop in the token manager.
*/
static final int LOOP_DETECTED = 3;
/**
* Indicates the reason why the exception is thrown. It will have
* one of the above 4 values.
*/
int errorCode;
/**
* Replaces unprintable characters by their escaped (or unicode escaped)
* equivalents in the given string
*/
protected static final String addEscapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
/**
* Returns a detailed message for the Error when it is thrown by the
* token manager to indicate a lexical error.
* Parameters :
* EOFSeen : indicates if EOF caused the lexical error
* curLexState : lexical state in which this error occurred
* errorLine : line number when the error occurred
* errorColumn : column number when the error occurred
* errorAfter : prefix that was seen before this error occurred
* curchar : the offending character
* Note: You can customize the lexical error message by modifying this method.
*/
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
return("Lexical error at line " +
errorLine + ", column " +
errorColumn + ". Encountered: " +
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
"after : \"" + addEscapes(errorAfter) + "\"");
}
/**
* You can also modify the body of this method to customize your error messages.
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
* of end-users concern, so you can return something like :
*
* "Internal Error : Please file a bug report .... "
*
* from this method for such cases in the release version of your parser.
*/
public String getMessage() {
return super.getMessage();
}
/*
* Constructors of various flavors follow.
*/
/** No arg constructor. */
public TokenMgrError() {
}
/** Constructor with message and reason. */
public TokenMgrError(String message, int reason) {
super(message);
errorCode = reason;
}
/** Full Constructor. */
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
}
}
/* JavaCC - OriginalChecksum=9500fc78ac75f898cc4736eb27e47aff (do not edit this line) */

View File

@@ -0,0 +1,19 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public class ATSAssociation extends ATSExpression {
public final ATSValueReference register;
public final ATSValueReference value;
public ATSAssociation(ATSValueReference register, ATSValueReference value) {
this.register = register;
this.value = value;
}
@Override
public Object evaluate(ScriptContext context) {
register.set(context, value.evaluate(context));
return next!=null ? next.evaluate(context) : null;
}
}

View File

@@ -0,0 +1,21 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public class ATSConstantReference extends ATSValueReference {
public final Object value;
public ATSConstantReference(Object value) {
this.value = value;
}
@Override
public void set(ScriptContext context, Object value) {
throw new RuntimeException("ATScript : trying to associate a value to a constant ? come on...");
}
@Override
public Object evaluate(ScriptContext context) {
return value;
}
}

View File

@@ -0,0 +1,56 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public class ATSContextObjectReference extends ATSValueReference {
public enum ContextObject {
world {
@Override
public Object evaluate(ScriptContext context) {
return context.world;
}
},
map{
@Override
public Object evaluate(ScriptContext context) {
return context.map;
}
},
player{
@Override
public Object evaluate(ScriptContext context) {
return context.player;
}
},
actor{
@Override
public Object evaluate(ScriptContext context) {
return context.actor;
}
},
item{
@Override
public Object evaluate(ScriptContext context) {
return context.item;
}
};
public abstract Object evaluate(ScriptContext context);
}
public final ContextObject contextObject;
public ATSContextObjectReference(ContextObject contextObject) {
this.contextObject = contextObject;
}
@Override
public void set(ScriptContext context, Object value) {
throw new RuntimeException("ATScript : No associations to non-primitive objects please...");
}
@Override
public Object evaluate(ScriptContext context) {
return contextObject.evaluate(context);
}
}

View File

@@ -0,0 +1,7 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public abstract class ATSExpression extends ATSNode {
public ATSExpression next = null;
}

View File

@@ -0,0 +1,28 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public class ATSFlowControl extends ATSExpression {
public final ATSValueReference condition;
public final ATSExpression ifBlock, elseBlock;
public ATSFlowControl(ATSValueReference condition, ATSExpression ifBlock, ATSExpression optionalElseBlock) {
this.condition = condition;
this.ifBlock = ifBlock;
this.elseBlock = optionalElseBlock;
}
@Override
public Object evaluate(ScriptContext context) {
Object returned = null;
if ((Boolean)condition.evaluate(context)) {
returned = ifBlock.evaluate(context);
} else if (elseBlock != null) {
returned = elseBlock.evaluate(context);
}
if (context.returnReached) return returned;
return next!=null ? next.evaluate(context) : returned;
}
}

View File

@@ -0,0 +1,69 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public class ATSLocalVarReference extends ATSValueReference {
public enum VarType {
num {
@Override
public void set(ScriptContext context, Object value, int index) {
context.localNums[index] = (Double)value;
}
@Override
public Object evaluate(ScriptContext context, int index) {
return context.localNums[index];
}
},
bool{
@Override
public void set(ScriptContext context, Object value, int index) {
context.localBools[index] = (Boolean)value;
}
@Override
public Object evaluate(ScriptContext context, int index) {
return context.localBools[index];
}
},
string{
@Override
public void set(ScriptContext context, Object value, int index) {
context.localStrings[index] = (String)value;
}
@Override
public Object evaluate(ScriptContext context, int index) {
return context.localStrings[index];
}
},
object{
@Override
public void set(ScriptContext context, Object value, int index) {
context.localObjects[index] = value;
}
@Override
public Object evaluate(ScriptContext context, int index) {
return context.localObjects[index];
}
};
public abstract void set(ScriptContext context, Object value, int index);
public abstract Object evaluate(ScriptContext context, int index);
}
public final int index;
public final VarType type;
public ATSLocalVarReference(VarType type, int index) {
this.type = type;
this.index = index;
}
@Override
public void set(ScriptContext context, Object value) {
type.set(context, value, index);
}
@Override
public Object evaluate(ScriptContext context) {
return type.evaluate(context, index);
}
}

View File

@@ -0,0 +1,83 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
public class ATSLocalVarsHelper {
public int maxNumNeeded = 0;
public int maxBoolNeeded = 0;
public int maxStringNeeded = 0;
public int maxObjectNeeded = 0;
public Stack<Integer> numIndexInScope = new Stack<Integer>();
public Stack<Integer> boolIndexInScope = new Stack<Integer>();
public Stack<Integer> stringIndexInScope = new Stack<Integer>();
public Stack<Integer> objectIndexInScope = new Stack<Integer>();
public Stack<Map<String, ATSLocalVarReference>> variablesInScope = new Stack<Map<String,ATSLocalVarReference>>();
public ATSLocalVarsHelper() {
numIndexInScope.push(maxNumNeeded);
boolIndexInScope.push(maxBoolNeeded);
stringIndexInScope.push(maxStringNeeded);
objectIndexInScope.push(maxObjectNeeded);
variablesInScope.push(new HashMap<String, ATSLocalVarReference>());
}
public void pushScope() {
numIndexInScope.push(numIndexInScope.peek());
boolIndexInScope.push(boolIndexInScope.peek());
stringIndexInScope.push(stringIndexInScope.peek());
objectIndexInScope.push(objectIndexInScope.peek());
variablesInScope.push(new HashMap<String, ATSLocalVarReference>(variablesInScope.peek()));
}
public void popScope() {
maxNumNeeded = Math.max(maxNumNeeded, numIndexInScope.pop());
maxBoolNeeded = Math.max(maxBoolNeeded, boolIndexInScope.pop());
maxStringNeeded = Math.max(maxStringNeeded, stringIndexInScope.pop());
maxObjectNeeded = Math.max(maxObjectNeeded, objectIndexInScope.pop());
variablesInScope.pop();
}
public ATSLocalVarReference newNumVariable(String name) {
int index = numIndexInScope.pop();
ATSLocalVarReference varRef = new ATSLocalVarReference(ATSLocalVarReference.VarType.num, index);
numIndexInScope.push(++index);
variablesInScope.peek().put(name, varRef);
return varRef;
}
public ATSLocalVarReference newBoolVariable(String name) {
int index = boolIndexInScope.pop();
ATSLocalVarReference varRef = new ATSLocalVarReference(ATSLocalVarReference.VarType.bool, index);
boolIndexInScope.push(++index);
variablesInScope.peek().put(name, varRef);
return varRef;
}
public ATSLocalVarReference newStringVariable(String name) {
int index = stringIndexInScope.pop();
ATSLocalVarReference varRef = new ATSLocalVarReference(ATSLocalVarReference.VarType.string, index);
stringIndexInScope.push(++index);
variablesInScope.peek().put(name, varRef);
return varRef;
}
public ATSLocalVarReference newObjectVariable(String name) {
int index = stringIndexInScope.pop();
ATSLocalVarReference varRef = new ATSLocalVarReference(ATSLocalVarReference.VarType.object, index);
objectIndexInScope.push(++index);
variablesInScope.peek().put(name, varRef);
return varRef;
}
public ATSLocalVarReference getLocalVar(String name) {
return variablesInScope.peek().get(name);
}
}

View File

@@ -0,0 +1,167 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.Inventory;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.item.ItemTypeCollection;
import com.gpl.rpg.AndorsTrail.model.map.MapObject;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.model.quest.QuestProgress;
import com.gpl.rpg.AndorsTrail.scripting.proxyobjects.Item;
import com.gpl.rpg.AndorsTrail.util.ConstRange;
public class ATSMethodCall extends ATSValueReference {
public enum ObjectMethod {
worldGetMap {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
return ((WorldContext)targetInstance).maps.findPredefinedMap((String)parameters[0].evaluate(context));
}
},
mapActivateGroup {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
//TODO move this logic in the controller as activateGroup(PredefinedMap map, String group)
String group = (String) parameters[0].evaluate(context);
for (MapObject o : ((PredefinedMap)targetInstance).eventObjects) {
if (o.group.equals(group)) {
context.controllers.mapController.activateMapObject((PredefinedMap) targetInstance, o);
}
}
return null;
}
},
mapDeactivateGroup {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
//TODO move this logic in the controller as deactivateGroup(PredefinedMap map, String group)
String group = (String) parameters[0].evaluate(context);
for (MapObject o : ((PredefinedMap)targetInstance).eventObjects) {
if (o.group.equals(group)) {
context.controllers.mapController.deactivateMapObject(o);
}
}
return null;
}
},
actorAddCondition {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
context.controllers.actorStatsController.rollForConditionEffect(((Actor)targetInstance), new ActorConditionEffect(context.world.actorConditionsTypes.getActorConditionType((String)parameters[0].evaluate(context)), ((Double)parameters[1].evaluate(context)).intValue(), ((Double)parameters[2].evaluate(context)).intValue(), new ConstRange(100, ((Double)parameters[3].evaluate(context)).intValue()) ));
return null;
}
},
actorClearCondition {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
context.controllers.actorStatsController.rollForConditionEffect(((Actor)targetInstance), new ActorConditionEffect(context.world.actorConditionsTypes.getActorConditionType((String)parameters[0].evaluate(context)), ActorCondition.MAGNITUDE_REMOVE_ALL, 1, new ConstRange(100, ((Double)parameters[1].evaluate(context)).intValue()) ));
return null;
}
},
getItemCount {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
return ((Player)targetInstance).inventory.getItemQuantity((String) parameters[0].evaluate(context));
}
},
giveItem {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
((Player)targetInstance).inventory.addItem(context.world.itemTypes.getItemType((String) parameters[0].evaluate(context)), ((Double) parameters[1].evaluate(context)).intValue());
return null;
}
},
removeItem {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
((Player)targetInstance).inventory.removeItem((String) parameters[0].evaluate(context), ((Double) parameters[1].evaluate(context)).intValue());
return null;
}
},
getItemInSlot {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
ItemType type = ((Player)targetInstance).inventory.getItemTypeInWearSlot(Inventory.WearSlot.valueOf((String) parameters[0].evaluate(context)));
return new Item(type, null, type.effects_equip); //TODO better "object" handling
}
},
equipItemInSlot {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
ItemType type = context.world.itemTypes.getItemType((String) parameters[0].evaluate(context));
context.controllers.itemController.equipItem(type, Inventory.WearSlot.valueOf((String) parameters[1].evaluate(context)));
return null;
}
},
unequipSlot {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
//TODO Throws a systematic NPE until unequipSlot stops using ItemType...
context.controllers.itemController.unequipSlot(null, Inventory.WearSlot.valueOf((String) parameters[1].evaluate(context)));
return null;
}
},
hasQuestProgress {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
return ((Player)targetInstance).hasExactQuestProgress((String) parameters[0].evaluate(context), ((Double) parameters[1].evaluate(context)).intValue());
}
},
addQuestProgress {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
return ((Player)targetInstance).addQuestProgress(new QuestProgress((String) parameters[0].evaluate(context), ((Double) parameters[1].evaluate(context)).intValue()));
}
},
addExperience {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
context.controllers.actorStatsController.addExperience(((Double)parameters[0].evaluate(context)).intValue());
return null;
}
},
addAlignment {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
((Player)targetInstance).addAlignment((String) parameters[0].evaluate(context), ((Double) parameters[1].evaluate(context)).intValue());
return null;
}
},
getAlignment {
@Override
public Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).getAlignment((String) parameters[0].evaluate(context)));
}
};
public abstract Object evaluate(ScriptContext context, ATSValueReference[] parameters, Object targetInstance);
}
public final ObjectMethod method;
public final ATSValueReference[] parameters;
public final ATSValueReference targetInstance;
public ATSMethodCall(ObjectMethod method, ATSValueReference[] parameters, ATSValueReference optionalTargetInstance) {
this.method = method;
this.parameters = parameters;
this.targetInstance = optionalTargetInstance;
}
@Override
public void set(ScriptContext context, Object value) {
throw new RuntimeException("ATScript : Trying to associate a value to a method result ? come on...");
}
@Override
public Object evaluate(ScriptContext context) {
Object returned = method.evaluate(context, parameters, targetInstance.evaluate(context));
return next!=null ? next.evaluate(context) : returned;
}
}

View File

@@ -0,0 +1,7 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public abstract class ATSNode {
public abstract Object evaluate(ScriptContext context);
}

View File

@@ -0,0 +1,314 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.scripting.proxyobjects.Item;
public class ATSObjectFieldReference extends ATSValueReference {
public enum ObjectFields {
mapOutdoor{
@Override
public void set(ScriptContext context, Object value, Object noUseHere) {
throw new RuntimeException("ATScript : map.outdoor is not writable");
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return ((PredefinedMap)targetInstance).isOutdoors;
}
},
actorAc{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Actor)targetInstance).attackChance = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Actor)targetInstance).attackChance);
}
},
actorBc{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Actor)targetInstance).blockChance = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Actor)targetInstance).blockChance);
}
},
actorHpCur{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Actor)targetInstance).health.current = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Actor)targetInstance).health.current);
}
},
actorHpMax{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Actor)targetInstance).health.max = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Actor)targetInstance).health.max);
}
},
actorApCur{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Actor)targetInstance).ap.current = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Actor)targetInstance).ap.current);
}
},
actorApMax{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Actor)targetInstance).ap.max = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Actor)targetInstance).ap.max);
}
},
actorAdMin{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Actor)targetInstance).damagePotential.current = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Actor)targetInstance).damagePotential.current);
}
},
actorAdMax{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Actor)targetInstance).damagePotential.max = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Actor)targetInstance).damagePotential.max);
}
},
playerBaseAc{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Player)targetInstance).baseTraits.attackChance = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.attackChance);
}
},
playerBaseBc{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Player)targetInstance).baseTraits.blockChance = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.blockChance);
}
},
playerBaseMaxHP {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Player)targetInstance).baseTraits.maxHP = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.maxHP);
}
},
playerBaseMaxAP {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
//TODO : check if this should be allowed.
((Player)targetInstance).baseTraits.maxAP = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.maxAP);
}
},
playerBaseMoveCost {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Player)targetInstance).baseTraits.moveCost = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.moveCost);
}
},
playerBaseEquipCost {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
//TODO : check if this should be allowed.
((Player)targetInstance).baseTraits.reequipCost = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.reequipCost);
}
},
playerBaseUseCost {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
//TODO : check if this should be allowed.
((Player)targetInstance).baseTraits.useItemCost = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.useItemCost);
}
},
playerBaseAdMin {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
//TODO : check if this should be allowed.
((Player)targetInstance).baseTraits.damagePotential.current = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.damagePotential.current);
}
},
playerBaseAdMax {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
//TODO : check if this should be allowed.
((Player)targetInstance).baseTraits.damagePotential.max = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).baseTraits.damagePotential.max);
}
},
playerLevel {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
throw new RuntimeException("ATScript : player.level is not writable");
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).level);
}
},
playerTotalExp {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
//TODO : check if this should be allowed.
((Player)targetInstance).totalExperience = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).totalExperience);
}
},
playerCurrentExp {
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
//TODO : check if this should be allowed.
((Player)targetInstance).levelExperience.current = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Player)targetInstance).levelExperience.current);
}
},
itemCategory{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
throw new RuntimeException("ATScript : item.category is not writable");
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return ((Item)targetInstance).category;
}
},
itemId{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
throw new RuntimeException("ATScript : item.id is not writable");
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return ((Item)targetInstance).id;
}
},
itemRewardHpMax{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Item)targetInstance).reward.hpMax = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Item)targetInstance).reward.hpMax);
}
},
itemRewardHpMin{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Item)targetInstance).reward.hpMin = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Item)targetInstance).reward.hpMin);
}
},
itemRewardApMax{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Item)targetInstance).reward.apMax = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Item)targetInstance).reward.apMax);
}
},
itemRewardApMin{
@Override
public void set(ScriptContext context, Object value, Object targetInstance) {
((Item)targetInstance).reward.apMin = ((Double)value).intValue();
}
@Override
public Object evaluate(ScriptContext context, Object targetInstance) {
return Double.valueOf(((Item)targetInstance).reward.apMin);
}
};
public Object targetInstance = null;
public abstract void set(ScriptContext context, Object value, Object optionalTargetInstance);
public abstract Object evaluate(ScriptContext context, Object optionalTargetInstance);
}
public final ObjectFields targetField;
public final ATSValueReference targetInstance;
public ATSObjectFieldReference(ObjectFields targetField, ATSValueReference optionalTargetInstance) {
this.targetField = targetField;
this.targetInstance = optionalTargetInstance;
}
@Override
public void set(ScriptContext context, Object value) {
targetField.set(context, value, targetInstance == null ? null : targetInstance.evaluate(context));
}
@Override
public Object evaluate(ScriptContext context) {
return targetField.evaluate(context, targetInstance == null ? null : targetInstance.evaluate(context));
}
}

View File

@@ -0,0 +1,95 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public class ATSPrimitiveOperation extends ATSValueReference {
public static enum Operator {
not {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Boolean)rightHand.evaluate(context)) ? Boolean.FALSE : Boolean.TRUE;
};
},
and {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Boolean)leftHand.evaluate(context)) && ((Boolean)rightHand.evaluate(context));
};
},
or {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Boolean)leftHand.evaluate(context)) || ((Boolean)rightHand.evaluate(context));
};
},
gt {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Double)leftHand.evaluate(context)) > ((Double)rightHand.evaluate(context));
};
},
lt {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Double)leftHand.evaluate(context)) < ((Double)rightHand.evaluate(context));
};
},
goe {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Double)leftHand.evaluate(context)) >= ((Double)rightHand.evaluate(context));
};
},
loe {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Double)leftHand.evaluate(context)) <= ((Double)rightHand.evaluate(context));
};
},
eq {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return leftHand.evaluate(context).equals(rightHand.evaluate(context));
};
},
plus {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Double)leftHand.evaluate(context)) + ((Double)rightHand.evaluate(context));
};
},
minus {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Double)leftHand.evaluate(context)) - ((Double)rightHand.evaluate(context));
};
},
multiply {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Double)leftHand.evaluate(context)) * ((Double)rightHand.evaluate(context));
};
},
divide {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
return ((Double)leftHand.evaluate(context)) / ((Double)rightHand.evaluate(context));
};
},
concat {
public Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand) {
//Could be any object, including string and numbers. More flexible and efficient than a String cast.
return leftHand.evaluate(context).toString() + rightHand.evaluate(context).toString();
}
};
public abstract Object evaluate(ScriptContext context, ATSValueReference leftHand, ATSValueReference rightHand);
}
private final ATSValueReference leftHand, rightHand;
private final Operator operator;
public ATSPrimitiveOperation(Operator operator, ATSValueReference leftHand, ATSValueReference rightHand) {
this.leftHand = leftHand;
this.rightHand = rightHand;
this.operator = operator;
}
@Override
public void set(ScriptContext context, Object value) {
throw new RuntimeException("ATScript : Trying to associate a value to an operation's result ? come on...");
}
@Override
public Object evaluate(ScriptContext context) {
return operator.evaluate(context, leftHand, rightHand);
}
}

View File

@@ -0,0 +1,18 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public class ATSReturnStatement extends ATSExpression {
public final ATSValueReference value;
public ATSReturnStatement(ATSValueReference value) {
this.value = value;
}
@Override
public Object evaluate(ScriptContext context) {
Object returned = value.evaluate(context);
context.returnReached = true;
return returned;
}
}

View File

@@ -0,0 +1,7 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public abstract class ATSValueReference extends ATSExpression {
public abstract void set(ScriptContext context, Object value);
}

View File

@@ -0,0 +1,25 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
public class ATSWhileLoop extends ATSExpression {
public final ATSValueReference condition;
public final ATSExpression whileBlock;
public ATSWhileLoop(ATSValueReference condition, ATSExpression whileBlock) {
this.condition = condition;
this.whileBlock = whileBlock;
}
@Override
public Object evaluate(ScriptContext context) {
Object returned = null;
while (!(Boolean)condition.evaluate(context)) {
returned = whileBlock.evaluate(context);
}
if (context.returnReached) return returned;
return next!=null ? next.evaluate(context) : returned;
}
}

View File

@@ -0,0 +1,641 @@
/**
* JavaCC template file created by SF JavaCC plugin 1.5.17+ wizard for JavaCC 1.5.0+
*/
options {
JDK_VERSION = "1.5";
static = false;
}
PARSER_BEGIN(ATScriptParser)
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
import java.io.BufferedReader;
import java.io.StringReader;
public class ATScriptParser {
public static ATSNode parseScript(String script, ATSLocalVarsHelper localVarRefHelp) throws ParseException {
StringReader reader = new StringReader(script);
BufferedReader scriptReader = new BufferedReader(reader);
ATScriptParser parser = new ATScriptParser(scriptReader);
try {
return parser.parseScope(localVarRefHelp);
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
return null;
}
}
PARSER_END(ATScriptParser)
SKIP : {
" "
| "\r"
| "\t"
| "\n"
}
TOKEN : {
<DOT : ".">
| <LPAR : "(">
| <RPAR : ")">
| <LBRAC : "{">
| <RBRAC : "}">
| <SCOL : ";">
| <COMA : ",">
| <IF : "if">
| <ELSE : "else">
| <WHILE : "while">
| <RETURN : "return">
| <TRUE : "true">
| <FALSE : "false">
| <EXCLAM : "!">
| <GOE : ">=">
| <LOE : "<=">
| <GT : ">">
| <LT : "<">
| <EQ : "==">
| <PLUS : "+">
| <MINUS : "-">
| <MULTIPLY : "*">
| <DIVIDE : "/">
| <CONCAT : "%">
| <AND : "&&">
| <OR : "||">
| <EQUALS : "=">
| <DQUO : "\""> : LITERAL
| <NUMBER : (["-"])?(["0"-"9"])+(["."](["0"-"9"])+)?>
| <MAP : "map">
| <WORLD : "world">
| <ATTACK : "attack">
| <PLAYER : "player">
| <ACTOR : "actor">
| <ITEM : "item">
| <OUTDOOR : "outdoor">
| <ACTIVATEGROUP : "activateGroup">
| <DEACTIVATEGROUP : "deactivateGroup">
| <GETMAP : "getMap">
| <CURRENT : "current">
| <SOURCE : "source">
| <TARGET : "target">
| <DAMAGE : "damage">
| <CATEGORY : "category">
| <REWARD : "reward">
| <ADDCONDITION : "addActorCondition">
| <CLEARCONDITION : "clearActorCondition">
| <GETITEMCOUNT : "getItemCount">
| <GIVEITEM : "giveItem">
| <REMOVEITEM : "removeItem">
| <GETITEMINSLOT : "getItemInSlot">
| <EQUIPITEMINSLOT : "equipItemInSlot">
| <UNEQUIPSLOT : "unequipSlot">
| <HASQUESTPROGRESS : "hasQuestProgress">
| <ADDQUESTPROGRESS : "addQuestProgress">
| <ACTORCONDITIONS : "actorConditions"> //TODO
| <TOSOURCE : "toSource">
| <TOTARGET : "toTarget">
| <BASE : "base">
| <MAXHP : "maxHP">
| <MAXAP : "maxAP">
| <MOVECOST : "moveCost">
| <EQUIPCOST : "equipCost">
| <USECOST : "useCost">
| <ADDEXPERIENCE : "addExperience">
| <LEVEL : "level">
| <TOTALEXP : "totalExp">
| <CURRENTEXP : "currentExp">
| <ADDALIGNMENT : "addAlignment">
| <GETALIGNMENT : "getAlignment">
| <ID : "id">
| <HP : "hp">
| <AP : "ap">
| <AC : "ac">
| <AD : "ad">
| <BC : "bc">
| <DR : "dr">
| <CC : "cc">
| <CM : "cm">
| <MIN : "min">
| <MAX : "max">
| <CUR : "cur">
| <BOOL : "bool">
| <NUM : "num">
| <STRING : "string">
| <OBJECT : "object">
| <IDENTIFIER : ["a"-"z","A"-"Z"](["a"-"z","A"-"Z","0"-"9","-","_"])*>
}
<LITERAL>
TOKEN : {
<ESCAPED_DQUO : "\\\"">
| <DQUOBIS : "\""> : DEFAULT
| <LITERAL_VALUE : (~["\"","\\"])+>
}
ATSExpression parseScope(ATSLocalVarsHelper localVars) : {
ATSExpression scriptRoot;
localVars.pushScope();
} {
scriptRoot = parseScript(localVars)
{
localVars.popScope();
return scriptRoot;
}
}
ATSExpression parseScript(ATSLocalVarsHelper localVars) : {
ATSExpression scriptRoot, next;
} {
scriptRoot = construct(localVars) next = parseScript(localVars)
{
scriptRoot.next = next;
return scriptRoot;
}
| <EOF>
{
return null;
}
| <RBRAC>
{
return null;
}
}
ATSExpression construct(ATSLocalVarsHelper localVars) : {
ATSExpression construct;
} {
construct = associationOrMethodCall(localVars)
{
return construct;
}
| construct = ifElseConstruct(localVars)
{
return construct;
}
| construct = whileConstruct(localVars)
{
return construct;
}
| construct = returnConstruct(localVars)
{
return construct;
}
}
ATSExpression associationOrMethodCall(ATSLocalVarsHelper localVars) : {
ATSValueReference assignee;
ATSValueReference value = null;
} {
assignee = reference(localVars) (<EQUALS> value = value(localVars))? <SCOL>
{
if (value != null) {
return new ATSAssociation(assignee, value);
} else {
//Method call...
return assignee;
}
}
}
ATSValueReference reference(ATSLocalVarsHelper localVars) : {
ATSValueReference assignee;
} {
assignee = localVarDeclaration(localVars)
{
return assignee;
}
| assignee = contextVarReference(localVars)
{
return assignee;
}
}
ATSValueReference localVarDeclaration(ATSLocalVarsHelper localVars) : {
Token id;
int index;
} {
<BOOL> id = <IDENTIFIER>
{
if (localVars.getLocalVar(id.image)!= null) {
throw new ParseException("ATScript : Duplicate variable "+id.image+" at line "+id.beginLine+" column "+id.beginColumn);
}
return localVars.newBoolVariable(id.image);
}
| <NUM> id = <IDENTIFIER>
{
if (localVars.getLocalVar(id.image)!= null) {
throw new ParseException("ATScript : Duplicate variable "+id.image+" at line "+id.beginLine+" column "+id.beginColumn);
}
return localVars.newNumVariable(id.image);
}
| <STRING> id = <IDENTIFIER>
{
if (localVars.getLocalVar(id.image)!=null) {
throw new ParseException("ATScript : Duplicate variable "+id.image+" at line "+id.beginLine+" column "+id.beginColumn);
}
return localVars.newStringVariable(id.image);
}
| <OBJECT> id = <IDENTIFIER>
{
if (localVars.getLocalVar(id.image)!=null) {
throw new ParseException("ATScript : Duplicate variable "+id.image+" at line "+id.beginLine+" column "+id.beginColumn);
}
return localVars.newObjectVariable(id.image);
}
}
ATSValueReference contextVarReference(ATSLocalVarsHelper localVars) : {
ATSValueReference reference = null;
Token id;
} {
<MAP> (<DOT> reference = mapReference(localVars, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.map)))?
{
if (reference != null) return reference;
return new ATSContextObjectReference(ATSContextObjectReference.ContextObject.map);
}
| <ATTACK> <DOT> reference = attackReference(localVars)
{
return reference;
}
| <PLAYER> (<DOT> reference = playerReference(localVars))?
{
if (reference != null) return reference;
return new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player);
}
| <ACTOR> (<DOT> reference = actorReference(localVars, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.actor)))?
{
if (reference != null) return reference;
return new ATSContextObjectReference(ATSContextObjectReference.ContextObject.actor);
}
| <WORLD> (<DOT> reference = worldReference(localVars))?
{
if (reference != null) return reference;
return new ATSContextObjectReference(ATSContextObjectReference.ContextObject.world);
}
| <ITEM> (<DOT> reference = itemReference(localVars, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.item)))?
{
if (reference != null) return reference;
return new ATSContextObjectReference(ATSContextObjectReference.ContextObject.item);
}
| id = <IDENTIFIER>
{
ATSLocalVarReference var = localVars.getLocalVar(id.image);
if (var == null) {
throw new ParseException("Undeclared variable "+id.image+" at line"+id.beginLine+" column "+id.beginColumn);
}
return var;
}
}
ATSExpression whileConstruct(ATSLocalVarsHelper localVars) : {
ATSExpression block;
ATSValueReference condition;
} {
<WHILE> <LPAR> condition = value(localVars) <RPAR> <LBRAC> block = parseScope(localVars)
{
return new ATSWhileLoop(condition, block);
}
}
ATSExpression ifElseConstruct(ATSLocalVarsHelper localVars) : {
ATSExpression ifBlock, elseBlock=null;
ATSValueReference ifCondition;
} {
<IF> <LPAR> ifCondition = value(localVars) <RPAR> <LBRAC> ifBlock = parseScope(localVars) ( <ELSE> elseBlock = elseBlock(localVars))?
{
return new ATSFlowControl(ifCondition,ifBlock,elseBlock);
}
}
ATSExpression elseBlock(ATSLocalVarsHelper localVars) : {
ATSExpression block;
} {
<LBRAC> block = parseScope(localVars)
{
return block;
}
| block = ifElseConstruct(localVars)
{
return block;
}
}
ATSExpression returnConstruct(ATSLocalVarsHelper localVars) : {
ATSValueReference value;
} {
<RETURN> value = value(localVars)
{
return new ATSReturnStatement(value);
}
}
ATSValueReference value(ATSLocalVarsHelper localVars) : {
ATSValueReference reference;
ATSPrimitiveOperation operation = null;
Token tok;
} {
reference = reference(localVars) (operation = valueOp(localVars, reference)) ?
{
if (operation != null) {
return operation;
} else {
return reference;
}
}
| tok = <NUMBER> (operation = valueOp(localVars, new ATSConstantReference(new Double(tok.image)))) ?
{
if (operation != null) {
return operation;
} else {
return new ATSConstantReference(new Double(tok.image));
}
}
| <LPAR> reference = value(localVars) <RPAR>
{
return reference;
}
| <EXCLAM> reference = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.not, null, reference);
}
| <TRUE>
{
return new ATSConstantReference(Boolean.TRUE);
}
| <FALSE>
{
return new ATSConstantReference(Boolean.FALSE);
}
| <DQUO> tok=<LITERAL_VALUE> <DQUOBIS>
{
return new ATSConstantReference(tok.image);
}
}
ATSPrimitiveOperation valueOp(ATSLocalVarsHelper localVars, ATSValueReference leftHand) : {
ATSValueReference value;
} {
<GT> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.gt, leftHand, value);
}
| <LT> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.lt, leftHand, value);
}
| <GOE> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.goe, leftHand, value);
}
| <LOE> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.loe, leftHand, value);
}
| <EQ> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.eq, leftHand, value);
}
| <PLUS> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.plus, leftHand, value);
}
| <MINUS> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.minus, leftHand, value);
}
| <MULTIPLY> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.multiply, leftHand, value);
}
| <DIVIDE> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.divide, leftHand, value);
}
| <CONCAT> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.concat, leftHand, value);
}
| <AND> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.and, leftHand, value);
}
| <OR> value = value(localVars)
{
return new ATSPrimitiveOperation(ATSPrimitiveOperation.Operator.or, leftHand, value);
}
}
ATSValueReference mapReference(ATSLocalVarsHelper localVars, ATSValueReference targetInstance) : {
ATSValueReference param1;
} {
<OUTDOOR>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.mapOutdoor, targetInstance);
}
| <ACTIVATEGROUP> <LPAR> param1 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.mapActivateGroup, new ATSValueReference[]{param1}, targetInstance);
}
| <DEACTIVATEGROUP> <LPAR> param1 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.mapDeactivateGroup, new ATSValueReference[]{param1}, targetInstance);
}
}
ATSValueReference attackReference(ATSLocalVarsHelper localVars) : {
} {
{
return null;
}
}
ATSValueReference playerReference(ATSLocalVarsHelper localVars) : {
ATSValueReference ref;
ATSValueReference param1, param2;
} {
ref = actorReference(localVars, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player))
{
return ref;
}
| <BASE> <DOT> ref = playerBaseReference(localVars, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player))
{
return ref;
}
| <GETITEMCOUNT> <LPAR> param1 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.getItemCount, new ATSValueReference[]{param1}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <GIVEITEM> <LPAR> param1 = value(localVars) <COMA> param2 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.giveItem, new ATSValueReference[]{param1, param2}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <REMOVEITEM> <LPAR> param1 = value(localVars) <COMA> param2 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.removeItem, new ATSValueReference[]{param1, param2}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <GETITEMINSLOT> <LPAR> param1 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.getItemInSlot, new ATSValueReference[]{param1}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <EQUIPITEMINSLOT> <LPAR> param1 = value(localVars) <COMA> param2 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.equipItemInSlot, new ATSValueReference[]{param1, param2}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <UNEQUIPSLOT> <LPAR> param1 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.unequipSlot, new ATSValueReference[]{param1}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <HASQUESTPROGRESS> <LPAR> param1 = value(localVars) <COMA> param2 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.hasQuestProgress, new ATSValueReference[]{param1, param2}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <ADDQUESTPROGRESS> <LPAR> param1 = value(localVars) <COMA> param2 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.addQuestProgress, new ATSValueReference[]{param1, param2}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <ADDEXPERIENCE> <LPAR> param1 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.addExperience, new ATSValueReference[]{param1}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <ADDALIGNMENT> <LPAR> param1 = value(localVars) <COMA> param2 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.addAlignment, new ATSValueReference[]{param1, param2}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
| <GETALIGNMENT> <LPAR> param1 = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.addAlignment, new ATSValueReference[]{param1}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.player));
}
}
ATSValueReference playerBaseReference(ATSLocalVarsHelper localVars, ATSContextObjectReference targetInstance) : {
} {
<MAXHP>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseMaxHP, targetInstance);
}
| <MAXAP>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseMaxAP, targetInstance);
}
| <MOVECOST>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseMoveCost, targetInstance);
}
| <EQUIPCOST>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseEquipCost, targetInstance);
}
| <USECOST>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseUseCost, targetInstance);
}
| <AC>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseAc, targetInstance);
}
| <BC>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseBc, targetInstance);
}
| LOOKAHEAD(3)
<AD> <DOT> <MIN>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseAdMin, targetInstance);
}
| <AD> <DOT> <MIN>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.playerBaseAdMax, targetInstance);
}
}
ATSValueReference actorReference(ATSLocalVarsHelper localVars, ATSContextObjectReference targetInstance) : {
ATSValueReference condId, condMagnitude, condDuration, condChance;
} {
<AC>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.actorAc, targetInstance);
}
| <BC>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.actorBc, targetInstance);
}
| LOOKAHEAD(3)
<HP> <DOT> <CUR>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.actorHpCur, targetInstance);
}
| <HP> <DOT> <MAX>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.actorHpMax, targetInstance);
}
| LOOKAHEAD(3)
<AP> <DOT> <CUR>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.actorApCur, targetInstance);
}
| <AP> <DOT> <MAX>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.actorApMax, targetInstance);
}
| LOOKAHEAD(3)
<AD> <DOT> <MIN>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.actorAdMin, targetInstance);
}
| <AD> <DOT> <MAX>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.actorAdMax, targetInstance);
}
| <ADDCONDITION> <LPAR> condId = value(localVars) <COMA> condMagnitude = value(localVars) <COMA> condDuration = value(localVars) <COMA> condChance = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.actorAddCondition, new ATSValueReference[]{condId, condMagnitude, condDuration, condChance}, targetInstance);
}
| <CLEARCONDITION> <LPAR> condId = value(localVars) <COMA> condChance = value(localVars) <RPAR>
{
return new ATSMethodCall(ATSMethodCall.ObjectMethod.actorClearCondition, new ATSValueReference[]{condId, condChance}, targetInstance);
}
}
ATSValueReference worldReference(ATSLocalVarsHelper localVars) : {
ATSValueReference param1, objectCall = null;
} {
<GETMAP> <LPAR> param1 = value(localVars) <RPAR> (<DOT> objectCall = mapReference(localVars, new ATSMethodCall(ATSMethodCall.ObjectMethod.worldGetMap, new ATSValueReference[]{param1}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.world))))?
{
if (objectCall != null) return objectCall;
return new ATSMethodCall(ATSMethodCall.ObjectMethod.worldGetMap, new ATSValueReference[]{param1}, new ATSContextObjectReference(ATSContextObjectReference.ContextObject.world));
}
}
ATSValueReference itemReference(ATSLocalVarsHelper localVars, ATSContextObjectReference targetInstance) : {
ATSValueReference reference;
} {
<CATEGORY>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.itemCategory, targetInstance);
}
| <ID>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.itemId, targetInstance);
}
| <REWARD> <DOT> reference = itemRewardReference(localVars, targetInstance)
{
return reference;
}
}
ATSValueReference itemRewardReference(ATSLocalVarsHelper localVars, ATSContextObjectReference targetInstance) : {
} {
LOOKAHEAD(3)
<HP> <DOT> <MAX>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.itemRewardHpMax, targetInstance);
}
| <HP> <DOT> <MIN>
{
return new ATSObjectFieldReference(ATSObjectFieldReference.ObjectFields.itemRewardHpMin, targetInstance);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,298 @@
/* Generated By:JavaCC: Do not edit this line. ATScriptParserConstants.java */
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
/**
* Token literal values and constants.
* Generated by org.javacc.parser.OtherFilesGen#start()
*/
public interface ATScriptParserConstants {
/** End of File. */
int EOF = 0;
/** RegularExpression Id. */
int DOT = 5;
/** RegularExpression Id. */
int LPAR = 6;
/** RegularExpression Id. */
int RPAR = 7;
/** RegularExpression Id. */
int LBRAC = 8;
/** RegularExpression Id. */
int RBRAC = 9;
/** RegularExpression Id. */
int SCOL = 10;
/** RegularExpression Id. */
int COMA = 11;
/** RegularExpression Id. */
int IF = 12;
/** RegularExpression Id. */
int ELSE = 13;
/** RegularExpression Id. */
int WHILE = 14;
/** RegularExpression Id. */
int RETURN = 15;
/** RegularExpression Id. */
int TRUE = 16;
/** RegularExpression Id. */
int FALSE = 17;
/** RegularExpression Id. */
int EXCLAM = 18;
/** RegularExpression Id. */
int GOE = 19;
/** RegularExpression Id. */
int LOE = 20;
/** RegularExpression Id. */
int GT = 21;
/** RegularExpression Id. */
int LT = 22;
/** RegularExpression Id. */
int EQ = 23;
/** RegularExpression Id. */
int PLUS = 24;
/** RegularExpression Id. */
int MINUS = 25;
/** RegularExpression Id. */
int MULTIPLY = 26;
/** RegularExpression Id. */
int DIVIDE = 27;
/** RegularExpression Id. */
int CONCAT = 28;
/** RegularExpression Id. */
int AND = 29;
/** RegularExpression Id. */
int OR = 30;
/** RegularExpression Id. */
int EQUALS = 31;
/** RegularExpression Id. */
int DQUO = 32;
/** RegularExpression Id. */
int NUMBER = 33;
/** RegularExpression Id. */
int MAP = 34;
/** RegularExpression Id. */
int WORLD = 35;
/** RegularExpression Id. */
int ATTACK = 36;
/** RegularExpression Id. */
int PLAYER = 37;
/** RegularExpression Id. */
int ACTOR = 38;
/** RegularExpression Id. */
int ITEM = 39;
/** RegularExpression Id. */
int OUTDOOR = 40;
/** RegularExpression Id. */
int ACTIVATEGROUP = 41;
/** RegularExpression Id. */
int DEACTIVATEGROUP = 42;
/** RegularExpression Id. */
int GETMAP = 43;
/** RegularExpression Id. */
int CURRENT = 44;
/** RegularExpression Id. */
int SOURCE = 45;
/** RegularExpression Id. */
int TARGET = 46;
/** RegularExpression Id. */
int DAMAGE = 47;
/** RegularExpression Id. */
int CATEGORY = 48;
/** RegularExpression Id. */
int REWARD = 49;
/** RegularExpression Id. */
int ADDCONDITION = 50;
/** RegularExpression Id. */
int CLEARCONDITION = 51;
/** RegularExpression Id. */
int GETITEMCOUNT = 52;
/** RegularExpression Id. */
int GIVEITEM = 53;
/** RegularExpression Id. */
int REMOVEITEM = 54;
/** RegularExpression Id. */
int GETITEMINSLOT = 55;
/** RegularExpression Id. */
int EQUIPITEMINSLOT = 56;
/** RegularExpression Id. */
int UNEQUIPSLOT = 57;
/** RegularExpression Id. */
int HASQUESTPROGRESS = 58;
/** RegularExpression Id. */
int ADDQUESTPROGRESS = 59;
/** RegularExpression Id. */
int ACTORCONDITIONS = 60;
/** RegularExpression Id. */
int TOSOURCE = 61;
/** RegularExpression Id. */
int TOTARGET = 62;
/** RegularExpression Id. */
int BASE = 63;
/** RegularExpression Id. */
int MAXHP = 64;
/** RegularExpression Id. */
int MAXAP = 65;
/** RegularExpression Id. */
int MOVECOST = 66;
/** RegularExpression Id. */
int EQUIPCOST = 67;
/** RegularExpression Id. */
int USECOST = 68;
/** RegularExpression Id. */
int ADDEXPERIENCE = 69;
/** RegularExpression Id. */
int LEVEL = 70;
/** RegularExpression Id. */
int TOTALEXP = 71;
/** RegularExpression Id. */
int CURRENTEXP = 72;
/** RegularExpression Id. */
int ADDALIGNMENT = 73;
/** RegularExpression Id. */
int GETALIGNMENT = 74;
/** RegularExpression Id. */
int ID = 75;
/** RegularExpression Id. */
int HP = 76;
/** RegularExpression Id. */
int AP = 77;
/** RegularExpression Id. */
int AC = 78;
/** RegularExpression Id. */
int AD = 79;
/** RegularExpression Id. */
int BC = 80;
/** RegularExpression Id. */
int DR = 81;
/** RegularExpression Id. */
int CC = 82;
/** RegularExpression Id. */
int CM = 83;
/** RegularExpression Id. */
int MIN = 84;
/** RegularExpression Id. */
int MAX = 85;
/** RegularExpression Id. */
int CUR = 86;
/** RegularExpression Id. */
int BOOL = 87;
/** RegularExpression Id. */
int NUM = 88;
/** RegularExpression Id. */
int STRING = 89;
/** RegularExpression Id. */
int OBJECT = 90;
/** RegularExpression Id. */
int IDENTIFIER = 91;
/** RegularExpression Id. */
int ESCAPED_DQUO = 92;
/** RegularExpression Id. */
int DQUOBIS = 93;
/** RegularExpression Id. */
int LITERAL_VALUE = 94;
/** Lexical state. */
int DEFAULT = 0;
/** Lexical state. */
int LITERAL = 1;
/** Literal token values. */
String[] tokenImage = {
"<EOF>",
"\" \"",
"\"\\r\"",
"\"\\t\"",
"\"\\n\"",
"\".\"",
"\"(\"",
"\")\"",
"\"{\"",
"\"}\"",
"\";\"",
"\",\"",
"\"if\"",
"\"else\"",
"\"while\"",
"\"return\"",
"\"true\"",
"\"false\"",
"\"!\"",
"\">=\"",
"\"<=\"",
"\">\"",
"\"<\"",
"\"==\"",
"\"+\"",
"\"-\"",
"\"*\"",
"\"/\"",
"\"%\"",
"\"&&\"",
"\"||\"",
"\"=\"",
"\"\\\"\"",
"<NUMBER>",
"\"map\"",
"\"world\"",
"\"attack\"",
"\"player\"",
"\"actor\"",
"\"item\"",
"\"outdoor\"",
"\"activateGroup\"",
"\"deactivateGroup\"",
"\"getMap\"",
"\"current\"",
"\"source\"",
"\"target\"",
"\"damage\"",
"\"category\"",
"\"reward\"",
"\"addActorCondition\"",
"\"clearActorCondition\"",
"\"getItemCount\"",
"\"giveItem\"",
"\"removeItem\"",
"\"getItemInSlot\"",
"\"equipItemInSlot\"",
"\"unequipSlot\"",
"\"hasQuestProgress\"",
"\"addQuestProgress\"",
"\"actorConditions\"",
"\"toSource\"",
"\"toTarget\"",
"\"base\"",
"\"maxHP\"",
"\"maxAP\"",
"\"moveCost\"",
"\"equipCost\"",
"\"useCost\"",
"\"addExperience\"",
"\"level\"",
"\"totalExp\"",
"\"currentExp\"",
"\"addAlignment\"",
"\"getAlignment\"",
"\"id\"",
"\"hp\"",
"\"ap\"",
"\"ac\"",
"\"ad\"",
"\"bc\"",
"\"dr\"",
"\"cc\"",
"\"cm\"",
"\"min\"",
"\"max\"",
"\"cur\"",
"\"bool\"",
"\"num\"",
"\"string\"",
"\"object\"",
"<IDENTIFIER>",
"\"\\\\\\\"\"",
"\"\\\"\"",
"<LITERAL_VALUE>",
};
}

View File

@@ -0,0 +1,187 @@
/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 5.0 */
/* JavaCCOptions:KEEP_LINE_COL=null */
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
/**
* This exception is thrown when parse errors are encountered.
* You can explicitly create objects of this exception type by
* calling the method generateParseException in the generated
* parser.
*
* You can modify this class to customize your error reporting
* mechanisms so long as you retain the public fields.
*/
public class ParseException extends Exception {
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/**
* This constructor is used by the method "generateParseException"
* in the generated parser. Calling this constructor generates
* a new object of this type with the fields "currentToken",
* "expectedTokenSequences", and "tokenImage" set.
*/
public ParseException(Token currentTokenVal,
int[][] expectedTokenSequencesVal,
String[] tokenImageVal
)
{
super(initialise(currentTokenVal, expectedTokenSequencesVal, tokenImageVal));
currentToken = currentTokenVal;
expectedTokenSequences = expectedTokenSequencesVal;
tokenImage = tokenImageVal;
}
/**
* The following constructors are for use by you for whatever
* purpose you can think of. Constructing the exception in this
* manner makes the exception behave in the normal way - i.e., as
* documented in the class "Throwable". The fields "errorToken",
* "expectedTokenSequences", and "tokenImage" do not contain
* relevant information. The JavaCC generated code does not use
* these constructors.
*/
public ParseException() {
super();
}
/** Constructor with message. */
public ParseException(String message) {
super(message);
}
/**
* This is the last token that has been consumed successfully. If
* this object has been created due to a parse error, the token
* followng this token will (therefore) be the first error token.
*/
public Token currentToken;
/**
* Each entry in this array is an array of integers. Each array
* of integers represents a sequence of tokens (by their ordinal
* values) that is expected at this point of the parse.
*/
public int[][] expectedTokenSequences;
/**
* This is a reference to the "tokenImage" array of the generated
* parser within which the parse error occurred. This array is
* defined in the generated ...Constants interface.
*/
public String[] tokenImage;
/**
* It uses "currentToken" and "expectedTokenSequences" to generate a parse
* error message and returns it. If this object has been created
* due to a parse error, and you do not catch it (it gets thrown
* from the parser) the correct error message
* gets displayed.
*/
private static String initialise(Token currentToken,
int[][] expectedTokenSequences,
String[] tokenImage) {
String eol = System.getProperty("line.separator", "\n");
StringBuffer expected = new StringBuffer();
int maxSize = 0;
for (int i = 0; i < expectedTokenSequences.length; i++) {
if (maxSize < expectedTokenSequences[i].length) {
maxSize = expectedTokenSequences[i].length;
}
for (int j = 0; j < expectedTokenSequences[i].length; j++) {
expected.append(tokenImage[expectedTokenSequences[i][j]]).append(' ');
}
if (expectedTokenSequences[i][expectedTokenSequences[i].length - 1] != 0) {
expected.append("...");
}
expected.append(eol).append(" ");
}
String retval = "Encountered \"";
Token tok = currentToken.next;
for (int i = 0; i < maxSize; i++) {
if (i != 0) retval += " ";
if (tok.kind == 0) {
retval += tokenImage[0];
break;
}
retval += " " + tokenImage[tok.kind];
retval += " \"";
retval += add_escapes(tok.image);
retval += " \"";
tok = tok.next;
}
retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn;
retval += "." + eol;
if (expectedTokenSequences.length == 1) {
retval += "Was expecting:" + eol + " ";
} else {
retval += "Was expecting one of:" + eol + " ";
}
retval += expected.toString();
return retval;
}
/**
* The end of line string for this machine.
*/
protected String eol = System.getProperty("line.separator", "\n");
/**
* Used to convert raw characters to their escaped version
* when these raw version cannot be used as part of an ASCII
* string literal.
*/
static String add_escapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
}
/* JavaCC - OriginalChecksum=1d43dd1fac5be0a8e12b95f6ad54b62d (do not edit this line) */

View File

@@ -0,0 +1,45 @@
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
import com.gpl.rpg.AndorsTrail.context.ControllerContext;
import com.gpl.rpg.AndorsTrail.context.WorldContext;
import com.gpl.rpg.AndorsTrail.model.ability.ActorCondition;
import com.gpl.rpg.AndorsTrail.model.actor.Actor;
import com.gpl.rpg.AndorsTrail.model.actor.Player;
import com.gpl.rpg.AndorsTrail.model.item.Inventory;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.model.map.PredefinedMap;
import com.gpl.rpg.AndorsTrail.scripting.proxyobjects.Item;
public class ScriptContext {
public Double[] localNums;
public Boolean[] localBools;
public String[] localStrings;
public Object[] localObjects;
public PredefinedMap map;
public Player player;
public Actor actor;
public ActorCondition ac;
public Item item;
public String slot;
public final WorldContext world;
public final ControllerContext controllers;
public boolean returnReached = false;
public ScriptContext(WorldContext world, ControllerContext controllers) {
this.world = world;
this.controllers = controllers;
}
public void initializeLocalVars(int localBoolsSize, int localNumsSize, int localStringsSize, int localObjectsSize) {
this.localNums = localNumsSize > 0 ? new Double[localNumsSize] : null;
this.localBools = localBoolsSize > 0 ? new Boolean[localBoolsSize] : null;
this.localStrings = localStringsSize > 0 ? new String[localStringsSize] : null;
this.localObjects = localObjectsSize > 0 ? new Object[localObjectsSize] : null;
}
}

View File

@@ -0,0 +1,471 @@
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
/**
* An implementation of interface CharStream, where the stream is assumed to
* contain only ASCII characters (without unicode processing).
*/
public class SimpleCharStream
{
/** Whether parser is static. */
public static final boolean staticFlag = false;
int bufsize;
int available;
int tokenBegin;
/** Position in buffer. */
public int bufpos = -1;
protected int bufline[];
protected int bufcolumn[];
protected int column = 0;
protected int line = 1;
protected boolean prevCharIsCR = false;
protected boolean prevCharIsLF = false;
protected java.io.Reader inputStream;
protected char[] buffer;
protected int maxNextCharInd = 0;
protected int inBuf = 0;
protected int tabSize = 8;
protected void setTabSize(int i) { tabSize = i; }
protected int getTabSize(int i) { return tabSize; }
protected void ExpandBuff(boolean wrapAround)
{
char[] newbuffer = new char[bufsize + 2048];
int newbufline[] = new int[bufsize + 2048];
int newbufcolumn[] = new int[bufsize + 2048];
try
{
if (wrapAround)
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
}
else
{
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
buffer = newbuffer;
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
bufline = newbufline;
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
bufcolumn = newbufcolumn;
maxNextCharInd = (bufpos -= tokenBegin);
}
}
catch (Throwable t)
{
throw new Error(t.getMessage());
}
bufsize += 2048;
available = bufsize;
tokenBegin = 0;
}
protected void FillBuff() throws java.io.IOException
{
if (maxNextCharInd == available)
{
if (available == bufsize)
{
if (tokenBegin > 2048)
{
bufpos = maxNextCharInd = 0;
available = tokenBegin;
}
else if (tokenBegin < 0)
bufpos = maxNextCharInd = 0;
else
ExpandBuff(false);
}
else if (available > tokenBegin)
available = bufsize;
else if ((tokenBegin - available) < 2048)
ExpandBuff(true);
else
available = tokenBegin;
}
int i;
try {
if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1)
{
inputStream.close();
throw new java.io.IOException();
}
else
maxNextCharInd += i;
return;
}
catch(java.io.IOException e) {
--bufpos;
backup(0);
if (tokenBegin == -1)
tokenBegin = bufpos;
throw e;
}
}
/** Start. */
public char BeginToken() throws java.io.IOException
{
tokenBegin = -1;
char c = readChar();
tokenBegin = bufpos;
return c;
}
protected void UpdateLineColumn(char c)
{
column++;
if (prevCharIsLF)
{
prevCharIsLF = false;
line += (column = 1);
}
else if (prevCharIsCR)
{
prevCharIsCR = false;
if (c == '\n')
{
prevCharIsLF = true;
}
else
line += (column = 1);
}
switch (c)
{
case '\r' :
prevCharIsCR = true;
break;
case '\n' :
prevCharIsLF = true;
break;
case '\t' :
column--;
column += (tabSize - (column % tabSize));
break;
default :
break;
}
bufline[bufpos] = line;
bufcolumn[bufpos] = column;
}
/** Read a character. */
public char readChar() throws java.io.IOException
{
if (inBuf > 0)
{
--inBuf;
if (++bufpos == bufsize)
bufpos = 0;
return buffer[bufpos];
}
if (++bufpos >= maxNextCharInd)
FillBuff();
char c = buffer[bufpos];
UpdateLineColumn(c);
return c;
}
@Deprecated
/**
* @deprecated
* @see #getEndColumn
*/
public int getColumn() {
return bufcolumn[bufpos];
}
@Deprecated
/**
* @deprecated
* @see #getEndLine
*/
public int getLine() {
return bufline[bufpos];
}
/** Get token end column number. */
public int getEndColumn() {
return bufcolumn[bufpos];
}
/** Get token end line number. */
public int getEndLine() {
return bufline[bufpos];
}
/** Get token beginning column number. */
public int getBeginColumn() {
return bufcolumn[tokenBegin];
}
/** Get token beginning line number. */
public int getBeginLine() {
return bufline[tokenBegin];
}
/** Backup a number of characters. */
public void backup(int amount) {
inBuf += amount;
if ((bufpos -= amount) < 0)
bufpos += bufsize;
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.Reader dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn, int buffersize)
{
inputStream = dstream;
line = startline;
column = startcolumn - 1;
if (buffer == null || buffersize != buffer.length)
{
available = bufsize = buffersize;
buffer = new char[buffersize];
bufline = new int[buffersize];
bufcolumn = new int[buffersize];
}
prevCharIsLF = prevCharIsCR = false;
tokenBegin = inBuf = maxNextCharInd = 0;
bufpos = -1;
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.Reader dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, int startline,
int startcolumn)
{
this(dstream, startline, startcolumn, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
this(dstream, encoding, 1, 1, 4096);
}
/** Constructor. */
public SimpleCharStream(java.io.InputStream dstream)
{
this(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
{
ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn, int buffersize)
{
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream)
{
ReInit(dstream, 1, 1, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, String encoding, int startline,
int startcolumn) throws java.io.UnsupportedEncodingException
{
ReInit(dstream, encoding, startline, startcolumn, 4096);
}
/** Reinitialise. */
public void ReInit(java.io.InputStream dstream, int startline,
int startcolumn)
{
ReInit(dstream, startline, startcolumn, 4096);
}
/** Get token literal value. */
public String GetImage()
{
if (bufpos >= tokenBegin)
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
else
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
new String(buffer, 0, bufpos + 1);
}
/** Get the suffix. */
public char[] GetSuffix(int len)
{
char[] ret = new char[len];
if ((bufpos + 1) >= len)
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
else
{
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
len - bufpos - 1);
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
}
return ret;
}
/** Reset buffer when finished. */
public void Done()
{
buffer = null;
bufline = null;
bufcolumn = null;
}
/**
* Method to adjust line and column numbers for the start of a token.
*/
public void adjustBeginLineColumn(int newLine, int newCol)
{
int start = tokenBegin;
int len;
if (bufpos >= tokenBegin)
{
len = bufpos - tokenBegin + inBuf + 1;
}
else
{
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
}
int i = 0, j = 0, k = 0;
int nextColDiff = 0, columnDiff = 0;
while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
{
bufline[j] = newLine;
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
bufcolumn[j] = newCol + columnDiff;
columnDiff = nextColDiff;
i++;
}
if (i < len)
{
bufline[j] = newLine++;
bufcolumn[j] = newCol + columnDiff;
while (i++ < len)
{
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
bufline[j] = newLine++;
else
bufline[j] = newLine;
}
}
line = bufline[j];
column = bufcolumn[j];
}
}
/* JavaCC - OriginalChecksum=9c1602b36666d625c72f249f8f49db85 (do not edit this line) */

View File

@@ -0,0 +1,131 @@
/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
/**
* Describes the input token stream.
*/
public class Token implements java.io.Serializable {
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/**
* An integer that describes the kind of this token. This numbering
* system is determined by JavaCCParser, and a table of these numbers is
* stored in the file ...Constants.java.
*/
public int kind;
/** The line number of the first character of this Token. */
public int beginLine;
/** The column number of the first character of this Token. */
public int beginColumn;
/** The line number of the last character of this Token. */
public int endLine;
/** The column number of the last character of this Token. */
public int endColumn;
/**
* The string image of the token.
*/
public String image;
/**
* A reference to the next regular (non-special) token from the input
* stream. If this is the last token from the input stream, or if the
* token manager has not read tokens beyond this one, this field is
* set to null. This is true only if this token is also a regular
* token. Otherwise, see below for a description of the contents of
* this field.
*/
public Token next;
/**
* This field is used to access special tokens that occur prior to this
* token, but after the immediately preceding regular (non-special) token.
* If there are no such special tokens, this field is set to null.
* When there are more than one such special token, this field refers
* to the last of these special tokens, which in turn refers to the next
* previous special token through its specialToken field, and so on
* until the first special token (whose specialToken field is null).
* The next fields of special tokens refer to other special tokens that
* immediately follow it (without an intervening regular token). If there
* is no such token, this field is null.
*/
public Token specialToken;
/**
* An optional attribute value of the Token.
* Tokens which are not used as syntactic sugar will often contain
* meaningful values that will be used later on by the compiler or
* interpreter. This attribute value is often different from the image.
* Any subclass of Token that actually wants to return a non-null value can
* override this method as appropriate.
*/
public Object getValue() {
return null;
}
/**
* No-argument constructor
*/
public Token() {}
/**
* Constructs a new token for the specified Image.
*/
public Token(int kind)
{
this(kind, null);
}
/**
* Constructs a new token for the specified Image and Kind.
*/
public Token(int kind, String image)
{
this.kind = kind;
this.image = image;
}
/**
* Returns the image.
*/
public String toString()
{
return image;
}
/**
* Returns a new Token object, by default. However, if you want, you
* can create and return subclass objects based on the value of ofKind.
* Simply add the cases to the switch for all those special cases.
* For example, if you have a subclass of Token called IDToken that
* you want to create if ofKind is ID, simply add something like :
*
* case MyParserConstants.ID : return new IDToken(ofKind, image);
*
* to the following switch statement. Then you can cast matchedToken
* variable to the appropriate type and use sit in your lexical actions.
*/
public static Token newToken(int ofKind, String image)
{
switch(ofKind)
{
default : return new Token(ofKind, image);
}
}
public static Token newToken(int ofKind)
{
return newToken(ofKind, null);
}
}
/* JavaCC - OriginalChecksum=c8ce217eacfef3c39015dc49547d0c44 (do not edit this line) */

View File

@@ -0,0 +1,147 @@
/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
/* JavaCCOptions: */
package com.gpl.rpg.AndorsTrail.scripting.interpreter;
/** Token Manager Error. */
public class TokenMgrError extends Error
{
/**
* The version identifier for this Serializable class.
* Increment only if the <i>serialized</i> form of the
* class changes.
*/
private static final long serialVersionUID = 1L;
/*
* Ordinals for various reasons why an Error of this type can be thrown.
*/
/**
* Lexical error occurred.
*/
static final int LEXICAL_ERROR = 0;
/**
* An attempt was made to create a second instance of a static token manager.
*/
static final int STATIC_LEXER_ERROR = 1;
/**
* Tried to change to an invalid lexical state.
*/
static final int INVALID_LEXICAL_STATE = 2;
/**
* Detected (and bailed out of) an infinite loop in the token manager.
*/
static final int LOOP_DETECTED = 3;
/**
* Indicates the reason why the exception is thrown. It will have
* one of the above 4 values.
*/
int errorCode;
/**
* Replaces unprintable characters by their escaped (or unicode escaped)
* equivalents in the given string
*/
protected static final String addEscapes(String str) {
StringBuffer retval = new StringBuffer();
char ch;
for (int i = 0; i < str.length(); i++) {
switch (str.charAt(i))
{
case 0 :
continue;
case '\b':
retval.append("\\b");
continue;
case '\t':
retval.append("\\t");
continue;
case '\n':
retval.append("\\n");
continue;
case '\f':
retval.append("\\f");
continue;
case '\r':
retval.append("\\r");
continue;
case '\"':
retval.append("\\\"");
continue;
case '\'':
retval.append("\\\'");
continue;
case '\\':
retval.append("\\\\");
continue;
default:
if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
String s = "0000" + Integer.toString(ch, 16);
retval.append("\\u" + s.substring(s.length() - 4, s.length()));
} else {
retval.append(ch);
}
continue;
}
}
return retval.toString();
}
/**
* Returns a detailed message for the Error when it is thrown by the
* token manager to indicate a lexical error.
* Parameters :
* EOFSeen : indicates if EOF caused the lexical error
* curLexState : lexical state in which this error occurred
* errorLine : line number when the error occurred
* errorColumn : column number when the error occurred
* errorAfter : prefix that was seen before this error occurred
* curchar : the offending character
* Note: You can customize the lexical error message by modifying this method.
*/
protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) {
return("Lexical error at line " +
errorLine + ", column " +
errorColumn + ". Encountered: " +
(EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int)curChar + "), ") +
"after : \"" + addEscapes(errorAfter) + "\"");
}
/**
* You can also modify the body of this method to customize your error messages.
* For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
* of end-users concern, so you can return something like :
*
* "Internal Error : Please file a bug report .... "
*
* from this method for such cases in the release version of your parser.
*/
public String getMessage() {
return super.getMessage();
}
/*
* Constructors of various flavors follow.
*/
/** No arg constructor. */
public TokenMgrError() {
}
/** Constructor with message and reason. */
public TokenMgrError(String message, int reason) {
super(message);
errorCode = reason;
}
/** Full Constructor. */
public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) {
this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
}
}
/* JavaCC - OriginalChecksum=cccc305395111792d0fa347209e3668b (do not edit this line) */

View File

@@ -0,0 +1,26 @@
package com.gpl.rpg.AndorsTrail.scripting.proxyobjects;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
import com.gpl.rpg.AndorsTrail.model.item.ItemType;
import com.gpl.rpg.AndorsTrail.scripting.Script;
public class Item {
public String id;
public String category;
public ItemReward reward;
public Script[] privateScripts;
public Item(ItemType type, ItemTraits_OnUse useEffect, ItemTraits_OnEquip equipEffect) {
this.id = type.id;
this.category = type.category.id;
if (useEffect != null) {
this.reward = new ItemReward(useEffect);
} else if (equipEffect != null){
this.reward = new ItemReward(equipEffect);
}
this.privateScripts = type.private_scripts;
}
}

View File

@@ -0,0 +1,126 @@
package com.gpl.rpg.AndorsTrail.scripting.proxyobjects;
import com.gpl.rpg.AndorsTrail.model.ability.ActorConditionEffect;
import com.gpl.rpg.AndorsTrail.model.ability.traits.AbilityModifierTraits;
import com.gpl.rpg.AndorsTrail.model.ability.traits.StatsModifierTraits;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
import com.gpl.rpg.AndorsTrail.resource.VisualEffectCollection.VisualEffectID;
import com.gpl.rpg.AndorsTrail.util.ConstRange;
public class ItemReward {
private VisualEffectID visualEffectID = null;
public int hpMax = 0;
public int hpMin = 0;
public int apMax = 0;
public int apMin = 0;
public int increaseMaxHP = 0;
public int increaseMaxAP = 0;
public int increaseMoveCost = 0;
public int increaseUseItemCost = 0;
public int increaseReequipCost = 0;
public int increaseAttackCost = 0;
public int increaseAttackChance = 0;
public int increaseBlockChance = 0;
public int increaseMinDamage = 0;
public int increaseMaxDamage = 0;
public int increaseCriticalSkill = 0;
public float setCriticalMultiplier = 0;
public int increaseDamageResistance = 0;
public ActorConditionEffect[] effectsToSource;
public ActorConditionEffect[] effectsToTarget;
public ItemReward(ItemTraits_OnUse useEffect) {
if (useEffect.changedStats != null) {
this.visualEffectID = useEffect.changedStats.visualEffectID;
if (useEffect.changedStats.currentHPBoost != null) {
hpMax = useEffect.changedStats.currentHPBoost.max;
hpMin = useEffect.changedStats.currentHPBoost.current;
}
if (useEffect.changedStats.currentAPBoost != null) {
apMax = useEffect.changedStats.currentAPBoost.max;
apMin = useEffect.changedStats.currentAPBoost.current;
}
}
if (useEffect.addedConditions_source != null) {
int i = useEffect.addedConditions_source.length;
effectsToSource = new ActorConditionEffect[i];
while (i-- > 0) {
effectsToSource[i] = useEffect.addedConditions_source[i].clone();
}
}
if (useEffect.addedConditions_target != null) {
int i = useEffect.addedConditions_target.length;
effectsToTarget = new ActorConditionEffect[i];
while (i-- > 0) {
effectsToTarget[i] = useEffect.addedConditions_target[i].clone();
}
}
}
public ItemTraits_OnUse toUseEffect() {
ConstRange hpBoost = null;
if (hpMax != 0 || hpMin != 0) {
hpBoost = new ConstRange(hpMax, hpMin);
}
ConstRange apBoost = null;
if (apMax != 0 && apMin != 0) {
apBoost = new ConstRange(apMax, apMin);
}
StatsModifierTraits changedStats = null;
if (hpBoost != null || apBoost != null) {
changedStats = new StatsModifierTraits(visualEffectID, hpBoost, apBoost);
}
return new ItemTraits_OnUse(changedStats, effectsToSource, effectsToTarget);
}
public ItemReward(ItemTraits_OnEquip equipEffect) {
AbilityModifierTraits statsEffect = equipEffect.stats;
if (statsEffect != null) {
this.increaseAttackChance = statsEffect.increaseAttackChance;
this.increaseAttackCost = statsEffect.increaseAttackCost;
this.increaseBlockChance = statsEffect.increaseBlockChance;
this.increaseCriticalSkill = statsEffect.increaseCriticalSkill;
this.increaseDamageResistance = statsEffect.increaseDamageResistance;
this.increaseMaxAP = statsEffect.increaseMaxAP;
this.increaseMaxHP = statsEffect.increaseMaxHP;
this.increaseMinDamage = statsEffect.increaseMinDamage;
this.increaseMaxDamage = statsEffect.increaseMaxDamage;
this.increaseMoveCost = statsEffect.increaseMoveCost;
this.increaseReequipCost = statsEffect.increaseReequipCost;
this.increaseUseItemCost = statsEffect.increaseUseItemCost;
this.setCriticalMultiplier = statsEffect.setCriticalMultiplier;
}
if (equipEffect.addedConditions != null) {
int i = equipEffect.addedConditions.length;
effectsToSource = new ActorConditionEffect[i];
while (i-- > 0) {
effectsToSource[i] = equipEffect.addedConditions[i].clone();
}
}
}
public ItemTraits_OnEquip toEquipEffect() {
return new ItemTraits_OnEquip(
new AbilityModifierTraits(increaseMaxHP,
increaseMaxAP,
increaseMoveCost,
increaseUseItemCost,
increaseReequipCost,
increaseAttackCost,
increaseAttackChance,
increaseBlockChance,
increaseMinDamage,
increaseMaxDamage,
increaseCriticalSkill,
setCriticalMultiplier,
increaseDamageResistance),
effectsToSource);
}
}

View File

@@ -8,6 +8,7 @@ import android.widget.TextView;
import com.gpl.rpg.AndorsTrail.R; import com.gpl.rpg.AndorsTrail.R;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnEquip;
import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse; import com.gpl.rpg.AndorsTrail.model.item.ItemTraits_OnUse;
import com.gpl.rpg.AndorsTrail.scripting.Script;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;

View File

@@ -119,7 +119,7 @@ public final class MainView extends SurfaceView
); );
if (model.currentMap != null) { if (model.currentMap != null) {
onPlayerEnteredNewMap(model.currentMap, model.player.position); onPlayerEnteredNewMap(model.currentMap, model.player.position, null);
} else { } else {
redrawAll(RedrawAllDebugReason.SurfaceChanged); redrawAll(RedrawAllDebugReason.SurfaceChanged);
} }
@@ -331,7 +331,7 @@ public final class MainView extends SurfaceView
} }
@Override @Override
public void onPlayerEnteredNewMap(PredefinedMap map, Coord p) { public void onPlayerEnteredNewMap(PredefinedMap map, Coord p, PredefinedMap oldMap) {
synchronized (holder) { synchronized (holder) {
currentMap = map; currentMap = map;
currentTileMap = model.currentTileMap; currentTileMap = model.currentTileMap;