//TESH.scrollpos=0
//TESH.alwaysfold=0
function PlaySoundForPlayer takes sound s, player p returns nothing
set bj_lastPlayedSound = s
if s != null and GetLocalPlayer() == p then
call StartSound(s)
endif
endfunction
Name | Type | is_array | initial_value |
AccumulatedPointsTotal | integer | Yes | |
AGI_Celerity_Angle | real | Yes | |
AGI_Celerity_EnemyUnit | unit | Yes | |
AGI_Celerity_Point | location | Yes | |
AGI_Celerity_Transparent | real | Yes | |
AGI_CelerityCount | real | Yes | |
AGI_CelerityCustomValue | integer | No | |
AGI_CelerityDistanceReal | real | No | |
AGI_CelerityHeroGroup | group | No | |
AGI_CelerityPlacePoint | location | Yes | |
AGI_CelerityTempInt | integer | No | |
AGI_CelerityTempUnit | unit | No | |
AGI_HareSpringPoint | location | No | |
AGI_QuickWittedAddAgility | integer | No | |
AGI_QuickWittedAgilityAmount | integer | Yes | |
AGI_QuickWittedCustomValue | integer | No | |
AGI_QuickWittedUnitGroup | group | No | |
AGI_QWittedTempInt | integer | No | |
AGI_QWittedTempUnit | unit | No | |
AGI_QWittedTimer | timer | Yes | |
AGI_SpringCastPoint | location | No | |
AGIMGC_ADGryphArrived | boolean | Yes | |
AGIMGC_ADGryphtoTown | boolean | Yes | |
AGIMGC_AirborneCount | real | Yes | |
AGIMGC_AirborneCustomValue | integer | No | |
AGIMGC_AirborneDelivererPoint | location | Yes | |
AGIMGC_AirborneDeliverUnit | unit | Yes | |
AGIMGC_AirborneGroup1 | group | No | |
AGIMGC_AirborneGroup2 | group | No | |
AGIMGC_AirborneHero | unit | Yes | |
AGIMGC_AirborneHeroPoint | location | Yes | |
AGIMGC_AirborneMoveToPoint | location | Yes | |
AGIMGC_AirborneRandAngle | real | Yes | |
AGIMGC_AirborneTempInt | integer | No | |
AGIMGC_AirbornGryphPoint | location | Yes | |
AGIMGC_CarpetBombTempPt | location | No | |
AGIMGC_DistanceForCarpetBomb | real | Yes | |
AGIMGC_NestCount | real | Yes | |
AGIMGC_NestCustomValue | integer | No | |
AGIMGC_NestEffect1 | effect | Yes | |
AGIMGC_NestHero | unit | Yes | |
AGIMGC_NestHeroGroup | group | No | |
AGIMGC_NestHeroPoint | location | Yes | |
AGIMGC_NestHeroSpeed | real | Yes | |
AGIMGC_NestTempInt | integer | No | |
AGIMGC_WhirlarangTornado | unit | Yes | |
AGIMGC_WhirlCustomValue | integer | No | |
AGIMGC_WhirlEnemy | unit | Yes | |
AGIMGC_WhirlEnemyPoint | location | Yes | |
AGIMGC_WhirlHasUnit | boolean | Yes | |
AGIMGC_WhirlHeadingHome | boolean | Yes | |
AGIMGC_WhirlHero | unit | Yes | |
AGIMGC_WhirlHeroPoint | location | Yes | |
AGIMGC_WhirlMoveTo | location | Yes | |
AGIMGC_WhirlPeriodicCount | real | Yes | |
AGIMGC_WhirlPoint1 | location | Yes | |
AGIMGC_WhirlSpeed | real | Yes | |
AGIMGC_WhirlTempInt | integer | No | |
AGIMGC_WhirlUnitGroup | group | No | |
AGIRGD_CadavreDeathPt | location | No | |
AGIRGD_CampCaster | unit | Yes | |
AGIRGD_CampCount | real | Yes | |
AGIRGD_CampCustomValue | integer | No | |
AGIRGD_CampDeathPt | location | No | |
AGIRGD_CampFires | group | No | |
AGIRGD_CampfireUnitsInRange | group | No | |
AGIRGD_CampFireWarmedUnits | group | No | |
AGIRGD_CampTempInt | integer | No | |
AGIRGD_CreateCampPt | location | No | |
AGIRGD_FartPoint | location | No | |
AGIRGD_FartTempPt | location | No | |
AGIRGD_FartUnitsInRange | group | No | |
AGIRGD_RetchCasterGroundPt | location | Yes | |
AGIRGD_RetchCasterPt | location | No | |
AGIRGD_RetchCount | real | Yes | |
AGIRGD_RetchCountDummy | real | Yes | |
AGIRGD_RetchCustomValue | integer | No | |
AGIRGD_RetchDummyGroup | group | No | |
AGIRGD_RetcherPt | location | No | |
AGIRGD_RetchGroundPt | location | Yes | |
AGIRGD_RetchGroupQueue | group | No | |
AGIRGD_RetchHeroCount | real | Yes | |
AGIRGD_RetchHeroGroup | group | No | |
AGIRGD_RetchingGroup | group | No | |
AGIRGD_RetchSoonCount | real | Yes | |
AGIRGD_RetchSoonGroup | group | No | |
AGIRGD_RetchTempInt | integer | No | |
AGIRGD_RetchTempUnit | unit | No | |
AGIRGD_TurbCount | real | Yes | |
AGIRGD_TurbCustomValue | integer | No | |
AGIRGD_TurbTempInt | integer | No | |
AGIRGD_TurbulenceCaster | unit | Yes | |
AGIRGD_TurbulenceFarts | group | No | |
AncientofBuffsPoint | location | Yes | |
AOB_DefendCustomValue | integer | No | |
AOB_DefendGroup | group | No | |
AOB_DefendHero | unit | Yes | |
AOB_DefendPeriodicCount | real | Yes | |
AOB_DefendTempInt | integer | No | |
ArtOfCombat1Researched | boolean | Yes | |
ArtOfCombat2Researched | boolean | Yes | |
BargeAttackPointMove | location | No | |
BountyAssasinSpawnPoint | location | Yes | |
BountyAssassin_ContractBought | boolean | Yes | |
BountyAssassin_ContractUsed | boolean | Yes | |
BountyAssassin_CustomValue | integer | No | |
BountyAssassin_FriendlyGroup | group | No | |
BountyAssassin_HeroBuyer | unit | Yes | |
BountyAssassin_PeriodicCount | real | Yes | |
BountyAssassin_PeriodicGroup | group | No | |
BountyAssassin_SpecialEffect | effect | Yes | |
BountyAssassin_StartedAttack | boolean | Yes | |
BountyAssassin_TempAssassin | unit | No | |
BountyAssassin_TempBuyer | unit | No | |
BountyAssassin_TempInt | integer | No | |
BountyAssassin_TempTarget | unit | No | |
BountyAssassinBeingUsed | boolean | Yes | |
BountyAssassinTarget | unit | Yes | |
BountyAssassinUnit | unit | Yes | |
BountyShop | unit | Yes | |
CannonJobStart | boolean | Yes | |
Cardinals_Team1 | force | No | |
CarryBoxJobEarthquakePoint | location | Yes | |
CarryBoxJobStart | boolean | Yes | |
CatchAnimalJobPlayer | player | Yes | |
CatchAnimalJobStart | boolean | Yes | |
CCPirateBossDead | boolean | No | |
CCPlayerGroup | force | No | |
CentreLairGoldIncrements | integer | No | |
CentreLairPoint | location | No | |
CirclingPoint | location | Yes | |
CirclingPointReal | real | Yes | |
CLASSUP_AbilityLevel1 | integer | No | |
CLASSUP_AbilityLevel2 | integer | No | |
CLASSUP_AbilityLevel3 | integer | No | |
CLASSUP_AbilityLevel4 | integer | No | |
CLASSUP_AvailableSkillPoints | integer | No | |
CLASSUP_ClassingUp | boolean | Yes | |
CLASSUP_CustomValue | integer | No | |
CLASSUP_DummyCreatePt | location | No | |
CLASSUP_HeroAbilities1 | abilcode | Yes | |
CLASSUP_HeroGroup | group | No | |
CLASSUP_HeroItemInventory1 | itemcode | Yes | |
CLASSUP_HeroItemInventory2 | itemcode | Yes | |
CLASSUP_HeroItemInventory3 | itemcode | Yes | |
CLASSUP_HeroItemInventory4 | itemcode | Yes | |
CLASSUP_HeroItemInventory6 | itemcode | Yes | |
CLASSUP_HeroItemInventory7 | itemcode | Yes | |
CLASSUP_HeroItemInventory8 | itemcode | Yes | |
CLASSUP_HeroItemInventory9 | itemcode | Yes | |
CLASSUP_HeroLevel | integer | No | |
CLASSUP_HeroTempPoint | location | No | |
CLASSUP_HeroUnit | unit | Yes | |
CLASSUP_NewHeroTemp | unit | No | |
CLASSUP_OldHeroXP | integer | No | |
CLASSUP_PeriodicCount | real | Yes | |
CLASSUP_SFX1 | effect | Yes | |
CLASSUP_SFX2 | effect | Yes | |
CLASSUP_SFX3 | effect | Yes | |
CLASSUP_TempDummy | unit | No | |
CLASSUP_TempInt | integer | No | |
CLASSUP_TempOldHero | unit | No | |
CourierJobDone | boolean | Yes | |
CourierJobPlayer | player | Yes | |
CourierJobStart | boolean | Yes | |
CrateSpecialEffect | effect | Yes | |
CREEP_DropRandomNo | integer | No | |
CREEP_RespawnCustomValue | integer | No | |
CREEP_RespawnGroup | group | No | |
CREEP_RespawnPeriodic | real | Yes | |
CREEP_RespawnPoint | location | Yes | |
CREEP_RespawnTempInt | integer | No | |
CREEP_RespawnUnitType | unitcode | Yes | |
damage | real | No | |
DEVILFRUIT_HeroUnit | unit | No | |
DoingJobCurrentlyPlayer | boolean | Yes | |
DumpBoxDestination | location | No | |
DumpedBoxCount | integer | Yes | |
FARM_RandomNo | integer | No | |
FRUITSTAND_Eater | unit | No | |
FRUITSTAND_NectarinePlayer | player | No | |
GEN_EFFECTPOINT_1 | location | No | |
GEN_EFFECTPOINT_2 | location | No | |
GEN_EFFECTPOINT_3 | location | No | |
GROG_DrinkerInteger | integer | No | |
GROG_DrunkEffect | effect | Yes | |
GroundPunchPoint | location | Yes | |
HeroDeath | unit | Yes | |
HEROES | unit | Yes | |
HeroUnitMissionControl | unit | Yes | |
HireExtraLandSpawnPoint | location | No | |
ic | integer | Yes | |
Ingredient1 | itemcode | Yes | |
Ingredient2 | itemcode | Yes | |
Ingredient3 | itemcode | Yes | |
Ingredient4 | itemcode | Yes | |
Ingredient5 | itemcode | Yes | |
Ingredient6 | itemcode | Yes | |
Island1Claimed | boolean | No | |
Island2Claimed | boolean | No | |
Island3Claimed | boolean | No | |
Island4Claimed | boolean | No | |
Island5Claimed | boolean | No | |
Island6Claimed | boolean | No | |
Island7Claimed | boolean | No | |
Island8Claimed | boolean | No | |
IslandClaimPt | location | No | |
IslandClaimText | texttag | Yes | |
itemid1 | integer | Yes | |
itemid2 | integer | Yes | |
itemid3 | integer | Yes | |
itemid4 | integer | Yes | |
itemid5 | integer | Yes | |
itemid6 | integer | Yes | |
LairWhelpHero | unit | Yes | |
LandSpawnAttackMovePoint | location | No | |
LawnWormArray | unit | Yes | |
LawnWormID | integer | No | |
LawnWormJobCount | integer | Yes | |
LawnWormJobStart | boolean | Yes | |
LoadedIntoTransportGroup | group | No | |
LowerThisCase | string | Yes | |
MagicalBuffJobStart | boolean | Yes | |
MagicPotions1Researched | boolean | Yes | |
MagicPotions2Researched | boolean | Yes | |
MeatThrowJobStart | boolean | Yes | |
MemoryPointArray | location | Yes | |
MG_ExclamationMarks | effect | Yes | |
MG_WaterSki_Player | player | Yes | |
MG_WaterSki_SkiierPlacePoint | location | Yes | |
MG_WaterSki_Started | boolean | Yes | |
MGC_CometCount | real | Yes | |
MGC_CometCustomValue | integer | No | |
MGC_CometEffect | effect | Yes | |
MGC_CometHeroGroup | group | No | |
MGC_CometHeroUnit | unit | No | |
MGC_CometPoint | location | Yes | |
MGC_CometTempInt | integer | No | |
MGC_FrostCustomValue | integer | No | |
MGC_FrostEffect | effect | Yes | |
MGC_FrostEnemyUnit | unit | No | |
MGC_FrostHeroUnit | unit | Yes | |
MGC_FrostSurgeDummyPoint | location | Yes | |
MGC_FrostSurgeUnitGroup | group | No | |
MGC_FrostTempInt | integer | No | |
MGC_IcyPuddleEffect1 | effect | Yes | |
MGC_ManaMummyBoolean | boolean | Yes | |
MGC_ManaMummyCustomValue | integer | No | |
MGC_ManaMummyHeroTemp | unit | No | |
MGC_MummyAttackingUnit | unit | Yes | |
MGC_MummyCount | real | Yes | |
MGC_MummyIllusionUnit | unit | Yes | |
MGC_MummyTempInt | integer | No | |
MGC_MummyUnitGroup | group | No | |
MGC_MummyUnitPoint | location | Yes | |
MGC_MummyUnitSFX_1 | effect | Yes | |
MGC_MummyUnitSFX_2 | effect | Yes | |
MGC_PuddleConductor | boolean | Yes | |
MGC_SurgeEffectCount | real | Yes | |
MISSION_CannonCustomValue | integer | No | |
MISSION_CannonHero | unit | Yes | |
MISSION_CannonJobCount | integer | Yes | |
MISSION_CannonJobSiegeUnit | unit | Yes | |
MISSION_CannonPeriodicCount | real | Yes | |
MISSION_CannonPeriodicGroup | group | No | |
MISSION_CannonTankSpawnPoint | location | No | |
MISSION_CannonTempInt | integer | No | |
MISSION_CannonTempUnit | unit | No | |
MISSION_CarryBoxCountPeriodic | real | Yes | |
MISSION_CarryBoxCustomValue | integer | No | |
MISSION_CarryBoxGroup | group | No | |
MISSION_CarryBoxPoint | location | No | |
MISSION_CarryBoxTempInt | integer | No | |
MISSION_CarryBoxTempUnit | unit | No | |
MISSION_CarryingBoxCount | integer | Yes | |
MISSION_CatchAnimalCount | integer | Yes | |
MISSION_CatchChickenArray | group | Yes | |
MISSION_CatchChickenPoint | location | No | |
MISSION_CatchCount | real | Yes | |
MISSION_CatchCustomValue | integer | No | |
MISSION_CatchTempInt | integer | No | |
MISSION_CatchTempUnit | unit | No | |
MISSION_CatchUnitGroup | group | No | |
MISSION_ChickenToBeRemoved | unit | Yes | |
MISSION_CooldownBoolean | boolean | Yes | |
MISSION_CoolingDownUnit | unit | No | |
MISSION_CourierCompleteCount | integer | Yes | |
MISSION_CourierCount | real | Yes | |
MISSION_CourierCustomValue | integer | No | |
MISSION_CourierDeliveryDone1 | boolean | Yes | |
MISSION_CourierDeliveryDone2 | boolean | Yes | |
MISSION_CourierTempInt | integer | No | |
MISSION_CourierTempPoint | location | No | |
MISSION_CourierTempUnit | unit | No | |
MISSION_CourierUnitGroup | group | No | |
MISSION_CrateSpecialEffect | effect | Yes | |
MISSION_DumpBoxDestination | location | No | |
MISSION_DumpBoxPoint | location | Yes | |
MISSION_DumpedBoxCount | integer | Yes | |
MISSION_FailTeleportToStart | location | Yes | |
MISSION_FinishedHeroPoint | location | No | |
MISSION_GroundPunchPoint | location | Yes | |
MISSION_LawnCustomValue | integer | No | |
MISSION_LawnTempInt | integer | No | |
MISSION_LawnTempUnit | unit | No | |
MISSION_LawnUnitGroup | group | No | |
MISSION_LawnWormKillCount | integer | Yes | |
MISSION_LawnWormNumber | integer | No | |
MISSION_LawnWormPoint | location | No | |
MISSION_LawnWormsCount | real | Yes | |
MISSION_MagicalBuffCount | integer | Yes | |
MISSION_MagicalBuffRandomNo | integer | No | |
MISSION_MagicalBuffsGroup | group | No | |
MISSION_MagicalBuffsStartPoint | location | No | |
MISSION_MagicBuffPeriodicCount | real | Yes | |
MISSION_MagicBuffsCustomValue | integer | No | |
MISSION_MagicBuffsHeroDied | boolean | Yes | |
MISSION_MagicBuffsTempUnit | unit | No | |
MISSION_MagicBuffTempInt | integer | No | |
MISSION_MeatLaunchPoint | location | Yes | |
MISSION_MeatThrowCustomValue | integer | No | |
MISSION_MeatThrowerBeingUsed | boolean | No | |
MISSION_MeatThrowerHeroUnit | unit | Yes | |
MISSION_MeatThrowerPoint | location | No | |
MISSION_MeatThrowerWormPoint | location | Yes | |
MISSION_MeatThrowKillCount | integer | Yes | 5 |
MISSION_MeatThrowPeriodicCount | real | Yes | |
MISSION_MeatThrowPeriodicGroup | group | No | |
MISSION_MeatThrowTempInt | integer | No | |
MISSION_MeatThrowTempUnit | unit | No | |
MISSION_MeatThrowVisibility | fogmodifier | Yes | |
MISSION_MeatThrowZeppUnit | unit | Yes | |
MISSION_OnMissionCurrently | boolean | Yes | |
MISSION_PositionOfHeroUnit | location | No | |
MISSION_RockCreateGroup | group | No | |
MISSION_RockHarvestCount | integer | Yes | |
MISSION_RockHarvestCustomValue | integer | No | |
MISSION_RockHarvestRockPoint | location | Yes | |
MISSION_RockHarvestStart | boolean | Yes | |
MISSION_RockHarvKoboldRespawn | location | No | |
MISSION_RockHarvPeriodicCount | real | Yes | |
MISSION_RockHarvPeriodicGroup | group | No | |
MISSION_RockHarvTempInt | integer | No | |
MISSION_RockHarvTempUnit | unit | No | |
MISSION_RockRespawnCount | real | Yes | |
MISSION_RockRespawnCustomValue | integer | No | |
MISSION_RockRespawnTempInt | integer | No | |
MISSION_SnapDragonSpawnPoint | location | No | |
MISSION_StartSoundPlayer | player | No | |
MISSION_TempGainAbillityForJob | abilcode | Yes | |
MISSION_TempItem1 | item | Yes | |
MISSION_TempItem2 | item | Yes | |
MISSION_TempItem3 | item | Yes | |
MISSION_WaterDistanceBetween | real | Yes | |
MISSION_WaterSkiCount | integer | Yes | |
MISSION_WaterSkiCreatePoint | location | No | |
MISSION_WaterSkiCustomValue | integer | No | |
MISSION_WaterSkiDistanceToGo | real | No | |
MISSION_WaterSkiDistanceToMove | real | No | |
MISSION_WaterSkierUnit | unit | Yes | |
MISSION_WaterSkiHeroUnit | unit | Yes | |
MISSION_WaterSkiierTempUnit | unit | No | |
MISSION_WaterSkiLeash | lightning | Yes | |
MISSION_WaterSkiMoveSkierPoint | location | No | |
MISSION_WaterskiPeriodicGroup | group | No | |
MISSION_WaterskiPingPoint | location | No | |
MISSION_WaterSkiPointSkier | location | Yes | |
MISSION_WaterSkiPointTurtle | location | Yes | |
MISSION_WaterSkiRandomNo | integer | No | |
MISSION_WaterskiStart | boolean | Yes | |
MISSION_WaterSkiSurfEffect1 | effect | Yes | |
MISSION_WaterSkiSurfEffect2 | effect | Yes | |
MISSION_WaterSkiSurfEffect3 | effect | Yes | |
MISSION_WaterSkiTautLinePt | location | No | |
MISSION_WaterSkiTempHero | unit | No | |
MISSION_WaterSkiTempInt | integer | No | |
MISSION_WaterSkiTurtleAngle180 | real | Yes | |
MISSION_WaterSkiTurtleTempUnit | unit | No | |
MISSION_WaterSkiTurtleUnit | unit | Yes | |
MODESELECT_BothEnabled | boolean | No | false |
MODESELECT_Enabled | boolean | No | true |
MODESELECT_LandEnabled | boolean | No | false |
MODESELECT_PlayerBoth | integer | Yes | |
MODESELECT_PlayerLand | integer | Yes | |
MODESELECT_PlayerSea | integer | Yes | |
MODESELECT_SeaEnabled | boolean | No | false |
MODESELECT_TempInt | integer | Yes | |
MULTIBOARD_List | integer | No | |
MULTIBOARD_MainBoard | multiboard | No | |
MULTIBOARD_Spots | integer | Yes | |
NAGA_Caravan | unit | Yes | |
NAGA_CaravanLeader | unit | Yes | |
NAGA_GoldStash | integer | Yes | 50 |
NAGA_RespawnTimer | timer | Yes | |
NAGA_UnitGroupP11 | group | No | |
NAGA_UnitGroupP12 | group | No | |
output | integer | Yes | |
PET_Size | real | Yes | |
PetDeathTimer | timer | Yes | |
PetDeathTimerWindow | timerdialog | Yes | |
PETS_AuraAbilityGroup | group | No | |
PETS_AuraRandomNo | integer | No | |
PETS_AuraTempUnit | unit | No | |
PETS_DamageAuraUnitGroup | group | No | |
PETS_DefenseAuraUnitGroup | group | No | |
PETS_SpeedAuraUnitGroup | group | No | |
PirateBossLevel | integer | Yes | |
PirateBossUnit | unit | Yes | |
PirateHandNotTransformedYet | boolean | Yes | true |
PlantSeedPoint | location | No | |
PLAYER_KillHeroUnitSound | player | No | |
PlayerAgilityPoints | integer | Yes | |
PlayerBoughtOutpostPingPt | location | No | |
PlayerCanChooseAttribute | boolean | Yes | |
PlayerClaimIsle1 | player | No | |
PlayerClaimIsle2 | player | No | |
PlayerClaimIsle3 | player | No | |
PlayerClaimIsle4 | player | No | |
PlayerClaimIsle5 | player | No | |
PlayerClaimIsle6 | player | No | |
PlayerClaimIsle7 | player | No | |
PlayerClaimIsle8 | player | No | |
PlayerHasAnIsland | boolean | Yes | |
PlayerHasOutpostItem | boolean | Yes | |
PlayerHeroExp | integer | Yes | |
PlayerHeroLevel | integer | Yes | |
PlayerIslandClaimNumber_SOH | integer | Yes | |
PlayerMagicPoints | integer | Yes | |
PlayerOnAMission | boolean | Yes | |
PlayerPetMovePoint | location | No | |
PlayerPetPoint | location | No | |
PLAYERPETUNIT | unit | Yes | |
PlayerRangedPoints | integer | Yes | |
PLAYERS_Colours | string | Yes | |
PLAYERS_DeathCount | integer | Yes | |
PLAYERS_KillCount | integer | Yes | |
PLAYERS_NoOfPlayersPlaying | integer | No | |
PLAYERS_PlayerKillCount | integer | Yes | |
PlayersHaveAShip | boolean | Yes | |
PLAYERSHIPS | unit | Yes | |
PLAYERSHIPS_DieCustomValue | integer | No | |
PLAYERSHIPS_DieFX | effect | Yes | |
PLAYERSHIPS_DiePeriodicCount | real | Yes | |
PLAYERSHIPS_DieTempInt | integer | No | |
PLAYERSHIPS_ShipsDieGroup | group | No | |
PlayerStrengthPoints | integer | Yes | |
RC | boolean | No | |
RespawnTimers | timer | Yes | |
RespawnTimerWindows | timerdialog | Yes | |
Result | itemcode | Yes | |
RGD_IlluminationPoint | location | No | |
RGD_IlluminationUnitGroup | group | No | |
RGD_ReinforceCount | real | Yes | |
RGD_ReinforceCustomValue | integer | No | |
RGD_ReinforceFlamePoint | location | Yes | |
RGD_ReinforceHeroGroup | group | No | |
RGD_ReinforcePoint | location | Yes | |
RGD_ReinforceTank | unit | Yes | |
RGD_ReinforceTempInt | integer | No | |
RGD_ReinforceTempUnit | unit | No | |
RGD_ReinforceUnitGroup | group | Yes | |
RGD_TrophyAngleDiff | real | No | |
RGD_TrophyEnemyFacing | real | No | |
RGD_TrophyHeroFacing | real | No | |
RGDMGC_AcidBlastAttacker | unit | Yes | |
RGDMGC_AcidBlastBoolean | boolean | Yes | |
RGDMGC_AcidBlastCount | real | Yes | |
RGDMGC_AcidBlastCustomValue | integer | No | |
RGDMGC_AcidBlastEnemyPt | location | No | |
RGDMGC_AcidBlastEnemyUnit | unit | Yes | |
RGDMGC_AcidBlastHeroGroup | group | No | |
RGDMGC_AcidBlastHeroPoint | location | Yes | |
RGDMGC_AcidBlastHeroPt | location | No | |
RGDMGC_AcidHeroUnitTemp | unit | No | |
RGDMGC_AcidTempInt | integer | No | |
RGDMGC_HydraAttackPoint | location | Yes | |
RGDMGC_HydraCount | real | Yes | |
RGDMGC_HydraCustomValue | integer | No | |
RGDMGC_HydraEffect | effect | Yes | |
RGDMGC_HydraHeroGroup | group | No | |
RGDMGC_HydraHeroTemp | unit | No | |
RGDMGC_HydraPoint | location | Yes | |
RGDMGC_HydraTempInt | integer | No | |
RGDMGC_HydraUnit | unit | Yes | |
RGDMGC_ToxicPt | location | No | |
RN | integer | No | |
RockHarvestGolemDiesPoint | location | No | |
RockHarvestKoboldDeadCount | integer | No | |
RockHarvestKoboldMoveTo | location | No | |
RockHarvestKoboldUnit | unit | Yes | |
RRPirateBossDead | boolean | No | |
RRPlayerGroup | force | No | |
RT | trigger | No | |
SCURVY_CureCount | integer | Yes | |
SCURVY_CustomValue | integer | No | 1 |
ScurvyCurePoint | location | No | |
SEADOG_DirtyFightingRandomNo | integer | No | |
SEADOG_EffectPlacement | string | Yes | |
SEADOG_NetFlourishGroup | group | No | |
SEADOG_NetFlourishUnitsNo | integer | No | |
SEADOG_PileOnCustomValue | integer | No | |
SEADOG_PileOnDamageReal | real | No | |
SEADOG_PileOnDummyGroup | group | Yes | |
SEADOG_PileOnEffectsP1 | effect | Yes | |
SEADOG_PileOnEffectsP2 | effect | Yes | |
SEADOG_PileOnEffectsP3 | effect | Yes | |
SEADOG_PileOnEffectsP4 | effect | Yes | |
SEADOG_PileOnEffectsP6 | effect | Yes | |
SEADOG_PileOnEffectsP7 | effect | Yes | |
SEADOG_PileOnEffectsP8 | effect | Yes | |
SEADOG_PileOnEffectsP9 | effect | Yes | |
SEADOG_PileOnGroup | group | No | |
SEADOG_PileOnHero | unit | Yes | |
SEADOG_PileOnPeriodicCount | real | Yes | |
SEADOG_PileOnPt1 | location | No | |
SEADOG_PileOnPt2 | location | No | |
SEADOG_PileOnPt3 | location | No | |
SEADOG_PileOnTarget | unit | Yes | |
SEADOG_PileOnTargetPt1 | location | No | |
SEADOG_PileOnTempInt | integer | No | |
SEADOG_PileOnTempUnit | unit | No | |
SEAMONSTER_EnemiesInRange | group | No | |
SEAMONSTER_RandomNo | integer | No | |
SeaSpawnAttackMovePoint | location | No | |
SeaSpawnAttackMovePoint2 | location | No | |
SeaSpawnAttackMovePoint3_Base | location | No | |
SeaSpawnMoveCheckGroup | group | No | |
SetPirateBossLevel | integer | No | |
SHIP_BattleshipRearShipPt | location | No | |
SHIP_BattleshipRearTargetCast | location | No | |
SHIP_BattleshipTargetPtReal | real | No | |
SHIP_SpawnPointCreate | location | No | |
SHIP_SpawnTempUnit | unit | No | |
SHIPREPAIR_CustomValue | integer | No | |
SHIPREPAIR_PeriodicCount | real | Yes | |
SHIPREPAIR_Player | player | Yes | |
SHIPREPAIR_RepairAvailable | boolean | Yes | true |
SHIPREPAIR_RepairCreatePt | location | No | |
SHIPREPAIR_RepairGroup | group | No | |
SHIPREPAIR_RepairGuyThrowPt | location | No | |
SHIPREPAIR_RepairUnit1 | unit | Yes | |
SHIPREPAIR_RepairUnit2 | unit | Yes | |
SHIPREPAIR_RepairUnit3Thrower | unit | Yes | |
SHIPREPAIR_RepairUnitPlatform1 | effect | Yes | |
SHIPREPAIR_RepairUnitPlatform2 | effect | Yes | |
SHIPREPAIR_RepairUnitPlatform3 | effect | Yes | |
SHIPREPAIR_ShipPt | location | No | |
SHIPREPAIR_ShipToRepair | unit | Yes | |
SHIPREPAIR_TempInt | integer | No | |
SHIPREPAIR_TempShip | unit | No | |
SHIPS_BargeWaterFinalGroup | group | No | |
SHIPS_BargeWaterPoint | location | No | |
SHIPS_BargeWaterReal | real | No | |
SHIPS_BargeWaterShipPt | location | No | |
SHIPS_BargeWaterTempGroup | group | No | |
SHIPS_BargeWaterTempPt | location | No | |
SHIPS_BattleshipSmokePt | location | No | |
SHIPS_BattleshipSmokeShipPt | location | No | |
SHIPS_GhostlyMirageShipUnit | unit | No | |
SHIPS_LoneManCustomValue | integer | No | |
SHIPS_LoneManEffect | effect | Yes | |
SHIPS_LongRangeCustomVal | integer | No | |
SHIPS_LongRangeGroup | group | No | |
SHIPS_LongRangePeriodicCount | real | Yes | |
SHIPS_LongRangeShipHero | unit | Yes | |
SHIPS_LongRangeTargetPoint | location | Yes | |
SHIPS_LongRangeTempInt | integer | No | |
SHIPS_SideFire_BackLeft | location | No | |
SHIPS_SideFire_BackRight | location | No | |
SHIPS_SideFire_FrontLeft | location | No | |
SHIPS_SideFire_FrontRight | location | No | |
SHIPS_SideFire_MidLeft | location | No | |
SHIPS_SideFire_MidRight | location | No | |
SHIPS_SideFirePointDummyPt1 | location | No | |
SHIPS_SideFirePointDummyPt2 | location | No | |
SHIPS_SideFirePointPort_BL | location | No | |
SHIPS_SideFirePointPort_FL | location | No | |
SHIPS_SideFirePointPort_ML | location | No | |
SHIPS_SideFirePointStarbo_BR | location | No | |
SHIPS_SideFirePointStarbo_FR | location | No | |
SHIPS_SideFirePointStarbo_MR | location | No | |
ShipTransItemP1 | itemcode | Yes | |
ShipTransItemP2 | itemcode | Yes | |
ShipTransItemP3 | itemcode | Yes | |
ShipTransItemP4 | itemcode | Yes | |
ShipTransItemP6 | itemcode | Yes | |
ShipTransItemP7 | itemcode | Yes | |
ShipTransItemP8 | itemcode | Yes | |
ShipTransItemP9 | itemcode | Yes | |
ShipTransLevel | integer | Yes | |
SHIPTRAVEL_NorthEast_SouthWest | boolean | No | |
SHIPTRAVEL_NorthWest_SouthEast | boolean | No | |
SHIPTRAVEL_Point | location | No | |
SpecialEffectVarForUsers1 | effect | Yes | |
SpellChanneler | unit | Yes | |
STONEofHome_GoToIsle | boolean | Yes | |
STONEofHome_GoToTown | boolean | Yes | true |
STONEofHomeCustomValue | integer | No | |
STONEofHomeDestinationPt | location | No | |
STONEofHomeGroup | group | No | |
STONEofHomeHero | unit | Yes | |
STONEofHomeHeroPt | location | No | |
STONEofHomePeriodicCount | real | Yes | |
STONEofHomeSFX1 | effect | Yes | |
STONEofHomeSFX2 | effect | Yes | |
STONEofHomeTempInt | integer | No | |
STR_ButtonCount | real | Yes | |
STR_ButtonCustomValue | integer | No | |
STR_ButtonGroup | group | No | |
STR_ButtonTempHero | unit | No | |
STR_ButtonTempInt | integer | No | |
STR_GladiatorCount | real | Yes | |
STR_GladiatorCustomValue | integer | No | |
STR_GladiatorDistanceToMove | real | Yes | |
STR_GladiatorEnemy | unit | Yes | |
STR_GladiatorEnemyPoint | location | Yes | |
STR_GladiatorHero | unit | Yes | |
STR_GladiatorHeroPoint | location | Yes | |
STR_GladiatorLeash | lightning | Yes | |
STR_GladiatorTempInt | integer | No | |
STR_GladiatorUnitGroup | group | No | |
STRAGI_DanceDamageInt | integer | Yes | |
STRAGI_DanceUnit | unit | Yes | |
STRAGI_DashCastPoint | location | Yes | |
STRAGI_DashCount | real | Yes | |
STRAGI_DashCustomValue | integer | No | |
STRAGI_DashDirectionAngle | real | Yes | |
STRAGI_DashHero | unit | Yes | |
STRAGI_DashHeroGroup | group | No | |
STRAGI_DashHeroPoint | location | Yes | |
STRAGI_DashMovePoint | location | Yes | |
STRAGI_DashSmashedUnit | unit | Yes | |
STRAGI_DashTempInt | integer | No | |
STRAGI_DashTempUnit | unit | No | |
STRAGI_MishaAttackDamage | real | No | |
STRAGI_TantrumCount | real | Yes | |
STRAGI_TantrumCustomValue | integer | No | |
STRAGI_TantrumHeroGroup | group | No | |
STRAGI_TantrumPoint | location | Yes | |
STRAGI_TantrumTempInt | integer | No | |
STRAGI_ThrashCount | real | Yes | |
STRAGI_ThrashCustomValue | integer | No | |
STRAGI_ThrashEnemyPoint | location | Yes | |
STRAGI_ThrashExtraDamage | integer | Yes | |
STRAGI_ThrashHero | unit | Yes | |
STRAGI_ThrashHeroPoint | location | Yes | |
STRAGI_ThrashRoll | integer | Yes | |
STRAGI_ThrashTempInt | integer | No | |
STRAGI_ThrashUnitGroup | group | No | |
STRAGI_WoundCustomValue | integer | No | |
STRAGI_WoundDanceCount | real | Yes | |
STRAGI_WoundDanceHero | unit | Yes | |
STRAGI_WoundGroup | group | No | |
STRAGI_WoundTempInt | integer | No | |
STRButtonBurstEnemyCount | integer | Yes | |
STRButtonBurstEnemyPoint | location | Yes | |
STRButtonBurstEnemysInVicinity | group | Yes | |
STRButtonBurster_RangeMoved | real | Yes | |
STRButtonBurstHeroPoint | location | Yes | |
STRMGC_CrustAttackedUnits | group | No | |
STRMGC_CrustCustomValue | integer | No | |
STRMGC_CrustFiringTime | boolean | Yes | |
STRMGC_CrustHero | unit | Yes | |
STRMGC_CrustPeriodicCount | real | Yes | |
STRMGC_CrustTempInt | integer | No | |
STRMGC_CrustUnitGroup | group | No | |
STRMGC_DragonBreathPoint | location | Yes | |
STRMGC_DragonsBreathGroup | group | Yes | |
STRMGC_MagmaCount | real | Yes | |
STRMGC_MagmaCustomValue | integer | No | |
STRMGC_MagmaHero | unit | Yes | |
STRMGC_MagmaHeroFacing | real | Yes | |
STRMGC_MagmaHeroPoint | location | Yes | |
STRMGC_MagmaPoint | location | Yes | |
STRMGC_MagmaTempInt | integer | No | |
STRMGC_MagmaUnitGroup | group | No | |
STRMGC_RandomNumber | integer | No | |
STRMGC_TempUnit | unit | No | |
STRMGCMagmaFireEffect1 | effect | Yes | |
STRMGCMagmaFireEffect2 | effect | Yes | |
STRMGCMagmaFireEffect3 | effect | Yes | |
STRMGCMagmaFireEffect4 | effect | Yes | |
STRMGCMagmaFireEffect5 | effect | Yes | |
STRMGCMagmaFireEffect6 | effect | Yes | |
STRMGCMagmaFireEffect7 | effect | Yes | |
STRMGCMagmaFireEffect8 | effect | Yes | |
STRMGCMagmaFireEffect9 | effect | Yes | |
STRRGD_BeamGolemEffect1 | effect | Yes | |
STRRGD_BeamUnit | unit | Yes | |
STRRGD_CondCustomValue | integer | No | |
STRRGD_CondFireAngle | real | Yes | |
STRRGD_CondFireCustomValue | integer | No | |
STRRGD_CondFireTempInt | integer | No | |
STRRGD_CondFireUnitGroup | group | No | |
STRRGD_ConditionCount | real | Yes | |
STRRGD_ConditioningEffect1 | effect | Yes | |
STRRGD_ConditioningPoint | location | Yes | |
STRRGD_ConditionTempInt | integer | No | |
STRRGD_ConditionUnitGroup | group | No | |
STRRGD_CondTempUnit | unit | No | |
STRRGD_EnemyPoint | location | Yes | |
STRRGD_GolemDiePoint | location | No | |
STRRGD_HammerCount | real | Yes | |
STRRGD_HammerCustomValue | integer | No | |
STRRGD_HammerDamage | real | Yes | |
STRRGD_HammerDistanceBetween | real | Yes | |
STRRGD_HammerDistanceCheck | real | Yes | |
STRRGD_HammerEnemy1 | unit | Yes | |
STRRGD_HammerFoundNearestUnit1 | boolean | Yes | |
STRRGD_HammerFoundNearestUnit2 | boolean | Yes | |
STRRGD_HammerMoveTo | location | Yes | |
STRRGD_HammerNearestUnit1 | unit | Yes | |
STRRGD_HammerNearestUnit2 | unit | Yes | |
STRRGD_HammerNewTargetPoint | location | Yes | |
STRRGD_HammerReachedEnemy1 | boolean | Yes | |
STRRGD_HammerReachedEnemy2 | boolean | Yes | |
STRRGD_HammerReachedEnemy3 | boolean | Yes | |
STRRGD_HammerTempInt | integer | No | |
STRRGD_HammerUnit | unit | Yes | |
STRRGD_HammerUnitGroup | group | No | |
STRRGD_HammerUnitsWithinRange | group | Yes | |
STRRGD_HeroPoint | location | Yes | |
STRRGD_HeroTempUnit | unit | No | |
STRRGD_HurlCount | real | Yes | |
STRRGD_HurlCustomValue | integer | No | |
STRRGD_HurlHeroGroup | group | No | |
STRRGD_HurlHeroUnitTemp | unit | No | |
STRRGD_HurlRockCasterPoint | location | Yes | |
STRRGD_HurlRockPoint | location | Yes | |
STRRGD_HurlTempInt | integer | No | |
STRRGD_HurlTurretSetupGroup | group | Yes | |
STRRGD_HurlTurretTempPoint | location | No | |
STRRGD_LeyCasterPoint | location | Yes | |
STRRGD_LeyCustomValue | integer | No | |
STRRGD_LeyNodeCaster | unit | Yes | |
STRRGD_LeyNodePoint | location | Yes | |
STRRGD_LeyNodeUnitGroup | group | No | |
STRRGD_LeyNodeUnitTemp | unit | No | |
STRRGD_LeyTargetPoint | location | Yes | |
STRRGD_LeyTempInt | integer | No | |
TempGainAbillityForJobs2 | abilcode | Yes | |
testtesttest | unit | No | |
TimerForUserMissions | timer | Yes | |
TimerForUserMissionsWindow | timerdialog | Yes | |
TotalAttributePointsPerPlayer | integer | Yes | |
TRADE_AnimalStock | integer | Yes | |
TRADE_ChickenValue | integer | No | |
TRADE_DrakenipStock | integer | Yes | |
TRADE_EggsValue | integer | No | |
TRADE_FruitStock | integer | Yes | |
TRADE_FruitValue | integer | No | |
TRADE_GoldAmount | integer | No | |
TRADE_LambValue | integer | No | |
TRADE_TempUnit | unit | No | |
TRADE_WoolValue | integer | No | |
TransformInProgressHero | unit | No | |
TURRETUP_BlitzResearched | boolean | Yes | |
TURRETUP_GuardResearched | boolean | Yes | |
TURRETUP_ManaResearched | boolean | Yes | |
TURRETUP_SlowResearched | boolean | Yes | |
UPGRADE_Harvesters | boolean | Yes | |
UPGRADE_HarvestersGroup | group | No |
====================================================================
Recipe System. /
By Diablo-dk. /
====================================================================
Introduction:
This is a simple JASS recipe system that i made, using global arrays.
i made it as userfriendly as possible.
NOTE: this system uses ItemUserData.
Usage:
It is Very Simple how to use it. (check the Demo trigger for an example)
You create a new recipe this way:
call CreateRecipe2(itemid1,itemid2,itemid3.
Add this line to map initialization, and the system will do the rest.
itemid1 and itemid2 is the items required to make the recipe.
itemid3 is the combined item.
i also made some other functions for handling bigger recipes
CreateRecipe3
CreateRecipe4
CreateRecipe5
CreateRecipe6
they all do the same expect that they require x amount of items to combine.
the last itemid is always the combined item.
Another way to do it is just calling CreateRecipe(id,id,id,id,id,id,output)
this function can sometimes be handy if you don't like writing the number,
but keep in mind that you will have to enter 7 arguments no matter what, an example
would be this:
call CreateRecipe(id1,id2,id3,id4,0,0,output)
NOTE: this function is slightly slower than the others as it uses ifs.
and keep in mind that you should not make a recipe with it like this:
call CreateRecipe(id1,0,id2,id3,0,0,output)
all zeros MUST be after the ids or else it will bug.
I added a DisItem function too.
call DisItem(somerecipeitem)
It disassembles the recipe item entered to its original components.
It also returns a boolean. if there's not enough space for the items, or if it's not a
recipe item, it will return false.
in any other case it will return true
Implemention:
To implement this system into your map you just have to copy the Recipe trigger script
to your map header(custom script section)
and the GlobalVars trigger(make sure to remove it again and have automatically
create unknown variables)
Also, add this line to map initialization: Custom script: call InitRecipe()
And 1 more important thing. Remember to give credits if you use in your map!
//=======================================================================================================
// Recipe System
// By Fredbrik(Diablo-dk)
//
//=======================================================================================================
//globals
//integer RN=0 // Recipe number.
//trigger RT=CreateTrigger() // Main recipe trigger.
//boolean RC=true
//integer array itemid1
//integer array itemid2
//integer array itemid3
//integer array itemid4
//integer array itemid5
//integer array itemid6
//integer array ic //item count
//integer array output
//endglobals
//=======================================================================================================
// User changeable constants
//=======================================================================================================
constant function Recipe_Effect takes nothing returns string
return "Abilities\\Spells\\Items\\AIem\\AIemTarget.mdl" //An effect that comes whenever a recipe is made.
endfunction
constant function Recipe_AP takes nothing returns string
return "origin" //Attachment point for Recipe_Effect()
endfunction
//=======================================================================================================
// This function will return the first item of entered Id in the unit's inventory.
function GetItem takes unit u, integer Id returns item
local integer i=0
local item it
loop
exitwhen i==6
if GetItemTypeId(UnitItemInSlot(u,i)) == Id then
return UnitItemInSlot(u,i)
set i=5
endif
set i=i+1
endloop
return null
endfunction
//==============================
function HasItems takes unit u, integer i returns boolean
local integer index=0
local integer id=-1
local integer b1=0
local integer b2=0
local integer b3=0
local integer b4=0
local integer b5=0
local integer b6=0
loop
exitwhen index==6
set id=GetItemTypeId(UnitItemInSlot(u,index))
if id == 0 then
set id=-1
endif
if id == udg_itemid1[i] and b1 == 0 then
set b1=1
set id=-1
endif
if id == udg_itemid2[i] and b2 == 0 then
set b2=1
set id=-1
endif
if id == udg_itemid3[i] and b3 == 0 then
set b3=1
set id=-1
endif
if id == udg_itemid4[i] and b4 == 0 then
set b4=1
set id=-1
endif
if id == udg_itemid5[i] and b5 == 0 then
set b5=1
set id=-1
endif
if id == udg_itemid6[i] and b6 == 0 then
set b6=1
set id=-1
endif
if b1+b2+b3+b4+b5+b6 == udg_ic[i] then
return true
endif
set index=index+1
endloop
return false
endfunction
//=======================================================================================================
// User Functions:
// Recipe Creating:
//
//=======================================================================================================
function CreateRecipe takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6,integer output returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_ic[udg_RN]=2
if i3 != 0 then
set udg_itemid3[udg_RN]=i3
set udg_ic[udg_RN]=udg_ic[udg_RN]+1
endif
if i4 != 0 then
set udg_itemid4[udg_RN]=i4
set udg_ic[udg_RN]=udg_ic[udg_RN]+1
endif
if i5 != 0 then
set udg_itemid5[udg_RN]=i5
set udg_ic[udg_RN]=udg_ic[udg_RN]+1
endif
if i6 != 0 then
set udg_itemid6[udg_RN]=i6
set udg_ic[udg_RN]=udg_ic[udg_RN]+1
endif
set udg_output[udg_RN]=output
endfunction
function CreateRecipe2 takes integer i1,integer i2,integer i3 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_output[udg_RN]=i3
set udg_ic[udg_RN]=2
endfunction
// Creates a recipe that requires 2 items to combine into a new item. i3 is the combined item.
// Example: call CreateRecipe2('I000','I001','I002')
function CreateRecipe3 takes integer i1,integer i2,integer i3,integer i4 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_itemid3[udg_RN]=i3
set udg_output[udg_RN]=i4
set udg_ic[udg_RN]=3
endfunction
// The same as CreateRecipe2 except this requires 3 items to combine. i4 is the combined item.
function CreateRecipe4 takes integer i1,integer i2,integer i3,integer i4,integer i5 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_itemid3[udg_RN]=i3
set udg_itemid4[udg_RN]=i4
set udg_output[udg_RN]=i5
set udg_ic[udg_RN]=4
endfunction
// The same as CreateRecipe2 except this requires 4 items to combine. i5 is the combined item.
function CreateRecipe5 takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_itemid3[udg_RN]=i3
set udg_itemid4[udg_RN]=i4
set udg_itemid5[udg_RN]=i5
set udg_output[udg_RN]=i6
set udg_ic[udg_RN]=5
endfunction
// The same as CreateRecipe2 except this requires 5 items to combine. i6 is the combined item.
function CreateRecipe6 takes integer i1,integer i2,integer i3,integer i4,integer i5,integer i6,integer i7 returns nothing
set udg_RN=udg_RN+1
set udg_itemid1[udg_RN]=i1
set udg_itemid2[udg_RN]=i2
set udg_itemid3[udg_RN]=i3
set udg_itemid4[udg_RN]=i4
set udg_itemid5[udg_RN]=i5
set udg_itemid6[udg_RN]=i6
set udg_output[udg_RN]=i7
set udg_ic[udg_RN]=6
endfunction
// The same as CreateRecipe2 except this requires 6 items to combine. i7 is the combined item.
//===================================================================================================
// This function disassembles a recipe item to its original components.
function DisItem takes unit u,item it returns boolean
local integer c=GetItemUserData(it)
local item array newitem
local integer i=udg_ic[c]
if it != null then
if i <= 6-UnitInventoryCount(u)+1 and i > 0 then
set udg_RC=false
if udg_itemid2[c] != null then
set newitem[1]=CreateItem(udg_itemid1[c],GetUnitX(u),GetUnitY(u))
set newitem[2]=CreateItem(udg_itemid2[c],GetUnitX(u),GetUnitY(u))
endif
if udg_itemid3[c] != null then
set newitem[3]=CreateItem(udg_itemid3[c],GetUnitX(u),GetUnitY(u))
call UnitAddItem(u,newitem[3])
endif
if udg_itemid4[c] != null then
set newitem[4]=CreateItem(udg_itemid4[c],GetUnitX(u),GetUnitY(u))
call UnitAddItem(u,newitem[4])
endif
if udg_itemid5[c] != null then
set newitem[5]=CreateItem(udg_itemid5[c],GetUnitX(u),GetUnitY(u))
call UnitAddItem(u,newitem[5])
endif
if udg_itemid6[c] != null then
set newitem[6]=CreateItem(udg_itemid6[c],GetUnitX(u),GetUnitY(u))
call UnitAddItem(u,newitem[6])
endif
call RemoveItem(it)
call UnitAddItem(u,newitem[1])
call UnitAddItem(u,newitem[2])
set newitem[1]=null
set newitem[2]=null
set newitem[3]=null
set newitem[4]=null
set newitem[5]=null
set newitem[6]=null
set udg_RC=true
else
return false
endif
endif
return true
endfunction
//=======================================================================================================
//
//Main Recipe Function: Do not change unless you know what you are doing
//
//=======================================================================================================
function Recipe_Main takes nothing returns nothing
local item it
local integer i=0
local unit u=GetManipulatingUnit()
loop
exitwhen i==udg_RN
set i=i+1
if udg_RC == true then
if udg_ic[i] == 6 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call RemoveItem(GetItem(u,udg_itemid3[i]))
call RemoveItem(GetItem(u,udg_itemid4[i]))
call RemoveItem(GetItem(u,udg_itemid5[i]))
call RemoveItem(GetItem(u,udg_itemid6[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
elseif udg_ic[i] == 5 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call RemoveItem(GetItem(u,udg_itemid3[i]))
call RemoveItem(GetItem(u,udg_itemid4[i]))
call RemoveItem(GetItem(u,udg_itemid5[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
elseif udg_ic[i] == 4 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call RemoveItem(GetItem(u,udg_itemid3[i]))
call RemoveItem(GetItem(u,udg_itemid4[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
elseif udg_ic[i] == 3 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call RemoveItem(GetItem(u,udg_itemid3[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
elseif udg_ic[i] == 2 then
if HasItems(u,i) then
call RemoveItem(GetItem(u,udg_itemid1[i]))
call RemoveItem(GetItem(u,udg_itemid2[i]))
call DestroyEffect(AddSpecialEffectTarget(Recipe_Effect(),u,Recipe_AP()))
set it=CreateItem(udg_output[i],GetUnitX(u),GetUnitY(u))
call SetItemUserData(it,i) //Used for disassembling.
call UnitAddItem(u,it)
set i=udg_RN
endif
endif
endif
endloop
set it=null
set u=null
endfunction
function InitRecipe takes nothing returns nothing
set udg_RT=CreateTrigger()
set udg_RC=true
call TriggerRegisterAnyUnitEventBJ( udg_RT, EVENT_PLAYER_UNIT_PICKUP_ITEM )
call TriggerAddAction(udg_RT,function Recipe_Main)
endfunction
//call this at map init.
//forced by WE
function InitTrig_Recipe takes nothing returns nothing
endfunction
// End Recipe
//TESH.scrollpos=0
//TESH.alwaysfold=0
library Table initializer init
//***************************************************************
//* Table object
//* ------------
//*
//* set t=Table.create() - instanceates a new table object
//* call t.destroy() - destroys it
//* t[1234567] - Get value for key 1234567
//* (zero if not assigned previously)
//* set t[12341]=32 - Assigning it.
//* call t.flush(12341) - Flushes the stored value, so it
//* doesn't use any more memory
//* t.exists(32) - Was key 32 assigned? Notice
//* that flush() unassigns values.
//* call t.reset() - Flushes the whole contents of the
//* Table.
//*
//* call t.destroy() - Does reset() and also recycles the id.
//*
//* If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//***************************************************************
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//=========================================================
private gamecache gc
endglobals
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushStoredMission(gc,I2S(this))
endmethod
private method onDestroy takes nothing returns nothing
call FlushStoredMission(gc,I2S(this))
endmethod
endstruct
//Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
//! textmacro Table__make takes name, type, key
struct $name$ extends GTable
integer i = 0
method operator [] takes $type$ key returns integer
return GetStoredInteger(gc,I2S(this),$key$)
endmethod
method operator []= takes $type$ key, integer value returns nothing
call StoreInteger(gc,I2S(this),$key$, value)
endmethod
method flush takes $type$ key returns nothing
call FlushStoredInteger(gc,I2S(this),$key$)
endmethod
method exists takes $type$ key returns boolean
return HaveStoredInteger(gc,I2S(this),$key$)
endmethod
endstruct
//! endtextmacro
private function H2I takes handle h returns integer
// return h
return 0
endfunction
//! runtextmacro Table__make("Table","integer","I2S(key)" )
//! runtextmacro Table__make("StringTable","string","key" )
//! runtextmacro Table__make("HandleTable","handle","I2S(H2I(key))" )
//=============================================================
// initialize it all.
//
private function init takes nothing returns nothing
call FlushGameCache(InitGameCache("libtable.gc"))
set gc=InitGameCache("libtable.gc")
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library RecipeSYS initializer Init uses Table
// ¤ v0.6d ¤
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// ) RecipeSYS (
// ( Created by Artificial )
// )*'*-._.-*'*-._.-*'*-._.-*'*(
// ¤ ¤
//
// How to use the RecipeSYS
// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
// ---- Adding recipes
// Adding recipes is rather easy. You just call a function
// and give it some arguments. The function you call is
// recipe.create, and is called like this:
//
// call recipe.create(i1, i2, i3, i4, i5, i6, result, sfx, attPoint, charges, chargeType)
//
// i1 - i6 are the raw codes* of the items required for the
// recipe to combine. result is the raw code of the item they
// will combine to. sfx is the path of the special effect you
// want to use (give "" for default), and attPoint the attachment
// point of it ("" for default). The boolean charges is whether
// the result should have some other amount of charges than the
// default one. If it is true, chargeType determines what amount
// of charges the result will get when combined (-1 => amount of
// charges left in the ingredient with most charges, 0 => sum of
// charges left in the ingredients, anything else => the number
// given as the argument).
//
// * You can find out the rawcodes by going to the object
// editor and pressing ctrl + D. The first 4 characters
// are the rawcode of the item. When calling the function,
// remember to put the rawcode between ' and ' in case
// you want it to work.
//
// If you want the recipe to require less than 6 items, just give
// zeros as ingredient arguments.
//
// --- AddRecipe Wrappers
// You can also add recipes using some of the wrapper
// functions: AddRecipe, AddRecipeEx, AddRecipeWithCharges,
// and AddRecipeWithChargesEx.
//
// AddRecipe takes i1, i2, i3, i4, i5, i6, result
// AddRecipeEx takes i1, i2, i3, i4, i5, i6, result, sfx, attPoint
// AddRecipeWithCharges takes i1, i2, i3, i4, i5, i6, result, chargeType
// AddRecipeWithChargesEx takes i1, i2, i3, i4, i5, i6, result, chargeType, sfx, attPoint
//
// ---- Removing Recipes
// There are two ways of removing recipes: destroyin a specific
// recipe and removing recipes by the result (removes all recipes
// with that item as result).
// Removing a specific recipe is done by calling the .destroy method
// for that recipe, and removing by result is done by using the
// RemoveRecipeByResult function, eg. like this:
//
// call RemoveRecipeByResult('belv')
//
// ---- Disassembling Items
// Disassembling an item that is a result of some recipe would cause
// the item to be replaced with the ingredients of the recipe.
// Example of usage:
//
// call DisassembleItem(GetManipulatedItem(), GetTriggerUnit())
//
// The first argument is the item to be disassembled and the second
// one is the unit to give the ingredients to. In case you don't want
// to give the items to an unit, give null as the unit argument.
// You also have the DisassembleItemByRecipe function, which takes
// one argument more: the recipe whose ingredients you want the item
// to be disassembled to.
//
// There are a few restrictions with the disassembling:
// - If the item being disassemled isn't created by the system,
// and used on an item that is the result of several recipes
// the system will just give the items that are required for one
// of the recipes.
// - When used on an recipe added via the charged recipe thingy
// the ingredient items won't recieve the amount of items they
// had when the result was made, but the default amount of charges.
//
// Note: If you are using the function with the 'A unit Loses an item'
// event you'll need to add a little wait before the function
// call in case you want the items to be created at the position
// where the item was dropped. And the wait is also needed when
// the item being disassembled is the result of a recipe that has
// only the same type of items as ingredients (or at least I think so).
//
// ---- Disabling and Re-Enabling Recipes
// Instead of removing a recipe to disable it and then adding the
// recipe again you can also disable and enable the recipe.
// This is done by setting the enabled member of the recipe to false
// (or to true if enabling). You can also use the EnableRecipeByResult
// function:
//
// call EnableRecipeByResult('fgdg', false)
//
// That would disable the recipes that have the item 'fgdg' as result.
// The enabling of the recipe would happen with the same function, but
// with true as the boolean argument.
//
// ---- Disabling/Re-enabling the System
// If you need to disable/enable the system for some time, you can use these lines:
//
// call DisableTrigger(RecipeSYS_TRIGGER)
// call EnableTrigger(RecipeSYS_TRIGGER)
//
// Note, that this only disables the combining of items by the system itself,
// if you're using a combining trigger of your own, you'll need to disable that
// trigger.
//
// ---- Manual Checking For Recipes
// In case you'd want to use some other event than the 'A unit Acquires an
// item', you can set AUTO_COMBINE to false, and create a trigger that has
// the event you want (eg. 'A unit Starts the effect of an ability'), and
// then call the CheckForRecipes function from there. The arguments it takes
// are the item that should be checked if it belongs to a recipe and the unit
// the result should be created to (if any is created).
// The function returns a boolean depending on whether it combined the item
// to something or not. And if it combined something, you can refer to the
// created item with bj_lastCreatedItem (Last created item in GUI).
//
// Strengths of RecipeSYS
// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
// - Supports having several items of the same type as
// ingredients in the same recipe.
// - Supports having the same item type as an ingredient in
// several recipes.
// - Allows to specify the special effect and it's attachment
// point (each recipe can have its own ones, if you wish so).
// - All you need to do is add the recipes.
// - You can remove recipes.
// - You can add recipes with results that have charges.
// - The amount of charges can be predefined, the sum of charges
// left in the ingredients, or the amount of charges in the
// ingredient with most charges.
// - You can disable and enable single recipes or the whole sytem.
// - You can disassemble items.
// - You can disable the automatic combining of items, and create
// a trigger that combines items manually (so you can have any
// event you want).
//
// Weaknesses of RecipeSYS
// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
// - Don't know if it's optimized as much as it could nor if it's
// the best recipe system out there. ^_^
// - The item disassembling has some restrictions, and doesn't work
// flawlessy with the 'A unit Loses an item' event (see the Test2
// trigger in the demo map or the instructions of the function for
// additional information).
// - The max amount of item types you can use in recipes as
// ingredients is 8190 / AMOUNT_ING and as results 8190 / AMOUNT_RES.
//
// How to import RecipeSYS
// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
// Two easy steps:
// - Copy this trigger to your map.
// - Copy the trigger 'Table' to your map.
// Alternatively:
// - Create a trigger named 'RecipeSYS' in your map.
// - Convert it to Jass (Custom Script) and replace all
// of the code in there with the code in this trigger.
// - Create a trigger named 'Table' in your map.
// - Convert it to Jass (Custom Script) and replace all
// of the code in there with the code in the trigger 'Table'.
globals
// ¤ ¤
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// ) RecipeSYS configuration (
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// ¤ ¤
private constant boolean AUTO_COMBINE = true
//Whether you want the system to automatically combine
//the ingredients of a recipe to the result when a unit
//has all of them.
private constant string SFX_PATH = "Abilities\\Spells\\Items\\TomeOfRetraining\\TomeOfRetrainingCaster.mdl"
//The path of the default effect.
private constant string SFX_POINT = "origin"
//The default attachment point.
private constant integer AMOUNT_ING = 10
//The amount of recipes an item can be an ingredient in.
private constant integer AMOUNT_RES = 10
//The amount of recipes an item can be a result in.
// ¤ ¤
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// )DO NOT EDIT PAST THIS POINT(
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// )Well, you can if you really(
// ( want to, but only if you )
// )know what you're doing. And(
// ( it's not needed, anyways. )
// )*'*-._.-*'*-._.-*'*-._.-*'*(
// ¤ ¤
public constant trigger TRIGGER = CreateTrigger()
private Table ING_TABLE
private Table RES_TABLE
private HandleTable COMBINE_TABLE
endglobals
private type ingIn extends recipe array [AMOUNT_ING]
private type resIn extends recipe array [AMOUNT_RES]
struct recipe
integer array items [6]
integer result
integer chargeType
string sfx
string point
boolean resultHasCharges
boolean enabled
static method create takes integer i1, integer i2, integer i3, integer i4, integer i5, integer i6, integer result, string sfx, string attPoint, boolean charges, integer chargetype returns recipe
local recipe i = recipe.allocate()
local ingIn ing
local resIn res
local boolean array b
local integer j = 0
local integer k
local integer l = 0
set i.items[0] = i1
set i.items[1] = i2
set i.items[2] = i3
set i.items[3] = i4
set i.items[4] = i5
set i.items[5] = i6
set i.result = result
set i.enabled = true
set i.resultHasCharges = charges
set i.chargeType = chargetype
//To prevent linking the recipe to the item type twice.
set b[0] = true
set b[1] = i2 != i1
set b[2] = i3 != i2 and i3 != i1
set b[3] = i4 != i3 and i4 != i2 and i4 != i1
set b[4] = i5 != i4 and i5 != i3 and i5 != i2 and i5 != i1
set b[5] = i6 != i5 and i6 != i4 and i6 != i3 and i6 != i2 and i6 != i1
//Set the SFX things (default or specified).
if sfx == "" then
set i.sfx = SFX_PATH
else
set i.sfx = sfx
endif
if attPoint == "" then
set i.point = SFX_POINT
else
set i.point = attPoint
endif
//Linking the recipe to the item types.
loop
if i.items[j] != 0 and b[j] then
set k = ING_TABLE[i.items[j]]
if k != 0 then
//Item type is in another recipe aswell.
set ing = ingIn(k)
set k = 0
//Seek for an open slot.
loop
exitwhen ing[k] == 0
set k = k + 1
if k == ingIn.size then
debug call BJDebugMsg("|cffff0202RecipeSYS Error:|r AMOUNT_ING is too small!")
return 0
endif
endloop
else
//First appearance for the item type.
set ing = ingIn.create()
set k = 0
endif
set ing[k] = i
set ING_TABLE[i.items[j]] = integer(ing)
endif
set j = j + 1
exitwhen j == 6
endloop
set k = RES_TABLE[i.result]
if k != 0 then
//Item type is in some other recipe, too.
set res = resIn(k)
set k = 0
loop
exitwhen res[k] == 0
set k = k + 1
if k == resIn.size then
debug call BJDebugMsg("|cffff0202RecipeSYS Error:|r AMOUNT_RES too small!")
return 0
endif
endloop
else
//First time being in a recipe for the item type.
set res = resIn.create()
endif
set res[k] = i
set RES_TABLE[i.result] = integer(res)
return i
endmethod
private method ClearRecipeFromIngredient takes integer it returns nothing
local integer i = 0
local integer j
local ingIn ing = ingIn(ING_TABLE[it])
if it == 0 or integer(ing[0]) == 0 then
return
endif
//Finding the right array slot and setting it's value to 0.
loop
exitwhen i == ingIn.size
if ing[i] == this then
set j = i + 1
//Finding the last used array slot.
loop
exitwhen j == ingIn.size or ing[j] == 0
set j = j + 1
endloop
set j = j - 1
set ing[i] = ing[j]
set ing[j] = 0
exitwhen true
endif
set i = i + 1
endloop
//Free the array and flush if the slots are empty.
if integer(ing[0]) == 0 then
call ING_TABLE.flush(it)
call ing.destroy()
endif
endmethod
private method ClearRecipeFromResult takes integer it returns nothing
local integer i = 0
local integer j
local resIn res = resIn(RES_TABLE[it])
if it == 0 then
return
endif
//Finding the right array slot and setting it's value to 0.
loop
exitwhen i == resIn.size
if res[i] == this then
set j = i + 1
//Finding the last used array slot.
loop
exitwhen j == resIn.size or res[j] == 0
set j = j + 1
endloop
set j = j - 1
set res[i] = res[j]
set res[j] = 0
exitwhen true
endif
set i = i + 1
endloop
//Free the array slots and flush if it's empty.
if res[0] == 0 then
call RES_TABLE.flush(it)
call res.destroy()
endif
endmethod
method onDestroy takes nothing returns nothing
local integer i = 0
loop
call .ClearRecipeFromIngredient(.items[i])
set i = i + 1
exitwhen i == 6
endloop
call .ClearRecipeFromResult(.result)
set .result = 0
endmethod
endstruct
//****************************************************
//** Recipes Without Charges **
//****************************************************
function AddRecipe takes integer item1, integer item2, integer item3, integer item4, integer item5, integer item6, integer result returns recipe
return recipe.create(item1, item2, item3, item4, item5, item6, result, "", "", false, 0)
endfunction
function AddRecipeEx takes integer item1, integer item2, integer item3, integer item4, integer item5, integer item6, integer result, string sfx, string attachmentPoint returns recipe
return recipe.create(item1, item2, item3, item4, item5, item6, result, sfx, attachmentPoint, false, 0)
endfunction
//****************************************************
//** Recipes With Charges **
//****************************************************
function AddRecipeWithCharges takes integer item1, integer item2, integer item3, integer item4, integer item5, integer item6, integer result, integer chargeType returns recipe
return recipe.create(item1, item2, item3, item4, item5, item6, result, "", "", true, chargeType)
endfunction
function AddRecipeWithChargesEx takes integer item1, integer item2, integer item3, integer item4, integer item5, integer item6, integer result, integer chargeType, string sfx, string attachmentPoint returns recipe
return recipe.create(item1, item2, item3, item4, item5, item6, result, sfx, attachmentPoint, true, chargeType)
endfunction
//****************************************************
//** Removing Recipes **
//****************************************************
function RemoveRecipeByResult takes integer result returns nothing
local resIn res = resIn(RES_TABLE[result])
loop
exitwhen integer(res[0]) == 0
call res[0].destroy()
endloop
endfunction
//****************************************************
//** Disabling and enabling recipes **
//****************************************************
function EnableRecipeByResult takes integer result, boolean enable returns nothing
local resIn res = resIn(RES_TABLE[result])
local integer i = 0
loop
exitwhen integer(res[i]) == 0
set res[i].enabled = enable
set i = i + 1
endloop
endfunction
//****************************************************
//** Disassembling Combined Items **
//****************************************************
function DisassembleItemByRecipe takes item whichItem, unit whichUnit, recipe re returns nothing
local integer i = 0
local real x = GetItemX(whichItem)
local real y = GetItemY(whichItem)
local boolean b = IsTriggerEnabled(GetTriggeringTrigger())
local boolean c = IsTriggerEnabled(TRIGGER)
if re.result == GetItemTypeId(whichItem) then
if b then
//Avoid clashing with some events.
call DisableTrigger(GetTriggeringTrigger())
endif
call COMBINE_TABLE.flush(whichItem)
call RemoveItem(whichItem)
//Should the items be created for a unit or at ground?
if whichUnit == null then
loop
call CreateItem(re.items[i], x, y)
set i = i + 1
exitwhen i == 6
endloop
else
if c then
//Preventing infinite loop.
call DisableTrigger(TRIGGER)
endif
loop
call UnitAddItemById(whichUnit, re.items[i])
set i = i + 1
exitwhen i == 6
endloop
if c then
call EnableTrigger(TRIGGER)
endif
endif
if b then
call EnableTrigger(GetTriggeringTrigger())
endif
endif
endfunction
function DisassembleItem takes item whichItem, unit whichUnit returns nothing
local integer id = GetItemTypeId(whichItem)
local resIn r = resIn(RES_TABLE[id])
local recipe re = recipe(COMBINE_TABLE[whichItem])
if integer(re) == 0 or re.result != id then //The last one just in case the recipe has been destroyed.
if integer(r[0]) == 0 then
return
endif
set re = r[0]
endif
call DisassembleItemByRecipe(whichItem, whichUnit, re)
endfunction
//****************************************************
//** Combining **
//****************************************************
private function Combine takes recipe rec, unit u returns boolean
local integer array itemsReq
local integer itemInSlot
local integer topCharges = 0
local integer sumCharges = 0
local integer i = 0
local integer j = 0
local item resu
local item array itemsToCombine
//Setting the items.
loop
set itemsReq[i] = rec.items[i]
set i = i + 1
exitwhen i == 6
endloop
set i = 0
//Finding the items.
loop
set itemInSlot = GetItemTypeId(UnitItemInSlot(u, i))
loop
if itemsReq[j] == itemInSlot and itemInSlot != 0 then
set itemsToCombine[j] = UnitItemInSlot(u, i)
set itemsReq[j] = 0
exitwhen true
endif
set j = j + 1
exitwhen j == 6
endloop
set j = 0
set i = i + 1
exitwhen i == 6
endloop
set i = 0
set j = 0
//Checking if all items were found.
loop
if itemsReq[i] != 0 then
loop
set itemsToCombine[j] = null
set j = j + 1
exitwhen j == 6
endloop
return false
endif
set i = i + 1
exitwhen i == 6
endloop
set i = 0
//Remove the old items.
loop
//Set the different charge amounts in case the result has charges.
set j = GetItemCharges(itemsToCombine[i])
set sumCharges = sumCharges + j
if j > topCharges then
set topCharges = j
endif
call COMBINE_TABLE.flush(itemsToCombine[i])
call RemoveItem(itemsToCombine[i])
set itemsToCombine[i] = null
set i = i + 1
exitwhen i == 6
endloop
//Create the result.
set resu = UnitAddItemById(u, rec.result)
call DestroyEffect(AddSpecialEffectTarget(rec.sfx, u, rec.point))
//Set charges if it should have any.
if rec.resultHasCharges then
if rec.chargeType == 0 then
call SetItemCharges(resu, sumCharges)
elseif rec.chargeType == -1 then
call SetItemCharges(resu, topCharges)
else
call SetItemCharges(resu, rec.chargeType)
endif
endif
//Set the data if wanted.
set COMBINE_TABLE[resu] = integer(rec)
set bj_lastCreatedItem = resu
set resu = null
return true
endfunction
//****************************************************
//** Recipe Finding **
//****************************************************
function CheckForRecipes takes item check, unit u returns boolean
local ingIn r = ingIn(ING_TABLE[GetItemTypeId(check)])
local integer i = 0
loop
exitwhen integer(r[i]) == 0
if r[i].enabled then
if Combine(r[i], u) then
return true
endif
endif
set i = i + 1
endloop
return false
endfunction
private function Check takes nothing returns boolean
return CheckForRecipes(GetManipulatedItem(), GetTriggerUnit())
endfunction
//=====================================================================
private function SafeFilt takes nothing returns boolean
return true
endfunction
//=====================================================================
private function Init takes nothing returns nothing
local integer index = 0
if AUTO_COMBINE then
loop
call TriggerRegisterPlayerUnitEvent(TRIGGER, Player(index), EVENT_PLAYER_UNIT_PICKUP_ITEM, Filter(function SafeFilt))
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(TRIGGER, Condition(function Check))
endif
set ING_TABLE = Table.create()
set RES_TABLE = Table.create()
set COMBINE_TABLE = HandleTable.create()
endfunction
endlibrary
//TESH.scrollpos=0
//TESH.alwaysfold=0
library RecipeSYS initializer init uses Table
// ¤ v0.7b ¤
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// ) RecipeSYS (
// ( Created by Artificial )
// )*'*-._.-*'*-._.-*'*-._.-*'*(
// ¤ ¤
//
// How to use the RecipeSYS
// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
// ---- Adding recipes
// Adding recipes is rather easy. You just call a function
// and give it some arguments. The function you call is
// recipe.create, and is called like this:
//
// call recipe.create(i1, i2, i3, i4, i5, i6, result, sfx, attPoint, charges, chargeType)
//
// i1 - i6 are the raw codes* of the items required for the
// recipe to combine. result is the raw code of the item they
// will combine to. sfx is the path of the special effect you
// want to use (give "" for default), and attPoint the attachment
// point of it ("" for default). The boolean charges is whether
// the result should have some other amount of charges than the
// default one. If it is true, chargeType determines what amount
// of charges the result will get when combined (-1 => amount of
// charges left in the ingredient with most charges, 0 => sum of
// charges left in the ingredients, anything else => the number
// given as the argument).
//
// * You can find out the rawcodes by going to the object
// editor and pressing ctrl + D. The first 4 characters
// are the rawcode of the item. When calling the function,
// remember to put the rawcode between ' and ' in case
// you want it to work.
//
// If you want the recipe to require less than 6 items, just give
// zeros as ingredient arguments.
//
// --- AddRecipe Wrappers
// You can also add recipes using some of the wrapper
// functions: AddRecipe, AddRecipeEx, AddRecipeWithCharges,
// and AddRecipeWithChargesEx.
//
// AddRecipe takes i1, i2, i3, i4, i5, i6, result
// AddRecipeEx takes i1, i2, i3, i4, i5, i6, result, sfx, attPoint
// AddRecipeWithCharges takes i1, i2, i3, i4, i5, i6, result, chargeType
// AddRecipeWithChargesEx takes i1, i2, i3, i4, i5, i6, result, chargeType, sfx, attPoint
//
// ---- Removing Recipes
// There are two ways of removing recipes: destroyin a specific
// recipe and removing recipes by the result (removes all recipes
// with that item as result).
// Removing a specific recipe is done by calling the .destroy method
// for that recipe, and removing by result is done by using the
// RemoveRecipeByResult function, eg. like this:
//
// call RemoveRecipeByResult('belv')
//
// ---- Changing the Result / Ingredients
// Because of how the system works, you can't just do set r.result = 'aooo',
// but you must use the methods SetResult and SetIngredient.
// SetResult takes only the new item's raw code, and SetIngredient takes that
// and the ingredient number (0 - 5).
//
// call re.SetIngredient('rde1', 0)
//
// ---- Disassembling Items
// Disassembling an item that is a result of some recipe would cause
// the item to be replaced with the ingredients of the recipe.
// Example of usage:
//
// call DisassembleItem(GetManipulatedItem(), GetTriggerUnit())
//
// The first argument is the item to be disassembled and the second
// one is the unit to give the ingredients to. In case you don't want
// to give the items to an unit, give null as the unit argument.
// You also have the DisassembleItemByRecipe function, which takes
// one argument more: the recipe whose ingredients you want the item
// to be disassembled to.
//
// There are a few restrictions with the disassembling:
// - If the item being disassemled isn't created by the system,
// and used on an item that is the result of several recipes
// the system will just give the items that are required for one
// of the recipes.
// - When used on an recipe added via the charged recipe thingy
// the ingredient items won't recieve the amount of items they
// had when the result was made, but the default amount of charges.
//
// Note: If you are using the function with the 'A unit Loses an item'
// event you'll need to add a little wait before the function
// call in case you want the items to be created at the position
// where the item was dropped. And the wait is also needed when
// the item being disassembled is the result of a recipe that has
// only the same type of items as ingredients (or at least I think so).
//
// ---- Disabling and Re-Enabling Recipes
// Instead of removing a recipe to disable it and then adding the
// recipe again you can also disable and enable the recipe.
// This is done by setting the enabled member of the recipe to false
// (or to true if enabling). You can also use the EnableRecipeByResult
// function:
//
// call EnableRecipeByResult('fgdg', false)
//
// That would disable the recipes that have the item 'fgdg' as result.
// The enabling of the recipe would happen with the same function, but
// with true as the boolean argument.
//
// ---- Disabling/Re-enabling the System
// If you need to disable/enable the system for some time, you can use these lines:
//
// call DisableTrigger(RecipeSYS_TRIGGER)
// call EnableTrigger(RecipeSYS_TRIGGER)
//
// Note, that this only disables the combining of items by the system itself,
// if you're using a combining trigger of your own, you'll need to disable that
// trigger.
//
// ---- Manual Checking For Recipes
// In case you'd want to use some other event than the 'A unit Acquires an
// item', you can set AUTO_COMBINE to false, and create a trigger that has
// the event you want (eg. 'A unit Starts the effect of an ability'), and
// then call the RecipeSYS_Combine function from there. The arguments it takes
// are the item that should be checked if it belongs to a recipe and the unit
// the result should be created to (if any is created).
// The function returns a boolean depending on whether it combined the item
// to something or not. And if it combined something, you can refer to the
// created item with bj_lastCreatedItem (Last created item in GUI).
//
// Strengths of RecipeSYS
// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
// - Supports having several items of the same type as
// ingredients in the same recipe.
// - Supports having the same item type as an ingredient in
// several recipes.
// - Allows to specify the special effect and it's attachment
// point (each recipe can have its own ones, if you wish so).
// - All you need to do is add the recipes.
// - You can remove recipes.
// - You can add recipes with results that have charges.
// - The amount of charges can be predefined, the sum of charges
// left in the ingredients, or the amount of charges in the
// ingredient with most charges.
// - You can disable and enable single recipes or the whole sytem.
// - You can disassemble items.
// - You can disable the automatic combining of items, and create
// a trigger that combines items manually (so you can have any
// event you want).
//
// Weaknesses of RecipeSYS
// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
// - Don't know if it's optimized as much as it could nor if it's
// the best recipe system out there. ^_^
// - The item disassembling has some restrictions, and doesn't work
// flawlessy with the 'A unit Loses an item' event (see the Test2
// trigger in the demo map or the instructions of the function for
// additional information).
// - The max amount of item types you can use in recipes as
// ingredients is 8190 / AMOUNT_ING and as results 8190 / AMOUNT_RES.
//
// How to import RecipeSYS
// ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨
// Two easy steps:
// - Copy this trigger to your map.
// - Copy the trigger 'Table' to your map.
// Alternatively:
// - Create a trigger named 'RecipeSYS' in your map.
// - Convert it to Jass (Custom Script) and replace all
// of the code in there with the code in this trigger.
// - Create a trigger named 'Table' in your map.
// - Convert it to Jass (Custom Script) and replace all
// of the code in there with the code in the trigger 'Table'.
globals
// ¤ ¤
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// ) RecipeSYS configuration (
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// ¤ ¤
private constant boolean AUTO_COMBINE = true
//Whether you want the system to automatically combine
//the ingredients of a recipe to the result when a unit
//has all of them.
private constant boolean NEED_PICK_UP = true
// Whether the item actually has to be picked up by the
// unit in order for the recipe to combine, or if it's
// enough for the unit to be ordered to pick the item
// (this as false will make you able to "pick" the last
// ingredient needed for the recipe and combine the recipe
// even if the inventory is full (still plays the sound "Inventory
// is full" and displayes the message, but they can be hidden in
// game interface)).
private constant real MAX_RANGE = 200.
// How far away from the item can the unit be in order to
// be able to "pick it up" when NEED_PICK_UP is false.
private constant string SFX_PATH = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
//The path of the default effect.
private constant string SFX_POINT = "origin"
//The default attachment point.
private constant integer AMOUNT_ING = 50
//The amount of recipes an item can be an ingredient in.
private constant integer AMOUNT_RES = 50
//The amount of recipes an item can be a result in.
// ¤ ¤
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// )DO NOT EDIT PAST THIS POINT(
// ( *'*-._.-*'*-._.-*'*-._.-*'* )
// )Well, you can if you really(
// ( want to, but only if you )
// )know what you're doing. And(
// ( it's not needed, anyways. )
// )*'*-._.-*'*-._.-*'*-._.-*'*(
// ¤ ¤
private constant real MAX_RANGE_POW2 = MAX_RANGE * MAX_RANGE
public constant trigger TRIGGER = CreateTrigger()
private Table ING_TABLE
private Table RES_TABLE
private HandleTable COMBINE_TABLE
endglobals
private type ingIn extends recipe array [AMOUNT_ING]
private type resIn extends recipe array [AMOUNT_RES]
struct recipe
readonly integer array items [6]
readonly integer result
integer chargeType
string sfx
string point
boolean resultHasCharges
boolean enabled
static method create takes integer i1, integer i2, integer i3, integer i4, integer i5, integer i6, integer result, string sfx, string attPoint, boolean charges, integer chargetype returns recipe
local recipe i = recipe.allocate()
local ingIn ing
local resIn res
local boolean error = false // Stupid 1.24
local boolean array b
local integer j = 0
local integer k
local integer l = 0
set i.items[0] = i1
set i.items[1] = i2
set i.items[2] = i3
set i.items[3] = i4
set i.items[4] = i5
set i.items[5] = i6
set i.result = result
set i.enabled = true
set i.resultHasCharges = charges
set i.chargeType = chargetype
//To prevent linking the recipe to the item type twice.
set b[0] = true
set b[1] = i2 != i1
set b[2] = i3 != i2 and i3 != i1
set b[3] = i4 != i3 and i4 != i2 and i4 != i1
set b[4] = i5 != i4 and i5 != i3 and i5 != i2 and i5 != i1
set b[5] = i6 != i5 and i6 != i4 and i6 != i3 and i6 != i2 and i6 != i1
//Set the SFX things (default or specified).
if sfx == "" then
set i.sfx = SFX_PATH
else
set i.sfx = sfx
endif
if attPoint == "" then
set i.point = SFX_POINT
else
set i.point = attPoint
endif
//Linking the recipe to the item types.
loop
if i.items[j] != 0 and b[j] then
set k = ING_TABLE[i.items[j]]
if k != 0 then
//Item type is in another recipe aswell.
set ing = ingIn(k)
set k = 0
//Seek for an open slot.
loop
exitwhen error or ing[k] == 0
set k = k + 1
if k == ingIn.size then
debug call BJDebugMsg("|cffff0202RecipeSYS Error:|r AMOUNT_ING is too small!")
set error = true
endif
endloop
else
//First appearance for the item type.
set ing = ingIn.create()
set k = 0
endif
exitwhen error
set ing[k] = i
set ING_TABLE[i.items[j]] = integer(ing)
endif
set j = j + 1
exitwhen j == 6
endloop
if not error then
set k = RES_TABLE[i.result]
if k != 0 then
//Item type is in some other recipe, too.
set res = resIn(k)
set k = 0
loop
exitwhen error or res[k] == 0
set k = k + 1
if k == resIn.size then
debug call BJDebugMsg("|cffff0202RecipeSYS Error:|r AMOUNT_RES too small!")
set error = true
endif
endloop
else
//First time being in a recipe for the item type.
set res = resIn.create()
endif
if not error then
set res[k] = i
set RES_TABLE[i.result] = integer(res)
endif
endif
if error then
call i.destroy()
return recipe(0)
else
return i
endif
endmethod
private method ClearRecipeFromIngredient takes integer it returns nothing
local integer i = 0
local integer j = 0
local integer k
local ingIn ing = ingIn(ING_TABLE[it])
if it == 0 or integer(ing[0]) == 0 then
return
endif
//Finding the right array slot and setting it's value to 0.
loop
exitwhen i == ingIn.size
if ing[i] == this then
set j = i + 1
//Finding the last used array slot.
loop
exitwhen j == ingIn.size or ing[j] == 0
set j = j + 1
endloop
set j = j - 1
set ing[i] = ing[j]
set ing[j] = 0
exitwhen true
endif
set i = i + 1
endloop
//Free the array and flush if the slots are empty.
if integer(ing[0]) == 0 then
call ING_TABLE.flush(it)
call ing.destroy()
endif
endmethod
private method ClearRecipeFromResult takes integer it returns nothing
local integer i = 0
local integer j
local resIn res = resIn(RES_TABLE[it])
if it == 0 then
return
endif
//Finding the right array slot and setting it's value to 0.
loop
exitwhen i == resIn.size
if res[i] == this then
set j = i + 1
//Finding the last used array slot.
loop
exitwhen j == resIn.size or res[j] == 0
set j = j + 1
endloop
set j = j - 1
set res[i] = res[j]
set res[j] = 0
exitwhen true
endif
set i = i + 1
endloop
//Free the array slots and flush if it's empty.
if res[0] == 0 then
call RES_TABLE.flush(it)
call res.destroy()
endif
endmethod
// Used in SetIngredient to clear the old slot.
private method ClearSlot takes integer slot returns nothing
local integer i = 0
loop
exitwhen i == 6
if slot != i and .items[i] == .items[slot] then
// If the item is several times in the recipe,
// setting this one to 0 is enough.
set .items[slot] = 0
return
endif
set i = i + 1
endloop
// Otherwise we need to clear the recipe from the item.
call .ClearRecipeFromIngredient(.items[slot])
endmethod
method SetIngredient takes integer id, integer slot returns nothing
local ingIn ing
call .ClearSlot(slot)
set .items[slot] = id
set slot = ING_TABLE[id]
if slot != 0 then
//Item type is in another recipe aswell.
set ing = ingIn(slot)
set slot = 0
//Seek for an open slot.
loop
exitwhen ing[slot] == 0
set slot = slot + 1
if slot == ingIn.size then
debug call BJDebugMsg("|cffff0202RecipeSYS Error:|r AMOUNT_ING is too small!")
return
endif
endloop
else
//First appearance for the item type.
set ing = ingIn.create()
set slot = 0
endif
set ing[slot] = this
set ING_TABLE[id] = integer(ing)
endmethod
method SetResult takes integer id returns nothing
local resIn res
local integer k = RES_TABLE[id]
call .ClearRecipeFromResult(.result)
set .result = id
if k != 0 then
//Item type is in some other recipe, too.
set res = resIn(k)
set k = 0
loop
exitwhen res[k] == 0
set k = k + 1
if k == resIn.size then
debug call BJDebugMsg("|cffff0202RecipeSYS Error:|r AMOUNT_RES too small!")
return
endif
endloop
else
//First time being in a recipe for the item type.
set res = resIn.create()
endif
set res[k] = this
set RES_TABLE[.result] = integer(res)
endmethod
method onDestroy takes nothing returns nothing
local integer i = 0
loop
call .ClearRecipeFromIngredient(.items[i])
set i = i + 1
exitwhen i == 6
endloop
call .ClearRecipeFromResult(.result)
set .result = 0
endmethod
endstruct
//****************************************************
//** Recipes Without Charges **
//****************************************************
function AddRecipe takes integer item1, integer item2, integer item3, integer item4, integer item5, integer item6, integer result returns recipe
return recipe.create(item1, item2, item3, item4, item5, item6, result, "", "", false, 0)
endfunction
function AddRecipeEx takes integer item1, integer item2, integer item3, integer item4, integer item5, integer item6, integer result, string sfx, string attachmentPoint returns recipe
return recipe.create(item1, item2, item3, item4, item5, item6, result, sfx, attachmentPoint, false, 0)
endfunction
//****************************************************
//** Recipes With Charges **
//****************************************************
function AddRecipeWithCharges takes integer item1, integer item2, integer item3, integer item4, integer item5, integer item6, integer result, integer chargeType returns recipe
return recipe.create(item1, item2, item3, item4, item5, item6, result, "", "", true, chargeType)
endfunction
function AddRecipeWithChargesEx takes integer item1, integer item2, integer item3, integer item4, integer item5, integer item6, integer result, integer chargeType, string sfx, string attachmentPoint returns recipe
return recipe.create(item1, item2, item3, item4, item5, item6, result, sfx, attachmentPoint, true, chargeType)
endfunction
//****************************************************
//** Removing Recipes **
//****************************************************
function RemoveRecipeByResult takes integer result returns nothing
local resIn res = resIn(RES_TABLE[result])
loop
exitwhen integer(res[0]) == 0
call res[0].destroy()
endloop
endfunction
//****************************************************
//** Disabling and enabling recipes **
//****************************************************
function EnableRecipeByResult takes integer result, boolean enable returns nothing
local resIn res = resIn(RES_TABLE[result])
local integer i = 0
loop
exitwhen integer(res[i]) == 0
set res[i].enabled = enable
set i = i + 1
endloop
endfunction
//****************************************************
//** Disassembling Combined Items **
//****************************************************
function DisassembleItemByRecipe takes item whichItem, unit whichUnit, recipe re returns nothing
local integer i = 0
local real x = GetItemX(whichItem)
local real y = GetItemY(whichItem)
local boolean b = IsTriggerEnabled(GetTriggeringTrigger())
local boolean c = IsTriggerEnabled(TRIGGER)
if re.result == GetItemTypeId(whichItem) then
if b then
//Avoid clashing with some events.
call DisableTrigger(GetTriggeringTrigger())
endif
call COMBINE_TABLE.flush(whichItem)
call RemoveItem(whichItem)
//Should the items be created for a unit or at ground?
if whichUnit == null then
loop
call CreateItem(re.items[i], x, y)
set i = i + 1
exitwhen i == 6
endloop
else
if c then
//Preventing infinite loop.
call DisableTrigger(TRIGGER)
endif
loop
call UnitAddItemById(whichUnit, re.items[i])
set i = i + 1
exitwhen i == 6
endloop
if c then
call EnableTrigger(TRIGGER)
endif
endif
if b then
call EnableTrigger(GetTriggeringTrigger())
endif
endif
endfunction
function DisassembleItem takes item whichItem, unit whichUnit returns nothing
local integer id = GetItemTypeId(whichItem)
local resIn r = resIn(RES_TABLE[id])
local recipe re = recipe(COMBINE_TABLE[whichItem])
if integer(re) == 0 or re.result != id then //The last one just in case the recipe has been destroyed.
if integer(r[0]) == 0 then
return
endif
set re = r[0]
endif
call DisassembleItemByRecipe(whichItem, whichUnit, re)
endfunction
//****************************************************
//** Combining **
//****************************************************
private function DoCombine takes recipe rec, unit u, item noncarried returns boolean
local integer array itemsReq
local integer noncarriedId = GetItemTypeId(noncarried)
local integer itemInSlot
local integer topCharges = 0
local integer sumCharges = 0
local integer i = 0
local integer j = 0
local item resu
local item array itemsToCombine
//Setting the items.
loop
set itemsReq[i] = rec.items[i]
set i = i + 1
exitwhen i == 6
endloop
set i = 0
//Finding the items.
loop
set itemInSlot = GetItemTypeId(UnitItemInSlot(u, i))
loop
if itemsReq[j] == noncarriedId and noncarried != null then
set itemsToCombine[j] = noncarried
set itemsReq[j] = 0
set noncarried = null
exitwhen true
elseif itemsReq[j] == itemInSlot and itemInSlot != 0 then
set itemsToCombine[j] = UnitItemInSlot(u, i)
set itemsReq[j] = 0
exitwhen true
endif
set j = j + 1
exitwhen j == 6
endloop
set j = 0
set i = i + 1
exitwhen i == 6
endloop
set noncarried = null
set i = 0
set j = 0
//Checking if all items were found.
loop
if itemsReq[i] != 0 then
loop
set itemsToCombine[j] = null
set j = j + 1
exitwhen j == 6
endloop
return false
endif
set i = i + 1
exitwhen i == 6
endloop
set i = 0
//Remove the old items.
loop
//Set the different charge amounts in case the result has charges.
set j = GetItemCharges(itemsToCombine[i])
set sumCharges = sumCharges + j
if j > topCharges then
set topCharges = j
endif
call COMBINE_TABLE.flush(itemsToCombine[i])
call RemoveItem(itemsToCombine[i])
set itemsToCombine[i] = null
set i = i + 1
exitwhen i == 6
endloop
//Create the result.
set resu = UnitAddItemById(u, rec.result)
call DestroyEffect(AddSpecialEffectTarget(rec.sfx, u, rec.point))
//Set charges if it should have any.
if rec.resultHasCharges then
if rec.chargeType == 0 then
call SetItemCharges(resu, sumCharges)
elseif rec.chargeType == -1 then
call SetItemCharges(resu, topCharges)
else
call SetItemCharges(resu, rec.chargeType)
endif
endif
//Set the data if wanted.
set COMBINE_TABLE[resu] = integer(rec)
set bj_lastCreatedItem = resu
set resu = null
return true
endfunction
//****************************************************
//** Recipe Finding **
//****************************************************
function GetRecipeItemCombinedFrom takes item i returns recipe
local recipe r = recipe(COMBINE_TABLE[i])
if integer(r) == 0 or GetItemTypeId(i) != r.result then
set r = ingIn(ING_TABLE[GetItemTypeId(i)])[0]
endif
return r
endfunction
public function Combine takes item check, unit u returns boolean
local boolean isCarried = UnitHasItem(u, check)
local ingIn r = ingIn(ING_TABLE[GetItemTypeId(check)])
local integer i = 0
if check == null then
return false
endif
loop
exitwhen integer(r[i]) == 0 or i == r.size
if r[i].enabled then
if isCarried then
if DoCombine(r[i], u, null) then
return true
endif
else
if DoCombine(r[i], u, check) then
return true
endif
endif
endif
set i = i + 1
endloop
return false
endfunction
private function Check takes nothing returns boolean
local real dx
local real dy
if GetIssuedOrderId() == OrderId("smart") then
if GetOrderTargetItem() == null then
return false
endif
set dx = GetItemX(GetOrderTargetItem()) - GetUnitX(GetTriggerUnit())
set dy = GetItemY(GetOrderTargetItem()) - GetUnitY(GetTriggerUnit())
if dx * dx + dy * dy <= MAX_RANGE_POW2 then
return Combine(GetOrderTargetItem(), GetTriggerUnit())
endif
return false
endif
return Combine(GetManipulatedItem(), GetTriggerUnit())
endfunction
//=====================================================================
private function SafeFilt takes nothing returns boolean
return true
endfunction
//=====================================================================
private function init takes nothing returns nothing
local integer index = 0
if AUTO_COMBINE then
loop
call TriggerRegisterPlayerUnitEvent(TRIGGER, Player(index), EVENT_PLAYER_UNIT_PICKUP_ITEM, Filter(function SafeFilt))
if not NEED_PICK_UP then
call TriggerRegisterPlayerUnitEvent(TRIGGER, Player(index), EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER, Filter(function SafeFilt))
endif
set index = index + 1
exitwhen index == bj_MAX_PLAYER_SLOTS
endloop
call TriggerAddCondition(TRIGGER, Condition(function Check))
endif
set ING_TABLE = Table.create()
set RES_TABLE = Table.create()
set COMBINE_TABLE = HandleTable.create()
endfunction
endlibrary
//TESH.scrollpos=57
//TESH.alwaysfold=0
library Table
//***************************************************************
//* Table object 3.0
//* ------------
//*
//* set t=Table.create() - instanceates a new table object
//* call t.destroy() - destroys it
//* t[1234567] - Get value for key 1234567
//* (zero if not assigned previously)
//* set t[12341]=32 - Assigning it.
//* call t.flush(12341) - Flushes the stored value, so it
//* doesn't use any more memory
//* t.exists(32) - Was key 32 assigned? Notice
//* that flush() unassigns values.
//* call t.reset() - Flushes the whole contents of the
//* Table.
//*
//* call t.destroy() - Does reset() and also recycles the id.
//*
//* If you use HandleTable instead of Table, it is the same
//* but it uses handles as keys, the same with StringTable.
//*
//* You can use Table on structs' onInit if the struct is
//* placed in a library that requires Table or outside a library.
//*
//* You can also do 2D array syntax if you want to touch
//* mission keys directly, however, since this is shared space
//* you may want to prefix your mission keys accordingly:
//*
//* set Table["thisstring"][ 7 ] = 2
//* set Table["thisstring"][ 5 ] = Table["thisstring"][7]
//*
//***************************************************************
//=============================================================
globals
private constant integer MAX_INSTANCES=8100 //400000
//Feel free to change max instances if necessary, it will only affect allocation
//speed which shouldn't matter that much.
//=========================================================
private hashtable ht
endglobals
private struct GTable[MAX_INSTANCES]
method reset takes nothing returns nothing
call FlushChildHashtable(ht, integer(this) )
endmethod
private method onDestroy takes nothing returns nothing
call this.reset()
endmethod
//=============================================================
// initialize it all.
//
private static method onInit takes nothing returns nothing
set ht = InitHashtable()
endmethod
endstruct
//Hey: Don't instanciate other people's textmacros that you are not supposed to, thanks.
//! textmacro Table__make takes name, type, key
struct $name$ extends GTable
method operator [] takes $type$ key returns integer
return LoadInteger(ht, integer(this), $key$)
endmethod
method operator []= takes $type$ key, integer value returns nothing
call SaveInteger(ht, integer(this) ,$key$, value)
endmethod
method flush takes $type$ key returns nothing
call RemoveSavedInteger(ht, integer(this), $key$)
endmethod
method exists takes $type$ key returns boolean
return HaveSavedInteger( ht, integer(this) ,$key$)
endmethod
static method flush2D takes string firstkey returns nothing
call $name$(- StringHash(firstkey)).reset()
endmethod
static method operator [] takes string firstkey returns $name$
return $name$(- StringHash(firstkey) )
endmethod
endstruct
//! endtextmacro
//! runtextmacro Table__make("Table","integer","key" )
//! runtextmacro Table__make("StringTable","string", "StringHash(key)" )
//! runtextmacro Table__make("HandleTable","handle","GetHandleId(key)" )
endlibrary