u are a genious, i can not believe i made this mistake and i spent over 1 day trying to figure it out. I hope you do well in life!
Can anyone tell whatās wrong with this code? Iām trying to handle inputs for holdable skills but if you start holding one holdable skill button, and then hold another, if you let go of the second one then it will end the first skill. The intended behavior would either be for the second skill input to be ignored if it canāt be used at the same time or for the first and second held skills to have separately processed inputs.
Code
UserInputService.InputBegan:Connect(function(Input, GameProcessed)
if GameProcessed then return end
if Input.UserInputState ~= Enum.UserInputState.Begin then return end
local keys = {
Enum.KeyCode.One,
Enum.KeyCode.Two,
Enum.KeyCode.Three,
Enum.KeyCode.Four,
Enum.KeyCode.R,
Enum.UserInputType.MouseButton1,
Enum.KeyCode.F,
Enum.KeyCode.Q,
Enum.KeyCode.G}
local function processInput(Input)
local inputType
if Input.UserInputType == Enum.UserInputType.Keyboard then
inputType = Input.KeyCode
elseif Input.UserInputType then
inputType = Input.UserInputType
end
return inputType
end
local function getSkillIndex(skillInput)
local skillIndex = table.find(keys, skillInput)
if not skillIndex then return end
return skillIndex
end
local function getSkill(skillIndex)
local currentWCS_Character = getCurrentWCS_Character()
if not currentWCS_Character then return end
local currentMoveset = currentWCS_Character:GetMoveset()
if not currentMoveset then return end
local constructor = currentMoveset.Skills[skillIndex]
local skill = currentWCS_Character:GetSkillFromConstructor(constructor)
return skill
end
local skillInput = processInput(Input)
if not skillInput then return end
print(skillInput)
local skillIndex = getSkillIndex(skillInput)
if not skillIndex then return end
print(skillIndex)
local skill = getSkill(skillIndex)
if not skill then return end
local isHoldableSkill = skill:GetSkillType()
if isHoldableSkill then
skill:Start()
UserInputService.InputEnded:Connect(function(skillInput, GameProcessed)
skill:End()
end)
else
skill:Start()
end
end)
Now that I think about it, iām wondering if all those functions inside the InputBegan event should be outside of it instead. Does it have to create these functions from scratch every time you make an input? Sounds bad.
Highly recommend this framework, amazing design around it, I have a lot of projects, and different codebases can be stressful. This helps me implement any combat system I make into any framework or design.
omgā¦ that amazing! itās will help me ALOT thank you so much!
new tip..
but question
is there way that i can clear the skills?
thanks for support! you can manually iterate through the skill map and call the destroy method:
character:ClearMoveset()
for _, skill in character:GetSkills() do
skill:Destroy()
end
Iām making my own combat framework currently and Iāve been considering using this resource, however there are some aspects of it that make me reluctant to implement it. One aspect that iām iffy on is lag compensation. For example, in my own framework, I let the client perform any action they want (regardless of legitimacy) and send the playerās inputs and states off to the server as a ācommandā every heartbeat to check for integrity. If the check passes, the states of the player are replicated to the rest of the players where they can be interpreted (and properly compensated for lag including character position). Besides the obvious security concerns of my system, Iām just unsure if WCS is the way to go in my case due to the strict accuracy my game demands. Iād be happy to hear anyone out though!
Hi, Iāve had issue with making an holdableSkill Sprint, this skill canāt be used again after used one time, sorry to asking this I already try read docs and api but no one help (my english kinda bad).
main.client.ts
import { Players, ReplicatedStorage, UserInputService } from "@rbxts/services";
import { Character, CreateClient } from "@rbxts/wcs";
import { Sprint } from "shared/skills/sprint";
const Client = CreateClient();
Client.RegisterDirectory(ReplicatedStorage.TS.movesets);
Client.RegisterDirectory(ReplicatedStorage.TS.skills);
Client.RegisterDirectory(ReplicatedStorage.TS.statusEffects);
Client.Start();
function getCurrentWCS_Character() {
const characterModel = Players.LocalPlayer.Character;
if (!characterModel) return;
return Character.GetCharacterFromInstance(characterModel) || Character.CharacterCreated.Wait()[0];
}
UserInputService.InputBegan.Connect((Input, GameProcessed) => {
if (GameProcessed) return;
if (Input.UserInputState !== Enum.UserInputState.Begin) return;
const character = getCurrentWCS_Character();
if (Input.KeyCode === Enum.KeyCode.LeftControl) {
character?.GetSkillFromConstructor(Sprint)?.Start();
}
});
UserInputService.InputEnded.Connect((Input, GameProcessed) => {
if (GameProcessed) return;
const character = getCurrentWCS_Character();
if (Input.KeyCode === Enum.KeyCode.LeftControl) {
character?.GetSkillFromConstructor(Sprint)?.End();
}
});
sprint.ts
import { HoldableSkill, SkillDecorator } from "@rbxts/wcs";
import { SpeedBoost } from "shared/statusEffects/speedBoost";
import { Stun } from "shared/statusEffects/stun";
@SkillDecorator
export class Sprint extends HoldableSkill {
protected MutualExclusives = [Stun];
private speedBoost = new SpeedBoost(this.Character);
public OnConstructServer() {
this.SetMaxHoldTime(5);
}
public OnStartServer() {
this.speedBoost.Start();
this.ApplyCooldown(10);
}
public OnEndClient() {
this.speedBoost.Stop();
}
}
speedBoost.ts
import { StatusEffect, StatusEffectDecorator } from "@rbxts/wcs";
@StatusEffectDecorator
export class SpeedBoost extends StatusEffect {
public OnStartServer() {
this.SetHumanoidData({ WalkSpeed: [25, "Set"] });
}
public OnEndServer() {
this.SetHumanoidData({ WalkSpeed: [16, "Set"] });
}
}
nvm, Iāve found out the issueā¦ It shouldāve more than 29 characters?
Hello,
I had a minor question on some custom-types in wcs. I want to use StatusEffectImp, Character (type) in files outside of the package, how can I do it?
E.g:
local ReplicatedStorage = game:GetService(āReplicatedStorageā)
local WCS = require(ReplicatedStorage.Packages.wcs)
export type PlayPhaseStatusType = {
OriginalStatus: string,
Status: StatusEffectImp ā cannot find the type
}
Hello,
When I am attempting to call the name of an ability it keeps returning as Nilā¦ however, yesterday I had it working and calling the correct nameā¦ didnāt really change anythingā¦ and suddenly itās not working.
--References--
local skillsRef = WCSFolder:WaitForChild("skills")
local skills = {
Fireball = require(skillsRef.Fireball),
Frost_Shard = require(skillsRef.Frost_Shard),
Basic_Blast = require(skillsRef.Basic_Blast)
}
My skills are in fact registered:
Players.PlayerAdded:Connect(function(Player)
print("Player Added", Player)
Player.CharacterAdded:Connect(function(CharacterModel)
print("Character Added Gonna make skills")
-- apply the wrap when character model gets created
local WCS_Character = Character.new(CharacterModel)
print(WCS_Character, CharacterModel.Name)
-- apply our freshly made skill
skills.Fireball.new(WCS_Character)
skills.Frost_Shard.new(WCS_Character)
skills.Basic_Blast.new(WCS_Character)
ConstantSkills.Shield.new(WCS_Character)
-- destroy it when humanoid dies
local Humanoid = CharacterModel:WaitForChild("Humanoid")
Humanoid.Died:Once(function()
WCS_Character:Destroy()
end)
end)
end)
When I am trying to call the name, Itās more official name is meant to be applied to a Gui, and the reference of the module is meant to then be applied to another dictionary.
--Spell Changing Click Once "T"
elseif Input.KeyCode == Enum.KeyCode.T then
local character = getCurrentWCS_Character()
if not character then return end
print("The Character is", character)
local Num
local NumOfSkills = 0
local loopNum = 0
for i,v in pairs(skills) do
NumOfSkills = NumOfSkills + 1
print("Got SKill", i, v, NumOfSkills)
end
if Information.skillsListNum ~= NumOfSkills then
Num = Information.skillsListNum + 1
else
Num = 1
end
print("The Num is", Num)
for spell,SpellCert in pairs(skills) do
loopNum = loopNum + 1
print("Looking Through Spelld", spell, SpellCert)
if loopNum == Num then
print("Found the spell")
Information.Current_Spell = SpellCert --Here is where the problem is
Information.skillsListNum = Num
SpellID_GUI.SpellIdentifier.Text = SpellCert.Name --Here is where the problem is
break
elseif SpellCert.Name == nil then
print("Spell Name is Nil!..", spell)
end
end
print(NumOfSkills, Num, skills[Num],Information.Current_Spell)
end
end
It was working yesterdayā¦ dont know what changed.
Please help!
Thanks,
Manelin
Iām stuggling for some reason with the TakeDamage Method
local DamageContainer = Shock_Blast.CreateDamageContainer(15)
local targetCharacter = WCS.Character.GetCharacterFromInstance(Victim.Character)
print(DamageContainer.Damage, DamageContainer.Source, "Is the Damage values")
targetCharacter:TakeDamage(DamageContainer)
end
Please help!
Update, I managed to get it workingā¦ silly me. But Iām confused about why thereās still an error here that the 'DamageDealt" is nil, yet itās still running the damage function.
local function OnIntersection(Player: Player, Direction: Vector3, Part: string, Victim: Player?, Position: Vector3, Character: Model, Extra: any)
local Humanoid: Humanoid? = Character and Character:FindFirstChild("Humanoid") :: Humanoid
if not Humanoid or Humanoid.Health <= 0 then
return
end
local targetCharacter = WCS.Character.GetCharacterFromInstance(Victim.Character)
targetCharacter.DamageTaken:Connect(function(container)
print("Gonna Take Damage in Shock_Blast")
targetCharacter.Instance.Humanoid:TakeDamage(container.Damage)
end)
local DamageContainer = SkillScript:CreateDamageContainer(15)
print(DamageContainer.Damage, DamageContainer.Source.Character, "Is the Damage values")
targetCharacter:TakeDamage(DamageContainer)
--SkillScript:EffectOnTargetCharacter(Player,Direction,Victim,Position,Character)
print(`Intersected {Victim or Character}'s {Part}`)
end
are you running that on client?
I managed to figure it out. It was because I was failing to call the registered skill within the player rather than just callilng a require on the modulescript.
Iām having anew issue now, where my registeredHoldableSkills are returning as ādefaultā when I call the āGetSkillType()ā method.
I have put some checks within the source code when registering a holdable skill, and it appears that all of the skills are being processed properly as a holdable skillā¦ but there must be something wrong with how Iām calling holdable skills? Let me provide the output data as well as the area of code that iām using.
Output:
- Pink Highlight = A print I am generating from the āHoldableSkillā module within the WCS framework right after it classifies the skill type as holdable, and it presents it back as the correct vale. So I assume It must be something wrong with How iām using the framework in my own code.
- Yellow Highlight = The print I am generating with āGetSkillType()ā
Next: A fragment of my code:
Here is where I am indexing my required calls for all of my skill modules:
Here is the code in the script I am trying to use to call the Holdable Skill
--USER INPUT FUNCTION--
UserInputService.InputBegan:Connect(function(Input, GameProcessed)
if GameProcessed then return end
if Input.UserInputType == Enum.UserInputType.MouseButton1 then-->Run Spell Casting
if Input.UserInputState ~= Enum.UserInputState.Begin then return end
local character = getCurrentWCS_Character()
local SkillConstructed = character:GetSkillFromConstructor(Information.Current_Spell)
if not character or not Information.BattleReady then return end
if Information.Button_Down or Information.ChargeHold then return end
print(SkillConstructed:GetSkillType(), "Is the skilltype")
if SkillConstructed:GetSkillType() == "Holdable" then -----------------IS RETURNING AS DEFAULT INSTEAD OF HOLDABLE, BUT REGISTERED AS HOLDABLE!
Information.ChargeHold = true
ChargePrep(1.5)
character:GetSkillFromConstructor(Information.Current_Spell):Start()
local runRelease = UserInputService.InputEnded:Connect(function(NewInput, NewGameProcessed)
if NewInput.UserInputType == Enum.UserInputType.MouseButton1 then
Information.ChargeHold = false
ChargePrep(1.5)
if Information.Charged then
Information.Charged = false
character:GetSkillFromConstructor(Information.Current_Spell):Stop()
end
end
end)
repeat wait() until not Information.ChargeHold
runRelease:Disconnect()
else
local MouseHit = Mouse.Hit.Position
character:GetSkillFromConstructor(Information.Current_Spell):Start(MouseHit)
end
--HOLDABLE SHIELD SPELL-------->
elseif Input.UserInputType == Enum.UserInputType.Keyboard then-->Block Spell Casting + Change Spell
if Input.KeyCode == Enum.KeyCode.Q then -->Block is Click and Hold
local character = getCurrentWCS_Character()
local SkillConstructed = character:GetSkillFromConstructor(Skill_Data.ConstantSkills.Shield)
print(SkillConstructed:GetSkillType(), "Is the skilltype", SkillConstructed, Skill_Data.ConstantSkills.Shield) ---------------------------IS PRINTING AS DEFAULT INSTEAD OF HOLDABLE!!
if not character or not Information.BattleReady then return end
character:GetSkillFromConstructor(Skill_Data.ConstantSkills.Shield):Start()
Information.Button_Down = true
local runRelease = UserInputService.InputEnded:Connect(function(NewInput, NewGameProcessed)
if NewInput.KeyCode ~= Enum.KeyCode.Q then repeat wait() until NewInput.KeyCode == Enum.KeyCode.Q end
print()
character:GetSkillFromConstructor(Skill_Data.ConstantSkills.Shield):Stop()
Information.Button_Down = false
end)
repeat wait() until not Information.Button_Down
runRelease:Disconnect()
Here is the Shield Module that iām trying to get the Holdable type from,
The Yellow Highlight at the bottom is not calling at allā¦ Iām asuming this might ahve something to do with it?
Iām still learning to use this Framework so please bare with my questions. Iāll let you know if I figure it out before someone responds. But, if someone could help Please!
oh yeah, this is a bug and been fixed recently, the version just isnāt released yet. you can downgrade temporarily or add _internal_
prefix to the corresponding variable in a module named āholdableSkillā
Interesting. Thanks. I also discovered that you can simply get the skill from the character and add .skillType, which will return the skill type.
Legendary! Thanks a million!
-Manelin
What are starter params? Iām not sure what they are and how to use themā¦