User:ArthurAutomaton/sandbox: Difference between revisions
Jump to navigation
Jump to search
Warning:The two triggers should not overlap physically!
mNo edit summary |
(added a section on a jail system for dota 2) |
||
| Line 40: | Line 40: | ||
| If true, <code>amount</code> will be added to the player's current gold; if false, the player's current gold will be set to <code>amount</code>. | | If true, <code>amount</code> will be added to the player's current gold; if false, the player's current gold will be set to <code>amount</code>. | ||
|} | |} | ||
== Jail System == | |||
=== Hammer Setup === | |||
In Hammer, create a trigger_hero with the name <i>radiant_prison</i>. Create another trigger_hero with the name <i>dire_prison</i>. | |||
{{warning|The two triggers should not overlap physically!}} | |||
Set the Entity Scripts property of both triggers to <code>jail_trigger.lua</code>. Finally, add an output on both triggers as follows: | |||
::{| class=standard-table | |||
! || My Output || Target Entity || Target Input || Parameter || Delay || Only Once | |||
|- | |||
| [[Image:Io11.png]] || OnStartTouch || trigger_name|| CallScriptFunction || ReleasePrisonersConditionally || 0.00 || No | |||
|} | |||
=== VScripts === | |||
<code>jail_trigger.lua</code>: | |||
function ReleasePrisonersConditionally(trigger) | |||
print("!!! ReleasePrisonersConditionally CALLED !!!") | |||
local jailSystem = GameRules.MyAddon.jailSystem | |||
local thisPrison = trigger.caller | |||
local vInmates = jailSystem:GetPrisoners(thisPrison) | |||
if #vInmates == 0 then | |||
print("no inmates found in " .. thisPrison:GetName()) | |||
return | |||
end | |||
local nTeamID = vInmates[1]:GetTeam() | |||
if (not jailSystem:IsImprisoned(trigger.activator, thisPrison) and | |||
trigger.activator:GetTeam() == nTeamID) then | |||
print("releasing prisoners") | |||
for _,npc in pairs(vInmates) do | |||
jailSystem:Release(npc, thisPrison) | |||
end | |||
end | |||
end | |||
<code>addon_game_mode.lua</code>: | |||
RAZOR = "npc_dota_hero_razor" | |||
RADIANT_PRISON = "radiant_prison" | |||
DIRE_PRISON = "dire_prison" | |||
if CMyGameMode == nil then | |||
CMyGameMode = class({}) | |||
end | |||
function Precache (context) | |||
PrecacheUnitByNameSync(RAZOR, context) -- XXX | |||
end | |||
-- Create the game mode when we activate | |||
function Activate () | |||
GameRules.MyAddon = CMyGameMode() | |||
GameRules.MyAddon:InitGameMode() | |||
end | |||
function CMyGameMode:InitGameMode () | |||
print( "Addon is loaded." ) | |||
GameRules:SetHeroRespawnEnabled(false) | |||
-- XXX: For testing; remember to remove this! | |||
self:PopulateWorldForTesting() | |||
-- Initialize the jail system | |||
self.jailSystem = CJailSystem({ | |||
[DOTA_TEAM_GOODGUYS] = Entities:FindByName(nil, DIRE_PRISON), | |||
[DOTA_TEAM_BADGUYS] = Entities:FindByName(nil, RADIANT_PRISON) | |||
}) | |||
self.jailSystem:Init() | |||
end | |||
function CMyGameMode:PopulateWorldForTesting () | |||
local razor = CreateUnitByName(RAZOR, Vector(0, 512, 0), true, | |||
nil, nil, DOTA_TEAM_BADGUYS) | |||
razor:SetControllableByPlayer(0, true) | |||
end | |||
---------- | |||
if CJailSystem == nil then | |||
CJailSystem = class({ team2prison = {}; | |||
prisoners = {}; | |||
constructor = function (self, tbl) | |||
self.team2prison = tbl or self.team2prison | |||
for _,v in pairs(self.team2prison) do | |||
v.JAIL_prisoners = {} -- XXX: Use DoUniqueString | |||
end | |||
end | |||
}) | |||
end | |||
function CJailSystem:Init () | |||
ListenToGameEvent("entity_killed", Dynamic_Wrap(CJailSystem, "OnEntityKilled" ), self) | |||
end | |||
function CJailSystem:GetPrisoners (prison) | |||
local vInmates = {} | |||
for k,_ in pairs(prison.JAIL_prisoners) do | |||
table.insert(vInmates, k) | |||
end | |||
return vInmates | |||
end | |||
function CJailSystem:IsImprisoned (npc, prison) | |||
return prison.JAIL_prisoners[npc] | |||
end | |||
function CJailSystem:OnEntityKilled (keys) | |||
local killedEntity = EntIndexToHScript(keys.entindex_killed) | |||
local prison = self.team2prison[killedEntity:GetTeam()] | |||
if killedEntity:UnitCanRespawn() and prison then | |||
self:Imprison(killedEntity, prison) | |||
end | |||
end | |||
function CJailSystem:Imprison (npc, prison) | |||
prison.JAIL_prisoners[npc] = true | |||
npc:RespawnUnit() | |||
FindClearSpaceForUnit(npc, prison:GetCenter(), false) | |||
-- XXX: If we apply modifiers now, nothing happens (API bug?); | |||
-- so we wait a bit and then apply them. | |||
GameRules:GetGameModeEntity():SetThink( | |||
function() | |||
npc:AddNewModifier(npc, nil, "modifier_stunned", nil) | |||
npc:AddNewModifier(npc, nil, "modifier_invulnerable", nil) | |||
end, nil, 0.5) | |||
end | |||
function CJailSystem:Release (npc, prison) | |||
prison.JAIL_prisoners[npc] = false | |||
npc:RemoveModifierByName("modifier_stunned") | |||
npc:RemoveModifierByName("modifier_invulnerable") | |||
-- Add teleport stuff here! | |||
end | |||
Revision as of 05:46, 14 August 2014
Sandbox
Some notes to myself about modding DotA 2.
Creating a unit that's controllable by a specific player
This code creates a mud golem at (0, 0, 0) on the Radiant team and makes it controllable by player 0:
unit_team = DOTA_TEAM_GOODGUYS unit_name = "npc_dota_neutral_mud_golem" player = PlayerResource:GetPlayer(0) point = Vector(0, 0, 0) unit = CreateUnitByName(unit_name, point, true, nil, nil, unit_team) unit:SetControllableByPlayer(player:GetPlayerID(), true)
Relevant links:
CDOTA_BaseNPC_Hero.SetGold
void SetGold(int amount, bool addToCurrentGold)
Sets the gold amount for the player owning this hero
Parameters
| Type | Name | Description |
|---|---|---|
| int | amount | An amount of gold |
| bool | addToCurrentGold | If true, amount will be added to the player's current gold; if false, the player's current gold will be set to amount.
|
Jail System
Hammer Setup
In Hammer, create a trigger_hero with the name radiant_prison. Create another trigger_hero with the name dire_prison.
Set the Entity Scripts property of both triggers to jail_trigger.lua. Finally, add an output on both triggers as follows:
VScripts
jail_trigger.lua:
function ReleasePrisonersConditionally(trigger)
print("!!! ReleasePrisonersConditionally CALLED !!!")
local jailSystem = GameRules.MyAddon.jailSystem
local thisPrison = trigger.caller
local vInmates = jailSystem:GetPrisoners(thisPrison)
if #vInmates == 0 then
print("no inmates found in " .. thisPrison:GetName())
return
end
local nTeamID = vInmates[1]:GetTeam()
if (not jailSystem:IsImprisoned(trigger.activator, thisPrison) and
trigger.activator:GetTeam() == nTeamID) then
print("releasing prisoners")
for _,npc in pairs(vInmates) do
jailSystem:Release(npc, thisPrison)
end
end
end
addon_game_mode.lua:
RAZOR = "npc_dota_hero_razor"
RADIANT_PRISON = "radiant_prison"
DIRE_PRISON = "dire_prison"
if CMyGameMode == nil then
CMyGameMode = class({})
end
function Precache (context)
PrecacheUnitByNameSync(RAZOR, context) -- XXX
end
-- Create the game mode when we activate
function Activate ()
GameRules.MyAddon = CMyGameMode()
GameRules.MyAddon:InitGameMode()
end
function CMyGameMode:InitGameMode ()
print( "Addon is loaded." )
GameRules:SetHeroRespawnEnabled(false)
-- XXX: For testing; remember to remove this!
self:PopulateWorldForTesting()
-- Initialize the jail system
self.jailSystem = CJailSystem({
[DOTA_TEAM_GOODGUYS] = Entities:FindByName(nil, DIRE_PRISON),
[DOTA_TEAM_BADGUYS] = Entities:FindByName(nil, RADIANT_PRISON)
})
self.jailSystem:Init()
end
function CMyGameMode:PopulateWorldForTesting ()
local razor = CreateUnitByName(RAZOR, Vector(0, 512, 0), true,
nil, nil, DOTA_TEAM_BADGUYS)
razor:SetControllableByPlayer(0, true)
end
----------
if CJailSystem == nil then
CJailSystem = class({ team2prison = {};
prisoners = {};
constructor = function (self, tbl)
self.team2prison = tbl or self.team2prison
for _,v in pairs(self.team2prison) do
v.JAIL_prisoners = {} -- XXX: Use DoUniqueString
end
end
})
end
function CJailSystem:Init ()
ListenToGameEvent("entity_killed", Dynamic_Wrap(CJailSystem, "OnEntityKilled" ), self)
end
function CJailSystem:GetPrisoners (prison)
local vInmates = {}
for k,_ in pairs(prison.JAIL_prisoners) do
table.insert(vInmates, k)
end
return vInmates
end
function CJailSystem:IsImprisoned (npc, prison)
return prison.JAIL_prisoners[npc]
end
function CJailSystem:OnEntityKilled (keys)
local killedEntity = EntIndexToHScript(keys.entindex_killed)
local prison = self.team2prison[killedEntity:GetTeam()]
if killedEntity:UnitCanRespawn() and prison then
self:Imprison(killedEntity, prison)
end
end
function CJailSystem:Imprison (npc, prison)
prison.JAIL_prisoners[npc] = true
npc:RespawnUnit()
FindClearSpaceForUnit(npc, prison:GetCenter(), false)
-- XXX: If we apply modifiers now, nothing happens (API bug?);
-- so we wait a bit and then apply them.
GameRules:GetGameModeEntity():SetThink(
function()
npc:AddNewModifier(npc, nil, "modifier_stunned", nil)
npc:AddNewModifier(npc, nil, "modifier_invulnerable", nil)
end, nil, 0.5)
end
function CJailSystem:Release (npc, prison)
prison.JAIL_prisoners[npc] = false
npc:RemoveModifierByName("modifier_stunned")
npc:RemoveModifierByName("modifier_invulnerable")
-- Add teleport stuff here!
end